mirror of
https://github.com/Telecominfraproject/OpenNetworkLinux.git
synced 2025-11-01 10:48:18 +00:00
[as5916-54xks] Add support for YM-2851J DC PSU
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
|
||||
static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data);
|
||||
static ssize_t show_linear(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf);
|
||||
static ssize_t show_psu(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
static ssize_t show_string(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
static int as5916_54xks_psu_probe(struct platform_device *pdev);
|
||||
@@ -70,6 +71,7 @@ enum psu_data_index {
|
||||
PSU_FAN1,
|
||||
PSU_POUT0,
|
||||
PSU_POUT1,
|
||||
PSU_VOUT_MODE,
|
||||
PSU_STATUS_COUNT,
|
||||
PSU_MODEL = 0,
|
||||
PSU_SERIAL = 0
|
||||
@@ -93,7 +95,7 @@ struct ipmi_data {
|
||||
};
|
||||
|
||||
struct ipmi_psu_resp_data {
|
||||
unsigned char status[19];
|
||||
unsigned char status[20];
|
||||
char serial[19];
|
||||
char model[9];
|
||||
};
|
||||
@@ -152,7 +154,7 @@ enum as5916_54x_psu_sysfs_attrs {
|
||||
#define DECLARE_PSU_SENSOR_DEVICE_ATTR(index) \
|
||||
static SENSOR_DEVICE_ATTR(psu##index##_present, S_IRUGO, show_psu, NULL, PSU##index##_PRESENT); \
|
||||
static SENSOR_DEVICE_ATTR(psu##index##_power_good, S_IRUGO, show_psu, NULL, PSU##index##_POWER_GOOD); \
|
||||
static SENSOR_DEVICE_ATTR(psu##index##_vout, S_IRUGO, show_linear, NULL, PSU##index##_VOUT); \
|
||||
static SENSOR_DEVICE_ATTR(psu##index##_vout, S_IRUGO, show_vout, NULL, PSU##index##_VOUT); \
|
||||
static SENSOR_DEVICE_ATTR(psu##index##_iout, S_IRUGO, show_linear, NULL, PSU##index##_IOUT); \
|
||||
static SENSOR_DEVICE_ATTR(psu##index##_pout, S_IRUGO, show_linear, NULL, PSU##index##_POUT); \
|
||||
static SENSOR_DEVICE_ATTR(psu##index##_model, S_IRUGO, show_string, NULL, PSU##index##_MODEL); \
|
||||
@@ -304,6 +306,7 @@ static struct as5916_54xks_psu_data *as5916_54xks_psu_update_device(struct devic
|
||||
}
|
||||
|
||||
data->valid[pid] = 0;
|
||||
data->ipmi_resp[pid].status[PSU_VOUT_MODE] = 0xff; /* To be compatible for older BMC firmware */
|
||||
|
||||
/* Get status from ipmi */
|
||||
data->ipmi_tx_data[0] = pid + 1; /* PSU ID base id for ipmi start from 1 */
|
||||
@@ -319,7 +322,7 @@ static struct as5916_54xks_psu_data *as5916_54xks_psu_update_device(struct devic
|
||||
}
|
||||
|
||||
/* Get model name from ipmi */
|
||||
data->ipmi_tx_data[1] = 0x10;
|
||||
data->ipmi_tx_data[1] = IPMI_PSU_MODEL_NAME_CMD;
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_PSU_READ_CMD, data->ipmi_tx_data, 2,
|
||||
data->ipmi_resp[pid].model, sizeof(data->ipmi_resp[pid].model) - 1);
|
||||
if (unlikely(status != 0)) {
|
||||
@@ -332,7 +335,7 @@ static struct as5916_54xks_psu_data *as5916_54xks_psu_update_device(struct devic
|
||||
}
|
||||
|
||||
/* Get serial number from ipmi */
|
||||
data->ipmi_tx_data[1] = 0x11;
|
||||
data->ipmi_tx_data[1] = IPMI_PSU_SERIAL_NUM_CMD;
|
||||
status = ipmi_send_message(&data->ipmi, IPMI_PSU_READ_CMD, data->ipmi_tx_data, 2,
|
||||
data->ipmi_resp[pid].serial, sizeof(data->ipmi_resp[pid].serial) - 1);
|
||||
if (unlikely(status != 0)) {
|
||||
@@ -421,6 +424,50 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
unsigned char pid = attr->index / NUM_OF_PER_PSU_ATTR;
|
||||
u16 value = 0;
|
||||
int error = 0;
|
||||
int exponent = 0, mantissa = 0;
|
||||
int multiplier = 1000;
|
||||
u8 vout_mode = 0xff;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
data = as5916_54xks_psu_update_device(da);
|
||||
if (!data->valid[pid]) {
|
||||
error = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
vout_mode = (u8)data->ipmi_resp[pid].status[PSU_VOUT_MODE];
|
||||
value = ((u16)data->ipmi_resp[pid].status[PSU_VOUT0] |
|
||||
(u16)data->ipmi_resp[pid].status[PSU_VOUT1] << 8);
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
if (vout_mode == 0xff) {
|
||||
exponent = two_complement_to_int(value >> 11, 5, 0x1f);
|
||||
mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff);
|
||||
}
|
||||
else if (!(vout_mode & 0xe0)){
|
||||
exponent = two_complement_to_int(vout_mode & 0x1f, 5, 0x1f);
|
||||
mantissa = two_complement_to_int(value & 0xffff, 16, 0xffff);
|
||||
}
|
||||
else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) :
|
||||
sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
static ssize_t show_psu(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
|
||||
Reference in New Issue
Block a user