diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/Makefile b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/Makefile index 69b3b48885..0712ff9cd6 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/Makefile @@ -1,2 +1,2 @@ -obj-m := at24.o dni_ag9032v1_psu.o dni_emc2305.o delta_ag9032v1_platform.o +obj-m := at24.o dni_ag9032v1_psu.o dni_emc2305.o delta_ag9032v1_platform.o delta_ag9032v1_cpupld.o diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_cpupld.c b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_cpupld.c new file mode 100644 index 0000000000..3c8c8f8c46 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_cpupld.c @@ -0,0 +1,387 @@ +#include +#include +#include +#include +#include +#include + +#define CPUPLD_REG 0x31 + +enum cpld_type { + cpld, +}; + +struct platform_data { + int reg_addr; + struct i2c_client *client; +}; + +enum{ + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, +}; + +enum cpld_attributes { + CPLD_VER, + CPU_BOARD_VER, + CPU_ID, + CPLD_RST, + MB_RST, + I2C_SW_RST, + MB_PWR, + PSU_FAN_INT, + SPI_WP_GBE, + EEPROM_WP, +}; + +static void device_release(struct device *dev) +{ + return; +} + +/*---------------- CPUPLD - start ------------- */ +static struct platform_data ag9032v1_cpld_platform_data[] = { + [cpld] = { + .reg_addr = CPUPLD_REG, + }, +}; + +static struct platform_device ag9032v1_cpld = { + .name = "delta-ag9032v1-cpupld", + .id = 0, + .dev = { + .platform_data = ag9032v1_cpld_platform_data, + .release = device_release + }, +}; +static unsigned char cpld_reg_addr; +static ssize_t get_cpld_reg_value(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + struct platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[cpld].client, cpld_reg_addr); + + return sprintf(buf, "0x%02x\n", ret); +} + +static ssize_t set_cpld_reg_value(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + struct platform_data *pdata = dev->platform_data; + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + i2c_smbus_write_byte_data(pdata[cpld].client, cpld_reg_addr, data); + + return count; +} + +static ssize_t get_cpld_reg_addr(struct device *dev, struct device_attribute *devattr, char *buf) +{ + + return sprintf(buf, "0x%02x\n", cpld_reg_addr); +} + +static ssize_t set_cpld_reg_addr(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + cpld_reg_addr = data; + + return count; +} + +static ssize_t get_cpld_data(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + int ret; + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct platform_data *pdata = dev->platform_data; + unsigned char reg; + int mask; + int value; + char note[180]; + switch (attr->index) { + case CPLD_VER: + reg = 0x01; + value = i2c_smbus_read_byte_data(pdata[cpld].client, reg); + sprintf(note, "\nCPLD Version, controlled by CPLD editor.\n"); + return sprintf(buf, "0x%02x%s", value, note); + break; + case CPU_BOARD_VER: + reg = 0x02; + ret = i2c_smbus_read_byte_data(pdata[cpld].client, reg); + value = ret >> 4; + sprintf(note, "\n“0x00”: proto A1\n“0x01”: proto A2\n“0x02”: proto B\n"); + return sprintf(buf, "0x%02x%s", value, note); + break; + case CPU_ID: + reg = 0x02; + ret = i2c_smbus_read_byte_data(pdata[cpld].client, reg); + value = ret & 0x0F; + sprintf(note, "\n“0x00”: P2041 ECC\n“0x01”: Rangeley ECC\n“0x02”: T2080 ECC\n"); + return sprintf(buf, "0x%02x%s", value, note); + break; + case CPLD_RST: + reg = 0x05; + mask = 7; + sprintf(note, "\n“1” = Normal operation\n“0” = Reset\n"); + break; + case MB_RST: + reg = 0x05; + mask = 1; + sprintf(note, "\n“1” = Normal operation\n“0” = Reset\n"); + break; + case I2C_SW_RST: + reg = 0x05; + mask = 0; + sprintf(note, "\n“1” = Normal operation\n“0” = Reset\n"); + break; + case MB_PWR: + reg = 0x08; + mask = 4; + sprintf(note, "\n“1” = Power rail is good\n“0” = Power rail is failed\n"); + break; + case PSU_FAN_INT: + reg = 0x0A; + mask = 0; + sprintf(note, "\n“1” = Interrupt doesn’t occur\n“0” = Interrupt occurs\n"); + break; + case SPI_WP_GBE: + reg = 0x10; + mask = 3; + sprintf(note, "\n“1” = overrides the lock-down function enabling blocks to be erased or programmed using software commands.\n“0” = enables the lock-down mechanism.\n"); + break; + case EEPROM_WP: + reg = 0x10; + mask = 2; + sprintf(note, "\n“1” = overrides the lock-down function enabling blocks to be erased or programmed using software commands.\n“0” = enables the lock-down mechanism.\n"); + break; + default: + return sprintf(buf, "%d not found", attr->index); + } + ret = i2c_smbus_read_byte_data(pdata[cpld].client, reg); + value = (ret & (1 << mask)) >> mask; + return sprintf(buf, "%d%s", value, note); +} + +static ssize_t set_cpld_data(struct device *dev, struct device_attribute *dev_attr, + const char *buf, size_t count) +{ + int mask; + int err; + int ret; + unsigned long data; + unsigned char reg; + unsigned char mask_shift; + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct platform_data *pdata = dev->platform_data; + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + switch (attr->index) { + case CPLD_RST: + reg = 0x05; + mask = 7; + break; + case MB_RST: + reg = 0x05; + mask = 1; + break; + case I2C_SW_RST: + reg = 0x05; + mask = 0; + break; + case SPI_WP_GBE: + reg = 0x10; + mask = 3; + break; + case EEPROM_WP: + reg = 0x10; + mask = 2; + break; + default: + return count; + } + + ret = i2c_smbus_read_byte_data(pdata[cpld].client, reg); + mask_shift = 1 << mask; + data = (ret & ~mask_shift) | (data << mask); + i2c_smbus_write_byte_data(pdata[cpld].client, cpld_reg_addr, data); + + return count; +} + +static DEVICE_ATTR(cpld_reg_value, S_IRUGO | S_IWUSR, get_cpld_reg_value, set_cpld_reg_value); +static DEVICE_ATTR(cpld_reg_addr, S_IRUGO | S_IWUSR, get_cpld_reg_addr, set_cpld_reg_addr); + +static SENSOR_DEVICE_ATTR(cpld_ver, S_IRUGO, get_cpld_data, NULL, CPLD_VER); +static SENSOR_DEVICE_ATTR(cpu_board_ver, S_IRUGO, get_cpld_data, NULL, CPU_BOARD_VER); +static SENSOR_DEVICE_ATTR(cpu_id, S_IRUGO, get_cpld_data, NULL, CPU_ID); +static SENSOR_DEVICE_ATTR(cpld_rst, S_IRUGO | S_IWUSR, get_cpld_data, set_cpld_data, CPLD_RST); +static SENSOR_DEVICE_ATTR(mb_rst, S_IRUGO | S_IWUSR, get_cpld_data, set_cpld_data, MB_RST); +static SENSOR_DEVICE_ATTR(i2c_sw_rst, S_IRUGO | S_IWUSR, get_cpld_data, set_cpld_data, I2C_SW_RST); +static SENSOR_DEVICE_ATTR(mb_pwr, S_IRUGO, get_cpld_data, NULL, MB_PWR); +static SENSOR_DEVICE_ATTR(psu_fan_int, S_IRUGO, get_cpld_data, NULL, PSU_FAN_INT); +static SENSOR_DEVICE_ATTR(spi_wp_gbe, S_IRUGO | S_IWUSR, get_cpld_data, set_cpld_data, SPI_WP_GBE); +static SENSOR_DEVICE_ATTR(eeprom_wp, S_IRUGO | S_IWUSR, get_cpld_data, set_cpld_data, EEPROM_WP); + +static struct attribute *ag9032v1_cpld_attrs[] = { + &dev_attr_cpld_reg_value.attr, + &dev_attr_cpld_reg_addr.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_cpld_rst.dev_attr.attr, + &sensor_dev_attr_mb_rst.dev_attr.attr, + &sensor_dev_attr_i2c_sw_rst.dev_attr.attr, + &sensor_dev_attr_mb_pwr.dev_attr.attr, + &sensor_dev_attr_psu_fan_int.dev_attr.attr, + &sensor_dev_attr_spi_wp_gbe.dev_attr.attr, + &sensor_dev_attr_eeprom_wp.dev_attr.attr, + NULL, +}; + +static struct attribute_group ag9032v1_cpld_attr_group = { + .attrs = ag9032v1_cpld_attrs, +}; + +static int __init cpld_probe(struct platform_device *pdev) +{ + struct platform_data *pdata; + struct i2c_adapter *parent; + int ret; + int retval; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "CPUPLD platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(BUS2); + if (!parent) { + printk(KERN_WARNING "Parent adapter (%d) not found\n",BUS2); + return -ENODEV; + } + + pdata[cpld].client = i2c_new_dummy(parent, pdata[cpld].reg_addr); + if (!pdata[cpld].client) { + printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[cpld].reg_addr); + goto error; + } + + retval = sysfs_create_group(&pdev->dev.kobj, &ag9032v1_cpld_attr_group); + if (retval){ + printk(KERN_WARNING "Fail to create cpupld attribute group"); + goto error; + } + return 0; + +error: + i2c_unregister_device(pdata[cpld].client); + i2c_put_adapter(parent); + return -ENODEV; +} + +static int __exit cpld_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct platform_data *pdata = pdev->dev.platform_data; + sysfs_remove_group(&pdev->dev.kobj, &ag9032v1_cpld_attr_group); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[cpld].client) { + if (!parent) { + parent = (pdata[cpld].client)->adapter; + } + i2c_unregister_device(pdata[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-ag9032v1-cpupld", + }, +}; +/*---------------- CPUPLD - end ------------- */ + + +/*---------------- module initialization ------------- */ +static void __init delta_ag9032v1_cpupld_init(void) +{ + int ret; + printk(KERN_WARNING "ag9032v1_platform_cpupld module initialization\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(&ag9032v1_cpld); + if (ret) { + printk(KERN_WARNING "Fail to create cpupld device\n"); + goto error_ag9032v1_cpupld; + } + return 0; + +error_ag9032v1_cpupld: + platform_driver_unregister(&cpld_driver); +error_cpupld_driver: + return ret; +} + +static void __exit delta_ag9032v1_cpupld_exit(void) +{ + platform_device_unregister(&ag9032v1_cpld); + platform_driver_unregister(&cpld_driver); +} +module_init(delta_ag9032v1_cpupld_init); +module_exit(delta_ag9032v1_cpupld_exit); + +MODULE_DESCRIPTION("DNI ag9032v1 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/ag9032v1/modules/delta_ag9032v1_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c index 90454a5bdb..e2ee8ab80b 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #define BUS3_DEV_NUM 9 #define BUS4_DEV_NUM 6 @@ -581,6 +583,82 @@ enum cpld_type { struct cpld_platform_data { int reg_addr; struct i2c_client *client; + //struct kobject *kobj; +}; + +enum swpld_attributes { + SW_BOARD_ID, + SW_BOARD_VER, + SWPLD_VER, + SYS_RST, + B56960_RST, + MB_A_PLD_RST, + MB_B_PLD_RST, + PSU1_PWR_OK, + PSU2_PWR_OK, + HS1_PWR_OK, + HS2_PWR_OK, + B54616_RST, + B54616_INT, + B54616_MASK_INT, + PB_HS_INT, + MB_HS_INT, + PB_PWR_INT, + MB_PWR_INT, + FAN_INT, + PB_HS_MASK_INT, + MB_HS_MASK_INT, + PB_PWR1_MASK_INT, + PB_PWR2_MASK_INT, + FAN_MASK_INT, + QSFP_01TO08_INT, + QSFP_08TO16_INT, + QSFP_17TO24_INT, + QSFP_25TO32_INT, + QSFP_01TO08_ABS, + QSFP_08TO16_ABS, + QSFP_17TO24_ABS, + QSFP_25TO32_ABS, + QSFP_01TO08_MASK_INT, + QSFP_08TO16_MASK_INT, + QSFP_17TO24_MASK_INT, + QSFP_25TO32_MASK_INT, + QSFP_01TO08_MASK_ABS, + QSFP_08TO16_MASK_ABS, + QSFP_17TO24_MASK_ABS, + QSFP_25TO32_MASK_ABS, + QSFP01_MOD_INT, + QSFP02_MOD_INT, + QSFP03_MOD_INT, + QSFP04_MOD_INT, + QSFP05_MOD_INT, + QSFP06_MOD_INT, + QSFP07_MOD_INT, + QSFP08_MOD_INT, + QSFP09_MOD_INT, + QSFP10_MOD_INT, + QSFP11_MOD_INT, + QSFP12_MOD_INT, + QSFP13_MOD_INT, + QSFP14_MOD_INT, + QSFP15_MOD_INT, + QSFP16_MOD_INT, + QSFP17_MOD_INT, + QSFP18_MOD_INT, + QSFP19_MOD_INT, + QSFP20_MOD_INT, + QSFP21_MOD_INT, + QSFP22_MOD_INT, + QSFP23_MOD_INT, + QSFP24_MOD_INT, + QSFP25_MOD_INT, + QSFP26_MOD_INT, + QSFP27_MOD_INT, + QSFP28_MOD_INT, + QSFP29_MOD_INT, + QSFP30_MOD_INT, + QSFP31_MOD_INT, + QSFP32_MOD_INT, }; static struct cpld_platform_data ag9032v1_cpld_platform_data[] = { @@ -590,7 +668,7 @@ static struct cpld_platform_data ag9032v1_cpld_platform_data[] = { }; static struct platform_device ag9032v1_cpld = { - .name = "delta-ag9032v1-cpld", + .name = "delta-ag9032v1-swpld", .id = 0, .dev = { .platform_data = ag9032v1_cpld_platform_data, @@ -598,6 +676,365 @@ static struct platform_device ag9032v1_cpld = { }, }; +static struct swpld_attribute_data { + int reg_addr; + int reg_mask; + char reg_note[150]; +}; + +static struct swpld_attribute_data controller_interrupt_data[] = { +//BOARD + [SYS_RST] = { + .reg_addr = 0x04, + .reg_mask = 7, + .reg_note = "“1” = Normal operation\n“0” = Reset" + }, + [B56960_RST] = { + .reg_addr = 0x04, + .reg_mask = 6, + .reg_note = "“1” = Normal operation\n“0” = Reset" + }, + [MB_A_PLD_RST] = { + .reg_addr = 0x04, + .reg_mask = 4, + .reg_note = "“1” = Normal operation\n“0” = Reset" + }, + [MB_B_PLD_RST] = { + .reg_addr = 0x04, + .reg_mask = 3, + .reg_note = "“1” = Normal operation\n“0” = Reset" + }, +//PSU + [PSU1_PWR_OK] = { + .reg_addr = 0x0a, + .reg_mask = 7, + .reg_note = "‘0’ = Power rail is failed\n‘1’ = Power rail is good" + }, + [PSU2_PWR_OK] = { + .reg_addr = 0x0a, + .reg_mask = 6, + .reg_note = "‘0’ = Power rail is failed\n‘1’ = Power rail is good" + }, +//HOT SWAP + [HS1_PWR_OK] = { + .reg_addr = 0x08, + .reg_mask = 5, + .reg_note = "‘0’ = Hot swap controller disabled\n‘1’ = Hot swap controller enabled" + }, + [HS2_PWR_OK] = { + .reg_addr = 0x08, + .reg_mask = 4, + .reg_note = "‘0’ = Hot swap controller disabled\n‘1’ = Hot swap controller enabled" + }, +//BCM54616S + [B54616_RST] = { + .reg_addr = 0x04, + .reg_mask = 5, + .reg_note = "“0” = Reset\n“1” = Normal operation" + }, + [B54616_INT] = { + .reg_addr = 0x16, + .reg_mask = 7, + .reg_note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" + }, + [B54616_MASK_INT] = { + .reg_addr = 0x17, + .reg_mask = 7, + .reg_note = "“0” = Interrupt doesn’t masked\n“1” = Interrupt masked" + }, +//QSFP + [PB_HS_INT] = { + .reg_addr = 0x10, + .reg_mask = 7, + .reg_note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" + }, + [MB_HS_INT] = { + .reg_addr = 0x10, + .reg_mask = 6, + .reg_note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" + }, + [PB_PWR_INT] = { + .reg_addr = 0x10, + .reg_mask = 5, + .reg_note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" + }, + [MB_PWR_INT] = { + .reg_addr = 0x10, + .reg_mask = 4, + .reg_note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" + }, + [FAN_INT] = { + .reg_addr = 0x10, + .reg_mask = 3, + .reg_note = "‘0’ = Interrupt occurs\n‘1’ = Interrupt doesn’t occur" + }, + [PB_HS_MASK_INT] = { + .reg_addr = 0x11, + .reg_mask = 7, + .reg_note = "‘0’ = Interrupt doesn’t masked\n‘1’ = Interrupt masked" + }, + [MB_HS_MASK_INT] = { + .reg_addr = 0x11, + .reg_mask = 6, + .reg_note = "‘0’ = Interrupt doesn’t masked\n‘1’ = Interrupt masked" + }, + [PB_PWR1_MASK_INT] = { + .reg_addr = 0x11, + .reg_mask = 5, + .reg_note = "‘0’ = Interrupt doesn’t masked\n‘1’ = Interrupt masked" + }, + [PB_PWR2_MASK_INT] = { + .reg_addr = 0x11, + .reg_mask = 4, + .reg_note = "‘0’ = Interrupt doesn’t masked\n‘1’ = Interrupt masked" + }, + [FAN_MASK_INT] = { + .reg_addr = 0x11, + .reg_mask = 3, + .reg_note = "‘0’ = Interrupt doesn’t masked\n‘1’ = Interrupt masked" + }, + [QSFP_01TO08_INT] = { + .reg_addr = 0x12, + .reg_mask = 7, + .reg_note = "“0” = Interrupt occurs\n“1” = Interrupt doesn’t occur" + }, + [QSFP_08TO16_INT] = { + .reg_addr = 0x12, + .reg_mask = 6, + .reg_note = "“0” = Interrupt occurs\n“1” = Interrupt doesn’t occur" + }, + [QSFP_17TO24_INT] = { + .reg_addr = 0x12, + .reg_mask = 5, + .reg_note = "“0” = Interrupt occurs\n“1” = Interrupt doesn’t occur" + }, + [QSFP_25TO32_INT] = { + .reg_addr = 0x12, + .reg_mask = 4, + .reg_note = "“0” = Interrupt occurs\n“1” = Interrupt doesn’t occur" + }, + [QSFP_01TO08_ABS] = { + .reg_addr = 0x12, + .reg_mask = 3, + .reg_note = "“0” = Absence status change\n“1” = Absence status not changes" + }, + [QSFP_08TO16_ABS] = { + .reg_addr = 0x12, + .reg_mask = 2, + .reg_note = "“0” = Absence status change\n“1” = Absence status not changes" + }, + [QSFP_17TO24_ABS] = { + .reg_addr = 0x12, + .reg_mask = 1, + .reg_note = "“0” = Absence status change\n“1” = Absence status not changes" + }, + [QSFP_25TO32_ABS] = { + .reg_addr = 0x12, + .reg_mask = 0, + .reg_note = "“0” = Absence status change\n“1” = Absence status not changes" + }, + [QSFP_01TO08_MASK_INT] = { + .reg_addr = 0x13, + .reg_mask = 7, + .reg_note = "“0” = Interrupt doesn’t masked\n“1” = Interrupt masked" + }, + [QSFP_08TO16_MASK_INT] = { + .reg_addr = 0x13, + .reg_mask = 6, + .reg_note = "“0” = Interrupt doesn’t masked\n“1” = Interrupt masked" + }, + [QSFP_17TO24_MASK_INT] = { + .reg_addr = 0x13, + .reg_mask = 5, + .reg_note = "“0” = Interrupt doesn’t masked\n“1” = Interrupt masked" + }, + [QSFP_25TO32_MASK_INT] = { + .reg_addr = 0x13, + .reg_mask = 4, + .reg_note = "“0” = Interrupt doesn’t masked\n“1” = Interrupt masked" + }, + [QSFP_01TO08_MASK_ABS] = { + .reg_addr = 0x13, + .reg_mask = 3, + .reg_note = "“0” = Interrupt doesn’t masked\n“1” = Interrupt masked" + }, + [QSFP_08TO16_MASK_ABS] = { + .reg_addr = 0x13, + .reg_mask = 2, + .reg_note = "“0” = Interrupt doesn’t masked\n“1” = Interrupt masked" + }, + [QSFP_17TO24_MASK_ABS] = { + .reg_addr = 0x13, + .reg_mask = 1, + .reg_note = "“0” = Interrupt doesn’t masked\n“1” = Interrupt masked" + }, + [QSFP_25TO32_MASK_ABS] = { + .reg_addr = 0x13, + .reg_mask = 0, + .reg_note = "“0” = Interrupt doesn’t masked\n“1” = Interrupt masked" + }, + [QSFP01_MOD_INT] = { + .reg_addr = 0x40, + .reg_mask = 7, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP02_MOD_INT] = { + .reg_addr = 0x40, + .reg_mask = 6, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP03_MOD_INT] = { + .reg_addr = 0x40, + .reg_mask = 5, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP04_MOD_INT] = { + .reg_addr = 0x40, + .reg_mask = 4, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP05_MOD_INT] = { + .reg_addr = 0x40, + .reg_mask = 3, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP06_MOD_INT] = { + .reg_addr = 0x40, + .reg_mask = 2, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP07_MOD_INT] = { + .reg_addr = 0x40, + .reg_mask = 1, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP08_MOD_INT] = { + .reg_addr = 0x40, + .reg_mask = 0, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP09_MOD_INT] = { + .reg_addr = 0x41, + .reg_mask = 7, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP10_MOD_INT] = { + .reg_addr = 0x41, + .reg_mask = 6, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP11_MOD_INT] = { + .reg_addr = 0x41, + .reg_mask = 5, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP12_MOD_INT] = { + .reg_addr = 0x41, + .reg_mask = 4, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP13_MOD_INT] = { + .reg_addr = 0x41, + .reg_mask = 3, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP14_MOD_INT] = { + .reg_addr = 0x41, + .reg_mask = 2, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP15_MOD_INT] = { + .reg_addr = 0x41, + .reg_mask = 1, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP16_MOD_INT] = { + .reg_addr = 0x41, + .reg_mask = 0, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP17_MOD_INT] = { + .reg_addr = 0x42, + .reg_mask = 7, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP18_MOD_INT] = { + .reg_addr = 0x42, + .reg_mask = 6, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP19_MOD_INT] = { + .reg_addr = 0x42, + .reg_mask = 5, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP20_MOD_INT] = { + .reg_addr = 0x42, + .reg_mask = 4, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP21_MOD_INT] = { + .reg_addr = 0x42, + .reg_mask = 3, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP22_MOD_INT] = { + .reg_addr = 0x42, + .reg_mask = 2, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP23_MOD_INT] = { + .reg_addr = 0x42, + .reg_mask = 1, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP24_MOD_INT] = { + .reg_addr = 0x42, + .reg_mask = 0, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP25_MOD_INT] = { + .reg_addr = 0x43, + .reg_mask = 7, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP26_MOD_INT] = { + .reg_addr = 0x43, + .reg_mask = 6, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP27_MOD_INT] = { + .reg_addr = 0x43, + .reg_mask = 5, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP28_MOD_INT] = { + .reg_addr = 0x43, + .reg_mask = 4, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP29_MOD_INT] = { + .reg_addr = 0x43, + .reg_mask = 3, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP30_MOD_INT] = { + .reg_addr = 0x43, + .reg_mask = 2, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP31_MOD_INT] = { + .reg_addr = 0x43, + .reg_mask = 1, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, + [QSFP32_MOD_INT] = { + .reg_addr = 0x43, + .reg_mask = 0, + .reg_note = "“0” = The module issue the interrupt\n“1” = The module NOT issue the interrupt" + }, +}; + static ssize_t get_present(struct device *dev, struct device_attribute \ *dev_attr, char *buf) { @@ -977,7 +1414,6 @@ static struct platform_led_data led_data[] = { }, }; - static ssize_t get_led_color(struct device *dev, struct device_attribute *devattr, char *buf) { char str[9][20] = {0}; @@ -1032,15 +1468,74 @@ static ssize_t set_led_color(struct device *dev, struct device_attribute *devatt return count; } +static unsigned char swpld_reg_addr; +static ssize_t get_swpld_reg_value(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + struct cpld_platform_data *pdata = dev->platform_data; + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, swpld_reg_addr); + return sprintf(buf, "0x%02x\n", ret); +} + +static ssize_t set_swpld_reg_value(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + struct cpld_platform_data *pdata = dev->platform_data; + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + + i2c_smbus_write_byte_data(pdata[system_cpld].client, swpld_reg_addr, data); + + return count; +} + +static ssize_t get_swpld_reg_addr(struct device *dev, struct device_attribute *devattr, char *buf) +{ + + return sprintf(buf, "0x%02x\n", swpld_reg_addr); +} + +static ssize_t set_swpld_reg_addr(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int err; + + err = kstrtoul(buf, 0, &data); + if (err){ + return err; + } + if (data > 0xff){ + printk(KERN_ALERT "address out of range (0x00-0xFF)\n"); + return count; + } + swpld_reg_addr = data; + + return count; +} + +static DEVICE_ATTR(swpld_reg_value, S_IRUGO | S_IWUSR, get_swpld_reg_value, set_swpld_reg_value); +static DEVICE_ATTR(swpld_reg_addr, S_IRUGO | S_IWUSR, get_swpld_reg_addr, set_swpld_reg_addr); static DEVICE_ATTR(sfp_present, S_IRUGO, get_present, NULL ); -static DEVICE_ATTR(sfp_lpmode, S_IWUSR | S_IRUGO, get_lpmode, set_lpmode ); -static DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, get_reset, set_reset ); -static DEVICE_ATTR(sfp_response, S_IWUSR | S_IRUGO, get_response, set_response ); +static DEVICE_ATTR(sfp_lpmode, S_IRUGO | S_IWUSR, get_lpmode, set_lpmode ); +static DEVICE_ATTR(sfp_reset, S_IRUGO | S_IWUSR, get_reset, set_reset ); +static DEVICE_ATTR(sfp_response, S_IRUGO | S_IWUSR, get_response, set_response ); static DEVICE_ATTR(led_control, S_IRUGO | S_IWUSR, get_led_color, set_led_color); static struct attribute *ag9032v1_cpld_attrs[] = { - &dev_attr_sfp_response.attr, + &dev_attr_swpld_reg_value.attr, + &dev_attr_swpld_reg_addr.attr, + &dev_attr_sfp_response.attr, &dev_attr_sfp_present.attr, &dev_attr_sfp_lpmode.attr, &dev_attr_sfp_reset.attr, @@ -1052,12 +1547,297 @@ static struct attribute_group ag9032v1_cpld_attr_grp = { .attrs = ag9032v1_cpld_attrs, }; +static struct kobject *kobj_board; +static struct kobject *kobj_psu; +static struct kobject *kobj_hot_swap; +static struct kobject *kobj_controller_interrupt; +static struct kobject *kobj_BCM54616S; + +static ssize_t get_swpld_data(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + int ret; + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev = kobj_to_dev(kobj_board->parent); + struct cpld_platform_data *pdata = i2cdev->platform_data; + unsigned char reg; + int mask; + int value; + char note[150]; + + switch (attr->index) { + //attributes on BOARD + case SW_BOARD_ID: + reg = 0x00; + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, reg); + value = ret >> 4; + sprintf(note, "\n“0x00”: L9032NB-AL-R\n“0x01”: AK9032-R\n“0x02”: AG9032-R\n“0x03”: AG9032R-R\n“0x04”: AG9032 V1-R\n"); + return sprintf(buf, "0x%02x%s", value, note); + break; + case SW_BOARD_VER: + reg = 0x00; + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, reg); + value = ret & 0x0F; + sprintf(note, "\n“0x00”: proto-A\n“0x01”: proto-B\n"); + return sprintf(buf, "0x%02x%s", value, note); + break; + case SWPLD_VER: + reg = 0x01; + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, reg); + value = ret & 0xFF; + sprintf(note, " "); + return sprintf(buf, "0x%02x%s", value, note); + break; + //other attributes + case SYS_RST ... QSFP32_MOD_INT: + reg = controller_interrupt_data[attr->index].reg_addr; + mask = controller_interrupt_data[attr->index].reg_mask; + sprintf(note, "\n%s\n",controller_interrupt_data[attr->index].reg_note); + break; + default: + return sprintf(buf, "%d not found", attr->index); + } + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, reg); + value = (ret & (1 << mask)) >> mask; + return sprintf(buf, "%d%s", value, note); +} + +static ssize_t set_swpld_data(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) +{ + int ret; + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct device *i2cdev = kobj_to_dev(kobj_board->parent); + struct cpld_platform_data *pdata = i2cdev->platform_data; + unsigned char reg; + int mask; + int value; + char note[180]; + int data; + int val; + u8 mask_out; + + ret = kstrtoul(buf, 0, &val); + + if (ret) + { + return ret; + } + if (val > 1) + { + return -EINVAL; + } + + switch (attr->index) { + case SYS_RST ... MB_B_PLD_RST: + case HS1_PWR_OK ... HS2_PWR_OK: + case B54616_RST: + case QSFP_01TO08_MASK_INT... QSFP_25TO32_MASK_ABS: + reg = controller_interrupt_data[attr->index].reg_addr; + mask = controller_interrupt_data[attr->index].reg_mask; + sprintf(note, "\n%s\n",controller_interrupt_data[attr->index].reg_note); + break; + default: + return sprintf(buf, "%d not found", attr->index); + } + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, reg); + mask_out = ret & ~((u8)(1 << mask)); + data = mask_out | (val << mask); + i2c_smbus_write_byte_data(pdata[system_cpld].client, reg, (u8)(data & 0xff)); + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, reg); + return count; +} + +static SENSOR_DEVICE_ATTR(sw_board_id, S_IRUGO, get_swpld_data, NULL, SW_BOARD_ID); +static SENSOR_DEVICE_ATTR(sw_board_ver, S_IRUGO, get_swpld_data, NULL, SW_BOARD_VER); +static SENSOR_DEVICE_ATTR(swpld_ver, S_IRUGO, get_swpld_data, NULL, SWPLD_VER); +static SENSOR_DEVICE_ATTR(sys_rst, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, SYS_RST); +static SENSOR_DEVICE_ATTR(B56960_rst, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, B56960_RST); +static SENSOR_DEVICE_ATTR(mb_a_pld_rst, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, MB_A_PLD_RST); +static SENSOR_DEVICE_ATTR(mb_b_pld_rst, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, MB_B_PLD_RST); + +static struct attribute *ag9032v1_swpld_attrs_board[] = { + &sensor_dev_attr_sw_board_id.dev_attr.attr, + &sensor_dev_attr_sw_board_ver.dev_attr.attr, + &sensor_dev_attr_swpld_ver.dev_attr.attr, + &sensor_dev_attr_sys_rst.dev_attr.attr, + &sensor_dev_attr_B56960_rst.dev_attr.attr, + &sensor_dev_attr_mb_a_pld_rst.dev_attr.attr, + &sensor_dev_attr_mb_b_pld_rst.dev_attr.attr, + NULL, +}; + +static SENSOR_DEVICE_ATTR(psu1_pwr_ok, S_IRUGO, get_swpld_data, NULL, PSU1_PWR_OK); +static SENSOR_DEVICE_ATTR(psu2_pwr_ok, S_IRUGO, get_swpld_data, NULL, PSU2_PWR_OK); + +static struct attribute *ag9032v1_swpld_attrs_psu[] = { + &sensor_dev_attr_psu1_pwr_ok.dev_attr.attr, + &sensor_dev_attr_psu2_pwr_ok.dev_attr.attr, + NULL, +}; + +static SENSOR_DEVICE_ATTR(hs1_pwr_ok, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, HS1_PWR_OK); +static SENSOR_DEVICE_ATTR(hs2_pwr_ok, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, HS2_PWR_OK); + +static struct attribute *ag9032v1_swpld_attrs_hot_swap[] = { + &sensor_dev_attr_hs1_pwr_ok.dev_attr.attr, + &sensor_dev_attr_hs2_pwr_ok.dev_attr.attr, + NULL, +}; + +static SENSOR_DEVICE_ATTR(B54616_rst, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, B54616_RST ); +static SENSOR_DEVICE_ATTR(B54616_int, S_IRUGO, get_swpld_data, NULL, B54616_INT ); +static SENSOR_DEVICE_ATTR(B54616_mask_int, S_IRUGO, get_swpld_data, NULL, B54616_MASK_INT); + +static struct attribute *ag9032v1_swpld_attrs_BCM54616S[] = { + &sensor_dev_attr_B54616_rst.dev_attr.attr, + &sensor_dev_attr_B54616_int.dev_attr.attr, + &sensor_dev_attr_B54616_mask_int.dev_attr.attr, + NULL, +}; + +static SENSOR_DEVICE_ATTR(pb_hs_int, S_IRUGO, get_swpld_data, NULL, PB_HS_INT); +static SENSOR_DEVICE_ATTR(mb_hs_int, S_IRUGO, get_swpld_data, NULL, MB_HS_INT); +static SENSOR_DEVICE_ATTR(pb_pwr_int, S_IRUGO, get_swpld_data, NULL, PB_PWR_INT); +static SENSOR_DEVICE_ATTR(mb_pwr_int, S_IRUGO, get_swpld_data, NULL, MB_PWR_INT); +static SENSOR_DEVICE_ATTR(fan_int, S_IRUGO, get_swpld_data, NULL, FAN_INT); +static SENSOR_DEVICE_ATTR(pb_hs_mask_int, S_IRUGO, get_swpld_data, NULL, PB_HS_MASK_INT); +static SENSOR_DEVICE_ATTR(mb_hs_mask_int, S_IRUGO, get_swpld_data, NULL, MB_HS_MASK_INT); +static SENSOR_DEVICE_ATTR(pb_pwr1_mask_int, S_IRUGO, get_swpld_data, NULL, PB_PWR1_MASK_INT); +static SENSOR_DEVICE_ATTR(pb_pwr2_mask_int, S_IRUGO, get_swpld_data, NULL, PB_PWR2_MASK_INT); +static SENSOR_DEVICE_ATTR(fan_mask_int, S_IRUGO, get_swpld_data, NULL, FAN_MASK_INT); +static SENSOR_DEVICE_ATTR(qsfp_01to08_int, S_IRUGO, get_swpld_data, NULL, QSFP_01TO08_INT); +static SENSOR_DEVICE_ATTR(qsfp_08to16_int, S_IRUGO, get_swpld_data, NULL, QSFP_08TO16_INT); +static SENSOR_DEVICE_ATTR(qsfp_17to24_int, S_IRUGO, get_swpld_data, NULL, QSFP_17TO24_INT); +static SENSOR_DEVICE_ATTR(qsfp_25to32_int, S_IRUGO, get_swpld_data, NULL, QSFP_25TO32_INT); +static SENSOR_DEVICE_ATTR(qsfp_01to08_abs, S_IRUGO, get_swpld_data, NULL, QSFP_01TO08_ABS); +static SENSOR_DEVICE_ATTR(qsfp_08to16_abs, S_IRUGO, get_swpld_data, NULL, QSFP_08TO16_ABS); +static SENSOR_DEVICE_ATTR(qsfp_17to24_abs, S_IRUGO, get_swpld_data, NULL, QSFP_17TO24_ABS); +static SENSOR_DEVICE_ATTR(qsfp_25to32_abs, S_IRUGO, get_swpld_data, NULL, QSFP_25TO32_ABS); +static SENSOR_DEVICE_ATTR(qsfp_01to08_mask_int, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, QSFP_01TO08_MASK_INT); +static SENSOR_DEVICE_ATTR(qsfp_08to16_mask_int, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, QSFP_08TO16_MASK_INT); +static SENSOR_DEVICE_ATTR(qsfp_17to24_mask_int, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, QSFP_17TO24_MASK_INT); +static SENSOR_DEVICE_ATTR(qsfp_25to32_mask_int, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, QSFP_25TO32_MASK_INT); +static SENSOR_DEVICE_ATTR(qsfp_01to08_mask_abs, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, QSFP_01TO08_MASK_ABS); +static SENSOR_DEVICE_ATTR(qsfp_08to16_mask_abs, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, QSFP_08TO16_MASK_ABS); +static SENSOR_DEVICE_ATTR(qsfp_17to24_mask_abs, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, QSFP_17TO24_MASK_ABS); +static SENSOR_DEVICE_ATTR(qsfp_25to32_mask_abs, S_IRUGO | S_IWUSR, get_swpld_data, set_swpld_data, QSFP_25TO32_MASK_ABS); +static SENSOR_DEVICE_ATTR(qsfp01_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP01_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp02_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP02_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp03_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP03_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp04_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP04_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp05_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP05_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp06_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP06_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp07_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP07_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp08_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP08_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp09_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP09_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp10_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP10_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp11_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP11_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp12_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP12_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp13_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP13_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp14_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP14_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp15_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP15_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp16_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP16_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp17_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP17_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp18_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP18_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp19_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP19_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp20_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP20_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp21_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP21_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp22_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP22_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp23_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP23_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp24_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP24_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp25_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP25_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp26_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP26_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp27_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP27_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp28_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP28_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp29_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP29_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp30_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP30_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp31_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP31_MOD_INT); +static SENSOR_DEVICE_ATTR(qsfp32_mod_int, S_IRUGO, get_swpld_data, NULL, QSFP32_MOD_INT); + +static struct attribute *ag9032v1_swpld_attrs_controller_interrupt[] = { + &sensor_dev_attr_pb_hs_int.dev_attr.attr, + &sensor_dev_attr_mb_hs_int.dev_attr.attr, + &sensor_dev_attr_pb_pwr_int.dev_attr.attr, + &sensor_dev_attr_mb_pwr_int.dev_attr.attr, + &sensor_dev_attr_fan_int.dev_attr.attr, + &sensor_dev_attr_pb_hs_mask_int.dev_attr.attr, + &sensor_dev_attr_mb_hs_mask_int.dev_attr.attr, + &sensor_dev_attr_pb_pwr1_mask_int.dev_attr.attr, + &sensor_dev_attr_pb_pwr2_mask_int.dev_attr.attr, + &sensor_dev_attr_fan_mask_int.dev_attr.attr, + &sensor_dev_attr_qsfp_01to08_int.dev_attr.attr, + &sensor_dev_attr_qsfp_08to16_int.dev_attr.attr, + &sensor_dev_attr_qsfp_17to24_int.dev_attr.attr, + &sensor_dev_attr_qsfp_25to32_int.dev_attr.attr, + &sensor_dev_attr_qsfp_01to08_abs.dev_attr.attr, + &sensor_dev_attr_qsfp_08to16_abs.dev_attr.attr, + &sensor_dev_attr_qsfp_17to24_abs.dev_attr.attr, + &sensor_dev_attr_qsfp_25to32_abs.dev_attr.attr, + &sensor_dev_attr_qsfp_01to08_mask_int.dev_attr.attr, + &sensor_dev_attr_qsfp_08to16_mask_int.dev_attr.attr, + &sensor_dev_attr_qsfp_17to24_mask_int.dev_attr.attr, + &sensor_dev_attr_qsfp_25to32_mask_int.dev_attr.attr, + &sensor_dev_attr_qsfp_01to08_mask_abs.dev_attr.attr, + &sensor_dev_attr_qsfp_08to16_mask_abs.dev_attr.attr, + &sensor_dev_attr_qsfp_17to24_mask_abs.dev_attr.attr, + &sensor_dev_attr_qsfp_25to32_mask_abs.dev_attr.attr, + &sensor_dev_attr_qsfp01_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp02_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp03_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp04_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp05_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp06_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp07_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp08_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp09_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp10_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp11_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp12_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp13_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp14_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp15_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp16_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp17_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp18_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp19_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp20_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp21_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp22_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp23_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp24_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp25_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp26_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp27_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp28_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp29_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp30_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp31_mod_int.dev_attr.attr, + &sensor_dev_attr_qsfp32_mod_int.dev_attr.attr, + NULL, +}; + +static struct attribute_group ag9032v1_swpld_attr_grp_board = { + .attrs = ag9032v1_swpld_attrs_board, +}; +static struct attribute_group ag9032v1_swpld_attr_grp_psu = { + .attrs = ag9032v1_swpld_attrs_psu, +}; +static struct attribute_group ag9032v1_swpld_attr_grp_hot_swap = { + .attrs = ag9032v1_swpld_attrs_hot_swap, +}; +static struct attribute_group ag9032v1_swpld_attr_grp_BCM54616S = { + .attrs = ag9032v1_swpld_attrs_BCM54616S, +}; +static struct attribute_group ag9032v1_swpld_attr_grp_controller_interrupt = { + .attrs = ag9032v1_swpld_attrs_controller_interrupt, +}; + /* CPLD -- driver */ 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"); @@ -1066,7 +1846,7 @@ static int __init cpld_probe(struct platform_device *pdev) parent = i2c_get_adapter(BUS6); if (!parent) { - printk(KERN_WARNING "Parent adapter (%d) not found\n",BUS6); + printk(KERN_WARNING "Parent adapter (%d) not found\n", BUS6); return -ENODEV; } @@ -1076,18 +1856,83 @@ static int __init cpld_probe(struct platform_device *pdev) goto error; } + kobj_board = kobject_create_and_add("Board", &pdev->dev.kobj); + if (!kobj_board){ + printk(KERN_WARNING "Fail to create directory"); + goto error; + } + + kobj_psu = kobject_create_and_add("PSU", &pdev->dev.kobj); + if (!kobj_psu){ + printk(KERN_WARNING "Fail to create directory"); + goto error; + } + + kobj_hot_swap = kobject_create_and_add("HOT_SWAP", &pdev->dev.kobj); + if (!kobj_hot_swap){ + printk(KERN_WARNING "Fail to create directory"); + goto error; + } + + kobj_controller_interrupt = kobject_create_and_add("Controller_interrupt", &pdev->dev.kobj); + if (!kobj_controller_interrupt){ + printk(KERN_WARNING "Fail to create directory"); + goto error; + } + + kobj_BCM54616S = kobject_create_and_add("BCM54616S", &pdev->dev.kobj); + if (!kobj_BCM54616S){ + printk(KERN_WARNING "Fail to create directory"); + goto error; + } + + ret = sysfs_create_group(kobj_board, &ag9032v1_swpld_attr_grp_board); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + goto error; + } + + ret = sysfs_create_group(kobj_psu, &ag9032v1_swpld_attr_grp_psu); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + goto error; + } + + ret = sysfs_create_group(kobj_hot_swap, &ag9032v1_swpld_attr_grp_hot_swap); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + goto error; + } + + ret = sysfs_create_group(kobj_BCM54616S, &ag9032v1_swpld_attr_grp_BCM54616S); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + goto error; + } + + ret = sysfs_create_group(kobj_controller_interrupt, &ag9032v1_swpld_attr_grp_controller_interrupt); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + goto error; + } + ret = sysfs_create_group(&pdev->dev.kobj, &ag9032v1_cpld_attr_grp); - if (ret) { + if (ret) { printk(KERN_WARNING "Fail to create cpld attribute group"); goto error; } return 0; -error: +error: + kobject_put(kobj_board); + kobject_put(kobj_psu); + kobject_put(kobj_hot_swap); + kobject_put(kobj_controller_interrupt); + kobject_put(kobj_BCM54616S); i2c_unregister_device(pdata[system_cpld].client); i2c_put_adapter(parent); - + return -ENODEV; } @@ -1096,16 +1941,22 @@ 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, &ag9032v1_cpld_attr_grp); + sysfs_remove_group(kobj_board, &ag9032v1_swpld_attr_grp_board); if (!pdata) { dev_err(&pdev->dev, "Missing platform data\n"); } else { + kobject_put(kobj_board); + kobject_put(kobj_psu); + kobject_put(kobj_hot_swap); + kobject_put(kobj_controller_interrupt); + kobject_put(kobj_BCM54616S); if (pdata[system_cpld].client) { if (!parent) { parent = (pdata[system_cpld].client)->adapter; } - i2c_unregister_device(pdata[system_cpld].client); + i2c_unregister_device(pdata[system_cpld].client); } } i2c_put_adapter(parent); @@ -1118,7 +1969,7 @@ static struct platform_driver cpld_driver = { .remove = __exit_p(cpld_remove), .driver = { .owner = THIS_MODULE, - .name = "delta-ag9032v1-cpld", + .name = "delta-ag9032v1-swpld", }, }; diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9032v1.init b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9032v1.init index 9b829652fd..f98363b3ea 100755 --- a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9032v1.init +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9032v1.init @@ -25,6 +25,7 @@ start) modprobe dni_emc2305 modprobe at24 modprobe delta_ag9032v1_platform + modprobe delta_ag9032v1_cpupld /usr/local/bin/ag9032v1_platform_init.sh