From ee1a53237df79957675cc3cfa627afa1e7905fdf Mon Sep 17 00:00:00 2001 From: brandonchuang Date: Wed, 14 Jun 2017 14:54:49 +0800 Subject: [PATCH] [as6812-32x] Support DC power and YM2401J AC power --- .../builds/x86-64-accton-as6812-32x-psu.c | 172 +++++++++++++----- .../onlp/builds/src/module/src/fani.c | 108 ++++++++--- .../onlp/builds/src/module/src/platform_lib.c | 130 +++++++++++-- .../onlp/builds/src/module/src/platform_lib.h | 40 ++-- .../onlp/builds/src/module/src/psui.c | 82 ++++++++- .../platform-config/Makefile | 1 + .../x86_64_accton_as6812_32x_r0/__init__.py | 9 +- 7 files changed, 435 insertions(+), 107 deletions(-) create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/platform-config/Makefile diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/modules/builds/x86-64-accton-as6812-32x-psu.c b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/modules/builds/x86-64-accton-as6812-32x-psu.c index dfee68b1..ead60143 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/modules/builds/x86-64-accton-as6812-32x-psu.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/modules/builds/x86-64-accton-as6812-32x-psu.c @@ -33,14 +33,22 @@ #include #include +#define PSU_STATUS_I2C_ADDR 0x60 +#define PSU_STATUS_I2C_REG_OFFSET 0x2 + +#define IS_POWER_GOOD(id, value) (!!(value & BIT(id*4 + 1))) +#define IS_PRESENT(id, value) (!(value & BIT(id*4))) + +static ssize_t show_index(struct device *dev, struct device_attribute *da, char *buf); 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 int as6812_32x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); extern int as6812_32x_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +static int as6812_32x_psu_model_name_get(struct device *dev); /* Addresses scanned */ -static const unsigned short normal_i2c[] = { 0x50, 0x53, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; /* Each client has this additional data */ @@ -57,6 +65,7 @@ struct as6812_32x_psu_data { static struct as6812_32x_psu_data *as6812_32x_psu_update_device(struct device *dev); enum as6812_32x_psu_sysfs_attributes { + PSU_INDEX, PSU_PRESENT, PSU_MODEL_NAME, PSU_POWER_GOOD @@ -64,17 +73,28 @@ enum as6812_32x_psu_sysfs_attributes { /* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_index, S_IRUGO, show_index, NULL, PSU_INDEX); 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_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); static struct attribute *as6812_32x_psu_attributes[] = { + &sensor_dev_attr_psu_index.dev_attr.attr, &sensor_dev_attr_psu_present.dev_attr.attr, &sensor_dev_attr_psu_model_name.dev_attr.attr, &sensor_dev_attr_psu_power_good.dev_attr.attr, NULL }; +static ssize_t show_index(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as6812_32x_psu_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", data->index); +} + static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf) { @@ -82,11 +102,15 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, struct as6812_32x_psu_data *data = as6812_32x_psu_update_device(dev); u8 status = 0; + if (!data->valid) { + return sprintf(buf, "0\n"); + } + if (attr->index == PSU_PRESENT) { - status = !(data->status >> ((data->index-1)*4) & 0x1); + status = IS_PRESENT(data->index, data->status); } else { /* PSU_POWER_GOOD */ - status = data->status >> ((data->index-1)*4 + 1) & 0x1; + status = IS_POWER_GOOD(data->index, data->status); } return sprintf(buf, "%d\n", status); @@ -96,7 +120,18 @@ static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf) { struct as6812_32x_psu_data *data = as6812_32x_psu_update_device(dev); - + + if (!data->valid) { + return 0; + } + + if (!IS_PRESENT(data->index, data->status)) { + return 0; + } + + if (as6812_32x_psu_model_name_get(dev) < 0) { + return -ENXIO; + } return sprintf(buf, "%s\n", data->model_name); } @@ -123,6 +158,7 @@ static int as6812_32x_psu_probe(struct i2c_client *client, i2c_set_clientdata(client, data); data->valid = 0; + data->index = dev_id->driver_data; mutex_init(&data->update_lock); dev_info(&client->dev, "chip found\n"); @@ -139,14 +175,6 @@ static int as6812_32x_psu_probe(struct i2c_client *client, goto exit_remove; } - /* Update PSU index */ - if (client->addr == 0x50 || client->addr == 0x38) { - data->index = 1; - } - else if (client->addr == 0x53 || client->addr == 0x3b) { - data->index = 2; - } - dev_info(&client->dev, "%s: psu '%s'\n", dev_name(data->hwmon_dev), client->name); @@ -172,8 +200,15 @@ static int as6812_32x_psu_remove(struct i2c_client *client) return 0; } +enum psu_index +{ + as6812_32x_psu1, + as6812_32x_psu2 +}; + static const struct i2c_device_id as6812_32x_psu_id[] = { - { "as6812_32x_psu", 0 }, + { "as6812_32x_psu1", as6812_32x_psu1 }, + { "as6812_32x_psu2", as6812_32x_psu2 }, {} }; MODULE_DEVICE_TABLE(i2c, as6812_32x_psu_id); @@ -218,6 +253,76 @@ static int as6812_32x_psu_read_block(struct i2c_client *client, u8 command, u8 * return result; } +enum psu_type { + PSU_YM_2401_JCR, /* AC110V - F2B */ + PSU_YM_2401_JDR, /* AC110V - B2F */ + PSU_CPR_4011_4M11, /* AC110V - F2B */ + PSU_CPR_4011_4M21, /* AC110V - B2F */ + PSU_CPR_6011_2M11, /* AC110V - F2B */ + PSU_CPR_6011_2M21, /* AC110V - B2F */ + PSU_UM400D_01G, /* DC48V - F2B */ + PSU_UM400D01_01G /* DC48V - B2F */ +}; + +struct model_name_info { + enum psu_type type; + u8 offset; + u8 length; + char* model_name; +}; + +struct model_name_info models[] = { +{PSU_YM_2401_JCR, 0x20, 11, "YM-2401JCR"}, +{PSU_YM_2401_JDR, 0x20, 11, "YM-2401JDR"}, +{PSU_CPR_4011_4M11, 0x26, 13, "CPR-4011-4M11"}, +{PSU_CPR_4011_4M21, 0x26, 13, "CPR-4011-4M21"}, +{PSU_CPR_6011_2M11, 0x26, 13, "CPR-6011-2M11"}, +{PSU_CPR_6011_2M21, 0x26, 13, "CPR-6011-2M21"}, +{PSU_UM400D_01G, 0x50, 9, "um400d01G"}, +{PSU_UM400D01_01G, 0x50, 12, "um400d01-01G"}, +}; + +static int as6812_32x_psu_model_name_get(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as6812_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 = as6812_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'; + } + + if (i == PSU_YM_2401_JCR || i == PSU_YM_2401_JDR) { + /* Skip the meaningless data byte 8*/ + data->model_name[8] = data->model_name[9]; + data->model_name[9] = data->model_name[10]; + data->model_name[10] = '\0'; + } + + /* 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) { + return 0; + } + else { + data->model_name[0] = '\0'; + } + } + + return -ENODATA; +} + static struct as6812_32x_psu_data *as6812_32x_psu_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -227,56 +332,27 @@ static struct as6812_32x_psu_data *as6812_32x_psu_update_device(struct device *d if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) { - int status; - int present = 0; + int status = -1; dev_dbg(&client->dev, "Starting as6812_32x update\n"); + data->valid = 0; /* Read psu status */ - status = as6812_32x_i2c_cpld_read(0x60, 0x2); + status = as6812_32x_i2c_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET); if (status < 0) { - dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status); + dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status); + goto exit; } else { data->status = status; } - - /* Read model name */ - memset(data->model_name, 0, sizeof(data->model_name)); - present = !(data->status >> ((data->index-1)*4) & 0x1); - if (present) { - u8 command; - int model_name_len = 0; - - if (client->addr == 0x38 || client->addr == 0x3b) { - /* cpr_4011_4mxx AC power */ - command = 0x26; - model_name_len = 13; - } - else { /* 0x50 & 0x53 */ - /* ym2651 AC power */ - command = 0x20; - model_name_len = 8; - } - - status = as6812_32x_psu_read_block(client,command,data->model_name, - model_name_len); - - 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[model_name_len] = '\0'; - } - } - data->last_updated = jiffies; data->valid = 1; } +exit: mutex_unlock(&data->update_lock); return data; diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/fani.c b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/fani.c index b08d45b4..2659e85a 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/fani.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/fani.c @@ -24,14 +24,15 @@ * ***********************************************************/ #include -#include +#include +#include #include #include "platform_lib.h" #define PREFIX_PATH_ON_MAIN_BOARD "/sys/devices/platform/as6812_32x_fan/" #define PREFIX_PATH_ON_PSU "/sys/bus/i2c/devices/" -#define MAX_FAN_SPEED 25500 +#define MAX_FAN_SPEED 18000 /* use the smaller max_speed of the 2 fans in a fantray */ #define MAX_PSU_FAN_SPEED 19328 #define PROJECT_NAME @@ -92,7 +93,7 @@ static fan_path_T fan_path[] = /* must map with onlp_fan_id */ { \ { ONLP_FAN_ID_CREATE(FAN_##fan_id##_ON_PSU##psu_id), "Chassis PSU-"#psu_id " Fan "#fan_id, 0 }, \ 0x0, \ - (ONLP_FAN_CAPS_SET_PERCENTAGE | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \ + 0, \ 0, \ 0, \ ONLP_FAN_MODE_INVALID, \ @@ -128,6 +129,22 @@ onlp_fan_info_t linfo[] = { if (close(fd) == -1) \ return ONLP_STATUS_E_INTERNAL +/* PSU relative marco */ +#define SET_PSU_TYPE_AC_F2B_FAN(info) \ + info->status |= (ONLP_FAN_STATUS_PRESENT | ONLP_FAN_STATUS_F2B); \ + info->caps |= ONLP_FAN_CAPS_SET_PERCENTAGE | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE + +#define SET_PSU_TYPE_AC_B2F_FAN(info) \ + info->status |= (ONLP_FAN_STATUS_PRESENT | ONLP_FAN_STATUS_B2F); \ + info->caps |= ONLP_FAN_CAPS_SET_PERCENTAGE | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE + +#define SET_PSU_TYPE_UM400D_F2B_FAN(info) \ + info->status |= (ONLP_FAN_STATUS_PRESENT | ONLP_FAN_STATUS_F2B) + +#define SET_PSU_TYPE_UM400D_B2F_FAN(info) \ + info->status |= (ONLP_FAN_STATUS_PRESENT | ONLP_FAN_STATUS_B2F) + + static int _onlp_fani_info_get_fan(int local_id, onlp_fan_info_t* info) { @@ -178,6 +195,22 @@ _onlp_fani_info_get_fan(int local_id, onlp_fan_info_t* info) return ONLP_STATUS_OK; } +static int +_onlp_fani_info_get_fan_on_psu_ym2401(int pid, onlp_fan_info_t* info) +{ + int val = 0; + + /* get fan status + */ + if (psu_ym2401_pmbus_info_get(pid, "psu_fan1_speed_rpm", &val) == ONLP_STATUS_OK) { + info->status |= (val > 0) ? 0 : ONLP_FAN_STATUS_FAILED; + info->rpm = val; + info->percentage = (info->rpm * 100) / 21600; + } + + return ONLP_STATUS_OK; +} + static int _onlp_fani_info_get_fan_on_psu(int local_id, onlp_fan_info_t* info) { @@ -197,32 +230,48 @@ _onlp_fani_info_get_fan_on_psu(int local_id, onlp_fan_info_t* info) switch (psu_type) { - case PSU_TYPE_AC_F2B: - info->status |= (ONLP_FAN_STATUS_PRESENT | ONLP_FAN_STATUS_F2B); + case PSU_TYPE_AC_COMPUWARE_F2B: + case PSU_TYPE_AC_3YPOWER_F2B: + SET_PSU_TYPE_AC_F2B_FAN(info); break; - case PSU_TYPE_AC_B2F: - info->status |= (ONLP_FAN_STATUS_PRESENT | ONLP_FAN_STATUS_B2F); + case PSU_TYPE_AC_COMPUWARE_B2F: + case PSU_TYPE_AC_3YPOWER_B2F: + SET_PSU_TYPE_AC_B2F_FAN(info); + break; + case PSU_TYPE_DC_48V_F2B: + SET_PSU_TYPE_UM400D_F2B_FAN(info); + break; + case PSU_TYPE_DC_48V_B2F: + SET_PSU_TYPE_UM400D_B2F_FAN(info); break; default: DEBUG_PRINT("[Debug][%s][%d][psu_type=%d]\n", __FUNCTION__, __LINE__, psu_type); break; } - /* get fan fault status - */ - sprintf(fullpath, "%s%s", PREFIX_PATH_ON_PSU, fan_path[local_id].status); - OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len); - if (atoi(r_data) > 0) - info->status |= ONLP_FAN_STATUS_FAILED; + if (psu_type == PSU_TYPE_AC_COMPUWARE_F2B || + psu_type == PSU_TYPE_AC_COMPUWARE_B2F ) + { + /* get fan fault status + */ + sprintf(fullpath, "%s%s", PREFIX_PATH_ON_PSU, fan_path[local_id].status); + OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len); + if (atoi(r_data) > 0) + info->status |= ONLP_FAN_STATUS_FAILED; + + /* get fan speed + */ + sprintf(fullpath, "%s%s", PREFIX_PATH_ON_PSU, fan_path[local_id].speed); + OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len); + info->rpm = atoi(r_data); - /* get fan speed - */ - sprintf(fullpath, "%s%s", PREFIX_PATH_ON_PSU, fan_path[local_id].speed); - OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len); - info->rpm = atoi(r_data); - - /* get speed percentage from rpm */ - info->percentage = (info->rpm * 100) / MAX_PSU_FAN_SPEED; - info->status |= ONLP_FAN_STATUS_PRESENT; + /* get speed percentage from rpm */ + info->percentage = (info->rpm * 100)/MAX_PSU_FAN_SPEED; + } + else if (psu_type == PSU_TYPE_AC_3YPOWER_F2B || + psu_type == PSU_TYPE_AC_3YPOWER_B2F ) + { + return _onlp_fani_info_get_fan_on_psu_ym2401(psu_id, info); + } return ONLP_STATUS_OK; } @@ -310,8 +359,21 @@ onlp_fani_percentage_set(onlp_oid_t id, int p) { case FAN_1_ON_PSU1: case FAN_1_ON_PSU2: - sprintf(fullpath, "%s%s", PREFIX_PATH_ON_PSU, fan_path[local_id].ctrl_speed); + { + int psu_id; + psu_type_t psu_type; + + psu_id = local_id - FAN_1_ON_PSU1 + 1; + psu_type = get_psu_type(psu_id, NULL, 0); + + if (psu_type == PSU_TYPE_AC_3YPOWER_F2B || + psu_type == PSU_TYPE_AC_3YPOWER_B2F ) { + return psu_ym2401_pmbus_info_set(psu_id, "psu_fan1_duty_cycle_percentage", p); + } + + sprintf(fullpath, "%s%s", PREFIX_PATH_ON_PSU, fan_path[local_id].ctrl_speed); break; + } case FAN_1_ON_MAIN_BOARD: case FAN_2_ON_MAIN_BOARD: case FAN_3_ON_MAIN_BOARD: diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/platform_lib.c b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/platform_lib.c index b8eadf4b..1591cddd 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/platform_lib.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/platform_lib.c @@ -23,12 +23,13 @@ * * ***********************************************************/ -#include #include #include #include #include #include +#include +#include #include #include "platform_lib.h" @@ -66,7 +67,7 @@ int deviceNodeWriteInt(char *filename, int value, int data_len) char buf[8] = {0}; sprintf(buf, "%d", value); - return deviceNodeWrite(filename, buf, strlen(buf), data_len); + return deviceNodeWrite(filename, buf, sizeof(buf)-1, data_len); } int deviceNodeReadBinary(char *filename, char *buffer, int buf_size, int data_len) @@ -102,20 +103,25 @@ int deviceNodeReadString(char *filename, char *buffer, int buf_size, int data_le { int ret; - if (data_len >= buf_size) { + if (data_len >= buf_size || data_len < 0) { return -1; } ret = deviceNodeReadBinary(filename, buffer, buf_size-1, data_len); if (ret == 0) { - buffer[buf_size-1] = '\0'; + if (data_len) { + buffer[data_len] = '\0'; + } + else { + buffer[buf_size-1] = '\0'; + } } - return ret; } #define I2C_PSU_MODEL_NAME_LEN 13 +#define STRLEN(x) (sizeof(x) - 1) psu_type_t get_psu_type(int id, char* modelname, int modelname_len) { @@ -123,22 +129,122 @@ psu_type_t get_psu_type(int id, char* modelname, int modelname_len) char model_name[I2C_PSU_MODEL_NAME_LEN + 1] = {0}; /* Check AC model name */ - node = (id == PSU1_ID) ? PSU1_AC_HWMON_NODE(psu_model_name) : PSU2_AC_HWMON_NODE(psu_model_name); + node = (id == PSU1_ID) ? PSU1_AC_EEPROM_NODE(psu_model_name) : PSU2_AC_EEPROM_NODE(psu_model_name); if (deviceNodeReadString(node, model_name, sizeof(model_name), 0) == 0) { - if (strncmp(model_name, "CPR-4011-4M11", strlen("CPR-4011-4M11")) == 0) { + if (strncmp(model_name, "CPR-4011-4M11", STRLEN("CPR-4011-4M11")) == 0) { if (modelname) { - strncpy(modelname, model_name, modelname_len-1); + strncpy(modelname, model_name, sizeof(model_name)); } - return PSU_TYPE_AC_F2B; + return PSU_TYPE_AC_COMPUWARE_F2B; } - else if (strncmp(model_name, "CPR-4011-4M21", strlen("CPR-4011-4M21")) == 0) { + else if (strncmp(model_name, "CPR-4011-4M21", STRLEN("CPR-4011-4M21")) == 0) { if (modelname) { - strncpy(modelname, model_name, modelname_len-1); + strncpy(modelname, model_name, sizeof(model_name)); } - return PSU_TYPE_AC_B2F; + return PSU_TYPE_AC_COMPUWARE_B2F; + } + else if (strncmp(model_name, "CPR-6011-2M11", STRLEN("CPR-6011-2M11")) == 0) { + if (modelname) { + strncpy(modelname, model_name, sizeof(model_name)); + } + return PSU_TYPE_AC_COMPUWARE_F2B; + } + else if (strncmp(model_name, "CPR-6011-2M21", STRLEN("CPR-6011-2M21")) == 0) { + if (modelname) { + strncpy(modelname, model_name, sizeof(model_name)); + } + return PSU_TYPE_AC_COMPUWARE_B2F; + } + } + + /* Check 3Y-Power AC model name */ + memset(model_name, 0, sizeof(model_name)); + node = (id == PSU1_ID) ? PSU1_AC_3YPOWER_EEPROM_NODE(psu_model_name) : PSU2_AC_3YPOWER_EEPROM_NODE(psu_model_name); + + if (deviceNodeReadString(node, model_name, sizeof(model_name), 0) == 0) { + if (strncmp(model_name, "YM-2401JCR", STRLEN("YM-2401JCR")) == 0) { + if (modelname) { + model_name[STRLEN("YM-2401JCR")] = 0; + strncpy(modelname, model_name, 11); + } + return PSU_TYPE_AC_3YPOWER_F2B; + } + else if (strncmp(model_name, "YM-2401JDR", STRLEN("YM-2401JDR")) == 0) { + if (modelname) { + model_name[STRLEN("YM-2401JDR")] = 0; + strncpy(modelname, model_name, 11); + } + return PSU_TYPE_AC_3YPOWER_B2F; + } + } + + /* Check DC model name */ + memset(model_name, 0, sizeof(model_name)); + node = (id == PSU1_ID) ? PSU1_DC_EEPROM_NODE(psu_model_name) : PSU2_DC_EEPROM_NODE(psu_model_name); + + if (deviceNodeReadString(node, model_name, sizeof(model_name), 0) == 0) { + if (strncmp(model_name, "um400d01G", STRLEN("um400d01G")) == 0) { + if (modelname) { + model_name[STRLEN("um400d01G")] = 0; + strncpy(modelname, model_name, 10); + } + return PSU_TYPE_DC_48V_B2F; + } + else if (strncmp(model_name, "um400d01-01G", STRLEN("um400d01-01G")) == 0) { + if (modelname) { + model_name[STRLEN("um400d01-01G")] = 0; + strncpy(modelname, model_name, 13); + } + return PSU_TYPE_DC_48V_F2B; } } return PSU_TYPE_UNKNOWN; } + +int psu_ym2401_pmbus_info_get(int id, char *node, int *value) +{ + int ret = 0; + char path[64] = {0}; + + *value = 0; + + if (PSU1_ID == id) { + sprintf(path, "%s%s", PSU1_AC_3YPOWER_PMBUS_PREFIX, node); + } + else { + sprintf(path, "%s%s", PSU2_AC_3YPOWER_PMBUS_PREFIX, node); + } + + if (onlp_file_read_int(value, path) < 0) { + AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", path); + return ONLP_STATUS_E_INTERNAL; + } + + return ret; +} + +int psu_ym2401_pmbus_info_set(int id, char *node, int value) +{ + char path[64] = {0}; + + switch (id) { + case PSU1_ID: + sprintf(path, "%s%s", PSU1_AC_3YPOWER_PMBUS_PREFIX, node); + break; + case PSU2_ID: + sprintf(path, "%s%s", PSU2_AC_3YPOWER_PMBUS_PREFIX, node); + break; + default: + return ONLP_STATUS_E_UNSUPPORTED; + }; + + if (deviceNodeWriteInt(path, value, 0) < 0) { + AIM_LOG_ERROR("Unable to write data to file (%s)\r\n", path); + return ONLP_STATUS_E_INTERNAL; + } + + return ONLP_STATUS_OK; +} + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/platform_lib.h b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/platform_lib.h index 44edfb20..77a1aec4 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/platform_lib.h +++ b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/platform_lib.h @@ -36,17 +36,24 @@ #define PSU1_ID 1 #define PSU2_ID 2 -#define PSU1_AC_PMBUS_PREFIX "/sys/bus/i2c/devices/35-003c/" -#define PSU2_AC_PMBUS_PREFIX "/sys/bus/i2c/devices/36-003f/" +#define PSU1_AC_PMBUS_PREFIX "/sys/bus/i2c/devices/35-003c/" /* Compuware psu */ +#define PSU2_AC_PMBUS_PREFIX "/sys/bus/i2c/devices/36-003f/" /* Compuware psu */ +#define PSU1_AC_3YPOWER_PMBUS_PREFIX "/sys/bus/i2c/devices/35-0058/" /* 3YPower psu */ +#define PSU2_AC_3YPOWER_PMBUS_PREFIX "/sys/bus/i2c/devices/36-005b/" /* 3YPower psu */ -#define PSU1_AC_PMBUS_NODE(node) PSU1_AC_PMBUS_PREFIX#node -#define PSU2_AC_PMBUS_NODE(node) PSU2_AC_PMBUS_PREFIX#node +#define PSU1_AC_EEPROM_PREFIX "/sys/bus/i2c/devices/35-0038/" +#define PSU1_DC_EEPROM_PREFIX "/sys/bus/i2c/devices/35-0050/" +#define PSU2_AC_EEPROM_PREFIX "/sys/bus/i2c/devices/36-003b/" +#define PSU2_DC_EEPROM_PREFIX "/sys/bus/i2c/devices/36-0053/" +#define PSU1_AC_3YPOWER_EEPROM_PREFIX "/sys/bus/i2c/devices/35-0050/" +#define PSU2_AC_3YPOWER_EEPROM_PREFIX "/sys/bus/i2c/devices/36-0053/" -#define PSU1_AC_HWMON_PREFIX "/sys/bus/i2c/devices/35-0038/" -#define PSU2_AC_HWMON_PREFIX "/sys/bus/i2c/devices/36-003b/" - -#define PSU1_AC_HWMON_NODE(node) PSU1_AC_HWMON_PREFIX#node -#define PSU2_AC_HWMON_NODE(node) PSU2_AC_HWMON_PREFIX#node +#define PSU1_AC_EEPROM_NODE(node) PSU1_AC_EEPROM_PREFIX#node +#define PSU1_DC_EEPROM_NODE(node) PSU1_DC_EEPROM_PREFIX#node +#define PSU2_AC_EEPROM_NODE(node) PSU2_AC_EEPROM_PREFIX#node +#define PSU2_DC_EEPROM_NODE(node) PSU2_DC_EEPROM_PREFIX#node +#define PSU1_AC_3YPOWER_EEPROM_NODE(node) PSU1_AC_3YPOWER_EEPROM_PREFIX#node +#define PSU2_AC_3YPOWER_EEPROM_NODE(node) PSU2_AC_3YPOWER_EEPROM_PREFIX#node #define IDPROM_PATH "/sys/class/i2c-adapter/i2c-1/1-0057/eeprom" @@ -56,18 +63,25 @@ int deviceNodeReadString(char *filename, char *buffer, int buf_size, int data_le typedef enum psu_type { PSU_TYPE_UNKNOWN, - PSU_TYPE_AC_F2B, - PSU_TYPE_AC_B2F + PSU_TYPE_AC_COMPUWARE_F2B, + PSU_TYPE_AC_COMPUWARE_B2F, + PSU_TYPE_AC_3YPOWER_F2B, + PSU_TYPE_AC_3YPOWER_B2F, + PSU_TYPE_DC_48V_F2B, + PSU_TYPE_DC_48V_B2F } psu_type_t; psu_type_t get_psu_type(int id, char* modelname, int modelname_len); +int psu_ym2401_pmbus_info_get(int id, char *node, int *value); +int psu_ym2401_pmbus_info_set(int id, char *node, int value); #define DEBUG_MODE 0 #if (DEBUG_MODE == 1) - #define DEBUG_PRINT(format, ...) printf(format, __VA_ARGS__) + #define DEBUG_PRINT(fmt, args...) \ + printf("%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) #else - #define DEBUG_PRINT(format, ...) + #define DEBUG_PRINT(fmt, args...) #endif #endif /* __PLATFORM_LIB_H__ */ diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/psui.c b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/psui.c index 66d83e62..cfaffbaf 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/psui.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/module/src/psui.c @@ -24,7 +24,6 @@ * ***********************************************************/ #include -#include #include #include #include "platform_lib.h" @@ -43,7 +42,7 @@ } while(0) static int -psu_status_info_get(int id, char *node, int *value) +psu_status_info_get(int id, int is_ac, char *node, int *value) { int ret = 0; char buf[PSU_NODE_MAX_INT_LEN + 1] = {0}; @@ -52,12 +51,12 @@ psu_status_info_get(int id, char *node, int *value) *value = 0; if (PSU1_ID == id) { - sprintf(node_path, "%s%s", PSU1_AC_HWMON_PREFIX, node); + sprintf(node_path, "%s%s", is_ac ? PSU1_AC_EEPROM_PREFIX : PSU1_DC_EEPROM_PREFIX, node); } else if (PSU2_ID == id) { - sprintf(node_path, "%s%s", PSU2_AC_HWMON_PREFIX, node); + sprintf(node_path, "%s%s", is_ac ? PSU2_AC_EEPROM_PREFIX : PSU2_DC_EEPROM_PREFIX, node); } - + ret = deviceNodeReadString(node_path, buf, sizeof(buf), 0); if (ret == 0) { @@ -150,6 +149,62 @@ psu_cpr_4011_info_get(onlp_psu_info_t* info) return ONLP_STATUS_OK; } +int +psu_um400d_info_get(onlp_psu_info_t* info) +{ + int index = ONLP_OID_ID_GET(info->hdr.id); + + /* Set capability + */ + info->caps = ONLP_PSU_CAPS_DC48; + + if (info->status & ONLP_PSU_STATUS_FAILED) { + return ONLP_STATUS_OK; + } + + /* Set the associated oid_table */ + info->hdr.coids[0] = ONLP_FAN_ID_CREATE(index + CHASSIS_FAN_COUNT); + + return ONLP_STATUS_OK; +} + +static int +psu_ym2401_info_get(onlp_psu_info_t* info) +{ + int val = 0; + int index = ONLP_OID_ID_GET(info->hdr.id); + + /* Set capability + */ + info->caps = ONLP_PSU_CAPS_AC; + + if (info->status & ONLP_PSU_STATUS_FAILED) { + return ONLP_STATUS_OK; + } + + /* Set the associated oid_table */ + info->hdr.coids[0] = ONLP_FAN_ID_CREATE(index + CHASSIS_FAN_COUNT); + info->hdr.coids[1] = ONLP_THERMAL_ID_CREATE(index + CHASSIS_THERMAL_COUNT); + + /* Read voltage, current and power */ + if (psu_ym2401_pmbus_info_get(index, "psu_v_out", &val) == 0) { + info->mvout = val; + info->caps |= ONLP_PSU_CAPS_VOUT; + } + + if (psu_ym2401_pmbus_info_get(index, "psu_i_out", &val) == 0) { + info->miout = val; + info->caps |= ONLP_PSU_CAPS_IOUT; + } + + if (psu_ym2401_pmbus_info_get(index, "psu_p_out", &val) == 0) { + info->mpout = val; + info->caps |= ONLP_PSU_CAPS_POUT; + } + + return ONLP_STATUS_OK; +} + /* * Get all information about the given PSU oid. */ @@ -178,7 +233,7 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) *info = pinfo[index]; /* Set the onlp_oid_hdr_t */ /* Get the present state */ - if (psu_status_info_get(index, "psu_present", &val) != 0) { + if (psu_status_info_get(index, 1, "psu_present", &val) != 0) { printf("Unable to read PSU(%d) node(psu_present)\r\n", index); } @@ -190,12 +245,13 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) /* Get power good status */ - if (psu_status_info_get(index, "psu_power_good", &val) != 0) { + if (psu_status_info_get(index, 1, "psu_power_good", &val) != 0) { printf("Unable to read PSU(%d) node(psu_power_good)\r\n", index); } if (val != PSU_STATUS_POWER_GOOD) { info->status |= ONLP_PSU_STATUS_FAILED; + return 0; } @@ -204,10 +260,18 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) psu_type = get_psu_type(index, info->model, sizeof(info->model)); switch (psu_type) { - case PSU_TYPE_AC_F2B: - case PSU_TYPE_AC_B2F: + case PSU_TYPE_AC_COMPUWARE_F2B: + case PSU_TYPE_AC_COMPUWARE_B2F: ret = psu_cpr_4011_info_get(info); break; + case PSU_TYPE_AC_3YPOWER_F2B: + case PSU_TYPE_AC_3YPOWER_B2F: + ret = psu_ym2401_info_get(info); + break; + case PSU_TYPE_DC_48V_F2B: + case PSU_TYPE_DC_48V_B2F: + ret = psu_um400d_info_get(info); + break; default: ret = ONLP_STATUS_E_UNSUPPORTED; break; diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/platform-config/Makefile b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/platform-config/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/platform-config/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/platform-config/r0/src/python/x86_64_accton_as6812_32x_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/platform-config/r0/src/python/x86_64_accton_as6812_32x_r0/__init__.py index edc5c26a..66e8f002 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/platform-config/r0/src/python/x86_64_accton_as6812_32x_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/platform-config/r0/src/python/x86_64_accton_as6812_32x_r0/__init__.py @@ -9,6 +9,7 @@ class OnlPlatform_x86_64_accton_as6812_32x_r0(OnlPlatformAccton, def baseconfig(self): self.insmod('cpr_4011_4mxx') + self.insmod("ym2651y") for m in [ 'cpld', 'fan', 'psu', 'leds', 'sfp' ]: self.insmod("x86-64-accton-as6812-32x-%s.ko" % m) @@ -35,12 +36,16 @@ class OnlPlatform_x86_64_accton_as6812_32x_r0(OnlPlatformAccton, ('pca9548', 0x70, 1), # initiate PSU-1 - ('as6812_32x_psu', 0x38, 35), + ('as6812_32x_psu1', 0x38, 35), ('cpr_4011_4mxx', 0x3C, 35), + ('as6812_32x_psu1', 0x50, 35), + ('ym2401', 0x58, 35), # initiate PSU-2 - ('as6812_32x_psu', 0x3b, 36), + ('as6812_32x_psu2', 0x3b, 36), ('cpr_4011_4mxx', 0x3F, 36), + ('as6812_32x_psu2', 0x53, 36), + ('ym2401', 0x5b, 36), # initiate lm75 ('lm75', 0x48, 38),