diff --git a/packages/platforms/accton/x86-64/as5916-54xks/modules/builds/x86-64-accton-as5916-54xks-psu.c b/packages/platforms/accton/x86-64/as5916-54xks/modules/builds/x86-64-accton-as5916-54xks-psu.c index 3249a98f..d89e606d 100755 --- a/packages/platforms/accton/x86-64/as5916-54xks/modules/builds/x86-64-accton-as5916-54xks-psu.c +++ b/packages/platforms/accton/x86-64/as5916-54xks/modules/builds/x86-64-accton-as5916-54xks-psu.c @@ -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);