From fab46a8ee2ec4eb90e133e021f41696edad90a1b Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 11 Apr 2018 14:05:28 -0700 Subject: [PATCH] Revert "[as5812-54x] Add support for OOM" --- .../builds/x86-64-accton-as5812-54x-cpld.c | 1089 ++--------------- .../builds/x86-64-accton-as5812-54x-fan.c | 10 +- .../builds/x86-64-accton-as5812-54x-leds.c | 8 +- .../builds/x86-64-accton-as5812-54x-psu.c | 17 +- .../builds/x86-64-accton-as5812-54x-sfp.c | 508 ++++++++ .../onlp/builds/src/module/src/sfpi.c | 216 ++-- .../x86_64_accton_as5812_54x_r0/__init__.py | 21 +- 7 files changed, 757 insertions(+), 1112 deletions(-) create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-sfp.c diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-cpld.c b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-cpld.c index 5b9a5582..14e1d860 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-cpld.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-cpld.c @@ -33,13 +33,31 @@ #include #include #include +#include #include -#include -#include -#include -#define I2C_RW_RETRY_COUNT 10 -#define I2C_RW_RETRY_INTERVAL 60 /* ms */ +static struct dmi_system_id as5812_54x_dmi_table[] = { + { + .ident = "Accton AS5812-54X", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS5812-54X"), + }, + }, + { + .ident = "Accton AS5812-54X", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS5812-54X"), + }, + }, +}; + +int platform_accton_as5812_54x(void) +{ + return dmi_check_system(as5812_54x_dmi_table); +} +EXPORT_SYMBOL(platform_accton_as5812_54x); #define NUM_OF_CPLD1_CHANS 0x0 #define NUM_OF_CPLD2_CHANS 0x18 @@ -63,13 +81,10 @@ enum cpld_mux_type { as5812_54x_cpld1 }; -struct as5812_54x_cpld_data { +struct accton_i2c_cpld_mux { enum cpld_mux_type type; struct i2c_adapter *virt_adaps[ACCTON_I2C_CPLD_MUX_MAX_NCHANS]; u8 last_chan; /* last register value */ - - struct device *hwmon_dev; - struct mutex update_lock; }; struct chip_desc { @@ -93,833 +108,17 @@ static const struct chip_desc chips[] = { } }; -static const struct i2c_device_id as5812_54x_cpld_mux_id[] = { +static const struct i2c_device_id accton_i2c_cpld_mux_id[] = { { "as5812_54x_cpld1", as5812_54x_cpld1 }, { "as5812_54x_cpld2", as5812_54x_cpld2 }, { "as5812_54x_cpld3", as5812_54x_cpld3 }, { } }; -MODULE_DEVICE_TABLE(i2c, as5812_54x_cpld_mux_id); - -#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index -#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index -#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index -#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index - -enum as5812_54x_cpld1_sysfs_attributes { - CPLD_VERSION, - ACCESS, - MODULE_PRESENT_ALL, - MODULE_RXLOS_ALL, - /* transceiver attributes */ - TRANSCEIVER_PRESENT_ATTR_ID(1), - TRANSCEIVER_PRESENT_ATTR_ID(2), - TRANSCEIVER_PRESENT_ATTR_ID(3), - TRANSCEIVER_PRESENT_ATTR_ID(4), - TRANSCEIVER_PRESENT_ATTR_ID(5), - TRANSCEIVER_PRESENT_ATTR_ID(6), - TRANSCEIVER_PRESENT_ATTR_ID(7), - TRANSCEIVER_PRESENT_ATTR_ID(8), - TRANSCEIVER_PRESENT_ATTR_ID(9), - TRANSCEIVER_PRESENT_ATTR_ID(10), - TRANSCEIVER_PRESENT_ATTR_ID(11), - TRANSCEIVER_PRESENT_ATTR_ID(12), - TRANSCEIVER_PRESENT_ATTR_ID(13), - TRANSCEIVER_PRESENT_ATTR_ID(14), - TRANSCEIVER_PRESENT_ATTR_ID(15), - TRANSCEIVER_PRESENT_ATTR_ID(16), - TRANSCEIVER_PRESENT_ATTR_ID(17), - TRANSCEIVER_PRESENT_ATTR_ID(18), - TRANSCEIVER_PRESENT_ATTR_ID(19), - TRANSCEIVER_PRESENT_ATTR_ID(20), - TRANSCEIVER_PRESENT_ATTR_ID(21), - TRANSCEIVER_PRESENT_ATTR_ID(22), - TRANSCEIVER_PRESENT_ATTR_ID(23), - TRANSCEIVER_PRESENT_ATTR_ID(24), - TRANSCEIVER_PRESENT_ATTR_ID(25), - TRANSCEIVER_PRESENT_ATTR_ID(26), - TRANSCEIVER_PRESENT_ATTR_ID(27), - TRANSCEIVER_PRESENT_ATTR_ID(28), - TRANSCEIVER_PRESENT_ATTR_ID(29), - TRANSCEIVER_PRESENT_ATTR_ID(30), - TRANSCEIVER_PRESENT_ATTR_ID(31), - TRANSCEIVER_PRESENT_ATTR_ID(32), - TRANSCEIVER_PRESENT_ATTR_ID(33), - TRANSCEIVER_PRESENT_ATTR_ID(34), - TRANSCEIVER_PRESENT_ATTR_ID(35), - TRANSCEIVER_PRESENT_ATTR_ID(36), - TRANSCEIVER_PRESENT_ATTR_ID(37), - TRANSCEIVER_PRESENT_ATTR_ID(38), - TRANSCEIVER_PRESENT_ATTR_ID(39), - TRANSCEIVER_PRESENT_ATTR_ID(40), - TRANSCEIVER_PRESENT_ATTR_ID(41), - TRANSCEIVER_PRESENT_ATTR_ID(42), - TRANSCEIVER_PRESENT_ATTR_ID(43), - TRANSCEIVER_PRESENT_ATTR_ID(44), - TRANSCEIVER_PRESENT_ATTR_ID(45), - TRANSCEIVER_PRESENT_ATTR_ID(46), - TRANSCEIVER_PRESENT_ATTR_ID(47), - TRANSCEIVER_PRESENT_ATTR_ID(48), - TRANSCEIVER_PRESENT_ATTR_ID(49), - TRANSCEIVER_PRESENT_ATTR_ID(50), - TRANSCEIVER_PRESENT_ATTR_ID(51), - TRANSCEIVER_PRESENT_ATTR_ID(52), - TRANSCEIVER_PRESENT_ATTR_ID(53), - TRANSCEIVER_PRESENT_ATTR_ID(54), - TRANSCEIVER_TXDISABLE_ATTR_ID(1), - TRANSCEIVER_TXDISABLE_ATTR_ID(2), - TRANSCEIVER_TXDISABLE_ATTR_ID(3), - TRANSCEIVER_TXDISABLE_ATTR_ID(4), - TRANSCEIVER_TXDISABLE_ATTR_ID(5), - TRANSCEIVER_TXDISABLE_ATTR_ID(6), - TRANSCEIVER_TXDISABLE_ATTR_ID(7), - TRANSCEIVER_TXDISABLE_ATTR_ID(8), - TRANSCEIVER_TXDISABLE_ATTR_ID(9), - TRANSCEIVER_TXDISABLE_ATTR_ID(10), - TRANSCEIVER_TXDISABLE_ATTR_ID(11), - TRANSCEIVER_TXDISABLE_ATTR_ID(12), - TRANSCEIVER_TXDISABLE_ATTR_ID(13), - TRANSCEIVER_TXDISABLE_ATTR_ID(14), - TRANSCEIVER_TXDISABLE_ATTR_ID(15), - TRANSCEIVER_TXDISABLE_ATTR_ID(16), - TRANSCEIVER_TXDISABLE_ATTR_ID(17), - TRANSCEIVER_TXDISABLE_ATTR_ID(18), - TRANSCEIVER_TXDISABLE_ATTR_ID(19), - TRANSCEIVER_TXDISABLE_ATTR_ID(20), - TRANSCEIVER_TXDISABLE_ATTR_ID(21), - TRANSCEIVER_TXDISABLE_ATTR_ID(22), - TRANSCEIVER_TXDISABLE_ATTR_ID(23), - TRANSCEIVER_TXDISABLE_ATTR_ID(24), - TRANSCEIVER_TXDISABLE_ATTR_ID(25), - TRANSCEIVER_TXDISABLE_ATTR_ID(26), - TRANSCEIVER_TXDISABLE_ATTR_ID(27), - TRANSCEIVER_TXDISABLE_ATTR_ID(28), - TRANSCEIVER_TXDISABLE_ATTR_ID(29), - TRANSCEIVER_TXDISABLE_ATTR_ID(30), - TRANSCEIVER_TXDISABLE_ATTR_ID(31), - TRANSCEIVER_TXDISABLE_ATTR_ID(32), - TRANSCEIVER_TXDISABLE_ATTR_ID(33), - TRANSCEIVER_TXDISABLE_ATTR_ID(34), - TRANSCEIVER_TXDISABLE_ATTR_ID(35), - TRANSCEIVER_TXDISABLE_ATTR_ID(36), - TRANSCEIVER_TXDISABLE_ATTR_ID(37), - TRANSCEIVER_TXDISABLE_ATTR_ID(38), - TRANSCEIVER_TXDISABLE_ATTR_ID(39), - TRANSCEIVER_TXDISABLE_ATTR_ID(40), - TRANSCEIVER_TXDISABLE_ATTR_ID(41), - TRANSCEIVER_TXDISABLE_ATTR_ID(42), - TRANSCEIVER_TXDISABLE_ATTR_ID(43), - TRANSCEIVER_TXDISABLE_ATTR_ID(44), - TRANSCEIVER_TXDISABLE_ATTR_ID(45), - TRANSCEIVER_TXDISABLE_ATTR_ID(46), - TRANSCEIVER_TXDISABLE_ATTR_ID(47), - TRANSCEIVER_TXDISABLE_ATTR_ID(48), - TRANSCEIVER_RXLOS_ATTR_ID(1), - TRANSCEIVER_RXLOS_ATTR_ID(2), - TRANSCEIVER_RXLOS_ATTR_ID(3), - TRANSCEIVER_RXLOS_ATTR_ID(4), - TRANSCEIVER_RXLOS_ATTR_ID(5), - TRANSCEIVER_RXLOS_ATTR_ID(6), - TRANSCEIVER_RXLOS_ATTR_ID(7), - TRANSCEIVER_RXLOS_ATTR_ID(8), - TRANSCEIVER_RXLOS_ATTR_ID(9), - TRANSCEIVER_RXLOS_ATTR_ID(10), - TRANSCEIVER_RXLOS_ATTR_ID(11), - TRANSCEIVER_RXLOS_ATTR_ID(12), - TRANSCEIVER_RXLOS_ATTR_ID(13), - TRANSCEIVER_RXLOS_ATTR_ID(14), - TRANSCEIVER_RXLOS_ATTR_ID(15), - TRANSCEIVER_RXLOS_ATTR_ID(16), - TRANSCEIVER_RXLOS_ATTR_ID(17), - TRANSCEIVER_RXLOS_ATTR_ID(18), - TRANSCEIVER_RXLOS_ATTR_ID(19), - TRANSCEIVER_RXLOS_ATTR_ID(20), - TRANSCEIVER_RXLOS_ATTR_ID(21), - TRANSCEIVER_RXLOS_ATTR_ID(22), - TRANSCEIVER_RXLOS_ATTR_ID(23), - TRANSCEIVER_RXLOS_ATTR_ID(24), - TRANSCEIVER_RXLOS_ATTR_ID(25), - TRANSCEIVER_RXLOS_ATTR_ID(26), - TRANSCEIVER_RXLOS_ATTR_ID(27), - TRANSCEIVER_RXLOS_ATTR_ID(28), - TRANSCEIVER_RXLOS_ATTR_ID(29), - TRANSCEIVER_RXLOS_ATTR_ID(30), - TRANSCEIVER_RXLOS_ATTR_ID(31), - TRANSCEIVER_RXLOS_ATTR_ID(32), - TRANSCEIVER_RXLOS_ATTR_ID(33), - TRANSCEIVER_RXLOS_ATTR_ID(34), - TRANSCEIVER_RXLOS_ATTR_ID(35), - TRANSCEIVER_RXLOS_ATTR_ID(36), - TRANSCEIVER_RXLOS_ATTR_ID(37), - TRANSCEIVER_RXLOS_ATTR_ID(38), - TRANSCEIVER_RXLOS_ATTR_ID(39), - TRANSCEIVER_RXLOS_ATTR_ID(40), - TRANSCEIVER_RXLOS_ATTR_ID(41), - TRANSCEIVER_RXLOS_ATTR_ID(42), - TRANSCEIVER_RXLOS_ATTR_ID(43), - TRANSCEIVER_RXLOS_ATTR_ID(44), - TRANSCEIVER_RXLOS_ATTR_ID(45), - TRANSCEIVER_RXLOS_ATTR_ID(46), - TRANSCEIVER_RXLOS_ATTR_ID(47), - TRANSCEIVER_RXLOS_ATTR_ID(48), - TRANSCEIVER_TXFAULT_ATTR_ID(1), - TRANSCEIVER_TXFAULT_ATTR_ID(2), - TRANSCEIVER_TXFAULT_ATTR_ID(3), - TRANSCEIVER_TXFAULT_ATTR_ID(4), - TRANSCEIVER_TXFAULT_ATTR_ID(5), - TRANSCEIVER_TXFAULT_ATTR_ID(6), - TRANSCEIVER_TXFAULT_ATTR_ID(7), - TRANSCEIVER_TXFAULT_ATTR_ID(8), - TRANSCEIVER_TXFAULT_ATTR_ID(9), - TRANSCEIVER_TXFAULT_ATTR_ID(10), - TRANSCEIVER_TXFAULT_ATTR_ID(11), - TRANSCEIVER_TXFAULT_ATTR_ID(12), - TRANSCEIVER_TXFAULT_ATTR_ID(13), - TRANSCEIVER_TXFAULT_ATTR_ID(14), - TRANSCEIVER_TXFAULT_ATTR_ID(15), - TRANSCEIVER_TXFAULT_ATTR_ID(16), - TRANSCEIVER_TXFAULT_ATTR_ID(17), - TRANSCEIVER_TXFAULT_ATTR_ID(18), - TRANSCEIVER_TXFAULT_ATTR_ID(19), - TRANSCEIVER_TXFAULT_ATTR_ID(20), - TRANSCEIVER_TXFAULT_ATTR_ID(21), - TRANSCEIVER_TXFAULT_ATTR_ID(22), - TRANSCEIVER_TXFAULT_ATTR_ID(23), - TRANSCEIVER_TXFAULT_ATTR_ID(24), - TRANSCEIVER_TXFAULT_ATTR_ID(25), - TRANSCEIVER_TXFAULT_ATTR_ID(26), - TRANSCEIVER_TXFAULT_ATTR_ID(27), - TRANSCEIVER_TXFAULT_ATTR_ID(28), - TRANSCEIVER_TXFAULT_ATTR_ID(29), - TRANSCEIVER_TXFAULT_ATTR_ID(30), - TRANSCEIVER_TXFAULT_ATTR_ID(31), - TRANSCEIVER_TXFAULT_ATTR_ID(32), - TRANSCEIVER_TXFAULT_ATTR_ID(33), - TRANSCEIVER_TXFAULT_ATTR_ID(34), - TRANSCEIVER_TXFAULT_ATTR_ID(35), - TRANSCEIVER_TXFAULT_ATTR_ID(36), - TRANSCEIVER_TXFAULT_ATTR_ID(37), - TRANSCEIVER_TXFAULT_ATTR_ID(38), - TRANSCEIVER_TXFAULT_ATTR_ID(39), - TRANSCEIVER_TXFAULT_ATTR_ID(40), - TRANSCEIVER_TXFAULT_ATTR_ID(41), - TRANSCEIVER_TXFAULT_ATTR_ID(42), - TRANSCEIVER_TXFAULT_ATTR_ID(43), - TRANSCEIVER_TXFAULT_ATTR_ID(44), - TRANSCEIVER_TXFAULT_ATTR_ID(45), - TRANSCEIVER_TXFAULT_ATTR_ID(46), - TRANSCEIVER_TXFAULT_ATTR_ID(47), - TRANSCEIVER_TXFAULT_ATTR_ID(48), -}; - -/* sysfs attributes for hwmon - */ -static ssize_t show_status(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_present_all(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static ssize_t access(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static ssize_t show_version(struct device *dev, struct device_attribute *da, - char *buf); -static int as5812_54x_cpld_read_internal(struct i2c_client *client, u8 reg); -static int as5812_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); - -/* transceiver attributes */ -#define DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(index) \ - static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index) -#define DECLARE_TRANSCEIVER_PRESENT_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr - -#define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ - static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \ - static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \ - static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index) -#define DECLARE_SFP_TRANSCEIVER_ATTR(index) \ - &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \ - &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \ - &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr - -static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); -static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); -/* transceiver attributes */ -static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, NULL, MODULE_PRESENT_ALL); -static SENSOR_DEVICE_ATTR(module_rx_los_all, S_IRUGO, show_rxlos_all, NULL, MODULE_RXLOS_ALL); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(1); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(2); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(3); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(4); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(5); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(6); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(7); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(8); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(9); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(10); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(11); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(12); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(13); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(14); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(15); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(16); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(17); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(18); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(19); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(20); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(21); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(22); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(23); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(24); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(25); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(26); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(27); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(28); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(29); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(30); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(31); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(32); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(33); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(34); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(35); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(36); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(37); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(38); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(39); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(40); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(41); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(42); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(43); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(44); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(45); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(46); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(47); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(48); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(49); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(50); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(51); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(52); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(53); -DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(54); - -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(1); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(2); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(3); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(4); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(5); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(6); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(7); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(8); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(9); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(10); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(11); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(12); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(13); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(14); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(15); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(16); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(17); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(18); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(19); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(20); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(21); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(22); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(23); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(24); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(25); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(26); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(27); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(28); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(29); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(30); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(31); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(32); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(33); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(34); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(35); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(36); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(37); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(38); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(39); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(40); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(41); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(42); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(43); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(44); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(45); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(46); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(47); -DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48); - -static struct attribute *as5812_54x_cpld1_attributes[] = { - &sensor_dev_attr_version.dev_attr.attr, - &sensor_dev_attr_access.dev_attr.attr, - NULL -}; - -static const struct attribute_group as5812_54x_cpld1_group = { - .attrs = as5812_54x_cpld1_attributes, -}; - -static struct attribute *as5812_54x_cpld2_attributes[] = { - &sensor_dev_attr_version.dev_attr.attr, - &sensor_dev_attr_access.dev_attr.attr, - /* transceiver attributes */ - &sensor_dev_attr_module_present_all.dev_attr.attr, - &sensor_dev_attr_module_rx_los_all.dev_attr.attr, - DECLARE_TRANSCEIVER_PRESENT_ATTR(1), - DECLARE_TRANSCEIVER_PRESENT_ATTR(2), - DECLARE_TRANSCEIVER_PRESENT_ATTR(3), - DECLARE_TRANSCEIVER_PRESENT_ATTR(4), - DECLARE_TRANSCEIVER_PRESENT_ATTR(5), - DECLARE_TRANSCEIVER_PRESENT_ATTR(6), - DECLARE_TRANSCEIVER_PRESENT_ATTR(7), - DECLARE_TRANSCEIVER_PRESENT_ATTR(8), - DECLARE_TRANSCEIVER_PRESENT_ATTR(9), - DECLARE_TRANSCEIVER_PRESENT_ATTR(10), - DECLARE_TRANSCEIVER_PRESENT_ATTR(11), - DECLARE_TRANSCEIVER_PRESENT_ATTR(12), - DECLARE_TRANSCEIVER_PRESENT_ATTR(13), - DECLARE_TRANSCEIVER_PRESENT_ATTR(14), - DECLARE_TRANSCEIVER_PRESENT_ATTR(15), - DECLARE_TRANSCEIVER_PRESENT_ATTR(16), - DECLARE_TRANSCEIVER_PRESENT_ATTR(17), - DECLARE_TRANSCEIVER_PRESENT_ATTR(18), - DECLARE_TRANSCEIVER_PRESENT_ATTR(19), - DECLARE_TRANSCEIVER_PRESENT_ATTR(20), - DECLARE_TRANSCEIVER_PRESENT_ATTR(21), - DECLARE_TRANSCEIVER_PRESENT_ATTR(22), - DECLARE_TRANSCEIVER_PRESENT_ATTR(23), - DECLARE_TRANSCEIVER_PRESENT_ATTR(24), - DECLARE_SFP_TRANSCEIVER_ATTR(1), - DECLARE_SFP_TRANSCEIVER_ATTR(2), - DECLARE_SFP_TRANSCEIVER_ATTR(3), - DECLARE_SFP_TRANSCEIVER_ATTR(4), - DECLARE_SFP_TRANSCEIVER_ATTR(5), - DECLARE_SFP_TRANSCEIVER_ATTR(6), - DECLARE_SFP_TRANSCEIVER_ATTR(7), - DECLARE_SFP_TRANSCEIVER_ATTR(8), - DECLARE_SFP_TRANSCEIVER_ATTR(9), - DECLARE_SFP_TRANSCEIVER_ATTR(10), - DECLARE_SFP_TRANSCEIVER_ATTR(11), - DECLARE_SFP_TRANSCEIVER_ATTR(12), - DECLARE_SFP_TRANSCEIVER_ATTR(13), - DECLARE_SFP_TRANSCEIVER_ATTR(14), - DECLARE_SFP_TRANSCEIVER_ATTR(15), - DECLARE_SFP_TRANSCEIVER_ATTR(16), - DECLARE_SFP_TRANSCEIVER_ATTR(17), - DECLARE_SFP_TRANSCEIVER_ATTR(18), - DECLARE_SFP_TRANSCEIVER_ATTR(19), - DECLARE_SFP_TRANSCEIVER_ATTR(20), - DECLARE_SFP_TRANSCEIVER_ATTR(21), - DECLARE_SFP_TRANSCEIVER_ATTR(22), - DECLARE_SFP_TRANSCEIVER_ATTR(23), - DECLARE_SFP_TRANSCEIVER_ATTR(24), - NULL -}; - -static const struct attribute_group as5812_54x_cpld2_group = { - .attrs = as5812_54x_cpld2_attributes, -}; - -static struct attribute *as5812_54x_cpld3_attributes[] = { - &sensor_dev_attr_version.dev_attr.attr, - &sensor_dev_attr_access.dev_attr.attr, - /* transceiver attributes */ - &sensor_dev_attr_module_present_all.dev_attr.attr, - &sensor_dev_attr_module_rx_los_all.dev_attr.attr, - DECLARE_TRANSCEIVER_PRESENT_ATTR(25), - DECLARE_TRANSCEIVER_PRESENT_ATTR(26), - DECLARE_TRANSCEIVER_PRESENT_ATTR(27), - DECLARE_TRANSCEIVER_PRESENT_ATTR(28), - DECLARE_TRANSCEIVER_PRESENT_ATTR(29), - DECLARE_TRANSCEIVER_PRESENT_ATTR(30), - DECLARE_TRANSCEIVER_PRESENT_ATTR(31), - DECLARE_TRANSCEIVER_PRESENT_ATTR(32), - DECLARE_TRANSCEIVER_PRESENT_ATTR(33), - DECLARE_TRANSCEIVER_PRESENT_ATTR(34), - DECLARE_TRANSCEIVER_PRESENT_ATTR(35), - DECLARE_TRANSCEIVER_PRESENT_ATTR(36), - DECLARE_TRANSCEIVER_PRESENT_ATTR(37), - DECLARE_TRANSCEIVER_PRESENT_ATTR(38), - DECLARE_TRANSCEIVER_PRESENT_ATTR(39), - DECLARE_TRANSCEIVER_PRESENT_ATTR(40), - DECLARE_TRANSCEIVER_PRESENT_ATTR(41), - DECLARE_TRANSCEIVER_PRESENT_ATTR(42), - DECLARE_TRANSCEIVER_PRESENT_ATTR(43), - DECLARE_TRANSCEIVER_PRESENT_ATTR(44), - DECLARE_TRANSCEIVER_PRESENT_ATTR(45), - DECLARE_TRANSCEIVER_PRESENT_ATTR(46), - DECLARE_TRANSCEIVER_PRESENT_ATTR(47), - DECLARE_TRANSCEIVER_PRESENT_ATTR(48), - DECLARE_TRANSCEIVER_PRESENT_ATTR(49), - DECLARE_TRANSCEIVER_PRESENT_ATTR(50), - DECLARE_TRANSCEIVER_PRESENT_ATTR(51), - DECLARE_TRANSCEIVER_PRESENT_ATTR(52), - DECLARE_TRANSCEIVER_PRESENT_ATTR(53), - DECLARE_TRANSCEIVER_PRESENT_ATTR(54), - DECLARE_SFP_TRANSCEIVER_ATTR(25), - DECLARE_SFP_TRANSCEIVER_ATTR(26), - DECLARE_SFP_TRANSCEIVER_ATTR(27), - DECLARE_SFP_TRANSCEIVER_ATTR(28), - DECLARE_SFP_TRANSCEIVER_ATTR(29), - DECLARE_SFP_TRANSCEIVER_ATTR(30), - DECLARE_SFP_TRANSCEIVER_ATTR(31), - DECLARE_SFP_TRANSCEIVER_ATTR(32), - DECLARE_SFP_TRANSCEIVER_ATTR(33), - DECLARE_SFP_TRANSCEIVER_ATTR(34), - DECLARE_SFP_TRANSCEIVER_ATTR(35), - DECLARE_SFP_TRANSCEIVER_ATTR(36), - DECLARE_SFP_TRANSCEIVER_ATTR(37), - DECLARE_SFP_TRANSCEIVER_ATTR(38), - DECLARE_SFP_TRANSCEIVER_ATTR(39), - DECLARE_SFP_TRANSCEIVER_ATTR(40), - DECLARE_SFP_TRANSCEIVER_ATTR(41), - DECLARE_SFP_TRANSCEIVER_ATTR(42), - DECLARE_SFP_TRANSCEIVER_ATTR(43), - DECLARE_SFP_TRANSCEIVER_ATTR(44), - DECLARE_SFP_TRANSCEIVER_ATTR(45), - DECLARE_SFP_TRANSCEIVER_ATTR(46), - DECLARE_SFP_TRANSCEIVER_ATTR(47), - DECLARE_SFP_TRANSCEIVER_ATTR(48), - NULL -}; - -static const struct attribute_group as5812_54x_cpld3_group = { - .attrs = as5812_54x_cpld3_attributes, -}; - -static ssize_t show_present_all(struct device *dev, struct device_attribute *da, - char *buf) -{ - int i, status, num_regs = 0; - u8 values[4] = {0}; - u8 regs[] = {0x6, 0x7, 0x8, 0x14}; - struct i2c_client *client = to_i2c_client(dev); - struct as5812_54x_cpld_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - num_regs = (data->type == as5812_54x_cpld2) ? 3 : 4; - - for (i = 0; i < num_regs; i++) { - status = as5812_54x_cpld_read_internal(client, regs[i]); - - if (status < 0) { - goto exit; - } - - values[i] = ~(u8)status; - } - - mutex_unlock(&data->update_lock); - - /* Return values 1 -> 54 in order */ - if (data->type == as5812_54x_cpld2) { - status = sprintf(buf, "%.2x %.2x %.2x\n", - values[0], values[1], values[2]); - } - else { /* as5812_54x_cpld3 */ - values[3] &= 0x3F; - status = sprintf(buf, "%.2x %.2x %.2x %.2x\n", - values[0], values[1], values[2], values[3]); - } - - return status; - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, - char *buf) -{ - int i, status; - u8 values[3] = {0}; - u8 regs[] = {0xF, 0x10, 0x11}; - struct i2c_client *client = to_i2c_client(dev); - struct as5812_54x_cpld_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - for (i = 0; i < ARRAY_SIZE(regs); i++) { - status = as5812_54x_cpld_read_internal(client, regs[i]); - - if (status < 0) { - goto exit; - } - - values[i] = (u8)status; - } - - mutex_unlock(&data->update_lock); - - /* Return values 1 -> 24 in order */ - return sprintf(buf, "%.2x %.2x %.2x\n", values[0], values[1], values[2]); - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static ssize_t show_status(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct as5812_54x_cpld_data *data = i2c_get_clientdata(client); - int status = 0; - u8 reg = 0, mask = 0, revert = 0; - - switch (attr->index) { - case MODULE_PRESENT_1 ... MODULE_PRESENT_8: - reg = 0x6; - mask = 0x1 << (attr->index - MODULE_PRESENT_1); - break; - case MODULE_PRESENT_9 ... MODULE_PRESENT_16: - reg = 0x7; - mask = 0x1 << (attr->index - MODULE_PRESENT_9); - break; - case MODULE_PRESENT_17 ... MODULE_PRESENT_24: - reg = 0x8; - mask = 0x1 << (attr->index - MODULE_PRESENT_17); - break; - case MODULE_PRESENT_25 ... MODULE_PRESENT_32: - reg = 0x6; - mask = 0x1 << (attr->index - MODULE_PRESENT_25); - break; - case MODULE_PRESENT_33 ... MODULE_PRESENT_40: - reg = 0x7; - mask = 0x1 << (attr->index - MODULE_PRESENT_33); - break; - case MODULE_PRESENT_41 ... MODULE_PRESENT_48: - reg = 0x8; - mask = 0x1 << (attr->index - MODULE_PRESENT_41); - break; - case MODULE_PRESENT_49: - reg = 0x14; - mask = 0x1; - break; - case MODULE_PRESENT_50: - reg = 0x14; - mask = 0x4; - break; - case MODULE_PRESENT_51: - reg = 0x14; - mask = 0x10; - break; - case MODULE_PRESENT_52: - reg = 0x14; - mask = 0x2; - break; - case MODULE_PRESENT_53: - reg = 0x14; - mask = 0x8; - break; - case MODULE_PRESENT_54: - reg = 0x14; - mask = 0x20; - break; - case MODULE_TXFAULT_1 ... MODULE_TXFAULT_8: - reg = 0x9; - mask = 0x1 << (attr->index - MODULE_TXFAULT_1); - break; - case MODULE_TXFAULT_9 ... MODULE_TXFAULT_16: - reg = 0xA; - mask = 0x1 << (attr->index - MODULE_TXFAULT_9); - break; - case MODULE_TXFAULT_17 ... MODULE_TXFAULT_24: - reg = 0xB; - mask = 0x1 << (attr->index - MODULE_TXFAULT_17); - break; - case MODULE_TXFAULT_25 ... MODULE_TXFAULT_32: - reg = 0x9; - mask = 0x1 << (attr->index - MODULE_TXFAULT_25); - break; - case MODULE_TXFAULT_33 ... MODULE_TXFAULT_40: - reg = 0xA; - mask = 0x1 << (attr->index - MODULE_TXFAULT_33); - break; - case MODULE_TXFAULT_41 ... MODULE_TXFAULT_48: - reg = 0xB; - mask = 0x1 << (attr->index - MODULE_TXFAULT_41); - break; - case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: - reg = 0xC; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); - break; - case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: - reg = 0xD; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); - break; - case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: - reg = 0xE; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); - break; - case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: - reg = 0xC; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); - break; - case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: - reg = 0xD; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); - break; - case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: - reg = 0xE; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); - break; - case MODULE_RXLOS_1 ... MODULE_RXLOS_8: - reg = 0xF; - mask = 0x1 << (attr->index - MODULE_RXLOS_1); - break; - case MODULE_RXLOS_9 ... MODULE_RXLOS_16: - reg = 0x10; - mask = 0x1 << (attr->index - MODULE_RXLOS_9); - break; - case MODULE_RXLOS_17 ... MODULE_RXLOS_24: - reg = 0x11; - mask = 0x1 << (attr->index - MODULE_RXLOS_17); - break; - case MODULE_RXLOS_25 ... MODULE_RXLOS_32: - reg = 0xF; - mask = 0x1 << (attr->index - MODULE_RXLOS_25); - break; - case MODULE_RXLOS_33 ... MODULE_RXLOS_40: - reg = 0x10; - mask = 0x1 << (attr->index - MODULE_RXLOS_33); - break; - case MODULE_RXLOS_41 ... MODULE_RXLOS_48: - reg = 0x11; - mask = 0x1 << (attr->index - MODULE_RXLOS_41); - break; - default: - return 0; - } - - if (attr->index >= MODULE_PRESENT_1 && attr->index <= MODULE_PRESENT_54) { - revert = 1; - } - - mutex_lock(&data->update_lock); - status = as5812_54x_cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - mutex_unlock(&data->update_lock); - - return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask)); - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct as5812_54x_cpld_data *data = i2c_get_clientdata(client); - long disable; - int status; - u8 reg = 0, mask = 0; - - status = kstrtol(buf, 10, &disable); - if (status) { - return status; - } - - switch (attr->index) { - case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: - reg = 0xC; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); - break; - case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: - reg = 0xD; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); - break; - case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: - reg = 0xE; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); - break; - case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: - reg = 0xC; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); - break; - case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: - reg = 0xD; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); - break; - case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: - reg = 0xE; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); - break; - default: - return 0; - } - - /* Read current status */ - mutex_lock(&data->update_lock); - status = as5812_54x_cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - - /* Update tx_disable status */ - if (disable) { - status |= mask; - } - else { - status &= ~mask; - } - - status = as5812_54x_cpld_write_internal(client, reg, status); - if (unlikely(status < 0)) { - goto exit; - } - - mutex_unlock(&data->update_lock); - return count; - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static ssize_t access(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - int status; - u32 addr, val; - struct i2c_client *client = to_i2c_client(dev); - struct as5812_54x_cpld_data *data = i2c_get_clientdata(client); - - if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { - return -EINVAL; - } - - if (addr > 0xFF || val > 0xFF) { - return -EINVAL; - } - - mutex_lock(&data->update_lock); - status = as5812_54x_cpld_write_internal(client, addr, val); - if (unlikely(status < 0)) { - goto exit; - } - mutex_unlock(&data->update_lock); - return count; - -exit: - mutex_unlock(&data->update_lock); - return status; -} +MODULE_DEVICE_TABLE(i2c, accton_i2c_cpld_mux_id); /* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer() for this as they will try to lock adapter a second time */ -static int as5812_54x_cpld_mux_reg_write(struct i2c_adapter *adap, +static int accton_i2c_cpld_mux_reg_write(struct i2c_adapter *adap, struct i2c_client *client, u8 val) { unsigned long orig_jiffies; @@ -950,35 +149,35 @@ static int as5812_54x_cpld_mux_reg_write(struct i2c_adapter *adap, return res; } -static int as5812_54x_cpld_mux_select_chan(struct i2c_adapter *adap, +static int accton_i2c_cpld_mux_select_chan(struct i2c_adapter *adap, void *client, u32 chan) { - struct as5812_54x_cpld_data *data = i2c_get_clientdata(client); + struct accton_i2c_cpld_mux *data = i2c_get_clientdata(client); u8 regval; int ret = 0; regval = chan; /* Only select the channel if its different from the last channel */ if (data->last_chan != regval) { - ret = as5812_54x_cpld_mux_reg_write(adap, client, regval); + ret = accton_i2c_cpld_mux_reg_write(adap, client, regval); data->last_chan = regval; } return ret; } -static int as5812_54x_cpld_mux_deselect_mux(struct i2c_adapter *adap, +static int accton_i2c_cpld_mux_deselect_mux(struct i2c_adapter *adap, void *client, u32 chan) { - struct as5812_54x_cpld_data *data = i2c_get_clientdata(client); + struct accton_i2c_cpld_mux *data = i2c_get_clientdata(client); /* Deselect active channel */ data->last_chan = chips[data->type].deselectChan; - return as5812_54x_cpld_mux_reg_write(adap, client, data->last_chan); + return accton_i2c_cpld_mux_reg_write(adap, client, data->last_chan); } -static void as5812_54x_cpld_add_client(struct i2c_client *client) +static void accton_i2c_cpld_add_client(struct i2c_client *client) { struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); @@ -994,7 +193,7 @@ static void as5812_54x_cpld_add_client(struct i2c_client *client) mutex_unlock(&list_lock); } -static void as5812_54x_cpld_remove_client(struct i2c_client *client) +static void accton_i2c_cpld_remove_client(struct i2c_client *client) { struct list_head *list_node = NULL; struct cpld_client_node *cpld_node = NULL; @@ -1020,178 +219,107 @@ static void as5812_54x_cpld_remove_client(struct i2c_client *client) mutex_unlock(&list_lock); } -static ssize_t show_version(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_cpld_version(struct device *dev, struct device_attribute *attr, char *buf) { - int val = 0; - struct i2c_client *client = to_i2c_client(dev); - - val = i2c_smbus_read_byte_data(client, 0x1); + u8 reg = 0x1; + struct i2c_client *client; + int len; - if (val < 0) { - dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); - } - - return sprintf(buf, "%d", val); + client = to_i2c_client(dev); + len = sprintf(buf, "%d", i2c_smbus_read_byte_data(client, reg)); + + return len; } +static struct device_attribute ver = __ATTR(version, 0600, show_cpld_version, NULL); + /* * I2C init/probing/exit functions */ -static int as5812_54x_cpld_mux_probe(struct i2c_client *client, +static int accton_i2c_cpld_mux_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); int chan=0; - struct as5812_54x_cpld_data *data; + struct accton_i2c_cpld_mux *data; int ret = -ENODEV; - const struct attribute_group *group = NULL; if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) - goto exit; + goto err; - data = kzalloc(sizeof(struct as5812_54x_cpld_data), GFP_KERNEL); + data = kzalloc(sizeof(struct accton_i2c_cpld_mux), GFP_KERNEL); if (!data) { ret = -ENOMEM; - goto exit; + goto err; } i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); + data->type = id->driver_data; if (data->type == as5812_54x_cpld2 || data->type == as5812_54x_cpld3) { data->last_chan = chips[data->type].deselectChan; /* force the first selection */ - /* Now create an adapter for each channel */ - for (chan = 0; chan < chips[data->type].nchans; chan++) { - data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &client->dev, client, 0, chan, 0, - as5812_54x_cpld_mux_select_chan, - as5812_54x_cpld_mux_deselect_mux); + /* Now create an adapter for each channel */ + for (chan = 0; chan < chips[data->type].nchans; chan++) { + data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &client->dev, client, 0, chan, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) + I2C_CLASS_HWMON | I2C_CLASS_SPD, +#endif + accton_i2c_cpld_mux_select_chan, + accton_i2c_cpld_mux_deselect_mux); - if (data->virt_adaps[chan] == NULL) { - ret = -ENODEV; - dev_err(&client->dev, "failed to register multiplexed adapter %d\n", chan); - goto exit_mux_register; - } - } - - dev_info(&client->dev, "registered %d multiplexed busses for I2C mux %s\n", - chan, client->name); - } - - /* Register sysfs hooks */ - switch (data->type) { - case as5812_54x_cpld1: - group = &as5812_54x_cpld1_group; - break; - case as5812_54x_cpld2: - group = &as5812_54x_cpld2_group; - break; - case as5812_54x_cpld3: - group = &as5812_54x_cpld3_group; - break; - default: - break; - } - - - if (group) { - ret = sysfs_create_group(&client->dev.kobj, group); - if (ret) { - goto exit_mux_register; + if (data->virt_adaps[chan] == NULL) { + ret = -ENODEV; + dev_err(&client->dev, "failed to register multiplexed adapter %d\n", chan); + goto virt_reg_failed; } } - as5812_54x_cpld_add_client(client); + dev_info(&client->dev, "registered %d multiplexed busses for I2C mux %s\n", + chan, client->name); + } + + accton_i2c_cpld_add_client(client); + + ret = sysfs_create_file(&client->dev.kobj, &ver.attr); + if (ret) + goto virt_reg_failed; return 0; -exit_mux_register: +virt_reg_failed: for (chan--; chan >= 0; chan--) { i2c_del_mux_adapter(data->virt_adaps[chan]); } - kfree(data); -exit: + + kfree(data); +err: return ret; } -static int as5812_54x_cpld_mux_remove(struct i2c_client *client) +static int accton_i2c_cpld_mux_remove(struct i2c_client *client) { - struct as5812_54x_cpld_data *data = i2c_get_clientdata(client); + struct accton_i2c_cpld_mux *data = i2c_get_clientdata(client); const struct chip_desc *chip = &chips[data->type]; int chan; - const struct attribute_group *group = NULL; - as5812_54x_cpld_remove_client(client); - - /* Remove sysfs hooks */ - switch (data->type) { - case as5812_54x_cpld1: - group = &as5812_54x_cpld1_group; - break; - case as5812_54x_cpld2: - group = &as5812_54x_cpld2_group; - break; - case as5812_54x_cpld3: - group = &as5812_54x_cpld3_group; - break; - default: - break; - } - - if (group) { - sysfs_remove_group(&client->dev.kobj, group); - } + sysfs_remove_file(&client->dev.kobj, &ver.attr); for (chan = 0; chan < chip->nchans; ++chan) { - if (data->virt_adaps[chan]) { - i2c_del_mux_adapter(data->virt_adaps[chan]); - data->virt_adaps[chan] = NULL; - } + if (data->virt_adaps[chan]) { + i2c_del_mux_adapter(data->virt_adaps[chan]); + data->virt_adaps[chan] = NULL; + } } kfree(data); + accton_i2c_cpld_remove_client(client); return 0; } -static int as5812_54x_cpld_read_internal(struct i2c_client *client, u8 reg) -{ - int status = 0, retry = I2C_RW_RETRY_COUNT; - - while (retry) { - status = i2c_smbus_read_byte_data(client, reg); - if (unlikely(status < 0)) { - msleep(I2C_RW_RETRY_INTERVAL); - retry--; - continue; - } - - break; - } - - return status; -} - -static int as5812_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value) -{ - int status = 0, retry = I2C_RW_RETRY_COUNT; - - while (retry) { - status = i2c_smbus_write_byte_data(client, reg, value); - if (unlikely(status < 0)) { - msleep(I2C_RW_RETRY_INTERVAL); - retry--; - continue; - } - - break; - } - - return status; -} - -int as5812_54x_cpld_read(unsigned short cpld_addr, u8 reg) +int as5812_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg) { struct list_head *list_node = NULL; struct cpld_client_node *cpld_node = NULL; @@ -1201,21 +329,21 @@ int as5812_54x_cpld_read(unsigned short cpld_addr, u8 reg) list_for_each(list_node, &cpld_client_list) { - cpld_node = list_entry(list_node, struct cpld_client_node, list); + cpld_node = list_entry(list_node, struct cpld_client_node, list); - if (cpld_node->client->addr == cpld_addr) { - ret = as5812_54x_cpld_read_internal(cpld_node->client, reg); - break; - } + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } } mutex_unlock(&list_lock); return ret; } -EXPORT_SYMBOL(as5812_54x_cpld_read); +EXPORT_SYMBOL(as5812_54x_i2c_cpld_read); -int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +int as5812_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) { struct list_head *list_node = NULL; struct cpld_client_node *cpld_node = NULL; @@ -1225,45 +353,44 @@ int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) list_for_each(list_node, &cpld_client_list) { - cpld_node = list_entry(list_node, struct cpld_client_node, list); + cpld_node = list_entry(list_node, struct cpld_client_node, list); - if (cpld_node->client->addr == cpld_addr) { - ret = as5812_54x_cpld_write_internal(cpld_node->client, reg, value); - break; - } + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } } mutex_unlock(&list_lock); return ret; } -EXPORT_SYMBOL(as5812_54x_cpld_write); +EXPORT_SYMBOL(as5812_54x_i2c_cpld_write); -static struct i2c_driver as5812_54x_cpld_mux_driver = { +static struct i2c_driver accton_i2c_cpld_mux_driver = { .driver = { .name = "as5812_54x_cpld", .owner = THIS_MODULE, }, - .probe = as5812_54x_cpld_mux_probe, - .remove = as5812_54x_cpld_mux_remove, - .id_table = as5812_54x_cpld_mux_id, + .probe = accton_i2c_cpld_mux_probe, + .remove = accton_i2c_cpld_mux_remove, + .id_table = accton_i2c_cpld_mux_id, }; -static int __init as5812_54x_cpld_mux_init(void) +static int __init accton_i2c_cpld_mux_init(void) { mutex_init(&list_lock); - return i2c_add_driver(&as5812_54x_cpld_mux_driver); + return i2c_add_driver(&accton_i2c_cpld_mux_driver); } -static void __exit as5812_54x_cpld_mux_exit(void) +static void __exit accton_i2c_cpld_mux_exit(void) { - i2c_del_driver(&as5812_54x_cpld_mux_driver); + i2c_del_driver(&accton_i2c_cpld_mux_driver); } MODULE_AUTHOR("Brandon Chuang "); MODULE_DESCRIPTION("Accton I2C CPLD mux driver"); MODULE_LICENSE("GPL"); -module_init(as5812_54x_cpld_mux_init); -module_exit(as5812_54x_cpld_mux_exit); - +module_init(accton_i2c_cpld_mux_init); +module_exit(accton_i2c_cpld_mux_exit); diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-fan.c b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-fan.c index 2521a469..4c3cdeab 100755 --- a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-fan.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-fan.c @@ -131,8 +131,8 @@ static ssize_t fan_set_duty_cycle(struct device *dev, static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); -extern int as5812_54x_cpld_read(unsigned short cpld_addr, u8 reg); -extern int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); +extern int as5812_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5812_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); /*******************/ @@ -258,12 +258,12 @@ static const struct attribute_group accton_as5812_54x_fan_group = { static int accton_as5812_54x_fan_read_value(u8 reg) { - return as5812_54x_cpld_read(0x60, reg); + return as5812_54x_i2c_cpld_read(0x60, reg); } static int accton_as5812_54x_fan_write_value(u8 reg, u8 value) { - return as5812_54x_cpld_write(0x60, reg, value); + return as5812_54x_i2c_cpld_write(0x60, reg, value); } static void accton_as5812_54x_fan_update_device(struct device *dev) @@ -393,7 +393,7 @@ static struct platform_driver accton_as5812_54x_fan_driver = { static int __init accton_as5812_54x_fan_init(void) { int ret; - + ret = platform_driver_register(&accton_as5812_54x_fan_driver); if (ret < 0) { goto exit; diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-leds.c b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-leds.c index 0b8e46c4..f196f22c 100755 --- a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-leds.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-leds.c @@ -29,8 +29,8 @@ #include #include -extern int as5812_54x_cpld_read (unsigned short cpld_addr, u8 reg); -extern int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); +extern int as5812_54x_i2c_cpld_read (unsigned short cpld_addr, u8 reg); +extern int as5812_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); extern void led_classdev_unregister(struct led_classdev *led_cdev); extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); @@ -220,12 +220,12 @@ static u8 led_light_mode_to_reg_val(enum led_type type, static int accton_as5812_54x_led_read_value(u8 reg) { - return as5812_54x_cpld_read(0x60, reg); + return as5812_54x_i2c_cpld_read(0x60, reg); } static int accton_as5812_54x_led_write_value(u8 reg, u8 value) { - return as5812_54x_cpld_write(0x60, reg, value); + return as5812_54x_i2c_cpld_write(0x60, reg, value); } static void accton_as5812_54x_led_update(void) diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-psu.c b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-psu.c index 9d52e544..2703897f 100755 --- a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-psu.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-psu.c @@ -44,7 +44,7 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, char static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); static ssize_t show_serial_number(struct device *dev, struct device_attribute *da,char *buf); static int as5812_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); -extern int as5812_54x_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5812_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg); static int as5812_54x_psu_model_name_get(struct device *dev , int get_serial); /* Addresses scanned @@ -406,7 +406,7 @@ static struct as5812_54x_psu_data *as5812_54x_psu_update_device(struct device *d /* Read psu status */ - status = as5812_54x_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET); + status = as5812_54x_i2c_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET); if (status < 0) { dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status); @@ -426,9 +426,20 @@ exit: return data; } -module_i2c_driver(as5812_54x_psu_driver); +static int __init as5812_54x_psu_init(void) +{ + return i2c_add_driver(&as5812_54x_psu_driver); +} + +static void __exit as5812_54x_psu_exit(void) +{ + i2c_del_driver(&as5812_54x_psu_driver); +} MODULE_AUTHOR("Brandon Chuang "); MODULE_DESCRIPTION("accton as5812_54x_psu driver"); MODULE_LICENSE("GPL"); +module_init(as5812_54x_psu_init); +module_exit(as5812_54x_psu_exit); + diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-sfp.c b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-sfp.c new file mode 100644 index 00000000..44727e22 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/modules/builds/x86-64-accton-as5812-54x-sfp.c @@ -0,0 +1,508 @@ +/* + * An hwmon driver for accton as5812_54x sfp + * + * Copyright (C) 2015 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_OF_SFP_PORT 54 +#define BIT_INDEX(i) (1ULL << (i)) + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as5812_54x_sfp_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + int port; /* Front port index */ + char eeprom[256]; /* eeprom data */ + u64 status[4]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => is_present + 1 => tx_fail + 2 => tx_disable + 3 => rx_loss */ +}; + +/* The table maps active port to cpld port. + * Array index 0 is for active port 1, + * index 1 for active port 2, and so on. + * The array content implies cpld port index. + */ +static const u8 cpld_to_front_port_table[] = +{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 52, 50, 53, 51, 54}; + +#define CPLD_PORT_TO_FRONT_PORT(port) (cpld_to_front_port_table[port]) + +static struct as5812_54x_sfp_data *as5812_54x_sfp_update_device(struct device *dev, int update_eeprom); +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +extern int as5812_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5812_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +enum as5812_54x_sfp_sysfs_attributes { + SFP_IS_PRESENT, + SFP_TX_FAULT, + SFP_TX_DISABLE, + SFP_RX_LOSS, + SFP_PORT_NUMBER, + SFP_EEPROM, + SFP_RX_LOS_ALL, + SFP_IS_PRESENT_ALL, +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_status, NULL, SFP_IS_PRESENT); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, show_status, NULL, SFP_TX_FAULT); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, show_status, set_tx_disable, SFP_TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_rx_loss, S_IRUGO, show_status,NULL, SFP_RX_LOSS); +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, SFP_PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_eeprom, S_IRUGO, show_eeprom, NULL, SFP_EEPROM); +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, show_status,NULL, SFP_RX_LOS_ALL); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_status,NULL, SFP_IS_PRESENT_ALL); + +static struct attribute *as5812_54x_sfp_attributes[] = { + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_eeprom.dev_attr.attr, + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + NULL +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as5812_54x_sfp_data *data; + u8 val; + int values[7]; + + /* Error-check the CPLD read results. */ +#define VALIDATED_READ(_buf, _rv, _read_expr, _invert) \ + do { \ + _rv = (_read_expr); \ + if(_rv < 0) { \ + return sprintf(_buf, "READ ERROR\n"); \ + } \ + if(_invert) { \ + _rv = ~_rv; \ + } \ + _rv &= 0xFF; \ + } while(0) + + if(attr->index == SFP_RX_LOS_ALL) { + /* + * Report the RX_LOS status for all ports. + * This does not depend on the currently active SFP selector. + */ + + /* RX_LOS Ports 1-8 */ + VALIDATED_READ(buf, values[0], as5812_54x_i2c_cpld_read(0x61, 0x0F), 0); + /* RX_LOS Ports 9-16 */ + VALIDATED_READ(buf, values[1], as5812_54x_i2c_cpld_read(0x61, 0x10), 0); + /* RX_LOS Ports 17-24 */ + VALIDATED_READ(buf, values[2], as5812_54x_i2c_cpld_read(0x61, 0x11), 0); + /* RX_LOS Ports 25-32 */ + VALIDATED_READ(buf, values[3], as5812_54x_i2c_cpld_read(0x62, 0x0F), 0); + /* RX_LOS Ports 33-40 */ + VALIDATED_READ(buf, values[4], as5812_54x_i2c_cpld_read(0x62, 0x10), 0); + /* RX_LOS Ports 41-48 */ + VALIDATED_READ(buf, values[5], as5812_54x_i2c_cpld_read(0x62, 0x11), 0); + + /** Return values 1 -> 48 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5]); + } + + if(attr->index == SFP_IS_PRESENT_ALL) { + /* + * Report the SFP_PRESENCE status for all ports. + * This does not depend on the currently active SFP selector. + */ + + /* SFP_PRESENT Ports 1-8 */ + VALIDATED_READ(buf, values[0], as5812_54x_i2c_cpld_read(0x61, 0x6), 1); + /* SFP_PRESENT Ports 9-16 */ + VALIDATED_READ(buf, values[1], as5812_54x_i2c_cpld_read(0x61, 0x7), 1); + /* SFP_PRESENT Ports 17-24 */ + VALIDATED_READ(buf, values[2], as5812_54x_i2c_cpld_read(0x61, 0x8), 1); + /* SFP_PRESENT Ports 25-32 */ + VALIDATED_READ(buf, values[3], as5812_54x_i2c_cpld_read(0x62, 0x6), 1); + /* SFP_PRESENT Ports 33-40 */ + VALIDATED_READ(buf, values[4], as5812_54x_i2c_cpld_read(0x62, 0x7), 1); + /* SFP_PRESENT Ports 41-48 */ + VALIDATED_READ(buf, values[5], as5812_54x_i2c_cpld_read(0x62, 0x8), 1); + /* QSFP_PRESENT Ports 49-54 */ + VALIDATED_READ(buf, values[6], as5812_54x_i2c_cpld_read(0x62, 0x14), 1); + + /* Return values 1 -> 54 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5], + values[6] & 0x3F); + } + /* + * The remaining attributes are gathered on a per-selected-sfp basis. + */ + data = as5812_54x_sfp_update_device(dev, 0); + if (attr->index == SFP_IS_PRESENT) { + val = (data->status[attr->index] & BIT_INDEX(data->port)) ? 0 : 1; + } + else { + val = (data->status[attr->index] & BIT_INDEX(data->port)) ? 1 : 0; + } + + return sprintf(buf, "%d", val); +} + +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + unsigned short cpld_addr = 0; + u8 cpld_reg = 0, cpld_val = 0, cpld_bit = 0; + long disable; + int error; + + /* Tx disable is not supported for QSFP ports(49-54) */ + if (data->port >= 48) { + return -EINVAL; + } + + error = kstrtol(buf, 10, &disable); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + if(data->port < 24) { + cpld_addr = 0x61; + cpld_reg = 0xC + data->port / 8; + cpld_bit = 1 << (data->port % 8); + } + else { + cpld_addr = 0x62; + cpld_reg = 0xC + (data->port - 24) / 8; + cpld_bit = 1 << (data->port % 8); + } + + cpld_val = as5812_54x_i2c_cpld_read(cpld_addr, cpld_reg); + + /* Update tx_disable status */ + if (disable) { + data->status[SFP_TX_DISABLE] |= BIT_INDEX(data->port); + cpld_val |= cpld_bit; + } + else { + data->status[SFP_TX_DISABLE] &= ~BIT_INDEX(data->port); + cpld_val &= ~cpld_bit; + } + + as5812_54x_i2c_cpld_write(cpld_addr, cpld_reg, cpld_val); + + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as5812_54x_sfp_data *data = as5812_54x_sfp_update_device(dev, 1); + + if (!data->valid) { + return 0; + } + + if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) != 0) { + return 0; + } + + memcpy(buf, data->eeprom, sizeof(data->eeprom)); + + return sizeof(data->eeprom); +} + +static const struct attribute_group as5812_54x_sfp_group = { + .attrs = as5812_54x_sfp_attributes, +}; + +static int as5812_54x_sfp_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as5812_54x_sfp_data *data; + int status; + + extern int platform_accton_as5812_54x(void); + if(!platform_accton_as5812_54x()) { + return -ENODEV; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as5812_54x_sfp_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + i2c_set_clientdata(client, data); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as5812_54x_sfp_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: sfp '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as5812_54x_sfp_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as5812_54x_sfp_remove(struct i2c_client *client) +{ + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as5812_54x_sfp_group); + kfree(data); + + return 0; +} + +enum port_numbers { +as5812_54x_sfp1, as5812_54x_sfp2, as5812_54x_sfp3, as5812_54x_sfp4, +as5812_54x_sfp5, as5812_54x_sfp6, as5812_54x_sfp7, as5812_54x_sfp8, +as5812_54x_sfp9, as5812_54x_sfp10, as5812_54x_sfp11,as5812_54x_sfp12, +as5812_54x_sfp13, as5812_54x_sfp14, as5812_54x_sfp15,as5812_54x_sfp16, +as5812_54x_sfp17, as5812_54x_sfp18, as5812_54x_sfp19,as5812_54x_sfp20, +as5812_54x_sfp21, as5812_54x_sfp22, as5812_54x_sfp23,as5812_54x_sfp24, +as5812_54x_sfp25, as5812_54x_sfp26, as5812_54x_sfp27,as5812_54x_sfp28, +as5812_54x_sfp29, as5812_54x_sfp30, as5812_54x_sfp31,as5812_54x_sfp32, +as5812_54x_sfp33, as5812_54x_sfp34, as5812_54x_sfp35,as5812_54x_sfp36, +as5812_54x_sfp37, as5812_54x_sfp38, as5812_54x_sfp39,as5812_54x_sfp40, +as5812_54x_sfp41, as5812_54x_sfp42, as5812_54x_sfp43,as5812_54x_sfp44, +as5812_54x_sfp45, as5812_54x_sfp46, as5812_54x_sfp47,as5812_54x_sfp48, +as5812_54x_sfp49, as5812_54x_sfp52, as5812_54x_sfp50,as5812_54x_sfp53, +as5812_54x_sfp51, as5812_54x_sfp54 +}; + +static const struct i2c_device_id as5812_54x_sfp_id[] = { +{ "as5812_54x_sfp1", as5812_54x_sfp1 }, { "as5812_54x_sfp2", as5812_54x_sfp2 }, +{ "as5812_54x_sfp3", as5812_54x_sfp3 }, { "as5812_54x_sfp4", as5812_54x_sfp4 }, +{ "as5812_54x_sfp5", as5812_54x_sfp5 }, { "as5812_54x_sfp6", as5812_54x_sfp6 }, +{ "as5812_54x_sfp7", as5812_54x_sfp7 }, { "as5812_54x_sfp8", as5812_54x_sfp8 }, +{ "as5812_54x_sfp9", as5812_54x_sfp9 }, { "as5812_54x_sfp10", as5812_54x_sfp10 }, +{ "as5812_54x_sfp11", as5812_54x_sfp11 }, { "as5812_54x_sfp12", as5812_54x_sfp12 }, +{ "as5812_54x_sfp13", as5812_54x_sfp13 }, { "as5812_54x_sfp14", as5812_54x_sfp14 }, +{ "as5812_54x_sfp15", as5812_54x_sfp15 }, { "as5812_54x_sfp16", as5812_54x_sfp16 }, +{ "as5812_54x_sfp17", as5812_54x_sfp17 }, { "as5812_54x_sfp18", as5812_54x_sfp18 }, +{ "as5812_54x_sfp19", as5812_54x_sfp19 }, { "as5812_54x_sfp20", as5812_54x_sfp20 }, +{ "as5812_54x_sfp21", as5812_54x_sfp21 }, { "as5812_54x_sfp22", as5812_54x_sfp22 }, +{ "as5812_54x_sfp23", as5812_54x_sfp23 }, { "as5812_54x_sfp24", as5812_54x_sfp24 }, +{ "as5812_54x_sfp25", as5812_54x_sfp25 }, { "as5812_54x_sfp26", as5812_54x_sfp26 }, +{ "as5812_54x_sfp27", as5812_54x_sfp27 }, { "as5812_54x_sfp28", as5812_54x_sfp28 }, +{ "as5812_54x_sfp29", as5812_54x_sfp29 }, { "as5812_54x_sfp30", as5812_54x_sfp30 }, +{ "as5812_54x_sfp31", as5812_54x_sfp31 }, { "as5812_54x_sfp32", as5812_54x_sfp32 }, +{ "as5812_54x_sfp33", as5812_54x_sfp33 }, { "as5812_54x_sfp34", as5812_54x_sfp34 }, +{ "as5812_54x_sfp35", as5812_54x_sfp35 }, { "as5812_54x_sfp36", as5812_54x_sfp36 }, +{ "as5812_54x_sfp37", as5812_54x_sfp37 }, { "as5812_54x_sfp38", as5812_54x_sfp38 }, +{ "as5812_54x_sfp39", as5812_54x_sfp39 }, { "as5812_54x_sfp40", as5812_54x_sfp40 }, +{ "as5812_54x_sfp41", as5812_54x_sfp41 }, { "as5812_54x_sfp42", as5812_54x_sfp42 }, +{ "as5812_54x_sfp43", as5812_54x_sfp43 }, { "as5812_54x_sfp44", as5812_54x_sfp44 }, +{ "as5812_54x_sfp45", as5812_54x_sfp45 }, { "as5812_54x_sfp46", as5812_54x_sfp46 }, +{ "as5812_54x_sfp47", as5812_54x_sfp47 }, { "as5812_54x_sfp48", as5812_54x_sfp48 }, +{ "as5812_54x_sfp49", as5812_54x_sfp49 }, { "as5812_54x_sfp50", as5812_54x_sfp50 }, +{ "as5812_54x_sfp51", as5812_54x_sfp51 }, { "as5812_54x_sfp52", as5812_54x_sfp52 }, +{ "as5812_54x_sfp53", as5812_54x_sfp53 }, { "as5812_54x_sfp54", as5812_54x_sfp54 }, + +{} +}; +MODULE_DEVICE_TABLE(i2c, as5812_54x_sfp_id); + +static struct i2c_driver as5812_54x_sfp_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as5812_54x_sfp", + }, + .probe = as5812_54x_sfp_probe, + .remove = as5812_54x_sfp_remove, + .id_table = as5812_54x_sfp_id, + .address_list = normal_i2c, +}; + +static int as5812_54x_sfp_read_byte(struct i2c_client *client, u8 command, u8 *data) +{ + int result = i2c_smbus_read_byte_data(client, command); + + if (unlikely(result < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, result); + goto abort; + } + + *data = (u8)result; + result = 0; + +abort: + return result; +} + +#define ALWAYS_UPDATE_DEVICE 1 + +static struct as5812_54x_sfp_data *as5812_54x_sfp_update_device(struct device *dev, int update_eeprom) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54x_sfp_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (ALWAYS_UPDATE_DEVICE || time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status = -1; + int i = 0, j = 0; + + data->valid = 0; + //dev_dbg(&client->dev, "Starting as5812_54x sfp status update\n"); + memset(data->status, 0, sizeof(data->status)); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 2; i++) { + for (j = 0; j < 12; j++) { + status = as5812_54x_i2c_cpld_read(0x61+i, 0x6+j); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", 0x61+i, 0x6+j, status); + goto exit; + } + + data->status[j/3] |= (u64)status << ((i*24) + (j%3)*8); + } + } + + /* + * Bring QSFPs out of reset, + * This is a temporary fix until the QSFP+_MOD_RST register + * can be exposed through the driver. + */ + as5812_54x_i2c_cpld_write(0x62, 0x15, 0x3F); + + /* Read present status of port 49-54(QSFP port) */ + status = as5812_54x_i2c_cpld_read(0x62, 0x14); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", 0x61+i, 0x6+j, status); + } + else { + data->status[SFP_IS_PRESENT] |= (u64)status << 48; + } + + if (update_eeprom) { + /* Read eeprom data based on port number */ + memset(data->eeprom, 0, sizeof(data->eeprom)); + + /* Check if the port is present */ + if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) == 0) { + /* read eeprom */ + for (i = 0; i < sizeof(data->eeprom); i++) { + status = as5812_54x_sfp_read_byte(client, i, data->eeprom + i); + + if (status < 0) { + dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n", + CPLD_PORT_TO_FRONT_PORT(data->port)); + goto exit; + } + } + } + } + + data->valid = 1; + data->last_updated = jiffies; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(as5812_54x_sfp_driver); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as5812_54x_sfp driver"); +MODULE_LICENSE("GPL"); diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/onlp/builds/src/module/src/sfpi.c b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/onlp/builds/src/module/src/sfpi.c index f731e0d3..6cfa29a9 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/onlp/builds/src/module/src/sfpi.c +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/onlp/builds/src/module/src/sfpi.c @@ -24,24 +24,20 @@ * ***********************************************************/ #include -#include -#include -#include "x86_64_accton_as5812_54x_int.h" -#include "x86_64_accton_as5812_54x_log.h" +#include /* For O_RDWR && open */ +#include +#include +#include +#include +#include +#include "platform_lib.h" + +#define MAX_SFP_PATH 64 +static char sfp_node_path[MAX_SFP_PATH] = {0}; #define CPLD_MUX_BUS_START_INDEX 2 -#define PORT_EEPROM_FORMAT "/sys/bus/i2c/devices/%d-0050/eeprom" -#define MODULE_PRESENT_FORMAT "/sys/bus/i2c/devices/0-00%d/module_present_%d" -#define MODULE_RXLOS_FORMAT "/sys/bus/i2c/devices/0-00%d/module_rx_los_%d" -#define MODULE_TXFAULT_FORMAT "/sys/bus/i2c/devices/0-00%d/module_tx_fault_%d" -#define MODULE_TXDISABLE_FORMAT "/sys/bus/i2c/devices/0-00%d/module_tx_disable_%d" -#define MODULE_PRESENT_ALL_ATTR_CPLD2 "/sys/bus/i2c/devices/0-0061/module_present_all" -#define MODULE_PRESENT_ALL_ATTR_CPLD3 "/sys/bus/i2c/devices/0-0062/module_present_all" -#define MODULE_RXLOS_ALL_ATTR_CPLD2 "/sys/bus/i2c/devices/0-0061/module_rx_los_all" -#define MODULE_RXLOS_ALL_ATTR_CPLD3 "/sys/bus/i2c/devices/0-0062/module_rx_los_all" - -static int front_port_bus_index(int port) +static int front_port_to_cpld_mux_index(int port) { int rport = 0; @@ -67,6 +63,38 @@ static int front_port_bus_index(int port) return (rport + CPLD_MUX_BUS_START_INDEX); } +static int +as5812_54x_sfp_node_read_int(char *node_path, int *value, int data_len) +{ + int ret = 0; + char buf[8] = {0}; + *value = 0; + + ret = deviceNodeReadString(node_path, buf, sizeof(buf), data_len); + + if (ret == 0) { + *value = atoi(buf); + } + + return ret; +} + +static char* +as5812_54x_sfp_get_port_path_addr(int port, int addr, char *node_name) +{ + sprintf(sfp_node_path, "/sys/bus/i2c/devices/%d-00%d/%s", + front_port_to_cpld_mux_index(port), addr, + node_name); + return sfp_node_path; +} + +static char* +as5812_54x_sfp_get_port_path(int port, char *node_name) +{ + return as5812_54x_sfp_get_port_path_addr(port, 50, node_name); +} + + /************************************************************ * * SFPI Entry Points @@ -175,10 +203,10 @@ onlp_sfpi_is_present(int port) * Return < 0 if error. */ int present; - int addr = (port < 24) ? 61 : 62; - - if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT, addr, (port+1)) < 0) { - AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port); + char* path = as5812_54x_sfp_get_port_path(port, "sfp_is_present"); + + if (as5812_54x_sfp_node_read_int(path, &present, 1) != 0) { + AIM_LOG_INFO("Unable to read present status from port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; } @@ -189,35 +217,29 @@ int onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) { uint32_t bytes[7]; + char* path; FILE* fp; - /* Read present status of port 0~23 */ - fp = fopen(MODULE_PRESENT_ALL_ATTR_CPLD2, "r"); + path = as5812_54x_sfp_get_port_path(0, "sfp_is_present_all"); + fp = fopen(path, "r"); + if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the module_present_all device file of CPLD2."); + AIM_LOG_ERROR("Unable to open the sfp_is_present_all device file."); return ONLP_STATUS_E_INTERNAL; } - - int count = fscanf(fp, "%x %x %x", bytes+0, bytes+1, bytes+2); + int count = fscanf(fp, "%x %x %x %x %x %x %x", + bytes+0, + bytes+1, + bytes+2, + bytes+3, + bytes+4, + bytes+5, + bytes+6 + ); fclose(fp); - if(count != 3) { + if(count != AIM_ARRAYSIZE(bytes)) { /* Likely a CPLD read timeout. */ - AIM_LOG_ERROR("Unable to read all fields the module_present_all device file of CPLD2."); - return ONLP_STATUS_E_INTERNAL; - } - - /* Read present status of port 24~53 */ - fp = fopen(MODULE_PRESENT_ALL_ATTR_CPLD3, "r"); - if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the module_present_all device file of CPLD3."); - return ONLP_STATUS_E_INTERNAL; - } - - count = fscanf(fp, "%x %x %x %x", bytes+3, bytes+4, bytes+5, bytes+6); - fclose(fp); - if(count != 4) { - /* Likely a CPLD read timeout. */ - AIM_LOG_ERROR("Unable to read all fields the module_present_all device file of CPLD3."); + AIM_LOG_ERROR("Unable to read all fields from the sfp_is_present_all device file."); return ONLP_STATUS_E_INTERNAL; } @@ -246,39 +268,33 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) int onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) { - uint32_t bytes[6]; - uint32_t *ptr = bytes; + uint32_t bytes[7]; + char* path; FILE* fp; - /* Read present status of port 0~23 */ - int addr, i = 0; + path = as5812_54x_sfp_get_port_path(0, "sfp_rx_los_all"); + fp = fopen(path, "r"); - for (addr = 61; addr <= 62; addr++) { - if (addr == 61) { - fp = fopen(MODULE_RXLOS_ALL_ATTR_CPLD2, "r"); - } - else { - fp = fopen(MODULE_RXLOS_ALL_ATTR_CPLD3, "r"); - } - - if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the module_rx_los_all device file of CPLD(0x%d)", addr); - return ONLP_STATUS_E_INTERNAL; - } - - int count = fscanf(fp, "%x %x %x", ptr+0, ptr+1, ptr+2); - fclose(fp); - if(count != 3) { - /* Likely a CPLD read timeout. */ - AIM_LOG_ERROR("Unable to read all fields from the module_rx_los_all device file of CPLD(0x%d)", addr); - return ONLP_STATUS_E_INTERNAL; - } - - ptr += count; + if(fp == NULL) { + AIM_LOG_ERROR("Unable to open the sfp_rx_los_all device file."); + return ONLP_STATUS_E_INTERNAL; + } + int count = fscanf(fp, "%x %x %x %x %x %x", + bytes+0, + bytes+1, + bytes+2, + bytes+3, + bytes+4, + bytes+5 + ); + fclose(fp); + if(count != 6) { + AIM_LOG_ERROR("Unable to read all fields from the sfp_rx_los_all device file."); + return ONLP_STATUS_E_INTERNAL; } /* Convert to 64 bit integer in port order */ - i = 0; + int i = 0; uint64_t rx_los_all = 0 ; for(i = 5; i >= 0; i--) { rx_los_all <<= 8; @@ -299,22 +315,18 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) int onlp_sfpi_eeprom_read(int port, uint8_t data[256]) { + char* path = as5812_54x_sfp_get_port_path(port, "sfp_eeprom"); + /* * Read the SFP eeprom into data[] * * Return MISSING if SFP is missing. * Return OK if eeprom is read */ - int size = 0; memset(data, 0, 256); - if(onlp_file_read(data, 256, &size, PORT_EEPROM_FORMAT, front_port_bus_index(port)) != ONLP_STATUS_OK) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); - return ONLP_STATUS_E_INTERNAL; - } - - if (size != 256) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is different!\r\n", port); + if (deviceNodeReadBinary(path, (char*)data, 256, 256) != 0) { + AIM_LOG_INFO("Unable to read eeprom from port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; } @@ -324,26 +336,11 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256]) int onlp_sfpi_dom_read(int port, uint8_t data[256]) { - FILE* fp; - char file[64] = {0}; - - sprintf(file, PORT_EEPROM_FORMAT, front_port_bus_index(port)); - fp = fopen(file, "r"); - if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", port); - return ONLP_STATUS_E_INTERNAL; - } + char* path = as5812_54x_sfp_get_port_path_addr(port, 51, "sfp_eeprom"); + memset(data, 0, 256); - if (fseek(fp, 256, SEEK_CUR) != 0) { - fclose(fp); - AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", port); - return ONLP_STATUS_E_INTERNAL; - } - - int ret = fread(data, 1, 256, fp); - fclose(fp); - if (ret != 256) { - AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d)", port); + if (deviceNodeReadBinary(path, (char*)data, 256, 256) != 0) { + AIM_LOG_INFO("Unable to read eeprom from port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; } @@ -353,28 +350,28 @@ onlp_sfpi_dom_read(int port, uint8_t data[256]) int onlp_sfpi_dev_readb(int port, uint8_t devaddr, uint8_t addr) { - int bus = front_port_bus_index(port); + int bus = front_port_to_cpld_mux_index(port); return onlp_i2c_readb(bus, devaddr, addr, ONLP_I2C_F_FORCE); } int onlp_sfpi_dev_writeb(int port, uint8_t devaddr, uint8_t addr, uint8_t value) { - int bus = front_port_bus_index(port); + int bus = front_port_to_cpld_mux_index(port); return onlp_i2c_writeb(bus, devaddr, addr, value, ONLP_I2C_F_FORCE); } int onlp_sfpi_dev_readw(int port, uint8_t devaddr, uint8_t addr) { - int bus = front_port_bus_index(port); + int bus = front_port_to_cpld_mux_index(port); return onlp_i2c_readw(bus, devaddr, addr, ONLP_I2C_F_FORCE); } int onlp_sfpi_dev_writew(int port, uint8_t devaddr, uint8_t addr, uint16_t value) { - int bus = front_port_bus_index(port); + int bus = front_port_to_cpld_mux_index(port); return onlp_i2c_writew(bus, devaddr, addr, value, ONLP_I2C_F_FORCE); } @@ -387,13 +384,13 @@ onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) return ONLP_STATUS_E_UNSUPPORTED; } - int addr = (port < 24) ? 61 : 62; - switch(control) { case ONLP_SFP_CONTROL_TX_DISABLE: { - if (onlp_file_write_int(value, MODULE_TXDISABLE_FORMAT, addr, (port+1)) < 0) { + char* path = as5812_54x_sfp_get_port_path(port, "sfp_tx_disable"); + + if (deviceNodeWriteInt(path, value, 0) != 0) { AIM_LOG_ERROR("Unable to set tx_disable status to port(%d)\r\n", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -415,18 +412,19 @@ int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { int rv; + char* path = NULL; if (port < 0 || port >= 48) { return ONLP_STATUS_E_UNSUPPORTED; } - int addr = (port < 24) ? 61 : 62; - switch(control) { case ONLP_SFP_CONTROL_RX_LOS: { - if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, addr, (port+1)) < 0) { + path = as5812_54x_sfp_get_port_path(port, "sfp_rx_loss"); + + if (as5812_54x_sfp_node_read_int(path, value, 1) != 0) { AIM_LOG_ERROR("Unable to read rx_loss status from port(%d)\r\n", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -438,7 +436,9 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) case ONLP_SFP_CONTROL_TX_FAULT: { - if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, addr, (port+1)) < 0) { + path = as5812_54x_sfp_get_port_path(port, "sfp_tx_fault"); + + if (as5812_54x_sfp_node_read_int(path, value, 1) != 0) { AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -450,7 +450,9 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) case ONLP_SFP_CONTROL_TX_DISABLE: { - if (onlp_file_read_int(value, MODULE_TXDISABLE_FORMAT, addr, (port+1)) < 0) { + path = as5812_54x_sfp_get_port_path(port, "sfp_tx_disable"); + + if (as5812_54x_sfp_node_read_int(path, value, 0) != 0) { AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port); rv = ONLP_STATUS_E_INTERNAL; } diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/platform-config/r0/src/python/x86_64_accton_as5812_54x_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/platform-config/r0/src/python/x86_64_accton_as5812_54x_r0/__init__.py index b6505028..5eee6748 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/platform-config/r0/src/python/x86_64_accton_as5812_54x_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/platform-config/r0/src/python/x86_64_accton_as5812_54x_r0/__init__.py @@ -9,10 +9,9 @@ class OnlPlatform_x86_64_accton_as5812_54x_r0(OnlPlatformAccton, SYS_OBJECT_ID=".5812.54.1" def baseconfig(self): - self.insmod('optoe') self.insmod('cpr_4011_4mxx') self.insmod("ym2651y") - for m in [ 'cpld', 'fan', 'psu', 'leds' ]: + for m in [ 'cpld', 'fan', 'psu', 'leds', 'sfp' ]: self.insmod("x86-64-accton-as5812-54x-%s.ko" % m) ########### initialize I2C bus 0 ########### @@ -27,18 +26,16 @@ class OnlPlatform_x86_64_accton_as5812_54x_r0(OnlPlatformAccton, ) # initialize SFP devices for port in range(1, 49): - self.new_i2c_device('optoe2', 0x50, port+1) - subprocess.call('echo port%d > /sys/bus/i2c/devices/%d-0050/port_name' % (port, port+1), shell=True) + self.new_i2c_device('as5812_54x_sfp%d' % port, 0x50, port+1) + self.new_i2c_device('as5812_54x_sfp%d' % port, 0x51, port+1) # Initialize QSFP devices - for port in range(49, 55): - self.new_i2c_device('optoe1', 0x50, port+1) - subprocess.call('echo port49 > /sys/bus/i2c/devices/50-0050/port_name', shell=True) - subprocess.call('echo port52 > /sys/bus/i2c/devices/51-0050/port_name', shell=True) - subprocess.call('echo port50 > /sys/bus/i2c/devices/52-0050/port_name', shell=True) - subprocess.call('echo port53 > /sys/bus/i2c/devices/53-0050/port_name', shell=True) - subprocess.call('echo port51 > /sys/bus/i2c/devices/54-0050/port_name', shell=True) - subprocess.call('echo port54 > /sys/bus/i2c/devices/55-0050/port_name', shell=True) + self.new_i2c_device('as5812_54x_sfp49', 0x50, 50) + self.new_i2c_device('as5812_54x_sfp52', 0x50, 51) + self.new_i2c_device('as5812_54x_sfp50', 0x50, 52) + self.new_i2c_device('as5812_54x_sfp53', 0x50, 53) + self.new_i2c_device('as5812_54x_sfp51', 0x50, 54) + self.new_i2c_device('as5812_54x_sfp54', 0x50, 55) ########### initialize I2C bus 1 ########### self.new_i2c_devices(