From 9967b159232ae13b5c03ba6e6aa0884c0905bb40 Mon Sep 17 00:00:00 2001 From: Jeff Chen Date: Thu, 22 Nov 2018 13:39:01 +0800 Subject: [PATCH] [platform] delta new model agc7648sv1 --- .../x86-64/x86-64-delta-agc7648sv1/Makefile | 1 + .../x86-64-delta-agc7648sv1/modules/Makefile | 1 + .../x86-64-delta-agc7648sv1/modules/PKG.yml | 1 + .../modules/builds/Makefile | 7 + .../builds/delta_agc7648sv1_platform.c | 3332 +++++++++++++++++ .../modules/builds/dni_agc7648sv1_psu.c | 495 +++ .../modules/builds/dni_emc2305.c | 381 ++ .../modules/builds/tmp401.c | 796 ++++ .../x86-64-delta-agc7648sv1/onlp/Makefile | 1 + .../x86-64-delta-agc7648sv1/onlp/PKG.yml | 1 + .../onlp/builds/Makefile | 2 + .../onlp/builds/lib/Makefile | 45 + .../lib/libonlp-x86-64-delta-agc7648sv1-r0.mk | 10 + .../onlp/builds/onlpdump/Makefile | 46 + .../onlp/builds/src/.module | 1 + .../onlp/builds/src/Makefile | 10 + .../onlp/builds/src/module/auto/make.mk | 10 + .../module/auto/x86_64_delta_agc7648sv1.yml | 55 + .../x86_64_delta_agc7648sv1.x | 16 + .../x86_64_delta_agc7648sv1_config.h | 157 + .../x86_64_delta_agc7648sv1_dox.h | 26 + .../x86_64_delta_agc7648sv1_porting.h | 107 + .../onlp/builds/src/module/make.mk | 10 + .../onlp/builds/src/module/src/Makefile | 9 + .../onlp/builds/src/module/src/fani.c | 428 +++ .../onlp/builds/src/module/src/ledi.c | 503 +++ .../onlp/builds/src/module/src/make.mk | 9 + .../onlp/builds/src/module/src/platform_lib.c | 498 +++ .../onlp/builds/src/module/src/platform_lib.h | 221 ++ .../onlp/builds/src/module/src/psui.c | 320 ++ .../onlp/builds/src/module/src/sfpi.c | 467 +++ .../onlp/builds/src/module/src/sysi.c | 354 ++ .../onlp/builds/src/module/src/thermali.c | 227 ++ .../src/x86_64_delta_agc7648sv1_config.c | 91 + .../src/x86_64_delta_agc7648sv1_enums.c | 10 + .../module/src/x86_64_delta_agc7648sv1_int.h | 12 + .../module/src/x86_64_delta_agc7648sv1_log.c | 18 + .../module/src/x86_64_delta_agc7648sv1_log.h | 12 + .../src/x86_64_delta_agc7648sv1_module.c | 24 + .../module/src/x86_64_delta_agc7648sv1_ucli.c | 50 + .../platform-config/Makefile | 1 + .../platform-config/r0/Makefile | 1 + .../platform-config/r0/PKG.yml | 2 + .../r0/src/lib/x86-64-delta-agc7648sv1-r0.yml | 30 + .../x86_64_delta_agc7648sv1_r0/__init__.py | 32 + 45 files changed, 8830 insertions(+) create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/Makefile create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/Makefile create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/PKG.yml create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/Makefile create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/delta_agc7648sv1_platform.c create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/dni_agc7648sv1_psu.c create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/dni_emc2305.c create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/tmp401.c create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/Makefile create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/PKG.yml create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/Makefile create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/lib/Makefile create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/lib/libonlp-x86-64-delta-agc7648sv1-r0.mk create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/onlpdump/Makefile create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/.module create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/Makefile create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/auto/make.mk create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/auto/x86_64_delta_agc7648sv1.yml create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1.x create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1_config.h create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1_dox.h create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1_porting.h create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/make.mk create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/Makefile create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/fani.c create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/ledi.c create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/make.mk create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/platform_lib.c create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/platform_lib.h create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/psui.c create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/sfpi.c create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/sysi.c create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/thermali.c create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_config.c create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_enums.c create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_int.h create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_log.c create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_log.h create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_module.c create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_ucli.c create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/Makefile create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/Makefile create mode 100644 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/PKG.yml create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/src/lib/x86-64-delta-agc7648sv1-r0.yml create mode 100755 packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/src/python/x86_64_delta_agc7648sv1_r0/__init__.py diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/Makefile b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/Makefile b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/PKG.yml b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/PKG.yml new file mode 100644 index 00000000..bd7254d1 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/PKG.yml @@ -0,0 +1 @@ +!include $ONL_TEMPLATES/platform-modules.yml VENDOR=delta BASENAME=x86-64-delta-agc7648sv1 ARCH=amd64 KERNELS="onl-kernel-4.9-lts-x86-64-all:amd64" diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/Makefile b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/Makefile new file mode 100644 index 00000000..6656aa61 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/Makefile @@ -0,0 +1,7 @@ +KERNELS := onl-kernel-4.9-lts-x86-64-all:amd64 +KMODULES := $(wildcard *.c) +VENDOR := delta +BASENAME := x86-64-delta-agc7648sv1 +ARCH := x86_64 +include $(ONL)/make/kmodule.mk + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/delta_agc7648sv1_platform.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/delta_agc7648sv1_platform.c new file mode 100755 index 00000000..72a7a61a --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/delta_agc7648sv1_platform.c @@ -0,0 +1,3332 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CPUPLD_ADDR 0x31 +#define SWPLD1_ADDR 0x6a +#define SWPLD2_ADDR 0x75 +#define SWPLD3_ADDR 0x73 +#define DEFAULT_CPLD 0 + +#define MUX_VAL_SERDES_SWPLD3 0xFF +#define MUX_VAL_IDEEPROM 0xFC +#define MUX_VAL_PCA9547 0xFD + +#define MUX_VAL_FAN1_EEPROM 0x00 +#define MUX_VAL_FAN2_EEPROM 0x01 +#define MUX_VAL_FAN3_EEPROM 0x02 +#define MUX_VAL_FAN4_EEPROM 0x03 +#define MUX_VAL_FAN_CTL 0x05 +#define MUX_VAL_FAN_TMP75 0x06 +#define MUX_VAL_FAN_IO_CTL 0x07 + +#define MUX_VAL_PSU1 0x00 +#define MUX_VAL_PSU2 0x02 + +#define DEF_DEV_NUM 1 +#define BUS0_DEV_NUM 3 +#define BUS0_BASE_NUM 1 +#define BUS0_MUX_REG 0x14 + +#define BUS2_QSFP_DEV_NUM 6 +#define BUS2_QSFP_BASE_NUM 41 +#define BUS2_QSFP_MUX_REG 0x20 +#define BUS2_SFP_DEV_NUM 48 +#define BUS2_SFP_BASE_NUM 51 +#define BUS2_SFP_MUX_REG 0x21 +#define BUS5_DEV_NUM 7 +#define BUS5_BASE_NUM 21 +#define BUS5_MUX_REG 0x67 + +#define BUS6_DEV_NUM 2 +#define BUS6_BASE_NUM 31 +#define BUS6_MUX_REG 0x1f + +/* on SWPLD3 */ +#define SWPLD3_SFP_CH1_EN 0x00 +#define SWPLD3_SFP_CH2_EN 0x01 +#define SWPLD3_SFP_CH3_EN 0x02 +#define SWPLD3_SFP_CH4_EN 0x03 +#define SWPLD3_SFP_CH5_EN 0x04 +#define SWPLD3_SFP_CH6_EN 0x05 +#define SWPLD3_QSFP_CH_EN 0x06 +#define SWPLD3_SFP_CH_DISABLE 0x07 + +#define SWPLD3_SFP_PORT_9 9 +#define SWPLD3_SFP_PORT_19 19 +#define SWPLD3_SFP_PORT_29 29 +#define SWPLD3_SFP_PORT_39 39 +#define SWPLD3_SFP_PORT_48 48 + +/* on SWPLD2 */ +#define SFP_PRESENCE_1 0x30 +#define SFP_PRESENCE_2 0x31 +#define SFP_PRESENCE_3 0x32 +#define SFP_PRESENCE_4 0x33 +#define SFP_PRESENCE_5 0x34 +#define SFP_PRESENCE_6 0x35 +#define SFP_RXLOS_1 0x36 +#define SFP_RXLOS_2 0x37 +#define SFP_RXLOS_3 0x38 +#define SFP_RXLOS_4 0x39 +#define SFP_RXLOS_5 0x3A +#define SFP_RXLOS_6 0x3B +#define SFP_TXDIS_1 0x3C +#define SFP_TXDIS_2 0x3D +#define SFP_TXDIS_3 0x3E +#define SFP_TXDIS_4 0x3F +#define SFP_TXDIS_5 0x40 +#define SFP_TXDIS_6 0x41 +#define SFP_TXFAULT_1 0x42 +#define SFP_TXFAULT_2 0x43 +#define SFP_TXFAULT_3 0x44 +#define SFP_TXFAULT_4 0x45 +#define SFP_TXFAULT_5 0x46 +#define SFP_TXFAULT_6 0x47 + +/* on SWPLD1 */ +#define QSFP_PRESENCE 0x63 +#define QSFP_LPMODE 0x62 +#define QSFP_RESET 0x3c + +#define SWPLD1_QSFP_MODSEL_REG 0x64 +#define SWPLD1_QSFP_MODSEL_VAL 0x3f + +/* BMC IMPI CMD */ +#define IPMI_MAX_INTF (4) +#define DELTA_NETFN 0x38 +#define CMD_SETDATA 0x03 +#define CMD_GETDATA 0x02 +#define CMD_DIAGMODE 0x1a +#define BMC_DIAG_STATE 0x00 +#define BMC_ERR (-6) +#define BMC_NOT_EXIST 0xc1 +#define BMC_SWPLD_BUS 2 + + +/* Check cpld read results */ +#define VALIDATED_READ(_buf, _rv, _read, _invert) \ + do { \ + _rv = _read; \ + if (_rv < 0) { \ + return sprintf(_buf, "READ ERROR\n"); \ + } \ + if (_invert) { \ + _rv = ~_rv; \ + } \ + _rv &= 0xFF; \ + } while(0) \ + +struct mutex dni_lock; + +extern int dni_bmc_cmd(char set_cmd, char *cmd_data, int cmd_data_len); +extern int dni_create_user(void); +extern unsigned char dni_log2(unsigned char num); +extern int dni_bmc_exist_check(void); +extern void device_release(struct device *dev); +extern void msg_handler(struct ipmi_recv_msg *recv_msg,void* handler_data); +extern void dummy_smi_free(struct ipmi_smi_msg *msg); +extern void dummy_recv_free(struct ipmi_recv_msg *msg); + +static ipmi_user_t ipmi_mh_user = NULL; +static struct ipmi_user_hndl ipmi_hndlrs = { .ipmi_recv_hndl = msg_handler, }; +static atomic_t dummy_count = ATOMIC_INIT(0); + +static struct ipmi_smi_msg halt_smi_msg = { + .done = dummy_smi_free +}; + +static struct ipmi_recv_msg halt_recv_msg = { + .done = dummy_recv_free +}; + +void device_release(struct device *dev) +{ + return; +} +EXPORT_SYMBOL(device_release); + +void msg_handler(struct ipmi_recv_msg *recv_msg, void* handler_data) +{ + struct completion *comp = recv_msg->user_msg_data; + if (comp) + complete(comp); + else + ipmi_free_recv_msg(recv_msg); + return; +} +EXPORT_SYMBOL(msg_handler); + +void dummy_smi_free(struct ipmi_smi_msg *msg) +{ + atomic_dec(&dummy_count); +} +EXPORT_SYMBOL(dummy_smi_free); + +void dummy_recv_free(struct ipmi_recv_msg *msg) +{ + atomic_dec(&dummy_count); +} +EXPORT_SYMBOL(dummy_recv_free); + +int dni_bmc_exist_check(void) +{ + uint8_t set_cmd; + uint8_t cmd_data[1] = {0}; + int cmd_data_len, rv = 0; + + set_cmd = CMD_DIAGMODE; + cmd_data[0] = BMC_DIAG_STATE; + cmd_data_len = sizeof(cmd_data); + rv = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + return rv; +} +EXPORT_SYMBOL(dni_bmc_exist_check); + +unsigned char dni_log2 (unsigned char num){ + unsigned char num_log2 = 0; + while(num > 0){ + num = num >> 1; + num_log2 += 1; + } + return num_log2 -1; +} +EXPORT_SYMBOL(dni_log2); + +enum{ + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, + BUS8, + BUS9, + BUS10, + BUS11, + BUS12, + BUS13, + BUS14, +}; + +#define agc7648sv1_i2c_device_num(NUM){ \ + .name = "delta-agc7648sv1-i2c-device", \ + .id = NUM, \ + .dev = { \ + .platform_data = &agc7648sv1_i2c_device_platform_data[NUM], \ + .release = device_release, \ + }, \ +} + +static struct cpld_attribute_data { + uint8_t bus; + uint8_t addr; + uint8_t reg; + uint8_t mask; + char note[350]; +}; + +enum cpld_type { + system_cpld, +}; + +enum swpld1_type { + swpld1, +}; + +enum swpld2_type { + swpld2, +}; + +enum swpld3_type { + swpld3, +}; + +struct cpld_platform_data { + int reg_addr; + struct i2c_client *client; +}; + +enum cpld_attributes { +//CPLDs address and value + CPLD_REG_ADDR, + CPLD_REG_VALUE, + SWPLD1_REG_ADDR, + SWPLD1_REG_VALUE, + SWPLD2_REG_ADDR, + SWPLD2_REG_VALUE, + SWPLD3_REG_ADDR, + SWPLD3_REG_VALUE, +//CPLD + CPU_BOARD_ID1, + CPU_BOARD_ID2, + BOARD_VER, + CPULD_VER, + CPU_SYS_PWR_OK, + PLAT_RST, + CPLD_VR_HOT, + CPU_OVER_TMP, + DDR_OVER_TMP, + CPU_PWR_RST, + CPU_HARD_RST, + CPLD_RST, + MB_PWR_ENABLE, + MB_PWR_PGD, + MB_RST_DONE, + MB_RST, + EEPROM_WP, + PSU_FAN_EVENT, + CPU_I2C_MUX_EN, + CPU_I2C_MUX_SEL, +//SWPLD1 + BOARD_ID, + BCM88375_RST, + B54616S_RST, + PSU1_EN, + PSU2_EN, + PSU1_PWR_FAN_OK, + PSU2_PWR_FAN_OK, + PSU2_PRESENT, + PSU1_PRESENT, + PSU2_PWR_INT, + PSU1_PWR_INT, + BCM88375_INT, + BCM54616S_IRQ, + LED_SYS, + LED_PWR, + LED_FAN, + PSU_I2C_SEL, + FAN1_LED, + FAN2_LED, + FAN3_LED, + FAN4_LED, + FAN_I2C_SEL, +//SWPLD3 + QSFP_I2C_SEL, + SFP_CHAN_EN, + SFP_SEL, +}; + +enum agc7648sv1_sfp_sysfs_attributes +{ + SFP_SELECT_PORT, + SFP_IS_PRESENT, + SFP_IS_PRESENT_ALL, + SFP_LP_MODE, + SFP_RESET, + SFP_RX_LOS, + SFP_RX_LOS_ALL, + SFP_TX_DISABLE, + SFP_TX_FAULT +}; + +static struct cpld_attribute_data attribute_data[] = { +//CPLDs address and value + [CPLD_REG_ADDR] = { + }, + [CPLD_REG_VALUE] = { + }, + [SWPLD1_REG_ADDR] = { + }, + [SWPLD1_REG_VALUE] = { + }, + [SWPLD2_REG_ADDR] = { + }, + [SWPLD2_REG_VALUE] = { + }, + [SWPLD3_REG_ADDR] = { + }, +//CPLD + [CPU_BOARD_ID1] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x00, .mask = 0xff, + .note = "Configured by PLD editor.\n0x15 : BROADWELL D-1527" + }, + [CPU_BOARD_ID2] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x01, .mask = 0xff, + .note = "Configured by PLD editor.\n0x27 : BROADWELL D-1527" + }, + [BOARD_VER] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x02, .mask = 0xff, + .note = "Controlled by external resistors.\n0x00: EVT1\n0x01: EVT2\n0x02: EVT3\n0x03: EVT4\n0x10: DVT1\n0x11: DVT2\n0x20: PVT1" + }, + [CPULD_VER] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x03, .mask = 0xff, + .note = "CPLD Version, controlled by CPLD editor." + }, + [CPU_SYS_PWR_OK] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x06, .mask = 1 << 2, + .note = "Indicate CPU that System Power is OK.\n\"1\" = System Power is OK\n\"0\" = System Power is not OK" + }, + [PLAT_RST] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x09, .mask = 1 << 4, + .note = "Indicate Platform Reset.\n\"1\" = Platform Reset\n\"0\" = Platform Not Reset" + }, + [CPLD_VR_HOT] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x0b, .mask = 1 << 3, + .note = "Indicate Power Rail Over temperature\n\"1\" = Not over temperature\n\"0\" = Over temperature" + }, + [CPU_OVER_TMP] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x0b, .mask = 1 << 1, + .note = "CPU Disomic temperature sensor\n\"1\" = Not over temperature.\n\"0\" = Over temperature." + }, + [DDR_OVER_TMP] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x0b, .mask = 1 << 0, + .note = "DDR over temperature sensor\n\"1\" = Not over temperature.\n\"0\" = Over temperature." + }, + [CPU_PWR_RST] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x11, .mask = 1 << 4, + .note = "Software execute the CPU Power On reset\n\"0\" = Reset\n\"1\" = Normal operation" + }, + [CPU_HARD_RST] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x11, .mask = 1 << 2, + .note = "Software execute the CPU Hard reset\n\"0\" = Reset\n\"1\" = Normal operation" + }, + [CPLD_RST] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x11, .mask = 1 << 0, + .note = "Software reset the CPLD system\n\"0\" = Reset\n\"1\" = Normal operation" + }, + [MB_PWR_ENABLE] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x12, .mask = 1 << 3, + .note = "Software Enable Main board Power\n\"0\" = Disable.\n\"1\" = Enable." + }, + [MB_PWR_PGD] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x12, .mask = 1 << 2, + .note = "Indicate the Main board all power good\n\"0\" = Power rail is failed\n\"1\" = Power rail is good" + }, + [MB_RST_DONE] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x12, .mask = 1 << 1, + .note = "Main board reset done.\n\"0\" = Reset\n\"1\" = Normal operation" + }, + [MB_RST] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x12, .mask = 1 << 0, + .note = "Software reset Main board\n\"0\" = Reset\n\"1\" = Normal operation" + }, + [EEPROM_WP] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x14, .mask = 1 << 3, + .note = "ID EEPROM Write Protect\n\"1\" = enables the lock-down mechanism.\n\"0\" = overrides the lock-down function enabling blocks to be erased or programmed using software commands." + }, + [PSU_FAN_EVENT] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x15, .mask = 1 << 1, + .note = "Indicate the PSU Fan interrupt occurs or not.\n\"0\" = Interrupt occurs\n\"1\" = Interrupt doesn't occur" + }, + [CPU_I2C_MUX_EN] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x14, .mask = 1 << 2, + .note = "CPU I2C MUX Enable\n\"0\" = Enable CPU I2C MUX\n\"1\" = Disable CPU I2C MUX" + }, + [CPU_I2C_MUX_SEL] = { + .bus = BUS3, .addr = CPUPLD_ADDR, + .reg = 0x14, .mask = 0x03, + .note = "CPU I2C MUX Selection\n\"0x00\" = CPUBD devices\n\"0x01\" = SWBD devices\n\"0x02\" = SWPLDs\n\"0x03\" = QSFP-DD module devices" + }, +//SWPLD1 + [BOARD_ID] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x00, .mask = 0xf0, + .note = "SW Board ID\n\"0000\": AGC7648." + }, + [BCM88375_RST] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x04, .mask = 1 << 6, + .note = "software Reset for MAC\n\"0\" = Reset.\n\"1\" = Normal Operation." + }, + [B54616S_RST] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x04, .mask = 1 << 5, + .note = "Software Reset for PHY\n\"0\" = Reset.\n\"1\" = Normal Operation." + }, + [PSU1_EN] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x08, .mask = 1 << 7, + .note = "Enable/Disable the Power Supply 1\n\"0\" = Enabled.\n\"1\" = Disabled." + }, + [PSU2_EN] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x08, .mask = 1 << 6, + .note = "Enable/Disable the Power Supply 2\n\"0\" = Enabled.\n\"1\" = Disabled." + }, + [PSU1_PWR_FAN_OK] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x0b, .mask = 1 << 7, + .note = "Indicate the Power Supply 1 power good\n\"1\" = Power rail is good\n\"0\" = Power rail is failed" + }, + [PSU2_PWR_FAN_OK] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x0b, .mask = 1 << 6, + .note = "Indicate the Power Supply 2 power good\n\"1\" = Power rail is good\n\"0\" = Power rail is failed" + }, + [PSU2_PRESENT] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x0d, .mask = 1 << 1, + .note = "Indicate PSU2 present or not.\n\"0\" = YES.\n\"1\" = NO." + }, + [PSU1_PRESENT] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x0d, .mask = 1 << 0, + .note = "Indicate PSU1 present or not.\n\"0\" = YES.\n\"1\" = NO." + }, + [PSU2_PWR_INT] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x0e, .mask = 1 << 5, + .note = "Indicate the PSU2 interrupt occurs or not.\n\"0\" = Interrupt occurs\n\"1\" = Interrupt doesn't occur" + }, + [PSU1_PWR_INT] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x0e, .mask = 1 << 4, + .note = "Indicate the PSU1 interrupt occurs or not.\n\"0\" = Interrupt occurs\n\"1\" = Interrupt doesn't occur" + }, + [BCM88375_INT] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x0e, .mask = 1 << 3, + .note = "Indicate BCM88375 Interrupt occurs or not.\n\"0\" = Interrupt occurs\n\"1\" = Interrupt doesn't occur" + }, + [BCM54616S_IRQ] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x16, .mask = 1 << 7, + .note = "Indicate the BCM54616S interrupt occurs or not.\n\"0\" = Interrupt occurs\n\"1\" = Interrupt doesn't occur" + }, + [LED_SYS] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x1c, .mask = 0xf0, + .note = "\"0x00\"= Off (No Power)\n\"0x01\"= Solid Amber(System Fault)\n\"0x02\"= Solid Green(System Normal Operation)\n\"0x05\"= Blinking Green(1/4S)(System Booting)\n\"0x06\"= Blinking Amber(1/4S)\n\"0x09\"= Blinking Green(1/2S)\n\"0x0A\"= Blinking Amber(1/2S)\n\"0x0D\"= Blinking Green(1S)\n\"0x0E\"= Blinking Amber(1S)" + }, + [LED_PWR] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x1c, .mask = 0x0c, + .note = "\"0x00\"= Off (No Power)\n\"0x01\"= Solid Green(PSU Normal Operation)\n\"0x02\"= Solid Amber(POST in progress)\n\"0x03\"= (Not define)" + }, + [LED_FAN] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x1c, .mask = 0x03, + .note = "\"0x00\"= Off (No Power)\n\"0x01\"= Solid Green(Fan Normal Operation)\n\"0x02\"= Solid Amber(Fan not present)\n\"0x03\"= Blinking Amber(Fan failed)" + }, + [PSU_I2C_SEL] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x1f, .mask = 0x03, + .note = "FAN I2C channel selection\n\"0x00\" = PS1 EEPROM\n\"0x01\" = PS1 HOT SWAP IC\n\"0x02\" = PS2 EEPROM\n\"0x03\" = PS2 HOT SWAP IC\n" + }, + [FAN1_LED] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x65, .mask = 0xc0, + .note = "Indicate the FAN Tray 1 LED status\n\"0x00\" = Off\n\"0x01\" = Solid Green.\n\"0x02\" = Solid Red.\n\"0x03\" = Off\n" + }, + [FAN2_LED] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x65, .mask = 0x30, + .note = "Indicate the FAN Tray 2 LED status\n\"0x00\" = Off\n\"0x01\" = Solid Green.\n\"0x02\" = Solid Red.\n\"0x03\" = Off\n" + }, + [FAN3_LED] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x65, .mask = 0x0c, + .note = "Indicate the FAN Tray 3 LED status\n\"0x00\" = Off\n\"0x01\" = Solid Green.\n\"0x02\" = Solid Red.\n\"0x03\" = Off\n" + }, + [FAN4_LED] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x65, .mask = 0x03, + .note = "Indicate the FAN Tray 4 LED status\n\"0x00\" = Off\n\"0x01\" = Solid Green.\n\"0x02\" = Solid Red.\n\"0x03\" = Off\n" + }, + [FAN_I2C_SEL] = { + .bus = BUS7, .addr = SWPLD1_ADDR, + .reg = 0x67, .mask = 0x07, + .note = "FAN I2C channel selection\n\"0x00\" = FAN TRAY 1 EEPROM\n\"0x01\" = FAN TRAY 2 EEPROM\n\"0x02\" = FAN TRAY 3 EEPROM\n\"0x03\" = FAN TRAY 4 EEPROM\n\"0x04\" = Reserved;(Do not use)\n\"0x05\" = FAN Control IC (EMC2305)\n\"0x06\" = FAN Thermal Sensor (TMP75A)\n\"0x07\" = FAN IO Control (PCA9555DB)" + }, +//SWPLD3 + [QSFP_I2C_SEL] = { + .bus = BUS7, .addr = SWPLD3_ADDR, + .reg = 0x20, .mask = 0x07, + .note = "QSFP28 I2C channel selection.\n\"0x00\" : QSFP28 Port 0\n\"0x01\" : QSFP28 Port 1\n\"0x02\" : QSFP28 Port 2\n\"0x03\" : QSFP28 Port 3\n\"0x04\" : QSFP28 Port 4\n\"0x05\" : QSFP28 Port 5" + }, + [SFP_CHAN_EN] = { + .bus = BUS7, .addr = SWPLD3_ADDR, + .reg = 0x21, .mask = 0x70, + .note = "SFP+ I2C Nth channel and QSFP channel enable index\n\"0x00\": means SFP+ N=0 and 1th channel enable.\n\"0x01\": means SFP+ N=1 and 2th channel enable.\n ...\n\"0x05\": means SFP+ N=5 and 6th channel enable.\n\"0x06\": means QSFP channel enable.\n\"0x07\": Disable all channels." + }, + [SFP_SEL] = { + .bus = BUS7, .addr = SWPLD3_ADDR, + .reg = 0x21, .mask = 0x07, + .note = "SFP+ I2C Mth selection. (From PORT1 ~ PORT48)\n\"0x00\": means M=0.\n\"0x01\": means M=1.\n...\n\"0x07\": means M=7\nSFP I2C Channel Number = 8 * N + M +1" + }, +}; + +struct i2c_device_platform_data { + int parent; + struct i2c_board_info info; + struct i2c_client *client; +}; + +struct i2c_client * i2c_client_9547; + +static struct cpld_platform_data agc7648sv1_cpld_platform_data[] = { + [system_cpld] = { + .reg_addr = CPUPLD_ADDR, + }, +}; + +static struct cpld_platform_data agc7648sv1_swpld1_platform_data[] = { + [swpld1] = { + .reg_addr = SWPLD1_ADDR, + }, +}; + +static struct cpld_platform_data agc7648sv1_swpld2_platform_data[] = { + [swpld2] = { + .reg_addr = SWPLD2_ADDR, + }, +}; + +static struct cpld_platform_data agc7648sv1_swpld3_platform_data[] = { + [swpld3] = { + .reg_addr = SWPLD3_ADDR, + }, +}; + +// pca9548 - add 8 bus +static struct pca954x_platform_mode pca954x_mode[] = +{ + { + .adap_id = 4, + .deselect_on_exit = 1, + }, + { + .adap_id = 5, + .deselect_on_exit = 1, + }, + { + .adap_id = 6, + .deselect_on_exit = 1, + }, + { + .adap_id = 7, + .deselect_on_exit = 1, + }, + { + .adap_id = 8, + .deselect_on_exit = 1, + }, + { + .adap_id = 9, + .deselect_on_exit = 1, + }, + { + .adap_id = 10, + .deselect_on_exit = 1, + }, + { + .adap_id = 11, + .deselect_on_exit = 1, + }, +}; + +static struct pca954x_platform_data pca954x_data = +{ + .modes = pca954x_mode, + .num_modes = ARRAY_SIZE(pca954x_mode), +}; + +static struct i2c_board_info __initdata i2c_info_pca9547[] = +{ + { + I2C_BOARD_INFO("pca9547", 0x71), + .platform_data = &pca954x_data, + }, +}; + +/* ---------------- IPMI - start ------------- */ +int dni_create_user(void) +{ + int rv, i; + + for (i = 0, rv = 1; i < IPMI_MAX_INTF && rv; i++) + { + rv = ipmi_create_user(i, &ipmi_hndlrs, NULL, &ipmi_mh_user); + } + if(rv == 0) + { + printk("Enable IPMI protocol.\n"); + return rv; + } +} +EXPORT_SYMBOL(dni_create_user); + +int dni_bmc_cmd(char set_cmd, char *cmd_data, int cmd_data_len) +{ + int rv; + struct ipmi_system_interface_addr addr; + struct kernel_ipmi_msg msg; + struct completion comp; + + addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + addr.channel = IPMI_BMC_CHANNEL; + addr.lun = 0; + + msg.netfn = DELTA_NETFN; + msg.cmd = set_cmd; + msg.data_len = cmd_data_len; + msg.data = cmd_data; + + init_completion(&comp); + rv = ipmi_request_supply_msgs(ipmi_mh_user, (struct ipmi_addr*)&addr, 0, &msg, &comp, &halt_smi_msg, &halt_recv_msg, 0); + if(rv) + return BMC_ERR; + + wait_for_completion(&comp); + + switch(msg.cmd) + { + case CMD_GETDATA: + if(rv == 0) + return halt_recv_msg.msg.data[1]; + else + { + printk(KERN_ERR "IPMI get error!\n"); + return BMC_ERR; + } + break; + case CMD_SETDATA: + if(rv == 0) + return rv; + else + { + printk(KERN_ERR "IPMI set error!\n"); + return BMC_ERR; + } + case CMD_DIAGMODE: + if(rv == 0 && (halt_recv_msg.msg.data[0] != BMC_NOT_EXIST)) + return halt_recv_msg.msg.data[1]; + else + { + printk(KERN_ERR "BMC is not exist!\n"); + return BMC_ERR; + } + } + + ipmi_free_recv_msg(&halt_recv_msg); + + return rv; +} +EXPORT_SYMBOL(dni_bmc_cmd); +/* ---------------- IPMI - stop ------------- */ + +/* ---------------- I2C device - start ------------- */ +static struct i2c_device_platform_data agc7648sv1_i2c_device_platform_data[] = { + { + // id eeprom + .parent = 1, + .info = { I2C_BOARD_INFO("24c02", 0x53) }, + .client = NULL, + }, + { + // tmp75 + .parent = 8, + .info = { I2C_BOARD_INFO("tmp75", 0x4b) }, + .client = NULL, + }, + { + // tmp431 + .parent = 8, + .info = { I2C_BOARD_INFO("tmp431", 0x4c) }, + .client = NULL, + }, + { + // tmp432 + .parent = 8, + .info = { I2C_BOARD_INFO("tmp432", 0x4d) }, + .client = NULL, + }, + { + // tmp75 + .parent = 8, + .info = { I2C_BOARD_INFO("tmp75", 0x4e) }, + .client = NULL, + }, + { + // tmp75 cpu + .parent = 8, + .info = { I2C_BOARD_INFO("tmp75", 0x4f) }, + .client = NULL, + }, + { + // fan control 1 + .parent = 25, + .info = { I2C_BOARD_INFO("emc2305", 0x2c) }, + .client = NULL, + }, + { + // fan control 2 + .parent = 25, + .info = { I2C_BOARD_INFO("emc2305", 0x2d) }, + .client = NULL, + }, + { + // tmp75 fan + .parent = 26, + .info = { I2C_BOARD_INFO("tmp75", 0x4f) }, + .client = NULL, + }, + { + // PSU 1 + .parent = 31, + .info = { I2C_BOARD_INFO("dni_agc7648sv1_psu", 0x58) }, + .client = NULL, + }, + { + // PSU 2 + .parent = 32, + .info = { I2C_BOARD_INFO("dni_agc7648sv1_psu", 0x58) }, + .client = NULL, + }, + { + // qsfp 1 (0x50) + .parent = 41, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 2 (0x50) + .parent = 42, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 3 (0x50) + .parent = 43, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 4 (0x50) + .parent = 44, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 5 (0x50) + .parent = 45, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // qsfp 6 (0x50) + .parent = 46, + .info = { .type = "optoe1", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 1 (0x50) + .parent = 51, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 2 (0x50) + .parent = 52, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 3 (0x50) + .parent = 53, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 4 (0x50) + .parent = 54, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 5 (0x50) + .parent = 55, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 6 (0x50) + .parent = 56, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 7 (0x50) + .parent = 57, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 8 (0x50) + .parent = 58, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 9 (0x50) + .parent = 59, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 10 (0x50) + .parent = 60, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 11 (0x50) + .parent = 61, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 12 (0x50) + .parent = 62, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 13 (0x50) + .parent = 63, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 14 (0x50) + .parent = 64, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 15 (0x50) + .parent = 65, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 16 (0x50) + .parent = 66, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 17 (0x50) + .parent = 67, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 18 (0x50) + .parent = 68, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 19 (0x50) + .parent = 69, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 20 (0x50) + .parent = 70, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 21 (0x50) + .parent = 71, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 22 (0x50) + .parent = 72, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 23 (0x50) + .parent = 73, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 24 (0x50) + .parent = 74, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 25 (0x50) + .parent = 75, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 26 (0x50) + .parent = 76, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 27 (0x50) + .parent = 77, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 28 (0x50) + .parent = 78, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 29 (0x50) + .parent = 79, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 30 (0x50) + .parent = 80, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 31 (0x50) + .parent = 81, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 32 (0x50) + .parent = 82, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 33 (0x50) + .parent = 83, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 34 (0x50) + .parent = 84, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 35 (0x50) + .parent = 85, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 36 (0x50) + .parent = 86, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 37 (0x50) + .parent = 87, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 38 (0x50) + .parent = 88, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 39 (0x50) + .parent = 89, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 40 (0x50) + .parent = 90, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 41 (0x50) + .parent = 91, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 42 (0x50) + .parent = 92, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 43 (0x50) + .parent = 93, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 44 (0x50) + .parent = 94, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 45 (0x50) + .parent = 95, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 46 (0x50) + .parent = 96, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 47 (0x50) + .parent = 97, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, + { + // sfp 48 (0x50) + .parent = 98, + .info = { .type = "optoe2", .addr = 0x50 }, + .client = NULL, + }, +}; + +static struct platform_device agc7648sv1_i2c_device[] = { + agc7648sv1_i2c_device_num(0), + agc7648sv1_i2c_device_num(1), + agc7648sv1_i2c_device_num(2), + agc7648sv1_i2c_device_num(3), + agc7648sv1_i2c_device_num(4), + agc7648sv1_i2c_device_num(5), + agc7648sv1_i2c_device_num(6), + agc7648sv1_i2c_device_num(7), + agc7648sv1_i2c_device_num(8), + agc7648sv1_i2c_device_num(9), + agc7648sv1_i2c_device_num(10), + agc7648sv1_i2c_device_num(11), + agc7648sv1_i2c_device_num(12), + agc7648sv1_i2c_device_num(13), + agc7648sv1_i2c_device_num(14), + agc7648sv1_i2c_device_num(15), + agc7648sv1_i2c_device_num(16), + agc7648sv1_i2c_device_num(17), + agc7648sv1_i2c_device_num(18), + agc7648sv1_i2c_device_num(19), + agc7648sv1_i2c_device_num(20), + agc7648sv1_i2c_device_num(21), + agc7648sv1_i2c_device_num(22), + agc7648sv1_i2c_device_num(23), + agc7648sv1_i2c_device_num(24), + agc7648sv1_i2c_device_num(25), + agc7648sv1_i2c_device_num(26), + agc7648sv1_i2c_device_num(27), + agc7648sv1_i2c_device_num(28), + agc7648sv1_i2c_device_num(29), + agc7648sv1_i2c_device_num(30), + agc7648sv1_i2c_device_num(31), + agc7648sv1_i2c_device_num(32), + agc7648sv1_i2c_device_num(33), + agc7648sv1_i2c_device_num(34), + agc7648sv1_i2c_device_num(35), + agc7648sv1_i2c_device_num(36), + agc7648sv1_i2c_device_num(37), + agc7648sv1_i2c_device_num(38), + agc7648sv1_i2c_device_num(39), + agc7648sv1_i2c_device_num(40), + agc7648sv1_i2c_device_num(41), + agc7648sv1_i2c_device_num(42), + agc7648sv1_i2c_device_num(43), + agc7648sv1_i2c_device_num(44), + agc7648sv1_i2c_device_num(45), + agc7648sv1_i2c_device_num(46), + agc7648sv1_i2c_device_num(47), + agc7648sv1_i2c_device_num(48), + agc7648sv1_i2c_device_num(49), + agc7648sv1_i2c_device_num(50), + agc7648sv1_i2c_device_num(51), + agc7648sv1_i2c_device_num(52), + agc7648sv1_i2c_device_num(53), + agc7648sv1_i2c_device_num(54), + agc7648sv1_i2c_device_num(55), + agc7648sv1_i2c_device_num(56), + agc7648sv1_i2c_device_num(57), + agc7648sv1_i2c_device_num(58), + agc7648sv1_i2c_device_num(59), + agc7648sv1_i2c_device_num(60), + agc7648sv1_i2c_device_num(61), + agc7648sv1_i2c_device_num(62), + agc7648sv1_i2c_device_num(63), + agc7648sv1_i2c_device_num(64), +}; +/* ---------------- I2C device - end ------------- */ + +/* ---------------- I2C driver - start ------------- */ +static int __init i2c_device_probe(struct platform_device *pdev) +{ + struct i2c_device_platform_data *pdata; + struct i2c_adapter *parent; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", + pdata->parent); + return -ENODEV; + } + + pdata->client = i2c_new_device(parent, &pdata->info); + if (!pdata->client) { + dev_err(&pdev->dev, "Failed to create i2c client %s at %d\n", + pdata->info.type, pdata->parent); + return -ENODEV; + } + + return 0; +} + +static int __exit i2c_deivce_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent; + struct i2c_device_platform_data *pdata; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + if (pdata->client) { + parent = (pdata->client)->adapter; + i2c_unregister_device(pdata->client); + i2c_put_adapter(parent); + } + + return 0; +} +static struct platform_driver i2c_device_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc7648sv1-i2c-device", + } +}; +/* ---------------- I2C driver - end ------------- */ + +/* ---------------- SFP attribute read/write - start -------- */ +long sfp_port_data = 0; +static struct kobject *kobj_cpld; +static struct kobject *kobj_swpld1; +static struct kobject *kobj_swpld2; +static struct kobject *kobj_swpld3; + +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf){ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev_1 = kobj_to_dev(kobj_swpld1); + struct device *i2cdev_2 = kobj_to_dev(kobj_swpld2); + struct cpld_platform_data *pdata1 = i2cdev_1->platform_data; + struct cpld_platform_data *pdata2 = i2cdev_2->platform_data; + long port_t = 0; + u8 reg_t = 0x00; + int values[7] = {'\0'}; + int bit_t = 0x00; + int i; + mutex_lock(&dni_lock); + + switch (attr->index) { + case SFP_IS_PRESENT: + port_t = sfp_port_data; + if (port_t > 0 && port_t < 9) { /* SFP Port 1-8 */ + reg_t = SFP_PRESENCE_1; + } else if (port_t > 8 && port_t < 17) { /* SFP Port 9-16 */ + reg_t = SFP_PRESENCE_2; + } else if (port_t > 16 && port_t < 25) { /* SFP Port 17-24 */ + reg_t = SFP_PRESENCE_3; + } else if (port_t > 24 && port_t < 33) { /* SFP Port 25-32 */ + reg_t = SFP_PRESENCE_4; + } else if (port_t > 32 && port_t < 41) { /* SFP Port 33-40 */ + reg_t = SFP_PRESENCE_5; + } else if (port_t > 40 && port_t < 49) { /* SFP Port 41-48 */ + reg_t = SFP_PRESENCE_6; + } else if (port_t > 48 && port_t < 55) { /* QSFP Port 1-6 */ + reg_t = QSFP_PRESENCE; + } else { + values[0] = 1; /* return 1, module NOT present */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + } + + if (port_t > 48 && port_t < 55) { /* QSFP */ + VALIDATED_READ(buf, values[0], i2c_smbus_read_byte_data(pdata1[swpld1].client, reg_t), 0); + mutex_unlock(&dni_lock); + port_t = port_t - 1; + bit_t = 1 << (port_t % 8); + values[0] = values[0] & bit_t; + values[0] = values[0] / bit_t; + } + else { /* SFP */ + VALIDATED_READ(buf, values[0], i2c_smbus_read_byte_data(pdata2[swpld2].client, reg_t), 0); + mutex_unlock(&dni_lock); + port_t = port_t - 1; + bit_t = 1 << (port_t % 8); + values[0] = values[0] & bit_t; + values[0] = values[0] / bit_t; + } + + /* sfp_is_present value + * return 0 is module present + * return 1 is module NOT present */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + + case SFP_IS_PRESENT_ALL: + /* Report the SFP/QSFP ALL PRESENCE status + * This data information form SWPLD2(SFP) and SWPLD1(QSFP). */ + + /* SFP_PRESENT Ports 1-8 */ + VALIDATED_READ(buf, values[0], + i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_PRESENCE_1), 0); + /* SFP_PRESENT Ports 9-16 */ + VALIDATED_READ(buf, values[1], + i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_PRESENCE_2), 0); + /* SFP_PRESENT Ports 17-24 */ + VALIDATED_READ(buf, values[2], + i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_PRESENCE_3), 0); + /* SFP_PRESENT Ports 25-32 */ + VALIDATED_READ(buf, values[3], + i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_PRESENCE_4), 0); + /* SFP_PRESENT Ports 33-40 */ + VALIDATED_READ(buf, values[4], + i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_PRESENCE_5), 0); + /* SFP_PRESENT Ports 41-48 */ + VALIDATED_READ(buf, values[5], + i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_PRESENCE_6), 0); + /* QSFP_PRESENT Ports 49-54 */ + VALIDATED_READ(buf, values[6], + i2c_smbus_read_byte_data(pdata1[swpld1].client, QSFP_PRESENCE), 0); + + values[6] = values[6] & 0x3F; + + /* sfp_is_present_all value + * return 0 is module present + * return 1 is module NOT present */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%02X %02X %02X %02X %02X %02X %02X\n", values[6], values[5], values[4],values[3], values[2], values[1], values[0]); + + case SFP_LP_MODE: + port_t = sfp_port_data; + if (port_t > 48 && port_t < 55) { /* QSFP Port 49-54 */ + reg_t = QSFP_LPMODE; + } else { + values[0] = 0; /* return 0, module is NOT in LP mode */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + } + + if (port_t > 48 && port_t < 55) { /* QSFP Port 49-54 */ + VALIDATED_READ(buf, values[0], i2c_smbus_read_byte_data(pdata1[swpld1].client, reg_t), 0); + } else { /* In agc7648sv1 only QSFP support control LP MODE */ + values[0] = 0; + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + } + port_t = port_t - 1; + bit_t = 1 << (port_t % 8); + values[0] = values[0] & bit_t; + values[0] = values[0] / bit_t; + + /* sfp_lp_mode value + * return 0 is module NOT in LP mode + * return 1 is module in LP mode */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + + case SFP_RESET: + port_t = sfp_port_data; + if (port_t > 48 && port_t < 55) { /* QSFP Port 49-54 */ + reg_t = QSFP_RESET; + } else { + values[0] = 1; /* return 1, module NOT in reset mode */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + } + + if (port_t > 48 && port_t < 55) { /* QSFP Port 49-54 */ + VALIDATED_READ(buf, values[0], i2c_smbus_read_byte_data(pdata1[swpld1].client, reg_t), 0); + } else { /* In agc7648sv1 only QSFP support control RESET MODE */ + values[0] = 1; + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + } + port_t = port_t - 1; + bit_t = 1 << (port_t % 8); + values[0] = values[0] & bit_t; + values[0] = values[0] / bit_t; + + /* sfp_reset value + * return 0 is module Reset + * return 1 is module Normal */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + + case SFP_RX_LOS: + port_t = sfp_port_data; + if (port_t > 0 && port_t < 9) { /* SFP Port 1-8 */ + reg_t = SFP_RXLOS_1; + } else if (port_t > 8 && port_t < 17) { /* SFP Port 9-16 */ + reg_t = SFP_RXLOS_2; + } else if (port_t > 16 && port_t < 25) { /* SFP Port 17-24 */ + reg_t = SFP_RXLOS_3; + } else if (port_t > 24 && port_t < 33) { /* SFP Port 25-32 */ + reg_t = SFP_RXLOS_4; + } else if (port_t > 32 && port_t < 41) { /* SFP Port 33-40 */ + reg_t = SFP_RXLOS_5; + } else if (port_t > 40 && port_t < 49) { /* SFP Port 41-48 */ + reg_t = SFP_RXLOS_6; + } else { + values[0] = 1; /* return 1, module Error */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + } + + if (port_t > 0 && port_t < 49) { /* SFP */ + VALIDATED_READ(buf, values[0], i2c_smbus_read_byte_data(pdata2[swpld2].client, reg_t), 0); + } else { /* In agc7648sv1 only SFP support control RX_LOS MODE */ + values[0] = 1; + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + } + port_t = port_t - 1; + bit_t = 1 << (port_t % 8); + values[0] = values[0] & bit_t; + values[0] = values[0] / bit_t; + + /* sfp_rx_los value + * return 0 is module Normal Operation + * return 1 is module Error */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + + case SFP_RX_LOS_ALL: + /* Report the SFP ALL RXLOS status + * This data information form SWPLD2. */ + + /* SFP_RXLOS Ports 1-8 */ + VALIDATED_READ(buf, values[0], + i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_RXLOS_1), 0); + /* SFP_RXLOS Ports 9-16 */ + VALIDATED_READ(buf, values[1], + i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_RXLOS_2), 0); + /* SFP_RXLOS Ports 17-24 */ + VALIDATED_READ(buf, values[2], + i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_RXLOS_3), 0); + /* SFP_RXLOS Ports 25-32 */ + VALIDATED_READ(buf, values[3], + i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_RXLOS_4), 0); + /* SFP_RXLOS Ports 33-40 */ + VALIDATED_READ(buf, values[4], + i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_RXLOS_5), 0); + /* SFP_RXLOS Ports 41-48 */ + VALIDATED_READ(buf, values[5], + i2c_smbus_read_byte_data(pdata2[swpld2].client, SFP_RXLOS_6), 0); + + /* sfp_rx_los_all value + * return 0 is module Normal Operation + * return 1 is module Error */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%02X %02X %02X %02X %02X %02X\n", values[5], values[4],values[3], values[2], values[1], values[0]); + + case SFP_TX_DISABLE: + port_t = sfp_port_data; + if (port_t > 0 && port_t < 9) { /* SFP Port 1-8 */ + reg_t = SFP_TXDIS_1; + } else if (port_t > 8 && port_t < 17) { /* SFP Port 9-16 */ + reg_t = SFP_TXDIS_2; + } else if (port_t > 16 && port_t < 25) { /* SFP Port 17-24 */ + reg_t = SFP_TXDIS_3; + } else if (port_t > 24 && port_t < 33) { /* SFP Port 25-32 */ + reg_t = SFP_TXDIS_4; + } else if (port_t > 32 && port_t < 41) { /* SFP Port 33-40 */ + reg_t = SFP_TXDIS_5; + } else if (port_t > 40 && port_t < 49) { /* SFP Port 41-48 */ + reg_t = SFP_TXDIS_6; + } else { + values[0] = 1; /* return 1, module Transmitter Disabled */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + } + + if (port_t > 0 && port_t < 49) { /* SFP */ + VALIDATED_READ(buf, values[0], i2c_smbus_read_byte_data(pdata2[swpld2].client, reg_t), 0); + } else { /* In agc7648sv1 only SFP support control TX_DISABLE MODE */ + values[0] = 1; + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + } + port_t = port_t - 1; + bit_t = 1 << (port_t % 8); + values[0] = values[0] & bit_t; + values[0] = values[0] / bit_t; + + /* sfp_tx_disable value + * return 0 is module Enable Transmitter on + * return 1 is module Transmitter Disabled */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + + case SFP_TX_FAULT: + port_t = sfp_port_data; + if (port_t > 0 && port_t < 9) { /* SFP Port 1-8 */ + reg_t = SFP_TXFAULT_1; + } else if (port_t > 8 && port_t < 17) { /* SFP Port 9-16 */ + reg_t = SFP_TXFAULT_2; + } else if (port_t > 16 && port_t < 25) { /* SFP Port 17-24 */ + reg_t = SFP_TXFAULT_3; + } else if (port_t > 24 && port_t < 33) { /* SFP Port 25-32 */ + reg_t = SFP_TXFAULT_4; + } else if (port_t > 32 && port_t < 41) { /* SFP Port 33-40 */ + reg_t = SFP_TXFAULT_5; + } else if (port_t > 40 && port_t < 49) { /* SFP Port 41-48 */ + reg_t = SFP_TXFAULT_6; + } else { + values[0] = 1; /* return 1, module is Fault */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + } + + if (port_t > 0 && port_t < 49) { /* SFP */ + VALIDATED_READ(buf, values[0], i2c_smbus_read_byte_data(pdata2[swpld2].client, reg_t), 0); + } else { /* In agc7648sv1 only SFP support control TX_FAULT MODE */ + values[0] = 1; + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + } + port_t = port_t - 1; + bit_t = 1 << (port_t % 8); + values[0] = values[0] & bit_t; + values[0] = values[0] / bit_t; + + /* sfp_tx_fault value + * return 0 is module Normal + * return 1 is module Fault */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values[0]); + + default: + mutex_unlock(&dni_lock); + return sprintf(buf, "%d not found", attr->index); + } +} + +static ssize_t get_port_data(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + return sprintf(buf, "%ld\n", sfp_port_data); +} + +static ssize_t set_port_data(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) +{ + long data; + int error; + + error = kstrtol(buf, 10, &data); + if(error) + return error; + + if(data < 1 || data > 54) /* valid port is 1-54 */ + { + printk(KERN_ALERT "select port out of range (1-54)\n"); + return count; + } + else + sfp_port_data = data; + + return count; +} + +static ssize_t set_lpmode_data(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) +{ + struct device *i2cdev = kobj_to_dev(kobj_swpld1); + struct cpld_platform_data *pdata = i2cdev->platform_data; + long data; + int error; + long port_t = 0; + int bit_t = 0x00; + int values = 0x00; + u8 reg_t = 0x00; + + error = kstrtol(buf, 10, &data); + if (error) + return error; + mutex_lock(&dni_lock); + port_t = sfp_port_data; + if (port_t > 48 && port_t < 55) { /* QSFP Port 49-54 */ + reg_t = QSFP_LPMODE; + } else { + values = 0; /* return 0, module NOT in LP mode */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values); + } + + values = i2c_smbus_read_byte_data(pdata[swpld1].client, reg_t); + if (values < 0){ + mutex_unlock(&dni_lock); + return -EIO; + } + /* Indicate the module is in LP mode or not + * 0 = Disable + * 1 = Enable */ + port_t = port_t - 1; + if (data == 0) + { + bit_t = ~(1 << (port_t % 8)); + values = values & bit_t; + } + else if (data == 1){ + bit_t = (1 << (port_t % 8)); + values = values | bit_t; + } + else + { + mutex_unlock(&dni_lock); + return -EINVAL; + } + if (i2c_smbus_write_byte_data(pdata[swpld1].client, reg_t, (u8)values) < 0) + { + mutex_unlock(&dni_lock); + return -EIO; + } + mutex_unlock(&dni_lock); + return count; +} + +static ssize_t set_reset_data(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) +{ + struct device *i2cdev = kobj_to_dev(kobj_swpld1); + struct cpld_platform_data *pdata = i2cdev->platform_data; + long data; + int error; + long port_t = 0; + int bit_t = 0x00; + int values = 0x00; + u8 reg_t = 0x00; + + error = kstrtol(buf, 10, &data); + if (error) + return error; + + mutex_lock(&dni_lock); + port_t = sfp_port_data; + + if (port_t > 48 && port_t < 55) { /* QSFP Port 49-54 */ + reg_t = QSFP_RESET; + } else { + values = 1; /* return 1, module NOT in reset mode */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values); + } + + values = i2c_smbus_read_byte_data(pdata[swpld1].client, reg_t); + if (values < 0){ + mutex_unlock(&dni_lock); + return -EIO; + } + /* Indicate the module is in reset mode or not + * 0 = Reset + * 1 = Normal */ + port_t = port_t - 1; + if (data == 0) + { + bit_t = ~(1 << (port_t % 8)); + values = values & bit_t; + } + else if (data == 1) + { + bit_t = (1 << (port_t % 8)); + values = values | bit_t; + } + else + { + mutex_unlock(&dni_lock); + return -EINVAL; + } + if (i2c_smbus_write_byte_data(pdata[swpld1].client, reg_t, (u8)values) < 0) + { + mutex_unlock(&dni_lock); + return -EIO; + } + mutex_unlock(&dni_lock); + return count; +} + +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) +{ + struct device *i2cdev = kobj_to_dev(kobj_swpld2); + struct cpld_platform_data *pdata = i2cdev->platform_data; + long data; + int error; + long port_t = 0; + int bit_t = 0x00; + int values = 0x00; + u8 reg_t = 0x00; + + error = kstrtol(buf, 10, &data); + if (error) + return error; + + mutex_lock(&dni_lock); + port_t = sfp_port_data; + + if (port_t > 0 && port_t < 9) { /* SFP Port 1-8 */ + reg_t = SFP_TXDIS_1; + } else if (port_t > 8 && port_t < 17) { /* SFP Port 9-16 */ + reg_t = SFP_TXDIS_2; + } else if (port_t > 16 && port_t < 25) { /* SFP Port 17-24 */ + reg_t = SFP_TXDIS_3; + } else if (port_t > 24 && port_t < 33) { /* SFP Port 25-32 */ + reg_t = SFP_TXDIS_4; + } else if (port_t > 32 && port_t < 41) { /* SFP Port 33-40 */ + reg_t = SFP_TXDIS_5; + } else if (port_t > 40 && port_t < 49) { /* SFP Port 41-48 */ + reg_t = SFP_TXDIS_6; + } else { + values = 1; /* return 1, module NOT in reset mode */ + mutex_unlock(&dni_lock); + return sprintf(buf, "%d\n", values); + } + + values = i2c_smbus_read_byte_data(pdata[swpld2].client, reg_t); + if (values < 0){ + mutex_unlock(&dni_lock); + return -EIO; + } + /* Indicate the module is Enable Transmitter on or not + * 0 = Enable + * 1 = Disable */ + port_t = port_t - 1; + if (data == 0) + { + bit_t = ~(1 << (port_t % 8)); + values = values & bit_t; + } + else if (data == 1) + { + bit_t = (1 << (port_t % 8)); + values = values | bit_t; + } + else + { + mutex_unlock(&dni_lock); + return -EINVAL; + } + if (i2c_smbus_write_byte_data(pdata[swpld2].client, reg_t, (u8)values) < 0) + { + mutex_unlock(&dni_lock); + return -EIO; + } + mutex_unlock(&dni_lock); + return count; +} +/* ---------------- SFP attribute read/write - end -------- */ + +/* ---------------- CPLD - start ------------- */ +unsigned char cpupld_reg_addr; +unsigned char swpld1_reg_addr; +unsigned char swpld2_reg_addr; +unsigned char swpld3_reg_addr; + +/* CPLD -- device */ +static struct platform_device cpld_device = { + .name = "delta-agc7648sv1-cpld", + .id = 0, + .dev = { + .platform_data = agc7648sv1_cpld_platform_data, + .release = device_release + }, +}; + +static struct platform_device swpld1_device = { + .name = "delta-agc7648sv1-swpld1", + .id = 0, + .dev = { + .platform_data = agc7648sv1_swpld1_platform_data, + .release = device_release + }, +}; + +static struct platform_device swpld2_device = { + .name = "delta-agc7648sv1-swpld2", + .id = 0, + .dev = { + .platform_data = agc7648sv1_swpld2_platform_data, + .release = device_release + }, +}; + +static struct platform_device swpld3_device = { + .name = "delta-agc7648sv1-swpld3", + .id = 0, + .dev = { + .platform_data = agc7648sv1_swpld3_platform_data, + .release = device_release + }, +}; + +static ssize_t get_cpld_reg(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + int ret; + int mask; + int value; + char note[450]; + unsigned char reg; + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cpld_platform_data *pdata = dev->platform_data; + + mutex_lock(&dni_lock); + switch (attr->index) { + case CPLD_REG_ADDR: + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", cpupld_reg_addr); + case SWPLD1_REG_ADDR: + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", swpld1_reg_addr); + case SWPLD2_REG_ADDR: + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", swpld2_reg_addr); + case SWPLD3_REG_ADDR: + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", swpld3_reg_addr); + case CPLD_REG_VALUE: + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, cpupld_reg_addr); + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", ret); + case SWPLD1_REG_VALUE: + ret = i2c_smbus_read_byte_data(pdata[swpld1].client, swpld1_reg_addr); + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", ret); + case SWPLD2_REG_VALUE: + ret = i2c_smbus_read_byte_data(pdata[swpld2].client, swpld2_reg_addr); + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", ret); + case SWPLD3_REG_VALUE: + ret = i2c_smbus_read_byte_data(pdata[swpld3].client, swpld3_reg_addr); + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x\n", ret); + case CPU_BOARD_ID1 ... SFP_SEL: + reg = attribute_data[attr->index].reg; + mask = attribute_data[attr->index].mask; + value = i2c_smbus_read_byte_data(pdata[DEFAULT_CPLD].client, reg); + sprintf(note, "\n%s\n",attribute_data[attr->index].note); + value = value & mask; + break; + default: + mutex_unlock(&dni_lock); + return sprintf(buf, "%d not found", attr->index); + } + + switch (mask) { + case 0xff: + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x%s", value, note); + case 0x0f: + case 0x07: + case 0x03: + break; + case 0x0c: + value = value >> 2; + break; + case 0xf0: + case 0x70: + case 0x30: + value = value >> 4; + break; + case 0xe0: + value = value >> 5; + break; + case 0xc0: + value = value >> 6; + break; + default : + value = value >> dni_log2(mask); + mutex_unlock(&dni_lock); + return sprintf(buf, "%d%s", value, note); + } + mutex_unlock(&dni_lock); + return sprintf(buf, "0x%02x%s", value, note); +} + +static ssize_t set_cpld_reg(struct device *dev, struct device_attribute *dev_attr, + const char *buf, size_t count) +{ + int err; + int value; + int set_data; + unsigned long set_data_ul; + unsigned char reg; + unsigned char mask; + unsigned char mask_out; + + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cpld_platform_data *pdata = dev->platform_data; + + err = kstrtoul(buf, 0, &set_data_ul); + if (err){ + return err; + } + + set_data = (int)set_data_ul; + if (set_data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + mutex_lock(&dni_lock); + + switch (attr->index) { + case CPLD_REG_ADDR: + cpupld_reg_addr = set_data; + mutex_unlock(&dni_lock); + return count; + case SWPLD1_REG_ADDR: + swpld1_reg_addr = set_data; + mutex_unlock(&dni_lock); + return count; + case SWPLD2_REG_ADDR: + swpld2_reg_addr = set_data; + mutex_unlock(&dni_lock); + return count; + case SWPLD3_REG_ADDR: + swpld3_reg_addr = set_data; + mutex_unlock(&dni_lock); + return count; + case CPLD_REG_VALUE: + i2c_smbus_write_byte_data(pdata[system_cpld].client, cpupld_reg_addr, set_data); + mutex_unlock(&dni_lock); + return count; + case SWPLD1_REG_VALUE: + i2c_smbus_write_byte_data(pdata[swpld1].client, swpld1_reg_addr, set_data); + mutex_unlock(&dni_lock); + return count; + case SWPLD2_REG_VALUE: + i2c_smbus_write_byte_data(pdata[swpld2].client, swpld2_reg_addr, set_data); + mutex_unlock(&dni_lock); + return count; + case SWPLD3_REG_VALUE: + i2c_smbus_write_byte_data(pdata[swpld3].client, swpld3_reg_addr, set_data); + mutex_unlock(&dni_lock); + return count; + case CPU_BOARD_ID1 ... SFP_SEL: + reg = attribute_data[attr->index].reg; + mask = attribute_data[attr->index].mask; + value = i2c_smbus_read_byte_data(pdata[DEFAULT_CPLD].client, reg); + mask_out = value & ~(mask); + break; + default: + mutex_unlock(&dni_lock); + return sprintf(buf, "%d not found", attr->index); + } + + switch (mask) { + case 0x03: + case 0x07: + case 0x0f: + case 0xff: + set_data = mask_out | (set_data & mask); + break; + case 0x0c: + set_data = set_data << 2; + set_data = mask_out | (set_data & mask); + break; + case 0xf0: + case 0x70: + case 0x30: + set_data = set_data << 4; + set_data = mask_out | (set_data & mask); + break; + case 0xe0: + set_data = set_data << 5; + set_data = mask_out | (set_data & mask); + break; + case 0xc0: + set_data = set_data << 6; + set_data = mask_out | (set_data & mask); + break; + default : + set_data = mask_out | (set_data << dni_log2(mask) ); + } + + switch (attr->index) { + case CPU_BOARD_ID1 ... SFP_SEL: + i2c_smbus_write_byte_data(pdata[DEFAULT_CPLD].client, reg, set_data); + mutex_unlock(&dni_lock); + break; + default: + mutex_unlock(&dni_lock); + return sprintf(buf, "cpld not found"); + } + + return count; +} + +//address and value +static SENSOR_DEVICE_ATTR(cpld_reg_addr, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, CPLD_REG_ADDR); +static SENSOR_DEVICE_ATTR(cpld_reg_value, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, CPLD_REG_VALUE); +static SENSOR_DEVICE_ATTR(swpld1_reg_addr, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, SWPLD1_REG_ADDR); +static SENSOR_DEVICE_ATTR(swpld1_reg_value, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, SWPLD1_REG_VALUE); +static SENSOR_DEVICE_ATTR(swpld2_reg_addr, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, SWPLD2_REG_ADDR); +static SENSOR_DEVICE_ATTR(swpld2_reg_value, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, SWPLD2_REG_VALUE); +static SENSOR_DEVICE_ATTR(swpld3_reg_addr, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, SWPLD3_REG_ADDR); +static SENSOR_DEVICE_ATTR(swpld3_reg_value, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, SWPLD3_REG_VALUE); + +//CPLD +static SENSOR_DEVICE_ATTR(cpu_board_id1, S_IRUGO, get_cpld_reg, NULL, CPU_BOARD_ID1); +static SENSOR_DEVICE_ATTR(cpu_board_id2, S_IRUGO, get_cpld_reg, NULL, CPU_BOARD_ID2); +static SENSOR_DEVICE_ATTR(board_ver, S_IRUGO, get_cpld_reg, NULL, BOARD_VER); +static SENSOR_DEVICE_ATTR(cpuld_ver, S_IRUGO, get_cpld_reg, NULL, CPULD_VER); +static SENSOR_DEVICE_ATTR(cpu_sys_pwr_ok, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, CPU_SYS_PWR_OK); +static SENSOR_DEVICE_ATTR(plat_rst, S_IRUGO, get_cpld_reg, NULL, PLAT_RST); +static SENSOR_DEVICE_ATTR(cpld_vr_hot, S_IRUGO, get_cpld_reg, NULL, CPLD_VR_HOT); +static SENSOR_DEVICE_ATTR(cpu_over_tmp, S_IRUGO, get_cpld_reg, NULL, CPU_OVER_TMP); +static SENSOR_DEVICE_ATTR(ddr_over_tmp, S_IRUGO, get_cpld_reg, NULL, DDR_OVER_TMP); +static SENSOR_DEVICE_ATTR(cpu_pwr_rst, S_IRUGO, get_cpld_reg, NULL, CPU_PWR_RST); +static SENSOR_DEVICE_ATTR(cpu_hard_rst, S_IRUGO, get_cpld_reg, NULL, CPU_HARD_RST); +static SENSOR_DEVICE_ATTR(cpld_rst, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, CPLD_RST); +static SENSOR_DEVICE_ATTR(mb_pwr_enable, S_IRUGO, get_cpld_reg, NULL, MB_PWR_ENABLE); +static SENSOR_DEVICE_ATTR(mb_pwr_pgd, S_IRUGO, get_cpld_reg, NULL, MB_PWR_PGD); +static SENSOR_DEVICE_ATTR(mb_rst_done, S_IRUGO, get_cpld_reg, NULL, MB_RST_DONE); +static SENSOR_DEVICE_ATTR(mb_rst, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, MB_RST); +static SENSOR_DEVICE_ATTR(eeprom_wp, S_IRUGO, get_cpld_reg, NULL, EEPROM_WP); +static SENSOR_DEVICE_ATTR(psu_fan_event, S_IRUGO, get_cpld_reg, NULL, PSU_FAN_EVENT); +static SENSOR_DEVICE_ATTR(cpu_i2c_mux_en, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, CPU_I2C_MUX_EN); +static SENSOR_DEVICE_ATTR(cpu_i2c_mux_sel, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, CPU_I2C_MUX_SEL); + +//SWPLD1 +static SENSOR_DEVICE_ATTR(board_id, S_IRUGO, get_cpld_reg, NULL, BOARD_ID); +static SENSOR_DEVICE_ATTR(bcm88375_rst, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, BCM88375_RST); +static SENSOR_DEVICE_ATTR(b54616s_rst, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, B54616S_RST); +static SENSOR_DEVICE_ATTR(psu1_en, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, PSU1_EN); +static SENSOR_DEVICE_ATTR(psu2_en, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, PSU2_EN); +static SENSOR_DEVICE_ATTR(psu1_pwr_fan_ok, S_IRUGO, get_cpld_reg, NULL, PSU1_PWR_FAN_OK); +static SENSOR_DEVICE_ATTR(psu2_pwr_fan_ok, S_IRUGO, get_cpld_reg, NULL, PSU2_PWR_FAN_OK); +static SENSOR_DEVICE_ATTR(psu2_present, S_IRUGO, get_cpld_reg, NULL, PSU2_PRESENT); +static SENSOR_DEVICE_ATTR(psu1_present, S_IRUGO, get_cpld_reg, NULL, PSU1_PRESENT); +static SENSOR_DEVICE_ATTR(psu2_pwr_int, S_IRUGO, get_cpld_reg, NULL, PSU2_PWR_INT); +static SENSOR_DEVICE_ATTR(psu1_pwr_int, S_IRUGO, get_cpld_reg, NULL, PSU1_PWR_INT); +static SENSOR_DEVICE_ATTR(bcm88375_int, S_IRUGO, get_cpld_reg, NULL, BCM88375_INT); +static SENSOR_DEVICE_ATTR(bcm54616s_irq, S_IRUGO, get_cpld_reg, NULL, BCM54616S_IRQ); +static SENSOR_DEVICE_ATTR(led_sys, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, LED_SYS); +static SENSOR_DEVICE_ATTR(led_pwr, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, LED_PWR); +static SENSOR_DEVICE_ATTR(led_fan, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, LED_FAN); +static SENSOR_DEVICE_ATTR(psu_i2c_sel, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, PSU_I2C_SEL); +static SENSOR_DEVICE_ATTR(fan1_led, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, FAN1_LED); +static SENSOR_DEVICE_ATTR(fan2_led, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, FAN2_LED); +static SENSOR_DEVICE_ATTR(fan3_led, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, FAN3_LED); +static SENSOR_DEVICE_ATTR(fan4_led, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, FAN4_LED); +static SENSOR_DEVICE_ATTR(fan_i2c_sel, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, FAN_I2C_SEL); + +//SWPLD3 +static SENSOR_DEVICE_ATTR(qsfp_i2c_sel, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, QSFP_I2C_SEL); +static SENSOR_DEVICE_ATTR(sfp_chan_en, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, SFP_CHAN_EN); +static SENSOR_DEVICE_ATTR(sfp_sel, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, SFP_SEL); + +//SFP, QSFP +static SENSOR_DEVICE_ATTR(sfp_select_port, S_IRUGO | S_IWUSR, get_port_data, set_port_data, SFP_SELECT_PORT); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, for_status, NULL, SFP_IS_PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, for_status, NULL, SFP_IS_PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_lp_mode, S_IWUSR | S_IRUGO, for_status, set_lpmode_data, SFP_LP_MODE); +static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, for_status, set_reset_data, SFP_RESET); +static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, for_status, NULL, SFP_RX_LOS); +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, for_status, NULL, SFP_RX_LOS_ALL); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, for_status, set_tx_disable, SFP_TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, for_status, NULL, SFP_TX_FAULT); + +static struct attribute *cpld_attrs[] = { + &sensor_dev_attr_cpld_reg_value.dev_attr.attr, + &sensor_dev_attr_cpld_reg_addr.dev_attr.attr, + &sensor_dev_attr_cpu_board_id1.dev_attr.attr, + &sensor_dev_attr_cpu_board_id2.dev_attr.attr, + &sensor_dev_attr_board_ver.dev_attr.attr, + &sensor_dev_attr_cpuld_ver.dev_attr.attr, + &sensor_dev_attr_cpu_sys_pwr_ok.dev_attr.attr, + &sensor_dev_attr_plat_rst.dev_attr.attr, + &sensor_dev_attr_cpld_vr_hot.dev_attr.attr, + &sensor_dev_attr_cpu_over_tmp.dev_attr.attr, + &sensor_dev_attr_ddr_over_tmp.dev_attr.attr, + &sensor_dev_attr_cpu_pwr_rst.dev_attr.attr, + &sensor_dev_attr_cpu_hard_rst.dev_attr.attr, + &sensor_dev_attr_cpld_rst.dev_attr.attr, + &sensor_dev_attr_mb_pwr_enable.dev_attr.attr, + &sensor_dev_attr_mb_pwr_pgd.dev_attr.attr, + &sensor_dev_attr_mb_rst_done.dev_attr.attr, + &sensor_dev_attr_mb_rst.dev_attr.attr, + &sensor_dev_attr_eeprom_wp.dev_attr.attr, + &sensor_dev_attr_psu_fan_event.dev_attr.attr, + &sensor_dev_attr_cpu_i2c_mux_en.dev_attr.attr, + &sensor_dev_attr_cpu_i2c_mux_sel.dev_attr.attr, + NULL, +}; + +static struct attribute *swpld1_attrs[] = { + //SWPLD1 + &sensor_dev_attr_swpld1_reg_value.dev_attr.attr, + &sensor_dev_attr_swpld1_reg_addr.dev_attr.attr, + &sensor_dev_attr_board_id.dev_attr.attr, + &sensor_dev_attr_bcm88375_rst.dev_attr.attr, + &sensor_dev_attr_b54616s_rst.dev_attr.attr, + &sensor_dev_attr_psu1_en.dev_attr.attr, + &sensor_dev_attr_psu2_en.dev_attr.attr, + &sensor_dev_attr_psu1_pwr_fan_ok.dev_attr.attr, + &sensor_dev_attr_psu2_pwr_fan_ok.dev_attr.attr, + &sensor_dev_attr_psu2_present.dev_attr.attr, + &sensor_dev_attr_psu1_present.dev_attr.attr, + &sensor_dev_attr_psu2_pwr_int.dev_attr.attr, + &sensor_dev_attr_psu1_pwr_int.dev_attr.attr, + &sensor_dev_attr_bcm88375_int.dev_attr.attr, + &sensor_dev_attr_bcm54616s_irq.dev_attr.attr, + &sensor_dev_attr_led_sys.dev_attr.attr, + &sensor_dev_attr_led_pwr.dev_attr.attr, + &sensor_dev_attr_led_fan.dev_attr.attr, + &sensor_dev_attr_psu_i2c_sel.dev_attr.attr, + &sensor_dev_attr_fan1_led.dev_attr.attr, + &sensor_dev_attr_fan2_led.dev_attr.attr, + &sensor_dev_attr_fan3_led.dev_attr.attr, + &sensor_dev_attr_fan4_led.dev_attr.attr, + &sensor_dev_attr_fan_i2c_sel.dev_attr.attr, + //SFP, QSFP + &sensor_dev_attr_sfp_select_port.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_lp_mode.dev_attr.attr, + &sensor_dev_attr_sfp_reset.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + NULL, +}; + +static struct attribute *swpld2_attrs[] = { + &sensor_dev_attr_swpld2_reg_value.dev_attr.attr, + &sensor_dev_attr_swpld2_reg_addr.dev_attr.attr, + NULL, +}; + +static struct attribute *swpld3_attrs[] = { + &sensor_dev_attr_swpld3_reg_value.dev_attr.attr, + &sensor_dev_attr_swpld3_reg_addr.dev_attr.attr, + &sensor_dev_attr_qsfp_i2c_sel.dev_attr.attr, + &sensor_dev_attr_sfp_chan_en.dev_attr.attr, + &sensor_dev_attr_sfp_sel.dev_attr.attr, + NULL, +}; + +static struct attribute_group cpld_attr_grp = { + .attrs = cpld_attrs, +}; + +static struct attribute_group swpld1_attr_grp = { + .attrs = swpld1_attrs, +}; + +static struct attribute_group swpld2_attr_grp = { + .attrs = swpld2_attrs, +}; + +static struct attribute_group swpld3_attr_grp = { + .attrs = swpld3_attrs, +}; + +static int __init cpld_probe(struct platform_device *pdev) +{ + struct cpld_platform_data *pdata; + struct i2c_adapter *parent; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "CPLD platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(BUS0); + if (!parent) { + printk(KERN_WARNING "Parent adapter (%d) not found\n", BUS0); + return -ENODEV; + } + + pdata[system_cpld].client = i2c_new_dummy(parent, pdata[system_cpld].reg_addr); + if (!pdata[system_cpld].client) { + printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[system_cpld].reg_addr); + goto error; + } + + kobj_cpld = &pdev->dev.kobj; + ret = sysfs_create_group(&pdev->dev.kobj, &cpld_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + goto error; + } + + return 0; + +error: + kobject_put(kobj_cpld); + i2c_unregister_device(pdata[system_cpld].client); + i2c_put_adapter(parent); + + return -ENODEV; +} + +static int __init swpld1_probe(struct platform_device *pdev) +{ + struct cpld_platform_data *pdata; + struct i2c_adapter *parent; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD1 platform data not found\n"); + return -ENODEV; + } + parent = i2c_get_adapter(BUS7); + if (!parent) { + printk(KERN_WARNING "Parent adapter (%d) not found\n", BUS7); + return -ENODEV; + } + + pdata[swpld1].client = i2c_new_dummy(parent, pdata[swpld1].reg_addr); + if (!pdata[swpld1].client) { + printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[swpld1].reg_addr); + goto error; + } + + kobj_swpld1 = &pdev->dev.kobj; + ret = sysfs_create_group(&pdev->dev.kobj, &swpld1_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create swpld attribute group"); + goto error; + } + return 0; + +error: + kobject_put(kobj_swpld1); + i2c_unregister_device(pdata[swpld1].client); + i2c_put_adapter(parent); + return -ENODEV; +} + +static int __init swpld2_probe(struct platform_device *pdev) +{ + struct cpld_platform_data *pdata; + struct i2c_adapter *parent; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD2 platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(BUS7); + if (!parent) { + printk(KERN_WARNING "Parent adapter (%d) not found\n", BUS7); + return -ENODEV; + } + + pdata[swpld2].client = i2c_new_dummy(parent, pdata[swpld2].reg_addr); + if (!pdata[swpld2].client) { + printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[swpld2].reg_addr); + goto error; + } + + kobj_swpld2 = &pdev->dev.kobj; + ret = sysfs_create_group(&pdev->dev.kobj, &swpld2_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create swpld attribute group"); + goto error; + } + + return 0; + +error: + kobject_put(kobj_swpld2); + i2c_unregister_device(pdata[swpld2].client); + i2c_put_adapter(parent); + + return -ENODEV; +} + +static int __init swpld3_probe(struct platform_device *pdev) +{ + struct cpld_platform_data *pdata; + struct i2c_adapter *parent; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD3 platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(BUS7); + if (!parent) { + printk(KERN_WARNING "Parent adapter (%d) not found\n", BUS7); + return -ENODEV; + } + + pdata[swpld3].client = i2c_new_dummy(parent, pdata[swpld3].reg_addr); + if (!pdata[swpld3].client) { + printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[swpld3].reg_addr); + goto error; + } + + kobj_swpld3 = &pdev->dev.kobj; + ret = sysfs_create_group(&pdev->dev.kobj, &swpld3_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create swpld attribute group"); + goto error; + } + + return 0; + +error: + kobject_put(kobj_swpld3); + i2c_unregister_device(pdata[swpld3].client); + i2c_put_adapter(parent); + + return -ENODEV; +} + +static int __exit cpld_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + sysfs_remove_group(&pdev->dev.kobj, &cpld_attr_grp); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[system_cpld].client) { + if (!parent) { + parent = (pdata[system_cpld].client)->adapter; + } + i2c_unregister_device(pdata[system_cpld].client); + } + } + i2c_put_adapter(parent); + + return 0; +} + +static int __exit swpld1_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + sysfs_remove_group(&pdev->dev.kobj, &swpld1_attr_grp); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[swpld1].client) { + if (!parent) { + parent = (pdata[swpld1].client)->adapter; + } + i2c_unregister_device(pdata[swpld1].client); + } + } + i2c_put_adapter(parent); + return 0; +} + +static int __exit swpld2_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + sysfs_remove_group(&pdev->dev.kobj, &swpld2_attr_grp); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[swpld2].client) { + if (!parent) { + parent = (pdata[swpld2].client)->adapter; + } + i2c_unregister_device(pdata[swpld2].client); + } + } + i2c_put_adapter(parent); + return 0; +} + +static int __exit swpld3_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + sysfs_remove_group(&pdev->dev.kobj, &swpld3_attr_grp); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[swpld3].client) { + if (!parent) { + parent = (pdata[swpld3].client)->adapter; + } + i2c_unregister_device(pdata[swpld3].client); + } + } + i2c_put_adapter(parent); + return 0; +} + +static struct platform_driver cpld_driver = { + .probe = cpld_probe, + .remove = __exit_p(cpld_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc7648sv1-cpld", + }, +}; + +static struct platform_driver swpld1_driver = { + .probe = swpld1_probe, + .remove = __exit_p(swpld1_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc7648sv1-swpld1", + }, +}; + +static struct platform_driver swpld2_driver = { + .probe = swpld2_probe, + .remove = __exit_p(swpld2_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc7648sv1-swpld2", + }, +}; + +static struct platform_driver swpld3_driver = { + .probe = swpld3_probe, + .remove = __exit_p(swpld3_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc7648sv1-swpld3", + }, +}; +/* ---------------- CPLD - end ------------- */ + +/* ---------------- MUX - start ------------- */ +struct cpld_mux_platform_data { + int parent; + int base_nr; + struct i2c_client *cpld; + int reg_addr; +}; + +struct cpld_mux { + struct i2c_adapter *parent; + struct i2c_adapter **child; + struct cpld_mux_platform_data data; +}; + +static struct cpld_mux_platform_data agc7648sv1_cpld_mux_platform_data[] = { + { + .parent = BUS0, + .base_nr = BUS0_BASE_NUM, + .cpld = NULL, + .reg_addr = BUS0_MUX_REG, + }, +}; + +static struct cpld_mux_platform_data agc7648sv1_swpld1_mux_platform_data[] = { + { + .parent = BUS5, + .base_nr = BUS5_BASE_NUM, + .cpld = NULL, + .reg_addr = BUS5_MUX_REG, + }, + { + .parent = BUS6, + .base_nr = BUS6_BASE_NUM, + .cpld = NULL, + .reg_addr = BUS6_MUX_REG, + }, +}; + +static struct cpld_mux_platform_data agc7648sv1_swpld3_mux_platform_data[] = { + { + .parent = BUS2, + .base_nr = BUS2_QSFP_BASE_NUM, + .cpld = NULL, + .reg_addr = BUS2_QSFP_MUX_REG, + }, + { + .parent = BUS2, + .base_nr = BUS2_SFP_BASE_NUM, + .cpld = NULL, + .reg_addr = BUS2_SFP_MUX_REG, + }, +}; + +static struct platform_device cpld_mux_device[] = +{ + { + .name = "delta-agc7648sv1-cpld-mux", + .id = 0, + .dev = { + .platform_data = &agc7648sv1_cpld_mux_platform_data[0], + .release = device_release, + }, + }, +}; + +static struct platform_device swpld1_mux_device[] = +{ + { + .name = "delta-agc7648sv1-swpld1-mux", + .id = 0, + .dev = { + .platform_data = &agc7648sv1_swpld1_mux_platform_data[0], + .release = device_release, + }, + }, + { + .name = "delta-agc7648sv1-swpld1-mux", + .id = 1, + .dev = { + .platform_data = &agc7648sv1_swpld1_mux_platform_data[1], + .release = device_release, + }, + }, +}; + +static struct platform_device swpld3_mux_device[] = +{ + { + .name = "delta-agc7648sv1-swpld3-mux", + .id = 0, + .dev = { + .platform_data = &agc7648sv1_swpld3_mux_platform_data[0], + .release = device_release, + }, + }, + { + .name = "delta-agc7648sv1-swpld3-mux", + .id = 1, + .dev = { + .platform_data = &agc7648sv1_swpld3_mux_platform_data[1], + .release = device_release, + }, + }, +}; + +static int cpld_reg_write_byte(struct i2c_client *client, u8 regaddr, u8 val) +{ + union i2c_smbus_data data; + + data.byte = val; + return client->adapter->algo->smbus_xfer(client->adapter, client->addr, + client->flags, + I2C_SMBUS_WRITE, + regaddr, I2C_SMBUS_BYTE_DATA, &data); +} + +static int cpld_mux_select(struct i2c_mux_core *muxc, u32 chan) +{ + struct cpld_mux *mux = i2c_mux_priv(muxc); + u8 cpld_mux_val = 0; + + if ( mux->data.base_nr == BUS0_BASE_NUM ){ + switch (chan) { + case 0: + cpld_mux_val = MUX_VAL_IDEEPROM; + break; + case 1: + cpld_mux_val = MUX_VAL_SERDES_SWPLD3; + break; + case 2: + default: + cpld_mux_val = MUX_VAL_PCA9547; + break; + } + } + else + { + printk(KERN_ERR "CPLD mux select error\n"); + return 0; + } + return cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr, (u8)(cpld_mux_val & 0xff)); +} + +static int swpld1_mux_select(struct i2c_mux_core *muxc, u32 chan) +{ + struct cpld_mux *mux = i2c_mux_priv(muxc); + u8 swpld1_mux_val = 0; + u8 bmc_swpld1_mux_val = 0; + int ret; + uint8_t cmd_data[4] = {0}; + uint8_t set_cmd; + int cmd_data_len; + + ret = dni_bmc_exist_check(); + if(ret == 0) //BMC monitor on + { + if ( mux->data.base_nr == BUS5_BASE_NUM ){ + switch (chan) { + case 0: + bmc_swpld1_mux_val = MUX_VAL_FAN_TMP75; + break; + case 1: + bmc_swpld1_mux_val = MUX_VAL_FAN_IO_CTL; + break; + case 2: + bmc_swpld1_mux_val = (MUX_VAL_FAN1_EEPROM + 0x08); + break; + case 3: + bmc_swpld1_mux_val = (MUX_VAL_FAN2_EEPROM + 0x09); + break; + case 4: + bmc_swpld1_mux_val = (MUX_VAL_FAN3_EEPROM + 0x09); + break; + case 5: + bmc_swpld1_mux_val = (MUX_VAL_FAN4_EEPROM + 0x09); + break; + case 6: + bmc_swpld1_mux_val = (MUX_VAL_FAN_CTL + 0x08); + break; + default: + bmc_swpld1_mux_val = (MUX_VAL_FAN_CTL + 0x08); + break; + } + + set_cmd = CMD_SETDATA; + cmd_data[0] = BMC_SWPLD_BUS; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = BUS5_MUX_REG; + cmd_data[3] = bmc_swpld1_mux_val; + cmd_data_len = sizeof(cmd_data); + } + else if ( mux->data.base_nr == BUS6_BASE_NUM ){ + switch (chan) { + case 0: + bmc_swpld1_mux_val = MUX_VAL_PSU1; + break; + case 1: + bmc_swpld1_mux_val = MUX_VAL_PSU2; + break; + default: + bmc_swpld1_mux_val = MUX_VAL_PSU1; + break; + } + + set_cmd = CMD_SETDATA; + cmd_data[0] = BMC_SWPLD_BUS; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = BUS6_MUX_REG; + cmd_data[3] = bmc_swpld1_mux_val; + cmd_data_len = sizeof(cmd_data); + } + else + { + printk(KERN_ERR "SWPLD1 mux select error\n"); + return 0; + } + return dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + } + else //BMC monitor off or BMC is not exist + { + if ( mux->data.base_nr == BUS5_BASE_NUM ){ + switch (chan) { + case 0: + swpld1_mux_val = MUX_VAL_FAN1_EEPROM; + break; + case 1: + swpld1_mux_val = MUX_VAL_FAN2_EEPROM; + break; + case 2: + swpld1_mux_val = MUX_VAL_FAN3_EEPROM; + break; + case 3: + swpld1_mux_val = MUX_VAL_FAN4_EEPROM; + break; + case 4: + swpld1_mux_val = MUX_VAL_FAN_CTL; + break; + case 5: + swpld1_mux_val = MUX_VAL_FAN_TMP75; + break; + case 6: + swpld1_mux_val = MUX_VAL_FAN_IO_CTL; + break; + default: + swpld1_mux_val = MUX_VAL_FAN_CTL; + break; + } + } + else if ( mux->data.base_nr == BUS6_BASE_NUM ){ + switch (chan) { + case 0: + swpld1_mux_val = MUX_VAL_PSU1; + break; + case 1: + swpld1_mux_val = MUX_VAL_PSU2; + break; + default: + swpld1_mux_val = MUX_VAL_PSU1; + break; + } + } + else + { + printk(KERN_ERR "SWPLD1 mux select error\n"); + return 0; + } + return cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr, (u8)(swpld1_mux_val & 0xff)); + } +} + +static int swpld3_mux_select(struct i2c_mux_core *muxc, u32 chan) +{ + struct cpld_mux *mux = i2c_mux_priv(muxc); + struct device *i2cdev = kobj_to_dev(kobj_swpld1); + struct cpld_platform_data *pdata = i2cdev->platform_data; + u8 swpld3_mux_val = 0; + u8 swpld3_qsfp_ch_en = 0; + u8 swpld1_qsfp_modsel_val = 0; + int ret; + uint8_t cmd_data[4] = {0}; + uint8_t set_cmd; + int cmd_data_len; + + ret = dni_bmc_exist_check(); + + if ( mux->data.base_nr == BUS2_QSFP_BASE_NUM ){ + /* QSFP module selection */ + swpld1_qsfp_modsel_val = SWPLD1_QSFP_MODSEL_VAL & (~(1 << chan)); + if (ret == 0) //BMC monitor on + { + set_cmd = CMD_SETDATA; + cmd_data[0] = BMC_SWPLD_BUS; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = SWPLD1_QSFP_MODSEL_REG; + cmd_data[3] = swpld1_qsfp_modsel_val; + cmd_data_len = sizeof(cmd_data); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + } + else //BMC monitor off or BMC is not exist + { + if (cpld_reg_write_byte(pdata[swpld1].client, SWPLD1_QSFP_MODSEL_REG, swpld1_qsfp_modsel_val) < 0) + return -EIO; + } + + /* QSFP channel enable */ + swpld3_qsfp_ch_en |= SWPLD3_QSFP_CH_EN << 4; + if (cpld_reg_write_byte(mux->data.cpld, BUS2_SFP_MUX_REG, swpld3_qsfp_ch_en) < 0) + return -EIO; + + /* QSFP channel selection */ + swpld3_mux_val = chan; + } + else if ( mux->data.base_nr == BUS2_SFP_BASE_NUM ){ + /* SFP port 51-59, 9 ports, chan 0-8 */ + if ( chan < SWPLD3_SFP_PORT_9 ){ + swpld3_qsfp_ch_en |= SWPLD3_SFP_CH1_EN << 4; + swpld3_mux_val = swpld3_qsfp_ch_en | (chan + 1); + } + /* SFP port 60-69, 10 ports, chan 9-18 */ + else if ( chan >= SWPLD3_SFP_PORT_9 && chan < SWPLD3_SFP_PORT_19 ){ + swpld3_qsfp_ch_en |= SWPLD3_SFP_CH2_EN << 4; + swpld3_mux_val = swpld3_qsfp_ch_en | (chan - SWPLD3_SFP_PORT_9); + } + /* SFP port 70-79, 10 ports, chan 19-28 */ + else if ( chan >= SWPLD3_SFP_PORT_19 && chan < SWPLD3_SFP_PORT_29 ){ + swpld3_qsfp_ch_en |= SWPLD3_SFP_CH3_EN << 4; + swpld3_mux_val = swpld3_qsfp_ch_en | (chan - SWPLD3_SFP_PORT_19); + } + /* SFP port 80-89, 10 ports, chan 29-38 */ + else if ( chan >= SWPLD3_SFP_PORT_29 && chan < SWPLD3_SFP_PORT_39 ){ + swpld3_qsfp_ch_en |= SWPLD3_SFP_CH4_EN << 4; + swpld3_mux_val = swpld3_qsfp_ch_en | (chan - SWPLD3_SFP_PORT_29); + } + /* SFP port 90-98, 9 ports, chan 39-47 */ + else if ( chan >= SWPLD3_SFP_PORT_39 && chan < SWPLD3_SFP_PORT_48 ){ + swpld3_qsfp_ch_en |= SWPLD3_SFP_CH5_EN << 4; + swpld3_mux_val = swpld3_qsfp_ch_en | (chan - SWPLD3_SFP_PORT_39); + } + else { + swpld3_qsfp_ch_en |= SWPLD3_SFP_CH_DISABLE << 4; + swpld3_mux_val = swpld3_qsfp_ch_en; + } + } + else { + printk(KERN_ERR "SWPLD3 mux select error\n"); + return 0; + } + return cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr, (u8)(swpld3_mux_val & 0xff)); +} + +static int __init cpld_mux_probe(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc; + struct cpld_mux *mux; + struct cpld_mux_platform_data *pdata; + struct i2c_adapter *parent; + int i, ret, dev_num; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "CPLD platform data not found\n"); + return -ENODEV; + } + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) { + printk(KERN_ERR "Failed to allocate memory for mux\n"); + return -ENOMEM; + } + mux->data = *pdata; + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + kfree(mux); + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent); + return -ENODEV; + } + /* Judge bus number to decide how many devices*/ + switch (pdata->parent) { + case BUS0: + dev_num = BUS0_DEV_NUM; + break; + default : + dev_num = DEF_DEV_NUM; + break; + } + muxc = i2c_mux_alloc(parent, &pdev->dev, dev_num, 0, 0, cpld_mux_select, NULL); + if (!muxc) { + ret = -ENOMEM; + goto alloc_failed; + } + muxc->priv = mux; + platform_set_drvdata(pdev, muxc); + + for (i = 0; i < dev_num; i++) + { + int nr = pdata->base_nr + i; + unsigned int class = 0; + ret = i2c_mux_add_adapter(muxc, nr, i, class); + if (ret) { + dev_err(&pdev->dev, "Failed to add adapter %d\n", i); + goto add_adapter_failed; + } + } + dev_info(&pdev->dev, "%d port mux on %s adapter\n", dev_num, parent->name); + return 0; + +add_adapter_failed: + i2c_mux_del_adapters(muxc); +alloc_failed: + kfree(mux); + i2c_put_adapter(parent); + return ret; +} + +static int __init swpld1_mux_probe(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc; + struct cpld_mux *mux; + struct cpld_mux_platform_data *pdata; + struct i2c_adapter *parent; + int i, ret, dev_num; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD1 platform data not found\n"); + return -ENODEV; + } + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) { + printk(KERN_ERR "Failed to allocate memory for mux\n"); + return -ENOMEM; + } + mux->data = *pdata; + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + kfree(mux); + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent); + return -ENODEV; + } + /* Judge bus number to decide how many devices*/ + switch (pdata->parent) { + case BUS5: + dev_num = BUS5_DEV_NUM; + break; + case BUS6: + dev_num = BUS6_DEV_NUM; + break; + default : + dev_num = DEF_DEV_NUM; + break; + } + + muxc = i2c_mux_alloc(parent, &pdev->dev, dev_num, 0, 0, swpld1_mux_select, NULL); + if (!muxc) { + ret = -ENOMEM; + goto alloc_failed; + } + muxc->priv = mux; + platform_set_drvdata(pdev, muxc); + for (i = 0; i < dev_num; i++) + { + int nr = pdata->base_nr + i; + unsigned int class = 0; + ret = i2c_mux_add_adapter(muxc, nr, i, class); + if (ret) { + dev_err(&pdev->dev, "Failed to add adapter %d\n", i); + goto add_adapter_failed; + } + } + dev_info(&pdev->dev, "%d port mux on %s adapter\n", dev_num, parent->name); + return 0; + +add_adapter_failed: + i2c_mux_del_adapters(muxc); +alloc_failed: + kfree(mux); + i2c_put_adapter(parent); + + return ret; +} + +static int __init swpld3_mux_probe(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc; + struct cpld_mux *mux; + struct cpld_mux_platform_data *pdata; + struct i2c_adapter *parent; + int i, ret, dev_num; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD3 platform data not found\n"); + return -ENODEV; + } + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) { + printk(KERN_ERR "Failed to allocate memory for mux\n"); + return -ENOMEM; + } + mux->data = *pdata; + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + kfree(mux); + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent); + return -ENODEV; + } + /* Judge bus number to decide how many devices*/ + switch (pdata->base_nr) { + case BUS2_QSFP_BASE_NUM: + dev_num = BUS2_QSFP_DEV_NUM; + break; + case BUS2_SFP_BASE_NUM: + dev_num = BUS2_SFP_DEV_NUM; + break; + default : + dev_num = DEF_DEV_NUM; + break; + } + + muxc = i2c_mux_alloc(parent, &pdev->dev, dev_num, 0, 0, swpld3_mux_select, NULL); + if (!muxc) { + ret = -ENOMEM; + goto alloc_failed; + } + muxc->priv = mux; + platform_set_drvdata(pdev, muxc); + for (i = 0; i < dev_num; i++) + { + int nr = pdata->base_nr + i; + unsigned int class = 0; + ret = i2c_mux_add_adapter(muxc, nr, i, class); + if (ret) { + dev_err(&pdev->dev, "Failed to add adapter %d\n", i); + goto add_adapter_failed; + } + } + dev_info(&pdev->dev, "%d port mux on %s adapter\n", dev_num, parent->name); + return 0; + +add_adapter_failed: + i2c_mux_del_adapters(muxc); +alloc_failed: + kfree(mux); + i2c_put_adapter(parent); + + return ret; +} + +static int __exit cpld_mux_remove(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc = platform_get_drvdata(pdev); + struct i2c_adapter *parent = muxc->parent; + + i2c_mux_del_adapters(muxc); + i2c_put_adapter(parent); + + return 0; +} + +static int __exit swpld1_mux_remove(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc = platform_get_drvdata(pdev); + struct i2c_adapter *parent = muxc->parent; + + i2c_mux_del_adapters(muxc); + i2c_put_adapter(parent); + + return 0; +} + +static int __exit swpld3_mux_remove(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc = platform_get_drvdata(pdev); + struct i2c_adapter *parent = muxc->parent; + + i2c_mux_del_adapters(muxc); + i2c_put_adapter(parent); + + return 0; +} + +static struct platform_driver cpld_mux_driver = { + .probe = cpld_mux_probe, + .remove = __exit_p(cpld_mux_remove), /* TODO */ + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc7648sv1-cpld-mux", + }, +}; + +static struct platform_driver swpld1_mux_driver = { + .probe = swpld1_mux_probe, + .remove = __exit_p(swpld1_mux_remove), /* TODO */ + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc7648sv1-swpld1-mux", + }, +}; + +static struct platform_driver swpld3_mux_driver = { + .probe = swpld3_mux_probe, + .remove = __exit_p(swpld3_mux_remove), /* TODO */ + .driver = { + .owner = THIS_MODULE, + .name = "delta-agc7648sv1-swpld3-mux", + }, +}; +/* ---------------- MUX - end ------------- */ + +/* ---------------- module initialization ------------- */ +static int __init delta_agc7648sv1_platform_init(void) +{ +// struct i2c_client *client; + struct i2c_adapter *adapter; + struct cpld_mux_platform_data *cpld_mux_pdata; + struct cpld_platform_data *cpld_pdata; + struct cpld_mux_platform_data *swpld1_mux_pdata; + struct cpld_platform_data *swpld1_pdata; + struct cpld_mux_platform_data *swpld3_mux_pdata; + struct cpld_platform_data *swpld3_pdata; + int ret,i = 0; + + mutex_init(&dni_lock); + printk("agc7648sv1_platform module initialization\n"); + + ret = dni_create_user(); + if (ret != 0) { + printk(KERN_WARNING "Fail to create IPMI user\n"); + } + + ret = platform_driver_register(&cpld_driver); + if (ret) { + printk(KERN_WARNING "Fail to register cpupld driver\n"); + goto error_cpld_driver; + } + + // set the SWPLD prob and remove + ret = platform_driver_register(&swpld1_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld driver\n"); + goto error_swpld1_driver; + } + + // set the SWPLD prob and remove + ret = platform_driver_register(&swpld2_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld driver\n"); + goto error_swpld2_driver; + } + + // set the SWPLD prob and remove + ret = platform_driver_register(&swpld3_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld driver\n"); + goto error_swpld3_driver; + } + + // register the mux prob which call the SWPLD + ret = platform_driver_register(&cpld_mux_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld mux driver\n"); + goto error_cpld_mux_driver; + } + + // register the mux prob which call the SWPLD + ret = platform_driver_register(&swpld1_mux_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld1 mux driver\n"); + goto error_swpld1_mux_driver; + } + + // register the mux prob which call the SWPLD3 + ret = platform_driver_register(&swpld3_mux_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld3 mux driver\n"); + goto error_swpld3_mux_driver; + } + + // register the i2c devices + ret = platform_driver_register(&i2c_device_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_driver; + } + + // register the CPUPLD + ret = platform_device_register(&cpld_device); + if (ret) { + printk(KERN_WARNING "Fail to create cpupld device\n"); + goto error_cpld_device; + } + + // link the CPLD and the Mux + cpld_pdata = agc7648sv1_cpld_platform_data; + for (i = 0; i < ARRAY_SIZE(cpld_mux_device); i++) + { + cpld_mux_pdata = cpld_mux_device[i].dev.platform_data; + cpld_mux_pdata->cpld = cpld_pdata[system_cpld].client; + ret = platform_device_register(&cpld_mux_device[i]); + if (ret) { + printk(KERN_WARNING "Fail to create swpld mux %d\n", i); + goto error_cpld_mux; + } + } + + adapter = i2c_get_adapter(BUS3); + i2c_client_9547 = i2c_new_device(adapter, &i2c_info_pca9547[0]); + i2c_put_adapter(adapter); + + // register the SWPLD1 + ret = platform_device_register(&swpld1_device); + if (ret) { + printk(KERN_WARNING "Fail to create swpld1 device\n"); + goto error_swpld1_device; + } + + // register the SWPLD2 + ret = platform_device_register(&swpld2_device); + if (ret) { + printk(KERN_WARNING "Fail to create swpld2 device\n"); + goto error_swpld2_device; + } + + // register the SWPLD3 + ret = platform_device_register(&swpld3_device); + if (ret) { + printk(KERN_WARNING "Fail to create swpld3 device\n"); + goto error_swpld3_device; + } + + // link the SWPLD1 and the Mux + swpld1_pdata = agc7648sv1_swpld1_platform_data; + for (i = 0; i < ARRAY_SIZE(swpld1_mux_device); i++) + { + swpld1_mux_pdata = swpld1_mux_device[i].dev.platform_data; + swpld1_mux_pdata->cpld = swpld1_pdata[swpld1].client; + ret = platform_device_register(&swpld1_mux_device[i]); + if (ret) { + printk(KERN_WARNING "Fail to create swpld1 mux %d\n", i); + goto error_agc7648sv1_swpld1_mux; + } + } + + // link the SWPLD3 and the Mux + swpld3_pdata = agc7648sv1_swpld3_platform_data; + for (i = 0; i < ARRAY_SIZE(swpld3_mux_device); i++) + { + swpld3_mux_pdata = swpld3_mux_device[i].dev.platform_data; + swpld3_mux_pdata->cpld = swpld3_pdata[swpld3].client; + ret = platform_device_register(&swpld3_mux_device[i]); + if (ret) { + printk(KERN_WARNING "Fail to create swpld3 mux %d\n", i); + goto error_agc7648sv1_swpld3_mux; + } + } + + for (i = 0; i < ARRAY_SIZE(agc7648sv1_i2c_device); i++) + { + ret = platform_device_register(&agc7648sv1_i2c_device[i]); + if (ret) + { + printk(KERN_WARNING "Fail to create i2c device %d\n", i); + goto error_agc7648sv1_i2c_device; + } + } + if (ret) + goto error_cpld_mux; + return 0; + +error_agc7648sv1_i2c_device: + i--; + for (; i >= 0; i--) { + platform_device_unregister(&agc7648sv1_i2c_device[i]); + } + i = ARRAY_SIZE(swpld3_mux_device); +error_agc7648sv1_swpld3_mux: + i--; + for (; i >= 0; i--) { + platform_device_unregister(&swpld3_mux_device[i]); + } + i = ARRAY_SIZE(swpld1_mux_device); +error_agc7648sv1_swpld1_mux: + i--; + for (; i >= 0; i--) { + platform_device_unregister(&swpld1_mux_device[i]); + } + platform_device_unregister(&swpld3_device); +error_swpld3_device: + platform_device_unregister(&swpld2_device); +error_swpld2_device: + platform_device_unregister(&swpld1_device); +error_swpld1_device: + i2c_unregister_device(i2c_client_9547); + i = ARRAY_SIZE(cpld_mux_device); +error_cpld_mux: + i--; + for (; i >= 0; i--) { + platform_device_unregister(&cpld_mux_device[i]); + } + platform_device_unregister(&cpld_device); +error_cpld_device: + platform_driver_unregister(&i2c_device_driver); +error_i2c_device_driver: + platform_driver_unregister(&swpld3_mux_driver); +error_swpld3_mux_driver: + platform_driver_unregister(&swpld1_mux_driver); +error_swpld1_mux_driver: + platform_driver_unregister(&cpld_mux_driver); +error_cpld_mux_driver: + platform_driver_unregister(&swpld3_driver); +error_swpld3_driver: + platform_driver_unregister(&swpld2_driver); +error_swpld2_driver: + platform_driver_unregister(&swpld1_driver); +error_swpld1_driver: + platform_driver_unregister(&cpld_driver); +error_cpld_driver: + return ret; +} + +static void __exit delta_agc7648sv1_platform_exit(void) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(agc7648sv1_i2c_device); i++) { + platform_device_unregister(&agc7648sv1_i2c_device[i]); + } + + for (i = 0; i < ARRAY_SIZE(swpld3_mux_device); i++) { + platform_device_unregister(&swpld3_mux_device[i]); + } + + for (i = 0; i < ARRAY_SIZE(swpld1_mux_device); i++) { + platform_device_unregister(&swpld1_mux_device[i]); + } + + platform_device_unregister(&swpld1_device); + platform_driver_unregister(&swpld1_driver); + + platform_device_unregister(&swpld2_device); + platform_driver_unregister(&swpld2_driver); + + platform_device_unregister(&swpld3_device); + platform_driver_unregister(&swpld3_driver); + + i2c_unregister_device(i2c_client_9547); + + for (i = 0; i < ARRAY_SIZE(cpld_mux_device); i++) { + platform_device_unregister(&cpld_mux_device[i]); + } + + platform_driver_unregister(&i2c_device_driver); + platform_driver_unregister(&swpld3_mux_driver); + platform_driver_unregister(&swpld1_mux_driver); + platform_driver_unregister(&cpld_mux_driver); + platform_device_unregister(&cpld_device); + platform_driver_unregister(&cpld_driver); +} + +module_init(delta_agc7648sv1_platform_init); +module_exit(delta_agc7648sv1_platform_exit); + +MODULE_DESCRIPTION("DELTA agc7648sv1 Platform Support"); +MODULE_AUTHOR("Stanley Chi "); +MODULE_LICENSE("GPL"); diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/dni_agc7648sv1_psu.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/dni_agc7648sv1_psu.c new file mode 100644 index 00000000..4ba6e2c8 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/dni_agc7648sv1_psu.c @@ -0,0 +1,495 @@ +/* + * An hwmon driver for delta AGV7648SV1 PSU + * dps_800ab_16_d.c - Support for DPS-800AB-16 D Power Supply Module + * + * Copyright (C) 2017 Delta Networks, Inc. + * + * Aries Lin + * + * Based on ym2651y.c + * Based on ad7414.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Address scanned */ +static const unsigned short normal_i2c[] = { 0x58, I2C_CLIENT_END }; + +/* This is additional data */ +struct dps_800ab_16_d_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 v_in; + u16 v_out; + u16 i_in; + u16 i_out; + u16 p_in; + u16 p_out; + u16 temp_input[2]; + u8 fan_fault; + u16 fan_duty_cycle[2]; + u16 fan_speed[2]; + u8 mfr_model[14]; + u8 mfr_serial[14]; +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count); +static ssize_t for_linear_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); +static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); +static int dps_800ab_16_d_read_byte(struct i2c_client *client, u8 reg); +static int dps_800ab_16_d_read_word(struct i2c_client *client, u8 reg); +static int dps_800ab_16_d_write_word(struct i2c_client *client, u8 reg, \ + u16 value); +static int dps_800ab_16_d_read_block(struct i2c_client *client, u8 command, \ + u8 *data, int data_len); +static struct dps_800ab_16_d_data *dps_800ab_16_d_update_device( \ + struct device *dev); +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); + +enum dps_800ab_16_d_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_FAN1_FAULT, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct i2c_client *client = to_i2c_client(dev); + struct dps_800ab_16_d_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + dps_800ab_16_d_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t for_linear_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct dps_800ab_16_d_data *data = dps_800ab_16_d_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct dps_800ab_16_d_data *data = dps_800ab_16_d_update_device(dev); + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct dps_800ab_16_d_data *data = dps_800ab_16_d_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + return (exponent > 0) ? sprintf(buf, "%d\n", \ + mantissa * (1 << exponent)) : \ + sprintf(buf, "%d\n", mantissa / (1 << -exponent) * multiplier); + +} + +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct dps_800ab_16_d_data *data = dps_800ab_16_d_update_device(dev); + u8 *ptr = NULL; + + if (!data->valid) + return 0; + + switch (attr->index) { + case PSU_MFR_MODEL: + ptr = data->mfr_model + 1; + break; + case PSU_MFR_SERIAL: + ptr = data->mfr_serial + 1; + break; + default: + return 0; + } + return sprintf(buf, "%s\n", ptr); +} +static int dps_800ab_16_d_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int dps_800ab_16_d_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int dps_800ab_16_d_write_word(struct i2c_client *client, u8 reg, \ + u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags |= I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_WORD_DATA, &data); + +} + +static int dps_800ab_16_d_read_block(struct i2c_client *client, u8 command, \ + u8 *data, int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, + data); + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; +abort: + return result; +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct dps_800ab_16_d_data *dps_800ab_16_d_update_device( \ + struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct dps_800ab_16_d_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated)) { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = { + {0x20, &data->vout_mode}, + {0x81, &data->fan_fault} + }; + struct reg_data_word regs_word[] = { + {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x90, &(data->fan_speed[0])}, + }; + + dev_dbg(&client->dev, "start data update\n"); + + /* one milliseconds from now */ + data->last_updated = jiffies + HZ / 1000; + + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = dps_800ab_16_d_read_byte(client, + regs_byte[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + } else { + *(regs_byte[i].value) = status; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = dps_800ab_16_d_read_word(client, + regs_word[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + } else { + *(regs_word[i].value) = status; + } + } + + command = 0x9a; /* PSU mfr_model */ + status = dps_800ab_16_d_read_block(client, command, + data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, + status); + data->mfr_model[0] = '\0'; + } + + command = 0x9e; /* PSU mfr_serial */ + status = dps_800ab_16_d_read_block(client, command, + data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, + status); + data->mfr_serial[0] = '\0'; + } + + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, \ + S_IRUGO | S_IWUSR, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); + +static struct attribute *dps_800ab_16_d_attributes[] = { + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + NULL +}; + +static const struct attribute_group dps_800ab_16_d_group = { + .attrs = dps_800ab_16_d_attributes, +}; + +static int dps_800ab_16_d_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct dps_800ab_16_d_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "new chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &dps_800ab_16_d_group); + if (status) + goto exit_sysfs_create_group; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_hwmon_device_register; + } + + return 0; + +exit_hwmon_device_register: + sysfs_remove_group(&client->dev.kobj, &dps_800ab_16_d_group); +exit_sysfs_create_group: + kfree(data); +exit: + return status; +} + +static int dps_800ab_16_d_remove(struct i2c_client *client) +{ + struct dps_800ab_16_d_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &dps_800ab_16_d_group); + kfree(data); + + return 0; +} + +enum id_name { + dni_agc7648sv1_psu, + dps_800ab_16_d +}; + +static const struct i2c_device_id dps_800ab_16_d_id[] = { + { "dni_agc7648sv1_psu", dni_agc7648sv1_psu }, + { "dps_800ab_16_d", dps_800ab_16_d }, + {} +}; +MODULE_DEVICE_TABLE(i2c, dps_800ab_16_d_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver dps_800ab_16_d_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "dps_800ab_16_d", + }, + .probe = dps_800ab_16_d_probe, + .remove = dps_800ab_16_d_remove, + .id_table = dps_800ab_16_d_id, + .address_list = normal_i2c, +}; + +static int __init dps_800ab_16_d_init(void) +{ + return i2c_add_driver(&dps_800ab_16_d_driver); +} + +static void __exit dps_800ab_16_d_exit(void) +{ + i2c_del_driver(&dps_800ab_16_d_driver); +} + + +MODULE_AUTHOR("Aries Lin "); +MODULE_DESCRIPTION("DPS_800AB_16_D Driver"); +MODULE_LICENSE("GPL"); + +module_init(dps_800ab_16_d_init); +module_exit(dps_800ab_16_d_exit); diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/dni_emc2305.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/dni_emc2305.c new file mode 100644 index 00000000..73d9900a --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/dni_emc2305.c @@ -0,0 +1,381 @@ +/* + * + * + * Copyright (C) 2017 Delta Networks, Inc. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms ofthe GNU General Public License as + * published by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * + * + * + * + * A hwmon driver for the SMSC EMC2305 fan controller + * Complete datasheet is available (6/2013) at: + * http://www.smsc.com/media/Downloads_Public/Data_Sheets/2305.pdf + */ + +#include +#include +#include +#include +#include + + +static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count); +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf); +static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count); +static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, + char *buf); +static ssize_t set_fan_percentage(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count); +static ssize_t show_fan_percentage(struct device *dev, struct device_attribute * devattr, + char *buf); +static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, 0x2F, 0x4C, + 0x4D, I2C_CLIENT_END + }; + + +#define EMC2305_REG_DEVICE 0xFD +#define EMC2305_REG_VENDOR 0xFE + +//#define FAN_MINIMUN 0x33 /*20%*/ +#define FAN_MINIMUN 0x0 /*0%*/ +#define FAN_RPM_BASED 0xAB + +#define EMC2305_REG_FAN_DRIVE(n) (0x30 + 0x10 * n) +#define EMC2305_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * n) +#define EMC2305_REG_FAN_TACH(n) (0x3E + 0x10 * n) +#define EMC2305_REG_FAN_CONF(n) (0x32 + 0x10 * n) +#define EMC2305_REG_FAN_REAR_H_RPM(n) (0x3D + 0x10 * n) +#define EMC2305_REG_FAN_REAR_L_RPM(n) (0x3C + 0x10 * n) + +#define EMC2305_DEVICE 0x34 +#define EMC2305_VENDOR 0x5D +#define MAX_FAN_SPEED 23000 + +struct emc2305_data +{ + struct device *hwmon_dev; + struct attribute_group attrs; + struct mutex lock; +}; + +static int emc2305_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int emc2305_detect(struct i2c_client *client, + struct i2c_board_info *info); +static int emc2305_remove(struct i2c_client *client); + +static const struct i2c_device_id emc2305_id[] = +{ + { "emc2305", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, emc2305_id); + +static struct i2c_driver emc2305_driver = +{ + .class = I2C_CLASS_HWMON, + .driver = { + .name = "emc2305", + }, + .probe = emc2305_probe, + .remove = emc2305_remove, + .id_table = emc2305_id, + .detect = emc2305_detect, + .address_list = normal_i2c, +}; + +static SENSOR_DEVICE_ATTR(fan1_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 1); +static SENSOR_DEVICE_ATTR(fan3_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 2); +static SENSOR_DEVICE_ATTR(fan4_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 3); +static SENSOR_DEVICE_ATTR(fan5_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 4); +static SENSOR_DEVICE_ATTR(fan1_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 0); +static SENSOR_DEVICE_ATTR(fan2_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 1); +static SENSOR_DEVICE_ATTR(fan3_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 2); +static SENSOR_DEVICE_ATTR(fan4_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 3); +static SENSOR_DEVICE_ATTR(fan5_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 4); +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); +static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); +static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); +static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); +static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 4); + +static struct attribute *emc2305_attr[] = +{ + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan1_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan2_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan3_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan4_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan5_input_percentage.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + &sensor_dev_attr_pwm4.dev_attr.attr, + &sensor_dev_attr_pwm5.dev_attr.attr, + NULL +}; + +static ssize_t show_fan_percentage(struct device *dev, struct device_attribute * devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2305_data *data = i2c_get_clientdata(client); + int val; + + mutex_lock(&data->lock); + val = i2c_smbus_read_word_swapped(client, + EMC2305_REG_FAN_TACH(attr->index)); + mutex_unlock(&data->lock); + /* Left shift 3 bits for showing correct RPM */ + val = val >> 3; + if ((int)(3932160 * 2 / (val > 0 ? val : 1) == 960))return sprintf(buf, "%d\n", 0); + return sprintf(buf, "%d\n", (int)(3932160 * 2 / (val > 0 ? val : 1) * 100 / MAX_FAN_SPEED)); +} + + +static ssize_t set_fan_percentage(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2305_data *data = i2c_get_clientdata(client); + unsigned long hsb, lsb; + unsigned long tech; + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + { + return ret; + } + if (val > 100) + { + return -EINVAL; + } + + if (val <= 5) + { + hsb = 0xff; /*high bit*/ + lsb = 0xe0; /*low bit*/ + } + else + { + val = val * 230; + tech = (3932160 * 2) / (val > 0 ? val : 1); + hsb = (uint8_t)(((tech << 3) >> 8) & 0x0ff); + lsb = (uint8_t)((tech << 3) & 0x0f8); + } + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_REAR_H_RPM(attr->index), hsb); + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_REAR_L_RPM(attr->index), lsb); + mutex_unlock(&data->lock); + return count; +} + + +static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2305_data *data = i2c_get_clientdata(client); + int val; + + + mutex_lock(&data->lock); + val = i2c_smbus_read_word_swapped(client, + EMC2305_REG_FAN_TACH(attr->index)); + mutex_unlock(&data->lock); + /* Left shift 3 bits for showing correct RPM */ + val = val >> 3; + return sprintf(buf, "%d\n", 3932160 * 2 / (val > 0 ? val : 1)); +} + +static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2305_data *data = i2c_get_clientdata(client); + unsigned long hsb, lsb; + unsigned long tech; + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + { + return ret; + } + if (val > 23000) + { + return -EINVAL; + } + + if (val <= 960) + { + hsb = 0xff; /*high bit*/ + lsb = 0xe0; /*low bit*/ + } + else + { + tech = (3932160 * 2) / (val > 0 ? val : 1); + hsb = (uint8_t)(((tech << 3) >> 8) & 0x0ff); + lsb = (uint8_t)((tech << 3) & 0x0f8); + } + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_REAR_H_RPM(attr->index), hsb); + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_REAR_L_RPM(attr->index), lsb); + mutex_unlock(&data->lock); + return count; +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2305_data *data = i2c_get_clientdata(client); + int val; + + mutex_lock(&data->lock); + val = i2c_smbus_read_byte_data(client, + EMC2305_REG_FAN_DRIVE(attr->index)); + mutex_unlock(&data->lock); + return sprintf(buf, "%d\n", val); +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2305_data *data = i2c_get_clientdata(client); + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + { + return ret; + } + if (val > 255) + { + return -EINVAL; + } + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(client, + EMC2305_REG_FAN_DRIVE(attr->index), + val); + mutex_unlock(&data->lock); + return count; +} + +static int emc2305_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + int vendor, device; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + { + return -ENODEV; + } + + vendor = i2c_smbus_read_byte_data(client, EMC2305_REG_VENDOR); + if (vendor != EMC2305_VENDOR) + { + return -ENODEV; + } + + device = i2c_smbus_read_byte_data(client, EMC2305_REG_DEVICE); + if (device != EMC2305_DEVICE) + { + return -ENODEV; + } + + strlcpy(info->type, "emc2305", I2C_NAME_SIZE); + + return 0; +} + +static int emc2305_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct emc2305_data *data; + int err; + int i; + + data = devm_kzalloc(&client->dev, sizeof(struct emc2305_data), + GFP_KERNEL); + if (!data) + { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->lock); + + dev_info(&client->dev, "%s chip found\n", client->name); + + data->attrs.attrs = emc2305_attr; + err = sysfs_create_group(&client->dev.kobj, &data->attrs); + if (err) + { + return err; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) + { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + for (i = 0; i < 5; i++) + { + /* set minimum drive to 0% */ + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_MIN_DRIVE(i), FAN_MINIMUN); + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_CONF(i), FAN_RPM_BASED); + } + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->attrs); + return err; +} + +static int emc2305_remove(struct i2c_client *client) +{ + struct emc2305_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->attrs); + return 0; +} + +module_i2c_driver(emc2305_driver); + +MODULE_AUTHOR("Neal Tai"); +MODULE_DESCRIPTION("SMSC EMC2305 fan controller driver"); +MODULE_LICENSE("GPL"); diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/tmp401.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/tmp401.c new file mode 100644 index 00000000..eeeed2c7 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/modules/builds/tmp401.c @@ -0,0 +1,796 @@ +/* tmp401.c + * + * Copyright (C) 2007,2008 Hans de Goede + * Preliminary tmp411 support by: + * Gabriel Konat, Sander Leget, Wouter Willems + * Copyright (C) 2009 Andre Prendel + * + * Cleanup and support for TMP431 and TMP432 by Guenter Roeck + * Copyright (c) 2013 Guenter Roeck + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Driver for the Texas Instruments TMP401 SMBUS temperature sensor IC. + * + * Note this IC is in some aspect similar to the LM90, but it has quite a + * few differences too, for example the local temp has a higher resolution + * and thus has 16 bits registers for its value and limit instead of 8 bits. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d, + 0x4e, 0x4f, I2C_CLIENT_END }; + +enum chips { tmp401, tmp411, tmp431, tmp432, tmp435, tmp461 }; + +/* + * The TMP401 registers, note some registers have different addresses for + * reading and writing + */ +#define TMP401_STATUS 0x02 +#define TMP401_CONFIG_READ 0x03 +#define TMP401_CONFIG_WRITE 0x09 +#define TMP401_CONVERSION_RATE_READ 0x04 +#define TMP401_CONVERSION_RATE_WRITE 0x0A +#define TMP401_TEMP_CRIT_HYST 0x21 +#define TMP401_MANUFACTURER_ID_REG 0xFE +#define TMP401_DEVICE_ID_REG 0xFF + +static const u8 TMP401_TEMP_MSB_READ[7][2] = { + { 0x00, 0x01 }, /* temp */ + { 0x06, 0x08 }, /* low limit */ + { 0x05, 0x07 }, /* high limit */ + { 0x20, 0x19 }, /* therm (crit) limit */ + { 0x30, 0x34 }, /* lowest */ + { 0x32, 0x36 }, /* highest */ + { 0, 0x11 }, /* offset */ +}; + +static const u8 TMP401_TEMP_MSB_WRITE[7][2] = { + { 0, 0 }, /* temp (unused) */ + { 0x0C, 0x0E }, /* low limit */ + { 0x0B, 0x0D }, /* high limit */ + { 0x20, 0x19 }, /* therm (crit) limit */ + { 0x30, 0x34 }, /* lowest */ + { 0x32, 0x36 }, /* highest */ + { 0, 0x11 }, /* offset */ +}; + +static const u8 TMP401_TEMP_LSB[7][2] = { + { 0x15, 0x10 }, /* temp */ + { 0x17, 0x14 }, /* low limit */ + { 0x16, 0x13 }, /* high limit */ + { 0, 0 }, /* therm (crit) limit (unused) */ + { 0x31, 0x35 }, /* lowest */ + { 0x33, 0x37 }, /* highest */ + { 0, 0x12 }, /* offset */ +}; + +static const u8 TMP432_TEMP_MSB_READ[4][3] = { + { 0x00, 0x01, 0x23 }, /* temp */ + { 0x06, 0x08, 0x16 }, /* low limit */ + { 0x05, 0x07, 0x15 }, /* high limit */ + { 0x20, 0x19, 0x1A }, /* therm (crit) limit */ +}; + +static const u8 TMP432_TEMP_MSB_WRITE[4][3] = { + { 0, 0, 0 }, /* temp - unused */ + { 0x0C, 0x0E, 0x16 }, /* low limit */ + { 0x0B, 0x0D, 0x15 }, /* high limit */ + { 0x20, 0x19, 0x1A }, /* therm (crit) limit */ +}; + +static const u8 TMP432_TEMP_LSB[3][3] = { + { 0x29, 0x10, 0x24 }, /* temp */ + { 0x3E, 0x14, 0x18 }, /* low limit */ + { 0x3D, 0x13, 0x17 }, /* high limit */ +}; + +/* [0] = fault, [1] = low, [2] = high, [3] = therm/crit */ +static const u8 TMP432_STATUS_REG[] = { + 0x1b, 0x36, 0x35, 0x37 }; + +/* Flags */ +#define TMP401_CONFIG_RANGE BIT(2) +#define TMP401_CONFIG_SHUTDOWN BIT(6) +#define TMP401_STATUS_LOCAL_CRIT BIT(0) +#define TMP401_STATUS_REMOTE_CRIT BIT(1) +#define TMP401_STATUS_REMOTE_OPEN BIT(2) +#define TMP401_STATUS_REMOTE_LOW BIT(3) +#define TMP401_STATUS_REMOTE_HIGH BIT(4) +#define TMP401_STATUS_LOCAL_LOW BIT(5) +#define TMP401_STATUS_LOCAL_HIGH BIT(6) + +/* On TMP432, each status has its own register */ +#define TMP432_STATUS_LOCAL BIT(0) +#define TMP432_STATUS_REMOTE1 BIT(1) +#define TMP432_STATUS_REMOTE2 BIT(2) + +/* Manufacturer / Device ID's */ +#define TMP401_MANUFACTURER_ID 0x55 +#define TMP401_DEVICE_ID 0x11 +#define TMP411A_DEVICE_ID 0x12 +#define TMP411B_DEVICE_ID 0x13 +#define TMP411C_DEVICE_ID 0x10 +#define TMP431_DEVICE_ID 0x31 +#define TMP432_DEVICE_ID 0x32 +#define TMP435_DEVICE_ID 0x35 + +/* + * Driver data (common to all clients) + */ + +static const struct i2c_device_id tmp401_id[] = { + { "tmp401", tmp401 }, + { "tmp411", tmp411 }, + { "tmp431", tmp431 }, + { "tmp432", tmp432 }, + { "tmp435", tmp435 }, + { "tmp461", tmp461 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tmp401_id); + +/* + * Client data (each client gets its own) + */ + +struct tmp401_data { + struct i2c_client *client; + const struct attribute_group *groups[3]; + struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + enum chips kind; + + unsigned int update_interval; /* in milliseconds */ + + /* register values */ + u8 status[4]; + u8 config; + u16 temp[7][3]; + u8 temp_crit_hyst; +}; + +/* + * Sysfs attr show / store functions + */ + +static int tmp401_register_to_temp(u16 reg, u8 config) +{ + int temp = reg; + + if (config & TMP401_CONFIG_RANGE) + temp -= 64 * 256; + + return DIV_ROUND_CLOSEST(temp * 125, 32); +} + +static u16 tmp401_temp_to_register(long temp, u8 config, int zbits) +{ + if (config & TMP401_CONFIG_RANGE) { + temp = clamp_val(temp, -64000, 191000); + temp += 64000; + } else + temp = clamp_val(temp, 0, 127000); + + return DIV_ROUND_CLOSEST(temp * (1 << (8 - zbits)), 1000) << zbits; +} + +static int tmp401_update_device_reg16(struct i2c_client *client, + struct tmp401_data *data) +{ + int i, j, val; + int num_regs = data->kind == tmp411 ? 6 : 4; + int num_sensors = data->kind == tmp432 ? 3 : 2; + + for (i = 0; i < num_sensors; i++) { /* local / r1 / r2 */ + for (j = 0; j < num_regs; j++) { /* temp / low / ... */ + u8 regaddr; + /* + * High byte must be read first immediately followed + * by the low byte + */ + regaddr = data->kind == tmp432 ? + TMP432_TEMP_MSB_READ[j][i] : + TMP401_TEMP_MSB_READ[j][i]; + val = i2c_smbus_read_byte_data(client, regaddr); + if (val < 0) + return val; + data->temp[j][i] = val << 8; + if (j == 3) /* crit is msb only */ + continue; + regaddr = data->kind == tmp432 ? TMP432_TEMP_LSB[j][i] + : TMP401_TEMP_LSB[j][i]; + val = i2c_smbus_read_byte_data(client, regaddr); + if (val < 0) + return val; + data->temp[j][i] |= val; + } + } + return 0; +} + +static struct tmp401_data *tmp401_update_device(struct device *dev) +{ + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + struct tmp401_data *ret = data; + int i, val; + unsigned long next_update; + + mutex_lock(&data->update_lock); + + next_update = data->last_updated + + msecs_to_jiffies(data->update_interval); + if (time_after(jiffies, next_update) || !data->valid) { + if (data->kind != tmp432) { + /* + * The driver uses the TMP432 status format internally. + * Convert status to TMP432 format for other chips. + */ + val = i2c_smbus_read_byte_data(client, TMP401_STATUS); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + data->status[0] = + (val & TMP401_STATUS_REMOTE_OPEN) >> 1; + data->status[1] = + ((val & TMP401_STATUS_REMOTE_LOW) >> 2) | + ((val & TMP401_STATUS_LOCAL_LOW) >> 5); + data->status[2] = + ((val & TMP401_STATUS_REMOTE_HIGH) >> 3) | + ((val & TMP401_STATUS_LOCAL_HIGH) >> 6); + data->status[3] = val & (TMP401_STATUS_LOCAL_CRIT + | TMP401_STATUS_REMOTE_CRIT); + } else { + for (i = 0; i < ARRAY_SIZE(data->status); i++) { + val = i2c_smbus_read_byte_data(client, + TMP432_STATUS_REG[i]); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + data->status[i] = val; + } + } + + val = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + data->config = val; + val = tmp401_update_device_reg16(client, data); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + val = i2c_smbus_read_byte_data(client, TMP401_TEMP_CRIT_HYST); + if (val < 0) { + ret = ERR_PTR(val); + goto abort; + } + data->temp_crit_hyst = val; + + data->last_updated = jiffies; + data->valid = 1; + } + +abort: + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t show_temp(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int nr = to_sensor_dev_attr_2(devattr)->nr; + int index = to_sensor_dev_attr_2(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + return sprintf(buf, "%d\n", + tmp401_register_to_temp(data->temp[nr][index], data->config)); +} + +static ssize_t show_temp_crit_hyst(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int temp, index = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + mutex_lock(&data->update_lock); + temp = tmp401_register_to_temp(data->temp[3][index], data->config); + temp -= data->temp_crit_hyst * 1000; + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", temp); +} + +static ssize_t show_status(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int nr = to_sensor_dev_attr_2(devattr)->nr; + int mask = to_sensor_dev_attr_2(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + return sprintf(buf, "%d\n", !!(data->status[nr] & mask)); +} + +static ssize_t store_temp(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + int nr = to_sensor_dev_attr_2(devattr)->nr; + int index = to_sensor_dev_attr_2(devattr)->index; + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + long val; + u16 reg; + u8 regaddr; + + if (kstrtol(buf, 10, &val)) + return -EINVAL; + + reg = tmp401_temp_to_register(val, data->config, nr == 3 ? 8 : 4); + + mutex_lock(&data->update_lock); + + regaddr = data->kind == tmp432 ? TMP432_TEMP_MSB_WRITE[nr][index] + : TMP401_TEMP_MSB_WRITE[nr][index]; + i2c_smbus_write_byte_data(client, regaddr, reg >> 8); + if (nr != 3) { + regaddr = data->kind == tmp432 ? TMP432_TEMP_LSB[nr][index] + : TMP401_TEMP_LSB[nr][index]; + i2c_smbus_write_byte_data(client, regaddr, reg & 0xFF); + } + data->temp[nr][index] = reg; + + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + int temp, index = to_sensor_dev_attr(devattr)->index; + struct tmp401_data *data = tmp401_update_device(dev); + long val; + u8 reg; + + if (IS_ERR(data)) + return PTR_ERR(data); + + if (kstrtol(buf, 10, &val)) + return -EINVAL; + + if (data->config & TMP401_CONFIG_RANGE) + val = clamp_val(val, -64000, 191000); + else + val = clamp_val(val, 0, 127000); + + mutex_lock(&data->update_lock); + temp = tmp401_register_to_temp(data->temp[3][index], data->config); + val = clamp_val(val, temp - 255000, temp); + reg = ((temp - val) + 500) / 1000; + + i2c_smbus_write_byte_data(data->client, TMP401_TEMP_CRIT_HYST, + reg); + + data->temp_crit_hyst = reg; + + mutex_unlock(&data->update_lock); + + return count; +} + +/* + * Resets the historical measurements of minimum and maximum temperatures. + * This is done by writing any value to any of the minimum/maximum registers + * (0x30-0x37). + */ +static ssize_t reset_temp_history(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) +{ + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + long val; + + if (kstrtol(buf, 10, &val)) + return -EINVAL; + + if (val != 1) { + dev_err(dev, + "temp_reset_history value %ld not supported. Use 1 to reset the history!\n", + val); + return -EINVAL; + } + mutex_lock(&data->update_lock); + i2c_smbus_write_byte_data(client, TMP401_TEMP_MSB_WRITE[5][0], val); + data->valid = 0; + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_update_interval(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmp401_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%u\n", data->update_interval); +} + +static ssize_t set_update_interval(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + unsigned long val; + int err, rate; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + /* + * For valid rates, interval can be calculated as + * interval = (1 << (7 - rate)) * 125; + * Rounded rate is therefore + * rate = 7 - __fls(interval * 4 / (125 * 3)); + * Use clamp_val() to avoid overflows, and to ensure valid input + * for __fls. + */ + val = clamp_val(val, 125, 16000); + rate = 7 - __fls(val * 4 / (125 * 3)); + mutex_lock(&data->update_lock); + i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, rate); + data->update_interval = (1 << (7 - rate)) * 125; + mutex_unlock(&data->update_lock); + + return count; +} + +static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0); +static SENSOR_DEVICE_ATTR_2(temp1_min, S_IWUSR | S_IRUGO, show_temp, + store_temp, 1, 0); +static SENSOR_DEVICE_ATTR_2(temp1_max, S_IWUSR | S_IRUGO, show_temp, + store_temp, 2, 0); +static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IWUSR | S_IRUGO, show_temp, + store_temp, 3, 0); +static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, + show_temp_crit_hyst, store_temp_crit_hyst, 0); +static SENSOR_DEVICE_ATTR_2(temp1_min_alarm, S_IRUGO, show_status, NULL, + 1, TMP432_STATUS_LOCAL); +static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, show_status, NULL, + 2, TMP432_STATUS_LOCAL); +static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, show_status, NULL, + 3, TMP432_STATUS_LOCAL); +static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1); +static SENSOR_DEVICE_ATTR_2(temp2_min, S_IWUSR | S_IRUGO, show_temp, + store_temp, 1, 1); +static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp, + store_temp, 2, 1); +static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IWUSR | S_IRUGO, show_temp, + store_temp, 3, 1); +static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, + NULL, 1); +static SENSOR_DEVICE_ATTR_2(temp2_fault, S_IRUGO, show_status, NULL, + 0, TMP432_STATUS_REMOTE1); +static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, show_status, NULL, + 1, TMP432_STATUS_REMOTE1); +static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, show_status, NULL, + 2, TMP432_STATUS_REMOTE1); +static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, show_status, NULL, + 3, TMP432_STATUS_REMOTE1); + +static DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval, + set_update_interval); + +static struct attribute *tmp401_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + + &dev_attr_update_interval.attr, + + NULL +}; + +static const struct attribute_group tmp401_group = { + .attrs = tmp401_attributes, +}; + +/* + * Additional features of the TMP411 chip. + * The TMP411 stores the minimum and maximum + * temperature measured since power-on, chip-reset, or + * minimum and maximum register reset for both the local + * and remote channels. + */ +static SENSOR_DEVICE_ATTR_2(temp1_lowest, S_IRUGO, show_temp, NULL, 4, 0); +static SENSOR_DEVICE_ATTR_2(temp1_highest, S_IRUGO, show_temp, NULL, 5, 0); +static SENSOR_DEVICE_ATTR_2(temp2_lowest, S_IRUGO, show_temp, NULL, 4, 1); +static SENSOR_DEVICE_ATTR_2(temp2_highest, S_IRUGO, show_temp, NULL, 5, 1); +static SENSOR_DEVICE_ATTR(temp_reset_history, S_IWUSR, NULL, reset_temp_history, + 0); + +static struct attribute *tmp411_attributes[] = { + &sensor_dev_attr_temp1_highest.dev_attr.attr, + &sensor_dev_attr_temp1_lowest.dev_attr.attr, + &sensor_dev_attr_temp2_highest.dev_attr.attr, + &sensor_dev_attr_temp2_lowest.dev_attr.attr, + &sensor_dev_attr_temp_reset_history.dev_attr.attr, + NULL +}; + +static const struct attribute_group tmp411_group = { + .attrs = tmp411_attributes, +}; + +static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2); +static SENSOR_DEVICE_ATTR_2(temp3_min, S_IWUSR | S_IRUGO, show_temp, + store_temp, 1, 2); +static SENSOR_DEVICE_ATTR_2(temp3_max, S_IWUSR | S_IRUGO, show_temp, + store_temp, 2, 2); +static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IWUSR | S_IRUGO, show_temp, + store_temp, 3, 2); +static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, + NULL, 2); +static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_status, NULL, + 0, TMP432_STATUS_REMOTE2); +static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, show_status, NULL, + 1, TMP432_STATUS_REMOTE2); +static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, show_status, NULL, + 2, TMP432_STATUS_REMOTE2); +static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, show_status, NULL, + 3, TMP432_STATUS_REMOTE2); + +static struct attribute *tmp432_attributes[] = { + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp3_fault.dev_attr.attr, + &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, + + NULL +}; + +static const struct attribute_group tmp432_group = { + .attrs = tmp432_attributes, +}; + +/* + * Additional features of the TMP461 chip. + * The TMP461 temperature offset for the remote channel. + */ +static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IWUSR | S_IRUGO, show_temp, + store_temp, 6, 1); + +static struct attribute *tmp461_attributes[] = { + &sensor_dev_attr_temp2_offset.dev_attr.attr, + NULL +}; + +static const struct attribute_group tmp461_group = { + .attrs = tmp461_attributes, +}; + +/* + * Begin non sysfs callback code (aka Real code) + */ + +static int tmp401_init_client(struct tmp401_data *data, + struct i2c_client *client) +{ + int config, config_orig, status = 0; + + /* Set the conversion rate to 2 Hz */ + i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5); + data->update_interval = 500; + + /* Start conversions (disable shutdown if necessary) */ + config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); + if (config < 0) + return config; + + config_orig = config; + config &= ~TMP401_CONFIG_SHUTDOWN; + + if (config != config_orig) + status = i2c_smbus_write_byte_data(client, + TMP401_CONFIG_WRITE, + config); + + return status; +} + +static int tmp401_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + enum chips kind; + struct i2c_adapter *adapter = client->adapter; + u8 reg; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + /* Detect and identify the chip */ + reg = i2c_smbus_read_byte_data(client, TMP401_MANUFACTURER_ID_REG); + if (reg != TMP401_MANUFACTURER_ID) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG); + + switch (reg) { + case TMP401_DEVICE_ID: + if (client->addr != 0x4c) + return -ENODEV; + kind = tmp401; + break; + case TMP411A_DEVICE_ID: + if (client->addr != 0x4c) + return -ENODEV; + kind = tmp411; + break; + case TMP411B_DEVICE_ID: + if (client->addr != 0x4d) + return -ENODEV; + kind = tmp411; + break; + case TMP411C_DEVICE_ID: + if (client->addr != 0x4e) + return -ENODEV; + kind = tmp411; + break; + case TMP431_DEVICE_ID: + if (client->addr != 0x4c && client->addr != 0x4d) + return -ENODEV; + kind = tmp431; + break; + case TMP432_DEVICE_ID: + if (client->addr != 0x4c && client->addr != 0x4d) + return -ENODEV; + kind = tmp432; + break; + case TMP435_DEVICE_ID: + kind = tmp435; + break; + default: + return -ENODEV; + } + + reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); + if (reg & 0x1b) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, TMP401_CONVERSION_RATE_READ); + /* Datasheet says: 0x1-0x6 */ + if (reg > 15) + return -ENODEV; + + strlcpy(info->type, tmp401_id[kind].name, I2C_NAME_SIZE); + + return 0; +} + +static int tmp401_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + static const char * const names[] = { + "TMP401", "TMP411", "TMP431", "TMP432", "TMP435", "TMP461" + }; + struct device *dev = &client->dev; + struct device *hwmon_dev; + struct tmp401_data *data; + int groups = 0, status; + + data = devm_kzalloc(dev, sizeof(struct tmp401_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->client = client; + mutex_init(&data->update_lock); + data->kind = id->driver_data; + + /* Initialize the TMP401 chip */ + status = tmp401_init_client(data, client); + if (status < 0) + return status; + + /* Register sysfs hooks */ + data->groups[groups++] = &tmp401_group; + + /* Register additional tmp411 sysfs hooks */ + if (data->kind == tmp411) + data->groups[groups++] = &tmp411_group; + + /* Register additional tmp432 sysfs hooks */ + if (data->kind == tmp432) + data->groups[groups++] = &tmp432_group; + + if (data->kind == tmp461) + data->groups[groups++] = &tmp461_group; + + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, data->groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + + dev_info(dev, "Detected TI %s chip\n", names[data->kind]); + + return 0; +} + +static struct i2c_driver tmp401_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "tmp401", + }, + .probe = tmp401_probe, + .id_table = tmp401_id, + .detect = tmp401_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(tmp401_driver); + +MODULE_AUTHOR("Hans de Goede "); +MODULE_DESCRIPTION("Texas Instruments TMP401 temperature sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/Makefile b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/PKG.yml b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/PKG.yml new file mode 100644 index 00000000..eee0b187 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/PKG.yml @@ -0,0 +1 @@ +!include $ONL_TEMPLATES/onlp-platform-any.yml PLATFORM=x86-64-delta-agc7648sv1 ARCH=amd64 TOOLCHAIN=x86_64-linux-gnu diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/Makefile b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/Makefile new file mode 100644 index 00000000..e7437cb2 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/Makefile @@ -0,0 +1,2 @@ +FILTER=src +include $(ONL)/make/subdirs.mk diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/lib/Makefile b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/lib/Makefile new file mode 100644 index 00000000..2b1ca74c --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/lib/Makefile @@ -0,0 +1,45 @@ +############################################################ +# +# +# Copyright 2014 BigSwitch Networks, Inc. +# +# Licensed under the Eclipse Public License, Version 1.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.eclipse.org/legal/epl-v10.html +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific +# language governing permissions and limitations under the +# License. +# +# +############################################################ +# +# +############################################################ +include $(ONL)/make/config.amd64.mk + +MODULE := libonlp-x86-64-delta-agc7648sv1 +include $(BUILDER)/standardinit.mk + +DEPENDMODULES := AIM IOF x86_64_delta_agc7648sv1 onlplib +DEPENDMODULE_HEADERS := sff + +include $(BUILDER)/dependmodules.mk + +SHAREDLIB := libonlp-x86-64-delta-agc7648sv1.so +$(SHAREDLIB)_TARGETS := $(ALL_TARGETS) +include $(BUILDER)/so.mk +.DEFAULT_GOAL := $(SHAREDLIB) + +GLOBAL_CFLAGS += -I$(onlp_BASEDIR)/module/inc +GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1 +GLOBAL_CFLAGS += -fPIC +GLOBAL_LINK_LIBS += -lpthread + +include $(BUILDER)/targets.mk + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/lib/libonlp-x86-64-delta-agc7648sv1-r0.mk b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/lib/libonlp-x86-64-delta-agc7648sv1-r0.mk new file mode 100644 index 00000000..16e01bbf --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/lib/libonlp-x86-64-delta-agc7648sv1-r0.mk @@ -0,0 +1,10 @@ + +############################################################################### +# +# Inclusive Makefile for the libonlp-x86-64-delta-agc7648sv1-r0 module. +# +# Autogenerated 2016-03-16 22:11:47.698846 +# +############################################################################### +libonlp-x86-64-delta-agc7648sv1-r0_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/onlpdump/Makefile b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/onlpdump/Makefile new file mode 100644 index 00000000..bf472fe6 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/onlpdump/Makefile @@ -0,0 +1,46 @@ +############################################################ +# +# +# Copyright 2014 BigSwitch Networks, Inc. +# +# Licensed under the Eclipse Public License, Version 1.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.eclipse.org/legal/epl-v10.html +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific +# language governing permissions and limitations under the +# License. +# +# +############################################################ +# +# +# +############################################################ +include $(ONL)/make/config.amd64.mk + +.DEFAULT_GOAL := onlpdump + +MODULE := onlpdump +include $(BUILDER)/standardinit.mk + +DEPENDMODULES := AIM IOF onlp x86_64_delta_agc7648sv1 onlplib onlp_platform_defaults sff cjson cjson_util timer_wheel OS + +include $(BUILDER)/dependmodules.mk + +BINARY := onlpdump +$(BINARY)_LIBRARIES := $(LIBRARY_TARGETS) +include $(BUILDER)/bin.mk + +GLOBAL_CFLAGS += -DAIM_CONFIG_AIM_MAIN_FUNCTION=onlpdump_main +GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1 +GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MAIN=1 +GLOBAL_LINK_LIBS += -lpthread -lm + +include $(BUILDER)/targets.mk + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/.module b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/.module new file mode 100644 index 00000000..b9e80409 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/.module @@ -0,0 +1 @@ +name: x86_64_delta_agc7648sv1 diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/Makefile b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/Makefile new file mode 100644 index 00000000..e385dfe2 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/Makefile @@ -0,0 +1,10 @@ +############################################################ +# +# +# +############################################################ +include $(ONL)/make/config.mk + +MODULE := x86_64_delta_agc7648sv1 +AUTOMODULE := x86_64_delta_agc7648sv1 +include $(BUILDER)/definemodule.mk diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/auto/make.mk b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/auto/make.mk new file mode 100755 index 00000000..8f4a18e0 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/auto/make.mk @@ -0,0 +1,10 @@ +############################################################################### +# +# x86_64_delta_agc7648sv1 Autogeneration +# +############################################################################### + +x86_64_delta_agc7648sv1_AUTO_DEFS := module/auto/x86_64_delta_agc7648sv1.yml +x86_64_delta_agc7648sv1_AUTO_DIRS := module/inc/x86_64_delta_agc7648sv1 module/src +include $(BUILDER)/auto.mk + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/auto/x86_64_delta_agc7648sv1.yml b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/auto/x86_64_delta_agc7648sv1.yml new file mode 100755 index 00000000..99d94f52 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/auto/x86_64_delta_agc7648sv1.yml @@ -0,0 +1,55 @@ +############################################################################### +# +# x86_64_delta_agc7648sv1 Autogeneration Definitions. +# +############################################################################### + +cdefs: &cdefs +- X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_LOGGING: + doc: "Include or exclude logging." + default: 1 +- X86_64_DELTA_AGC7648SV1_CONFIG_LOG_OPTIONS_DEFAULT: + doc: "Default enabled log options." + default: AIM_LOG_OPTIONS_DEFAULT +- X86_64_DELTA_AGC7648SV1_CONFIG_LOG_BITS_DEFAULT: + doc: "Default enabled log bits." + default: AIM_LOG_BITS_DEFAULT +- X86_64_DELTA_AGC7648SV1_CONFIG_LOG_CUSTOM_BITS_DEFAULT: + doc: "Default enabled custom log bits." + default: 0 +- X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB: + doc: "Default all porting macros to use the C standard libraries." + default: 1 +- X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS: + doc: "Include standard library headers for stdlib porting macros." + default: X86_64_DELTA_agc7648sv1_CONFIG_PORTING_STDLIB +- X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_UCLI: + doc: "Include generic uCli support." + default: 0 +- X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION: + doc: "Assume chassis fan direction is the same as the PSU fan direction." + default: 0 +- X86_64_DELTA_AGC7648SV1_CONFIG_SFP_COUNT: + doc: "SFP port numbers." + default: 4 +- X86_64_DELTA_AGC7648SV1_CONFIG_FAN_RPM_MAX: + doc: "Max fan speed." + default: 18000 + +definitions: + cdefs: + X86_64_DELTA_AGC7648SV1_CONFIG_HEADER: + defs: *cdefs + basename: x86_64_delta_agc7648sv1_config + + portingmacro: + X86_64_DELTA_agc7648sv1: + macros: + - malloc + - free + - memset + - memcpy + - strncpy + - vsnprintf + - snprintf + - strlen diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1.x b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1.x new file mode 100644 index 00000000..e7839305 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1.x @@ -0,0 +1,16 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ + + +#include + +/* <--auto.start.xmacro(ALL).define> */ +/* */ + +/* <--auto.start.xenum(ALL).define> */ +/* */ + + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1_config.h b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1_config.h new file mode 100755 index 00000000..84bdbedf --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1_config.h @@ -0,0 +1,157 @@ +/**************************************************************************//** + * + * @file + * @brief x86_64_delta_agc7648sv1 Configuration Header + * + * @addtogroup x86_64_delta_agc7648sv1-config + * @{ + * + *****************************************************************************/ +#ifndef __X86_64_DELTA_AGC7648SV1_CONFIG_H__ +#define __X86_64_DELTA_AGC7648SV1_CONFIG_H__ + +#ifdef GLOBAL_INCLUDE_CUSTOM_CONFIG +#include +#endif +#ifdef X86_64_DELTA_AGC7648SV1_INCLUDE_CUSTOM_CONFIG +#include +#endif + +/* */ +#include +/** + * X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_LOGGING + * + * Include or exclude logging. */ + + +#ifndef X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_LOGGING +#define X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_LOGGING 1 +#endif + +/** + * X86_64_DELTA_AGC7648SV1_CONFIG_LOG_OPTIONS_DEFAULT + * + * Default enabled log options. */ + + +#ifndef X86_64_DELTA_AGC7648SV1_CONFIG_LOG_OPTIONS_DEFAULT +#define X86_64_DELTA_AGC7648SV1_CONFIG_LOG_OPTIONS_DEFAULT AIM_LOG_OPTIONS_DEFAULT +#endif + +/** + * X86_64_DELTA_AGC7648SV1_CONFIG_LOG_BITS_DEFAULT + * + * Default enabled log bits. */ + + +#ifndef X86_64_DELTA_AGC7648SV1_CONFIG_LOG_BITS_DEFAULT +#define X86_64_DELTA_AGC7648SV1_CONFIG_LOG_BITS_DEFAULT AIM_LOG_BITS_DEFAULT +#endif + +/** + * X86_64_DELTA_AGC7648SV1_CONFIG_LOG_CUSTOM_BITS_DEFAULT + * + * Default enabled custom log bits. */ + + +#ifndef X86_64_DELTA_AGC7648SV1_CONFIG_LOG_CUSTOM_BITS_DEFAULT +#define X86_64_DELTA_AGC7648SV1_CONFIG_LOG_CUSTOM_BITS_DEFAULT 0 +#endif + +/** + * X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB + * + * Default all porting macros to use the C standard libraries. */ + + +#ifndef X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB +#define X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB 1 +#endif + +/** + * X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS + * + * Include standard library headers for stdlib porting macros. */ + + +#ifndef X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS +#define X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS X86_64_DELTA_agc7648sv1_CONFIG_PORTING_STDLIB +#endif + +/** + * X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_UCLI + * + * Include generic uCli support. */ + + +#ifndef X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_UCLI +#define X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_UCLI 0 +#endif + +/** + * X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION + * + * Assume chassis fan direction is the same as the PSU fan direction. */ + + +#ifndef X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION +#define X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION 0 +#endif + +/** + * X86_64_DELTA_AGC7648SV1_CONFIG_SFP_COUNT + * + * SFP port numbers. */ + + +#ifndef X86_64_DELTA_AGC7648SV1_CONFIG_SFP_COUNT +#define X86_64_DELTA_AGC7648SV1_CONFIG_SFP_COUNT 4 +#endif + +/** + * X86_64_DELTA_AGC7648SV1_CONFIG_FAN_RPM_MAX + * + * Max fan speed. */ + + +#ifndef X86_64_DELTA_AGC7648SV1_CONFIG_FAN_RPM_MAX +#define X86_64_DELTA_AGC7648SV1_CONFIG_FAN_RPM_MAX 18000 +#endif + + + +/** + * All compile time options can be queried or displayed + */ + +/** Configuration settings structure. */ +typedef struct x86_64_delta_agc7648sv1_config_settings_s { + /** name */ + const char* name; + /** value */ + const char* value; +} x86_64_delta_agc7648sv1_config_settings_t; + +/** Configuration settings table. */ +/** x86_64_delta_agc7648sv1_config_settings table. */ +extern x86_64_delta_agc7648sv1_config_settings_t x86_64_delta_agc7648sv1_config_settings[]; + +/** + * @brief Lookup a configuration setting. + * @param setting The name of the configuration option to lookup. + */ +const char* x86_64_delta_agc7648sv1_config_lookup(const char* setting); + +/** + * @brief Show the compile-time configuration. + * @param pvs The output stream. + */ +int x86_64_delta_agc7648sv1_config_show(struct aim_pvs_s* pvs); + +/* */ + +#include "x86_64_delta_agc7648sv1_porting.h" + +#endif /* __x86_64_delta_agc7648sv1_CONFIG_H__ */ +/* @} */ diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1_dox.h b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1_dox.h new file mode 100644 index 00000000..67eaa614 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1_dox.h @@ -0,0 +1,26 @@ +/**************************************************************************//** + * + * x86_64_delta_agc7648sv1 Doxygen Header + * + *****************************************************************************/ +#ifndef __X86_64_DELTA_agc7648sv1_DOX_H__ +#define _X86_64_DELTA_agc7648sv1_DOX_H__ + +/** + * @defgroup x86_64_delta_agc7648sv1 x86_64_delta_agc7648sv1 - x86_64_delta_agc7648sv1 Description + * + +The documentation overview for this module should go here. + + * + * @{ + * + * @defgroup x86_64_delta_agc7648sv1-x86_64_delta_agc7648sv1 Public Interface + * @defgroup x86_64_delta_agc7648sv1-config Compile Time Configuration + * @defgroup x86_64_delta_agc7648sv1-porting Porting Macros + * + * @} + * + */ + +#endif /* __X86_64_DELTA_agc7648sv1_DOX_H__ */ diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1_porting.h b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1_porting.h new file mode 100755 index 00000000..a21610ef --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/inc/x86_64_delta_agc7648sv1/x86_64_delta_agc7648sv1_porting.h @@ -0,0 +1,107 @@ +/**************************************************************************//** + * + * @file + * @brief x86_64_delta_agc7648sv1 Porting Macros. + * + * @addtogroup x86_64_delta_agc7648sv1-porting + * @{ + * + *****************************************************************************/ +#ifndef __X86_64_DELTA_AGC7648SV1_PORTING_H__ +#define __X86_64_DELTA_AGC7648SV1_PORTING_H__ + + +/* */ +#if X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS == 1 +#include +#include +#include +#include +#include +#endif + +#ifndef X86_64_DELTA_AGC7648SV1_MALLOC + #if defined(GLOBAL_MALLOC) + #define X86_64_DELTA_AGC7648SV1_MALLOC GLOBAL_MALLOC + #elif X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB == 1 + #define X86_64_DELTA_AGC7648SV1_MALLOC malloc + #else + #error The macro X86_64_DELTA_AGC7648SV1_MALLOC is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_DELTA_AGC7648SV1_FREE + #if defined(GLOBAL_FREE) + #define X86_64_DELTA_AGC7648SV1_FREE GLOBAL_FREE + #elif X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB == 1 + #define X86_64_DELTA_AGC7648SV1_FREE free + #else + #error The macro X86_64_DELTA_AGC7648SV1_FREE is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_DELTA_AGC7648SV1_MEMSET + #if defined(GLOBAL_MEMSET) + #define X86_64_DELTA_AGC7648SV1_MEMSET GLOBAL_MEMSET + #elif X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB == 1 + #define X86_64_DELTA_AGC7648SV1_MEMSET memset + #else + #error The macro X86_64_DELTA_AGC7648SV1_MEMSET is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_DELTA_AGC7648SV1_MEMCPY + #if defined(GLOBAL_MEMCPY) + #define X86_64_DELTA_AGC7648SV1_MEMCPY GLOBAL_MEMCPY + #elif X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB == 1 + #define X86_64_DELTA_AGC7648SV1_MEMCPY memcpy + #else + #error The macro X86_64_DELTA_AGC7648SV1_MEMCPY is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_DELTA_AGC7648SV1_STRNCPY + #if defined(GLOBAL_STRNCPY) + #define X86_64_DELTA_AGC7648SV1_STRNCPY GLOBAL_STRNCPY + #elif X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB == 1 + #define X86_64_DELTA_AGC7648SV1_STRNCPY strncpy + #else + #error The macro X86_64_DELTA_AGC7648SV1_STRNCPY is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_DELTA_AGC7648SV1_VSNPRINTF + #if defined(GLOBAL_VSNPRINTF) + #define X86_64_DELTA_AGC7648SV1_VSNPRINTF GLOBAL_VSNPRINTF + #elif X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB == 1 + #define X86_64_DELTA_AGC7648SV1_VSNPRINTF vsnprintf + #else + #error The macro X86_64_DELTA_AGC7648SV1_VSNPRINTF is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_DELTA_AGC7648SV1_SNPRINTF + #if defined(GLOBAL_SNPRINTF) + #define X86_64_DELTA_AGC7648SV1_SNPRINTF GLOBAL_SNPRINTF + #elif X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB == 1 + #define X86_64_DELTA_AGC7648SV1_SNPRINTF snprintf + #else + #error The macro X86_64_DELTA_AGC7648SV1_SNPRINTF is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_DELTA_AGC7648SV1_STRLEN + #if defined(GLOBAL_STRLEN) + #define X86_64_DELTA_AGC7648SV1_STRLEN GLOBAL_STRLEN + #elif X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB == 1 + #define X86_64_DELTA_AGC7648SV1_STRLEN strlen + #else + #error The macro X86_64_DELTA_AGC7648SV1_STRLEN is required but cannot be defined. + #endif +#endif + +/* */ + + +#endif /* _X86_64_DELTA_AGC7648SV1_PORTING_H__ */ +/* @} */ diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/make.mk b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/make.mk new file mode 100755 index 00000000..e5ffb6ee --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/make.mk @@ -0,0 +1,10 @@ +############################################################################### +# +# +# +############################################################################### +THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +x86_64_delta_agc7648sv1_INCLUDES := -I $(THIS_DIR)inc +x86_64_delta_agc7648sv1_INTERNAL_INCLUDES := -I $(THIS_DIR)src +x86_64_delta_agc7648sv1_DEPENDMODULE_ENTRIES := init:x86_64_delta_agc7648sv1 ucli:x86_64_delta_agc7648sv1 + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/Makefile b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/Makefile new file mode 100644 index 00000000..d7537072 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/Makefile @@ -0,0 +1,9 @@ +############################################################################### +# +# Local source generation targets. +# +############################################################################### + +ucli: + @../../../../tools/uclihandlers.py x86_64_delta_agc7648sv1_ucli.c + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/fani.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/fani.c new file mode 100755 index 00000000..6c8b80d6 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/fani.c @@ -0,0 +1,428 @@ +/************************************************************ + * + * + * Copyright 2014 Big Switch Networks, Inc. + * Copyright (C) 2017 Delta Networks, Inc. + * + * Licensed under the Eclipse Public License, Version 1.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.eclipse.org/legal/epl-v10.html + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + * + * + ************************************************************ + * + * Fan Platform Implementation Defaults. + * + ***********************************************************/ +#include "platform_lib.h" +#include +#include + +typedef struct fan_path_S +{ + char *status; + char *speed; + char *ctrl_speed; +}fan_path_T; + +static fan_path_T fan_path[] = /* must map with onlp_fan_id */ +{ + { NULL, NULL, NULL }, + { "25-002c/fan4_fault", "25-002c/fan4_input", "25-002c/fan4_input_percentage" }, + { "25-002c/fan3_fault", "25-002c/fan3_input", "25-002c/fan3_input_percentage" }, + { "25-002c/fan2_fault", "25-002c/fan2_input", "25-002c/fan2_input_percentage" }, + { "25-002c/fan1_fault", "25-002c/fan1_input", "25-002c/fan1_input_percentage" }, + { "25-002d/fan4_fault", "25-002d/fan4_input", "25-002d/fan4_input_percentage" }, + { "25-002d/fan3_fault", "25-002d/fan3_input", "25-002d/fan3_input_percentage" }, + { "25-002d/fan2_fault", "25-002d/fan2_input", "25-002d/fan2_input_percentage" }, + { "25-002d/fan1_fault", "25-002d/fan1_input", "25-002d/fan1_input_percentage" }, + { "31-0058/psu_fan1_fault", "31-0058/psu_fan1_speed_rpm", "31-0058/psu_fan1_duty_cycle_percentage" }, + { "32-0058/psu_fan1_fault", "32-0058/psu_fan1_speed_rpm", "32-0058/psu_fan1_duty_cycle_percentage" } +}; + +#define MAKE_FAN_INFO_NODE_ON_FAN_BOARD(id) \ + { \ + { ONLP_FAN_ID_CREATE(FAN_##id##_ON_FAN_BOARD), "Chassis Fan "#id, 0 }, \ + 0x0, \ + (ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \ + 0, \ + 0, \ + ONLP_FAN_MODE_INVALID, \ + } + +#define MAKE_FAN_INFO_NODE_ON_PSU(psu_id, 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_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \ + 0, \ + 0, \ + ONLP_FAN_MODE_INVALID, \ + } + +/* Static fan information */ +onlp_fan_info_t linfo[] = { + { }, // Not used + MAKE_FAN_INFO_NODE_ON_FAN_BOARD(1), + MAKE_FAN_INFO_NODE_ON_FAN_BOARD(2), + MAKE_FAN_INFO_NODE_ON_FAN_BOARD(3), + MAKE_FAN_INFO_NODE_ON_FAN_BOARD(4), + MAKE_FAN_INFO_NODE_ON_FAN_BOARD(5), + MAKE_FAN_INFO_NODE_ON_FAN_BOARD(6), + MAKE_FAN_INFO_NODE_ON_FAN_BOARD(7), + MAKE_FAN_INFO_NODE_ON_FAN_BOARD(8), + MAKE_FAN_INFO_NODE_ON_PSU(1,1), + MAKE_FAN_INFO_NODE_ON_PSU(2,1), +}; + +#define VALIDATE(_id) \ + do { \ + if(!ONLP_OID_IS_FAN(_id)) { \ + return ONLP_STATUS_E_INVALID; \ + } \ + } while(0) + +static int dni_fani_info_get_fan(int local_id, onlp_fan_info_t* info, char *dev_name) +{ + int bit_data = 0; + int rpm = 0; + char fullpath[100] = {0}; + int rv = ONLP_STATUS_OK; + uint8_t present_bit = 0x00; + UINT4 multiplier = 1; + UINT4 u4Data = 0; + + if(dni_bmc_check() == BMC_ON) + { + if(dni_bmc_sensor_read(dev_name, &u4Data, multiplier) == ONLP_STATUS_OK) + { + info->rpm = u4Data; + info->percentage = (info->rpm * 100) / MAX_FRONT_FAN_SPEED; + } + + rv = dni_bmc_fanpresent_info_get(&bit_data); + if(rv == ONLP_STATUS_OK && bit_data != 0) + present_bit = bit_data; + else + rv = ONLP_STATUS_E_INVALID; + } + else + { + dev_info_t dev_info; + dev_info.bus = I2C_BUS_27; + dev_info.addr = FAN_IO_CTL; + dev_info.offset = 0x00; + dev_info.flags = DEFAULT_FLAG; + + sprintf(fullpath, "%s%s", PREFIX_PATH, fan_path[local_id].speed); + rpm = dni_i2c_lock_read_attribute(NULL, fullpath); + info->rpm = rpm; + + /* If rpm is FAN_ZERO_TACH, then the rpm value is zero. */ + if(info->rpm == 960) + info->rpm = 0; + + /* get speed percentage from rpm */ + info->percentage = (info->rpm * 100)/MAX_FRONT_FAN_SPEED; + present_bit = dni_i2c_lock_read(NULL, &dev_info); + } + + switch(local_id) { + case FAN_4_ON_FAN_BOARD: + case FAN_8_ON_FAN_BOARD: + if((present_bit & 1) == 0) + info->status |= ONLP_FAN_STATUS_PRESENT; + else + info->status |= ONLP_FAN_STATUS_FAILED; + break; + case FAN_3_ON_FAN_BOARD: + case FAN_7_ON_FAN_BOARD: + if((present_bit & (1 << 1)) == 0) + info->status |= ONLP_FAN_STATUS_PRESENT; + else + info->status |= ONLP_FAN_STATUS_FAILED; + break; + case FAN_2_ON_FAN_BOARD: + case FAN_6_ON_FAN_BOARD: + if((present_bit & (1 << 2)) == 0) + info->status |= ONLP_FAN_STATUS_PRESENT; + else + info->status |= ONLP_FAN_STATUS_FAILED; + break; + case FAN_1_ON_FAN_BOARD: + case FAN_5_ON_FAN_BOARD: + if((present_bit & (1 << 3)) == 0) + info->status |= ONLP_FAN_STATUS_PRESENT; + else + info->status |= ONLP_FAN_STATUS_FAILED; + break; + } + + return rv; +} + +static int dni_fani_info_get_fan_on_psu(int local_id, onlp_fan_info_t* info, char *dev_name) +{ + int rpm_data = 0; + int r_data = 0; + int bit_data = 0; + int rv = ONLP_STATUS_OK; + int psu_present = 0; + UINT4 multiplier = 1; + UINT4 u4Data = 0; + char fullpath[100] = {0}; + + if(dni_bmc_check() == BMC_ON) + { + rv = dni_psu_present(&bit_data); + psu_present = bit_data; + rv = dni_bmc_sensor_read(dev_name, &u4Data, multiplier); + rpm_data = (int)u4Data; + + switch(local_id) + { + case FAN_1_ON_PSU1: + if((psu_present & 0x80) != 0x80) + { + info->rpm = rpm_data; + info->percentage = (info->rpm * 100) / MAX_FRONT_FAN_SPEED; + info->status |= ONLP_FAN_STATUS_PRESENT | ONLP_FAN_STATUS_B2F; + } + else + { + info->status |= ONLP_FAN_STATUS_FAILED; + rv = ONLP_STATUS_E_INVALID; + } + break; + case FAN_1_ON_PSU2: + if((psu_present & 0x08) != 0x08) + { + info->rpm = rpm_data; + info->percentage = (info->rpm * 100) / MAX_FRONT_FAN_SPEED; + info->status |= ONLP_FAN_STATUS_PRESENT | ONLP_FAN_STATUS_B2F; + } + else + { + info->status |= ONLP_FAN_STATUS_FAILED; + rv = ONLP_STATUS_E_INVALID; + } + break; + } + } + else + { + dev_info_t dev_info; + dev_info.addr = PSU_EEPROM; + dev_info.offset = 0x00; /* In EEPROM address 0x00 */ + dev_info.flags = DEFAULT_FLAG; + switch(local_id) + { + case FAN_1_ON_PSU1: + dev_info.bus = I2C_BUS_31; + sprintf(fullpath, "%s%s", PREFIX_PATH, fan_path[local_id].status); + break; + case FAN_1_ON_PSU2: + dev_info.bus = I2C_BUS_32; + sprintf(fullpath, "%s%s", PREFIX_PATH, fan_path[local_id].status); + break; + default: + break; + } + if(dni_i2c_lock_read(NULL, &dev_info) >= 0) + info->status |= ONLP_FAN_STATUS_PRESENT | ONLP_FAN_STATUS_B2F; + + sprintf(fullpath, "%s%s", PREFIX_PATH, fan_path[local_id].status); + r_data = dni_i2c_lock_read_attribute(NULL, fullpath); + if (r_data == 1) + info->status |= ONLP_FAN_STATUS_FAILED; + + /* Read PSU FAN speed from psu_fan1_speed_rpm */ + sprintf(fullpath, "%s%s", PREFIX_PATH, fan_path[local_id].speed); + r_data = dni_i2c_lock_read_attribute(NULL, fullpath); + info->rpm = r_data; + + /* Calculate psu fan duty cycle based on rpm */ + info->percentage = (info->rpm * 100) / MAX_PSU_FAN_SPEED; + } + + return rv; +} + +/* + * This function will be called prior to all of onlp_fani_* functions. + */ +int onlp_fani_init(void) +{ + lockinit(); + return ONLP_STATUS_OK; +} + +int onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info) +{ + int local_id; + int rv = ONLP_STATUS_OK; + + VALIDATE(id); + local_id = ONLP_OID_ID_GET(id); + *info = linfo[ONLP_OID_ID_GET(id)]; + + switch(local_id) { + case FAN_1_ON_FAN_BOARD: + rv = dni_fani_info_get_fan(local_id, info, "Fantray_1_1"); + break; + case FAN_2_ON_FAN_BOARD: + rv = dni_fani_info_get_fan(local_id, info, "Fantray_1_2"); + break; + case FAN_3_ON_FAN_BOARD: + rv = dni_fani_info_get_fan(local_id, info, "Fantray_1_3"); + break; + case FAN_4_ON_FAN_BOARD: + rv = dni_fani_info_get_fan(local_id, info, "Fantray_1_4"); + break; + case FAN_5_ON_FAN_BOARD: + rv = dni_fani_info_get_fan(local_id, info, "Fantray_2_1"); + break; + case FAN_6_ON_FAN_BOARD: + rv = dni_fani_info_get_fan(local_id, info, "Fantray_2_2"); + break; + case FAN_7_ON_FAN_BOARD: + rv = dni_fani_info_get_fan(local_id, info, "Fantray_2_3"); + break; + case FAN_8_ON_FAN_BOARD: + rv = dni_fani_info_get_fan(local_id, info, "Fantray_2_4"); + break; + case FAN_1_ON_PSU1: + rv = dni_fani_info_get_fan_on_psu(local_id, info, "PSU1_Fan"); + break; + case FAN_1_ON_PSU2: + rv = dni_fani_info_get_fan_on_psu(local_id, info, "PSU2_Fan"); + break; + default: + rv = ONLP_STATUS_E_INVALID; + break; + } + + return rv; +} + +/* + * This function sets the speed of the given fan in RPM. + * + * This function will only be called if the fan supprots the RPM_SET + * capability. + * + * It is optional if you have no fans at all with this feature. + */ +int onlp_fani_rpm_set(onlp_oid_t id, int rpm) +{ + int local_id; + char data[10] = {0}; + char fullpath[70] = {0}; + VALIDATE(id); + local_id = ONLP_OID_ID_GET(id); + + /* get fullpath */ + switch (local_id) { + case FAN_1_ON_FAN_BOARD: + case FAN_2_ON_FAN_BOARD: + case FAN_3_ON_FAN_BOARD: + case FAN_4_ON_FAN_BOARD: + case FAN_5_ON_FAN_BOARD: + case FAN_6_ON_FAN_BOARD: + case FAN_7_ON_FAN_BOARD: + case FAN_8_ON_FAN_BOARD: + sprintf(fullpath, "%s%s", PREFIX_PATH, fan_path[local_id].speed); + break; + default: + return ONLP_STATUS_E_INVALID; + } + sprintf(data, "%d", rpm); + dni_i2c_lock_write_attribute(NULL, data, fullpath); + + return ONLP_STATUS_OK; +} + +/* + * This function sets the fan speed of the given OID as a percentage. + * + * This will only be called if the OID has the PERCENTAGE_SET + * capability. + * + * It is optional if you have no fans at all with this feature. + */ +int onlp_fani_percentage_set(onlp_oid_t id, int p) +{ + int local_id; + char data[10] = {0}; + char fullpath[70] = {0}; + + VALIDATE(id); + local_id = ONLP_OID_ID_GET(id); + + /* Select PSU member */ + switch (local_id) { + case FAN_1_ON_FAN_BOARD: + case FAN_2_ON_FAN_BOARD: + case FAN_3_ON_FAN_BOARD: + case FAN_4_ON_FAN_BOARD: + case FAN_5_ON_FAN_BOARD: + case FAN_6_ON_FAN_BOARD: + case FAN_7_ON_FAN_BOARD: + case FAN_8_ON_FAN_BOARD: + case FAN_1_ON_PSU1: + case FAN_1_ON_PSU2: + break; + default: + return ONLP_STATUS_E_INVALID; + } + + sprintf(fullpath, "%s%s", PREFIX_PATH, fan_path[local_id].ctrl_speed); + /* Write percentage to psu_fan1_duty_cycle_percentage */ + sprintf(data, "%d", p); + dni_i2c_lock_write_attribute(NULL, data, fullpath); + + return ONLP_STATUS_OK; +} + +/* + * This function sets the fan speed of the given OID as per + * the predefined ONLP fan speed modes: off, slow, normal, fast, max. + * + * Interpretation of these modes is up to the platform. + * + */ +int onlp_fani_mode_set(onlp_oid_t id, onlp_fan_mode_t mode) +{ + return ONLP_STATUS_E_UNSUPPORTED; +} + +/* + * This function sets the fan direction of the given OID. + * + * This function is only relevant if the fan OID supports both direction + * capabilities. + * + * This function is optional unless the functionality is available. + */ +int onlp_fani_dir_set(onlp_oid_t id, onlp_fan_dir_t dir) +{ + return ONLP_STATUS_E_UNSUPPORTED; +} + +/* + * Generic fan ioctl. Optional. + */ +int onlp_fani_ioctl(onlp_oid_t id, va_list vargs) +{ + return ONLP_STATUS_E_UNSUPPORTED; +} + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/ledi.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/ledi.c new file mode 100755 index 00000000..6c858fd0 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/ledi.c @@ -0,0 +1,503 @@ +/************************************************************ + * + * + * Copyright 2014 Big Switch Networks, Inc. + * Copyright (C) 2017 Delta Networks, Inc. + * + * Licensed under the Eclipse Public License, Version 1.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.eclipse.org/legal/epl-v10.html + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + * + * + ************************************************************ + * + * + * + ***********************************************************/ +#include "platform_lib.h" +#include +#include + + +#define VALIDATE(_id) \ + do { \ + if(!ONLP_OID_IS_LED(_id)) { \ + return ONLP_STATUS_E_INVALID; \ + } \ + } while(0) + +/* Get the information for the given LED OID. */ +static onlp_led_info_t linfo[] = +{ + { }, // Not used + { + { ONLP_LED_ID_CREATE(LED_FRONT_FAN), "FRONT LED (FAN LED)", 0 }, + ONLP_LED_STATUS_PRESENT, + ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_YELLOW | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_YELLOW_BLINKING, + }, + { + { ONLP_LED_ID_CREATE(LED_FRONT_PWR), "FRONT LED (PWR LED)", 0 }, + ONLP_LED_STATUS_PRESENT, + ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_YELLOW | ONLP_LED_CAPS_GREEN, + }, + { + { ONLP_LED_ID_CREATE(LED_FRONT_SYS), "FRONT LED (SYS LED)", 0 }, + ONLP_LED_STATUS_PRESENT, + ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_YELLOW | ONLP_LED_CAPS_GREEN_BLINKING | \ + ONLP_LED_CAPS_YELLOW_BLINKING, + }, + { + { ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_1), "FAN TRAY 1 LED", 0 }, + ONLP_LED_STATUS_PRESENT, + ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED, + }, + { + { ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_2), "FAN TRAY 2 LED", 0 }, + ONLP_LED_STATUS_PRESENT, + ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED, + }, + { + { ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_3), "FAN TRAY 3 LED", 0 }, + ONLP_LED_STATUS_PRESENT, + ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED, + }, + { + { ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_4), "FAN TRAY 4 LED", 0 }, + ONLP_LED_STATUS_PRESENT, + ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED, + }, +}; + + +/* This function will be called prior to any other onlp_ledi_* functions. */ +int onlp_ledi_init(void) +{ + lockinit(); + return ONLP_STATUS_OK; +} + +int onlp_ledi_info_get(onlp_oid_t id, onlp_led_info_t* info) +{ + int local_id; + int r_data = 0; + int bit_data = 0; + + VALIDATE(id); + local_id = ONLP_OID_ID_GET(id); + *info = linfo[ONLP_OID_ID_GET(id)]; + + if(dni_bmc_check() == BMC_ON) + { + switch(local_id) { + case LED_FRONT_FAN: + if( dni_bmc_data_get(BMC_SWPLD_BUS, SWPLD_1_ADDR, SYS_LED_REGISTER, 1, &bit_data) != ONLP_STATUS_OK){ + return ONLP_STATUS_E_INTERNAL; + } + r_data = bit_data; + if((r_data & 0x03) == 0x01) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0x03) == 0x02) + info->mode = ONLP_LED_MODE_YELLOW; + else if((r_data & 0x03) == 0x03) + info->mode = ONLP_LED_MODE_YELLOW_BLINKING; + else if((r_data & 0x03) == 0x00) + info->mode = ONLP_LED_MODE_OFF; + else + return ONLP_STATUS_E_INTERNAL; + break; + + case LED_FRONT_PWR: + if( dni_bmc_data_get(BMC_SWPLD_BUS, SWPLD_1_ADDR, SYS_LED_REGISTER, 1, &bit_data) != ONLP_STATUS_OK){ + return ONLP_STATUS_E_INTERNAL; + } + r_data = bit_data; + if((r_data & 0x0c) == 0x04) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0x0c) == 0x08) + info->mode = ONLP_LED_MODE_YELLOW; + else if((r_data & 0x0c) == 0x0c || (r_data & 0x0c) == 0x00) + info->mode = ONLP_LED_MODE_OFF; + else + return ONLP_STATUS_E_INTERNAL; + break; + + case LED_FRONT_SYS: + if( dni_bmc_data_get(BMC_SWPLD_BUS, SWPLD_1_ADDR, SYS_LED_REGISTER, 1, &bit_data) != ONLP_STATUS_OK){ + return ONLP_STATUS_E_INTERNAL; + } + r_data = bit_data; + if((r_data & 0xf0) == 0x10) + info->mode = ONLP_LED_MODE_YELLOW; + else if((r_data & 0xf0) == 0x20) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0xf0) == 0x90) // 0.5S + info->mode = ONLP_LED_MODE_GREEN_BLINKING; + else if((r_data & 0xf0) == 0xa0) // 0.5S + info->mode = ONLP_LED_MODE_YELLOW_BLINKING; + else if ((r_data & 0xf0) == 0x00) + info->mode = ONLP_LED_MODE_OFF; + else + return ONLP_STATUS_E_INTERNAL; + break; + + case LED_REAR_FAN_TRAY_1: + if( dni_bmc_data_get(BMC_SWPLD_BUS, SWPLD_1_ADDR, FAN_LED_REGISTER, 1, &bit_data) != ONLP_STATUS_OK){ + return ONLP_STATUS_E_INTERNAL; + } + r_data = bit_data; + if(dni_fan_present(LED_REAR_FAN_TRAY_1) == ONLP_STATUS_OK){ + if((r_data & 0xc0) == 0x40) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0xc0) == 0x80) + info->mode = ONLP_LED_MODE_RED; + } + else + info->mode = ONLP_LED_MODE_OFF; + break; + + case LED_REAR_FAN_TRAY_2: + if( dni_bmc_data_get(BMC_SWPLD_BUS, SWPLD_1_ADDR, FAN_LED_REGISTER, 1, &bit_data) != ONLP_STATUS_OK){ + return ONLP_STATUS_E_INTERNAL; + } + r_data = bit_data; + if(dni_fan_present(LED_REAR_FAN_TRAY_2) == ONLP_STATUS_OK){ + if((r_data & 0x30) == 0x10) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0x30) == 0x20) + info->mode = ONLP_LED_MODE_RED; + } + else + info->mode = ONLP_LED_MODE_OFF; + break; + case LED_REAR_FAN_TRAY_3: + if( dni_bmc_data_get(BMC_SWPLD_BUS, SWPLD_1_ADDR, FAN_LED_REGISTER, 1, &bit_data) != ONLP_STATUS_OK){ + return ONLP_STATUS_E_INTERNAL; + } + r_data = bit_data; + if(dni_fan_present(LED_REAR_FAN_TRAY_3) == ONLP_STATUS_OK){ + if((r_data & 0x0c) == 0x04) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0x0c) == 0x08) + info->mode = ONLP_LED_MODE_RED; + } + else + info->mode = ONLP_LED_MODE_OFF; + break; + + case LED_REAR_FAN_TRAY_4: + if( dni_bmc_data_get(BMC_SWPLD_BUS, SWPLD_1_ADDR, FAN_LED_REGISTER, 1, &bit_data) != ONLP_STATUS_OK){ + return ONLP_STATUS_E_INTERNAL; + } + r_data = bit_data; + if(dni_fan_present(LED_REAR_FAN_TRAY_4) == ONLP_STATUS_OK){ + if((r_data & 0x03) == 0x01) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0x03) == 0x02) + info->mode = ONLP_LED_MODE_RED; + } + else + info->mode = ONLP_LED_MODE_OFF; + break; + } + } + else{ + switch(local_id) + { + case LED_FRONT_FAN: + r_data = dni_lock_cpld_read_attribute(SWPLD1_PATH, SYS_LED_REGISTER); + if((r_data & 0x03) == 0x01) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0x03) == 0x02) + info->mode = ONLP_LED_MODE_YELLOW; + else if((r_data & 0x03) == 0x03) + info->mode = ONLP_LED_MODE_YELLOW_BLINKING; + else if((r_data & 0x03) == 0x00) + info->mode = ONLP_LED_MODE_OFF; + else + return ONLP_STATUS_E_INTERNAL; + break; + + case LED_FRONT_PWR: + r_data = dni_lock_cpld_read_attribute(SWPLD1_PATH, SYS_LED_REGISTER); + if((r_data & 0x0c) == 0x4) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0x0c) == 0x8) + info->mode = ONLP_LED_MODE_YELLOW; + else if((r_data & 0x0c) == 0xc || (r_data & 0x0c) == 0x00) + info->mode = ONLP_LED_MODE_OFF; + else + return ONLP_STATUS_E_INTERNAL; + break; + + case LED_FRONT_SYS: + r_data = dni_lock_cpld_read_attribute(SWPLD1_PATH, SYS_LED_REGISTER); + if((r_data & 0xf0) == 0x10) + info->mode = ONLP_LED_MODE_YELLOW; + else if((r_data & 0xf0) == 0x20) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0xf0) == 0x90) // 0.5S + info->mode = ONLP_LED_MODE_GREEN_BLINKING; + else if((r_data & 0xf0) == 0xa0) // 0.5S + info->mode = ONLP_LED_MODE_YELLOW_BLINKING; + else if ((r_data & 0xf0) == 0x00) + info->mode = ONLP_LED_MODE_OFF; + else + return ONLP_STATUS_E_INTERNAL; + break; + + case LED_REAR_FAN_TRAY_1: + r_data = dni_lock_cpld_read_attribute(SWPLD1_PATH, FAN_LED_REGISTER); + if(dni_fan_present(LED_REAR_FAN_TRAY_1) == ONLP_STATUS_OK){ + if((r_data & 0xc0) == 0x40) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0xc0) == 0x80) + info->mode = ONLP_LED_MODE_RED; + } + else + info->mode = ONLP_LED_MODE_OFF; + break; + + case LED_REAR_FAN_TRAY_2: + r_data = dni_lock_cpld_read_attribute(SWPLD1_PATH, FAN_LED_REGISTER); + if(dni_fan_present(LED_REAR_FAN_TRAY_2) == ONLP_STATUS_OK){ + if((r_data & 0x30) == 0x10) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0x30) == 0x20) + info->mode = ONLP_LED_MODE_RED; + } + else + info->mode = ONLP_LED_MODE_OFF; + break; + + case LED_REAR_FAN_TRAY_3: + r_data = dni_lock_cpld_read_attribute(SWPLD1_PATH, FAN_LED_REGISTER); + if(dni_fan_present(LED_REAR_FAN_TRAY_3) == ONLP_STATUS_OK){ + if((r_data & 0x0c) == 0x04) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0x0c) == 0x08) + info->mode = ONLP_LED_MODE_RED; + } + else + info->mode = ONLP_LED_MODE_OFF; + break; + + case LED_REAR_FAN_TRAY_4: + r_data = dni_lock_cpld_read_attribute(SWPLD1_PATH, FAN_LED_REGISTER); + if(dni_fan_present(LED_REAR_FAN_TRAY_4) == ONLP_STATUS_OK){ + if((r_data & 0x03) == 0x01) + info->mode = ONLP_LED_MODE_GREEN; + else if((r_data & 0x03) == 0x02) + info->mode = ONLP_LED_MODE_RED; + } + else + info->mode = ONLP_LED_MODE_OFF; + break; + } + } + + /* Set the on/off status */ + if (info->mode == ONLP_LED_MODE_OFF) + info->status = ONLP_LED_STATUS_FAILED; + else + info->status |= ONLP_LED_STATUS_PRESENT; + + return ONLP_STATUS_OK; +} + +/* Turn an LED on or off. + * + * This function will only be called if the LED OID supports the ONOFF + * capability. + * + * What 'on' means in terms of colors or modes for multimode LEDs is + * up to the platform to decide. This is intended as baseline toggle mechanism. */ +int onlp_ledi_set(onlp_oid_t id, int on_or_off) +{ + if (!on_or_off) + { + return onlp_ledi_mode_set(id, ONLP_LED_MODE_OFF); + } + return ONLP_STATUS_E_UNSUPPORTED; +} + +/* This function puts the LED into the given mode. It is a more functional + * interface for multimode LEDs. + * + * Only modes reported in the LED's capabilities will be attempted. */ +int onlp_ledi_mode_set(onlp_oid_t id, onlp_led_mode_t mode) +{ + VALIDATE(id); + int local_id = ONLP_OID_ID_GET(id); + uint8_t front_panel_led_value = 0; + uint8_t fan_tray_led_reg_value = 0; + + if(dni_bmc_check() == BMC_ON) + { + return ONLP_STATUS_OK; + } + else{ + switch(local_id) + { + case LED_FRONT_FAN: + front_panel_led_value = dni_lock_cpld_read_attribute(SWPLD1_PATH, SYS_LED_REGISTER); + front_panel_led_value &= ~0x03; + + if(mode == ONLP_LED_MODE_GREEN){ + front_panel_led_value |= 0x01; + } + else if(mode == ONLP_LED_MODE_YELLOW){ + front_panel_led_value |= 0x02; + } + else{ + front_panel_led_value = front_panel_led_value; + } + + if(dni_lock_cpld_write_attribute(SWPLD1_PATH, SYS_LED_REGISTER, front_panel_led_value) != 0){ + AIM_LOG_ERROR("Unable to set led(%d) status\r\n", local_id); + return ONLP_STATUS_E_INTERNAL; + } + break; + + case LED_FRONT_PWR: + front_panel_led_value = dni_lock_cpld_read_attribute(SWPLD1_PATH, SYS_LED_REGISTER); + front_panel_led_value &= ~0x0c; + + if(mode == ONLP_LED_MODE_GREEN){ + front_panel_led_value |= 0x04; + } + else if(mode == ONLP_LED_MODE_YELLOW){ + front_panel_led_value |= 0x08; + } + else{ + front_panel_led_value = front_panel_led_value; + } + if(dni_lock_cpld_write_attribute(SWPLD1_PATH, SYS_LED_REGISTER, front_panel_led_value) != 0){ + AIM_LOG_ERROR("Unable to set led(%d) status\r\n", local_id); + return ONLP_STATUS_E_INTERNAL; + } + break; + + case LED_FRONT_SYS: + front_panel_led_value = dni_lock_cpld_read_attribute(SWPLD1_PATH, SYS_LED_REGISTER); + front_panel_led_value &= ~0xf0; + + if(mode == ONLP_LED_MODE_YELLOW){ + front_panel_led_value |= 0x10; + } + else if(mode == ONLP_LED_MODE_GREEN){ + front_panel_led_value |= 0x20; + } + else if(mode == ONLP_LED_MODE_GREEN_BLINKING){ // 0.5S + front_panel_led_value |= 0x90; + } + else if(mode == ONLP_LED_MODE_YELLOW_BLINKING){ // 0.5S + front_panel_led_value |= 0xa0; + } + else{ + front_panel_led_value = front_panel_led_value; + } + if(dni_lock_cpld_write_attribute(SWPLD1_PATH, SYS_LED_REGISTER, front_panel_led_value) != 0){ + AIM_LOG_ERROR("Unable to set led(%d) status\r\n", local_id); + return ONLP_STATUS_E_INTERNAL; + } + break; + + case LED_REAR_FAN_TRAY_1: + fan_tray_led_reg_value = dni_lock_cpld_read_attribute(SWPLD1_PATH, FAN_LED_REGISTER); + fan_tray_led_reg_value &= ~0xc0; + + if(mode == ONLP_LED_MODE_GREEN){ + fan_tray_led_reg_value |= 0x40; + } + else if(mode == ONLP_LED_MODE_RED){ + fan_tray_led_reg_value |= 0x80; + } + else{ + fan_tray_led_reg_value = fan_tray_led_reg_value;; + } + + if(dni_lock_cpld_write_attribute(SWPLD1_PATH, FAN_LED_REGISTER, fan_tray_led_reg_value) != 0){ + AIM_LOG_ERROR("Unable to set led(%d) status\r\n", local_id); + return ONLP_STATUS_E_INTERNAL; + } + break; + + case LED_REAR_FAN_TRAY_2: + fan_tray_led_reg_value = dni_lock_cpld_read_attribute(SWPLD1_PATH, FAN_LED_REGISTER); + fan_tray_led_reg_value &= ~0x30; + + if(mode == ONLP_LED_MODE_GREEN){ + fan_tray_led_reg_value |= 0x10; + } + else if(mode == ONLP_LED_MODE_RED){ + fan_tray_led_reg_value |= 0x20; + } + else{ + fan_tray_led_reg_value = fan_tray_led_reg_value;; + } + + if(dni_lock_cpld_write_attribute(SWPLD1_PATH, FAN_LED_REGISTER, fan_tray_led_reg_value) != 0){ + AIM_LOG_ERROR("Unable to set led(%d) status\r\n", local_id); + return ONLP_STATUS_E_INTERNAL; + } + break; + + case LED_REAR_FAN_TRAY_3: + fan_tray_led_reg_value = dni_lock_cpld_read_attribute(SWPLD1_PATH, FAN_LED_REGISTER); + fan_tray_led_reg_value &= ~0x0c; + + if(mode == ONLP_LED_MODE_GREEN){ + fan_tray_led_reg_value |= 0x04; + } + else if(mode == ONLP_LED_MODE_RED){ + fan_tray_led_reg_value |= 0x08; + } + else{ + fan_tray_led_reg_value = fan_tray_led_reg_value;; + } + + if(dni_lock_cpld_write_attribute(SWPLD1_PATH, FAN_LED_REGISTER, fan_tray_led_reg_value) != 0){ + AIM_LOG_ERROR("Unable to set led(%d) status\r\n", local_id); + return ONLP_STATUS_E_INTERNAL; + } + break; + + case LED_REAR_FAN_TRAY_4: + fan_tray_led_reg_value = dni_lock_cpld_read_attribute(SWPLD1_PATH, FAN_LED_REGISTER); + fan_tray_led_reg_value &= ~0x03; + + if(mode == ONLP_LED_MODE_GREEN){ + fan_tray_led_reg_value |= 0x01; + } + else if(mode == ONLP_LED_MODE_RED){ + fan_tray_led_reg_value |= 0x02; + } + else{ + fan_tray_led_reg_value = fan_tray_led_reg_value;; + } + + if(dni_lock_cpld_write_attribute(SWPLD1_PATH, FAN_LED_REGISTER, fan_tray_led_reg_value) != 0){ + AIM_LOG_ERROR("Unable to set led(%d) status\r\n", local_id); + return ONLP_STATUS_E_INTERNAL; + } + break; + } + } + return ONLP_STATUS_OK; +} + +/* Generic LED ioctl interface. */ +int onlp_ledi_ioctl(onlp_oid_t id, va_list vargs) +{ + return ONLP_STATUS_E_UNSUPPORTED; +} + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/make.mk b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/make.mk new file mode 100755 index 00000000..70160b4c --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/make.mk @@ -0,0 +1,9 @@ +############################################################################### +# +# +# +############################################################################### + +LIBRARY := x86_64_delta_agc7648sv1 +$(LIBRARY)_SUBDIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(BUILDER)/lib.mk diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/platform_lib.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/platform_lib.c new file mode 100755 index 00000000..4f4e8076 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/platform_lib.c @@ -0,0 +1,498 @@ +/************************************************************ + * + * + * Copyright 2014 Big Switch Networks, Inc. + * Copyright (C) 2017 Delta Networks, Inc. + * + * Licensed under the Eclipse Public License, Version 1.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.eclipse.org/legal/epl-v10.html + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + * + * + ************************************************************ + * + * + * + ***********************************************************/ +#include "platform_lib.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "platform_lib.h" +#include + +static onlp_shlock_t* dni_lock = NULL; + +#define DNI_BUS_LOCK() \ + do{ \ + onlp_shlock_take(dni_lock); \ + }while(0) + +#define DNI_BUS_UNLOCK() \ + do{ \ + onlp_shlock_give(dni_lock); \ + }while(0) + +#define DNILOCK_MAGIC 0xA6D2B4E8 + +void lockinit() +{ + static int sem_inited = 0; + if(!sem_inited) + { + onlp_shlock_create(DNILOCK_MAGIC, &dni_lock, "bus-lock"); + sem_inited = 1; + } +} + +int dni_bmc_sensor_read(char *device_name, UINT4 *num, UINT4 multiplier) +{ + FILE *fpRead; + char Buf[10] = {0}; + char ipmi_command[120] = {0}; + int lenth = 10; + float num_f; + + sprintf(ipmi_command, "ipmitool sdr get %s |grep 'Sensor Reading'| awk -F':' '{print $2}'| awk -F' ' '{ print $1}'", device_name); + fpRead = popen(ipmi_command, "r"); + + if(fpRead == NULL){ + pclose(fpRead); + return ONLP_STATUS_E_GENERIC; + } + fgets(Buf, lenth , fpRead); + num_f = atof(Buf); + *num = num_f * multiplier; + pclose(fpRead); + + return ONLP_STATUS_OK; +} + +int dni_bmc_check() +{ + char cmd[30] = {0}; + char str_data[100] = {0}; + FILE *fptr = NULL; + int rv = 0; + + sprintf(cmd, "ipmitool raw 0x38 0x1a 0x00"); + fptr = popen(cmd, "r"); + if(fptr != NULL) + { + if(fgets(str_data, sizeof(str_data), fptr) != NULL) + rv = strtol(str_data, NULL, 16); + if(rv == 1) + rv = BMC_OFF; + else + rv = BMC_ON; + } + else + rv = ONLP_STATUS_E_INVALID; + pclose(fptr); + + return rv; +} + +int dni_bmc_data_get(int bus, int addr, int reg, int len, int *r_data) +{ + int rv = ONLP_STATUS_OK; + char cmd[50] = {0}; + char rdata[10] = {0}; + FILE *fptr = NULL; + + sprintf(cmd, "ipmitool raw 0x38 0x2 %d 0x%x 0x%x %d", bus ,addr, reg, len); + fptr = popen(cmd, "r"); + if(fptr != NULL) + { + if(fgets(rdata, sizeof(rdata), fptr) != NULL) + *r_data = strtol(rdata, NULL, 16); + else + rv = ONLP_STATUS_E_INVALID; + } + else + rv = ONLP_STATUS_E_INVALID; + pclose(fptr); + + return rv; +} + +int dni_bmc_fanpresent_info_get(int *r_data) +{ + int rv = ONLP_STATUS_OK; + char cmd[30] = {0}; + char str_data[100] = {0}; + FILE *fptr = NULL; + + sprintf(cmd, "ipmitool raw 0x38 0x0e"); + fptr = popen(cmd, "r"); + if(fptr != NULL) + { + if(fgets(str_data, sizeof(str_data), fptr) != NULL) + *r_data = strtol(str_data, NULL, 16); + else + rv = ONLP_STATUS_E_INVALID; + } + else + rv = ONLP_STATUS_E_INVALID; + pclose(fptr); + + return rv; +} + +int hex_to_int(char hex_input) +{ + int first = hex_input / 16 - 3; + int second = hex_input % 16; + int result = first * 10 + second; + + if(result > 9) result--; + return result; +} + +int hex_to_ascii(char hex_high, char hex_low) +{ + int high = hex_to_int(hex_high) * 16; + int low = hex_to_int(hex_low); + + return high + low; +} + +int dni_psu_present(int *r_data) +{ + FILE *fptr = NULL; + int rv = ONLP_STATUS_OK; + char cmd[35] = {0}; + char str_data[50] = {0}; + + sprintf(cmd, "ipmitool raw 0x38 0x2 3 0x6a 0x03 1"); + fptr = popen(cmd, "r"); + if(fptr != NULL) + { + if(fgets(str_data, sizeof(str_data), fptr) != NULL) + *r_data = strtol(str_data, NULL, 16); + else + rv = ONLP_STATUS_E_INVALID; + } + else + rv = ONLP_STATUS_E_INVALID; + pclose(fptr); + + return rv; +} + +int dni_psui_eeprom_info_get(char * r_data, char *device_name, int number) +{ + int i = 0; + int rv = ONLP_STATUS_OK; + FILE *fptr = NULL; + char cmd[35] = {0}; + char str_data[50] = {0}; + char buf; + char* renewCh; + + sprintf(cmd, "ipmitool fru print %d | grep '%s' | awk -F':' '{print $2}'",number,device_name); + fptr = popen(cmd, "r"); + while((buf = fgetc(fptr)) != EOF) + { + if(buf != ' ') + { + str_data[i] = buf; + i++; + } + } + for(i = 0; i < PSU_NUM_LENGTH; i++) + r_data[i] = str_data[i]; + pclose(fptr); + + renewCh = strstr(r_data,"\n"); + if(renewCh) + *renewCh= '\0'; + + return rv; +} + +int dni_i2c_lock_read(mux_info_t * mux_info, dev_info_t * dev_info) +{ + int r_data = 0; + + DNI_BUS_LOCK(); + if(dev_info->size == 1) + r_data = onlp_i2c_readb(dev_info->bus, dev_info->addr, dev_info->offset, dev_info->flags); + else + r_data = onlp_i2c_readw(dev_info->bus, dev_info->addr, dev_info->offset, dev_info->flags); + + DNI_BUS_UNLOCK(); + return r_data; +} + +int dni_i2c_lock_write(mux_info_t * mux_info, dev_info_t * dev_info) +{ + DNI_BUS_LOCK(); + /* Write size */ + if(dev_info->size == 1) + onlp_i2c_write(dev_info->bus, dev_info->addr, dev_info->offset, 1, &dev_info->data_8, dev_info->flags); + else + onlp_i2c_writew(dev_info->bus, dev_info->addr, dev_info->offset, dev_info->data_16, dev_info->flags); + + DNI_BUS_UNLOCK(); + return 0; +} + +int dni_i2c_lock_read_attribute(mux_info_t * mux_info, char * fullpath) +{ + int fd, nbytes = 10, rv = -1; + char r_data[10] = {0}; + + DNI_BUS_LOCK(); + if ((fd = open(fullpath, O_RDONLY)) >= 0) + { + if ((read(fd, r_data, nbytes)) > 0) + rv = atoi(r_data); + } + close(fd); + DNI_BUS_UNLOCK(); + return rv; +} + +int dni_i2c_lock_write_attribute(mux_info_t * mux_info, char * data,char * fullpath) +{ + int fd, nbytes = 10, rv = -1; + + DNI_BUS_LOCK(); + /* Create output file descriptor */ + if ((fd = open(fullpath, O_WRONLY, 0644)) >= 0) + { + if (write(fd, data, (ssize_t)nbytes) > 0) + { + fsync(fd); + rv = 0; + } + } + close(fd); + DNI_BUS_UNLOCK(); + return rv; +} + +/* Use this function to select MUX and read data on CPLD */ +int dni_lock_cpld_read_attribute(char *cpld_path, int addr) +{ + int fd, fd1, nbytes = 10, data = 0, rv = -1; + char r_data[10] = {0}; + char address[10] = {0}; + char cpld_data_path[100] = {0}; + char cpld_addr_path[100] = {0}; + + sprintf(cpld_data_path, "%s/swpld1_reg_value", cpld_path); + sprintf(cpld_addr_path, "%s/swpld1_reg_addr", cpld_path); + sprintf(address, "0x%02x", addr); + DNI_BUS_LOCK(); + /* Create output file descriptor */ + if ((fd = open(cpld_addr_path, O_WRONLY, 0644)) >= 0) + { + if (write(fd, address, 4) > 0) + { + fsync(fd); + if ((fd1 = open(cpld_data_path, O_RDONLY, 0644)) >= 0) + { + if ((read(fd1, r_data, nbytes)) > 0) + { + sscanf(r_data, "%x", &data); + rv = data; + } + } + close(fd1); + } + } + close(fd); + DNI_BUS_UNLOCK(); + return rv; +} + +/* Use this function to select MUX and write data on CPLD */ +int dni_lock_cpld_write_attribute(char *cpld_path, int addr, int data) +{ + int fd, fd1, rv = -1; + char address[10] = {0}; + char datas[10] = {0}; + char cpld_data_path[100] = {0}; + char cpld_addr_path[100] = {0}; + + sprintf(cpld_data_path, "%s/swpld1_reg_value", cpld_path); + sprintf(cpld_addr_path, "%s/swpld1_reg_addr", cpld_path); + sprintf(address, "0x%02x", addr); + DNI_BUS_LOCK(); + /* Create output file descriptor */ + if ((fd = open(cpld_addr_path, O_WRONLY, 0644)) >= 0) + { + if ((write(fd, address, 4)) > 0) + { + fsync(fd); + if ((fd1 = open(cpld_data_path, O_WRONLY, 0644)) >= 0) + { + sprintf(datas, "0x%02x", data); + if (write(fd1, datas, 4) > 0) + { + fsync(fd1); + rv = 0; + } + } + close(fd1); + } + } + close(fd); + DNI_BUS_UNLOCK(); + return rv; +} + +int dni_fan_present(int id) +{ + int rv; + dev_info_t dev_info; + int bit_data = 0; + int data = 0; + uint8_t present_bit = 0x00; + int fantray_present = 0; + + if(dni_bmc_check() == BMC_ON) + { + rv = dni_bmc_fanpresent_info_get(&bit_data); + if(rv == ONLP_STATUS_OK) + { + present_bit = bit_data; + data = (present_bit & (1 << -(id - NUM_OF_LED_ON_MAIN_BROAD))); + if(data == 0) + rv = ONLP_STATUS_OK; + else + rv = ONLP_STATUS_E_INVALID; + } + else + rv = ONLP_STATUS_E_INVALID; + } + else if(dni_bmc_check() == BMC_OFF) + { + dev_info.offset = 0x00; + dev_info.flags = DEFAULT_FLAG; + switch(id) { + case LED_REAR_FAN_TRAY_1: + dev_info.addr = FAN_TRAY_1; + dev_info.bus = I2C_BUS_21; + break; + case LED_REAR_FAN_TRAY_2: + dev_info.addr = FAN_TRAY_2; + dev_info.bus = I2C_BUS_22; + break; + case LED_REAR_FAN_TRAY_3: + dev_info.addr = FAN_TRAY_3; + dev_info.bus = I2C_BUS_23; + break; + case LED_REAR_FAN_TRAY_4: + dev_info.addr = FAN_TRAY_4; + dev_info.bus = I2C_BUS_24; + break; + } + fantray_present = dni_i2c_lock_read(NULL, &dev_info); + if(fantray_present >= 0) + rv = ONLP_STATUS_OK; + else + rv = ONLP_STATUS_E_INVALID; + } + else + rv = ONLP_STATUS_E_INVALID; + + return rv; +} + +int dni_fan_speed_good() +{ + int rpm = 0, rpm1 = 0, speed_good = 0; + + rpm = dni_i2c_lock_read_attribute(NULL, FAN1_FRONT); + rpm1 = dni_i2c_lock_read_attribute(NULL, FAN1_REAR); + if(rpm != 0 && rpm != 960 && rpm1 != 0 && rpm1 != 960) + speed_good++; + + rpm = dni_i2c_lock_read_attribute(NULL, FAN2_FRONT); + rpm1 = dni_i2c_lock_read_attribute(NULL, FAN2_REAR); + if(rpm != 0 && rpm != 960 && rpm1 != 0 && rpm1 != 960) + speed_good++; + + rpm = dni_i2c_lock_read_attribute(NULL, FAN3_FRONT); + rpm1 = dni_i2c_lock_read_attribute(NULL, FAN3_REAR); + if(rpm != 0 && rpm != 960 && rpm1 != 0 && rpm1 != 960) + speed_good++; + + rpm = dni_i2c_lock_read_attribute(NULL, FAN4_FRONT); + rpm1 = dni_i2c_lock_read_attribute(NULL, FAN4_REAR); + if(rpm != 0 && rpm != 960 && rpm1 != 0 && rpm1 != 960) + speed_good++; + + return speed_good; +} + +int dni_i2c_read_attribute_binary(char *filename, char *buffer, int buf_size, int data_len) +{ + int fd, rv = 0; + int len; + DNI_BUS_LOCK(); + + if ((buffer == NULL) || (buf_size < 0)) { + rv = -1; + goto ERROR; + } + + if ((fd = open(filename, O_RDONLY)) == -1) { + rv = -1; + goto ERROR; + } + + if ((len = read(fd, buffer, buf_size)) < 0) { + close(fd); + rv = -1; + goto ERROR; + } + + if ((close(fd) == -1)) { + rv = -1; + goto ERROR; + } + + if ((len > buf_size) || (data_len != 0 && len != data_len)) { + rv = -1; + goto ERROR; + } + +ERROR: + DNI_BUS_UNLOCK(); + return rv; +} + +int dni_i2c_read_attribute_string(char *filename, char *buffer, int buf_size, int data_len) +{ + int ret; + + if (data_len >= buf_size) + return -1; + + ret = dni_i2c_read_attribute_binary(filename, buffer, buf_size-1, data_len); + if (ret == 0) + buffer[buf_size-1] = '\0'; + + return ret; +} + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/platform_lib.h b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/platform_lib.h new file mode 100755 index 00000000..c28dbf12 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/platform_lib.h @@ -0,0 +1,221 @@ +/************************************************************ + * + * + * Copyright 2014 Big Switch Networks, Inc. + * Copyright (C) 2017 Delta Networks, Inc. + * + * Licensed under the Eclipse Public License, Version 1.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.eclipse.org/legal/epl-v10.html + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + * + * + ************************************************************ + * + * + * + ***********************************************************/ +#ifndef __PLATFORM_LIB_H__ +#define __PLATFORM_LIB_H__ + +#include "x86_64_delta_agc7648sv1_log.h" +#include +#include + +typedef unsigned int UINT4; + +/* CPLD numbrt & peripherals */ +#define NUM_OF_SFP (48) +#define NUM_OF_QSFP (6) +#define NUM_OF_PORT NUM_OF_SFP + NUM_OF_QSFP +#define NUM_OF_THERMAL_ON_MAIN_BROAD (9) +#define NUM_OF_LED_ON_MAIN_BROAD (7) +#define NUM_OF_FAN_ON_MAIN_BROAD (8) +#define NUM_OF_PSU_ON_MAIN_BROAD (2) +#define NUM_OF_SENSORS (47) +#define CHASSIS_FAN_COUNT (8) +#define CHASSIS_THERMAL_COUNT (9) +#define NUM_OF_THERMAL (11) +#define PSU1_ID (1) +#define PSU2_ID (2) +#define PSU_NUM_LENGTH (15) +#define MAX_FRONT_FAN_SPEED (23000) +#define MAX_PSU_FAN_SPEED (18380) +#define MAX_REAR_FAN_SPEED (20500) +#define FAN_ZERO_RPM (960) +#define FAN_SPEED_NORMALLY (4) +#define ALL_FAN_TRAY_EXIST (4) +#define BMC_OFF (1) +#define BMC_ON (0) +#define PSU_NODE_MAX_PATH_LEN (64) + +#define CPU_CPLD_VERSION "/sys/devices/platform/delta-agc7648sv1-cpld.0/cpuld_ver" +#define IDPROM_PATH "/sys/class/i2c-adapter/i2c-1/1-0053/eeprom" +#define SWPLD1_PATH "/sys/devices/platform/delta-agc7648sv1-swpld1.0" +#define SWPLD2_PATH "/sys/devices/platform/delta-agc7648sv1-swpld2.0" +#define FAN1_FRONT "/sys/bus/i2c/devices/i2c-25/25-002c/fan4_input" +#define FAN1_REAR "/sys/bus/i2c/devices/i2c-25/25-002d/fan4_input" +#define FAN2_FRONT "/sys/bus/i2c/devices/i2c-25/25-002c/fan3_input" +#define FAN2_REAR "/sys/bus/i2c/devices/i2c-25/25-002d/fan3_input" +#define FAN3_FRONT "/sys/bus/i2c/devices/i2c-25/25-002c/fan2_input" +#define FAN3_REAR "/sys/bus/i2c/devices/i2c-25/25-002d/fan2_input" +#define FAN4_FRONT "/sys/bus/i2c/devices/i2c-25/25-002c/fan1_input" +#define FAN4_REAR "/sys/bus/i2c/devices/i2c-25/25-002d/fan1_input" +#define PORT_EEPROM_FORMAT "/sys/bus/i2c/devices/%d-0050/eeprom" +#define SFP_SELECT_PORT_PATH "/sys/devices/platform/delta-agc7648sv1-swpld1.0/sfp_select_port" +#define SFP_IS_PRESENT_PATH "/sys/devices/platform/delta-agc7648sv1-swpld1.0/sfp_is_present" +#define SFP_IS_PRESENT_ALL_PATH "/sys/devices/platform/delta-agc7648sv1-swpld1.0/sfp_is_present_all" +#define SFP_RX_LOS_PATH "/sys/devices/platform/delta-agc7648sv1-swpld1.0/sfp_rx_los" +#define SFP_RX_LOS_ALL_PATH "/sys/devices/platform/delta-agc7648sv1-swpld1.0/sfp_rx_los_all" +#define SFP_TX_DISABLE_PATH "/sys/devices/platform/delta-agc7648sv1-swpld1.0/sfp_tx_disable" +#define SFP_TX_FAULT_PATH "/sys/devices/platform/delta-agc7648sv1-swpld1.0/sfp_tx_fault" +#define QSFP_RESET_PATH "/sys/devices/platform/delta-agc7648sv1-swpld1.0/sfp_reset" +#define QSFP_LP_MODE_PATH "/sys/devices/platform/delta-agc7648sv1-swpld1.0/sfp_lp_mode" +#define PREFIX_PATH "/sys/bus/i2c/devices/" +#define PSU1_AC_PMBUS_PREFIX "/sys/bus/i2c/devices/31-0058/" +#define PSU2_AC_PMBUS_PREFIX "/sys/bus/i2c/devices/32-0058/" +#define PSU2_AC_PMBUS_NODE(node) PSU2_AC_PMBUS_PREFIX#node + +/* REG define */ +#define SWPLD_1_ADDR (0x6A) +#define SWPLD_2_ADDR (0x75) +#define SWPLD_3_ADDR (0x73) +#define PSU_EEPROM (0x50) +#define FAN_TRAY_1 (0x52) +#define FAN_TRAY_2 (0x53) +#define FAN_TRAY_3 (0x54) +#define FAN_TRAY_4 (0x55) +#define FAN_IO_CTL (0x27) +#define SYS_LED_REGISTER (0x1C) +#define FAN_LED_REGISTER (0x65) +#define POWER_STATUS_REGISTER (0x0B) +#define POWER_INT_REGISTER (0x0E) +#define DEFAULT_FLAG (0x00) + +/* BMC BUS define */ +#define BMC_SWPLD_BUS (2) + +/* SFP REG define */ +#define SFP_RESPOND_1 (0x0A) +#define SFP_RESPOND_2 (0x0B) +#define SFP_RESPOND_3 (0x0C) +#define SFP_RESPOND_4 (0x0D) + +typedef struct mux_info_s +{ + uint8_t offset; + uint8_t channel; + char dev_data[10]; + uint32_t flags; + +}mux_info_t; + +typedef struct dev_info_s +{ + int bus; + int size; + uint8_t addr; + uint8_t data_8; + uint16_t data_16; + uint8_t offset; + uint32_t flags; + +}dev_info_t; + +int dni_i2c_read_attribute_binary(char *filename, char *buffer, int buf_size, int data_len); +int dni_lock_cpld_write_attribute(char *cpld_path, int addr, int data); +int dni_lock_cpld_read_attribute(char *cpld_path, int addr); +int dni_fan_present(int id); +int dni_fan_speed_good(); +int dni_i2c_read_attribute_string(char *filename, char *buffer, int buf_size, int data_len); +int dni_bmc_sensor_read(char *device_name, UINT4 *num, UINT4 multiplier); +int dni_psui_eeprom_info_get(char *r_data,char *device_name,int number); +int dni_bmc_check(); +int dni_bmc_fanpresent_info_get(int *r_data); +int dni_i2c_lock_read( mux_info_t * mux_info, dev_info_t * dev_info); +int dni_i2c_lock_read_attribute(mux_info_t * mux_info, char * fullpath); +int dni_i2c_lock_write_attribute(mux_info_t * mux_info, char * data,char * fullpath); +int dni_psu_present(int *r_data); +int dni_bmc_data_get(int bus, int addr, int reg, int len, int *r_data); +void lockinit(); + +char dev_name[50][32]; +float dev_sensor[50]; + +enum onlp_thermal_id +{ + THERMAL_RESERVED = 0, + THERMAL_1_ON_FAN_BOARD, + THERMAL_2_ON_CPU_BOARD, + THERMAL_3_ON_MAIN_BOARD_TEMP_1, + THERMAL_4_ON_MAIN_BOARD_TEMP_2, + THERMAL_5_ON_MAIN_BOARD_TEMP_1, + THERMAL_6_ON_MAIN_BOARD_TEMP_2, + THERMAL_7_ON_MAIN_BOARD_TEMP_3, + THERMAL_8_ON_MAIN_BOARD, + THERMAL_9_ON_MAIN_BOARD, + THERMAL_10_ON_PSU1, + THERMAL_11_ON_PSU2 +}; + +typedef enum +{ + FAN_RESERVED = 0, + FAN_1_ON_FAN_BOARD, + FAN_2_ON_FAN_BOARD, + FAN_3_ON_FAN_BOARD, + FAN_4_ON_FAN_BOARD, + FAN_5_ON_FAN_BOARD, + FAN_6_ON_FAN_BOARD, + FAN_7_ON_FAN_BOARD, + FAN_8_ON_FAN_BOARD, + FAN_1_ON_PSU1, + FAN_1_ON_PSU2 +} onlp_fan_id; + +typedef enum +{ + LED_RESERVED = 0, + LED_FRONT_FAN, + LED_FRONT_PWR, + LED_FRONT_SYS, + LED_REAR_FAN_TRAY_1, + LED_REAR_FAN_TRAY_2, + LED_REAR_FAN_TRAY_3, + LED_REAR_FAN_TRAY_4 +}onlp_led_id; + +enum bus +{ + I2C_BUS_0 = 0, + I2C_BUS_1, + I2C_BUS_2, + I2C_BUS_3, + I2C_BUS_4, + I2C_BUS_5, + I2C_BUS_6, + I2C_BUS_7, + I2C_BUS_8, + I2C_BUS_9, + I2C_BUS_10, + I2C_BUS_11, + I2C_BUS_21 = 21, + I2C_BUS_22, + I2C_BUS_23, + I2C_BUS_24, + I2C_BUS_25, + I2C_BUS_26, + I2C_BUS_27, + I2C_BUS_31 = 31, + I2C_BUS_32 +}; +#endif /* __PLATFORM_LIB_H__ */ + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/psui.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/psui.c new file mode 100755 index 00000000..64b6a415 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/psui.c @@ -0,0 +1,320 @@ +/************************************************************ + * + * + * Copyright 2014 Big Switch Networks, Inc. + * Copyright 2017 (C) Delta Networks, Inc. + * + * Licensed under the Eclipse Public License, Version 1.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.eclipse.org/legal/epl-v10.html + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + * + * + ************************************************************ + * + * + * + ***********************************************************/ +#include +#include "x86_64_delta_agc7648sv1_int.h" +#include +#include "platform_lib.h" + +#define VALIDATE(_id) \ + do { \ + if(!ONLP_OID_IS_PSU(_id)) { \ + return ONLP_STATUS_E_INVALID; \ + } \ + } while(0) + +/* + * Get all information about the given PSU oid. + */ +static onlp_psu_info_t pinfo[] = +{ + { }, /* Not used */ + { + { ONLP_PSU_ID_CREATE(PSU1_ID), "PSU-1", 0 }, + }, + { + { ONLP_PSU_ID_CREATE(PSU2_ID), "PSU-2", 0 }, + } +}; + +static int dni_psu_pmbus_info_get(int id, char *node, int *value) +{ + int ret = ONLP_STATUS_OK; + char node_path[PSU_NODE_MAX_PATH_LEN] = {0}; + + *value = 0; + + switch (id) { + case PSU1_ID: + sprintf(node_path, "%s%s", PSU1_AC_PMBUS_PREFIX, node); + break; + case PSU2_ID: + sprintf(node_path, "%s%s", PSU2_AC_PMBUS_PREFIX, node); + break; + default: + break; + } + /* Read attribute value */ + *value = dni_i2c_lock_read_attribute(NULL, node_path); + + return ret; +} + +int onlp_psui_init(void) +{ + lockinit(); + return ONLP_STATUS_OK; +} + +static int dni_psu_info_get(onlp_oid_t id, onlp_psu_info_t* info) +{ + int i = 0; + int ret = ONLP_STATUS_OK; + int local_id; + char device_name[10] = {0}; + UINT4 u4Data = 0; + UINT4 multiplier = 1000; + char name[20] = {0}; + char name1[20] = {0}; + char *module_name = name; + char *module_name1 = name1; + int val = 0; + char val_char[16] = {'\0'}; + char node_path[PSU_NODE_MAX_PATH_LEN] = {'\0'}; + + local_id = ONLP_OID_ID_GET(info->hdr.id); + + /* Set the associated oid_table + * Set PSU's fan and thermal to child OID */ + info->hdr.coids[0] = ONLP_FAN_ID_CREATE(local_id + CHASSIS_FAN_COUNT); + info->hdr.coids[1] = ONLP_THERMAL_ID_CREATE(local_id + CHASSIS_THERMAL_COUNT); + if(dni_bmc_check() == BMC_ON) + { + /* get psu model name */ + if(dni_psui_eeprom_info_get(name, "Product Name", local_id) == ONLP_STATUS_OK) + { + for(i = 0; i < PSU_NUM_LENGTH; i++) + name[i] = *(module_name + i); + strcpy(info->model, module_name); + } + else + strcpy(info->model, "ONLP_STATUS_E_UNSUPPORTED"); + + /* get psu serial number */ + if(dni_psui_eeprom_info_get(name1, "Product Serial", local_id) == ONLP_STATUS_OK) + { + for(i = 0; i < PSU_NUM_LENGTH; i++) + name1[i] = *(module_name1 + i); + strcpy(info->serial, module_name1); + } + else + strcpy(info->serial, "ONLP_STATUS_E_UNSUPPORTED"); + + /* get psu Vin/Vout */ + sprintf(device_name, "PSU%d_Vin", local_id); + if(dni_bmc_sensor_read(device_name, &u4Data, multiplier) == ONLP_STATUS_OK) + { + info->mvin = u4Data; + info->status = ONLP_PSU_STATUS_PRESENT; + info->caps |= ONLP_PSU_CAPS_VIN; + } + else + info->caps |= ONLP_PSU_STATUS_UNPLUGGED; + + sprintf(device_name, "PSU%d_Vout", local_id); + if(dni_bmc_sensor_read(device_name, &u4Data, multiplier) == ONLP_STATUS_OK) + { + info->mvout = u4Data; + info->status = ONLP_PSU_STATUS_PRESENT; + info->caps |= ONLP_PSU_CAPS_VOUT; + } + else + info->caps |= ONLP_PSU_STATUS_UNPLUGGED; + + /* get psu Iin/Iout */ + sprintf(device_name, "PSU%d_Iin", local_id); + if(dni_bmc_sensor_read(device_name, &u4Data, multiplier) == ONLP_STATUS_OK) + { + info->miin = u4Data; + info->status = ONLP_PSU_STATUS_PRESENT; + info->caps |= ONLP_PSU_CAPS_IIN; + } + else + info->caps |= ONLP_PSU_STATUS_UNPLUGGED; + + sprintf(device_name, "PSU%d_Iout", local_id); + if(dni_bmc_sensor_read(device_name, &u4Data, multiplier) == ONLP_STATUS_OK) + { + info->miout = u4Data; + info->status = ONLP_PSU_STATUS_PRESENT; + info->caps |= ONLP_PSU_CAPS_IOUT; + } + else + info->caps |= ONLP_PSU_STATUS_UNPLUGGED; + + /* get psu Pin/Pout */ + sprintf(device_name, "PSU%d_Pin", local_id); + if(dni_bmc_sensor_read(device_name, &u4Data, multiplier) == ONLP_STATUS_OK) + { + info->mpin = u4Data; + info->status = ONLP_PSU_STATUS_PRESENT; + info->caps |= ONLP_PSU_CAPS_PIN; + } + else + info->caps |= ONLP_PSU_STATUS_UNPLUGGED; + + sprintf(device_name, "PSU%d_Pout", local_id); + if(dni_bmc_sensor_read(device_name, &u4Data, multiplier) == ONLP_STATUS_OK) + { + info->mpout = u4Data; + info->status = ONLP_PSU_STATUS_PRESENT; + info->caps |= ONLP_PSU_CAPS_POUT; + } + else + info->caps |= ONLP_PSU_STATUS_UNPLUGGED; + } + else + { + int index = ONLP_OID_ID_GET(info->hdr.id); + + /* Read PSU product name from attribute */ + sprintf(node_path, "%s%s", PSU1_AC_PMBUS_PREFIX, "psu_mfr_model"); + dni_i2c_read_attribute_string(node_path, val_char, sizeof(val_char), 0); + strcpy(info->model, val_char); + + /* Read PSU serial number from attribute */ + sprintf(node_path, "%s%s", PSU1_AC_PMBUS_PREFIX, "psu_mfr_serial"); + dni_i2c_read_attribute_string(node_path, val_char, sizeof(val_char), 0); + strcpy(info->serial, val_char); + + /* Read voltage, current and power */ + if (dni_psu_pmbus_info_get(index, "psu_v_in", &val) == 0) + { + info->mvin = val; + info->caps |= ONLP_PSU_CAPS_VIN; + } + + if (dni_psu_pmbus_info_get(index, "psu_v_out", &val) == 0) + { + info->mvout = val; + info->caps |= ONLP_PSU_CAPS_VOUT; + } + + if (dni_psu_pmbus_info_get(index, "psu_i_in", &val) == 0) + { + info->miin = val; + info->caps |= ONLP_PSU_CAPS_IIN; + } + + if (dni_psu_pmbus_info_get(index, "psu_i_out", &val) == 0) + { + info->miout = val; + info->caps |= ONLP_PSU_CAPS_IOUT; + } + + if (dni_psu_pmbus_info_get(index, "psu_p_in", &val) == 0) + { + info->mpin = val; + info->caps |= ONLP_PSU_CAPS_PIN; + } + + if (dni_psu_pmbus_info_get(index, "psu_p_out", &val) == 0) + { + info->mpout = val; + info->caps |= ONLP_PSU_CAPS_POUT; + } + } + return ret; +} + +int onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info) +{ + int val = 0; + int ret = ONLP_STATUS_OK; + int index = ONLP_OID_ID_GET(id); + dev_info_t dev_info; + char device_name[10] = {0}; + UINT4 u4Data = 0; + UINT4 multiplier = 1000; + + VALIDATE(id); + + /* Set the onlp_oid_hdr_t */ + memset(info, 0, sizeof(onlp_psu_info_t)); + *info = pinfo[index]; + + switch (index) { + case PSU1_ID: + dev_info.bus = I2C_BUS_31; + break; + case PSU2_ID: + dev_info.bus = I2C_BUS_32; + break; + default: + break; + } + + if(dni_bmc_check() == BMC_ON) + { + /* Check PSU have voltage input or not */ + sprintf(device_name, "PSU%d_Vin", index); + if(dni_bmc_sensor_read(device_name, &u4Data, multiplier) == ONLP_STATUS_OK) + { + if(u4Data == 0) + { + info->status = ONLP_PSU_STATUS_FAILED; + return ret; + } + info->mpin = u4Data; + info->status = ONLP_PSU_STATUS_PRESENT; + info->caps |= ONLP_PSU_CAPS_VIN; + } + } + else + { + dev_info.addr = PSU_EEPROM; + dev_info.offset = 0x00; /* In EEPROM address 0x00 */ + dev_info.flags = DEFAULT_FLAG; + + /* Check PSU have voltage input or not */ + dni_psu_pmbus_info_get(index, "psu_v_in", &val); + + /* Check PSU is PRESENT or not + * Read PSU EEPROM 1 byte from adress 0x00 + * if not present, return negative value. */ + if(val == 0 && dni_i2c_lock_read(NULL, &dev_info) < 0) + { + /* Unable to read PSU EEPROM */ + /* Able to read PSU VIN(psu_power_not_good) */ + info->status |= ONLP_PSU_STATUS_FAILED; + return ret; + } + else if(val == 0) + { + /* Unable to read PSU VIN(psu_power_good) */ + info->status |= ONLP_PSU_STATUS_UNPLUGGED; + } + else + info->status |= ONLP_PSU_STATUS_PRESENT; + } + + ret = dni_psu_info_get(id, info); + return ret; +} + +int onlp_psui_ioctl(onlp_oid_t pid, va_list vargs) +{ + return ONLP_STATUS_E_UNSUPPORTED; +} diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/sfpi.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/sfpi.c new file mode 100755 index 00000000..a7c402e8 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/sfpi.c @@ -0,0 +1,467 @@ +/************************************************************ + * + * + * Copyright 2014 Big Switch Networks, Inc. + * Copyright (C) 2017 Delta Networks, Inc. + * + * Licensed under the Eclipse Public License, Version 1.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.eclipse.org/legal/epl-v10.html + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + * + * + ************************************************************ + * + * + * + ***********************************************************/ +#include +#include /* For O_RDWR && open */ +#include +#include +#include +#include +#include +#include +#include +#include "platform_lib.h" + +/******************* Utility Function *****************************************/ +int sfp_map_bus[] = { + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, /* SFP */ + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, /* SFP */ + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, /* SFP */ + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, /* SFP */ + 91, 92, 93, 94, 95, 96, 97, 98, /* SFP */ + 41, 42, 43, 44, 45, 46, /* QSFP */ +}; + +/************************************************************ + * + * SFPI Entry Points + * + ***********************************************************/ +int onlp_sfpi_init(void) +{ + /* Called at initialization time */ + lockinit(); + return ONLP_STATUS_OK; +} + +int onlp_sfpi_map_bus_index(int port) +{ + if(port < 0 || port > 54) + return ONLP_STATUS_E_INTERNAL; + return sfp_map_bus[port-1]; +} + +int onlp_sfpi_bitmap_get(onlp_sfp_bitmap_t* bmap) +{ + /* Ports {1, 54} */ + int p; + AIM_BITMAP_CLR_ALL(bmap); + + for(p = 1; p <= NUM_OF_PORT; p++) { + AIM_BITMAP_SET(bmap, p); + } + return ONLP_STATUS_OK; +} + +int onlp_sfpi_is_present(int port) +{ + char port_data[2]; + int present, present_bit; + + if(port > 0 && port < 55) + { + /* Select QSFP/SFP port */ + sprintf(port_data, "%d", port ); + if(dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH) < 0){ + AIM_LOG_ERROR("Unable to select port(%d)\r\n", port); + } + + /* Read QSFP/SFP MODULE is present or not */ + present_bit = dni_i2c_lock_read_attribute(NULL, SFP_IS_PRESENT_PATH); + if(present_bit < 0){ + AIM_LOG_ERROR("Unable to read present or not from port(%d)\r\n", port); + } + } + + /* From sfp_is_present value, + * return 0 = The module is preset + * return 1 = The module is NOT present */ + if(present_bit == 0) { + present = 1; + } else if (present_bit == 1) { + present = 0; + AIM_LOG_ERROR("Unble to present status from port(%d)\r\n", port); + } else { + /* Port range over 1-54, return -1 */ + AIM_LOG_ERROR("Error to present status from port(%d)\r\n", port); + present = -1; + } + return present; +} + +int onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) +{ + char present_all_data[21] = {'\0'}; + char *r_byte; + char *r_array[7]; + uint8_t bytes[7]; + int count = 0; + + /* Read presence bitmap from SWPLD2 SFP+ and SWPLD1 QSFP28 Presence Register + * if only port 0 is present, return 3F FF FF FF FF FF FE + * if only port 0 and 1 present, return 3F FF FF FF FF FF FC */ + + if(dni_i2c_read_attribute_string(SFP_IS_PRESENT_ALL_PATH, present_all_data, + sizeof(present_all_data), 0) < 0) { + return -1; + } + + /* String split */ + r_byte = strtok(present_all_data, " "); + while (r_byte != NULL) { + r_array[count++] = r_byte; + r_byte = strtok(NULL, " "); + } + + /* Convert a string to unsigned 8 bit integer + * and saved into bytes[] */ + for (count = 0; count < 7; count++) { + bytes[count] = ~strtol(r_array[count], NULL, 16); + } + + /* Mask out non-existant SFP/QSFP ports */ + bytes[0] &= 0x3F; + + /* Convert to 64 bit integer in port order */ + int i = 0; + uint64_t presence_all = 0; + + for(i = 0; i < AIM_ARRAYSIZE(bytes); i++) { + presence_all <<= 8; + presence_all |= bytes[i]; + } + + /* Populate bitmap & remap */ + for(i = 0; presence_all; i++) + { + AIM_BITMAP_MOD(dst, i+1, (presence_all & 1)); + presence_all >>= 1; + } + return ONLP_STATUS_OK; +} + +int onlp_sfpi_eeprom_read(int port, uint8_t data[256]) +{ + int size = 0; + + memset(data, 0, 256); + + if(onlp_file_read(data, 256, &size, PORT_EEPROM_FORMAT, onlp_sfpi_map_bus_index(port)) != ONLP_STATUS_OK) { + AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + + if (size != 256) { + AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is different!\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + return ONLP_STATUS_OK; +} + +int onlp_sfpi_port_map(int port, int* rport) +{ + *rport = port; + return ONLP_STATUS_OK; +} + +int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) +{ + int value_t; + char port_data[2]; + + if(port > 0 && port < 55) + { + /* Select SFP(1-48), QSFP(49-54) port */ + sprintf(port_data, "%d", port ); + if(dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH) < 0){ + AIM_LOG_INFO("Unable to select port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + } + + switch (control) { + case ONLP_SFP_CONTROL_RESET_STATE: + /* From sfp_reset value, + * return 0 = The module is in Reset + * return 1 = The module is NOT in Reset */ + *value = dni_i2c_lock_read_attribute(NULL, QSFP_RESET_PATH); + if (*value == 0) + { + *value = 1; + } + else if (*value == 1) + { + *value = 0; + } + value_t = ONLP_STATUS_OK; + break; + case ONLP_SFP_CONTROL_RX_LOS: + /* From sfp_rx_los value, + * return 0 = The module is Normal Operation + * return 1 = The module is Error */ + *value = dni_i2c_lock_read_attribute(NULL, SFP_RX_LOS_PATH); + value_t = ONLP_STATUS_OK; + break; + case ONLP_SFP_CONTROL_TX_DISABLE: + /* From sfp_tx_disable value, + * return 0 = The module is Enable Transmitter on + * return 1 = The module is Transmitter Disabled */ + *value = dni_i2c_lock_read_attribute(NULL, SFP_TX_DISABLE_PATH); + value_t = ONLP_STATUS_OK; + break; + case ONLP_SFP_CONTROL_TX_FAULT: + /* From sfp_tx_fault value, + * return 0 = The module is Normal + * return 1 = The module is Fault */ + *value = dni_i2c_lock_read_attribute(NULL, SFP_TX_FAULT_PATH); + value_t = ONLP_STATUS_OK; + break; + case ONLP_SFP_CONTROL_LP_MODE: + /* From sfp_lp_mode value, + * return 0 = The module is NOT in LP mode + * return 1 = The module is in LP mode */ + *value = dni_i2c_lock_read_attribute(NULL, QSFP_LP_MODE_PATH); + value_t = ONLP_STATUS_OK; + break; + default: + value_t = ONLP_STATUS_E_UNSUPPORTED; + break; + } + return value_t; +} + +int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) +{ + int value_t; + char port_data[2]; + + if(port > 0 && port < 55) + { + /* Select SFP(1-48), QSFP(49-54) port */ + sprintf(port_data, "%d", port ); + if(dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH) < 0){ + AIM_LOG_INFO("Unable to select port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + } + + switch (control) { + case ONLP_SFP_CONTROL_RESET_STATE: + sprintf(port_data, "%d", value); + if(dni_i2c_lock_write_attribute(NULL, port_data, QSFP_RESET_PATH) < 0){ + AIM_LOG_INFO("Unable to control reset state from port(%d)\r\n", port); + value_t = ONLP_STATUS_E_INTERNAL; + } + value_t = ONLP_STATUS_OK; + break; + case ONLP_SFP_CONTROL_RX_LOS: + value_t = ONLP_STATUS_E_UNSUPPORTED; + break; + case ONLP_SFP_CONTROL_TX_DISABLE: + sprintf(port_data, "%d", value); + if(dni_i2c_lock_write_attribute(NULL, port_data, SFP_TX_DISABLE_PATH) < 0){ + AIM_LOG_INFO("Unable to control tx disable from port(%d)\r\n", port); + value_t = ONLP_STATUS_E_INTERNAL; + } + value_t = ONLP_STATUS_OK; + break; + case ONLP_SFP_CONTROL_TX_FAULT: + value_t = ONLP_STATUS_E_UNSUPPORTED; + break; + case ONLP_SFP_CONTROL_LP_MODE: + sprintf(port_data, "%d", value); + if(dni_i2c_lock_write_attribute(NULL, port_data, QSFP_LP_MODE_PATH) < 0){ + AIM_LOG_INFO("Unable to control LP mode from port(%d)\r\n", port); + value_t = ONLP_STATUS_E_INTERNAL; + } + value_t = ONLP_STATUS_OK; + break; + default: + value_t = ONLP_STATUS_E_UNSUPPORTED; + break; + } + return value_t; +} + +int onlp_sfpi_dev_readb(int port, uint8_t devaddr, uint8_t addr) +{ + int bus; + + bus = onlp_sfpi_map_bus_index(port); + return onlp_i2c_readb(bus, devaddr, addr, ONLP_I2C_F_FORCE); +} + +int onlp_sfpi_dev_writeb(int port, uint8_t devaddr, uint8_t addr, uint8_t value) +{ + int bus; + + bus = onlp_sfpi_map_bus_index(port); + return onlp_i2c_writeb(bus, devaddr, addr, value, ONLP_I2C_F_FORCE); + +} + +int onlp_sfpi_dev_readw(int port, uint8_t devaddr, uint8_t addr) +{ + int bus; + + bus = onlp_sfpi_map_bus_index(port); + return onlp_i2c_readw(bus, devaddr, addr, ONLP_I2C_F_FORCE); +} + +int onlp_sfpi_dev_writew(int port, uint8_t devaddr, uint8_t addr, uint16_t value) +{ + int bus; + + bus = onlp_sfpi_map_bus_index(port); + return onlp_i2c_writew(bus, devaddr, addr, value, ONLP_I2C_F_FORCE); +} + +int onlp_sfpi_control_supported(int port, onlp_sfp_control_t control, int* rv) +{ + char port_data[2] ; + + if(port > 0 && port < 55) + { + /* Select SFP(1-48), QSFP(49-54) port */ + sprintf(port_data, "%d", port); + if(dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH) < 0){ + AIM_LOG_INFO("Unable to select port(%d)\r\n", port); + return ONLP_STATUS_E_INTERNAL; + } + } + + switch (control) { + case ONLP_SFP_CONTROL_RESET_STATE: + if(port > 48 && port < 55) /* QSFP */ + *rv = 1; + else + *rv = 0; + break; + case ONLP_SFP_CONTROL_RX_LOS: + if(port > 0 && port < 49) /* SFP */ + *rv = 1; + else + *rv = 0; + break; + case ONLP_SFP_CONTROL_TX_DISABLE: + if(port > 0 && port < 49) /* SFP */ + *rv = 1; + else + *rv = 0; + break; + case ONLP_SFP_CONTROL_TX_FAULT: + if(port > 0 && port < 49) /* SFP */ + *rv = 1; + else + *rv = 0; + break; + case ONLP_SFP_CONTROL_LP_MODE: + if(port > 48 && port < 55) /* QSFP */ + *rv = 1; + else + *rv = 0; + break; + default: + break; + } + return ONLP_STATUS_OK; +} + +int onlp_sfpi_denit(void) +{ + return ONLP_STATUS_OK; +} + +int onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) +{ + char rxlos_all_data[18] = {'\0'}; + char *r_byte; + char *r_array[6]; + uint8_t bytes[6]; + int count = 0; + + /* Read rx_los bitmap from SWPLD2 SFP+ LOSS Register + * if only port 0 is normal operation, return FF FF FF FF FF FE + * if only port 0 and 1 normal operation, return FF FF FF FF FF FC */ + + if(dni_i2c_read_attribute_string(SFP_RX_LOS_ALL_PATH, rxlos_all_data, + sizeof(rxlos_all_data), 0) < 0) { + return -1; + } + + /* String split */ + r_byte = strtok(rxlos_all_data, " "); + while (r_byte != NULL) { + r_array[count++] = r_byte; + r_byte = strtok(NULL, " "); + } + + /* Convert a string to unsigned 8 bit integer + * and saved into bytes[] */ + for (count = 0; count < 6; count++) { + bytes[count] = strtol(r_array[count], NULL, 16); + } + + /* Convert to 64 bit integer in port order */ + int i = 0; + uint64_t rxlos_all = 0; + + for(i = 0; i < AIM_ARRAYSIZE(bytes); i++) { + rxlos_all <<= 8; + rxlos_all |= bytes[i]; + } + + for(i = 0; i < 48; i++) + { + AIM_BITMAP_MOD(dst, i+1, (rxlos_all & 1)); + rxlos_all >>= 1; + } + + /* Mask out non-existant QSFP ports */ + for(i = 48; i < 54; i++) + AIM_BITMAP_MOD(dst, i+1, 0); + + return ONLP_STATUS_OK; +} + +int onlp_sfpi_dom_read(int port, uint8_t data[256]) +{ + return ONLP_STATUS_OK; +} + +int onlp_sfpi_post_insert(int port, sff_info_t* info) +{ + return ONLP_STATUS_E_UNSUPPORTED; +} + +void onlp_sfpi_debug(int port, aim_pvs_t* pvs) +{ +} + +int onlp_sfpi_ioctl(int port, va_list vargs) +{ + return ONLP_STATUS_E_UNSUPPORTED; +} + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/sysi.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/sysi.c new file mode 100755 index 00000000..4a793442 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/sysi.c @@ -0,0 +1,354 @@ +/************************************************************ + * + * + * Copyright 2014 Big Switch Networks, Inc. + * Copyright 2017 (C) Delta Networks, Inc. + * + * Licensed under the Eclipse Public License, Version 1.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.eclipse.org/legal/epl-v10.html + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + * + * + ************************************************************ + * + * + * + ***********************************************************/ +#include +#include +#include +#include "x86_64_delta_agc7648sv1_int.h" +#include "x86_64_delta_agc7648sv1_log.h" +#include "platform_lib.h" +#include +#include +#include +#include +#include +#include +#include +#include + +int decide_percentage(int *percentage, int temper) +{ + int level; + + if(temper <= 50) + { + *percentage = 50; + level = 1; + } + else if(temper > 50 && temper <= 55) + { + *percentage = 58; + level = 2; + } + else if(temper > 55 && temper <= 60) + { + *percentage = 65; + level = 3; + } + else if(temper > 60 && temper <= 65) + { + *percentage = 80; + level = 4; + } + else if(temper > 65) + { + *percentage = 100; + level = 5; + } + else + { + *percentage = 100; + level = 6; + } + + return level; +} + +const char* onlp_sysi_platform_get(void) +{ + return "x86-64-delta-agc7648sv1-r0"; +} + +int onlp_sysi_init(void) +{ + lockinit(); + return ONLP_STATUS_OK; +} + +int onlp_sysi_onie_data_get(uint8_t** data, int* size) +{ + uint8_t* rdata = aim_zmalloc(256); + + if(onlp_file_read(rdata, 256, size, IDPROM_PATH) == ONLP_STATUS_OK) + { + if(*size == 256) + { + *data = rdata; + return ONLP_STATUS_OK; + } + } + + aim_free(rdata); + *size = 0; + + return ONLP_STATUS_E_UNSUPPORTED; +} + +int onlp_sysi_platform_info_get(onlp_platform_info_t* pi) +{ + int cpld_version = 6; + cpld_version = dni_i2c_lock_read_attribute(NULL, CPU_CPLD_VERSION); + pi->cpld_versions = aim_fstrdup("%d", cpld_version); + + return ONLP_STATUS_OK; +} + +void onlp_sysi_onie_data_free(uint8_t* data) +{ + aim_free(data); +} + +void onlp_sysi_platform_info_free(onlp_platform_info_t* pi) +{ + aim_free(pi->cpld_versions); +} + +int onlp_sysi_oids_get(onlp_oid_t* table, int max) +{ + int i = 0; + onlp_oid_t* e = table; + memset(table, 0, max*sizeof(onlp_oid_t)); + + for (i = 1; i <= NUM_OF_THERMAL_ON_MAIN_BROAD; i++) + { + *e++ = ONLP_THERMAL_ID_CREATE(i); + } + + for (i = 1; i <= NUM_OF_LED_ON_MAIN_BROAD; i++) + { + *e++ = ONLP_LED_ID_CREATE(i); + } + + for (i = 1; i <= NUM_OF_PSU_ON_MAIN_BROAD; i++) + { + *e++ = ONLP_PSU_ID_CREATE(i); + } + + for (i = 1; i <= NUM_OF_FAN_ON_MAIN_BROAD; i++) + { + *e++ = ONLP_FAN_ID_CREATE(i); + } + + return ONLP_STATUS_OK; +} + +int onlp_sysi_platform_manage_fans(void) +{ + int i, new_percentage, highest_temp = 0; + onlp_thermal_info_t thermal; + int rv; + + if(dni_bmc_check() == BMC_ON) + { + rv = ONLP_STATUS_OK; + } + else{ + /* Get all thermal current temperature and decide fan percentage */ + for(i = 1; i <= NUM_OF_THERMAL; ++i) + { + if(onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(i), &thermal) != ONLP_STATUS_OK) + { + AIM_LOG_ERROR("Unable to read thermal status"); + return ONLP_STATUS_E_INTERNAL; + } + + thermal.mcelsius /= 1000; + if(thermal.mcelsius > highest_temp) + { + highest_temp = thermal.mcelsius; + } + decide_percentage(&new_percentage, highest_temp); + } + + /* Set fantray RPM and PSU fan percentage */ + onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_1_ON_FAN_BOARD), MAX_FRONT_FAN_SPEED * new_percentage / 100); + onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_2_ON_FAN_BOARD), MAX_FRONT_FAN_SPEED * new_percentage / 100); + onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_3_ON_FAN_BOARD), MAX_FRONT_FAN_SPEED * new_percentage / 100); + onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_4_ON_FAN_BOARD), MAX_FRONT_FAN_SPEED * new_percentage / 100); + onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_5_ON_FAN_BOARD), MAX_REAR_FAN_SPEED * new_percentage / 100); + onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_6_ON_FAN_BOARD), MAX_REAR_FAN_SPEED * new_percentage / 100); + onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_7_ON_FAN_BOARD), MAX_REAR_FAN_SPEED * new_percentage / 100); + onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_8_ON_FAN_BOARD), MAX_REAR_FAN_SPEED * new_percentage / 100); + onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(FAN_1_ON_PSU1), new_percentage); + onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(FAN_1_ON_PSU2), new_percentage); + + rv = ONLP_STATUS_OK; + } + return rv; +} + +int onlp_sysi_platform_manage_leds(void) +{ + int rpm = 0, rpm1 = 0, count = 0; + uint8_t present_bit = 0x00; + int rv; + int fantray_count; + uint8_t psu_state; + int psu_pwr_status = 0; + int psu_pwr_int = 0; + dev_info_t dev_info; + + if(dni_bmc_check() == BMC_ON) + { + rv = ONLP_STATUS_OK; + } + else{ + dev_info.offset = 0x00; + dev_info.flags = DEFAULT_FLAG; + dev_info.addr = FAN_IO_CTL; + dev_info.bus = I2C_BUS_27; + dev_info.size = 1; + + present_bit = dni_i2c_lock_read(NULL, &dev_info); + /* Fan tray 1 */ + rpm = dni_i2c_lock_read_attribute(NULL, FAN1_FRONT); + rpm1 = dni_i2c_lock_read_attribute(NULL, FAN1_REAR); + + if((present_bit & (1 << 3)) == 0 && rpm != FAN_ZERO_RPM && rpm != 0 && rpm1 != FAN_ZERO_RPM && rpm1 != 0 ) + { + /* Green */ + if(onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_1),ONLP_LED_MODE_GREEN) != ONLP_STATUS_OK) + rv = ONLP_STATUS_E_INTERNAL; + } + else + { + /* Red */ + if(onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_1),ONLP_LED_MODE_RED) != ONLP_STATUS_OK) + rv = ONLP_STATUS_E_INTERNAL; + } + + /* Fan tray 2 */ + rpm = dni_i2c_lock_read_attribute(NULL, FAN2_FRONT); + rpm1 = dni_i2c_lock_read_attribute(NULL, FAN2_REAR); + + if((present_bit & (1 << 2)) == 0 && rpm != FAN_ZERO_RPM && rpm != 0 && rpm1 != FAN_ZERO_RPM && rpm1 != 0 ) + { + /* Green */ + if(onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_2),ONLP_LED_MODE_GREEN) != ONLP_STATUS_OK) + rv = ONLP_STATUS_E_INTERNAL; + } + else + { + /* Red */ + if(onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_2),ONLP_LED_MODE_RED) != ONLP_STATUS_OK) + rv = ONLP_STATUS_E_INTERNAL; + } + + /* Fan tray 3 */ + rpm = dni_i2c_lock_read_attribute(NULL, FAN3_FRONT); + rpm1 = dni_i2c_lock_read_attribute(NULL, FAN3_REAR); + + if((present_bit & (1 << 1)) == 0 && rpm != FAN_ZERO_RPM && rpm != 0 && rpm1 != FAN_ZERO_RPM && rpm1 != 0 ) + { + /* Green */ + if(onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_3),ONLP_LED_MODE_GREEN) != ONLP_STATUS_OK) + rv = ONLP_STATUS_E_INTERNAL; + } + else + { + /* Red */ + if(onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_3),ONLP_LED_MODE_RED) != ONLP_STATUS_OK) + rv = ONLP_STATUS_E_INTERNAL; + } + + /* Fan tray 4 */ + rpm = dni_i2c_lock_read_attribute(NULL, FAN4_FRONT); + rpm1 = dni_i2c_lock_read_attribute(NULL, FAN4_REAR); + + if((present_bit & 1) == 0 && rpm != FAN_ZERO_RPM && rpm != 0 && rpm1 != FAN_ZERO_RPM && rpm1 != 0 ) + { + /* Green */ + if(onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_4),ONLP_LED_MODE_GREEN) != ONLP_STATUS_OK) + rv = ONLP_STATUS_E_INTERNAL; + } + else + { + /* Red */ + if(onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_4),ONLP_LED_MODE_RED) != ONLP_STATUS_OK) + rv = ONLP_STATUS_E_INTERNAL; + } + + /* FRONT FAN & SYS LED */ + for(fantray_count = 0; fantray_count < 4; fantray_count++) + { + present_bit = dni_i2c_lock_read(NULL, &dev_info); + if((present_bit & (1 << fantray_count)) == 0) + count++; + } + + if(count == ALL_FAN_TRAY_EXIST && dni_fan_speed_good() == FAN_SPEED_NORMALLY) + { + /* Green */ + if((onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FRONT_FAN),ONLP_LED_MODE_GREEN) != ONLP_STATUS_OK) || + (onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FRONT_SYS),ONLP_LED_MODE_GREEN) != ONLP_STATUS_OK)) + rv = ONLP_STATUS_E_INTERNAL; + } + else + { + /* Solid Amber FAN or more failed*/ + if((onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FRONT_FAN),ONLP_LED_MODE_YELLOW) != ONLP_STATUS_OK) || + (onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FRONT_SYS),ONLP_LED_MODE_YELLOW) != ONLP_STATUS_OK)) + rv = ONLP_STATUS_E_INTERNAL; + } + + /* Set front light of PWR */ + dev_info.bus = I2C_BUS_31; // PSU1 + dev_info.addr = PSU_EEPROM; + psu_state = dni_i2c_lock_read(NULL, &dev_info); + psu_pwr_status = dni_lock_cpld_read_attribute(SWPLD1_PATH,POWER_STATUS_REGISTER); + psu_pwr_int = dni_lock_cpld_read_attribute(SWPLD1_PATH,POWER_INT_REGISTER); + + if(psu_state == 1 && (psu_pwr_status & 0x80) == 0x80 && (psu_pwr_int & 0x10) == 0x10) + { + /* Green */ + if(onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FRONT_PWR),ONLP_LED_MODE_GREEN) != ONLP_STATUS_OK) + rv = ONLP_STATUS_E_INTERNAL; + } + else + { + /* Amber */ + if(onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FRONT_PWR),ONLP_LED_MODE_YELLOW) != ONLP_STATUS_OK) + rv = ONLP_STATUS_E_INTERNAL; + } + + dev_info.bus = I2C_BUS_32; // PSU2 + psu_state = dni_i2c_lock_read(NULL, &dev_info); + + if(psu_state == 1 && (psu_pwr_status & 0x40) == 0x40 && (psu_pwr_int & 0x20) == 0x20) + { + /* Green */ + if(onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FRONT_PWR),ONLP_LED_MODE_GREEN) != ONLP_STATUS_OK) + rv = ONLP_STATUS_E_INTERNAL; + } + else + { + /* Amber */ + if(onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FRONT_PWR),ONLP_LED_MODE_YELLOW) != ONLP_STATUS_OK) + rv = ONLP_STATUS_E_INTERNAL; + } + rv = ONLP_STATUS_OK; + } + return rv; +} diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/thermali.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/thermali.c new file mode 100755 index 00000000..1a232070 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/thermali.c @@ -0,0 +1,227 @@ +/************************************************************ + * + * + * Copyright 2014 Big Switch Networks, Inc. + * Copyright 2017 (C) Delta Networks, Inc. + * + * Licensed under the Eclipse Public License, Version 1.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.eclipse.org/legal/epl-v10.html + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + * + * + ************************************************************ + * + * Thermal Sensor Platform Implementation. + * + ***********************************************************/ + +#include "platform_lib.h" +#include +#include +#include "x86_64_delta_agc7648sv1_log.h" + + +#define VALIDATE(_id) \ + do { \ + if(!ONLP_OID_IS_THERMAL(_id)) { \ + return ONLP_STATUS_E_INVALID; \ + } \ + } while(0) + +#define dni_onlp_thermal_threshold(WARNING_DEFAULT, ERROR_DEFAULT, SHUTDOWN_DEFAULT){ \ + WARNING_DEFAULT, \ + ERROR_DEFAULT, \ + SHUTDOWN_DEFAULT, \ +} +static char* path[] = /* must map with onlp_thermal_id */ +{ + "reserved", + "26-004f/hwmon/hwmon6/temp1_input", + "8-004b/hwmon/hwmon1/temp1_input", + "8-004c/hwmon/hwmon2/temp1_input", + "8-004c/hwmon/hwmon2/temp2_input", + "8-004d/hwmon/hwmon3/temp1_input", + "8-004d/hwmon/hwmon3/temp2_input", + "8-004d/hwmon/hwmon3/temp3_input", + "8-004e/hwmon/hwmon4/temp1_input", + "8-004f/hwmon/hwmon5/temp1_input", + "31-0058/psu_temp1_input", + "32-0058/psu_temp1_input" +}; + +/* Static values */ +static onlp_thermal_info_t linfo[] = { + { }, /* Not used */ + { { ONLP_THERMAL_ID_CREATE(THERMAL_1_ON_FAN_BOARD), "Board sensor on Fan_BD", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_2_ON_CPU_BOARD), "Board sensor near CPU", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_3_ON_MAIN_BOARD_TEMP_1), "Board sensor near MAC temp-1", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_4_ON_MAIN_BOARD_TEMP_2), "Board sensor near MAC temp-2", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_5_ON_MAIN_BOARD_TEMP_1), "Board sensor near SyncE temp-1", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_6_ON_MAIN_BOARD_TEMP_2), "Board sensor near SyncE temp-2", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_7_ON_MAIN_BOARD_TEMP_3), "Board sensor near SyncE temp-3", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_8_ON_MAIN_BOARD), "Board sensor near MAC", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_9_ON_MAIN_BOARD), "Board sensor near MAC", 0}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_10_ON_PSU1), "PSU-1 internal sensor", ONLP_PSU_ID_CREATE(PSU1_ID)}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + }, + { { ONLP_THERMAL_ID_CREATE(THERMAL_11_ON_PSU2), "PSU-2 internal Sensor", ONLP_PSU_ID_CREATE(PSU2_ID)}, + ONLP_THERMAL_STATUS_PRESENT, + ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS + } +}; + +/* + * This will be called to intiialize the thermali subsystem. + */ +int +onlp_thermali_init(void) +{ + lockinit(); + return ONLP_STATUS_OK; +} + +/* + * Retrieve the information structure for the given thermal OID. + * + * If the OID is invalid, return ONLP_E_STATUS_INVALID. + * If an unexpected error occurs, return ONLP_E_STATUS_INTERNAL. + * Otherwise, return ONLP_STATUS_OK with the OID's information. + * + * Note -- it is expected that you fill out the information + * structure even if the sensor described by the OID is not present. + */ +int +onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info) +{ + uint8_t local_id = 0; + UINT4 multiplier = 1000; + UINT4 u4Data = 0; + char device_buf[20] = {0}; + int temp_base = 1; + int rv; + char fullpath[50] = {0}; + int r_data = 0; + + VALIDATE(id); + local_id = ONLP_OID_ID_GET(id); + *info = linfo[local_id]; + + if(dni_bmc_check() == BMC_ON) + { + switch(local_id) { + case THERMAL_1_ON_FAN_BOARD: + sprintf(device_buf, "Fan_Temp"); + rv = dni_bmc_sensor_read(device_buf, &u4Data, multiplier); + break; + case THERMAL_2_ON_CPU_BOARD: + case THERMAL_3_ON_MAIN_BOARD_TEMP_1: + case THERMAL_4_ON_MAIN_BOARD_TEMP_2: + case THERMAL_5_ON_MAIN_BOARD_TEMP_1: + case THERMAL_6_ON_MAIN_BOARD_TEMP_2: + case THERMAL_7_ON_MAIN_BOARD_TEMP_3: + case THERMAL_8_ON_MAIN_BOARD: + case THERMAL_9_ON_MAIN_BOARD: + local_id--; + sprintf(device_buf, "Temp_Sensor_%d", local_id); + rv = dni_bmc_sensor_read(device_buf, &u4Data, multiplier); + break; + case THERMAL_10_ON_PSU1: + sprintf(device_buf, "PSU1_Temp_1"); + rv = dni_bmc_sensor_read(device_buf, &u4Data, multiplier); + break; + case THERMAL_11_ON_PSU2: + sprintf(device_buf, "PSU2_Temp_1"); + rv = dni_bmc_sensor_read(device_buf, &u4Data, multiplier); + break; + default: + AIM_LOG_ERROR("Invalid Thermal ID!!\n"); + return ONLP_STATUS_E_PARAM; + } + + if (u4Data == 0 || rv == ONLP_STATUS_E_GENERIC){ + return ONLP_STATUS_E_INTERNAL; + } + else{ + info->mcelsius = u4Data; + return 0; + } + } + else + { + switch (local_id) { + case THERMAL_1_ON_FAN_BOARD: + sprintf(fullpath,"%s%s", PREFIX_PATH, path[local_id]); + break; + case THERMAL_2_ON_CPU_BOARD: + sprintf(fullpath,"%s%s", PREFIX_PATH, path[local_id]); + break; + case THERMAL_3_ON_MAIN_BOARD_TEMP_1: + sprintf(fullpath,"%s%s", PREFIX_PATH, path[local_id]); + break; + case THERMAL_4_ON_MAIN_BOARD_TEMP_2: + sprintf(fullpath,"%s%s", PREFIX_PATH, path[local_id]); + break; + case THERMAL_5_ON_MAIN_BOARD_TEMP_1: + sprintf(fullpath,"%s%s", PREFIX_PATH, path[local_id]); + break; + case THERMAL_6_ON_MAIN_BOARD_TEMP_2: + sprintf(fullpath,"%s%s", PREFIX_PATH, path[local_id]); + break; + case THERMAL_7_ON_MAIN_BOARD_TEMP_3: + sprintf(fullpath,"%s%s", PREFIX_PATH, path[local_id]); + break; + case THERMAL_8_ON_MAIN_BOARD: + sprintf(fullpath,"%s%s", PREFIX_PATH, path[local_id]); + break; + case THERMAL_9_ON_MAIN_BOARD: + sprintf(fullpath,"%s%s", PREFIX_PATH, path[local_id]); + break; + case THERMAL_10_ON_PSU1: + sprintf(fullpath,"%s%s", PREFIX_PATH, path[local_id]); + break; + case THERMAL_11_ON_PSU2: + sprintf(fullpath,"%s%s", PREFIX_PATH, path[local_id]); + break; + } + r_data = dni_i2c_lock_read_attribute(NULL, fullpath); + info->mcelsius = r_data / temp_base; + } + return ONLP_STATUS_OK; +} diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_config.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_config.c new file mode 100755 index 00000000..421e2320 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_config.c @@ -0,0 +1,91 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +/* */ +#define __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME(_x) #_x +#define __x86_64_delta_agc7648sv1_config_STRINGIFY_VALUE(_x) __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME(_x) +x86_64_delta_agc7648sv1_config_settings_t x86_64_delta_agc7648sv1_config_settings[] = +{ +#ifdef X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_LOGGING + { __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_LOGGING), __x86_64_delta_agc7648sv1_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_LOGGING) }, +#else +{ X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_LOGGING(__x86_64_delta_agc7648sv1_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_DELTA_AGC7648SV1_CONFIG_LOG_OPTIONS_DEFAULT + { __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648SV1_CONFIG_LOG_OPTIONS_DEFAULT), __x86_64_delta_agc7648sv1_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648SV1_CONFIG_LOG_OPTIONS_DEFAULT) }, +#else +{ X86_64_DELTA_AGC7648SV1_CONFIG_LOG_OPTIONS_DEFAULT(__x86_64_delta_agc7648sv1_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_DELTA_AGC7648SV1_CONFIG_LOG_BITS_DEFAULT + { __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648SV1_CONFIG_LOG_BITS_DEFAULT), __x86_64_delta_agc7648sv1_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648SV1_CONFIG_LOG_BITS_DEFAULT) }, +#else +{ X86_64_DELTA_AGC7648SV1_CONFIG_LOG_BITS_DEFAULT(__x86_64_delta_agc7648sv1_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_DELTA_AGC7648SV1_CONFIG_LOG_CUSTOM_BITS_DEFAULT + { __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648SV1_CONFIG_LOG_CUSTOM_BITS_DEFAULT), __x86_64_delta_agc7648sv1_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648SV1_CONFIG_LOG_CUSTOM_BITS_DEFAULT) }, +#else +{ X86_64_DELTA_AGC7648SV1_CONFIG_LOG_CUSTOM_BITS_DEFAULT(__x86_64_delta_agc7648sv1_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB + { __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB), __x86_64_delta_agc7648sv1_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB) }, +#else +{ X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_STDLIB(__x86_64_delta_agc7648sv1_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS + { __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS), __x86_64_delta_agc7648sv1_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS) }, +#else +{ X86_64_DELTA_AGC7648SV1_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS(__x86_64_delta_agc7648sv1_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_UCLI + { __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_UCLI), __x86_64_delta_agc7648sv1_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_UCLI) }, +#else +{ X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_UCLI(__x86_64_delta_agc7648sv1_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION + { __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION), __x86_64_delta_agc7648sv1_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION) }, +#else +{ X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION(__x86_64_delta_agc7648sv1_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_DELTA_AGC7648SV1_CONFIG_SFP_COUNT + { __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648SV1_CONFIG_SFP_COUNT), __x86_64_delta_agc7648sv1_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648SV1_CONFIG_SFP_COUNT) }, +#else +{ X86_64_DELTA_AGC7648SV1_CONFIG_SFP_COUNT(__x86_64_delta_agc7648sv1_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_DELTA_AGC7648SV1_CONFIG_FAN_RPM_MAX + { __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648SV1_CONFIG_FAN_RPM_MAX), __x86_64_delta_agc7648sv1_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648SV1_CONFIG_FAN_RPM_MAX) }, +#else +{ X86_64_DELTA_AGC7648SV1_CONFIG_FAN_RPM_MAX(__x86_64_delta_agc7648sv1_config_STRINGIFY_NAME), "__undefined__" }, +#endif + { NULL, NULL } +}; +#undef __x86_64_delta_agc7648sv1_config_STRINGIFY_VALUE +#undef __x86_64_delta_agc7648sv1_config_STRINGIFY_NAME + +const char* +x86_64_delta_agc7648sv1_config_lookup(const char* setting) +{ + int i; + for(i = 0; x86_64_delta_agc7648sv1_config_settings[i].name; i++) { + if(!strcmp(x86_64_delta_agc7648sv1_config_settings[i].name, setting)) { + return x86_64_delta_agc7648sv1_config_settings[i].value; + } + } + return NULL; +} + +int +x86_64_delta_agc7648sv1_config_show(struct aim_pvs_s* pvs) +{ + int i; + for(i = 0; x86_64_delta_agc7648sv1_config_settings[i].name; i++) { + aim_printf(pvs, "%s = %s\n", x86_64_delta_agc7648sv1_config_settings[i].name, x86_64_delta_agc7648sv1_config_settings[i].value); + } + return i; +} + +/* */ + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_enums.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_enums.c new file mode 100644 index 00000000..5ce2fa14 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_enums.c @@ -0,0 +1,10 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +/* <--auto.start.enum(ALL).source> */ +/* */ + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_int.h b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_int.h new file mode 100644 index 00000000..6b86597d --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_int.h @@ -0,0 +1,12 @@ +/**************************************************************************//** + * + * x86_64_delta_agc7648sv1 Internal Header + * + *****************************************************************************/ +#ifndef __x86_64_delta_agc7648sv1_INT_H__ +#define __x86_64_delta_agc7648sv1_INT_H__ + +#include + + +#endif /* __x86_64_delta_agc7648sv1_INT_H__ */ diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_log.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_log.c new file mode 100755 index 00000000..59daed67 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_log.c @@ -0,0 +1,18 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +#include "x86_64_delta_agc7648sv1_log.h" +/* + * x86_64_delta_agc7648sv1 log struct. + */ +AIM_LOG_STRUCT_DEFINE( + X86_64_DELTA_AGC7648SV1_CONFIG_LOG_OPTIONS_DEFAULT, + X86_64_DELTA_AGC7648SV1_CONFIG_LOG_BITS_DEFAULT, + NULL, /* Custom log map */ + X86_64_DELTA_AGC7648SV1_CONFIG_LOG_CUSTOM_BITS_DEFAULT + ); + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_log.h b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_log.h new file mode 100644 index 00000000..66de4fcd --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_log.h @@ -0,0 +1,12 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#ifndef __x86_64_delta_agc7648sv1_LOG_H__ +#define __x86_64_delta_agc7648sv1_LOG_H__ + +#define AIM_LOG_MODULE_NAME x86_64_delta_agc7648sv1 +#include + +#endif /* __x86_64_delta_agc7648sv1_LOG_H__ */ diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_module.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_module.c new file mode 100644 index 00000000..85efe84f --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_module.c @@ -0,0 +1,24 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +#include "x86_64_delta_agc7648sv1_log.h" + +static int +datatypes_init__(void) +{ +#define x86_64_delta_agc7648sv1_ENUMERATION_ENTRY(_enum_name, _desc) AIM_DATATYPE_MAP_REGISTER(_enum_name, _enum_name##_map, _desc, AIM_LOG_INTERNAL); +#include + return 0; +} + +void __x86_64_delta_agc7648sv1_module_init__(void) +{ + AIM_LOG_STRUCT_REGISTER(); + datatypes_init__(); +} + +int __onlp_platform_version__ = 1; diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_ucli.c b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_ucli.c new file mode 100755 index 00000000..8746e060 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/onlp/builds/src/module/src/x86_64_delta_agc7648sv1_ucli.c @@ -0,0 +1,50 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +#if X86_64_DELTA_AGC7648SV1_CONFIG_INCLUDE_UCLI == 1 + +#include +#include +#include + +static ucli_status_t +x86_64_delta_agc7648sv1_ucli_ucli__config__(ucli_context_t* uc) +{ + UCLI_HANDLER_MACRO_MODULE_CONFIG(x86_64_delta_agc7648sv1) +} + +/* */ +/* */ + +static ucli_module_t +x86_64_delta_agc7648sv1_ucli_module__ = + { + "x86_64_delta_agc7648sv1_ucli", + NULL, + x86_64_delta_agc7648sv1_ucli_ucli_handlers__, + NULL, + NULL, + }; + +ucli_node_t* +x86_64_delta_agc7648sv1_ucli_node_create(void) +{ + ucli_node_t* n; + ucli_module_init(&x86_64_delta_agc7648sv1_ucli_module__); + n = ucli_node_create("x86_64_delta_agc7648sv1", NULL, &x86_64_delta_agc7648sv1_ucli_module__); + ucli_node_subnode_add(n, ucli_module_log_node_create("x86_64_delta_agc7648sv1")); + return n; +} + +#else +void* +x86_64_delta_agc7648sv1_ucli_node_create(void) +{ + return NULL; +} +#endif + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/Makefile b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/Makefile b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/PKG.yml b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/PKG.yml new file mode 100644 index 00000000..ffa172f2 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/PKG.yml @@ -0,0 +1,2 @@ +!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=amd64 VENDOR=delta BASENAME=x86-64-delta-agc7648sv1 REVISION=r0 + diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/src/lib/x86-64-delta-agc7648sv1-r0.yml b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/src/lib/x86-64-delta-agc7648sv1-r0.yml new file mode 100755 index 00000000..437129a5 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/src/lib/x86-64-delta-agc7648sv1-r0.yml @@ -0,0 +1,30 @@ +--- + +###################################################################### +# +# platform-config for AGC7648SV1 +# +###################################################################### + +x86-64-delta-agc7648sv1-r0: + grub: + + serial: >- + --port=0x3f8 + --speed=115200 + --word=8 + --parity=no + --stop=1 + + kernel: + <<: *kernel-4-9 + + args: >- + nopat + console=ttyS0,115200n8 + + ##network + ## interfaces: + ## ma1: + ## name: ~ + ## syspath: pci0000:00/0000:00:14.0 diff --git a/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/src/python/x86_64_delta_agc7648sv1_r0/__init__.py b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/src/python/x86_64_delta_agc7648sv1_r0/__init__.py new file mode 100755 index 00000000..2c1bc662 --- /dev/null +++ b/packages/platforms/delta/x86-64/x86-64-delta-agc7648sv1/platform-config/r0/src/python/x86_64_delta_agc7648sv1_r0/__init__.py @@ -0,0 +1,32 @@ +from onl.platform.base import * +from onl.platform.delta import * + +class OnlPlatform_x86_64_delta_agc7648sv1_r0(OnlPlatformDelta, + OnlPlatformPortConfig_32x100): + PLATFORM='x86-64-delta-agc7648sv1-r0' + MODEL="AGC7648SV1" + SYS_OBJECT_ID=".7648.1" + + + def baseconfig(self): + #Remove and rescan bus + os.system("echo 1 >/sys/bus/i2c/devices/i2c-0/firmware_node/physical_node/remove") + os.system("echo 1 > /sys/bus/pci/rescan") + + #insert tmp401(tmp431/tmp432) module + self.insmod('tmp401') + + #insert platform module + self.insmod('delta_agc7648sv1_platform') + + #Insert psu module + self.insmod('dni_agc7648sv1_psu') + + #insert fan module + self.insmod('dni_emc2305') + + #insert qsfp mosule + self.insmod('optoe') + + return True +