From a992d7ef0c44df58b7905365439fa6d08e8e3256 Mon Sep 17 00:00:00 2001 From: Sean Wu Date: Fri, 14 May 2021 15:35:30 +0800 Subject: [PATCH 1/3] [Accton] support ACBEL FSF019 PSU Models: as7326_56x, as7712_32x, as7716_32x, as7726_32x Signed-off-by: Sean Wu --- .../modules/accton_as7326_56x_psu.c | 99 ++++++++++++++++--- .../modules/accton_as7712_32x_psu.c | 99 ++++++++++++++++--- .../modules/accton_as7716_32x_psu.c | 13 ++- .../modules/accton_as7726_32x_psu.c | 98 +++++++++++++++--- 4 files changed, 260 insertions(+), 49 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c index 8c2ece6200fe..705b94887207 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c @@ -34,8 +34,9 @@ #include #include +#define MAX_MODEL_NAME 16 static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf); static int as7326_56x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); extern int as7326_56x_cpld_read(unsigned short cpld_addr, u8 reg); @@ -52,7 +53,7 @@ struct as7326_56x_psu_data { unsigned long last_updated; /* In jiffies */ u8 index; /* PSU index */ u8 status; /* Status(present/power_good) register read from CPLD */ - char model_name[9]; /* Model name, read from eeprom */ + char model_name[MAX_MODEL_NAME+1]; /* Model name, read from eeprom */ }; static struct as7326_56x_psu_data *as7326_56x_psu_update_device(struct device *dev); @@ -66,7 +67,7 @@ enum as7326_56x_psu_sysfs_attributes { /* sysfs attributes for hwmon */ static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); -static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_string, NULL, PSU_MODEL_NAME); static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); static struct attribute *as7326_56x_psu_attributes[] = { @@ -83,6 +84,10 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, struct as7326_56x_psu_data *data = as7326_56x_psu_update_device(dev); u8 status = 0; + if (!data->valid) { + return -EIO; + } + if (attr->index == PSU_PRESENT) { status = !(data->status >> (1-data->index) & 0x1); } @@ -93,12 +98,24 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, return sprintf(buf, "%d\n", status); } -static ssize_t show_model_name(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_string(struct device *dev, struct device_attribute *da, + char *buf) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct as7326_56x_psu_data *data = as7326_56x_psu_update_device(dev); + char *ptr = NULL; + + if (!data->valid) { + return -EIO; + } - return sprintf(buf, "%s\n", data->model_name); + if (attr->index == PSU_MODEL_NAME) { + ptr = data->model_name; + } + else { + return -EIO; + } + return sprintf(buf, "%s\n", ptr); } static const struct attribute_group as7326_56x_psu_group = { @@ -219,6 +236,62 @@ static int as7326_56x_psu_read_block(struct i2c_client *client, u8 command, u8 * return result; } +enum psu_type { + PSU_TYPE_AC_110V, + PSU_TYPE_DC_48V, + PSU_TYPE_DC_12V, + PSU_TYPE_AC_ACBEL_FSF019 +}; + +struct model_name_info { + enum psu_type type; + u8 offset; + u8 length; + u8 chk_length; + char* model_name; +}; + +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-"} +}; + +static int as7326_56x_psu_model_name_get(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7326_56x_psu_data *data = i2c_get_clientdata(client); + int i, status; + + for (i = 0; i < ARRAY_SIZE(models); i++) { + memset(data->model_name, 0, sizeof(data->model_name)); + + status = as7326_56x_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) { + return 0; + } + else { + data->model_name[0] = '\0'; + } + } + + return -ENODATA; +} + static struct as7326_56x_psu_data *as7326_56x_psu_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -231,6 +304,7 @@ static struct as7326_56x_psu_data *as7326_56x_psu_update_device(struct device *d int status; int power_good = 0; + data->valid = 0; dev_dbg(&client->dev, "Starting as7326_56x update\n"); /* Read psu status */ @@ -238,6 +312,7 @@ static struct as7326_56x_psu_data *as7326_56x_psu_update_device(struct device *d if (status < 0) { dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status); + goto exit; } else { data->status = status; @@ -248,15 +323,8 @@ static struct as7326_56x_psu_data *as7326_56x_psu_update_device(struct device *d power_good = (data->status >> (3-data->index) & 0x1); if (power_good) { - status = as7326_56x_psu_read_block(client, 0x20, data->model_name, - ARRAY_SIZE(data->model_name)-1); - - if (status < 0) { - data->model_name[0] = '\0'; - dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr); - } - else { - data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0'; + if (as7326_56x_psu_model_name_get(dev) < 0) { + goto exit; } } @@ -264,6 +332,7 @@ static struct as7326_56x_psu_data *as7326_56x_psu_update_device(struct device *d data->valid = 1; } +exit: mutex_unlock(&data->update_lock); return data; diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_psu.c index 233aef78e09f..edbad79fcbf5 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_psu.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_psu.c @@ -34,8 +34,9 @@ #include #include +#define MAX_MODEL_NAME 16 static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf); static int as7712_32x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); @@ -52,7 +53,7 @@ struct as7712_32x_psu_data { unsigned long last_updated; /* In jiffies */ u8 index; /* PSU index */ u8 status; /* Status(present/power_good) register read from CPLD */ - char model_name[9]; /* Model name, read from eeprom */ + char model_name[MAX_MODEL_NAME+1]; /* Model name, read from eeprom */ }; static struct as7712_32x_psu_data *as7712_32x_psu_update_device(struct device *dev); @@ -66,7 +67,7 @@ enum as7712_32x_psu_sysfs_attributes { /* sysfs attributes for hwmon */ static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); -static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_string, NULL, PSU_MODEL_NAME); static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); static struct attribute *as7712_32x_psu_attributes[] = { @@ -83,6 +84,10 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, struct as7712_32x_psu_data *data = as7712_32x_psu_update_device(dev); u8 status = 0; + if (!data->valid) { + return -EIO; + } + if (attr->index == PSU_PRESENT) { status = !(data->status >> (1-data->index) & 0x1); } @@ -93,12 +98,24 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, return sprintf(buf, "%d\n", status); } -static ssize_t show_model_name(struct device *dev, struct device_attribute *da, +static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct as7712_32x_psu_data *data = as7712_32x_psu_update_device(dev); - - return sprintf(buf, "%s\n", data->model_name); + char *ptr = NULL; + + if (!data->valid) { + return -EIO; + } + + if (attr->index == PSU_MODEL_NAME) { + ptr = data->model_name; + } + else { + return -EIO; + } + return sprintf(buf, "%s\n", ptr); } static const struct attribute_group as7712_32x_psu_group = { @@ -219,6 +236,62 @@ static int as7712_32x_psu_read_block(struct i2c_client *client, u8 command, u8 * return result; } +enum psu_type { + PSU_TYPE_AC_110V, + PSU_TYPE_DC_48V, + PSU_TYPE_DC_12V, + PSU_TYPE_AC_ACBEL_FSF019 +}; + +struct model_name_info { + enum psu_type type; + u8 offset; + u8 length; + u8 chk_length; + char* model_name; +}; + +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-"} +}; + +static int as7712_32x_psu_model_name_get(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7712_32x_psu_data *data = i2c_get_clientdata(client); + int i, status; + + for (i = 0; i < ARRAY_SIZE(models); i++) { + memset(data->model_name, 0, sizeof(data->model_name)); + + status = as7712_32x_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) { + return 0; + } + else { + data->model_name[0] = '\0'; + } + } + + return -ENODATA; +} + static struct as7712_32x_psu_data *as7712_32x_psu_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -231,6 +304,7 @@ static struct as7712_32x_psu_data *as7712_32x_psu_update_device(struct device *d int status; int power_good = 0; + data->valid = 0; dev_dbg(&client->dev, "Starting as7712_32x update\n"); /* Read psu status */ @@ -238,6 +312,7 @@ static struct as7712_32x_psu_data *as7712_32x_psu_update_device(struct device *d if (status < 0) { dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status); + goto exit; } else { data->status = status; @@ -248,15 +323,8 @@ static struct as7712_32x_psu_data *as7712_32x_psu_update_device(struct device *d power_good = (data->status >> (3-data->index) & 0x1); if (power_good) { - status = as7712_32x_psu_read_block(client, 0x20, data->model_name, - ARRAY_SIZE(data->model_name)-1); - - if (status < 0) { - data->model_name[0] = '\0'; - dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr); - } - else { - data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0'; + if (as7712_32x_psu_model_name_get(dev) < 0) { + goto exit; } } @@ -264,6 +332,7 @@ static struct as7712_32x_psu_data *as7712_32x_psu_update_device(struct device *d data->valid = 1; } +exit: mutex_unlock(&data->update_lock); return data; diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_psu.c index 78a58b820b2a..9d814d40cf58 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_psu.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_psu.c @@ -248,20 +248,23 @@ static int as7716_32x_psu_read_block(struct i2c_client *client, u8 command, u8 * enum psu_type { PSU_TYPE_AC_110V, PSU_TYPE_DC_48V, - PSU_TYPE_DC_12V + PSU_TYPE_DC_12V, + PSU_TYPE_AC_ACBEL_FSF019 }; struct model_name_info { enum psu_type type; u8 offset; u8 length; + u8 chk_length; char* model_name; }; struct model_name_info models[] = { -{PSU_TYPE_AC_110V, 0x20, 8, "YM-2651Y"}, -{PSU_TYPE_DC_48V, 0x20, 8, "YM-2651V"}, -{PSU_TYPE_DC_12V, 0x00, 11, "PSU-12V-750"}, +{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-"} }; static int as7716_32x_psu_model_name_get(struct device *dev) @@ -287,7 +290,7 @@ static int as7716_32x_psu_model_name_get(struct device *dev) /* Determine if the model name is known, if not, read next index */ - if (strncmp(data->model_name, models[i].model_name, models[i].length) == 0) { + if (strncmp(data->model_name, models[i].model_name, models[i].chk_length) == 0) { return 0; } else { diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_psu.c index f4da01e86d9b..c615df5664fa 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_psu.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_psu.c @@ -34,8 +34,9 @@ #include #include +#define MAX_MODEL_NAME 16 static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf); static int as7726_32x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); extern int as7726_32x_cpld_read(unsigned short cpld_addr, u8 reg); @@ -52,7 +53,7 @@ struct as7726_32x_psu_data { unsigned long last_updated; /* In jiffies */ u8 index; /* PSU index */ u8 status; /* Status(present/power_good) register read from CPLD */ - char model_name[9]; /* Model name, read from eeprom */ + char model_name[MAX_MODEL_NAME+1]; /* Model name, read from eeprom */ }; static struct as7726_32x_psu_data *as7726_32x_psu_update_device(struct device *dev); @@ -66,7 +67,7 @@ enum as7726_32x_psu_sysfs_attributes { /* sysfs attributes for hwmon */ static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); -static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_string, NULL, PSU_MODEL_NAME); static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); static struct attribute *as7726_32x_psu_attributes[] = { @@ -83,6 +84,10 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, struct as7726_32x_psu_data *data = as7726_32x_psu_update_device(dev); u8 status = 0; + if (!data->valid) { + return -EIO; + } + if (attr->index == PSU_PRESENT) { status = !(data->status >> (1-data->index) & 0x1); } @@ -93,12 +98,24 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, return sprintf(buf, "%d\n", status); } -static ssize_t show_model_name(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_string(struct device *dev, struct device_attribute *da, + char *buf) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct as7726_32x_psu_data *data = as7726_32x_psu_update_device(dev); + char *ptr = NULL; + + if (!data->valid) { + return -EIO; + } - return sprintf(buf, "%s\n", data->model_name); + if (attr->index == PSU_MODEL_NAME) { + ptr = data->model_name; + } + else { + return -EIO; + } + return sprintf(buf, "%s\n", ptr); } static const struct attribute_group as7726_32x_psu_group = { @@ -219,6 +236,62 @@ static int as7726_32x_psu_read_block(struct i2c_client *client, u8 command, u8 * return result; } +enum psu_type { + PSU_TYPE_AC_110V, + PSU_TYPE_DC_48V, + PSU_TYPE_DC_12V, + PSU_TYPE_AC_ACBEL_FSF019 +}; + +struct model_name_info { + enum psu_type type; + u8 offset; + u8 length; + u8 chk_length; + char* model_name; +}; + +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-"} +}; + +static int as7726_32x_psu_model_name_get(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7726_32x_psu_data *data = i2c_get_clientdata(client); + int i, status; + + for (i = 0; i < ARRAY_SIZE(models); i++) { + memset(data->model_name, 0, sizeof(data->model_name)); + + status = as7726_32x_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) { + return 0; + } + else { + data->model_name[0] = '\0'; + } + } + + return -ENODATA; +} + static struct as7726_32x_psu_data *as7726_32x_psu_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -231,6 +304,7 @@ static struct as7726_32x_psu_data *as7726_32x_psu_update_device(struct device *d int status; int power_good = 0; + data->valid = 0; dev_dbg(&client->dev, "Starting as7726_32x update\n"); /* Read psu status */ @@ -238,6 +312,7 @@ static struct as7726_32x_psu_data *as7726_32x_psu_update_device(struct device *d if (status < 0) { dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status); + goto exit; } else { data->status = status; @@ -248,14 +323,8 @@ static struct as7726_32x_psu_data *as7726_32x_psu_update_device(struct device *d power_good = (data->status >> (3-data->index) & 0x1); if (power_good) { - status = as7726_32x_psu_read_block(client, 0x20, data->model_name, - ARRAY_SIZE(data->model_name)-1); - if (status < 0) { - data->model_name[0] = '\0'; - dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr); - } - else { - data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0'; + if (as7726_32x_psu_model_name_get(dev) < 0) { + goto exit; } } @@ -263,6 +332,7 @@ static struct as7726_32x_psu_data *as7726_32x_psu_update_device(struct device *d data->valid = 1; } +exit: mutex_unlock(&data->update_lock); return data; From 64848d71ea92768c0355fe853bc97e195ea935dc Mon Sep 17 00:00:00 2001 From: Sean Wu Date: Tue, 13 Jul 2021 03:59:24 +0000 Subject: [PATCH 2/3] [Accton] Support ACBEL FSF045 PSU Signed-off-by: Sean Wu --- .../as7326-56x/modules/accton_as7326_56x_psu.c | 15 ++++++++------- .../as7712-32x/modules/accton_as7712_32x_psu.c | 15 ++++++++------- .../as7716-32x/modules/accton_as7716_32x_psu.c | 15 ++++++++------- .../as7726-32x/modules/accton_as7726_32x_psu.c | 15 ++++++++------- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c index 705b94887207..ef831bd365ce 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c @@ -240,22 +240,23 @@ enum psu_type { PSU_TYPE_AC_110V, PSU_TYPE_DC_48V, PSU_TYPE_DC_12V, - PSU_TYPE_AC_ACBEL_FSF019 + PSU_TYPE_AC_ACBEL_FSF019, + PSU_TYPE_AC_ACBEL_FSF045 }; struct model_name_info { enum psu_type type; u8 offset; u8 length; - u8 chk_length; char* model_name; }; 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_110V, 0x20, 8, "YM-2651Y"}, + {PSU_TYPE_DC_48V, 0x20, 8, "YM-2651V"}, + {PSU_TYPE_DC_12V, 0x00, 11, "PSU-12V-750"}, + {PSU_TYPE_AC_ACBEL_FSF019, 0x15, 10, "FSF019-"}, + {PSU_TYPE_AC_ACBEL_FSF045, 0x15, 10, "FSF045-"} }; static int as7326_56x_psu_model_name_get(struct device *dev) @@ -281,7 +282,7 @@ static int as7326_56x_psu_model_name_get(struct device *dev) /* 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 (strncmp(data->model_name, models[i].model_name, strlen(models[i].model_name)) == 0) { return 0; } else { diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_psu.c index edbad79fcbf5..7c611015cf8d 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_psu.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_psu.c @@ -240,22 +240,23 @@ enum psu_type { PSU_TYPE_AC_110V, PSU_TYPE_DC_48V, PSU_TYPE_DC_12V, - PSU_TYPE_AC_ACBEL_FSF019 + PSU_TYPE_AC_ACBEL_FSF019, + PSU_TYPE_AC_ACBEL_FSF045 }; struct model_name_info { enum psu_type type; u8 offset; u8 length; - u8 chk_length; char* model_name; }; 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_110V, 0x20, 8, "YM-2651Y"}, + {PSU_TYPE_DC_48V, 0x20, 8, "YM-2651V"}, + {PSU_TYPE_DC_12V, 0x00, 11, "PSU-12V-750"}, + {PSU_TYPE_AC_ACBEL_FSF019, 0x15, 10, "FSF019-"}, + {PSU_TYPE_AC_ACBEL_FSF045, 0x15, 10, "FSF045-"} }; static int as7712_32x_psu_model_name_get(struct device *dev) @@ -281,7 +282,7 @@ static int as7712_32x_psu_model_name_get(struct device *dev) /* 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 (strncmp(data->model_name, models[i].model_name, strlen(models[i].model_name)) == 0) { return 0; } else { diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_psu.c index 9d814d40cf58..7f5d8c2c8ccc 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_psu.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_psu.c @@ -249,22 +249,23 @@ enum psu_type { PSU_TYPE_AC_110V, PSU_TYPE_DC_48V, PSU_TYPE_DC_12V, - PSU_TYPE_AC_ACBEL_FSF019 + PSU_TYPE_AC_ACBEL_FSF019, + PSU_TYPE_AC_ACBEL_FSF045 }; struct model_name_info { enum psu_type type; u8 offset; u8 length; - u8 chk_length; char* model_name; }; 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_110V, 0x20, 8, "YM-2651Y"}, + {PSU_TYPE_DC_48V, 0x20, 8, "YM-2651V"}, + {PSU_TYPE_DC_12V, 0x00, 11, "PSU-12V-750"}, + {PSU_TYPE_AC_ACBEL_FSF019, 0x15, 10, "FSF019-"}, + {PSU_TYPE_AC_ACBEL_FSF045, 0x15, 10, "FSF045-"} }; static int as7716_32x_psu_model_name_get(struct device *dev) @@ -290,7 +291,7 @@ static int as7716_32x_psu_model_name_get(struct device *dev) /* 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 (strncmp(data->model_name, models[i].model_name, strlen(models[i].model_name)) == 0) { return 0; } else { diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_psu.c index c615df5664fa..a2ae40d2b4ea 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_psu.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_psu.c @@ -240,22 +240,23 @@ enum psu_type { PSU_TYPE_AC_110V, PSU_TYPE_DC_48V, PSU_TYPE_DC_12V, - PSU_TYPE_AC_ACBEL_FSF019 + PSU_TYPE_AC_ACBEL_FSF019, + PSU_TYPE_AC_ACBEL_FSF045 }; struct model_name_info { enum psu_type type; u8 offset; u8 length; - u8 chk_length; char* model_name; }; 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_110V, 0x20, 8, "YM-2651Y"}, + {PSU_TYPE_DC_48V, 0x20, 8, "YM-2651V"}, + {PSU_TYPE_DC_12V, 0x00, 11, "PSU-12V-750"}, + {PSU_TYPE_AC_ACBEL_FSF019, 0x15, 10, "FSF019-"}, + {PSU_TYPE_AC_ACBEL_FSF045, 0x15, 10, "FSF045-"} }; static int as7726_32x_psu_model_name_get(struct device *dev) @@ -281,7 +282,7 @@ static int as7726_32x_psu_model_name_get(struct device *dev) /* 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 (strncmp(data->model_name, models[i].model_name, strlen(models[i].model_name)) == 0) { return 0; } else { From c2893a444dc8b722273448ee8f81285be0c6aac2 Mon Sep 17 00:00:00 2001 From: Sean Wu Date: Tue, 14 Dec 2021 03:13:43 +0000 Subject: [PATCH 3/3] Add serial num sysfs node to PSU driver * Model: AS7726-32X, AS7326-56X Signed-off-by: Sean Wu --- .../modules/accton_as7326_56x_psu.c | 61 +++++++++++++++++++ .../modules/accton_as7726_32x_psu.c | 61 +++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c index ef831bd365ce..9dbd061c9e45 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c @@ -35,6 +35,7 @@ #include #define MAX_MODEL_NAME 16 +#define MAX_SERIAL_NUMBER 18 static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf); static int as7326_56x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); @@ -54,6 +55,7 @@ struct as7326_56x_psu_data { u8 index; /* PSU index */ u8 status; /* Status(present/power_good) register read from CPLD */ char model_name[MAX_MODEL_NAME+1]; /* Model name, read from eeprom */ + char serial_number[MAX_SERIAL_NUMBER+1]; }; static struct as7326_56x_psu_data *as7326_56x_psu_update_device(struct device *dev); @@ -61,6 +63,7 @@ static struct as7326_56x_psu_data *as7326_56x_psu_update_device(struct device *d enum as7326_56x_psu_sysfs_attributes { PSU_PRESENT, PSU_MODEL_NAME, + PSU_SERIAL_NUMBER, PSU_POWER_GOOD }; @@ -68,11 +71,13 @@ enum as7326_56x_psu_sysfs_attributes { */ static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_string, NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_serial_number, S_IRUGO, show_string, NULL, PSU_SERIAL_NUMBER); static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); static struct attribute *as7326_56x_psu_attributes[] = { &sensor_dev_attr_psu_present.dev_attr.attr, &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_serial_number.dev_attr.attr, &sensor_dev_attr_psu_power_good.dev_attr.attr, NULL }; @@ -112,6 +117,9 @@ static ssize_t show_string(struct device *dev, struct device_attribute *da, if (attr->index == PSU_MODEL_NAME) { ptr = data->model_name; } + else if (attr->index == PSU_SERIAL_NUMBER) { + ptr = data->serial_number; + } else { return -EIO; } @@ -251,6 +259,13 @@ struct model_name_info { char* model_name; }; +struct serial_number_info { + enum psu_type type; + u8 offset; + u8 length; + char* serial_number; +}; + struct model_name_info models[] = { {PSU_TYPE_AC_110V, 0x20, 8, "YM-2651Y"}, {PSU_TYPE_DC_48V, 0x20, 8, "YM-2651V"}, @@ -259,6 +274,14 @@ struct model_name_info models[] = { {PSU_TYPE_AC_ACBEL_FSF045, 0x15, 10, "FSF045-"} }; +struct serial_number_info serials[] = { + {PSU_TYPE_AC_110V, 0x2e, 18, "YM-2651Y"}, + {PSU_TYPE_DC_48V, 0x2e, 18, "YM-2651V"}, + {PSU_TYPE_DC_12V, 0x2e, 18, "PSU-12V-750"}, + {PSU_TYPE_AC_ACBEL_FSF019, 0x2e, 16, "FSF019-"}, + {PSU_TYPE_AC_ACBEL_FSF045, 0x2e, 16, "FSF045-"} +}; + static int as7326_56x_psu_model_name_get(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -293,6 +316,40 @@ static int as7326_56x_psu_model_name_get(struct device *dev) return -ENODATA; } +static int as7326_56x_psu_serial_number_get(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7326_56x_psu_data *data = i2c_get_clientdata(client); + int i, status; + + for (i = 0; i < ARRAY_SIZE(models); i++) { + memset(data->serial_number, 0, sizeof(data->serial_number)); + + status = as7326_56x_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_number from (0x%x) offset(0x%x)\n", + client->addr, serials[i].offset); + return status; + } + else { + data->serial_number[serials[i].length] = '\0'; + } + + /* Determine if the model name is known, if not, read next index + */ + if (strncmp(data->model_name, models[i].model_name, strlen(models[i].model_name)) == 0) { + return 0; + } + else { + data->serial_number[0] = '\0'; + } + } + + return -ENODATA; +} + static struct as7326_56x_psu_data *as7326_56x_psu_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -321,12 +378,16 @@ static struct as7326_56x_psu_data *as7326_56x_psu_update_device(struct device *d /* Read model name */ memset(data->model_name, 0, sizeof(data->model_name)); + memset(data->serial_number, 0, sizeof(data->serial_number)); power_good = (data->status >> (3-data->index) & 0x1); if (power_good) { if (as7326_56x_psu_model_name_get(dev) < 0) { goto exit; } + if (as7326_56x_psu_serial_number_get(dev) < 0) { + goto exit; + } } data->last_updated = jiffies; diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_psu.c index a2ae40d2b4ea..3736cc8da0b5 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_psu.c +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/modules/accton_as7726_32x_psu.c @@ -35,6 +35,7 @@ #include #define MAX_MODEL_NAME 16 +#define MAX_SERIAL_NUMBER 18 static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf); static int as7726_32x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); @@ -54,6 +55,7 @@ struct as7726_32x_psu_data { u8 index; /* PSU index */ u8 status; /* Status(present/power_good) register read from CPLD */ char model_name[MAX_MODEL_NAME+1]; /* Model name, read from eeprom */ + char serial_number[MAX_SERIAL_NUMBER+1]; }; static struct as7726_32x_psu_data *as7726_32x_psu_update_device(struct device *dev); @@ -61,6 +63,7 @@ static struct as7726_32x_psu_data *as7726_32x_psu_update_device(struct device *d enum as7726_32x_psu_sysfs_attributes { PSU_PRESENT, PSU_MODEL_NAME, + PSU_SERIAL_NUMBER, PSU_POWER_GOOD }; @@ -68,11 +71,13 @@ enum as7726_32x_psu_sysfs_attributes { */ static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_string, NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_serial_number, S_IRUGO, show_string, NULL, PSU_SERIAL_NUMBER); static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); static struct attribute *as7726_32x_psu_attributes[] = { &sensor_dev_attr_psu_present.dev_attr.attr, &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_serial_number.dev_attr.attr, &sensor_dev_attr_psu_power_good.dev_attr.attr, NULL }; @@ -112,6 +117,9 @@ static ssize_t show_string(struct device *dev, struct device_attribute *da, if (attr->index == PSU_MODEL_NAME) { ptr = data->model_name; } + else if (attr->index == PSU_SERIAL_NUMBER) { + ptr = data->serial_number; + } else { return -EIO; } @@ -251,6 +259,12 @@ struct model_name_info { char* model_name; }; +struct serial_number_info { + enum psu_type type; + u8 offset; + u8 length; + char* serial_number; +}; struct model_name_info models[] = { {PSU_TYPE_AC_110V, 0x20, 8, "YM-2651Y"}, {PSU_TYPE_DC_48V, 0x20, 8, "YM-2651V"}, @@ -259,6 +273,15 @@ struct model_name_info models[] = { {PSU_TYPE_AC_ACBEL_FSF045, 0x15, 10, "FSF045-"} }; +struct serial_number_info serials[] = { + {PSU_TYPE_AC_110V, 0x2e, 18, "YM-2651Y"}, + {PSU_TYPE_DC_48V, 0x2e, 18, "YM-2651V"}, + {PSU_TYPE_DC_12V, 0x2e, 18, "PSU-12V-750"}, + {PSU_TYPE_AC_ACBEL_FSF019, 0x2e, 16, "FSF019-"}, + {PSU_TYPE_AC_ACBEL_FSF045, 0x2e, 16, "FSF045-"} +}; + + static int as7726_32x_psu_model_name_get(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -293,6 +316,40 @@ static int as7726_32x_psu_model_name_get(struct device *dev) return -ENODATA; } +static int as7726_32x_psu_serial_number_get(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7726_32x_psu_data *data = i2c_get_clientdata(client); + int i, status; + + for (i = 0; i < ARRAY_SIZE(models); i++) { + memset(data->serial_number, 0, sizeof(data->serial_number)); + + status = as7726_32x_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_number from (0x%x) offset(0x%x)\n", + client->addr, serials[i].offset); + return status; + } + else { + data->serial_number[serials[i].length] = '\0'; + } + + /* Determine if the model name is known, if not, read next index + */ + if (strncmp(data->model_name, models[i].model_name, strlen(models[i].model_name)) == 0) { + return 0; + } + else { + data->serial_number[0] = '\0'; + } + } + + return -ENODATA; +} + static struct as7726_32x_psu_data *as7726_32x_psu_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -321,12 +378,16 @@ static struct as7726_32x_psu_data *as7726_32x_psu_update_device(struct device *d /* Read model name */ memset(data->model_name, 0, sizeof(data->model_name)); + memset(data->serial_number, 0, sizeof(data->serial_number)); power_good = (data->status >> (3-data->index) & 0x1); if (power_good) { if (as7726_32x_psu_model_name_get(dev) < 0) { goto exit; } + if (as7726_32x_psu_serial_number_get(dev) < 0) { + goto exit; + } } data->last_updated = jiffies;