[AS9716-32D]Support multi PSU SN in PDDF (#8214)
Add needed code to pddf_custom_psu.c to deal with multi PSU and get SN. How to verify it Plugin new PSU (3Y) and test, ``` root@sonic:/sys/bus/i2c/drivers/psu/9-0050# cat psu_serial_num S0A000X601919000013 root@sonic:/sys/bus/i2c/drivers/psu/9-0050# cat psu_model_name YESM1300AM root@sonic:/home/admin# pddf_psuutil mfrinfo PSU Status Manufacturer ID Model Serial Fan Airflow Direction PSU1 NOT OK 3Y POWER YESM1300AM S0A000X601919000007 exhaust PSU2 OK 3Y POWER YESM1300AM S0A000X601919000013 exhaust ``` Co-authored-by: Jostar Yang <jostar_yang@accton.com.tw>
This commit is contained in:
parent
fed8957b47
commit
3e7228d45c
@ -13,6 +13,95 @@
|
||||
|
||||
ssize_t pddf_show_custom_psu_v_out(struct device *dev, struct device_attribute *da, char *buf);
|
||||
extern PSU_SYSFS_ATTR_DATA access_psu_v_out;
|
||||
ssize_t pddf_get_custom_psu_model_name(struct device *dev, struct device_attribute *da, char *buf);
|
||||
ssize_t pddf_get_custom_psu_serial_num(struct device *dev, struct device_attribute *da, char *buf);
|
||||
extern PSU_SYSFS_ATTR_DATA access_psu_model_name;
|
||||
extern PSU_SYSFS_ATTR_DATA access_psu_serial_num;
|
||||
|
||||
#define MAX_MODEL_NAME 16
|
||||
#define MAX_SERIAL_NUMBER 19
|
||||
|
||||
enum psu_type {
|
||||
PSU_TYPE_AC_110V,
|
||||
PSU_TYPE_DC_48V,
|
||||
PSU_TYPE_DC_12V,
|
||||
PSU_TYPE_AC_ACBEL_FSF019,
|
||||
PSU_TYPE_AC_ACBEL_FSH082,
|
||||
PSU_TYPE_YESM1300
|
||||
|
||||
};
|
||||
|
||||
struct model_name_info {
|
||||
enum psu_type type;
|
||||
u8 offset;
|
||||
u8 length;
|
||||
u8 chk_length;
|
||||
char* model_name;
|
||||
};
|
||||
|
||||
struct serial_number_info {
|
||||
enum psu_type type;
|
||||
u8 offset;
|
||||
u8 length;
|
||||
u8 chk_length;
|
||||
char* serial_number;
|
||||
};
|
||||
|
||||
struct model_name_info models[] = {
|
||||
{PSU_TYPE_AC_110V, 0x20, 8, 8, "YM-2651Y"},
|
||||
{PSU_TYPE_DC_48V, 0x20, 8, 8, "YM-2651V"},
|
||||
{PSU_TYPE_DC_12V, 0x00, 11, 11, "PSU-12V-750"},
|
||||
{PSU_TYPE_AC_ACBEL_FSF019, 0x15, 10, 7, "FSF019-"},
|
||||
{PSU_TYPE_AC_ACBEL_FSH082, 0x20, 10, 7, "FSH082-"},
|
||||
{PSU_TYPE_YESM1300, 0x20, 11, 8, "YESM1300"},
|
||||
|
||||
};
|
||||
|
||||
struct serial_number_info serials[] = {
|
||||
{PSU_TYPE_AC_110V, 0x2e, 18, 18, "YM-2651Y"},
|
||||
{PSU_TYPE_DC_48V, 0x2e, 18, 18, "YM-2651V"},
|
||||
{PSU_TYPE_DC_12V, 0x2e, 18, 18, "PSU-12V-750"},
|
||||
{PSU_TYPE_AC_ACBEL_FSF019, 0x2e, 16, 16, "FSF019-"},
|
||||
{PSU_TYPE_AC_ACBEL_FSH082, 0x35, 18, 18, "FSH082-"},
|
||||
{PSU_TYPE_YESM1300, 0x35, 20, 19, "YESM1300"},
|
||||
|
||||
};
|
||||
|
||||
struct pddf_psu_data {
|
||||
char model_name[MAX_MODEL_NAME+1];
|
||||
char serial_number[MAX_SERIAL_NUMBER+1];
|
||||
};
|
||||
|
||||
|
||||
static int pddf_psu_read_block(struct i2c_client *client, u8 command, u8 *data,
|
||||
int data_len)
|
||||
{
|
||||
int result = 0;
|
||||
int retry_count = 10;
|
||||
|
||||
while (retry_count) {
|
||||
retry_count--;
|
||||
|
||||
result = i2c_smbus_read_i2c_block_data(client, command, data_len, data);
|
||||
|
||||
if (unlikely(result < 0)) {
|
||||
msleep(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (unlikely(result != data_len)) {
|
||||
result = -EIO;
|
||||
msleep(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int two_complement_to_int(u16 data, u8 valid_bit, int mask)
|
||||
{
|
||||
@ -90,7 +179,7 @@ ssize_t pddf_show_custom_psu_v_out(struct device *dev, struct device_attribute *
|
||||
exponent = two_complement_to_int(vout_mode & 0x1f, 5, 0x1f);
|
||||
else
|
||||
{
|
||||
printk(KERN_ERR "%s: Only support linear mode for vout mode\n", __func__);
|
||||
/*printk(KERN_ERR "%s: Only support linear mode for vout mode\n", __func__);*/
|
||||
exponent = 0;
|
||||
}
|
||||
mantissa = value;
|
||||
@ -100,13 +189,117 @@ ssize_t pddf_show_custom_psu_v_out(struct device *dev, struct device_attribute *
|
||||
return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
|
||||
}
|
||||
|
||||
ssize_t pddf_get_custom_psu_serial_num(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct pddf_psu_data data;
|
||||
int i, status;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(models); i++) {
|
||||
memset(data.serial_number, 0, sizeof(data.serial_number));
|
||||
|
||||
status = pddf_psu_read_block(client, models[i].offset,
|
||||
data.model_name, models[i].length);
|
||||
if (status < 0) {
|
||||
data.model_name[0] = '\0';
|
||||
dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x%x)\n",
|
||||
client->addr, models[i].offset);
|
||||
return status;
|
||||
}
|
||||
else {
|
||||
data.model_name[models[i].length] = '\0';
|
||||
}
|
||||
|
||||
/* Determine if the model name is known, if not, read next index
|
||||
*/
|
||||
|
||||
if (strncmp(data.model_name, models[i].model_name, models[i].chk_length) == 0) {
|
||||
status = pddf_psu_read_block(client, serials[i].offset,
|
||||
data.serial_number, serials[i].length);
|
||||
|
||||
if (status < 0) {
|
||||
data.serial_number[0] = '\0';
|
||||
dev_dbg(&client->dev, "unable to read serial num from (0x%x) offset(0x%x)\n",
|
||||
client->addr, serials[i].offset);
|
||||
return status;
|
||||
}
|
||||
else {
|
||||
data.serial_number[serials[i].length] = '\0';
|
||||
return sprintf(buf, "%s\n", data.serial_number);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
data.serial_number[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return -ENODATA;
|
||||
|
||||
|
||||
}
|
||||
|
||||
ssize_t pddf_get_custom_psu_model_name(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct pddf_psu_data data;
|
||||
int i, status;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(models); i++) {
|
||||
memset(data.model_name, 0, sizeof(data.model_name));
|
||||
|
||||
status = pddf_psu_read_block(client, models[i].offset,
|
||||
data.model_name, models[i].length);
|
||||
if (status < 0) {
|
||||
data.model_name[0] = '\0';
|
||||
dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x%x)\n",
|
||||
client->addr, models[i].offset);
|
||||
return status;
|
||||
}
|
||||
else {
|
||||
data.model_name[models[i].length] = '\0';
|
||||
}
|
||||
|
||||
/* Determine if the model name is known, if not, read next index
|
||||
*/
|
||||
if (strncmp(data.model_name, models[i].model_name, models[i].chk_length) == 0) {
|
||||
if (models[i].type==PSU_TYPE_YESM1300)
|
||||
{
|
||||
if (data.model_name[9]=='A' && data.model_name[10]=='M')
|
||||
{
|
||||
data.model_name[8]='A';
|
||||
data.model_name[9]='M';
|
||||
data.model_name[strlen("YESM1300AM")]='\0';
|
||||
}
|
||||
else
|
||||
data.model_name[strlen("YESM1300")]='\0';
|
||||
}
|
||||
|
||||
return sprintf(buf, "%s\n", data.model_name);
|
||||
}
|
||||
else {
|
||||
data.model_name[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return -ENODATA;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int __init pddf_custom_psu_init(void)
|
||||
{
|
||||
access_psu_v_out.show = pddf_show_custom_psu_v_out;
|
||||
access_psu_v_out.do_get = NULL;
|
||||
printk(KERN_ERR "pddf_custom_psu_init\n");
|
||||
|
||||
access_psu_serial_num.show = pddf_get_custom_psu_serial_num;
|
||||
access_psu_serial_num.do_get = NULL;
|
||||
|
||||
access_psu_model_name.show = pddf_get_custom_psu_model_name;
|
||||
access_psu_model_name.do_get = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user