From 02653d58029453ba4ee7e5307fdc30e3bbcea729 Mon Sep 17 00:00:00 2001 From: brandonchuang Date: Fri, 23 Dec 2016 14:36:23 +0800 Subject: [PATCH] [as7712] Support DC12V(PSU-12V-650)/DC48V(YM-2651V) power supply --- ...orm-accton-as7712_32x-device-drivers.patch | 245 +++++++++++++----- .../onlp/builds/src/module/src/fani.c | 92 +++++-- .../onlp/builds/src/module/src/platform_lib.c | 73 ++++-- .../onlp/builds/src/module/src/platform_lib.h | 7 +- .../onlp/builds/src/module/src/psui.c | 85 +++++- 5 files changed, 381 insertions(+), 121 deletions(-) diff --git a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as7712_32x-device-drivers.patch b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as7712_32x-device-drivers.patch index 8bba8fc5..41ff38bc 100644 --- a/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as7712_32x-device-drivers.patch +++ b/packages/base/any/kernels/3.2.65-1+deb7u2/patches/platform-accton-as7712_32x-device-drivers.patch @@ -44,10 +44,10 @@ index f8ee399..ea97f4a 100644 obj-$(CONFIG_SENSORS_AD7414) += ad7414.o diff --git a/drivers/hwmon/accton_as7712_32x_fan.c b/drivers/hwmon/accton_as7712_32x_fan.c new file mode 100644 -index 0000000..f2246e3 +index 0000000..74c577d --- /dev/null +++ b/drivers/hwmon/accton_as7712_32x_fan.c -@@ -0,0 +1,452 @@ +@@ -0,0 +1,491 @@ +/* + * A hwmon driver for the Accton as7712 32x fan + * @@ -93,6 +93,7 @@ index 0000000..f2246e3 + */ +static const u8 fan_reg[] = { + 0x0F, /* fan 1-6 present status */ ++ 0x10, /* fan 1-6 direction(0:B2F 1:F2B) */ + 0x11, /* fan PWM(for all fan) */ + 0x12, /* front fan 1 speed(rpm) */ + 0x13, /* front fan 2 speed(rpm) */ @@ -128,6 +129,7 @@ index 0000000..f2246e3 + +enum sysfs_fan_attributes { + FAN_PRESENT_REG, ++ FAN_DIRECTION_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, @@ -141,6 +143,12 @@ index 0000000..f2246e3 + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN6_REAR_SPEED_RPM, ++ FAN1_DIRECTION, ++ FAN2_DIRECTION, ++ FAN3_DIRECTION, ++ FAN4_DIRECTION, ++ FAN5_DIRECTION, ++ FAN6_DIRECTION, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, @@ -200,6 +208,13 @@ index 0000000..f2246e3 +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(5); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(6); ++/* 6 fan direction attribute in this platform */ ++DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); ++DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); ++DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); ++DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); ++DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); ++DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(6); +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); + @@ -223,6 +238,12 @@ index 0000000..f2246e3 + DECLARE_FAN_PRESENT_ATTR(4), + DECLARE_FAN_PRESENT_ATTR(5), + DECLARE_FAN_PRESENT_ATTR(6), ++ DECLARE_FAN_DIRECTION_ATTR(1), ++ DECLARE_FAN_DIRECTION_ATTR(2), ++ DECLARE_FAN_DIRECTION_ATTR(3), ++ DECLARE_FAN_DIRECTION_ATTR(4), ++ DECLARE_FAN_DIRECTION_ATTR(5), ++ DECLARE_FAN_DIRECTION_ATTR(6), + DECLARE_FAN_DUTY_CYCLE_ATTR(), + NULL +}; @@ -259,6 +280,14 @@ index 0000000..f2246e3 + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + ++static u8 reg_val_to_direction(u8 reg_val, enum fan_id id) ++{ ++ u8 mask = (1 << id); ++ ++ reg_val &= mask; ++ ++ return reg_val ? 1 : 0; ++} +static u8 reg_val_to_is_present(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); @@ -349,6 +378,16 @@ index 0000000..f2246e3 + case FAN6_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; ++ case FAN1_DIRECTION: ++ case FAN2_DIRECTION: ++ case FAN3_DIRECTION: ++ case FAN4_DIRECTION: ++ case FAN5_DIRECTION: ++ case FAN6_DIRECTION: ++ ret = sprintf(buf, "%d\n", ++ reg_val_to_direction(data->reg_val[FAN_DIRECTION_REG], ++ attr->index - FAN1_DIRECTION)); ++ break; + default: + break; + } @@ -480,10 +519,10 @@ index 0000000..f2246e3 + +static int __init as7712_32x_fan_init(void) +{ -+ extern int platform_accton_as7712_32x(void); -+ if (!platform_accton_as7712_32x()) { -+ return -ENODEV; -+ } ++ extern int platform_accton_as7712_32x(void); ++ if (!platform_accton_as7712_32x()) { ++ return -ENODEV; ++ } + + return i2c_add_driver(&as7712_32x_fan_driver); +} @@ -502,10 +541,10 @@ index 0000000..f2246e3 + diff --git a/drivers/hwmon/accton_as7712_32x_psu.c b/drivers/hwmon/accton_as7712_32x_psu.c new file mode 100644 -index 0000000..4574150 +index 0000000..f1f11f5 --- /dev/null +++ b/drivers/hwmon/accton_as7712_32x_psu.c -@@ -0,0 +1,293 @@ +@@ -0,0 +1,384 @@ +/* + * An hwmon driver for accton as7712_32x Power Module + * @@ -542,14 +581,18 @@ index 0000000..4574150 +#include +#include + ++#define MAX_MODEL_NAME 16 ++ ++#define DC12V_FAN_DIR_OFFSET 0x34 ++#define DC12V_FAN_DIR_LEN 3 ++ +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 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); + +/* 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 + */ @@ -560,27 +603,32 @@ index 0000000..4574150 + 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]; /* Model name, read from eeprom */ ++ char fan_dir[DC12V_FAN_DIR_LEN+1]; /* DC12V fan direction */ +}; + ++static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf); +static struct as7712_32x_psu_data *as7712_32x_psu_update_device(struct device *dev); + +enum as7712_32x_psu_sysfs_attributes { + PSU_PRESENT, + PSU_MODEL_NAME, -+ PSU_POWER_GOOD ++ PSU_POWER_GOOD, ++ PSU_FAN_DIR /* For DC12V only */ +}; + +/* 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_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); ++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_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); ++static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_string, NULL, PSU_FAN_DIR); + +static struct attribute *as7712_32x_psu_attributes[] = { + &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, ++ &sensor_dev_attr_psu_fan_dir.dev_attr.attr, + NULL +}; + @@ -591,6 +639,10 @@ index 0000000..4574150 + 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); + } @@ -601,12 +653,25 @@ index 0000000..4574150 + 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 { /* PSU_FAN_DIR */ ++ ptr = data->fan_dir; ++ } ++ ++ return sprintf(buf, "%s\n", ptr); +} + +static const struct attribute_group as7712_32x_psu_group = { @@ -703,30 +768,83 @@ index 0000000..4574150 +{ + int result = 0; + int retry_count = 5; -+ -+ 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); ++ ++ while (retry_count) { ++ retry_count--; ++ ++ result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); ++ ++ if (unlikely(result < 0)) { ++ msleep(10); + continue; + } -+ -+ result = 0; -+ break; -+ } -+ ++ ++ if (unlikely(result != data_len)) { ++ result = -EIO; ++ msleep(10); ++ continue; ++ } ++ ++ result = 0; ++ break; ++ } ++ + return result; +} + ++enum psu_type { ++ PSU_TYPE_AC_110V, ++ PSU_TYPE_DC_48V, ++ PSU_TYPE_DC_12V ++}; ++ ++struct model_name_info { ++ enum psu_type type; ++ u8 offset; ++ u8 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"}, ++}; ++ ++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].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); @@ -737,8 +855,9 @@ index 0000000..4574150 + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status; -+ int power_good = 0; ++ int power_good = 0; + ++ data->valid = 0; + dev_dbg(&client->dev, "Starting as7712_32x update\n"); + + /* Read psu status */ @@ -746,25 +865,35 @@ index 0000000..4574150 + + if (status < 0) { + dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status); ++ goto exit; + } + else { + data->status = status; + } -+ ++ + /* Read model name */ + memset(data->model_name, 0, sizeof(data->model_name)); ++ memset(data->fan_dir, 0, sizeof(data->fan_dir)); + 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); ++ if (power_good) { ++ if (as7712_32x_psu_model_name_get(dev) < 0) { ++ goto exit; + } -+ else { -+ data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0'; ++ ++ if (strncmp(data->model_name, ++ models[PSU_TYPE_DC_12V].model_name, ++ models[PSU_TYPE_DC_12V].length) == 0) { ++ /* Read fan direction */ ++ status = as7712_32x_psu_read_block(client, DC12V_FAN_DIR_OFFSET, ++ data->fan_dir, DC12V_FAN_DIR_LEN); ++ ++ if (status < 0) { ++ data->fan_dir[0] = '\0'; ++ dev_dbg(&client->dev, "unable to read fan direction from (0x%x) offset(0x%x)\n", ++ client->addr, DC12V_FAN_DIR_OFFSET); ++ goto exit; ++ } + } + } + @@ -772,6 +901,7 @@ index 0000000..4574150 + data->valid = 1; + } + ++exit: + mutex_unlock(&data->update_lock); + + return data; @@ -779,10 +909,10 @@ index 0000000..4574150 + +static int __init as7712_32x_psu_init(void) +{ -+ extern int platform_accton_as7712_32x(void); -+ if (!platform_accton_as7712_32x()) { -+ return -ENODEV; -+ } ++ extern int platform_accton_as7712_32x(void); ++ if (!platform_accton_as7712_32x()) { ++ return -ENODEV; ++ } + + return i2c_add_driver(&as7712_32x_psu_driver); +} @@ -803,7 +933,7 @@ diff --git a/drivers/hwmon/accton_i2c_cpld.c b/drivers/hwmon/accton_i2c_cpld.c index 96e3490..3aeb08d 100644 --- a/drivers/hwmon/accton_i2c_cpld.c +++ b/drivers/hwmon/accton_i2c_cpld.c -@@ -201,6 +201,29 @@ int platform_accton_as7512_32x(void) +@@ -201,6 +201,22 @@ int platform_accton_as7512_32x(void) } EXPORT_SYMBOL(platform_accton_as7512_32x); @@ -814,14 +944,7 @@ index 96e3490..3aeb08d 100644 + DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS7712"), + }, -+ }, -+ { -+ .ident = "Accton AS7712", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Accton"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "AS7712"), -+ }, -+ }, ++ } +}; + +int platform_accton_as7712_32x(void) diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/fani.c b/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/fani.c index cae38872..7e48d6da 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/fani.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/fani.c @@ -49,21 +49,23 @@ typedef struct fan_path_S { + char present[LEN_FILE_NAME]; char status[LEN_FILE_NAME]; char speed[LEN_FILE_NAME]; + char direction[LEN_FILE_NAME]; char ctrl_speed[LEN_FILE_NAME]; char r_speed[LEN_FILE_NAME]; }fan_path_T; #define _MAKE_FAN_PATH_ON_MAIN_BOARD(prj,id) \ - { #prj"fan"#id"_fault", #prj"fan"#id"_front_speed_rpm", \ - #prj"fan_duty_cycle_percentage", #prj"fan"#id"_rear_speed_rpm" } + { #prj"fan"#id"_present", #prj"fan"#id"_fault", #prj"fan"#id"_front_speed_rpm", \ + #prj"fan"#id"_direction", #prj"fan"#id"_duty_cycle_percentage", #prj"fan"#id"_rear_speed_rpm" } #define MAKE_FAN_PATH_ON_MAIN_BOARD(prj,id) _MAKE_FAN_PATH_ON_MAIN_BOARD(prj,id) #define MAKE_FAN_PATH_ON_PSU(folder) \ - {#folder"/psu_fan1_fault", #folder"/psu_fan1_speed_rpm", \ - #folder"/psu_fan1_duty_cycle_percentage", "" } + {"", #folder"/psu_fan1_fault", #folder"/psu_fan1_speed_rpm", \ + "", #folder"/psu_fan1_duty_cycle_percentage", "" } static fan_path_T fan_path[] = /* must map with onlp_fan_id */ { @@ -129,6 +131,39 @@ onlp_fan_info_t linfo[] = { if (close(fd) == -1) \ return ONLP_STATUS_E_INTERNAL +static uint32_t +_onlp_fani_info_get_psu_fan_direction(void) +{ + /* Try to read direction from PSU1. + * If PSU1 is not valid, read from PSU2 + */ + int i = 0; + + for (i = PSU1_ID; i <= PSU2_ID; i++) { + psu_type_t psu_type; + psu_type = get_psu_type(i, NULL, 0); + + if (psu_type == PSU_TYPE_UNKNOWN) { + continue; + } + + switch (psu_type) { + case PSU_TYPE_AC_F2B: + case PSU_TYPE_DC_48V_F2B: + case PSU_TYPE_DC_12V_F2B: + return ONLP_FAN_STATUS_F2B; + case PSU_TYPE_AC_B2F: + case PSU_TYPE_DC_48V_B2F: + case PSU_TYPE_DC_12V_B2F: + return ONLP_FAN_STATUS_B2F; + default: + return 0; + }; + } + + return 0; +} + static int _onlp_fani_info_get_fan(int local_id, onlp_fan_info_t* info) { @@ -136,14 +171,34 @@ _onlp_fani_info_get_fan(int local_id, onlp_fan_info_t* info) char r_data[10] = {0}; char fullpath[65] = {0}; + /* check if fan is present + */ + sprintf(fullpath, "%s%s", PREFIX_PATH_ON_MAIN_BOARD, fan_path[local_id].present); + OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len); + if (atoi(r_data) == 0) { + return ONLP_STATUS_OK; + } + info->status |= ONLP_FAN_STATUS_PRESENT; + /* get fan fault status (turn on when any one fails) */ sprintf(fullpath, "%s%s", PREFIX_PATH_ON_MAIN_BOARD, 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; + return ONLP_STATUS_OK; } + /* get fan/fanr direction (both : the same) + */ + sprintf(fullpath, "%s%s", PREFIX_PATH_ON_MAIN_BOARD, fan_path[local_id].direction); + OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len); + + if (atoi(r_data) == 0) /*B2F*/ + info->status |= ONLP_FAN_STATUS_B2F; + else + info->status |= ONLP_FAN_STATUS_F2B; + /* get fan speed (take the min from two speeds) */ sprintf(fullpath, "%s%s", PREFIX_PATH_ON_MAIN_BOARD, fan_path[local_id].speed); @@ -159,16 +214,11 @@ _onlp_fani_info_get_fan(int local_id, onlp_fan_info_t* info) /* get speed percentage from rpm */ info->percentage = (info->rpm * 100)/MAX_FAN_SPEED; - /* check present */ - if (info->rpm > 0) { - info->status |= ONLP_FAN_STATUS_PRESENT; - } - return ONLP_STATUS_OK; } static int -_onlp_fani_info_get_fan_on_psu(int local_id, int psu_id, onlp_fan_info_t* info) +_onlp_fani_info_get_fan_on_psu(int local_id, onlp_fan_info_t* info) { int fd, len, nbytes = 10; char r_data[10] = {0}; @@ -176,17 +226,7 @@ _onlp_fani_info_get_fan_on_psu(int local_id, int psu_id, onlp_fan_info_t* info) /* get fan direction */ - switch(get_psu_type(psu_id, NULL, 0)) - { - case PSU_TYPE_AC_F2B: - info->status |= ONLP_FAN_STATUS_F2B; - break; - case PSU_TYPE_AC_B2F: - info->status |= ONLP_FAN_STATUS_B2F; - break; - default: - break; - } + info->status |= _onlp_fani_info_get_psu_fan_direction(); /* get fan fault status */ @@ -227,12 +267,10 @@ onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info) *info = linfo[local_id]; switch (local_id) - { - case FAN_1_ON_PSU1: - rc = _onlp_fani_info_get_fan_on_psu(local_id, PSU1_ID, info); - break; + { + case FAN_1_ON_PSU1: case FAN_1_ON_PSU2: - rc = _onlp_fani_info_get_fan_on_psu(local_id, PSU2_ID, info); + rc = _onlp_fani_info_get_fan_on_psu(local_id, info); break; case FAN_1_ON_MAIN_BOARD: case FAN_2_ON_MAIN_BOARD: @@ -245,7 +283,7 @@ onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info) default: rc = ONLP_STATUS_E_INVALID; break; - } + } return rc; } diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/platform_lib.c b/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/platform_lib.c index 324d6075..b4ef2d04 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/platform_lib.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/platform_lib.c @@ -115,7 +115,7 @@ int deviceNodeReadString(char *filename, char *buffer, int buf_size, int data_le return ret; } -#define I2C_PSU_MODEL_NAME_LEN 9 +#define I2C_PSU_MODEL_NAME_LEN 11 #define I2C_PSU_FAN_DIR_LEN 3 #include psu_type_t get_psu_type(int id, char* modelname, int modelname_len) @@ -124,7 +124,6 @@ psu_type_t get_psu_type(int id, char* modelname, int modelname_len) char model_name[I2C_PSU_MODEL_NAME_LEN + 1] = {0}; char fan_dir[I2C_PSU_FAN_DIR_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); @@ -132,32 +131,70 @@ psu_type_t get_psu_type(int id, char* modelname, int modelname_len) return PSU_TYPE_UNKNOWN; } - - if (strncmp(model_name, "YM-2651Y", strlen("YM-2651Y")) != 0) { - return PSU_TYPE_UNKNOWN; - } - if(isspace(model_name[strlen(model_name)-1])) { model_name[strlen(model_name)-1] = 0; } - if (modelname) { - strncpy(modelname, model_name, modelname_len-1); + if (strncmp(model_name, "YM-2651Y", 8) == 0) { + if (modelname) { + strncpy(modelname, model_name, 8); + } + + node = (id == PSU1_ID) ? PSU1_AC_PMBUS_NODE(psu_fan_dir) : PSU2_AC_PMBUS_NODE(psu_fan_dir); + if (deviceNodeReadString(node, fan_dir, sizeof(fan_dir), 0) != 0) { + return PSU_TYPE_UNKNOWN; + } + + if (strncmp(fan_dir, "F2B", strlen("F2B")) == 0) { + return PSU_TYPE_AC_F2B; + } + + if (strncmp(fan_dir, "B2F", strlen("B2F")) == 0) { + return PSU_TYPE_AC_B2F; + } } - node = (id == PSU1_ID) ? PSU1_AC_PMBUS_NODE(psu_fan_dir) : PSU2_AC_PMBUS_NODE(psu_fan_dir); + if (strncmp(model_name, "YM-2651V", 8) == 0) { + if (modelname) { + strncpy(modelname, model_name, 8); + } - if (deviceNodeReadString(node, fan_dir, sizeof(fan_dir), 0) != 0) { - return PSU_TYPE_UNKNOWN; + node = (id == PSU1_ID) ? PSU1_AC_PMBUS_NODE(psu_fan_dir) : PSU2_AC_PMBUS_NODE(psu_fan_dir); + if (deviceNodeReadString(node, fan_dir, sizeof(fan_dir), 0) != 0) { + return PSU_TYPE_UNKNOWN; + } + + if (strncmp(fan_dir, "F2B", strlen("F2B")) == 0) { + return PSU_TYPE_DC_48V_F2B; + } + + if (strncmp(fan_dir, "B2F", strlen("B2F")) == 0) { + return PSU_TYPE_DC_48V_B2F; + } } - if (strncmp(fan_dir, "F2B", strlen("F2B")) == 0) { - return PSU_TYPE_AC_F2B; - } + if (strncmp(model_name, "PSU-12V-750", 11) == 0) { + if (modelname) { + strncpy(modelname, model_name, 11); + } - if (strncmp(fan_dir, "B2F", strlen("B2F")) == 0) { - return PSU_TYPE_AC_B2F; - } + node = (id == PSU1_ID) ? PSU1_AC_HWMON_NODE(psu_fan_dir) : PSU2_AC_HWMON_NODE(psu_fan_dir); + if (deviceNodeReadString(node, fan_dir, sizeof(fan_dir), 0) != 0) { + return PSU_TYPE_UNKNOWN; + } + + if (strncmp(fan_dir, "F2B", 3) == 0) { + return PSU_TYPE_DC_12V_F2B; + } + + if (strncmp(fan_dir, "B2F", 3) == 0) { + return PSU_TYPE_DC_12V_B2F; + } + + if (strncmp(fan_dir, "NON", 3) == 0) { + return PSU_TYPE_DC_12V_FANLESS; + } + } return PSU_TYPE_UNKNOWN; } diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/platform_lib.h b/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/platform_lib.h index d2a032b4..10c3f8d6 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/platform_lib.h +++ b/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/platform_lib.h @@ -55,7 +55,12 @@ 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_B2F, + PSU_TYPE_DC_48V_F2B, + PSU_TYPE_DC_48V_B2F, + PSU_TYPE_DC_12V_FANLESS, + PSU_TYPE_DC_12V_F2B, + PSU_TYPE_DC_12V_B2F } psu_type_t; psu_type_t get_psu_type(int id, char* modelname, int modelname_len); diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/psui.c b/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/psui.c index 3277077c..88c02f03 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/psui.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/module/src/psui.c @@ -68,7 +68,7 @@ psu_status_info_get(int id, char *node, int *value) } static int -psu_ym2651y_pmbus_info_get(int id, char *node, int *value) +psu_ym2651_pmbus_info_get(int id, char *node, int *value) { int ret = 0; char buf[PSU_NODE_MAX_INT_LEN + 1] = {0}; @@ -99,35 +99,31 @@ onlp_psui_init(void) } static int -psu_ym2651y_info_get(onlp_psu_info_t* info) +psu_ym2651_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; - } + + 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_ym2651y_pmbus_info_get(index, "psu_v_out", &val) == 0) { + if (psu_ym2651_pmbus_info_get(index, "psu_v_out", &val) == 0) { info->mvout = val; info->caps |= ONLP_PSU_CAPS_VOUT; } - if (psu_ym2651y_pmbus_info_get(index, "psu_i_out", &val) == 0) { + if (psu_ym2651_pmbus_info_get(index, "psu_i_out", &val) == 0) { info->miout = val; info->caps |= ONLP_PSU_CAPS_IOUT; } - if (psu_ym2651y_pmbus_info_get(index, "psu_p_out", &val) == 0) { + if (psu_ym2651_pmbus_info_get(index, "psu_p_out", &val) == 0) { info->mpout = val; info->caps |= ONLP_PSU_CAPS_POUT; } @@ -135,6 +131,56 @@ psu_ym2651y_info_get(onlp_psu_info_t* info) return ONLP_STATUS_OK; } +#include +#define DC12V_750_REG_TO_CURRENT(low, high) (((low << 4 | high >> 4) * 20 * 1000) / 754) +#define DC12V_750_REG_TO_VOLTAGE(low, high) ((low << 4 | high >> 4) * 25) + +static int +psu_dc12v_750_info_get(onlp_psu_info_t* info) +{ + int pid = ONLP_OID_ID_GET(info->hdr.id); + int bus = (PSU1_ID == pid) ? 11 : 10; + int iout_low, iout_high; + int vout_low, vout_high; + + /* Set capability + */ + info->caps = ONLP_PSU_CAPS_DC12; + + if (info->status & ONLP_PSU_STATUS_FAILED) { + return ONLP_STATUS_OK; + } + + /* Get current + */ + iout_low = onlp_i2c_readb(bus, 0x6f, 0x0, ONLP_I2C_F_FORCE); + iout_high = onlp_i2c_readb(bus, 0x6f, 0x1, ONLP_I2C_F_FORCE); + + if ((iout_low >= 0) && (iout_high >= 0)) { + info->miout = DC12V_750_REG_TO_CURRENT(iout_low, iout_high); + info->caps |= ONLP_PSU_CAPS_IOUT; + } + + /* Get voltage + */ + vout_low = onlp_i2c_readb(bus, 0x6f, 0x2, ONLP_I2C_F_FORCE); + vout_high = onlp_i2c_readb(bus, 0x6f, 0x3, ONLP_I2C_F_FORCE); + + if ((vout_low >= 0) && (vout_high >= 0)) { + info->mvout = DC12V_750_REG_TO_VOLTAGE(vout_low, vout_high); + info->caps |= ONLP_PSU_CAPS_VOUT; + } + + /* Get power based on current and voltage + */ + if ((info->caps & ONLP_PSU_CAPS_IOUT) && (info->caps & ONLP_PSU_CAPS_VOUT)) { + info->mpout = (info->miout * info->mvout) / 1000; + info->caps |= ONLP_PSU_CAPS_POUT; + } + + return ONLP_STATUS_OK; +} + /* * Get all information about the given PSU oid. */ @@ -191,7 +237,18 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) switch (psu_type) { case PSU_TYPE_AC_F2B: case PSU_TYPE_AC_B2F: - ret = psu_ym2651y_info_get(info); + info->caps = ONLP_PSU_CAPS_AC; + ret = psu_ym2651_info_get(info); + break; + case PSU_TYPE_DC_48V_F2B: + case PSU_TYPE_DC_48V_B2F: + info->caps = ONLP_PSU_CAPS_DC48; + ret = psu_ym2651_info_get(info); + break; + case PSU_TYPE_DC_12V_F2B: + case PSU_TYPE_DC_12V_B2F: + case PSU_TYPE_DC_12V_FANLESS: + ret = psu_dc12v_750_info_get(info); break; case PSU_TYPE_UNKNOWN: /* User insert a unknown PSU or unplugged.*/ info->status |= ONLP_PSU_STATUS_UNPLUGGED;