diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/Makefile b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/Makefile index 53589d555416..124e0ff5b820 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/Makefile @@ -1,4 +1,6 @@ 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 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 new file mode 100644 index 000000000000..f30081a8829e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_common.h @@ -0,0 +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." + }, +}; \ 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 new file mode 100644 index 000000000000..0db05d967ccf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_cpld.c @@ -0,0 +1,860 @@ +#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 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 df0b47037e12..38fb82d443c7 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,86 +1,14 @@ -#include -#include -#include -#include #include #include #include #include #include -#include -#include #include #include #include #include -#include - -#include -#include -#include -#include - -#define DEFAULT_NUM 1 -#define BUS9_DEV_NUM 64 -#define BUS9_BASE_NUM 20 - -#define IPMI_MAX_INTF (4) -#define DELTA_NETFN 0x38 -#define BMC_BUS_5 0x04 -#define CMD_SETDATA 0x3 -#define CMD_GETDATA 0x2 - -#define CPLD_REG 0x31 -#define SWPLD1_ADDR 0x35 -#define SWPLD2_ADDR 0x34 -#define SWPLD3_ADDR 0x33 -#define SWPLD4_ADDR 0x32 -#define QSFP_PORT_MUX_REG 0x13 - -#define QSFP_PRESENCE_1 0x3 -#define QSFP_PRESENCE_2 0x3 -#define QSFP_PRESENCE_3 0x24 -#define QSFP_PRESENCE_4 0x24 -#define QSFP_PRESENCE_5 0x4 -#define QSFP_PRESENCE_6 0x4 -#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 + +#include "delta_ag9064_common.h" #define SFF8436_INFO(data) \ .type = "sff8436", .addr = 0x50, .platform_data = (data) @@ -97,56 +25,8 @@ }, \ } - -static 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; -} - -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 void dummy_smi_free(struct ipmi_smi_msg *msg) -{ - atomic_dec(&dummy_count); -} -static void dummy_recv_free(struct ipmi_recv_msg *msg) -{ - atomic_dec(&dummy_count); -} -static struct ipmi_smi_msg halt_smi_msg = { - .done = dummy_smi_free -}; -static struct ipmi_recv_msg halt_recv_msg = { - .done = dummy_recv_free -}; - struct i2c_client * i2c_client_9548; -enum{ - BUS0 = 0, - BUS1, - BUS2, - BUS3, - BUS4, - BUS5, - BUS6, - BUS7, - BUS8, - BUS9, - BUS10, - BUS11, - BUS12, - BUS13, - BUS14, -}; - /* pca9548 - add 8 bus */ static struct pca954x_platform_mode pca954x_mode[] = { @@ -265,8 +145,45 @@ static struct sff_8436_platform_data sff_8436_port[] = { { SFF_8346_PORT() }, }; -/*---------------- IPMI - start ------------- */ +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; @@ -281,6 +198,7 @@ int dni_create_user(void) return rv; } } +EXPORT_SYMBOL(dni_create_user); int dni_bmc_cmd(char set_cmd, char *cmd_data, int cmd_data_len) { @@ -299,7 +217,7 @@ int dni_bmc_cmd(char set_cmd, char *cmd_data, int cmd_data_len) msg.data = cmd_data; init_completion(&comp); - rv = ipmi_request_supply_msgs(ipmi_mh_user, (struct ipmi_addr*)&addr, 0,&msg, &comp, &halt_smi_msg, &halt_recv_msg, 0); + rv = ipmi_request_supply_msgs(ipmi_mh_user, (struct ipmi_addr*)&addr, 0, &msg, &comp, &halt_smi_msg, &halt_recv_msg, 0); if (rv) { return -6; } @@ -334,16 +252,11 @@ int dni_bmc_cmd(char set_cmd, char *cmd_data, int cmd_data_len) return rv; } - +EXPORT_SYMBOL(dni_bmc_cmd); /*---------------- IPMI - stop ------------- */ /*---------------- I2C device - start ------------- */ -static void device_release(struct device *dev) -{ - return; -} - struct i2c_device_platform_data { int parent; struct i2c_board_info info; @@ -1014,7 +927,6 @@ static int __init swpld_mux_probe(struct platform_device *pdev) return ret; } - static int __exit swpld_mux_remove(struct platform_device *pdev) { int i; @@ -1063,657 +975,8 @@ static struct platform_driver swpld_mux_driver = { .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) -{ - 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 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 void __init delta_ag9064_platform_init(void) @@ -1734,12 +997,6 @@ static void __init delta_ag9064_platform_init(void) 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) { @@ -1754,13 +1011,6 @@ static void __init delta_ag9064_platform_init(void) 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; //swpld_pdata->cpld = cpld_pdata[system_cpld].client; ret = platform_device_register(&ag9064_swpld_mux); @@ -1794,14 +1044,10 @@ static void __init delta_ag9064_platform_init(void) 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; } @@ -1814,10 +1060,8 @@ static void __exit delta_ag9064_platform_exit(void) } 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); } @@ -1826,4 +1070,4 @@ module_exit(delta_ag9064_platform_exit); MODULE_DESCRIPTION("DELTA ag9064 Platform Support"); MODULE_AUTHOR("Johnson Lu "); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL"); \ No newline at end of file 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 new file mode 100644 index 000000000000..80a0ddc0d370 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_swpld.c @@ -0,0 +1,620 @@ +#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 diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.init b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.init index 669379fc9c12..dee41fd6f457 100755 --- a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.init +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.init @@ -26,6 +26,8 @@ start) modprobe ipmi_devintf modprobe ipmi_si trydefaults=1 modprobe delta_ag9064_platform + modprobe delta_ag9064_cpld + modprobe delta_ag9064_swpld /usr/local/bin/ag9064_platform_init.sh