From 6a8a0130a7ec5e7d21e0dc72c1f443fea314de1c Mon Sep 17 00:00:00 2001 From: hans-tseng Date: Sat, 14 Apr 2018 13:49:35 +0800 Subject: [PATCH] [devices]: modified and fixed delta ag9064 modules (#28) 2. enable build ag9064 Signed-off-by: neal tai --- .../ag9064/modules/Makefile | 3 +- .../ag9064/modules/delta_ag9064_common.h | 1132 +++---- .../ag9064/modules/delta_ag9064_cpld.c | 1722 +++++----- .../ag9064/modules/delta_ag9064_platform.c | 2993 +++++++---------- .../ag9064/modules/delta_ag9064_swpld.c | 1243 +++---- 5 files changed, 3230 insertions(+), 3863 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/Makefile b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/Makefile index 124e0ff5b820..5642e82fa058 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/Makefile @@ -2,5 +2,4 @@ obj-m += delta_ag9064_platform.o obj-m += delta_ag9064_cpld.o obj-m += delta_ag9064_swpld.o obj-m += i2c-mei.o -i2c-mei-objs := i2c-mei_io.o i2c-mei_main.o i2c-mei_rw.o - +i2c-mei-objs := i2c-mei_io.o i2c-mei_main.o i2c-mei_rw.o \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_common.h b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_common.h index f30081a8829e..5be2eb91fedf 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_common.h +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_common.h @@ -1,567 +1,567 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IPMI_MAX_INTF (4) -#define DELTA_NETFN 0x38 -#define BMC_BUS_5 0x04 -#define CMD_SETDATA 0x03 -#define CMD_GETDATA 0x02 - -#define CPUPLD_ADDR 0x31 -#define SWPLD1_ADDR 0x35 -#define SWPLD2_ADDR 0x34 -#define SWPLD3_ADDR 0x33 -#define SWPLD4_ADDR 0x32 -#define QSFP_PORT_MUX_REG 0x13 - -#define DEFAULT_NUM 1 -#define BUS9_DEV_NUM 64 -#define BUS9_BASE_NUM 20 - -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 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 -}; - -enum{ - BUS0 = 0, - BUS1, - BUS2, - BUS3, - BUS4, - BUS5, - BUS6, - BUS7, - BUS8, - BUS9, - BUS10, - BUS11, - BUS12, - BUS13, - BUS14, -}; - -static struct cpld_attribute_data { - uint8_t bus; - uint8_t addr; - uint8_t reg; - uint8_t mask; - char note[200]; -}; - - -enum cpld_type { - system_cpld, - swpld1, - swpld2, - swpld3, - swpld4, -}; - -struct cpld_platform_data { - int reg_addr; - struct i2c_client *client; -}; - -static struct cpld_platform_data ag9064_cpld_platform_data[] = { - [system_cpld] = { - .reg_addr = CPUPLD_ADDR, - }, -}; - -static struct cpld_platform_data ag9064_swpld1_platform_data[] = { - [swpld1] = { - .reg_addr = SWPLD1_ADDR, - }, -}; - -static struct cpld_platform_data ag9064_swpld2_platform_data[] = { - [swpld2] = { - .reg_addr = SWPLD2_ADDR, - }, -}; - -static struct cpld_platform_data ag9064_swpld3_platform_data[] = { - [swpld3] = { - .reg_addr = SWPLD3_ADDR, - }, -}; - -static struct cpld_platform_data ag9064_swpld4_platform_data[] = { - [swpld4] = { - .reg_addr = SWPLD4_ADDR, - }, -}; - -enum cpld_attributes { - CPLD_REG_ADDR, - CPLD_REG_VALUE, - SWPLD1_REG_ADDR, - SWPLD1_REG_VALUE, - SWPLD2_REG_ADDR, - SWPLD2_REG_VALUE, - SWPLD3_REG_ADDR, - SWPLD3_REG_VALUE, - SWPLD4_REG_ADDR, - SWPLD4_REG_VALUE, - //CPLD - CPLD_VER, - CPU_BOARD_VER, - CPU_ID, - MB_ID, - MB_VER, - CPU0_PWR_OK, - PSU_OVER_TEMP, - PWR_RAIL_OVER_TEMP, - CPU_DISOMIC_OVER_TEMP, - DDR_OVER_TEMP, - CPLD_PWR_ON_RST, - CPLD_HARD_RST, - CPLD_RST, - MB_PWR, - MB_RST, - PSU_FAN_INT, - OP_MODULE_INT, -//SWPLD1 - SWPLD1_MAJOR_VER, - SWPLD1_MINOR_VER, - SWPLD1_SCRTCH_REG, - PSU1_PWR_OK, - PSU1_INT, - PSU2_PWR_OK, - PSU2_INT, - SYNCE_INT, - SYNCE_RST, - SYNCE_EEPROM_WP, - PSU1_GREEN_LED, - PSU1_RED_LED, - PSU2_GREEN_LED, - PSU2_RED_LED, - PSU_LED_MODE, -//SWPLD2 - SWPLD2_MAJOR_VER, - SWPLD2_MINOR_VER, - SWPLD2_SCRTCH_REG, - FAN_LED, - SYS_LED, - FAN_MOD1_LED, - FAN_MOD2_LED, - FAN_MOD3_LED, - FAN_MOD4_LED, -//SWPLD3 - SWPLD3_MAJOR_VER, - SWPLD3_MINOR_VER, - SWPLD3_SCRTCH_REG, - SB_VER, - PLATFORM_TYPE, -//SWPLD4 - SWPLD4_MAJOR_VER, - SWPLD4_MINOR_VER, - SWPLD4_SCRTCH_REG, - BMC_RST, - CPLD_LPC_RST, - CPLD_SW_RST, - MB_CPLD_RST, - BCM56970_RST, - CPLD_UPGRADE_RST, - MB_RST_CPLD, - CPU_RST_MB_OOB, - GPIO_PHY_RST, - PSU_FAN_EVENT, - CPU_THERMAL_INT, - FAN_INT, - CPLD_SPI_WP, - RJ45_CONSOLE_SEL, - SYSTEM_INT, - CPLD_MB_RST_DONE, - MB_PWR_OK, - FAN_EEPROM_WP, -}; - -static struct cpld_attribute_data attribute_data[] = { - [CPLD_REG_ADDR] = { - }, - [CPLD_REG_VALUE] = { - }, - [SWPLD1_REG_ADDR] = { - }, - [SWPLD1_REG_VALUE] = { - }, - [SWPLD2_REG_ADDR] = { - }, - [SWPLD2_REG_VALUE] = { - }, - [SWPLD3_REG_ADDR] = { - }, - [SWPLD3_REG_VALUE] = { - }, - [SWPLD4_REG_ADDR] = { - }, - [SWPLD4_REG_VALUE] = { - }, -//CPLD - [CPLD_VER] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x01, .mask = 0xFF, - .note = "CPLD Version, controlled by CPLD editor" - }, - [CPU_BOARD_VER] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x02, .mask = 0xF0, - .note = "“0x0”: proto A1\n“0x1”: proto A2\n“0x2”: PR (Production)" - }, - [CPU_ID] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x02, .mask = 0x0F, - .note = "“0x0”: C2558 ECC\n“0x1”: Rangeley ECC\n“0x2”: BROADWELL-DE ECC" - }, - [MB_ID] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x03, .mask = 0xFF, - .note = "“0x00”: proto A1\n“0x01”: proto A2\n“0x02”: PR (Production)" - }, - [MB_VER] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x04, .mask = 0x0F, - .note = "“0x0”: proto-A\n“0x1”: proto-B" - }, - [CPU0_PWR_OK] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x08, .mask = 1 << 3, - .note = "“1” =Power rail is good\n“0” = Power rail is failed" - }, - [PSU_OVER_TEMP] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x0b, .mask = 1 << 4, - .note = "“1” = Not over temperature\n“0” = Over temperature" - }, - [PWR_RAIL_OVER_TEMP] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x0b, .mask = 1 << 3, - .note = "“1” = Not over temperature\n“0” = Over temperature" - }, - [CPU_DISOMIC_OVER_TEMP] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x0b, .mask = 1 << 1, - .note = "“1” = Not over temperature\n“0” = Over temperature" - }, - [DDR_OVER_TEMP] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x0b, .mask = 1 << 0, - .note = "“1” = Not over temperature\n“0” = Over temperature" - }, - [CPLD_PWR_ON_RST] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x11, .mask = 1 << 4, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [CPLD_HARD_RST] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x11, .mask = 1 << 2, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [CPLD_RST] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x11, .mask = 1 << 0, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [MB_PWR] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x12, .mask = 1 << 2, - .note = "“0” = Power rail is failed\n“1” =Power rail is good" - }, - [MB_RST] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x12, .mask = 1 << 0, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [PSU_FAN_INT] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x15, .mask = 1 << 1, - .note = "“0” = Interrupt occurs\n“1” = Interrupt doesn't occur" - }, - [OP_MODULE_INT] = { - .bus = BUS0, .addr = CPUPLD_ADDR, - .reg = 0x15, .mask = 1 << 0, - .note = "“0” = Interrupt occurs\n“1” = Interrupt doesn't occur" - }, -//SWPLD1 - [SWPLD1_MAJOR_VER] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x00, .mask = 0xF0, - .note = "CPLD Major Version, controlled by CPLD editor." - }, - [SWPLD1_MINOR_VER] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x00, .mask = 0x0F, - .note = "CPLD Minor Version, controlled by CPLD editor." - }, - [SWPLD1_SCRTCH_REG] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x01, .mask = 0xFF, - .note = "CPLD read/write test register, to provide a way to test CPLD access." - }, - [PSU1_PWR_OK] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x02, .mask = 1 << 6, - .note = "‘0’ = Power rail is good\n‘1’ = Power rail is failed" - }, - [PSU1_INT] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x02, .mask = 1 << 5, - .note = "‘0’ = Interrupt doesn’t occur\n‘1’ = Interrupt occurs" - }, - [PSU2_PWR_OK] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x02, .mask = 1 << 2, - .note = "‘0’ = Power rail is good\n‘1’ = Power rail is failed" - }, - [PSU2_INT] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x02, .mask = 1 << 1, - .note = "‘0’ = Interrupt doesn’t occur\n‘1’ = Interrupt occurs" - }, - [SYNCE_INT] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x12, .mask = 1 << 7, - .note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" - }, - [SYNCE_RST] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x12, .mask = 1 << 6, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [SYNCE_EEPROM_WP] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x12, .mask = 1 << 5, - .note = "“1” = enables the lock-down mechanism.\n“0” = overrides the lock-down function enabling blocks to be erased or programmed using software commands." - }, - [PSU1_GREEN_LED] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x13, .mask = 1 << 7, - .note = "“0”: Solid Green – Power Supply 1 is supplied to the switch & operating normally\n“1”: OFF" - }, - [PSU1_RED_LED] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x13, .mask = 1 << 6, - .note = "“0”: Solid Red – Power Supply 1 is supplied to the switch & operating normally\n“1”: OFF" - }, - [PSU2_GREEN_LED] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x13, .mask = 1 << 5, - .note = "“0”: Solid Green – Power Supply 2 is supplied to the switch & operating normally\n“1”: OFF" - }, - [PSU2_RED_LED] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x13, .mask = 1 << 4, - .note = "“0”: Solid Red – Power Supply 1=2 is supplied to the switch & operating normally\n“1”: OFF" - }, - [PSU_LED_MODE] = { - .bus = BUS0, .addr = SWPLD1_ADDR, - .reg = 0x13, .mask = 1 << 0, - .note = "“0”: PSU LED can be changed manually\n“1”: PSU LED can’t be changed manually" - }, -//SWPLD2 - [SWPLD2_MAJOR_VER] = { - .bus = BUS0, .addr = SWPLD2_ADDR, - .reg = 0x00, .mask =0xF0 , - .note = "CPLD Major Version, controlled by CPLD editor." - }, - [SWPLD2_MINOR_VER] = { - .bus = BUS0, .addr = SWPLD2_ADDR, - .reg = 0x00, .mask = 0x0F, - .note = "CPLD Minor Version, controlled by CPLD editor." - }, - [SWPLD2_SCRTCH_REG] = { - .bus = BUS0, .addr = SWPLD2_ADDR, - .reg = 0x01, .mask = 0xFF, - .note = "CPLD read/write test register, to provide a way to test CPLD access." - }, - [FAN_LED] = { - .bus = BUS0, .addr = SWPLD2_ADDR, - .reg = 0x02, .mask = 0xC0, - .note = "“00’/”11”: OFF\n“01”: Solid Green – FANs are operating normally\n“10”: Solid Amber – FANs are Error" - }, - [SYS_LED] = { - .bus = BUS0, .addr = SWPLD2_ADDR, - .reg = 0x02, .mask = 0x30, - .note = "‘00’: Off\n‘01’: Solid Green – Normal operation\n‘10’: Blinking Green – Booting Progress\n‘11’: Solid Red – System Fail" - }, - [FAN_MOD1_LED] = { - .bus = BUS0, .addr = SWPLD2_ADDR, - .reg = 0x1b, .mask = 1 << 7, - .note = "‘0’ = Amber\n‘1’ = Green" - }, - [FAN_MOD2_LED] = { - .bus = BUS0, .addr = SWPLD2_ADDR, - .reg = 0x1b, .mask = 1 << 6, - .note = "‘0’ = Amber\n‘1’ = Green" - }, - [FAN_MOD3_LED] = { - .bus = BUS0, .addr = SWPLD2_ADDR, - .reg = 0x1b, .mask = 1 << 5, - .note = "‘0’ = Amber\n‘1’ = Green" - }, - [FAN_MOD4_LED] = { - .bus = BUS0, .addr = SWPLD2_ADDR, - .reg = 0x1b, .mask = 1 << 4, - .note = "‘0’ = Amber\n‘1’ = Green" - }, -//SWPLD3 - [SWPLD3_MAJOR_VER] = { - .bus = BUS0, .addr = SWPLD3_ADDR, - .reg = 0x00, .mask = 0xF0, - .note = "CPLD Major Version, controlled by CPLD editor." - }, - [SWPLD3_MINOR_VER] = { - .bus = BUS0, .addr = SWPLD3_ADDR, - .reg = 0x00, .mask = 0x0F, - .note = "CPLD Minor Version, controlled by CPLD editor." - }, - [SWPLD3_SCRTCH_REG] = { - .bus = BUS0, .addr = SWPLD3_ADDR, - .reg = 0x01, .mask = 0xFF, - .note = "CPLD read/write test register, to provide a way to test CPLD access." - }, - [SB_VER] = { - .bus = BUS0, .addr = SWPLD3_ADDR, - .reg = 0x02, .mask = 0xF0, - .note = "“0x0”: proto-A\n“0x1”: proto-B" - }, - [PLATFORM_TYPE] = { - .bus = BUS0, .addr = SWPLD3_ADDR, - .reg = 0x02, .mask = 0x0F, - .note = "“0x0”: 64X100G_2U\n“0x1”~”0xF” Reserved" - }, -//SWPLD4 - [SWPLD4_MAJOR_VER] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x00, .mask = 0xF0, - .note = "CPLD Major Version, controlled by CPLD editor." - }, - [SWPLD4_MINOR_VER] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x00, .mask = 0x0F, - .note = "CPLD Minor Version, controlled by CPLD editor." - }, - [SWPLD4_SCRTCH_REG] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x01, .mask = 0xFF, - .note = "CPLD read/write test register, to provide a way to test CPLD access." - }, - [BMC_RST] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x02, .mask = 1 << 6, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [CPLD_LPC_RST] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x02, .mask = 1 << 5, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [CPLD_SW_RST] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x02, .mask = 1 << 3, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [MB_CPLD_RST] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x02, .mask = 1 << 2, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [BCM56970_RST] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x02, .mask = 1 << 1, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [CPLD_UPGRADE_RST] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x03, .mask = 1 << 7, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [MB_RST_CPLD] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x03, .mask = 1 << 6, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [CPU_RST_MB_OOB] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x03, .mask = 1 << 5, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [GPIO_PHY_RST] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x03, .mask = 1 << 4, - .note = "“0” = Reset\n“1” = Normal operation" - }, - [PSU_FAN_EVENT] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x04, .mask = 1 << 4, - .note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" - }, - [CPU_THERMAL_INT] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x04, .mask = 1 << 1, - .note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" - }, - [FAN_INT] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x04, .mask = 1 << 0, - .note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" - }, - [CPLD_SPI_WP] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x06, .mask = 1 << 3, - .note = "“0” = SPI write operation is disabled\n“1” = SPI write operation is enabled" - }, - [RJ45_CONSOLE_SEL] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x06, .mask = 1 << 2, - .note = "“0” = Use BCM UART\n“1” = Use CPU UART" - }, - [SYSTEM_INT] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x07, .mask = 1 << 2, - .note = "“0” = Interrupt is asserted\n“1” = Interrupt is deasserted" - }, - [CPLD_MB_RST_DONE] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x07, .mask = 1 << 1, - .note = "“0” = Is done\n“1” = Is not done" - }, - [MB_PWR_OK] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x07, .mask = 1 << 0, - .note = "‘0’ = Power is failed\n‘1’ = Power is good" - }, - [FAN_EEPROM_WP] = { - .bus = BUS0, .addr = SWPLD4_ADDR, - .reg = 0x15, .mask = 1 << 2, - .note = "“1” = enables the lock-down mechanism.\n“0” = overrides the lock-down function enabling blocks to be erased or programmed using software commands." - }, +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IPMI_MAX_INTF (4) +#define DELTA_NETFN 0x38 +#define BMC_BUS_5 0x04 +#define CMD_SETDATA 0x03 +#define CMD_GETDATA 0x02 + +#define CPUPLD_ADDR 0x31 +#define SWPLD1_ADDR 0x35 +#define SWPLD2_ADDR 0x34 +#define SWPLD3_ADDR 0x33 +#define SWPLD4_ADDR 0x32 +#define QSFP_PORT_MUX_REG 0x13 + +#define DEFAULT_NUM 1 +#define BUS9_DEV_NUM 64 +#define BUS9_BASE_NUM 20 + +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 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 +}; + +enum{ + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, + BUS8, + BUS9, + BUS10, + BUS11, + BUS12, + BUS13, + BUS14, +}; + +static struct cpld_attribute_data { + uint8_t bus; + uint8_t addr; + uint8_t reg; + uint8_t mask; + char note[200]; +}; + + +enum cpld_type { + system_cpld, + swpld1, + swpld2, + swpld3, + swpld4, +}; + +struct cpld_platform_data { + int reg_addr; + struct i2c_client *client; +}; + +static struct cpld_platform_data ag9064_cpld_platform_data[] = { + [system_cpld] = { + .reg_addr = CPUPLD_ADDR, + }, +}; + +static struct cpld_platform_data ag9064_swpld1_platform_data[] = { + [swpld1] = { + .reg_addr = SWPLD1_ADDR, + }, +}; + +static struct cpld_platform_data ag9064_swpld2_platform_data[] = { + [swpld2] = { + .reg_addr = SWPLD2_ADDR, + }, +}; + +static struct cpld_platform_data ag9064_swpld3_platform_data[] = { + [swpld3] = { + .reg_addr = SWPLD3_ADDR, + }, +}; + +static struct cpld_platform_data ag9064_swpld4_platform_data[] = { + [swpld4] = { + .reg_addr = SWPLD4_ADDR, + }, +}; + +enum cpld_attributes { + CPLD_REG_ADDR, + CPLD_REG_VALUE, + SWPLD1_REG_ADDR, + SWPLD1_REG_VALUE, + SWPLD2_REG_ADDR, + SWPLD2_REG_VALUE, + SWPLD3_REG_ADDR, + SWPLD3_REG_VALUE, + SWPLD4_REG_ADDR, + SWPLD4_REG_VALUE, + //CPLD + CPLD_VER, + CPU_BOARD_VER, + CPU_ID, + MB_ID, + MB_VER, + CPU0_PWR_OK, + PSU_OVER_TEMP, + PWR_RAIL_OVER_TEMP, + CPU_DISOMIC_OVER_TEMP, + DDR_OVER_TEMP, + CPLD_PWR_ON_RST, + CPLD_HARD_RST, + CPLD_RST, + MB_PWR, + MB_RST, + PSU_FAN_INT, + OP_MODULE_INT, +//SWPLD1 + SWPLD1_MAJOR_VER, + SWPLD1_MINOR_VER, + SWPLD1_SCRTCH_REG, + PSU1_PWR_OK, + PSU1_INT, + PSU2_PWR_OK, + PSU2_INT, + SYNCE_INT, + SYNCE_RST, + SYNCE_EEPROM_WP, + PSU1_GREEN_LED, + PSU1_RED_LED, + PSU2_GREEN_LED, + PSU2_RED_LED, + PSU_LED_MODE, +//SWPLD2 + SWPLD2_MAJOR_VER, + SWPLD2_MINOR_VER, + SWPLD2_SCRTCH_REG, + FAN_LED, + SYS_LED, + FAN_MOD1_LED, + FAN_MOD2_LED, + FAN_MOD3_LED, + FAN_MOD4_LED, +//SWPLD3 + SWPLD3_MAJOR_VER, + SWPLD3_MINOR_VER, + SWPLD3_SCRTCH_REG, + SB_VER, + PLATFORM_TYPE, +//SWPLD4 + SWPLD4_MAJOR_VER, + SWPLD4_MINOR_VER, + SWPLD4_SCRTCH_REG, + BMC_RST, + CPLD_LPC_RST, + CPLD_SW_RST, + MB_CPLD_RST, + BCM56970_RST, + CPLD_UPGRADE_RST, + MB_RST_CPLD, + CPU_RST_MB_OOB, + GPIO_PHY_RST, + PSU_FAN_EVENT, + CPU_THERMAL_INT, + FAN_INT, + CPLD_SPI_WP, + RJ45_CONSOLE_SEL, + SYSTEM_INT, + CPLD_MB_RST_DONE, + MB_PWR_OK, + FAN_EEPROM_WP, +}; + +static struct cpld_attribute_data attribute_data[] = { + [CPLD_REG_ADDR] = { + }, + [CPLD_REG_VALUE] = { + }, + [SWPLD1_REG_ADDR] = { + }, + [SWPLD1_REG_VALUE] = { + }, + [SWPLD2_REG_ADDR] = { + }, + [SWPLD2_REG_VALUE] = { + }, + [SWPLD3_REG_ADDR] = { + }, + [SWPLD3_REG_VALUE] = { + }, + [SWPLD4_REG_ADDR] = { + }, + [SWPLD4_REG_VALUE] = { + }, +//CPLD + [CPLD_VER] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x01, .mask = 0xFF, + .note = "CPLD Version, controlled by CPLD editor" + }, + [CPU_BOARD_VER] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x02, .mask = 0xF0, + .note = "“0x0”: proto A1\n“0x1”: proto A2\n“0x2”: PR (Production)" + }, + [CPU_ID] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x02, .mask = 0x0F, + .note = "“0x0”: C2558 ECC\n“0x1”: Rangeley ECC\n“0x2”: BROADWELL-DE ECC" + }, + [MB_ID] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x03, .mask = 0xFF, + .note = "“0x00”: proto A1\n“0x01”: proto A2\n“0x02”: PR (Production)" + }, + [MB_VER] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x04, .mask = 0x0F, + .note = "“0x0”: proto-A\n“0x1”: proto-B" + }, + [CPU0_PWR_OK] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x08, .mask = 1 << 3, + .note = "“1” =Power rail is good\n“0” = Power rail is failed" + }, + [PSU_OVER_TEMP] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x0b, .mask = 1 << 4, + .note = "“1” = Not over temperature\n“0” = Over temperature" + }, + [PWR_RAIL_OVER_TEMP] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x0b, .mask = 1 << 3, + .note = "“1” = Not over temperature\n“0” = Over temperature" + }, + [CPU_DISOMIC_OVER_TEMP] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x0b, .mask = 1 << 1, + .note = "“1” = Not over temperature\n“0” = Over temperature" + }, + [DDR_OVER_TEMP] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x0b, .mask = 1 << 0, + .note = "“1” = Not over temperature\n“0” = Over temperature" + }, + [CPLD_PWR_ON_RST] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x11, .mask = 1 << 4, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [CPLD_HARD_RST] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x11, .mask = 1 << 2, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [CPLD_RST] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x11, .mask = 1 << 0, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [MB_PWR] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x12, .mask = 1 << 2, + .note = "“0” = Power rail is failed\n“1” =Power rail is good" + }, + [MB_RST] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x12, .mask = 1 << 0, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [PSU_FAN_INT] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x15, .mask = 1 << 1, + .note = "“0” = Interrupt occurs\n“1” = Interrupt doesn't occur" + }, + [OP_MODULE_INT] = { + .bus = BUS0, .addr = CPUPLD_ADDR, + .reg = 0x15, .mask = 1 << 0, + .note = "“0” = Interrupt occurs\n“1” = Interrupt doesn't occur" + }, +//SWPLD1 + [SWPLD1_MAJOR_VER] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x00, .mask = 0xF0, + .note = "CPLD Major Version, controlled by CPLD editor." + }, + [SWPLD1_MINOR_VER] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x00, .mask = 0x0F, + .note = "CPLD Minor Version, controlled by CPLD editor." + }, + [SWPLD1_SCRTCH_REG] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x01, .mask = 0xFF, + .note = "CPLD read/write test register, to provide a way to test CPLD access." + }, + [PSU1_PWR_OK] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x02, .mask = 1 << 6, + .note = "‘0’ = Power rail is good\n‘1’ = Power rail is failed" + }, + [PSU1_INT] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x02, .mask = 1 << 5, + .note = "‘0’ = Interrupt doesn’t occur\n‘1’ = Interrupt occurs" + }, + [PSU2_PWR_OK] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x02, .mask = 1 << 2, + .note = "‘0’ = Power rail is good\n‘1’ = Power rail is failed" + }, + [PSU2_INT] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x02, .mask = 1 << 1, + .note = "‘0’ = Interrupt doesn’t occur\n‘1’ = Interrupt occurs" + }, + [SYNCE_INT] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x12, .mask = 1 << 7, + .note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" + }, + [SYNCE_RST] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x12, .mask = 1 << 6, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [SYNCE_EEPROM_WP] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x12, .mask = 1 << 5, + .note = "“1” = enables the lock-down mechanism.\n“0” = overrides the lock-down function enabling blocks to be erased or programmed using software commands." + }, + [PSU1_GREEN_LED] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x13, .mask = 1 << 7, + .note = "“0”: Solid Green – Power Supply 1 is supplied to the switch & operating normally\n“1”: OFF" + }, + [PSU1_RED_LED] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x13, .mask = 1 << 6, + .note = "“0”: Solid Red – Power Supply 1 is supplied to the switch & operating normally\n“1”: OFF" + }, + [PSU2_GREEN_LED] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x13, .mask = 1 << 5, + .note = "“0”: Solid Green – Power Supply 2 is supplied to the switch & operating normally\n“1”: OFF" + }, + [PSU2_RED_LED] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x13, .mask = 1 << 4, + .note = "“0”: Solid Red – Power Supply 1=2 is supplied to the switch & operating normally\n“1”: OFF" + }, + [PSU_LED_MODE] = { + .bus = BUS0, .addr = SWPLD1_ADDR, + .reg = 0x13, .mask = 1 << 0, + .note = "“0”: PSU LED can be changed manually\n“1”: PSU LED can’t be changed manually" + }, +//SWPLD2 + [SWPLD2_MAJOR_VER] = { + .bus = BUS0, .addr = SWPLD2_ADDR, + .reg = 0x00, .mask =0xF0 , + .note = "CPLD Major Version, controlled by CPLD editor." + }, + [SWPLD2_MINOR_VER] = { + .bus = BUS0, .addr = SWPLD2_ADDR, + .reg = 0x00, .mask = 0x0F, + .note = "CPLD Minor Version, controlled by CPLD editor." + }, + [SWPLD2_SCRTCH_REG] = { + .bus = BUS0, .addr = SWPLD2_ADDR, + .reg = 0x01, .mask = 0xFF, + .note = "CPLD read/write test register, to provide a way to test CPLD access." + }, + [FAN_LED] = { + .bus = BUS0, .addr = SWPLD2_ADDR, + .reg = 0x02, .mask = 0xC0, + .note = "“00’/”11”: OFF\n“01”: Solid Green – FANs are operating normally\n“10”: Solid Amber – FANs are Error" + }, + [SYS_LED] = { + .bus = BUS0, .addr = SWPLD2_ADDR, + .reg = 0x02, .mask = 0x30, + .note = "‘00’: Off\n‘01’: Solid Green – Normal operation\n‘10’: Blinking Green – Booting Progress\n‘11’: Solid Red – System Fail" + }, + [FAN_MOD1_LED] = { + .bus = BUS0, .addr = SWPLD2_ADDR, + .reg = 0x1b, .mask = 1 << 7, + .note = "‘0’ = Amber\n‘1’ = Green" + }, + [FAN_MOD2_LED] = { + .bus = BUS0, .addr = SWPLD2_ADDR, + .reg = 0x1b, .mask = 1 << 6, + .note = "‘0’ = Amber\n‘1’ = Green" + }, + [FAN_MOD3_LED] = { + .bus = BUS0, .addr = SWPLD2_ADDR, + .reg = 0x1b, .mask = 1 << 5, + .note = "‘0’ = Amber\n‘1’ = Green" + }, + [FAN_MOD4_LED] = { + .bus = BUS0, .addr = SWPLD2_ADDR, + .reg = 0x1b, .mask = 1 << 4, + .note = "‘0’ = Amber\n‘1’ = Green" + }, +//SWPLD3 + [SWPLD3_MAJOR_VER] = { + .bus = BUS0, .addr = SWPLD3_ADDR, + .reg = 0x00, .mask = 0xF0, + .note = "CPLD Major Version, controlled by CPLD editor." + }, + [SWPLD3_MINOR_VER] = { + .bus = BUS0, .addr = SWPLD3_ADDR, + .reg = 0x00, .mask = 0x0F, + .note = "CPLD Minor Version, controlled by CPLD editor." + }, + [SWPLD3_SCRTCH_REG] = { + .bus = BUS0, .addr = SWPLD3_ADDR, + .reg = 0x01, .mask = 0xFF, + .note = "CPLD read/write test register, to provide a way to test CPLD access." + }, + [SB_VER] = { + .bus = BUS0, .addr = SWPLD3_ADDR, + .reg = 0x02, .mask = 0xF0, + .note = "“0x0”: proto-A\n“0x1”: proto-B" + }, + [PLATFORM_TYPE] = { + .bus = BUS0, .addr = SWPLD3_ADDR, + .reg = 0x02, .mask = 0x0F, + .note = "“0x0”: 64X100G_2U\n“0x1”~”0xF” Reserved" + }, +//SWPLD4 + [SWPLD4_MAJOR_VER] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x00, .mask = 0xF0, + .note = "CPLD Major Version, controlled by CPLD editor." + }, + [SWPLD4_MINOR_VER] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x00, .mask = 0x0F, + .note = "CPLD Minor Version, controlled by CPLD editor." + }, + [SWPLD4_SCRTCH_REG] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x01, .mask = 0xFF, + .note = "CPLD read/write test register, to provide a way to test CPLD access." + }, + [BMC_RST] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x02, .mask = 1 << 6, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [CPLD_LPC_RST] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x02, .mask = 1 << 5, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [CPLD_SW_RST] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x02, .mask = 1 << 3, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [MB_CPLD_RST] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x02, .mask = 1 << 2, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [BCM56970_RST] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x02, .mask = 1 << 1, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [CPLD_UPGRADE_RST] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x03, .mask = 1 << 7, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [MB_RST_CPLD] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x03, .mask = 1 << 6, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [CPU_RST_MB_OOB] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x03, .mask = 1 << 5, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [GPIO_PHY_RST] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x03, .mask = 1 << 4, + .note = "“0” = Reset\n“1” = Normal operation" + }, + [PSU_FAN_EVENT] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x04, .mask = 1 << 4, + .note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" + }, + [CPU_THERMAL_INT] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x04, .mask = 1 << 1, + .note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" + }, + [FAN_INT] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x04, .mask = 1 << 0, + .note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" + }, + [CPLD_SPI_WP] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x06, .mask = 1 << 3, + .note = "“0” = SPI write operation is disabled\n“1” = SPI write operation is enabled" + }, + [RJ45_CONSOLE_SEL] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x06, .mask = 1 << 2, + .note = "“0” = Use BCM UART\n“1” = Use CPU UART" + }, + [SYSTEM_INT] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x07, .mask = 1 << 2, + .note = "“0” = Interrupt is asserted\n“1” = Interrupt is deasserted" + }, + [CPLD_MB_RST_DONE] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x07, .mask = 1 << 1, + .note = "“0” = Is done\n“1” = Is not done" + }, + [MB_PWR_OK] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x07, .mask = 1 << 0, + .note = "‘0’ = Power is failed\n‘1’ = Power is good" + }, + [FAN_EEPROM_WP] = { + .bus = BUS0, .addr = SWPLD4_ADDR, + .reg = 0x15, .mask = 1 << 2, + .note = "“1” = enables the lock-down mechanism.\n“0” = overrides the lock-down function enabling blocks to be erased or programmed using software commands." + }, }; \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_cpld.c b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_cpld.c index 0db05d967ccf..97e1b640010b 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_cpld.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_cpld.c @@ -1,860 +1,862 @@ -#include "delta_ag9064_common.h" - -#define QSFP_PRESENCE_1 0x03 -#define QSFP_PRESENCE_2 0x03 -#define QSFP_PRESENCE_3 0x24 -#define QSFP_PRESENCE_4 0x24 -#define QSFP_PRESENCE_5 0x04 -#define QSFP_PRESENCE_6 0x04 -#define QSFP_PRESENCE_7 0x25 -#define QSFP_PRESENCE_8 0x25 - -#define QSFP_LP_MODE_1 0x0c -#define QSFP_LP_MODE_2 0x0c -#define QSFP_LP_MODE_3 0x2a -#define QSFP_LP_MODE_4 0x2a -#define QSFP_LP_MODE_5 0x0d -#define QSFP_LP_MODE_6 0x0d -#define QSFP_LP_MODE_7 0x2b -#define QSFP_LP_MODE_8 0x2b - -#define QSFP_RESET_1 0x06 -#define QSFP_RESET_2 0x06 -#define QSFP_RESET_3 0x26 -#define QSFP_RESET_4 0x26 -#define QSFP_RESET_5 0x07 -#define QSFP_RESET_6 0x07 -#define QSFP_RESET_7 0x27 -#define QSFP_RESET_8 0x27 - -#define QSFP_RESPONSE_1 0x09 -#define QSFP_RESPONSE_2 0x09 -#define QSFP_RESPONSE_3 0x28 -#define QSFP_RESPONSE_4 0x28 -#define QSFP_RESPONSE_5 0x0a -#define QSFP_RESPONSE_6 0x0a -#define QSFP_RESPONSE_7 0x29 -#define QSFP_RESPONSE_8 0x29 - -#define QSFP_INTERRUPT_1 0x0f -#define QSFP_INTERRUPT_2 0x0f -#define QSFP_INTERRUPT_3 0x2c -#define QSFP_INTERRUPT_4 0x2c -#define QSFP_INTERRUPT_5 0x10 -#define QSFP_INTERRUPT_6 0x10 -#define QSFP_INTERRUPT_7 0x2d -#define QSFP_INTERRUPT_8 0x2d - -unsigned char cpupld_reg_addr; -/*---------------- CPLD - start ------------- */ -/* CPLD -- device */ -static struct platform_device ag9064_cpld = { - .name = "delta-ag9064-cpld", - .id = 0, - .dev = { - .platform_data = ag9064_cpld_platform_data, - .release = device_release - }, -}; - -static ssize_t get_present(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - int ret; - u64 data = 0; - uint8_t cmd_data[4]={0}; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_GETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_PRESENCE_1; - cmd_data[3] = 1; - cmd_data_len = sizeof(cmd_data); - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data = (u64)(ret & 0xff); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_PRESENCE_2; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 8; - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_PRESENCE_3; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 16; - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_PRESENCE_4; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 24; - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_PRESENCE_5; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 32; - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_PRESENCE_6; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 40; - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_PRESENCE_7; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 48; - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_PRESENCE_8; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 56; - - return sprintf(buf, "0x%016llx\n", data); -} - -static ssize_t get_lpmode(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - int ret; - u64 data = 0; - uint8_t cmd_data[4]={0}; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_GETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_LP_MODE_1; - cmd_data[3] = 1; - cmd_data_len = sizeof(cmd_data); - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data = (u64)(ret & 0xff); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_LP_MODE_2; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 8; - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_LP_MODE_3; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 16; - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_LP_MODE_4; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 24; - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_LP_MODE_5; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 32; - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_LP_MODE_6; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 40; - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_LP_MODE_7; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 48; - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_LP_MODE_8; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 56; - - return sprintf(buf, "0x%016llx\n", data); -} - -static ssize_t get_reset(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - int ret; - u64 data = 0; - uint8_t cmd_data[4]={0}; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_GETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESET_1; - cmd_data[3] = 1; - cmd_data_len = sizeof(cmd_data); - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data = (u64)(ret & 0xff); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESET_2; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 8; - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESET_3; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 16; - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESET_4; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 24; - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESET_5; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 32; - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESET_6; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 40; - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESET_7; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 48; - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESET_8; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 56; - - return sprintf(buf, "0x%016llx\n", data); -} - -static ssize_t get_response(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - int ret; - u64 data = 0; - uint8_t cmd_data[4]={0}; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_GETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESPONSE_1; - cmd_data[3] = 1; - cmd_data_len = sizeof(cmd_data); - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data = (u64)(ret & 0xff); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESPONSE_2; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 8; - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESPONSE_3; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 16; - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESPONSE_4; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 24; - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESPONSE_5; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 32; - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESPONSE_6; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 40; - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESPONSE_7; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 48; - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESPONSE_8; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 56; - - return sprintf(buf, "0x%016llx\n", data); -} - -static ssize_t get_interrupt(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - int ret; - u64 data = 0; - uint8_t cmd_data[4]={0}; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_GETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_INTERRUPT_1; - cmd_data[3] = 1; - cmd_data_len = sizeof(cmd_data); - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data = (u64)(ret & 0xff); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_INTERRUPT_2; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 8; - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_INTERRUPT_3; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 16; - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_INTERRUPT_4; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 24; - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_INTERRUPT_5; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 32; - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_INTERRUPT_6; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 40; - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_INTERRUPT_7; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 48; - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_INTERRUPT_8; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 56; - - return sprintf(buf, "0x%016llx\n", data); -} - -static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) -{ - unsigned long long set_data; - int err; - - err = kstrtoull(buf, 16, &set_data); - if (err){ - return err; - } - uint8_t cmd_data[4]={0}; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_SETDATA; - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_LP_MODE_1; - cmd_data[3] = (set_data & 0xff); - cmd_data_len = sizeof(cmd_data); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_LP_MODE_2; - cmd_data[3] = ((set_data >> 8 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_LP_MODE_3; - cmd_data[3] = ((set_data >> 16 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_LP_MODE_4; - cmd_data[3] = ((set_data >> 24 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_LP_MODE_5; - cmd_data[3] = ((set_data >> 32 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_LP_MODE_6; - cmd_data[3] = ((set_data >> 40 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_LP_MODE_7; - cmd_data[3] = ((set_data >> 48 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_LP_MODE_8; - cmd_data[3] = ((set_data >> 56 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - return count; -} - -static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) -{ - unsigned long long set_data; - int err; - - err = kstrtoull(buf, 16, &set_data); - if (err){ - return err; - } - uint8_t cmd_data[4]={0}; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_SETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESET_1; - cmd_data[3] = (set_data & 0xff); - cmd_data_len = sizeof(cmd_data); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESET_2; - cmd_data[3] = ((set_data >> 8 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESET_3; - cmd_data[3] = ((set_data >> 16 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESET_4; - cmd_data[3] = ((set_data >> 24 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESET_5; - cmd_data[3] = ((set_data >> 32 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESET_6; - cmd_data[3] = ((set_data >> 40 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESET_7; - cmd_data[3] = ((set_data >> 48 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESET_8; - cmd_data[3] = ((set_data >> 56 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - return count; -} - -static ssize_t set_response(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) -{ - unsigned long long set_data; - int err; - - err = kstrtoull(buf, 16, &set_data); - if (err){ - return err; - } - uint8_t cmd_data[4]={0}; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_SETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESPONSE_1; - cmd_data[3] = (set_data & 0xff); - cmd_data_len = sizeof(cmd_data); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESPONSE_2; - cmd_data[3] = ((set_data >> 8 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESPONSE_3; - cmd_data[3] = ((set_data >> 16 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESPONSE_4; - cmd_data[3] = ((set_data >> 24 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESPONSE_5; - cmd_data[3] = ((set_data >> 32 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESPONSE_6; - cmd_data[3] = ((set_data >> 40 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESPONSE_7; - cmd_data[3] = ((set_data >> 48 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESPONSE_8; - cmd_data[3] = ((set_data >> 56 ) & 0xff); - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - - return count; -} - -static ssize_t get_cpld_reg(struct device *dev, struct device_attribute *dev_attr, char *buf) -{ - int ret; - int mask; - int value; - char note[200]; - unsigned char reg; - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cpld_platform_data *pdata = dev->platform_data; - - switch (attr->index) { - case CPLD_REG_ADDR: - return sprintf(buf, "0x%02x\n", cpupld_reg_addr); - case CPLD_REG_VALUE: - ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, cpupld_reg_addr); - return sprintf(buf, "0x%02x\n", ret); - case CPLD_VER ... OP_MODULE_INT: - reg = attribute_data[attr->index].reg; - mask = attribute_data[attr->index].mask; - value = i2c_smbus_read_byte_data(pdata[system_cpld].client, reg); - sprintf(note, "\n%s\n",attribute_data[attr->index].note); - value = (value & mask); - break; - default: - return sprintf(buf, "%d not found", attr->index); - } - - switch (mask) { - case 0xFF: - return sprintf(buf, "0x%02x%s", value, note); - case 0x0F: - return sprintf(buf, "0x%01x%s", value, note); - case 0xF0: - value = value >> 4; - return sprintf(buf, "0x%01x%s", value, note); - default : - value = value >> dni_log2(mask); - return sprintf(buf, "%d%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 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); - if (err){ - return err; - } - - if (set_data > 0xff){ - printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); - return count; - } - - switch (attr->index) { - case CPLD_REG_ADDR: - cpupld_reg_addr = set_data; - return count; - case CPLD_REG_VALUE: - i2c_smbus_write_byte_data(pdata[system_cpld].client, cpupld_reg_addr, set_data); - return count; - case CPLD_VER ... OP_MODULE_INT: - reg = attribute_data[attr->index].reg; - mask = attribute_data[attr->index].mask; - value = i2c_smbus_read_byte_data(pdata[system_cpld].client, reg); - mask_out = value & ~(mask); - break; - default: - return sprintf(buf, "%d not found", attr->index); - } - - switch (mask) { - case 0xFF: - set_data = mask_out | (set_data & mask); - break; - case 0x0F: - set_data = mask_out | (set_data & mask); - break; - case 0xF0: - set_data = set_data << 4; - set_data = mask_out | (set_data & mask); - break; - default : - set_data = mask_out | (set_data << dni_log2(mask) ); - } - - i2c_smbus_write_byte_data(pdata[system_cpld].client, reg, set_data); - return count; -} - -static DEVICE_ATTR(qsfp_present, S_IRUGO, get_present, NULL); -static DEVICE_ATTR(qsfp_lpmode, S_IWUSR | S_IRUGO, get_lpmode, set_lpmode); -static DEVICE_ATTR(qsfp_reset, S_IWUSR | S_IRUGO, get_reset, set_reset); -static DEVICE_ATTR(qsfp_modsel, S_IWUSR | S_IRUGO, get_response, set_response); -static DEVICE_ATTR(qsfp_interrupt, S_IRUGO, get_interrupt, NULL); - -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(cpld_ver, S_IRUGO, get_cpld_reg, NULL, CPLD_VER); -static SENSOR_DEVICE_ATTR(cpu_board_ver, S_IRUGO, get_cpld_reg, NULL, CPU_BOARD_VER); -static SENSOR_DEVICE_ATTR(cpu_id, S_IRUGO, get_cpld_reg, NULL, CPU_ID); -static SENSOR_DEVICE_ATTR(mb_id, S_IRUGO, get_cpld_reg, NULL, MB_ID); -static SENSOR_DEVICE_ATTR(mb_ver, S_IRUGO, get_cpld_reg, NULL, MB_VER); -static SENSOR_DEVICE_ATTR(cpu0_pwr_ok, S_IRUGO, get_cpld_reg, NULL, CPU0_PWR_OK); -static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, get_cpld_reg, NULL, PSU_OVER_TEMP); -static SENSOR_DEVICE_ATTR(pwr_rail_over_temp, S_IRUGO, get_cpld_reg, NULL, PWR_RAIL_OVER_TEMP); -static SENSOR_DEVICE_ATTR(cpu_disomic_over_temp, S_IRUGO, get_cpld_reg, NULL, CPU_DISOMIC_OVER_TEMP); -static SENSOR_DEVICE_ATTR(ddr_over_temp, S_IRUGO, get_cpld_reg, NULL, DDR_OVER_TEMP); -static SENSOR_DEVICE_ATTR(cpld_pwr_on_rst, S_IRUGO, get_cpld_reg, NULL, CPLD_PWR_ON_RST); -static SENSOR_DEVICE_ATTR(cpld_hard_rst, S_IRUGO, get_cpld_reg, NULL, CPLD_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, S_IRUGO, get_cpld_reg, NULL, MB_PWR); -static SENSOR_DEVICE_ATTR(mb_rst, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, MB_RST); -static SENSOR_DEVICE_ATTR(psu_fan_int, S_IRUGO, get_cpld_reg, NULL, PSU_FAN_INT); -static SENSOR_DEVICE_ATTR(op_module_int, S_IRUGO, get_cpld_reg, NULL, OP_MODULE_INT); - -static struct attribute *ag9064_cpld_attrs[] = { - &dev_attr_qsfp_present.attr, - &dev_attr_qsfp_lpmode.attr, - &dev_attr_qsfp_reset.attr, - &dev_attr_qsfp_modsel.attr, - &dev_attr_qsfp_interrupt.attr, - &sensor_dev_attr_cpld_reg_value.dev_attr.attr, - &sensor_dev_attr_cpld_reg_addr.dev_attr.attr, - &sensor_dev_attr_cpld_ver.dev_attr.attr, - &sensor_dev_attr_cpu_board_ver.dev_attr.attr, - &sensor_dev_attr_cpu_id.dev_attr.attr, - &sensor_dev_attr_mb_id.dev_attr.attr, - &sensor_dev_attr_mb_ver.dev_attr.attr, - &sensor_dev_attr_cpu0_pwr_ok.dev_attr.attr, - &sensor_dev_attr_psu_over_temp.dev_attr.attr, - &sensor_dev_attr_pwr_rail_over_temp.dev_attr.attr, - &sensor_dev_attr_cpu_disomic_over_temp.dev_attr.attr, - &sensor_dev_attr_ddr_over_temp.dev_attr.attr, - &sensor_dev_attr_cpld_pwr_on_rst.dev_attr.attr, - &sensor_dev_attr_cpld_hard_rst.dev_attr.attr, - &sensor_dev_attr_cpld_rst.dev_attr.attr, - &sensor_dev_attr_mb_pwr.dev_attr.attr, - &sensor_dev_attr_mb_rst.dev_attr.attr, - &sensor_dev_attr_psu_fan_int.dev_attr.attr, - &sensor_dev_attr_op_module_int.dev_attr.attr, - NULL, -}; - -static struct attribute_group ag9064_cpld_attr_grp = { - .attrs = ag9064_cpld_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(BUS7); - if (!parent) { - printk(KERN_WARNING "Parent adapter (%d) not found\n",BUS7); - 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; - } - - ret = sysfs_create_group(&pdev->dev.kobj, &ag9064_cpld_attr_grp); - if (ret) { - printk(KERN_WARNING "Fail to create cpld attribute group"); - goto error; - } - - return 0; - -error: - i2c_unregister_device(pdata[system_cpld].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, &ag9064_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 struct platform_driver cpld_driver = { - .probe = cpld_probe, - .remove = __exit_p(cpld_remove), - .driver = { - .owner = THIS_MODULE, - .name = "delta-ag9064-cpld", - }, -}; - -/*---------------- CPLD - end ------------- */ - -/*---------------- module initialization ------------- */ -static void __init delta_ag9064_cpupld_init(void) -{ - int ret; - printk(KERN_WARNING "ag9064_platform_cpupld module initialization\n"); - - ret = dni_create_user(); - if (ret != 0){ - printk(KERN_WARNING "Fail to create IPMI user\n"); - } - - // set the CPUPLD prob and remove - ret = platform_driver_register(&cpld_driver); - if (ret) { - printk(KERN_WARNING "Fail to register cpupld driver\n"); - goto error_cpupld_driver; - } - - // register the CPUPLD - ret = platform_device_register(&ag9064_cpld); - if (ret) { - printk(KERN_WARNING "Fail to create cpupld device\n"); - goto error_ag9064_cpupld; - } - return 0; - -error_ag9064_cpupld: - platform_driver_unregister(&cpld_driver); -error_cpupld_driver: - return ret; -} - -static void __exit delta_ag9064_cpupld_exit(void) -{ - platform_device_unregister(&ag9064_cpld); - platform_driver_unregister(&cpld_driver); -} -module_init(delta_ag9064_cpupld_init); -module_exit(delta_ag9064_cpupld_exit); - -MODULE_DESCRIPTION("DNI ag9064 CPLD Platform Support"); -MODULE_AUTHOR("Stanley Chi "); -MODULE_LICENSE("GPL"); \ No newline at end of file +#include "delta_ag9064_common.h" + +#define QSFP_PRESENCE_1 0x03 +#define QSFP_PRESENCE_2 0x03 +#define QSFP_PRESENCE_3 0x24 +#define QSFP_PRESENCE_4 0x24 +#define QSFP_PRESENCE_5 0x04 +#define QSFP_PRESENCE_6 0x04 +#define QSFP_PRESENCE_7 0x25 +#define QSFP_PRESENCE_8 0x25 + +#define QSFP_LP_MODE_1 0x0c +#define QSFP_LP_MODE_2 0x0c +#define QSFP_LP_MODE_3 0x2a +#define QSFP_LP_MODE_4 0x2a +#define QSFP_LP_MODE_5 0x0d +#define QSFP_LP_MODE_6 0x0d +#define QSFP_LP_MODE_7 0x2b +#define QSFP_LP_MODE_8 0x2b + +#define QSFP_RESET_1 0x06 +#define QSFP_RESET_2 0x06 +#define QSFP_RESET_3 0x26 +#define QSFP_RESET_4 0x26 +#define QSFP_RESET_5 0x07 +#define QSFP_RESET_6 0x07 +#define QSFP_RESET_7 0x27 +#define QSFP_RESET_8 0x27 + +#define QSFP_RESPONSE_1 0x09 +#define QSFP_RESPONSE_2 0x09 +#define QSFP_RESPONSE_3 0x28 +#define QSFP_RESPONSE_4 0x28 +#define QSFP_RESPONSE_5 0x0a +#define QSFP_RESPONSE_6 0x0a +#define QSFP_RESPONSE_7 0x29 +#define QSFP_RESPONSE_8 0x29 + +#define QSFP_INTERRUPT_1 0x0f +#define QSFP_INTERRUPT_2 0x0f +#define QSFP_INTERRUPT_3 0x2c +#define QSFP_INTERRUPT_4 0x2c +#define QSFP_INTERRUPT_5 0x10 +#define QSFP_INTERRUPT_6 0x10 +#define QSFP_INTERRUPT_7 0x2d +#define QSFP_INTERRUPT_8 0x2d + +unsigned char cpupld_reg_addr; +/*---------------- CPLD - start ------------- */ +/* CPLD -- device */ +static struct platform_device ag9064_cpld = { + .name = "delta-ag9064-cpld", + .id = 0, + .dev = { + .platform_data = ag9064_cpld_platform_data, + .release = device_release + }, +}; + +static ssize_t get_present(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + int ret; + u64 data = 0; + uint8_t cmd_data[4]={0}; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_GETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_PRESENCE_1; + cmd_data[3] = 1; + cmd_data_len = sizeof(cmd_data); + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data = (u64)(ret & 0xff); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_PRESENCE_2; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 8; + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_PRESENCE_3; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 16; + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_PRESENCE_4; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 24; + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_PRESENCE_5; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 32; + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_PRESENCE_6; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 40; + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_PRESENCE_7; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 48; + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_PRESENCE_8; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 56; + + return sprintf(buf, "0x%016llx\n", data); +} + +static ssize_t get_lpmode(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + int ret; + u64 data = 0; + uint8_t cmd_data[4]={0}; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_GETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_LP_MODE_1; + cmd_data[3] = 1; + cmd_data_len = sizeof(cmd_data); + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data = (u64)(ret & 0xff); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_LP_MODE_2; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 8; + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_LP_MODE_3; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 16; + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_LP_MODE_4; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 24; + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_LP_MODE_5; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 32; + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_LP_MODE_6; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 40; + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_LP_MODE_7; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 48; + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_LP_MODE_8; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 56; + + return sprintf(buf, "0x%016llx\n", data); +} + +static ssize_t get_reset(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + int ret; + u64 data = 0; + uint8_t cmd_data[4]={0}; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_GETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESET_1; + cmd_data[3] = 1; + cmd_data_len = sizeof(cmd_data); + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data = (u64)(ret & 0xff); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESET_2; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 8; + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESET_3; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 16; + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESET_4; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 24; + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESET_5; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 32; + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESET_6; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 40; + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESET_7; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 48; + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESET_8; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 56; + + return sprintf(buf, "0x%016llx\n", data); +} + +static ssize_t get_response(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + int ret; + u64 data = 0; + uint8_t cmd_data[4]={0}; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_GETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESPONSE_1; + cmd_data[3] = 1; + cmd_data_len = sizeof(cmd_data); + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data = (u64)(ret & 0xff); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESPONSE_2; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 8; + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESPONSE_3; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 16; + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESPONSE_4; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 24; + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESPONSE_5; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 32; + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESPONSE_6; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 40; + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESPONSE_7; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 48; + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESPONSE_8; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 56; + + return sprintf(buf, "0x%016llx\n", data); +} + +static ssize_t get_interrupt(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + int ret; + u64 data = 0; + uint8_t cmd_data[4]={0}; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_GETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_INTERRUPT_1; + cmd_data[3] = 1; + cmd_data_len = sizeof(cmd_data); + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data = (u64)(ret & 0xff); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_INTERRUPT_2; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 8; + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_INTERRUPT_3; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 16; + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_INTERRUPT_4; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 24; + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_INTERRUPT_5; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 32; + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_INTERRUPT_6; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 40; + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_INTERRUPT_7; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 48; + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_INTERRUPT_8; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 56; + + return sprintf(buf, "0x%016llx\n", data); +} + +static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long long set_data; + int err; + + err = kstrtoull(buf, 16, &set_data); + if (err){ + return err; + } + uint8_t cmd_data[4]={0}; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_SETDATA; + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_LP_MODE_1; + cmd_data[3] = (set_data & 0xff); + cmd_data_len = sizeof(cmd_data); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_LP_MODE_2; + cmd_data[3] = ((set_data >> 8 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_LP_MODE_3; + cmd_data[3] = ((set_data >> 16 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_LP_MODE_4; + cmd_data[3] = ((set_data >> 24 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_LP_MODE_5; + cmd_data[3] = ((set_data >> 32 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_LP_MODE_6; + cmd_data[3] = ((set_data >> 40 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_LP_MODE_7; + cmd_data[3] = ((set_data >> 48 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_LP_MODE_8; + cmd_data[3] = ((set_data >> 56 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + return count; +} + +static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long long set_data; + int err; + + err = kstrtoull(buf, 16, &set_data); + if (err){ + return err; + } + uint8_t cmd_data[4]={0}; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_SETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESET_1; + cmd_data[3] = (set_data & 0xff); + cmd_data_len = sizeof(cmd_data); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESET_2; + cmd_data[3] = ((set_data >> 8 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESET_3; + cmd_data[3] = ((set_data >> 16 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESET_4; + cmd_data[3] = ((set_data >> 24 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESET_5; + cmd_data[3] = ((set_data >> 32 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESET_6; + cmd_data[3] = ((set_data >> 40 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESET_7; + cmd_data[3] = ((set_data >> 48 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESET_8; + cmd_data[3] = ((set_data >> 56 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + return count; +} + +static ssize_t set_response(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long long set_data; + int err; + + err = kstrtoull(buf, 16, &set_data); + if (err){ + return err; + } + uint8_t cmd_data[4]={0}; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_SETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESPONSE_1; + cmd_data[3] = (set_data & 0xff); + cmd_data_len = sizeof(cmd_data); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESPONSE_2; + cmd_data[3] = ((set_data >> 8 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESPONSE_3; + cmd_data[3] = ((set_data >> 16 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESPONSE_4; + cmd_data[3] = ((set_data >> 24 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESPONSE_5; + cmd_data[3] = ((set_data >> 32 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESPONSE_6; + cmd_data[3] = ((set_data >> 40 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESPONSE_7; + cmd_data[3] = ((set_data >> 48 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESPONSE_8; + cmd_data[3] = ((set_data >> 56 ) & 0xff); + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + + return count; +} + +static ssize_t get_cpld_reg(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + int ret; + int mask; + int value; + char note[200]; + unsigned char reg; + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cpld_platform_data *pdata = dev->platform_data; + + switch (attr->index) { + case CPLD_REG_ADDR: + return sprintf(buf, "0x%02x\n", cpupld_reg_addr); + case CPLD_REG_VALUE: + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, cpupld_reg_addr); + return sprintf(buf, "0x%02x\n", ret); + case CPLD_VER ... OP_MODULE_INT: + reg = attribute_data[attr->index].reg; + mask = attribute_data[attr->index].mask; + value = i2c_smbus_read_byte_data(pdata[system_cpld].client, reg); + sprintf(note, "\n%s\n",attribute_data[attr->index].note); + value = (value & mask); + break; + default: + return sprintf(buf, "%d not found", attr->index); + } + + switch (mask) { + case 0xFF: + return sprintf(buf, "0x%02x%s", value, note); + case 0x0F: + return sprintf(buf, "0x%01x%s", value, note); + case 0xF0: + value = value >> 4; + return sprintf(buf, "0x%01x%s", value, note); + default : + value = value >> dni_log2(mask); + return sprintf(buf, "%d%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; + } + + switch (attr->index) { + case CPLD_REG_ADDR: + cpupld_reg_addr = set_data; + return count; + case CPLD_REG_VALUE: + i2c_smbus_write_byte_data(pdata[system_cpld].client, cpupld_reg_addr, set_data); + return count; + case CPLD_VER ... OP_MODULE_INT: + reg = attribute_data[attr->index].reg; + mask = attribute_data[attr->index].mask; + value = i2c_smbus_read_byte_data(pdata[system_cpld].client, reg); + mask_out = value & ~(mask); + break; + default: + return sprintf(buf, "%d not found", attr->index); + } + + switch (mask) { + case 0xFF: + set_data = mask_out | (set_data & mask); + break; + case 0x0F: + set_data = mask_out | (set_data & mask); + break; + case 0xF0: + set_data = set_data << 4; + set_data = mask_out | (set_data & mask); + break; + default : + set_data = mask_out | (set_data << dni_log2(mask) ); + } + + i2c_smbus_write_byte_data(pdata[system_cpld].client, reg, set_data); + return count; +} + +static DEVICE_ATTR(qsfp_present, S_IRUGO, get_present, NULL); +static DEVICE_ATTR(qsfp_lpmode, S_IWUSR | S_IRUGO, get_lpmode, set_lpmode); +static DEVICE_ATTR(qsfp_reset, S_IWUSR | S_IRUGO, get_reset, set_reset); +static DEVICE_ATTR(qsfp_modsel, S_IWUSR | S_IRUGO, get_response, set_response); +static DEVICE_ATTR(qsfp_interrupt, S_IRUGO, get_interrupt, NULL); + +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(cpld_ver, S_IRUGO, get_cpld_reg, NULL, CPLD_VER); +static SENSOR_DEVICE_ATTR(cpu_board_ver, S_IRUGO, get_cpld_reg, NULL, CPU_BOARD_VER); +static SENSOR_DEVICE_ATTR(cpu_id, S_IRUGO, get_cpld_reg, NULL, CPU_ID); +static SENSOR_DEVICE_ATTR(mb_id, S_IRUGO, get_cpld_reg, NULL, MB_ID); +static SENSOR_DEVICE_ATTR(mb_ver, S_IRUGO, get_cpld_reg, NULL, MB_VER); +static SENSOR_DEVICE_ATTR(cpu0_pwr_ok, S_IRUGO, get_cpld_reg, NULL, CPU0_PWR_OK); +static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, get_cpld_reg, NULL, PSU_OVER_TEMP); +static SENSOR_DEVICE_ATTR(pwr_rail_over_temp, S_IRUGO, get_cpld_reg, NULL, PWR_RAIL_OVER_TEMP); +static SENSOR_DEVICE_ATTR(cpu_disomic_over_temp, S_IRUGO, get_cpld_reg, NULL, CPU_DISOMIC_OVER_TEMP); +static SENSOR_DEVICE_ATTR(ddr_over_temp, S_IRUGO, get_cpld_reg, NULL, DDR_OVER_TEMP); +static SENSOR_DEVICE_ATTR(cpld_pwr_on_rst, S_IRUGO, get_cpld_reg, NULL, CPLD_PWR_ON_RST); +static SENSOR_DEVICE_ATTR(cpld_hard_rst, S_IRUGO, get_cpld_reg, NULL, CPLD_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, S_IRUGO, get_cpld_reg, NULL, MB_PWR); +static SENSOR_DEVICE_ATTR(mb_rst, S_IRUGO | S_IWUSR, get_cpld_reg, set_cpld_reg, MB_RST); +static SENSOR_DEVICE_ATTR(psu_fan_int, S_IRUGO, get_cpld_reg, NULL, PSU_FAN_INT); +static SENSOR_DEVICE_ATTR(op_module_int, S_IRUGO, get_cpld_reg, NULL, OP_MODULE_INT); + +static struct attribute *ag9064_cpld_attrs[] = { + &dev_attr_qsfp_present.attr, + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_reset.attr, + &dev_attr_qsfp_modsel.attr, + &dev_attr_qsfp_interrupt.attr, + &sensor_dev_attr_cpld_reg_value.dev_attr.attr, + &sensor_dev_attr_cpld_reg_addr.dev_attr.attr, + &sensor_dev_attr_cpld_ver.dev_attr.attr, + &sensor_dev_attr_cpu_board_ver.dev_attr.attr, + &sensor_dev_attr_cpu_id.dev_attr.attr, + &sensor_dev_attr_mb_id.dev_attr.attr, + &sensor_dev_attr_mb_ver.dev_attr.attr, + &sensor_dev_attr_cpu0_pwr_ok.dev_attr.attr, + &sensor_dev_attr_psu_over_temp.dev_attr.attr, + &sensor_dev_attr_pwr_rail_over_temp.dev_attr.attr, + &sensor_dev_attr_cpu_disomic_over_temp.dev_attr.attr, + &sensor_dev_attr_ddr_over_temp.dev_attr.attr, + &sensor_dev_attr_cpld_pwr_on_rst.dev_attr.attr, + &sensor_dev_attr_cpld_hard_rst.dev_attr.attr, + &sensor_dev_attr_cpld_rst.dev_attr.attr, + &sensor_dev_attr_mb_pwr.dev_attr.attr, + &sensor_dev_attr_mb_rst.dev_attr.attr, + &sensor_dev_attr_psu_fan_int.dev_attr.attr, + &sensor_dev_attr_op_module_int.dev_attr.attr, + NULL, +}; + +static struct attribute_group ag9064_cpld_attr_grp = { + .attrs = ag9064_cpld_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(BUS7); + if (!parent) { + printk(KERN_WARNING "Parent adapter (%d) not found\n",BUS7); + 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; + } + + ret = sysfs_create_group(&pdev->dev.kobj, &ag9064_cpld_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + goto error; + } + + return 0; + +error: + i2c_unregister_device(pdata[system_cpld].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, &ag9064_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 struct platform_driver cpld_driver = { + .probe = cpld_probe, + .remove = __exit_p(cpld_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-ag9064-cpld", + }, +}; + +/*---------------- CPLD - end ------------- */ + +/*---------------- module initialization ------------- */ +static int __init delta_ag9064_cpupld_init(void) +{ + int ret; + printk(KERN_WARNING "ag9064_platform_cpupld module initialization\n"); + + ret = dni_create_user(); + if (ret != 0){ + printk(KERN_WARNING "Fail to create IPMI user\n"); + } + + // set the CPUPLD prob and remove + ret = platform_driver_register(&cpld_driver); + if (ret) { + printk(KERN_WARNING "Fail to register cpupld driver\n"); + goto error_cpupld_driver; + } + + // register the CPUPLD + ret = platform_device_register(&ag9064_cpld); + if (ret) { + printk(KERN_WARNING "Fail to create cpupld device\n"); + goto error_ag9064_cpupld; + } + return 0; + +error_ag9064_cpupld: + platform_driver_unregister(&cpld_driver); +error_cpupld_driver: + return ret; +} + +static void __exit delta_ag9064_cpupld_exit(void) +{ + platform_device_unregister(&ag9064_cpld); + platform_driver_unregister(&cpld_driver); +} +module_init(delta_ag9064_cpupld_init); +module_exit(delta_ag9064_cpupld_exit); + +MODULE_DESCRIPTION("DNI ag9064 CPLD Platform Support"); +MODULE_AUTHOR("Stanley Chi "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c index f4222907d4f2..099d7ea987da 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c @@ -1,1815 +1,1178 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "delta_ag9064_common.h" - -#define SFF8436_INFO(data) \ - .type = "sff8436", .addr = 0x50, .platform_data = (data) - -#define SFF_8346_PORT(eedata) \ - .byte_len = 256, .page_size = 1, .flags = SFF_8436_FLAG_READONLY - -#define ag9064_i2c_device_num(NUM){ \ - .name = "delta-ag9064-i2c-device", \ - .id = NUM, \ - .dev = { \ - .platform_data = &ag9064_i2c_device_platform_data[NUM], \ - .release = device_release, \ - }, \ -} - -struct i2c_client * i2c_client_9548; - -/* pca9548 - add 8 bus */ -static struct pca954x_platform_mode pca954x_mode[] = -{ - { - .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, - }, - { - .adap_id = 12, - .deselect_on_exit = 1, - }, - { - .adap_id = 13, - .deselect_on_exit = 1, - }, - { - .adap_id = 14, - .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_pca9548[] = -{ - { - I2C_BOARD_INFO("pca9548", 0x70), - .platform_data = &pca954x_data, - }, -}; - -static struct sff_8436_platform_data sff_8436_port[] = { - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, - { SFF_8346_PORT() }, -}; - -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); - -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); -/*---------------- IPMI - start ------------- */ -int dni_create_user(void) -{ - int rv, i; - - for (i=0,rv=1; idev.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-ag9064-i2c-device", - } -}; - -/*---------------- I2C driver - end ------------- */ - -/*---------------- MUX - start ------------- */ - -struct swpld_mux_platform_data { - int parent; - int base_nr; -// struct i2c_client *cpld; -}; - -struct swpld_mux { - struct i2c_adapter *parent; - struct i2c_adapter **child; - struct swpld_mux_platform_data data; -}; - -static struct swpld_mux_platform_data ag9064_swpld_mux_platform_data[] = { - { - .parent = BUS9, - .base_nr = BUS9_BASE_NUM, -// .cpld = NULL, - }, -}; - -static struct platform_device ag9064_swpld_mux[] = -{ - { - .name = "delta-ag9064-swpld-mux", - .id = 0, - .dev = { - .platform_data = &ag9064_swpld_mux_platform_data[0], - .release = device_release, - }, - }, -}; -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) -static int swpld_mux_select(struct i2c_adapter *adap, void *data, u8 chan) -{ - uint8_t cmd_data[4]={0}; - struct swpld_mux *mux = data; - uint8_t set_cmd; - int cmd_data_len; - - if ( mux->data.base_nr == BUS9_BASE_NUM ) - { - set_cmd = CMD_SETDATA; - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_PORT_MUX_REG; - cmd_data[3] = chan + 1; - cmd_data_len = sizeof(cmd_data); - // return 0; - return dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - } - else - { - printk(KERN_ERR "Swpld mux QSFP select port error\n"); - return 0; - } -} -#else -static int swpld_mux_select(struct i2c_mux_core *muxc, u32 chan) -{ - uint8_t cmd_data[4]={0}; - struct swpld_mux *mux = i2c_mux_priv(muxc); - uint8_t set_cmd; - int cmd_data_len; - - if ( mux->data.base_nr == BUS9_BASE_NUM ) - { - set_cmd = CMD_SETDATA; - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_PORT_MUX_REG; - cmd_data[3] = chan + 1; - cmd_data_len = sizeof(cmd_data); - return dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - return 0; - } - else - { - printk(KERN_ERR "Swpld mux QSFP select port error\n"); - return 0; - } - -} -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) -static int __init swpld_mux_probe(struct platform_device *pdev) -{ - struct swpld_mux *mux; - struct swpld_mux_platform_data *pdata; - struct i2c_adapter *parent; - int i, ret, dev_num; - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(&pdev->dev, "SWPLD platform data not found\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; - } - /* Judge bus number to decide how many devices*/ - switch (pdata->parent) { - case BUS9: - dev_num = BUS9_DEV_NUM; - break; - default : - dev_num = DEFAULT_NUM; - break; - } - - mux = kzalloc(sizeof(*mux), GFP_KERNEL); - if (!mux) { - ret = -ENOMEM; - printk(KERN_ERR "Failed to allocate memory for mux\n"); - goto alloc_failed; - } - - mux->parent = parent; - mux->data = *pdata; - mux->child = kzalloc(sizeof(struct i2c_adapter *) * dev_num, GFP_KERNEL); - if (!mux->child) { - ret = -ENOMEM; - printk(KERN_ERR "Failed to allocate memory for device on mux\n"); - goto alloc_failed2; - } - - for (i = 0; i < dev_num; i++) - { - int nr = pdata->base_nr + i; - unsigned int class = 0; - - mux->child[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, - nr, i, class, - swpld_mux_select, NULL); - if (!mux->child[i]) - { - ret = -ENODEV; - dev_err(&pdev->dev, "Failed to add adapter %d\n", i); - goto add_adapter_failed; - } - } - - platform_set_drvdata(pdev, mux); - return 0; - -add_adapter_failed: - for (; i > 0; i--) - i2c_del_mux_adapter(mux->child[i - 1]); - kfree(mux->child); -alloc_failed2: - kfree(mux); -alloc_failed: - i2c_put_adapter(parent); - - return ret; -} -#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) -static int __init swpld_mux_probe(struct platform_device *pdev) -{ - struct i2c_mux_core *muxc; - struct swpld_mux *mux; - struct swpld_mux_platform_data *pdata; - struct i2c_adapter *parent; - int i, ret, dev_num; - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(&pdev->dev, "SWPLD 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 BUS9: - dev_num = BUS9_DEV_NUM; - break; - default : - dev_num = DEFAULT_NUM; - break; - } - - muxc = i2c_mux_alloc(parent, &pdev->dev, dev_num, 0, 0,swpld_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_failed2: - kfree(mux); -alloc_failed: - i2c_put_adapter(parent); - - return ret; -} -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) -static int __exit swpld_mux_remove(struct platform_device *pdev) -{ - int i; - struct swpld_mux *mux = platform_get_drvdata(pdev); - struct swpld_mux_platform_data *pdata; - struct i2c_adapter *parent; - int dev_num; - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(&pdev->dev, "SWPLD platform data not found\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; - } - switch (pdata->parent) { - case BUS9: - dev_num = BUS9_DEV_NUM; - break; - default : - dev_num = DEFAULT_NUM; - break; - } - - for (i = 0; i < dev_num; i++) - i2c_del_mux_adapter(mux->child[i]); - - platform_set_drvdata(pdev, NULL); - i2c_put_adapter(mux->parent); - kfree(mux->child); - kfree(mux); - - return 0; -} -#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) -static int __exit swpld_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; -} -#endif - -static struct platform_driver swpld_mux_driver = { - .probe = swpld_mux_probe, - .remove = __exit_p(swpld_mux_remove), /* TODO */ - .driver = { - .owner = THIS_MODULE, - .name = "delta-ag9064-swpld-mux", - }, -}; -/*---------------- MUX - end ------------- */ - -/*---------------- CPLD - start ------------- */ - -/* CPLD -- device */ - -static ssize_t get_present(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - uint8_t cmd_data[4]={0}; - int ret; - u64 data = 0; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_GETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_PRESENCE_1; - cmd_data[3] = 1; - cmd_data_len = sizeof(cmd_data); - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - ret=0; - data = (u64)(ret & 0xff); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_PRESENCE_2; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); -// ret=0; - data |= (u64)(ret & 0xff) << 8; - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_PRESENCE_3; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 16; - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_PRESENCE_4; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 24; - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_PRESENCE_5; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 32; - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_PRESENCE_6; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 40; - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_PRESENCE_7; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 48; - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_PRESENCE_8; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 56; - - return sprintf(buf, "0x%016llx\n", data); -} - -static ssize_t get_lpmode(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - uint8_t cmd_data[4]={0}; - int ret; - u64 data = 0; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_GETDATA; - ret=0; - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_LP_MODE_1; - cmd_data[3] = 1; - cmd_data_len = sizeof(cmd_data); - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data = (u64)(ret & 0xff); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_LP_MODE_2; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 8; - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_LP_MODE_3; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 16; - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_LP_MODE_4; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 24; - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_LP_MODE_5; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 32; - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_LP_MODE_6; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 40; - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_LP_MODE_7; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 48; - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_LP_MODE_8; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 56; - - return sprintf(buf, "0x%016llx\n", data); -} - -static ssize_t get_reset(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - uint8_t cmd_data[4]={0}; - int ret; - u64 data = 0; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_GETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESET_1; - cmd_data[3] = 1; - cmd_data_len = sizeof(cmd_data); - ret=0; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data = (u64)(ret & 0xff); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESET_2; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 8; - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESET_3; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 16; - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESET_4; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 24; - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESET_5; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 32; - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESET_6; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 40; - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESET_7; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 48; - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESET_8; - ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - data |= (u64)(ret & 0xff) << 56; - - return sprintf(buf, "0x%016llx\n", data); -} - -static ssize_t get_response(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - uint8_t cmd_data[4]={0}; - int ret; - u64 data = 0; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_GETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESPONSE_1; - cmd_data[3] = 1; - cmd_data_len = sizeof(cmd_data); - ret = 0; - data = (u64)(ret & 0xff); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESPONSE_2; - data |= (u64)(ret & 0xff) << 8; - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESPONSE_3; - data |= (u64)(ret & 0xff) << 16; - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESPONSE_4; - data |= (u64)(ret & 0xff) << 24; - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESPONSE_5; - data |= (u64)(ret & 0xff) << 32; - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESPONSE_6; - data |= (u64)(ret & 0xff) << 40; - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESPONSE_7; - data |= (u64)(ret & 0xff) << 48; - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESPONSE_8; - data |= (u64)(ret & 0xff) << 56; - - return sprintf(buf, "0x%016llx\n", data); -} - -static ssize_t get_interrupt(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - uint8_t cmd_data[4]={0}; - int ret; - u64 data = 0; - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_GETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_INTERRUPT_1; - cmd_data[3] = 1; - cmd_data_len = sizeof(cmd_data); - ret=0; - data = (u64)(ret & 0xff); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_INTERRUPT_2; - data |= (u64)(ret & 0xff) << 8; - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_INTERRUPT_3; - data |= (u64)(ret & 0xff) << 16; - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_INTERRUPT_4; - data |= (u64)(ret & 0xff) << 24; - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_INTERRUPT_5; - data |= (u64)(ret & 0xff) << 32; - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_INTERRUPT_6; - data |= (u64)(ret & 0xff) << 40; - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_INTERRUPT_7; - data |= (u64)(ret & 0xff) << 48; - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_INTERRUPT_8; - data |= (u64)(ret & 0xff) << 56; - - return sprintf(buf, "0x%016llx\n", data); -} - - -static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) -{ - uint8_t cmd_data[4]={0}; - unsigned long long set_data; - int err; - - err = kstrtoull(buf, 16, &set_data); - if (err){ - return err; - } - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_SETDATA; - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_LP_MODE_1; - cmd_data[3] = (set_data & 0xff); - cmd_data_len = sizeof(cmd_data); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_LP_MODE_2; - cmd_data[3] = ((set_data >> 8 ) & 0xff); - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_LP_MODE_3; - cmd_data[3] = ((set_data >> 16 ) & 0xff); - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_LP_MODE_4; - cmd_data[3] = ((set_data >> 24 ) & 0xff); - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_LP_MODE_5; - cmd_data[3] = ((set_data >> 32 ) & 0xff); - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_LP_MODE_6; - cmd_data[3] = ((set_data >> 40 ) & 0xff); - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_LP_MODE_7; - cmd_data[3] = ((set_data >> 48 ) & 0xff); - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_LP_MODE_8; - cmd_data[3] = ((set_data >> 56 ) & 0xff); - - return count; -} - -static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) -{ - uint8_t cmd_data[4]={0}; - unsigned long long set_data; - int err; - - err = kstrtoull(buf, 16, &set_data); - if (err){ - return err; - } - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_SETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESET_1; - cmd_data[3] = (set_data & 0xff); - cmd_data_len = sizeof(cmd_data); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESET_2; - cmd_data[3] = ((set_data >> 8 ) & 0xff); - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESET_3; - cmd_data[3] = ((set_data >> 16 ) & 0xff); - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESET_4; - cmd_data[3] = ((set_data >> 24 ) & 0xff); - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESET_5; - cmd_data[3] = ((set_data >> 32 ) & 0xff); - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESET_6; - cmd_data[3] = ((set_data >> 40 ) & 0xff); - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESET_7; - cmd_data[3] = ((set_data >> 48 ) & 0xff); - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESET_8; - cmd_data[3] = ((set_data >> 56 ) & 0xff); - - return count; -} - -static ssize_t set_response(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) -{ - uint8_t cmd_data[4]={0}; - unsigned long long set_data; - int err; - - err = kstrtoull(buf, 16, &set_data); - if (err){ - return err; - } - uint8_t set_cmd; - int cmd_data_len; - - set_cmd = CMD_SETDATA; - - /*QSFP1~8*/ - cmd_data[0] = BMC_BUS_5; - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESPONSE_1; - cmd_data[3] = (set_data & 0xff); - cmd_data_len = sizeof(cmd_data); - - /*QSFP9~16*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESPONSE_2; - cmd_data[3] = ((set_data >> 8 ) & 0xff); - - /*QSFP17~24*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESPONSE_3; - cmd_data[3] = ((set_data >> 16 ) & 0xff); - - /*QSFP25~32*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESPONSE_4; - cmd_data[3] = ((set_data >> 24 ) & 0xff); - - /*QSFP33~40*/ - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = QSFP_RESPONSE_5; - cmd_data[3] = ((set_data >> 32 ) & 0xff); - - /*QSFP41~48*/ - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = QSFP_RESPONSE_6; - cmd_data[3] = ((set_data >> 40 ) & 0xff); - - /*QSFP49~56*/ - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = QSFP_RESPONSE_7; - cmd_data[3] = ((set_data >> 48 ) & 0xff); - - /*QSFP57~64*/ - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = QSFP_RESPONSE_8; - cmd_data[3] = ((set_data >> 56 ) & 0xff); - - return count; -} - -static DEVICE_ATTR(qsfp_present, S_IRUGO, get_present, NULL); -static DEVICE_ATTR(qsfp_lpmode, S_IWUSR | S_IRUGO, get_lpmode, set_lpmode); -static DEVICE_ATTR(qsfp_reset, S_IWUSR | S_IRUGO, get_reset, set_reset); -static DEVICE_ATTR(qsfp_modsel, S_IWUSR | S_IRUGO, get_response, set_response); -static DEVICE_ATTR(qsfp_interrupt, S_IRUGO, get_interrupt, NULL); - -static struct attribute *ag9064_cpld_attrs[] = { - &dev_attr_qsfp_present.attr, - &dev_attr_qsfp_lpmode.attr, - &dev_attr_qsfp_reset.attr, - &dev_attr_qsfp_modsel.attr, - &dev_attr_qsfp_interrupt.attr, - NULL, -}; - -static struct attribute_group ag9064_cpld_attr_grp = { - .attrs = ag9064_cpld_attrs, -}; - -enum cpld_type { - system_cpld, -}; - -struct cpld_platform_data { - int reg_addr; - struct i2c_client *client; -}; - -static struct cpld_platform_data ag9064_cpld_platform_data[] = { - [system_cpld] = { - .reg_addr = CPLD_REG, - }, -}; - -static struct platform_device ag9064_cpld = { - .name = "delta-ag9064-cpld", - .id = 0, - .dev = { - .platform_data = ag9064_cpld_platform_data, - .release = device_release - }, -}; - -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(BUS7); - if (!parent) { - printk(KERN_WARNING "Parent adapter (%d) not found\n",BUS7); - 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; - } - - ret = sysfs_create_group(&pdev->dev.kobj, &ag9064_cpld_attr_grp); - if (ret) { - printk(KERN_WARNING "Fail to create cpld attribute group"); - goto error; - } - - return 0; - -error: - i2c_unregister_device(pdata[system_cpld].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, &ag9064_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 struct platform_driver cpld_driver = { - .probe = cpld_probe, - .remove = __exit_p(cpld_remove), - .driver = { - .owner = THIS_MODULE, - .name = "delta-ag9064-cpld", - }, -}; - -/*---------------- CPLD - end ------------- */ - -/*---------------- module initialization ------------- */ - -static int __init delta_ag9064_platform_init(void) -{ - struct i2c_client *client; - struct i2c_adapter *adapter; - struct swpld_mux_platform_data *swpld_pdata; - struct cpld_platform_data * cpld_pdata; - int ret,i = 0; - - printk("ag9064_platform module initialization\n"); - - adapter = i2c_get_adapter(BUS2); - i2c_client_9548 = i2c_new_device(adapter, &i2c_info_pca9548[0]); - i2c_put_adapter(adapter); - - 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 cpld driver\n"); - goto error_cpld_driver; - } - - // register the mux prob which call the SWPLD - ret = platform_driver_register(&swpld_mux_driver); - if (ret) { - printk(KERN_WARNING "Fail to register swpld mux driver\n"); - goto error_swpld_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 CPLD - ret = platform_device_register(&ag9064_cpld); - if (ret) { - printk(KERN_WARNING "Fail to create cpld device\n"); - goto error_ag9064_cpld; - } - - swpld_pdata = ag9064_swpld_mux[0].dev.platform_data; - ret = platform_device_register(&ag9064_swpld_mux[0]); - if (ret) { - printk(KERN_WARNING "Fail to create swpld mux\n"); - goto error_ag9064_swpld_mux; - } - - for (i = 0; i < ARRAY_SIZE(ag9064_i2c_device); i++) - { - ret = platform_device_register(&ag9064_i2c_device[i]); - if (ret) - { - printk(KERN_WARNING "Fail to create i2c device %d\n", i); - goto error_ag9064_i2c_device; - } - } - if (ret) - goto error_ag9064_swpld_mux; - - return 0; - -error_ag9064_i2c_device: - i--; - for (; i >= 0; i--) { - platform_device_unregister(&ag9064_i2c_device[i]); - } - i = ARRAY_SIZE(ag9064_swpld_mux); -error_ag9064_swpld_mux: - i--; - for (; i >= 0; i--) { - platform_device_unregister(&ag9064_swpld_mux); - } - platform_driver_unregister(&ag9064_cpld); -error_ag9064_cpld: - platform_driver_unregister(&i2c_device_driver); -error_i2c_device_driver: - platform_driver_unregister(&swpld_mux_driver); -error_swpld_mux_driver: - platform_driver_unregister(&cpld_driver); -error_cpld_driver: - return ret; -} - -static void __exit delta_ag9064_platform_exit(void) -{ - int i = 0; - - for ( i = 0; i < ARRAY_SIZE(ag9064_i2c_device); i++ ) { - platform_device_unregister(&ag9064_i2c_device[i]); - } - - platform_device_unregister(&ag9064_swpld_mux); - platform_device_unregister(&ag9064_cpld); - platform_driver_unregister(&i2c_device_driver); - platform_driver_unregister(&swpld_mux_driver); - platform_driver_unregister(&cpld_driver); - i2c_unregister_device(i2c_client_9548); -} - -module_init(delta_ag9064_platform_init); -module_exit(delta_ag9064_platform_exit); - -MODULE_DESCRIPTION("DELTA ag9064 Platform Support"); -MODULE_AUTHOR("Johnson Lu "); -MODULE_LICENSE("GPL"); +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "delta_ag9064_common.h" + +#define SFF8436_INFO(data) \ + .type = "sff8436", .addr = 0x50, .platform_data = (data) + +#define SFF_8346_PORT(eedata) \ + .byte_len = 256, .page_size = 1, .flags = SFF_8436_FLAG_READONLY + +#define ag9064_i2c_device_num(NUM){ \ + .name = "delta-ag9064-i2c-device", \ + .id = NUM, \ + .dev = { \ + .platform_data = &ag9064_i2c_device_platform_data[NUM], \ + .release = device_release, \ + }, \ +} + +struct i2c_client * i2c_client_9548; + + +/* pca9548 - add 8 bus */ +static struct pca954x_platform_mode pca954x_mode[] = +{ + { + .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, + }, + { + .adap_id = 12, + .deselect_on_exit = 1, + }, + { + .adap_id = 13, + .deselect_on_exit = 1, + }, + { + .adap_id = 14, + .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_pca9548[] = +{ + { + I2C_BOARD_INFO("pca9548", 0x70), + .platform_data = &pca954x_data, + }, +}; + +static struct sff_8436_platform_data sff_8436_port[] = { + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, +}; + +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); +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); + +/*---------------- IPMI - start ------------- */ + +int dni_create_user(void) +{ + int rv, i; + + for (i=0,rv=1; idev.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-ag9064-i2c-device", + } +}; + +/*---------------- I2C driver - end ------------- */ + +/*---------------- MUX - start ------------- */ + +struct swpld_mux_platform_data { + int parent; + int base_nr; +// struct i2c_client *cpld; +}; + +struct swpld_mux { + struct i2c_adapter *parent; + struct i2c_adapter **child; + struct swpld_mux_platform_data data; +}; + +static struct swpld_mux_platform_data ag9064_swpld_mux_platform_data[] = { + { + .parent = BUS9, + .base_nr = BUS9_BASE_NUM, +// .cpld = NULL, + }, +}; + +static struct platform_device ag9064_swpld_mux[] = +{ + { + .name = "delta-ag9064-swpld-mux", + .id = 0, + .dev = { + .platform_data = &ag9064_swpld_mux_platform_data[0], + .release = device_release, + }, + }, +}; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) +static int swpld_mux_select(struct i2c_adapter *adap, void *data, u8 chan) +{ + uint8_t cmd_data[4]={0}; + struct swpld_mux *mux = data; + uint8_t set_cmd; + int cmd_data_len; + + if ( mux->data.base_nr == BUS9_BASE_NUM ) + { + set_cmd = CMD_SETDATA; + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_PORT_MUX_REG; + cmd_data[3] = chan + 1; + cmd_data_len = sizeof(cmd_data); + return dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + } + else + { + printk(KERN_ERR "Swpld mux QSFP select port error\n"); + return 0; + } +} +#else +static int swpld_mux_select(struct i2c_mux_core *muxc, u32 chan) +{ + uint8_t cmd_data[4]={0}; + struct swpld_mux *mux = i2c_mux_priv(muxc); + uint8_t set_cmd; + int cmd_data_len; + + if ( mux->data.base_nr == BUS9_BASE_NUM ) + { + set_cmd = CMD_SETDATA; + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_PORT_MUX_REG; + cmd_data[3] = chan + 1; + cmd_data_len = sizeof(cmd_data); + return dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + } + else + { + printk(KERN_ERR "Swpld mux QSFP select port error\n"); + return 0; + } + +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) +static int __init swpld_mux_probe(struct platform_device *pdev) +{ + struct swpld_mux *mux; + struct swpld_mux_platform_data *pdata; + struct i2c_adapter *parent; + int i, ret, dev_num; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD platform data not found\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; + } + /* Judge bus number to decide how many devices*/ + switch (pdata->parent) { + case BUS9: + dev_num = BUS9_DEV_NUM; + break; + default : + dev_num = DEFAULT_NUM; + break; + } + + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) { + ret = -ENOMEM; + printk(KERN_ERR "Failed to allocate memory for mux\n"); + goto alloc_failed; + } + + mux->parent = parent; + mux->data = *pdata; + mux->child = kzalloc(sizeof(struct i2c_adapter *) * dev_num, GFP_KERNEL); + if (!mux->child) { + ret = -ENOMEM; + printk(KERN_ERR "Failed to allocate memory for device on mux\n"); + goto alloc_failed2; + } + + for (i = 0; i < dev_num; i++) + { + int nr = pdata->base_nr + i; + unsigned int class = 0; + + mux->child[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, + nr, i, class, + swpld_mux_select, NULL); + if (!mux->child[i]) + { + ret = -ENODEV; + dev_err(&pdev->dev, "Failed to add adapter %d\n", i); + goto add_adapter_failed; + } + } + + platform_set_drvdata(pdev, mux); + return 0; + +add_adapter_failed: + for (; i > 0; i--) + i2c_del_mux_adapter(mux->child[i - 1]); + kfree(mux->child); +alloc_failed2: + kfree(mux); +alloc_failed: + i2c_put_adapter(parent); + + return ret; +} +#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +static int __init swpld_mux_probe(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc; + struct swpld_mux *mux; + struct swpld_mux_platform_data *pdata; + struct i2c_adapter *parent; + int i, ret, dev_num; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD 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 BUS9: + dev_num = BUS9_DEV_NUM; + break; + default : + dev_num = DEFAULT_NUM; + break; + } + + muxc = i2c_mux_alloc(parent, &pdev->dev, dev_num, 0, 0,swpld_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_failed2: + kfree(mux); +alloc_failed: + i2c_put_adapter(parent); + + return ret; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) +static int __exit swpld_mux_remove(struct platform_device *pdev) +{ + int i; + struct swpld_mux *mux = platform_get_drvdata(pdev); + struct swpld_mux_platform_data *pdata; + struct i2c_adapter *parent; + int dev_num; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD platform data not found\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; + } + switch (pdata->parent) { + case BUS9: + dev_num = BUS9_DEV_NUM; + break; + default : + dev_num = DEFAULT_NUM; + break; + } + + for (i = 0; i < dev_num; i++) + i2c_del_mux_adapter(mux->child[i]); + + platform_set_drvdata(pdev, NULL); + i2c_put_adapter(mux->parent); + kfree(mux->child); + kfree(mux); + + return 0; +} +#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +static int __exit swpld_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; +} +#endif + +static struct platform_driver swpld_mux_driver = { + .probe = swpld_mux_probe, + .remove = __exit_p(swpld_mux_remove), /* TODO */ + .driver = { + .owner = THIS_MODULE, + .name = "delta-ag9064-swpld-mux", + }, +}; + +/*---------------- MUX - end ------------- */ + +/*---------------- module initialization ------------- */ + +static int __init delta_ag9064_platform_init(void) +{ +// struct i2c_client *client; + struct i2c_adapter *adapter; + struct swpld_mux_platform_data *swpld_pdata; +// struct cpld_platform_data * cpld_pdata; + int ret,i = 0; + + printk("ag9064_platform module initialization\n"); + + adapter = i2c_get_adapter(BUS2); + i2c_client_9548 = i2c_new_device(adapter, &i2c_info_pca9548[0]); + i2c_put_adapter(adapter); + + ret = dni_create_user(); + if (ret != 0){ + printk(KERN_WARNING "Fail to create IPMI user\n"); + } + + // register the mux prob which call the SWPLD + ret = platform_driver_register(&swpld_mux_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld mux driver\n"); + goto error_swpld_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; + } + + swpld_pdata = ag9064_swpld_mux[0].dev.platform_data; + ret = platform_device_register(&ag9064_swpld_mux[0]); + if (ret) { + printk(KERN_WARNING "Fail to create swpld mux\n"); + goto error_ag9064_swpld_mux; + } + + for (i = 0; i < ARRAY_SIZE(ag9064_i2c_device); i++) + { + ret = platform_device_register(&ag9064_i2c_device[i]); + if (ret) + { + printk(KERN_WARNING "Fail to create i2c device %d\n", i); + goto error_ag9064_i2c_device; + } + } + if (ret) + goto error_ag9064_swpld_mux; + + return 0; + +error_ag9064_i2c_device: + i--; + for (; i >= 0; i--) { + platform_device_unregister(&ag9064_i2c_device[i]); + } + i = ARRAY_SIZE(ag9064_swpld_mux); +error_ag9064_swpld_mux: + platform_device_unregister(&ag9064_swpld_mux[0]); + platform_driver_unregister(&i2c_device_driver); +error_i2c_device_driver: + platform_driver_unregister(&swpld_mux_driver); +error_swpld_mux_driver: + return ret; +} + +static void __exit delta_ag9064_platform_exit(void) +{ + int i = 0; + + for ( i = 0; i < ARRAY_SIZE(ag9064_i2c_device); i++ ) { + platform_device_unregister(&ag9064_i2c_device[i]); + } + + platform_device_unregister(&ag9064_swpld_mux[0]); + platform_driver_unregister(&i2c_device_driver); + platform_driver_unregister(&swpld_mux_driver); + i2c_unregister_device(i2c_client_9548); +} + +module_init(delta_ag9064_platform_init); +module_exit(delta_ag9064_platform_exit); + +MODULE_DESCRIPTION("DELTA ag9064 Platform Support"); +MODULE_AUTHOR("Johnson Lu "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_swpld.c b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_swpld.c index 80a0ddc0d370..cab54a43bb07 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_swpld.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_swpld.c @@ -1,620 +1,623 @@ -#include "delta_ag9064_common.h" - -unsigned char swpld1_reg_addr; -unsigned char swpld2_reg_addr; -unsigned char swpld3_reg_addr; -unsigned char swpld4_reg_addr; - -/*---------------- CPLD - start ------------- */ -/* SWPLD1 -- device */ -static struct platform_device swpld1_device = { - .name = "delta-ag9064-swpld1", - .id = 0, - .dev = { - .platform_data = ag9064_swpld1_platform_data, - .release = device_release - }, -}; - -static struct platform_device swpld2_device = { - .name = "delta-ag9064-swpld2", - .id = 0, - .dev = { - .platform_data = ag9064_swpld2_platform_data, - .release = device_release - }, -}; -static struct platform_device swpld3_device = { - .name = "delta-ag9064-swpld3", - .id = 0, - .dev = { - .platform_data = ag9064_swpld3_platform_data, - .release = device_release - }, -}; -static struct platform_device swpld4_device = { - .name = "delta-ag9064-swpld4", - .id = 0, - .dev = { - .platform_data = ag9064_swpld4_platform_data, - .release = device_release - }, -}; - -static ssize_t get_swpld_reg(struct device *dev, struct device_attribute *dev_attr, char *buf) -{ - int ret; - int mask; - int value; - int cmd_data_len; - char note[200]; - uint8_t cmd_data[4]={0}; - uint8_t get_cmd; - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - - cmd_data_len = sizeof(cmd_data); - get_cmd = CMD_GETDATA; - cmd_data[0] = BMC_BUS_5; - cmd_data[3] = 1; - mask = attribute_data[attr->index].mask; - sprintf(note, "\n%s\n",attribute_data[attr->index].note); - - if (attr->index <= SWPLD4_REG_VALUE){ - switch (attr->index) { - case SWPLD1_REG_ADDR: - return sprintf(buf, "0x%02x\n", swpld1_reg_addr); - case SWPLD2_REG_ADDR: - return sprintf(buf, "0x%02x\n", swpld2_reg_addr); - case SWPLD3_REG_ADDR: - return sprintf(buf, "0x%02x\n", swpld3_reg_addr); - case SWPLD4_REG_ADDR: - return sprintf(buf, "0x%02x\n", swpld4_reg_addr); - case SWPLD1_REG_VALUE: - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = swpld1_reg_addr; - break; - case SWPLD2_REG_VALUE: - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = swpld2_reg_addr; - break; - case SWPLD3_REG_VALUE: - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = swpld3_reg_addr; - break; - case SWPLD4_REG_VALUE: - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = swpld4_reg_addr; - break; - default: - return sprintf(buf, "%d not found", attr->index); - } - ret = dni_bmc_cmd(get_cmd, cmd_data, cmd_data_len); - ret = ret & 0xff; - return sprintf(buf, "0x%02x\n", ret); - }else{ - - switch (attr->index) { - case SWPLD1_MAJOR_VER ... PSU_LED_MODE : - cmd_data[1] = SWPLD1_ADDR; - break; - case SWPLD2_MAJOR_VER ... FAN_MOD4_LED : - cmd_data[1] = SWPLD2_ADDR; - break; - case SWPLD3_MAJOR_VER ... PLATFORM_TYPE : - cmd_data[1] = SWPLD3_ADDR; - break; - case SWPLD4_MAJOR_VER ... FAN_EEPROM_WP : - cmd_data[1] = SWPLD4_ADDR; - break; - default: - return sprintf(buf, "%d not found", attr->index); - } - cmd_data[2] = attribute_data[attr->index].reg; - value = dni_bmc_cmd(get_cmd, cmd_data, cmd_data_len); - value = value & mask; - switch (mask) { - case 0xFF: - return sprintf(buf, "0x%02x%s", value, note); - case 0x0F: - return sprintf(buf, "0x%01x%s", value, note); - case 0xF0: - value = value >> 4; - return sprintf(buf, "0x%01x%s", value, note); - case 0xC0: - value = value >> 6; - return sprintf(buf, "0x%01x%s", value, note); - case 0x30: - value = value >> 4; - return sprintf(buf, "0x%01x%s", value, note); - default : - value = value >> dni_log2(mask); - return sprintf(buf, "%d%s", value, note); - } - } -} - -static ssize_t set_swpld_reg(struct device *dev, struct device_attribute *dev_attr, - const char *buf, size_t count) -{ - int err; - int value; - int set_data; - int cmd_data_len; - uint8_t cmd_data[4]={0}; - uint8_t set_cmd; - uint8_t get_cmd; - unsigned char mask; - unsigned char mask_out; - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - - cmd_data_len = sizeof(cmd_data); - set_cmd = CMD_SETDATA; - get_cmd = CMD_GETDATA; - - err = kstrtoul(buf, 0, &set_data); - if (err){ - return err; - } - - if (set_data > 0xff){ - printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); - return count; - } - if (attr->index <= SWPLD4_REG_VALUE){ - cmd_data[0] = BMC_BUS_5; - cmd_data[3] = set_data; - switch (attr->index) { - //reg_addr - case SWPLD1_REG_ADDR: - swpld1_reg_addr = set_data; - return count; - case SWPLD2_REG_ADDR: - swpld2_reg_addr = set_data; - return count; - case SWPLD3_REG_ADDR: - swpld3_reg_addr = set_data; - return count; - case SWPLD4_REG_ADDR: - swpld4_reg_addr = set_data; - return count; - //reg_value - case SWPLD1_REG_VALUE: - cmd_data[1] = SWPLD1_ADDR; - cmd_data[2] = swpld1_reg_addr; - break; - case SWPLD2_REG_VALUE: - cmd_data[1] = SWPLD2_ADDR; - cmd_data[2] = swpld2_reg_addr; - break; - case SWPLD3_REG_VALUE: - cmd_data[1] = SWPLD3_ADDR; - cmd_data[2] = swpld3_reg_addr; - break; - case SWPLD4_REG_VALUE: - cmd_data[1] = SWPLD4_ADDR; - cmd_data[2] = swpld4_reg_addr; - break; - default : - return sprintf(buf, "%d not found", attr->index); - } - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - return count; - } - else{ - cmd_data[0] = BMC_BUS_5; - cmd_data[2] = attribute_data[attr->index].reg; - cmd_data[3] = 1; - switch (attr->index) { - //attributes - case SWPLD1_MAJOR_VER ... PSU_LED_MODE://SWPLD1 - cmd_data[1] = SWPLD1_ADDR; - break; - case SWPLD2_MAJOR_VER ... FAN_MOD4_LED://SWPLD2 - cmd_data[1] = SWPLD2_ADDR; - break; - case SWPLD3_MAJOR_VER ... PLATFORM_TYPE://SWPLD3 - cmd_data[1] = SWPLD3_ADDR; - break; - case SWPLD4_MAJOR_VER ... FAN_EEPROM_WP://SWPLD4 - cmd_data[1] = SWPLD4_ADDR; - break; - default: - return sprintf(buf, "%d not found", attr->index); - } - - value = dni_bmc_cmd(get_cmd, cmd_data, cmd_data_len); - mask = attribute_data[attr->index].mask; - mask_out = value & ~(mask); - cmd_data[3] = set_data; - switch (mask) { - case 0xFF: - set_data = mask_out | (set_data & mask); - break; - case 0x0F: - set_data = mask_out | (set_data & mask); - break; - case 0xF0: - set_data = set_data << 4; - set_data = mask_out | (set_data & mask); - break; - case 0xC0: - set_data = set_data << 6; - set_data = mask_out | (set_data & mask); - break; - case 0x30: - set_data = set_data << 4; - set_data = mask_out | (set_data & mask); - break; - default : - set_data = mask_out | (set_data << dni_log2(mask) ); - } - dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); - return count; - } -} - -//SWPLD -static SENSOR_DEVICE_ATTR(swpld1_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD1_REG_ADDR); -static SENSOR_DEVICE_ATTR(swpld1_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD1_REG_VALUE); -static SENSOR_DEVICE_ATTR(swpld2_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD2_REG_ADDR); -static SENSOR_DEVICE_ATTR(swpld2_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD2_REG_VALUE); -static SENSOR_DEVICE_ATTR(swpld3_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD3_REG_ADDR); -static SENSOR_DEVICE_ATTR(swpld3_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD3_REG_VALUE); -static SENSOR_DEVICE_ATTR(swpld4_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD4_REG_ADDR); -static SENSOR_DEVICE_ATTR(swpld4_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD4_REG_VALUE); -//SWPLD1 -static SENSOR_DEVICE_ATTR(swpld1_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD1_MAJOR_VER); -static SENSOR_DEVICE_ATTR(swpld1_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD1_MINOR_VER); -static SENSOR_DEVICE_ATTR(swpld1_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD1_SCRTCH_REG); -static SENSOR_DEVICE_ATTR(psu1_pwr_ok, S_IRUGO, get_swpld_reg, NULL, PSU1_PWR_OK); -static SENSOR_DEVICE_ATTR(psu1_int, S_IRUGO, get_swpld_reg, NULL, PSU1_INT); -static SENSOR_DEVICE_ATTR(psu2_pwr_ok, S_IRUGO, get_swpld_reg, NULL, PSU2_PWR_OK); -static SENSOR_DEVICE_ATTR(psu2_int, S_IRUGO, get_swpld_reg, NULL, PSU2_INT); -static SENSOR_DEVICE_ATTR(synce_int, S_IRUGO, get_swpld_reg, NULL, SYNCE_INT); -static SENSOR_DEVICE_ATTR(synce_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYNCE_RST); -static SENSOR_DEVICE_ATTR(synce_eeprom_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYNCE_EEPROM_WP); -static SENSOR_DEVICE_ATTR(psu1_green_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU1_GREEN_LED); -static SENSOR_DEVICE_ATTR(psu1_red_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU1_RED_LED); -static SENSOR_DEVICE_ATTR(psu2_green_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU2_GREEN_LED); -static SENSOR_DEVICE_ATTR(psu2_red_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU2_RED_LED); -static SENSOR_DEVICE_ATTR(psu_led_mode, S_IRUGO, get_swpld_reg, NULL, PSU_LED_MODE); -//SWPLD2 -static SENSOR_DEVICE_ATTR(swpld2_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD2_MAJOR_VER); -static SENSOR_DEVICE_ATTR(swpld2_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD2_MINOR_VER); -static SENSOR_DEVICE_ATTR(swpld2_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD2_SCRTCH_REG); -static SENSOR_DEVICE_ATTR(fan_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_LED); -static SENSOR_DEVICE_ATTR(sys_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYS_LED); -static SENSOR_DEVICE_ATTR(fan_mod1_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_MOD1_LED); -static SENSOR_DEVICE_ATTR(fan_mod2_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_MOD2_LED); -static SENSOR_DEVICE_ATTR(fan_mod3_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_MOD3_LED); -static SENSOR_DEVICE_ATTR(fan_mod4_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_MOD4_LED); -//SWPLD3 -static SENSOR_DEVICE_ATTR(swpld3_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD3_MAJOR_VER); -static SENSOR_DEVICE_ATTR(swpld3_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD3_MINOR_VER); -static SENSOR_DEVICE_ATTR(swpld3_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD3_SCRTCH_REG); -static SENSOR_DEVICE_ATTR(sb_ver, S_IRUGO, get_swpld_reg, NULL, SB_VER); -static SENSOR_DEVICE_ATTR(platform_type, S_IRUGO, get_swpld_reg, NULL, PLATFORM_TYPE); - -//SWPLD4 -static SENSOR_DEVICE_ATTR(swpld4_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD4_MAJOR_VER); -static SENSOR_DEVICE_ATTR(swpld4_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD4_MINOR_VER); -static SENSOR_DEVICE_ATTR(swpld4_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD4_SCRTCH_REG); -static SENSOR_DEVICE_ATTR(bmc_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, BMC_RST); -static SENSOR_DEVICE_ATTR(cpld_lpc_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_LPC_RST); -static SENSOR_DEVICE_ATTR(cpld_sw_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_SW_RST); -static SENSOR_DEVICE_ATTR(mb_cpld_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, MB_CPLD_RST); -static SENSOR_DEVICE_ATTR(bcm56970_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, BCM56970_RST); - -static SENSOR_DEVICE_ATTR(cpld_upgrade_rst, S_IRUGO, get_swpld_reg, NULL, CPLD_UPGRADE_RST); -static SENSOR_DEVICE_ATTR(mb_rst_cpld, S_IRUGO, get_swpld_reg, NULL, MB_RST_CPLD); -static SENSOR_DEVICE_ATTR(cpu_rst_mb_oob, S_IRUGO, get_swpld_reg, NULL, CPU_RST_MB_OOB); -static SENSOR_DEVICE_ATTR(gpio_phy_rst, S_IRUGO, get_swpld_reg, NULL, GPIO_PHY_RST); -static SENSOR_DEVICE_ATTR(psu_fan_event, S_IRUGO, get_swpld_reg, NULL, PSU_FAN_EVENT); -static SENSOR_DEVICE_ATTR(cpu_thermal_int, S_IRUGO, get_swpld_reg, NULL, CPU_THERMAL_INT); -static SENSOR_DEVICE_ATTR(fan_int, S_IRUGO, get_swpld_reg, NULL, FAN_INT); - -static SENSOR_DEVICE_ATTR(cpld_spi_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_SPI_WP); -static SENSOR_DEVICE_ATTR(rj45_console_sel, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, RJ45_CONSOLE_SEL); -static SENSOR_DEVICE_ATTR(system_int, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYSTEM_INT); -static SENSOR_DEVICE_ATTR(cpld_mb_rst_done, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_MB_RST_DONE); -static SENSOR_DEVICE_ATTR(mb_pwr_ok, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, MB_PWR_OK); -static SENSOR_DEVICE_ATTR(fan_eeprom_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_EEPROM_WP); - -static struct attribute *swpld1_device_attrs[] = { - &sensor_dev_attr_swpld1_reg_value.dev_attr.attr, - &sensor_dev_attr_swpld1_reg_addr.dev_attr.attr, - &sensor_dev_attr_swpld1_major_ver.dev_attr.attr, - &sensor_dev_attr_swpld1_minor_ver.dev_attr.attr, - &sensor_dev_attr_swpld1_scrtch_reg.dev_attr.attr, - &sensor_dev_attr_psu1_pwr_ok.dev_attr.attr, - &sensor_dev_attr_psu1_int.dev_attr.attr, - &sensor_dev_attr_psu2_pwr_ok.dev_attr.attr, - &sensor_dev_attr_psu2_int.dev_attr.attr, - &sensor_dev_attr_synce_int.dev_attr.attr, - &sensor_dev_attr_synce_rst.dev_attr.attr, - &sensor_dev_attr_synce_eeprom_wp.dev_attr.attr, - &sensor_dev_attr_psu1_green_led.dev_attr.attr, - &sensor_dev_attr_psu1_red_led.dev_attr.attr, - &sensor_dev_attr_psu2_green_led.dev_attr.attr, - &sensor_dev_attr_psu2_red_led.dev_attr.attr, - &sensor_dev_attr_psu_led_mode.dev_attr.attr, - NULL, -}; - -static struct attribute *swpld2_device_attrs[] = { - &sensor_dev_attr_swpld2_reg_value.dev_attr.attr, - &sensor_dev_attr_swpld2_reg_addr.dev_attr.attr, - &sensor_dev_attr_swpld2_major_ver.dev_attr.attr, - &sensor_dev_attr_swpld2_minor_ver.dev_attr.attr, - &sensor_dev_attr_swpld2_scrtch_reg.dev_attr.attr, - &sensor_dev_attr_fan_led.dev_attr.attr, - &sensor_dev_attr_sys_led.dev_attr.attr, - &sensor_dev_attr_fan_mod1_led.dev_attr.attr, - &sensor_dev_attr_fan_mod2_led.dev_attr.attr, - &sensor_dev_attr_fan_mod3_led.dev_attr.attr, - &sensor_dev_attr_fan_mod4_led.dev_attr.attr, - NULL, -}; - -static struct attribute *swpld3_device_attrs[] = { - &sensor_dev_attr_swpld3_reg_value.dev_attr.attr, - &sensor_dev_attr_swpld3_reg_addr.dev_attr.attr, - &sensor_dev_attr_swpld3_major_ver.dev_attr.attr, - &sensor_dev_attr_swpld3_minor_ver.dev_attr.attr, - &sensor_dev_attr_swpld3_scrtch_reg.dev_attr.attr, - &sensor_dev_attr_sb_ver.dev_attr.attr, - &sensor_dev_attr_platform_type.dev_attr.attr, - NULL, -}; - -static struct attribute *swpld4_device_attrs[] = { - &sensor_dev_attr_swpld4_reg_value.dev_attr.attr, - &sensor_dev_attr_swpld4_reg_addr.dev_attr.attr, - &sensor_dev_attr_swpld4_major_ver.dev_attr.attr, - &sensor_dev_attr_swpld4_minor_ver.dev_attr.attr, - &sensor_dev_attr_swpld4_scrtch_reg.dev_attr.attr, - &sensor_dev_attr_bmc_rst.dev_attr.attr, - &sensor_dev_attr_cpld_lpc_rst.dev_attr.attr, - &sensor_dev_attr_cpld_sw_rst.dev_attr.attr, - &sensor_dev_attr_mb_cpld_rst.dev_attr.attr, - &sensor_dev_attr_bcm56970_rst.dev_attr.attr, - &sensor_dev_attr_cpld_upgrade_rst.dev_attr.attr, - &sensor_dev_attr_mb_rst_cpld.dev_attr.attr, - &sensor_dev_attr_cpu_rst_mb_oob.dev_attr.attr, - &sensor_dev_attr_gpio_phy_rst.dev_attr.attr, - &sensor_dev_attr_psu_fan_event.dev_attr.attr, - &sensor_dev_attr_cpu_thermal_int.dev_attr.attr, - &sensor_dev_attr_fan_int.dev_attr.attr, - &sensor_dev_attr_cpld_spi_wp.dev_attr.attr, - &sensor_dev_attr_rj45_console_sel.dev_attr.attr, - &sensor_dev_attr_system_int.dev_attr.attr, - &sensor_dev_attr_cpld_mb_rst_done.dev_attr.attr, - &sensor_dev_attr_mb_pwr_ok.dev_attr.attr, - &sensor_dev_attr_fan_eeprom_wp.dev_attr.attr, - NULL, -}; - -static struct attribute_group swpld1_device_attr_grp = { - .attrs = swpld1_device_attrs, -}; - -static struct attribute_group swpld2_device_attr_grp = { - .attrs = swpld2_device_attrs, -}; - -static struct attribute_group swpld3_device_attr_grp = { - .attrs = swpld3_device_attrs, -}; - -static struct attribute_group swpld4_device_attr_grp = { - .attrs = swpld4_device_attrs, -}; - -static int __init swpld1_probe(struct platform_device *pdev) -{ - int ret; - ret = sysfs_create_group(&pdev->dev.kobj, &swpld1_device_attr_grp); - if (ret) { - printk(KERN_WARNING "Fail to create cpld attribute group"); - return -ENODEV; - } - return 0; -} - -static int __init swpld2_probe(struct platform_device *pdev) -{ - int ret; - ret = sysfs_create_group(&pdev->dev.kobj, &swpld2_device_attr_grp); - if (ret) { - printk(KERN_WARNING "Fail to create cpld attribute group"); - return -ENODEV; - } - return 0; -} - -static int __init swpld3_probe(struct platform_device *pdev) -{ - int ret; - ret = sysfs_create_group(&pdev->dev.kobj, &swpld3_device_attr_grp); - if (ret) { - printk(KERN_WARNING "Fail to create cpld attribute group"); - return -ENODEV; - } - return 0; -} - -static int __init swpld4_probe(struct platform_device *pdev) -{ - int ret; - ret = sysfs_create_group(&pdev->dev.kobj, &swpld4_device_attr_grp); - if (ret) { - printk(KERN_WARNING "Fail to create cpld attribute group"); - return -ENODEV; - } - return 0; -} - -static int __exit swpld1_remove(struct platform_device *pdev) -{ - sysfs_remove_group(&pdev->dev.kobj, &swpld1_device_attr_grp); - return 0; -} - -static int __exit swpld2_remove(struct platform_device *pdev) -{ - sysfs_remove_group(&pdev->dev.kobj, &swpld2_device_attr_grp); - return 0; -} - -static int __exit swpld3_remove(struct platform_device *pdev) -{ - sysfs_remove_group(&pdev->dev.kobj, &swpld3_device_attr_grp); - return 0; -} - -static int __exit swpld4_remove(struct platform_device *pdev) -{ - sysfs_remove_group(&pdev->dev.kobj, &swpld4_device_attr_grp); - return 0; -} - -static struct platform_driver swpld1_driver = { - .probe = swpld1_probe, - .remove = __exit_p(swpld1_remove), - .driver = { - .owner = THIS_MODULE, - .name = "delta-ag9064-swpld1", - }, -}; - -static struct platform_driver swpld2_driver = { - .probe = swpld2_probe, - .remove = __exit_p(swpld2_remove), - .driver = { - .owner = THIS_MODULE, - .name = "delta-ag9064-swpld2", - }, -}; - -static struct platform_driver swpld3_driver = { - .probe = swpld3_probe, - .remove = __exit_p(swpld3_remove), - .driver = { - .owner = THIS_MODULE, - .name = "delta-ag9064-swpld3", - }, -}; - -static struct platform_driver swpld4_driver = { - .probe = swpld4_probe, - .remove = __exit_p(swpld4_remove), - .driver = { - .owner = THIS_MODULE, - .name = "delta-ag9064-swpld4", - }, -}; -/*---------------- CPLD - end ------------- */ - -/*---------------- module initialization ------------- */ -static void __init delta_ag9064_swpld_init(void) -{ - int ret; - printk(KERN_WARNING "ag9064_platform_swpld module initialization\n"); - - ret = dni_create_user(); - if (ret != 0){ - printk(KERN_WARNING "Fail to create IPMI user\n"); - } - - // 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; - } - - // register the SWPLD - ret = platform_device_register(&swpld1_device); - if (ret) { - printk(KERN_WARNING "Fail to create swpld device\n"); - goto error_swpld1_device; - } - - // 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; - } - - // register the SWPLD - ret = platform_device_register(&swpld2_device); - if (ret) { - printk(KERN_WARNING "Fail to create swpld device\n"); - goto error_swpld2_device; - } - - // 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 SWPLD - ret = platform_device_register(&swpld3_device); - if (ret) { - printk(KERN_WARNING "Fail to create swpld device\n"); - goto error_swpld3_device; - } - - // set the SWPLD prob and remove - ret = platform_driver_register(&swpld4_driver); - if (ret) { - printk(KERN_WARNING "Fail to register swpld driver\n"); - goto error_swpld4_driver; - } - - // register the SWPLD - ret = platform_device_register(&swpld4_device); - if (ret) { - printk(KERN_WARNING "Fail to create swpld device\n"); - goto error_swpld4_device; - } - return 0; - -error_swpld4_device: - platform_driver_unregister(&swpld4_driver); -error_swpld4_driver: - platform_driver_unregister(&swpld3_device); -error_swpld3_device: - platform_driver_unregister(&swpld3_driver); -error_swpld3_driver: - platform_driver_unregister(&swpld2_device); -error_swpld2_device: - platform_driver_unregister(&swpld2_driver); -error_swpld2_driver: - platform_driver_unregister(&swpld1_device); -error_swpld1_device: - platform_driver_unregister(&swpld1_driver); -error_swpld1_driver: - return ret; -} - -static void __exit delta_ag9064_swpld_exit(void) -{ - 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); - platform_device_unregister(&swpld4_device); - platform_driver_unregister(&swpld4_driver); -} -module_init(delta_ag9064_swpld_init); -module_exit(delta_ag9064_swpld_exit); - -MODULE_DESCRIPTION("DNI ag9064 CPLD Platform Support"); -MODULE_AUTHOR("Stanley Chi "); -MODULE_LICENSE("GPL"); \ No newline at end of file +#include "delta_ag9064_common.h" + +unsigned char swpld1_reg_addr; +unsigned char swpld2_reg_addr; +unsigned char swpld3_reg_addr; +unsigned char swpld4_reg_addr; + +/*---------------- CPLD - start ------------- */ +/* SWPLD1 -- device */ +static struct platform_device swpld1_device = { + .name = "delta-ag9064-swpld1", + .id = 0, + .dev = { + .platform_data = ag9064_swpld1_platform_data, + .release = device_release + }, +}; + +static struct platform_device swpld2_device = { + .name = "delta-ag9064-swpld2", + .id = 0, + .dev = { + .platform_data = ag9064_swpld2_platform_data, + .release = device_release + }, +}; +static struct platform_device swpld3_device = { + .name = "delta-ag9064-swpld3", + .id = 0, + .dev = { + .platform_data = ag9064_swpld3_platform_data, + .release = device_release + }, +}; +static struct platform_device swpld4_device = { + .name = "delta-ag9064-swpld4", + .id = 0, + .dev = { + .platform_data = ag9064_swpld4_platform_data, + .release = device_release + }, +}; + +static ssize_t get_swpld_reg(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + int ret; + int mask; + int value; + int cmd_data_len; + char note[200]; + uint8_t cmd_data[4]={0}; + uint8_t get_cmd; + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + + cmd_data_len = sizeof(cmd_data); + get_cmd = CMD_GETDATA; + cmd_data[0] = BMC_BUS_5; + cmd_data[3] = 1; + mask = attribute_data[attr->index].mask; + sprintf(note, "\n%s\n",attribute_data[attr->index].note); + + if (attr->index <= SWPLD4_REG_VALUE){ + switch (attr->index) { + case SWPLD1_REG_ADDR: + return sprintf(buf, "0x%02x\n", swpld1_reg_addr); + case SWPLD2_REG_ADDR: + return sprintf(buf, "0x%02x\n", swpld2_reg_addr); + case SWPLD3_REG_ADDR: + return sprintf(buf, "0x%02x\n", swpld3_reg_addr); + case SWPLD4_REG_ADDR: + return sprintf(buf, "0x%02x\n", swpld4_reg_addr); + case SWPLD1_REG_VALUE: + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = swpld1_reg_addr; + break; + case SWPLD2_REG_VALUE: + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = swpld2_reg_addr; + break; + case SWPLD3_REG_VALUE: + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = swpld3_reg_addr; + break; + case SWPLD4_REG_VALUE: + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = swpld4_reg_addr; + break; + default: + return sprintf(buf, "%d not found", attr->index); + } + ret = dni_bmc_cmd(get_cmd, cmd_data, cmd_data_len); + ret = ret & 0xff; + return sprintf(buf, "0x%02x\n", ret); + }else{ + + switch (attr->index) { + case SWPLD1_MAJOR_VER ... PSU_LED_MODE : + cmd_data[1] = SWPLD1_ADDR; + break; + case SWPLD2_MAJOR_VER ... FAN_MOD4_LED : + cmd_data[1] = SWPLD2_ADDR; + break; + case SWPLD3_MAJOR_VER ... PLATFORM_TYPE : + cmd_data[1] = SWPLD3_ADDR; + break; + case SWPLD4_MAJOR_VER ... FAN_EEPROM_WP : + cmd_data[1] = SWPLD4_ADDR; + break; + default: + return sprintf(buf, "%d not found", attr->index); + } + cmd_data[2] = attribute_data[attr->index].reg; + value = dni_bmc_cmd(get_cmd, cmd_data, cmd_data_len); + value = value & mask; + switch (mask) { + case 0xFF: + return sprintf(buf, "0x%02x%s", value, note); + case 0x0F: + return sprintf(buf, "0x%01x%s", value, note); + case 0xF0: + value = value >> 4; + return sprintf(buf, "0x%01x%s", value, note); + case 0xC0: + value = value >> 6; + return sprintf(buf, "0x%01x%s", value, note); + case 0x30: + value = value >> 4; + return sprintf(buf, "0x%01x%s", value, note); + default : + value = value >> dni_log2(mask); + return sprintf(buf, "%d%s", value, note); + } + } +} + +static ssize_t set_swpld_reg(struct device *dev, struct device_attribute *dev_attr, + const char *buf, size_t count) +{ + int err; + int value; + int set_data; + int cmd_data_len; + uint8_t cmd_data[4]={0}; + uint8_t set_cmd; + uint8_t get_cmd; + unsigned long set_data_ul; + unsigned char mask; + unsigned char mask_out; + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + + cmd_data_len = sizeof(cmd_data); + set_cmd = CMD_SETDATA; + get_cmd = CMD_GETDATA; + + err = kstrtoul(buf, 0, &set_data_ul); + if (err){ + return err; + } + + if (set_data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + set_data = (int)set_data_ul; + if (attr->index <= SWPLD4_REG_VALUE){ + cmd_data[0] = BMC_BUS_5; + cmd_data[3] = set_data; + switch (attr->index) { + //reg_addr + case SWPLD1_REG_ADDR: + swpld1_reg_addr = set_data; + return count; + case SWPLD2_REG_ADDR: + swpld2_reg_addr = set_data; + return count; + case SWPLD3_REG_ADDR: + swpld3_reg_addr = set_data; + return count; + case SWPLD4_REG_ADDR: + swpld4_reg_addr = set_data; + return count; + //reg_value + case SWPLD1_REG_VALUE: + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = swpld1_reg_addr; + break; + case SWPLD2_REG_VALUE: + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = swpld2_reg_addr; + break; + case SWPLD3_REG_VALUE: + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = swpld3_reg_addr; + break; + case SWPLD4_REG_VALUE: + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = swpld4_reg_addr; + break; + default : + return sprintf(buf, "%d not found", attr->index); + } + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + return count; + } + else{ + cmd_data[0] = BMC_BUS_5; + cmd_data[2] = attribute_data[attr->index].reg; + cmd_data[3] = 1; + switch (attr->index) { + //attributes + case SWPLD1_MAJOR_VER ... PSU_LED_MODE://SWPLD1 + cmd_data[1] = SWPLD1_ADDR; + break; + case SWPLD2_MAJOR_VER ... FAN_MOD4_LED://SWPLD2 + cmd_data[1] = SWPLD2_ADDR; + break; + case SWPLD3_MAJOR_VER ... PLATFORM_TYPE://SWPLD3 + cmd_data[1] = SWPLD3_ADDR; + break; + case SWPLD4_MAJOR_VER ... FAN_EEPROM_WP://SWPLD4 + cmd_data[1] = SWPLD4_ADDR; + break; + default: + return sprintf(buf, "%d not found", attr->index); + } + + value = dni_bmc_cmd(get_cmd, cmd_data, cmd_data_len); + mask = attribute_data[attr->index].mask; + mask_out = value & ~(mask); + cmd_data[3] = set_data; + switch (mask) { + case 0xFF: + set_data = mask_out | (set_data & mask); + break; + case 0x0F: + set_data = mask_out | (set_data & mask); + break; + case 0xF0: + set_data = set_data << 4; + set_data = mask_out | (set_data & mask); + break; + case 0xC0: + set_data = set_data << 6; + set_data = mask_out | (set_data & mask); + break; + case 0x30: + set_data = set_data << 4; + set_data = mask_out | (set_data & mask); + break; + default : + set_data = mask_out | (set_data << dni_log2(mask) ); + } + dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + return count; + } +} + +//SWPLD +static SENSOR_DEVICE_ATTR(swpld1_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD1_REG_ADDR); +static SENSOR_DEVICE_ATTR(swpld1_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD1_REG_VALUE); +static SENSOR_DEVICE_ATTR(swpld2_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD2_REG_ADDR); +static SENSOR_DEVICE_ATTR(swpld2_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD2_REG_VALUE); +static SENSOR_DEVICE_ATTR(swpld3_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD3_REG_ADDR); +static SENSOR_DEVICE_ATTR(swpld3_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD3_REG_VALUE); +static SENSOR_DEVICE_ATTR(swpld4_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD4_REG_ADDR); +static SENSOR_DEVICE_ATTR(swpld4_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD4_REG_VALUE); +//SWPLD1 +static SENSOR_DEVICE_ATTR(swpld1_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD1_MAJOR_VER); +static SENSOR_DEVICE_ATTR(swpld1_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD1_MINOR_VER); +static SENSOR_DEVICE_ATTR(swpld1_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD1_SCRTCH_REG); +static SENSOR_DEVICE_ATTR(psu1_pwr_ok, S_IRUGO, get_swpld_reg, NULL, PSU1_PWR_OK); +static SENSOR_DEVICE_ATTR(psu1_int, S_IRUGO, get_swpld_reg, NULL, PSU1_INT); +static SENSOR_DEVICE_ATTR(psu2_pwr_ok, S_IRUGO, get_swpld_reg, NULL, PSU2_PWR_OK); +static SENSOR_DEVICE_ATTR(psu2_int, S_IRUGO, get_swpld_reg, NULL, PSU2_INT); +static SENSOR_DEVICE_ATTR(synce_int, S_IRUGO, get_swpld_reg, NULL, SYNCE_INT); +static SENSOR_DEVICE_ATTR(synce_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYNCE_RST); +static SENSOR_DEVICE_ATTR(synce_eeprom_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYNCE_EEPROM_WP); +static SENSOR_DEVICE_ATTR(psu1_green_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU1_GREEN_LED); +static SENSOR_DEVICE_ATTR(psu1_red_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU1_RED_LED); +static SENSOR_DEVICE_ATTR(psu2_green_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU2_GREEN_LED); +static SENSOR_DEVICE_ATTR(psu2_red_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, PSU2_RED_LED); +static SENSOR_DEVICE_ATTR(psu_led_mode, S_IRUGO, get_swpld_reg, NULL, PSU_LED_MODE); +//SWPLD2 +static SENSOR_DEVICE_ATTR(swpld2_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD2_MAJOR_VER); +static SENSOR_DEVICE_ATTR(swpld2_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD2_MINOR_VER); +static SENSOR_DEVICE_ATTR(swpld2_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD2_SCRTCH_REG); +static SENSOR_DEVICE_ATTR(fan_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_LED); +static SENSOR_DEVICE_ATTR(sys_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYS_LED); +static SENSOR_DEVICE_ATTR(fan_mod1_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_MOD1_LED); +static SENSOR_DEVICE_ATTR(fan_mod2_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_MOD2_LED); +static SENSOR_DEVICE_ATTR(fan_mod3_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_MOD3_LED); +static SENSOR_DEVICE_ATTR(fan_mod4_led, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_MOD4_LED); +//SWPLD3 +static SENSOR_DEVICE_ATTR(swpld3_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD3_MAJOR_VER); +static SENSOR_DEVICE_ATTR(swpld3_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD3_MINOR_VER); +static SENSOR_DEVICE_ATTR(swpld3_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD3_SCRTCH_REG); +static SENSOR_DEVICE_ATTR(sb_ver, S_IRUGO, get_swpld_reg, NULL, SB_VER); +static SENSOR_DEVICE_ATTR(platform_type, S_IRUGO, get_swpld_reg, NULL, PLATFORM_TYPE); + +//SWPLD4 +static SENSOR_DEVICE_ATTR(swpld4_major_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD4_MAJOR_VER); +static SENSOR_DEVICE_ATTR(swpld4_minor_ver, S_IRUGO, get_swpld_reg, NULL, SWPLD4_MINOR_VER); +static SENSOR_DEVICE_ATTR(swpld4_scrtch_reg, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SWPLD4_SCRTCH_REG); +static SENSOR_DEVICE_ATTR(bmc_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, BMC_RST); +static SENSOR_DEVICE_ATTR(cpld_lpc_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_LPC_RST); +static SENSOR_DEVICE_ATTR(cpld_sw_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_SW_RST); +static SENSOR_DEVICE_ATTR(mb_cpld_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, MB_CPLD_RST); +static SENSOR_DEVICE_ATTR(bcm56970_rst, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, BCM56970_RST); + +static SENSOR_DEVICE_ATTR(cpld_upgrade_rst, S_IRUGO, get_swpld_reg, NULL, CPLD_UPGRADE_RST); +static SENSOR_DEVICE_ATTR(mb_rst_cpld, S_IRUGO, get_swpld_reg, NULL, MB_RST_CPLD); +static SENSOR_DEVICE_ATTR(cpu_rst_mb_oob, S_IRUGO, get_swpld_reg, NULL, CPU_RST_MB_OOB); +static SENSOR_DEVICE_ATTR(gpio_phy_rst, S_IRUGO, get_swpld_reg, NULL, GPIO_PHY_RST); +static SENSOR_DEVICE_ATTR(psu_fan_event, S_IRUGO, get_swpld_reg, NULL, PSU_FAN_EVENT); +static SENSOR_DEVICE_ATTR(cpu_thermal_int, S_IRUGO, get_swpld_reg, NULL, CPU_THERMAL_INT); +static SENSOR_DEVICE_ATTR(fan_int, S_IRUGO, get_swpld_reg, NULL, FAN_INT); + +static SENSOR_DEVICE_ATTR(cpld_spi_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_SPI_WP); +static SENSOR_DEVICE_ATTR(rj45_console_sel, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, RJ45_CONSOLE_SEL); +static SENSOR_DEVICE_ATTR(system_int, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, SYSTEM_INT); +static SENSOR_DEVICE_ATTR(cpld_mb_rst_done, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, CPLD_MB_RST_DONE); +static SENSOR_DEVICE_ATTR(mb_pwr_ok, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, MB_PWR_OK); +static SENSOR_DEVICE_ATTR(fan_eeprom_wp, S_IRUGO | S_IWUSR, get_swpld_reg, set_swpld_reg, FAN_EEPROM_WP); + +static struct attribute *swpld1_device_attrs[] = { + &sensor_dev_attr_swpld1_reg_value.dev_attr.attr, + &sensor_dev_attr_swpld1_reg_addr.dev_attr.attr, + &sensor_dev_attr_swpld1_major_ver.dev_attr.attr, + &sensor_dev_attr_swpld1_minor_ver.dev_attr.attr, + &sensor_dev_attr_swpld1_scrtch_reg.dev_attr.attr, + &sensor_dev_attr_psu1_pwr_ok.dev_attr.attr, + &sensor_dev_attr_psu1_int.dev_attr.attr, + &sensor_dev_attr_psu2_pwr_ok.dev_attr.attr, + &sensor_dev_attr_psu2_int.dev_attr.attr, + &sensor_dev_attr_synce_int.dev_attr.attr, + &sensor_dev_attr_synce_rst.dev_attr.attr, + &sensor_dev_attr_synce_eeprom_wp.dev_attr.attr, + &sensor_dev_attr_psu1_green_led.dev_attr.attr, + &sensor_dev_attr_psu1_red_led.dev_attr.attr, + &sensor_dev_attr_psu2_green_led.dev_attr.attr, + &sensor_dev_attr_psu2_red_led.dev_attr.attr, + &sensor_dev_attr_psu_led_mode.dev_attr.attr, + NULL, +}; + +static struct attribute *swpld2_device_attrs[] = { + &sensor_dev_attr_swpld2_reg_value.dev_attr.attr, + &sensor_dev_attr_swpld2_reg_addr.dev_attr.attr, + &sensor_dev_attr_swpld2_major_ver.dev_attr.attr, + &sensor_dev_attr_swpld2_minor_ver.dev_attr.attr, + &sensor_dev_attr_swpld2_scrtch_reg.dev_attr.attr, + &sensor_dev_attr_fan_led.dev_attr.attr, + &sensor_dev_attr_sys_led.dev_attr.attr, + &sensor_dev_attr_fan_mod1_led.dev_attr.attr, + &sensor_dev_attr_fan_mod2_led.dev_attr.attr, + &sensor_dev_attr_fan_mod3_led.dev_attr.attr, + &sensor_dev_attr_fan_mod4_led.dev_attr.attr, + NULL, +}; + +static struct attribute *swpld3_device_attrs[] = { + &sensor_dev_attr_swpld3_reg_value.dev_attr.attr, + &sensor_dev_attr_swpld3_reg_addr.dev_attr.attr, + &sensor_dev_attr_swpld3_major_ver.dev_attr.attr, + &sensor_dev_attr_swpld3_minor_ver.dev_attr.attr, + &sensor_dev_attr_swpld3_scrtch_reg.dev_attr.attr, + &sensor_dev_attr_sb_ver.dev_attr.attr, + &sensor_dev_attr_platform_type.dev_attr.attr, + NULL, +}; + +static struct attribute *swpld4_device_attrs[] = { + &sensor_dev_attr_swpld4_reg_value.dev_attr.attr, + &sensor_dev_attr_swpld4_reg_addr.dev_attr.attr, + &sensor_dev_attr_swpld4_major_ver.dev_attr.attr, + &sensor_dev_attr_swpld4_minor_ver.dev_attr.attr, + &sensor_dev_attr_swpld4_scrtch_reg.dev_attr.attr, + &sensor_dev_attr_bmc_rst.dev_attr.attr, + &sensor_dev_attr_cpld_lpc_rst.dev_attr.attr, + &sensor_dev_attr_cpld_sw_rst.dev_attr.attr, + &sensor_dev_attr_mb_cpld_rst.dev_attr.attr, + &sensor_dev_attr_bcm56970_rst.dev_attr.attr, + &sensor_dev_attr_cpld_upgrade_rst.dev_attr.attr, + &sensor_dev_attr_mb_rst_cpld.dev_attr.attr, + &sensor_dev_attr_cpu_rst_mb_oob.dev_attr.attr, + &sensor_dev_attr_gpio_phy_rst.dev_attr.attr, + &sensor_dev_attr_psu_fan_event.dev_attr.attr, + &sensor_dev_attr_cpu_thermal_int.dev_attr.attr, + &sensor_dev_attr_fan_int.dev_attr.attr, + &sensor_dev_attr_cpld_spi_wp.dev_attr.attr, + &sensor_dev_attr_rj45_console_sel.dev_attr.attr, + &sensor_dev_attr_system_int.dev_attr.attr, + &sensor_dev_attr_cpld_mb_rst_done.dev_attr.attr, + &sensor_dev_attr_mb_pwr_ok.dev_attr.attr, + &sensor_dev_attr_fan_eeprom_wp.dev_attr.attr, + NULL, +}; + +static struct attribute_group swpld1_device_attr_grp = { + .attrs = swpld1_device_attrs, +}; + +static struct attribute_group swpld2_device_attr_grp = { + .attrs = swpld2_device_attrs, +}; + +static struct attribute_group swpld3_device_attr_grp = { + .attrs = swpld3_device_attrs, +}; + +static struct attribute_group swpld4_device_attr_grp = { + .attrs = swpld4_device_attrs, +}; + +static int __init swpld1_probe(struct platform_device *pdev) +{ + int ret; + ret = sysfs_create_group(&pdev->dev.kobj, &swpld1_device_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + return -ENODEV; + } + return 0; +} + +static int __init swpld2_probe(struct platform_device *pdev) +{ + int ret; + ret = sysfs_create_group(&pdev->dev.kobj, &swpld2_device_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + return -ENODEV; + } + return 0; +} + +static int __init swpld3_probe(struct platform_device *pdev) +{ + int ret; + ret = sysfs_create_group(&pdev->dev.kobj, &swpld3_device_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + return -ENODEV; + } + return 0; +} + +static int __init swpld4_probe(struct platform_device *pdev) +{ + int ret; + ret = sysfs_create_group(&pdev->dev.kobj, &swpld4_device_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + return -ENODEV; + } + return 0; +} + +static int __exit swpld1_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &swpld1_device_attr_grp); + return 0; +} + +static int __exit swpld2_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &swpld2_device_attr_grp); + return 0; +} + +static int __exit swpld3_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &swpld3_device_attr_grp); + return 0; +} + +static int __exit swpld4_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &swpld4_device_attr_grp); + return 0; +} + +static struct platform_driver swpld1_driver = { + .probe = swpld1_probe, + .remove = __exit_p(swpld1_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-ag9064-swpld1", + }, +}; + +static struct platform_driver swpld2_driver = { + .probe = swpld2_probe, + .remove = __exit_p(swpld2_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-ag9064-swpld2", + }, +}; + +static struct platform_driver swpld3_driver = { + .probe = swpld3_probe, + .remove = __exit_p(swpld3_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-ag9064-swpld3", + }, +}; + +static struct platform_driver swpld4_driver = { + .probe = swpld4_probe, + .remove = __exit_p(swpld4_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-ag9064-swpld4", + }, +}; +/*---------------- CPLD - end ------------- */ + +/*---------------- module initialization ------------- */ +static int __init delta_ag9064_swpld_init(void) +{ + int ret; + printk(KERN_WARNING "ag9064_platform_swpld module initialization\n"); + + ret = dni_create_user(); + if (ret != 0){ + printk(KERN_WARNING "Fail to create IPMI user\n"); + } + + // 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; + } + + // register the SWPLD + ret = platform_device_register(&swpld1_device); + if (ret) { + printk(KERN_WARNING "Fail to create swpld device\n"); + goto error_swpld1_device; + } + + // 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; + } + + // register the SWPLD + ret = platform_device_register(&swpld2_device); + if (ret) { + printk(KERN_WARNING "Fail to create swpld device\n"); + goto error_swpld2_device; + } + + // 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 SWPLD + ret = platform_device_register(&swpld3_device); + if (ret) { + printk(KERN_WARNING "Fail to create swpld device\n"); + goto error_swpld3_device; + } + + // set the SWPLD prob and remove + ret = platform_driver_register(&swpld4_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld driver\n"); + goto error_swpld4_driver; + } + + // register the SWPLD + ret = platform_device_register(&swpld4_device); + if (ret) { + printk(KERN_WARNING "Fail to create swpld device\n"); + goto error_swpld4_device; + } + return 0; + +error_swpld4_device: + platform_driver_unregister(&swpld4_driver); +error_swpld4_driver: + platform_device_unregister(&swpld3_device); +error_swpld3_device: + platform_driver_unregister(&swpld3_driver); +error_swpld3_driver: + platform_device_unregister(&swpld2_device); +error_swpld2_device: + platform_driver_unregister(&swpld2_driver); +error_swpld2_driver: + platform_device_unregister(&swpld1_device); +error_swpld1_device: + platform_driver_unregister(&swpld1_driver); +error_swpld1_driver: + return ret; +} + +static void __exit delta_ag9064_swpld_exit(void) +{ + 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); + platform_device_unregister(&swpld4_device); + platform_driver_unregister(&swpld4_driver); +} +module_init(delta_ag9064_swpld_init); +module_exit(delta_ag9064_swpld_exit); + +MODULE_DESCRIPTION("DNI ag9064 CPLD Platform Support"); +MODULE_AUTHOR("Stanley Chi "); +MODULE_LICENSE("GPL");