diff --git a/packages/base/any/kernels/5.15-lts/configs/arm64-all/Makefile b/packages/base/any/kernels/5.15-lts/configs/arm64-all/Makefile index fd96792a6..5e50fac24 100644 --- a/packages/base/any/kernels/5.15-lts/configs/arm64-all/Makefile +++ b/packages/base/any/kernels/5.15-lts/configs/arm64-all/Makefile @@ -15,7 +15,7 @@ K_PATCH_SERIES=series.arm64 include ../../kconfig.mk K_CONFIG := arm64-all.config -K_BUILD_TARGET := Image Image.gz freescale/fsl-ls1043a-rdb.dtb freescale/fsl-ls1046a-rdb-sdk.dtb freescale/fsl-ls2080a-rdb.dtb freescale/fsl-ls2088a-rdb.dtb freescale/fsl-ls1088a-rdb.dtb +K_BUILD_TARGET := Image Image.gz freescale/fsl-ls1043a-rdb.dtb freescale/fsl-ls1046a-rdb-sdk.dtb freescale/fsl-ls2080a-rdb.dtb freescale/fsl-ls2088a-rdb.dtb freescale/fsl-ls1088a-rdb.dtb marvell/accton-as4224.dtb marvell/accton-as5114.dtb marvell/accton-as4564-26p.dtb K_COPY_SRC := arch/arm64/boot/Image K_COPY_GZIP := 1 ifndef K_COPY_DST diff --git a/packages/platforms/accton/arm64/as4224/as4224-52p/modules/PKG.yml b/packages/platforms/accton/arm64/as4224/as4224-52p/modules/PKG.yml index a2296af30..247a46a33 100644 --- a/packages/platforms/accton/arm64/as4224/as4224-52p/modules/PKG.yml +++ b/packages/platforms/accton/arm64/as4224/as4224-52p/modules/PKG.yml @@ -1 +1 @@ -!include $ONL_TEMPLATES/platform-modules.yml ARCH=arm64 VENDOR=accton BASENAME=arm64-accton-as4224-52p KERNELS="onl-kernel-5.10-lts-arm64-all:arm64" +!include $ONL_TEMPLATES/platform-modules.yml ARCH=arm64 VENDOR=accton BASENAME=arm64-accton-as4224-52p KERNELS="onl-kernel-5.15-lts-arm64-all:arm64" diff --git a/packages/platforms/accton/arm64/as4224/as4224-52p/modules/builds/Makefile b/packages/platforms/accton/arm64/as4224/as4224-52p/modules/builds/Makefile index d73213f60..b0de05ba9 100644 --- a/packages/platforms/accton/arm64/as4224/as4224-52p/modules/builds/Makefile +++ b/packages/platforms/accton/arm64/as4224/as4224-52p/modules/builds/Makefile @@ -1,5 +1,5 @@ -KERNELS := onl-kernel-5.10-lts-arm64-all:arm64 -KMODULES := $(ONL)/packages/platforms/accton/arm64/as4224/src/modules-5_10/ +KERNELS := onl-kernel-5.15-lts-arm64-all:arm64 +KMODULES := $(ONL)/packages/platforms/accton/arm64/as4224/src/modules/ VENDOR := accton BASENAME := arm64-accton-as4224-52p ARCH := arm64 diff --git a/packages/platforms/accton/arm64/as4224/as4224-52p/platform-config/r0/src/lib/arm64-accton-as4224-52p-r0.yml b/packages/platforms/accton/arm64/as4224/as4224-52p/platform-config/r0/src/lib/arm64-accton-as4224-52p-r0.yml index 1c347824a..ab28a69ca 100644 --- a/packages/platforms/accton/arm64/as4224/as4224-52p/platform-config/r0/src/lib/arm64-accton-as4224-52p-r0.yml +++ b/packages/platforms/accton/arm64/as4224/as4224-52p/platform-config/r0/src/lib/arm64-accton-as4224-52p-r0.yml @@ -9,10 +9,10 @@ arm64-accton-as4224-52p-r0: flat_image_tree: kernel: - <<: *arm64-kernel-5-10 + <<: *arm64-kernel-5-15 dtb: =: accton-as4224.dtb - <<: *arm64-kernel-5-10-package + <<: *arm64-kernel-5-15-package itb: <<: *arm64-itb diff --git a/packages/platforms/accton/arm64/as4224/as4224-52t/modules/PKG.yml b/packages/platforms/accton/arm64/as4224/as4224-52t/modules/PKG.yml index 13ca668ee..182a421c6 100644 --- a/packages/platforms/accton/arm64/as4224/as4224-52t/modules/PKG.yml +++ b/packages/platforms/accton/arm64/as4224/as4224-52t/modules/PKG.yml @@ -1 +1 @@ -!include $ONL_TEMPLATES/platform-modules.yml ARCH=arm64 VENDOR=accton BASENAME=arm64-accton-as4224-52t KERNELS="onl-kernel-5.10-lts-arm64-all:arm64" +!include $ONL_TEMPLATES/platform-modules.yml ARCH=arm64 VENDOR=accton BASENAME=arm64-accton-as4224-52t KERNELS="onl-kernel-5.15-lts-arm64-all:arm64" diff --git a/packages/platforms/accton/arm64/as4224/as4224-52t/modules/builds/Makefile b/packages/platforms/accton/arm64/as4224/as4224-52t/modules/builds/Makefile index 2a3cc488d..90803fafa 100644 --- a/packages/platforms/accton/arm64/as4224/as4224-52t/modules/builds/Makefile +++ b/packages/platforms/accton/arm64/as4224/as4224-52t/modules/builds/Makefile @@ -1,5 +1,5 @@ -KERNELS := onl-kernel-5.10-lts-arm64-all:arm64 -KMODULES := $(ONL)/packages/platforms/accton/arm64/as4224/src/modules-5_10/ +KERNELS := onl-kernel-5.15-lts-arm64-all:arm64 +KMODULES := $(ONL)/packages/platforms/accton/arm64/as4224/src/modules/ VENDOR := accton BASENAME := arm64-accton-as4224-52t ARCH := arm64 diff --git a/packages/platforms/accton/arm64/as4224/as4224-52t/platform-config/r0/src/lib/arm64-accton-as4224-52t-r0.yml b/packages/platforms/accton/arm64/as4224/as4224-52t/platform-config/r0/src/lib/arm64-accton-as4224-52t-r0.yml index 3a6551a2e..25ad136eb 100644 --- a/packages/platforms/accton/arm64/as4224/as4224-52t/platform-config/r0/src/lib/arm64-accton-as4224-52t-r0.yml +++ b/packages/platforms/accton/arm64/as4224/as4224-52t/platform-config/r0/src/lib/arm64-accton-as4224-52t-r0.yml @@ -9,10 +9,10 @@ arm64-accton-as4224-52t-r0: flat_image_tree: kernel: - <<: *arm64-kernel-5-10 + <<: *arm64-kernel-5-15 dtb: =: accton-as4224.dtb - <<: *arm64-kernel-5-10-package + <<: *arm64-kernel-5-15-package itb: <<: *arm64-itb diff --git a/packages/platforms/accton/arm64/as4224/as5114-48x/modules/PKG.yml b/packages/platforms/accton/arm64/as4224/as5114-48x/modules/PKG.yml index d8fb367c4..e45020b08 100644 --- a/packages/platforms/accton/arm64/as4224/as5114-48x/modules/PKG.yml +++ b/packages/platforms/accton/arm64/as4224/as5114-48x/modules/PKG.yml @@ -1 +1 @@ -!include $ONL_TEMPLATES/platform-modules.yml ARCH=arm64 VENDOR=accton BASENAME=arm64-accton-as5114-48x KERNELS="onl-kernel-5.10-lts-arm64-all:arm64" +!include $ONL_TEMPLATES/platform-modules.yml ARCH=arm64 VENDOR=accton BASENAME=arm64-accton-as5114-48x KERNELS="onl-kernel-5.15-lts-arm64-all:arm64" diff --git a/packages/platforms/accton/arm64/as4224/as5114-48x/modules/builds/Makefile b/packages/platforms/accton/arm64/as4224/as5114-48x/modules/builds/Makefile index 2b9df99e6..b79dacd5a 100644 --- a/packages/platforms/accton/arm64/as4224/as5114-48x/modules/builds/Makefile +++ b/packages/platforms/accton/arm64/as4224/as5114-48x/modules/builds/Makefile @@ -1,5 +1,5 @@ -KERNELS := onl-kernel-5.10-lts-arm64-all:arm64 -KMODULES := $(ONL)/packages/platforms/accton/arm64/as4224/src/modules-5_10/ +KERNELS := onl-kernel-5.15-lts-arm64-all:arm64 +KMODULES := $(ONL)/packages/platforms/accton/arm64/as4224/src/modules/ VENDOR := accton BASENAME := arm64-accton-as5114-48x ARCH := arm64 diff --git a/packages/platforms/accton/arm64/as4224/as5114-48x/platform-config/r0/src/lib/arm64-accton-as5114-48x-r0.yml b/packages/platforms/accton/arm64/as4224/as5114-48x/platform-config/r0/src/lib/arm64-accton-as5114-48x-r0.yml index 1abce11db..0d5d8cc9a 100644 --- a/packages/platforms/accton/arm64/as4224/as5114-48x/platform-config/r0/src/lib/arm64-accton-as5114-48x-r0.yml +++ b/packages/platforms/accton/arm64/as4224/as5114-48x/platform-config/r0/src/lib/arm64-accton-as5114-48x-r0.yml @@ -9,10 +9,10 @@ arm64-accton-as5114-48x-r0: flat_image_tree: kernel: - <<: *arm64-kernel-5-10 + <<: *arm64-kernel-5-15 dtb: =: accton-as5114.dtb - <<: *arm64-kernel-5-10-package + <<: *arm64-kernel-5-15-package itb: <<: *arm64-itb diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_6/.gitignore b/packages/platforms/accton/arm64/as4224/src/modules-5_6/.gitignore deleted file mode 100644 index e35baed35..000000000 --- a/packages/platforms/accton/arm64/as4224/src/modules-5_6/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -*.ko -*.mod* -*.o -*.a -Module.* -modules.order diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_6/Makefile b/packages/platforms/accton/arm64/as4224/src/modules-5_6/Makefile deleted file mode 100644 index 595bad396..000000000 --- a/packages/platforms/accton/arm64/as4224/src/modules-5_6/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-m += arm64-accton-as4224-cpld.o -obj-m += arm64-accton-as4224-fan.o -obj-m += arm64-accton-as4224-psu.o -obj-m += arm64-accton-as4224-gpio-i2c.o -obj-m += optoe.o \ No newline at end of file diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_6/arm64-accton-as4224-cpld.c b/packages/platforms/accton/arm64/as4224/src/modules-5_6/arm64-accton-as4224-cpld.c deleted file mode 100644 index b89d2b036..000000000 --- a/packages/platforms/accton/arm64/as4224/src/modules-5_6/arm64-accton-as4224-cpld.c +++ /dev/null @@ -1,1518 +0,0 @@ -/* - * Copyright (C) Brandon Chuang - * - * This module supports the accton cpld that hold the channel select - * mechanism for other i2c slave devices, such as SFP. - * This includes the: - * Accton as4224 CPLD1/CPLD2/CPLD3 - * - * Based on: - * pca954x.c from Kumar Gala - * Copyright (C) 2006 - * - * Based on: - * pca954x.c from Ken Harrenstien - * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) - * - * Based on: - * i2c-virtual_cb.c from Brian Kuschak - * and - * pca9540.c from Jean Delvare . - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRVNAME "as4224_cpld" - -#define I2C_RW_RETRY_COUNT 10 -#define I2C_RW_RETRY_INTERVAL 60 /* ms */ -#define BOARD_INFO_REG_OFFSET 0x00 -#define I2C_WRITE_REQUEST_REG 0xE0 -#define I2C_LOCK_BY_7040_VAL 0x10 -#define I2C_WRITE_REQUEST_7040_VAL 0x1 -#define I2C_WRITE_REQUEST_RETRY_TIMES 3 -#define WTD_RESET_GPIO_PIN_MPP3 35 - -static ssize_t show_module(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_module_48x(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_module_52x(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_control_48x(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static ssize_t set_control_52x(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 ssize_t show_platform_id(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t show_wtd(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t set_wtd(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static ssize_t reset_wtd(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static int as4224_cpld_read_internal(struct i2c_client *client, u8 reg); -static int as4224_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); -static ssize_t show_i2c_request(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t set_i2c_request(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); - -static LIST_HEAD(cpld_client_list); -static struct mutex list_lock; - -struct cpld_client_node { - struct i2c_client *client; - struct list_head list; -}; - -enum cpld_type { - as4224_cpld1 -}; - -enum as4224_platform_id { - AS5114_48X, - AS4224_52P, - AS4224_52T, - AS4224_52T_DAC, - PID_UNKNOWN -}; - -struct as4224_cpld_data { - enum cpld_type type; - struct device *hwmon_dev; - struct mutex update_lock; - enum as4224_platform_id platform_id; -}; - -static const struct i2c_device_id as4224_cpld_id[] = { - { "as4224_cpld1", as4224_cpld1 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, as4224_cpld_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 as4224_cpld_sysfs_attributes { - PLATFORM_ID, - CPLD_VERSION, - ACCESS, - I2C_ACCESS_REQUEST_7040, - WTD_RESET_7040, /* Trigger GPIO to reset wtd timer */ - WTD_STATE_7040, /* Register 0x90 bit 1 */ - WTD_ENABLE_7040, /* Register 0x91 bit 1 */ - WTD_CLOCK_7040, /* Register 0x92 bit 7:6 */ - WTD_COUNTER_7040, /* Register 0x92 bit 5:0 */ - MODULE_PRESENT_ALL, - MODULE_RXLOS_ALL, - MODULE_COUNT, - MODULE_INDEX_BEGIN, - /* 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_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_TXDISABLE_ATTR_ID(49), - TRANSCEIVER_TXDISABLE_ATTR_ID(50), - TRANSCEIVER_TXDISABLE_ATTR_ID(51), - TRANSCEIVER_TXDISABLE_ATTR_ID(52), - 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_RXLOS_ATTR_ID(49), - TRANSCEIVER_RXLOS_ATTR_ID(50), - TRANSCEIVER_RXLOS_ATTR_ID(51), - TRANSCEIVER_RXLOS_ATTR_ID(52), - 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), - TRANSCEIVER_TXFAULT_ATTR_ID(49), - TRANSCEIVER_TXFAULT_ATTR_ID(50), - TRANSCEIVER_TXFAULT_ATTR_ID(51), - TRANSCEIVER_TXFAULT_ATTR_ID(52), -}; - -/* sysfs attributes for hwmon - */ -static SENSOR_DEVICE_ATTR(platform_id, S_IRUGO, show_platform_id, NULL, PLATFORM_ID); -static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); -static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); -static SENSOR_DEVICE_ATTR(wtd_reset_7040, S_IWUSR, NULL, reset_wtd, WTD_RESET_7040); -static SENSOR_DEVICE_ATTR(wtd_state_7040, S_IRUGO, show_wtd, NULL, WTD_STATE_7040); -static SENSOR_DEVICE_ATTR(wtd_enable_7040, S_IRUGO | S_IWUSR, show_wtd, set_wtd, WTD_ENABLE_7040); -static SENSOR_DEVICE_ATTR(wtd_clock_7040, S_IRUGO | S_IWUSR, show_wtd, set_wtd, WTD_CLOCK_7040); -static SENSOR_DEVICE_ATTR(wtd_counter_7040, S_IRUGO | S_IWUSR, show_wtd, set_wtd, WTD_COUNTER_7040); -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); -static SENSOR_DEVICE_ATTR(module_count, S_IRUGO, show_module, NULL, MODULE_COUNT); -static SENSOR_DEVICE_ATTR(module_index_begin, S_IRUGO, show_module, NULL, MODULE_INDEX_BEGIN); -static SENSOR_DEVICE_ATTR(i2c_access_request_7040, S_IRUGO | S_IWUSR, show_i2c_request, set_i2c_request, I2C_ACCESS_REQUEST_7040); - -static struct attribute *cpld_attributes_common[] = { - &sensor_dev_attr_platform_id.dev_attr.attr, - &sensor_dev_attr_version.dev_attr.attr, - &sensor_dev_attr_access.dev_attr.attr, - &sensor_dev_attr_i2c_access_request_7040.dev_attr.attr, - &sensor_dev_attr_wtd_reset_7040.dev_attr.attr, - &sensor_dev_attr_wtd_state_7040.dev_attr.attr, - &sensor_dev_attr_wtd_enable_7040.dev_attr.attr, - &sensor_dev_attr_wtd_clock_7040.dev_attr.attr, - &sensor_dev_attr_wtd_counter_7040.dev_attr.attr, - &sensor_dev_attr_module_present_all.dev_attr.attr, - &sensor_dev_attr_module_rx_los_all.dev_attr.attr, - &sensor_dev_attr_module_count.dev_attr.attr, - &sensor_dev_attr_module_index_begin.dev_attr.attr, - NULL -}; - -#define CPLD_ATTRS_COMMON() { .attrs = cpld_attributes_common } - -#define MODULE_ATTRS(index) \ - static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_module_52x, NULL, MODULE_PRESENT_##index); \ - static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_module_52x, set_control_52x, MODULE_TXDISABLE_##index); \ - static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_module_52x, NULL, MODULE_RXLOS_##index); \ - static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_module_52x, NULL, MODULE_TXFAULT_##index); \ - static struct attribute *module_attributes##index[] = { \ - &sensor_dev_attr_module_present_##index.dev_attr.attr, \ - &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, \ - NULL \ - } - -MODULE_ATTRS(1); -MODULE_ATTRS(2); -MODULE_ATTRS(3); -MODULE_ATTRS(4); -MODULE_ATTRS(5); -MODULE_ATTRS(6); -MODULE_ATTRS(7); -MODULE_ATTRS(8); -MODULE_ATTRS(9); -MODULE_ATTRS(10); -MODULE_ATTRS(11); -MODULE_ATTRS(12); -MODULE_ATTRS(13); -MODULE_ATTRS(14); -MODULE_ATTRS(15); -MODULE_ATTRS(16); -MODULE_ATTRS(17); -MODULE_ATTRS(18); -MODULE_ATTRS(19); -MODULE_ATTRS(20); -MODULE_ATTRS(21); -MODULE_ATTRS(22); -MODULE_ATTRS(23); -MODULE_ATTRS(24); -MODULE_ATTRS(25); -MODULE_ATTRS(26); -MODULE_ATTRS(27); -MODULE_ATTRS(28); -MODULE_ATTRS(29); -MODULE_ATTRS(30); -MODULE_ATTRS(31); -MODULE_ATTRS(32); -MODULE_ATTRS(33); -MODULE_ATTRS(34); -MODULE_ATTRS(35); -MODULE_ATTRS(36); -MODULE_ATTRS(37); -MODULE_ATTRS(38); -MODULE_ATTRS(39); -MODULE_ATTRS(40); -MODULE_ATTRS(41); -MODULE_ATTRS(42); -MODULE_ATTRS(43); -MODULE_ATTRS(44); -MODULE_ATTRS(45); -MODULE_ATTRS(46); -MODULE_ATTRS(47); -MODULE_ATTRS(48); -MODULE_ATTRS(49); -MODULE_ATTRS(50); -MODULE_ATTRS(51); -MODULE_ATTRS(52); - -#define MODULE_ATTR_GROUP(index) { .attrs = module_attributes##index } - -static struct attribute_group cpld_group[] = { - CPLD_ATTRS_COMMON(), - MODULE_ATTR_GROUP(1), - MODULE_ATTR_GROUP(2), - MODULE_ATTR_GROUP(3), - MODULE_ATTR_GROUP(4), - MODULE_ATTR_GROUP(5), - MODULE_ATTR_GROUP(6), - MODULE_ATTR_GROUP(7), - MODULE_ATTR_GROUP(8), - MODULE_ATTR_GROUP(9), - MODULE_ATTR_GROUP(10), - MODULE_ATTR_GROUP(11), - MODULE_ATTR_GROUP(12), - MODULE_ATTR_GROUP(13), - MODULE_ATTR_GROUP(14), - MODULE_ATTR_GROUP(15), - MODULE_ATTR_GROUP(16), - MODULE_ATTR_GROUP(17), - MODULE_ATTR_GROUP(18), - MODULE_ATTR_GROUP(19), - MODULE_ATTR_GROUP(20), - MODULE_ATTR_GROUP(21), - MODULE_ATTR_GROUP(22), - MODULE_ATTR_GROUP(23), - MODULE_ATTR_GROUP(24), - MODULE_ATTR_GROUP(25), - MODULE_ATTR_GROUP(26), - MODULE_ATTR_GROUP(27), - MODULE_ATTR_GROUP(28), - MODULE_ATTR_GROUP(29), - MODULE_ATTR_GROUP(30), - MODULE_ATTR_GROUP(31), - MODULE_ATTR_GROUP(32), - MODULE_ATTR_GROUP(33), - MODULE_ATTR_GROUP(34), - MODULE_ATTR_GROUP(35), - MODULE_ATTR_GROUP(36), - MODULE_ATTR_GROUP(37), - MODULE_ATTR_GROUP(38), - MODULE_ATTR_GROUP(39), - MODULE_ATTR_GROUP(40), - MODULE_ATTR_GROUP(41), - MODULE_ATTR_GROUP(42), - MODULE_ATTR_GROUP(43), - MODULE_ATTR_GROUP(44), - MODULE_ATTR_GROUP(45), - MODULE_ATTR_GROUP(46), - MODULE_ATTR_GROUP(47), - MODULE_ATTR_GROUP(48), - MODULE_ATTR_GROUP(49), - MODULE_ATTR_GROUP(50), - MODULE_ATTR_GROUP(51), - MODULE_ATTR_GROUP(52), -}; - -static int get_platform_id(struct i2c_client *client) -{ - int status; - - status = as4224_cpld_read_internal(client, BOARD_INFO_REG_OFFSET); - if (status < 0) { - dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", client->addr, status); - return PID_UNKNOWN; - } - - if (status & 0x10) { - return AS4224_52T; - } - else if (status & 0x20) { - return AS4224_52T_DAC; - } - else if (status & 0x80) { - return AS5114_48X; - } - else { - return AS4224_52P; - } -} - -static ssize_t show_present_all(struct device *dev, struct device_attribute *da, - char *buf) -{ - int i, status; - u8 values[6] = {0}; - u8 regs_52x[] = {0x41}; - u8 regs_48x[] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5}; - u8 *regs[] = {regs_48x, regs_52x, regs_52x, regs_52x}; - u8 size[] = {ARRAY_SIZE(regs_48x), ARRAY_SIZE(regs_52x), ARRAY_SIZE(regs_52x), ARRAY_SIZE(regs_52x)}; - struct i2c_client *client = to_i2c_client(dev); - struct as4224_cpld_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - for (i = 0; i < size[data->platform_id]; i++) { - status = as4224_cpld_read_internal(client, regs[data->platform_id][i]); - if (status < 0) { - goto exit; - } - - values[i] = ~(u8)status; - } - - mutex_unlock(&data->update_lock); - - /* Return values in order */ - if (data->platform_id == AS5114_48X) { - return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", values[0], values[1], - values[2], values[3], - values[4], values[5]); - } - else { /* AS4224_52X */ - return sprintf(buf, "%.2x\n", values[0] & 0xF); - } - -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[6] = {0}; - u8 regs_52x[] = {0x40}; - u8 regs_mask_52x[] = {0x36}; - u8 regs_48x[] = {0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB}; - u8 regs_mask_48x[] = {0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB}; - u8 *regs[] = {regs_48x, regs_52x, regs_52x, regs_52x}; - u8 size[] = {ARRAY_SIZE(regs_48x), ARRAY_SIZE(regs_52x), ARRAY_SIZE(regs_52x), ARRAY_SIZE(regs_52x)}; - u8 *regs_mask[] = {regs_mask_48x, regs_mask_52x, regs_mask_52x, regs_mask_52x}; - struct i2c_client *client = to_i2c_client(dev); - struct as4224_cpld_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - for (i = 0; i < size[data->platform_id]; i++) { - /* Enable the interrupt to CPU */ - status = as4224_cpld_write_internal(client, regs_mask[data->platform_id][i], 0); - if (unlikely(status < 0)) { - goto exit; - } - - status = as4224_cpld_read_internal(client, regs[data->platform_id][i]); - if (status < 0) { - goto exit; - } - - values[i] = (u8)status; - } - - mutex_unlock(&data->update_lock); - - /* Return values in order */ - if (data->platform_id == AS5114_48X) { - return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", values[0], values[1], - values[2], values[3], - values[4], values[5]); - } - else { /* AS4224_52X */ - return sprintf(buf, "%.2x\n", values[0] & 0xF); - } - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static ssize_t show_module_48x(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 as4224_cpld_data *data = i2c_get_clientdata(client); - int status = 0; - u8 reg = 0, mask = 0, invert = 0; - - switch (attr->index) { - case MODULE_PRESENT_1 ... MODULE_PRESENT_8: - invert = 1; - reg = 0xC0; - mask = 0x1 << (attr->index - MODULE_PRESENT_1); - break; - case MODULE_PRESENT_9 ... MODULE_PRESENT_16: - invert = 1; - reg = 0xC1; - mask = 0x1 << (attr->index - MODULE_PRESENT_9); - break; - case MODULE_PRESENT_17 ... MODULE_PRESENT_24: - invert = 1; - reg = 0xC2; - mask = 0x1 << (attr->index - MODULE_PRESENT_17); - break; - case MODULE_PRESENT_25 ... MODULE_PRESENT_32: - invert = 1; - reg = 0xC3; - mask = 0x1 << (attr->index - MODULE_PRESENT_25); - break; - case MODULE_PRESENT_33 ... MODULE_PRESENT_40: - invert = 1; - reg = 0xC4; - mask = 0x1 << (attr->index - MODULE_PRESENT_33); - break; - case MODULE_PRESENT_41 ... MODULE_PRESENT_48: - invert = 1; - reg = 0xC5; - mask = 0x1 << (attr->index - MODULE_PRESENT_41); - break; - case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: - reg = 0xC6; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); - break; - case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: - reg = 0xC7; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); - break; - case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: - reg = 0xC8; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); - break; - case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: - reg = 0xC9; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); - break; - case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: - reg = 0xCA; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); - break; - case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: - reg = 0xCB; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); - break; - case MODULE_RXLOS_1 ... MODULE_RXLOS_8: - reg = 0xA6; - mask = 0x1 << (attr->index - MODULE_RXLOS_1); - break; - case MODULE_RXLOS_9 ... MODULE_RXLOS_16: - reg = 0xA7; - mask = 0x1 << (attr->index - MODULE_RXLOS_9); - break; - case MODULE_RXLOS_17 ... MODULE_RXLOS_24: - reg = 0xA8; - mask = 0x1 << (attr->index - MODULE_RXLOS_17); - break; - case MODULE_RXLOS_25 ... MODULE_RXLOS_32: - reg = 0xA9; - mask = 0x1 << (attr->index - MODULE_RXLOS_25); - break; - case MODULE_RXLOS_33 ... MODULE_RXLOS_40: - reg = 0xAA; - mask = 0x1 << (attr->index - MODULE_RXLOS_33); - break; - case MODULE_RXLOS_41 ... MODULE_RXLOS_48: - reg = 0xAB; - mask = 0x1 << (attr->index - MODULE_RXLOS_41); - break; - case MODULE_TXFAULT_1 ... MODULE_TXFAULT_8: - reg = 0xA0; - mask = 0x1 << (attr->index - MODULE_TXFAULT_1); - break; - case MODULE_TXFAULT_9 ... MODULE_TXFAULT_16: - reg = 0xA1; - mask = 0x1 << (attr->index - MODULE_TXFAULT_9); - break; - case MODULE_TXFAULT_17 ... MODULE_TXFAULT_24: - reg = 0xA2; - mask = 0x1 << (attr->index - MODULE_TXFAULT_17); - break; - case MODULE_TXFAULT_25 ... MODULE_TXFAULT_32: - reg = 0xA3; - mask = 0x1 << (attr->index - MODULE_TXFAULT_25); - break; - case MODULE_TXFAULT_33 ... MODULE_TXFAULT_40: - reg = 0xA4; - mask = 0x1 << (attr->index - MODULE_TXFAULT_33); - break; - case MODULE_TXFAULT_41 ... MODULE_TXFAULT_48: - reg = 0xA5; - mask = 0x1 << (attr->index - MODULE_TXFAULT_41); - break; - default: - return 0; - } - - mutex_lock(&data->update_lock); - if (attr->index >= MODULE_TXFAULT_1 && attr->index <= MODULE_TXFAULT_48) { - int reg_mask = 0xB0 + ((attr->index - MODULE_TXFAULT_1) / 8); - status = as4224_cpld_read_internal(client, reg_mask); - if (unlikely(status < 0)) { - goto exit; - } - - /* Enable the interrupt to CPU */ - status = as4224_cpld_write_internal(client, reg_mask, status & (~mask)); - if (unlikely(status < 0)) { - goto exit; - } - } - - if (attr->index >= MODULE_RXLOS_1 && attr->index <= MODULE_RXLOS_48) { - int reg_mask = 0xB6 + ((attr->index - MODULE_RXLOS_1) / 8); - status = as4224_cpld_read_internal(client, reg_mask); - if (unlikely(status < 0)) { - goto exit; - } - - /* Enable the interrupt to CPU */ - status = as4224_cpld_write_internal(client, reg_mask, status & (~mask)); - if (unlikely(status < 0)) { - goto exit; - } - } - - status = as4224_cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - mutex_unlock(&data->update_lock); - - return sprintf(buf, "%d\n", invert ? !(status & mask) : !!(status & mask)); - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static ssize_t show_module_52x(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 as4224_cpld_data *data = i2c_get_clientdata(client); - int status = 0; - u8 reg = 0, mask = 0, invert = 0; - - if (data->platform_id == AS5114_48X) { - return show_module_48x(dev, da, buf); - } - - switch (attr->index) { - case MODULE_PRESENT_49 ... MODULE_PRESENT_52: - invert = 1; - reg = 0x41; - mask = 0x1 << (attr->index - MODULE_PRESENT_49); - break; - case MODULE_RXLOS_49 ... MODULE_RXLOS_52: - reg = 0x40; - mask = 0x1 << (attr->index - MODULE_RXLOS_49); - break; - case MODULE_TXFAULT_49 ... MODULE_TXFAULT_52: - reg = 0x40; - mask = 0x10 << (attr->index - MODULE_TXFAULT_49); - break; - case MODULE_TXDISABLE_49 ... MODULE_TXDISABLE_52: - reg = 0x42; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_49); - break; - default: - return 0; - } - - mutex_lock(&data->update_lock); - if ((attr->index >= MODULE_TXFAULT_49 && attr->index <= MODULE_TXFAULT_52) || - (attr->index >= MODULE_TXDISABLE_49 && attr->index <= MODULE_TXDISABLE_52)) { - status = as4224_cpld_read_internal(client, 0x36); - if (unlikely(status < 0)) { - goto exit; - } - - /* Enable the interrupt to CPU */ - status = as4224_cpld_write_internal(client, 0x36, status & (~mask)); - if (unlikely(status < 0)) { - goto exit; - } - } - - status = as4224_cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - mutex_unlock(&data->update_lock); - - return sprintf(buf, "%d\n", invert ? !(status & mask) : !!(status & mask)); - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static ssize_t show_module(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 as4224_cpld_data *data = i2c_get_clientdata(client); - int ret = 0; - - switch (attr->index) { - case MODULE_INDEX_BEGIN: - ret = (data->platform_id == AS5114_48X) ? 1: 49; - break; - case MODULE_COUNT: - ret = (data->platform_id == AS5114_48X) ? 48: 4; - break; - default: - return 0; - } - - return sprintf(buf, "%d\n", ret); -} - -static ssize_t set_control_48x(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 as4224_cpld_data *data = i2c_get_clientdata(client); - long value; - int status; - u8 reg = 0, mask = 0; - - status = kstrtol(buf, 10, &value); - if (status) { - return status; - } - - switch (attr->index) { - case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: - reg = 0xC6; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); - break; - case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: - reg = 0xC7; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); - break; - case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: - reg = 0xC8; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); - break; - case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: - reg = 0xC9; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); - break; - case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: - reg = 0xCA; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); - break; - case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: - reg = 0xCB; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); - break; - default: - return 0; - } - - /* Read current status */ - mutex_lock(&data->update_lock); - status = as4224_cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - - /* Update tx_disable status */ - if (value) { - value = (status | mask); - } - else { - value = (status & ~mask); - } - - /* Set value to CPLD */ - status = as4224_cpld_write_internal(client, reg, value); - if (unlikely(status < 0)) { - goto exit; - } - - mutex_unlock(&data->update_lock); - return count; - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static int i2c_write_request_begin(struct i2c_client *client) -{ - int status = 0; - int retry = 0; - - for (retry = 0; retry <= I2C_WRITE_REQUEST_RETRY_TIMES; retry++) { - /* Read current status */ - status = i2c_smbus_read_byte_data(client, I2C_WRITE_REQUEST_REG); - if (unlikely(status < 0)) { - continue; - } - - if (status & I2C_LOCK_BY_7040_VAL) { - return 0; /* I2C already lock by 7040, just return */ - } - - status |= I2C_WRITE_REQUEST_7040_VAL; - status = i2c_smbus_write_byte_data(client, I2C_WRITE_REQUEST_REG, status); - if (unlikely(status < 0)) { - continue; - } - - /* Read out to make sure if 7040 get the access right */ - msleep(50); - status = i2c_smbus_read_byte_data(client, I2C_WRITE_REQUEST_REG); - if (unlikely(status < 0)) { - continue; - } - - if (status & I2C_LOCK_BY_7040_VAL) { - return 0; - } - - status = -EBUSY; - - if (retry != I2C_WRITE_REQUEST_RETRY_TIMES) { - msleep(1000); - } - } - - return status; -} - -static int i2c_write_request_end(struct i2c_client *client) -{ - int status = 0; - - status = i2c_smbus_read_byte_data(client, I2C_WRITE_REQUEST_REG); - if (unlikely(status < 0)) { - return status; - } - - status &= ~I2C_WRITE_REQUEST_7040_VAL; - status = i2c_smbus_write_byte_data(client, I2C_WRITE_REQUEST_REG, status); - if (unlikely(status < 0)) { - return status; - } - - return 0; -} - -static ssize_t show_i2c_request(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - int status = 0; - - status = i2c_smbus_read_byte_data(client, I2C_WRITE_REQUEST_REG); - if (unlikely(status < 0)) { - return status; - } - - return sprintf(buf, "%d\n", !!(status & I2C_LOCK_BY_7040_VAL)); -} - -static ssize_t set_i2c_request(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - long value; - int status = 0; - - status = kstrtol(buf, 10, &value); - if (status) { - return status; - } - - if (value) { - status = i2c_write_request_begin(client); - } - else { - status = i2c_write_request_end(client); - } - - return status ? status : count; -} - -static ssize_t set_control_52x(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 as4224_cpld_data *data = i2c_get_clientdata(client); - long value; - int status; - u8 reg = 0, mask = 0; - - if (data->platform_id == AS5114_48X) { - return set_control_48x(dev, da, buf, count); - } - - status = kstrtol(buf, 10, &value); - if (status) { - return status; - } - - switch (attr->index) { - case MODULE_TXDISABLE_49 ... MODULE_TXDISABLE_52: - reg = 0x42; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_49); - break; - default: - return 0; - } - - /* Read current status */ - mutex_lock(&data->update_lock); - status = as4224_cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - - /* Update tx_disable status */ - if (value) { - value = (status | mask); - } - else { - value = (status & ~mask); - } - - /* Set value to CPLD */ - status = as4224_cpld_write_internal(client, reg, value); - if (unlikely(status < 0)) { - goto exit; - } - - mutex_unlock(&data->update_lock); - return count; - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static ssize_t show_wtd(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 as4224_cpld_data *data = i2c_get_clientdata(client); - int status = 0; - u8 reg = 0, mask = 0; - - switch (attr->index) { - case WTD_STATE_7040: - reg = 0x90; - mask = 0x2; - break; - case WTD_ENABLE_7040: - reg = 0x91; - mask = 0x10; - break; - case WTD_CLOCK_7040: - reg = 0x92; - mask = 0xC0; - break; - case WTD_COUNTER_7040: - reg = 0x92; - mask = 0x3F; - break; - default: - return 0; - } - - mutex_lock(&data->update_lock); - status = as4224_cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - mutex_unlock(&data->update_lock); - - while (!(mask & 0x1)) { - status >>= 1; - mask >>= 1; - } - - return sprintf(buf, "%d\n", (status & mask)); -exit: - mutex_unlock(&data->update_lock); - return status; -} - -#define VALIDATE_WTD_VAL_RETURN(value, mask) {if (value & ~mask) return -EINVAL;} - -static ssize_t set_wtd(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 as4224_cpld_data *data = i2c_get_clientdata(client); - long value; - int status; - u8 reg = 0, mask = 0; - - status = kstrtol(buf, 10, &value); - if (status) { - return status; - } - - switch (attr->index) { - case WTD_ENABLE_7040: - reg = 0x91; - mask = 0xD0; - value = ((!!value) | 0x8) << 4; - VALIDATE_WTD_VAL_RETURN(value, mask); - break; - case WTD_CLOCK_7040: - reg = 0x92; - mask = 0xC0; - value <<= 6; - VALIDATE_WTD_VAL_RETURN(value, mask); - break; - case WTD_COUNTER_7040: - reg = 0x92; - mask = 0x3F; - value &= mask; - VALIDATE_WTD_VAL_RETURN(value, mask); - break; - default: - return 0; - } - - /* Read current status */ - mutex_lock(&data->update_lock); - - status = as4224_cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - - /* Update wtd status */ - status = (value & mask) | (status & ~mask); - status = as4224_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 reset_wtd(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct as4224_cpld_data *data = i2c_get_clientdata(client); - long value; - int status; - - status = kstrtol(buf, 10, &value); - if (status) { - return status; - } - - if (!value) { - return count; - } - - /* Read current status */ - mutex_lock(&data->update_lock); - - /* Set gpio as output and set value as 0->1 to reset wtd */ - gpio_direction_output(WTD_RESET_GPIO_PIN_MPP3, 0); - gpio_direction_output(WTD_RESET_GPIO_PIN_MPP3, 1); - - mutex_unlock(&data->update_lock); - return count; -} - -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 as4224_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 = as4224_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; -} - -static void as4224_cpld_add_client(struct i2c_client *client) -{ - struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); - - if (!node) { - dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); - return; - } - - node->client = client; - - mutex_lock(&list_lock); - list_add(&node->list, &cpld_client_list); - mutex_unlock(&list_lock); -} - -static void as4224_cpld_remove_client(struct i2c_client *client) -{ - struct list_head *list_node = NULL; - struct cpld_client_node *cpld_node = NULL; - int found = 0; - - mutex_lock(&list_lock); - - list_for_each(list_node, &cpld_client_list) - { - cpld_node = list_entry(list_node, struct cpld_client_node, list); - - if (cpld_node->client == client) { - found = 1; - break; - } - } - - if (found) { - list_del(list_node); - kfree(cpld_node); - } - - mutex_unlock(&list_lock); -} - -static ssize_t show_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); - - if (val < 0) { - dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); - } - - return sprintf(buf, "%d\n", val); -} - -static ssize_t show_platform_id(struct device *dev, struct device_attribute *da, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct as4224_cpld_data *data = i2c_get_clientdata(client); - return sprintf(buf, "%d\n", data->platform_id); -} - -/* - * I2C init/probing/exit functions - */ -static int as4224_cpld_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); - struct as4224_cpld_data *data; - int ret = -ENODEV; - int i = 0; - u64 port_map[4] = { [AS5114_48X] = 0xFFFFFFFFFFFF, - [AS4224_52P] = 0xF000000000000, - [AS4224_52T] = 0xF000000000000, - [AS4224_52T_DAC] = 0xF000000000000}; - - if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) - goto exit; - - data = kzalloc(sizeof(struct as4224_cpld_data), GFP_KERNEL); - if (!data) { - ret = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - data->type = id->driver_data; - data->platform_id = get_platform_id(client); - - if (data->platform_id == PID_UNKNOWN) { - ret = -ENODEV; - goto exit_free; - } - - /* Register sysfs hooks */ - for (i = 0; i < ARRAY_SIZE(cpld_group); i++) { - /* index 0 is for common attriute, register anyway */ - if ((i != 0) && !(port_map[data->platform_id] & BIT(i-1))) { - continue; - } - - ret = sysfs_create_group(&client->dev.kobj, &cpld_group[i]); - if (ret) { - goto exit_free; - } - } - - ret = gpio_request(WTD_RESET_GPIO_PIN_MPP3, "wtd_reset_7040"); - if (ret) { - dev_err(&client->dev, "Failed to request MPP3 gpio\n"); - goto exit_free; - } - - as4224_cpld_add_client(client); - return 0; - -exit_free: - kfree(data); -exit: - for (--i; i >= 0; i--) { - sysfs_remove_group(&client->dev.kobj, &cpld_group[i]); - } - return ret; -} - -static int as4224_cpld_remove(struct i2c_client *client) -{ - int i = 0; - struct as4224_cpld_data *data = i2c_get_clientdata(client); - as4224_cpld_remove_client(client); - gpio_free(WTD_RESET_GPIO_PIN_MPP3); - - for (i = 0; i < ARRAY_SIZE(cpld_group); i++) { - sysfs_remove_group(&client->dev.kobj, &cpld_group[i]); - } - - kfree(data); - return 0; -} - -static int as4224_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 as4224_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value) -{ - int status = 0, retry = I2C_RW_RETRY_COUNT; - - status = i2c_write_request_begin(client); - if (unlikely(status < 0)) { - return status; - } - - while (retry) { - status = i2c_smbus_write_byte_data(client, reg, value); - if (unlikely(status < 0)) { - msleep(I2C_RW_RETRY_INTERVAL); - retry--; - continue; - } - - break; - } - - status = i2c_write_request_end(client); - if (unlikely(status < 0)) { - return status; - } - - return status; -} - -int as4224_cpld_read(unsigned short cpld_addr, u8 reg) -{ - struct list_head *list_node = NULL; - struct cpld_client_node *cpld_node = NULL; - int ret = -EPERM; - - mutex_lock(&list_lock); - - list_for_each(list_node, &cpld_client_list) - { - cpld_node = list_entry(list_node, struct cpld_client_node, list); - - if (cpld_node->client->addr == cpld_addr) { - ret = as4224_cpld_read_internal(cpld_node->client, reg); - break; - } - } - - mutex_unlock(&list_lock); - - return ret; -} -EXPORT_SYMBOL(as4224_cpld_read); - -int as4224_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) -{ - struct list_head *list_node = NULL; - struct cpld_client_node *cpld_node = NULL; - int ret = -EIO; - - mutex_lock(&list_lock); - - list_for_each(list_node, &cpld_client_list) - { - cpld_node = list_entry(list_node, struct cpld_client_node, list); - - if (cpld_node->client->addr == cpld_addr) { - ret = as4224_cpld_write_internal(cpld_node->client, reg, value); - break; - } - } - - mutex_unlock(&list_lock); - - return ret; -} -EXPORT_SYMBOL(as4224_cpld_write); - -static struct i2c_driver as4224_cpld_driver = { - .driver = { - .name = "as4224_cpld", - .owner = THIS_MODULE, - }, - .probe = as4224_cpld_probe, - .remove = as4224_cpld_remove, - .id_table = as4224_cpld_id, -}; - -static int __init as4224_cpld_init(void) -{ - mutex_init(&list_lock); - return i2c_add_driver(&as4224_cpld_driver); -} - -static void __exit as4224_cpld_exit(void) -{ - i2c_del_driver(&as4224_cpld_driver); -} - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("as4224_cpld driver"); -MODULE_LICENSE("GPL"); - -module_init(as4224_cpld_init); -module_exit(as4224_cpld_exit); diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_6/arm64-accton-as4224-fan.c b/packages/platforms/accton/arm64/as4224/src/modules-5_6/arm64-accton-as4224-fan.c deleted file mode 100644 index 11c0cdc21..000000000 --- a/packages/platforms/accton/arm64/as4224/src/modules-5_6/arm64-accton-as4224-fan.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - * A hwmon driver for the Accton as9926 24d fan - * - * Copyright (C) 2016 Accton Technology Corporation. - * Brandon Chuang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRVNAME "as4224_fan" - -#define BOARD_INFO_REG_OFFSET 0x00 -#define FAN_STATUS_I2C_ADDR 0x40 -#define MAX_FAN_SPEED_RPM 20500 -#define FAN_DUTY_CYCLE_REG_MASK 0xFF -#define FAN_MAX_DUTY_CYCLE 100 -#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 - -static struct as4224_fan_data *as4224_fan_update_device(struct device *dev); -static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static ssize_t show_wtd(struct device *dev, struct device_attribute *da, - char *buf); -static ssize_t set_wtd(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static int _reset_wtd(void); -static ssize_t reset_wtd(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -extern int as4224_cpld_read(unsigned short cpld_addr, u8 reg); -extern int as4224_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); - -static struct as4224_fan_data *data = NULL; - -/* fan related data, the index should match sysfs_fan_attributes - */ -static const u8 fan_reg[] = { - 0x70, /* fan1 PWM */ - 0x71, /* fan2 PWM */ - 0x72, /* fan3 PWM */ - 0x73, /* fan4 PWM */ - 0x74, /* fan5 PWM */ - 0x75, /* fan6 PWM */ - 0x80, /* fan 1 tach speed */ - 0x81, /* fan 2 tach speed */ - 0x82, /* fan 3 tach speed */ - 0x83, /* fan 4 tach speed */ - 0x84, /* fan 5 tach speed */ - 0x85, /* fan 6 tach speed */ - 0x62, /* fan tech speed setting */ -}; - -/* fan data */ -struct as4224_fan_data { - struct platform_device *pdev; - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* != 0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ - u8 fan_count; -}; - -enum fan_id { - FAN1_ID, - FAN2_ID, - FAN3_ID, - FAN4_ID, - FAN5_ID, - FAN6_ID -}; - -enum sysfs_fan_attributes { - FAN1_PWM, - FAN2_PWM, - FAN3_PWM, - FAN4_PWM, - FAN5_PWM, - FAN6_PWM, - FAN1_SPEED_RPM, - FAN2_SPEED_RPM, - FAN3_SPEED_RPM, - FAN4_SPEED_RPM, - FAN5_SPEED_RPM, - FAN6_SPEED_RPM, - FAN_TECH_SETTING, - FAN1_FAULT, - FAN2_FAULT, - FAN3_FAULT, - FAN4_FAULT, - FAN5_FAULT, - FAN6_FAULT, - FAN_MAX_RPM, - FAN_COUNT, - WTD_CLOCK, - WTD_COUNTER, - WTD_ENABLE, - WTD_RESET -}; - -/* sysfs attributes for hwmon - */ -static SENSOR_DEVICE_ATTR(fan_max_rpm, S_IRUGO, fan_show_value, NULL, FAN_MAX_RPM); -static SENSOR_DEVICE_ATTR(fan_count, S_IRUGO, fan_show_value, NULL, FAN_COUNT); - -/* Fan watchdog */ -static SENSOR_DEVICE_ATTR(wtd_clock, S_IRUGO | S_IWUSR, show_wtd, set_wtd, WTD_CLOCK); -static SENSOR_DEVICE_ATTR(wtd_counter, S_IRUGO | S_IWUSR, show_wtd, set_wtd, WTD_COUNTER); -static SENSOR_DEVICE_ATTR(wtd_enable, S_IRUGO | S_IWUSR, show_wtd, set_wtd, WTD_ENABLE); -static SENSOR_DEVICE_ATTR(wtd_reset, S_IWUSR, NULL, reset_wtd, WTD_RESET); - -static struct attribute *fan_attributes_common[] = { - &sensor_dev_attr_fan_max_rpm.dev_attr.attr, - &sensor_dev_attr_fan_count.dev_attr.attr, - &sensor_dev_attr_wtd_clock.dev_attr.attr, - &sensor_dev_attr_wtd_counter.dev_attr.attr, - &sensor_dev_attr_wtd_enable.dev_attr.attr, - &sensor_dev_attr_wtd_reset.dev_attr.attr, - NULL -}; - -#define FAN_ATTRS_COMMON() { .attrs = fan_attributes_common } - -#define FAN_ATTRS(fid) \ - static SENSOR_DEVICE_ATTR(fan##fid##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN##fid##_PWM); \ - static SENSOR_DEVICE_ATTR(fan##fid##_input, S_IRUGO, fan_show_value, NULL, FAN##fid##_SPEED_RPM); \ - static SENSOR_DEVICE_ATTR(fan##fid##_fault, S_IRUGO, fan_show_value, NULL, FAN##fid##_FAULT); \ - static struct attribute *fan_attributes##fid[] = { \ - &sensor_dev_attr_fan##fid##_duty_cycle_percentage.dev_attr.attr, \ - &sensor_dev_attr_fan##fid##_input.dev_attr.attr, \ - &sensor_dev_attr_fan##fid##_fault.dev_attr.attr, \ - NULL \ - } - -FAN_ATTRS(1); -FAN_ATTRS(2); -FAN_ATTRS(3); -FAN_ATTRS(4); -FAN_ATTRS(5); -FAN_ATTRS(6); - -#define FAN_ATTR_GROUP(fid) { .attrs = fan_attributes##fid } - -static struct attribute_group fan_group[] = { - FAN_ATTRS_COMMON(), - FAN_ATTR_GROUP(1), - FAN_ATTR_GROUP(2), - FAN_ATTR_GROUP(3), - FAN_ATTR_GROUP(4), - FAN_ATTR_GROUP(5), - FAN_ATTR_GROUP(6), -}; - -static int as4224_fan_read_value(u8 reg) -{ - return as4224_cpld_read(FAN_STATUS_I2C_ADDR, reg); -} - -static int as4224_fan_write_value(u8 reg, u8 value) -{ - return as4224_cpld_write(FAN_STATUS_I2C_ADDR, reg, value); -} - -/* fan utility functions - */ -static u32 reg_val_to_duty_cycle(u8 reg_val) -{ - reg_val &= FAN_DUTY_CYCLE_REG_MASK; - return (reg_val == 0xFF) ? 100 : (((u32)reg_val) * 100 / 255) + 1; -} - -static u8 duty_cycle_to_reg_val(u8 duty_cycle) -{ - if (duty_cycle == 0) { - return 0; - } - else if (duty_cycle > FAN_MAX_DUTY_CYCLE) { - duty_cycle = FAN_MAX_DUTY_CYCLE; - } - - return ((u32)duty_cycle) * 255 / 100; -} - -static u32 reg_val_to_speed_rpm(u8 reg_val, u8 tech_reg_val) -{ - u32 timer[] = { 1048, 2097, 4194, 8389 }; - u8 counter = (tech_reg_val & 0x3F); - u8 clock = (tech_reg_val >> 6) & 0x3; - - return (reg_val * 3000000) / (timer[clock] * counter); -} - -static u8 is_fan_fault(struct as4224_fan_data *data, enum fan_id id) -{ - return !reg_val_to_speed_rpm(data->reg_val[FAN1_SPEED_RPM + id], - data->reg_val[FAN_TECH_SETTING]); -} - -static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - int error, value; - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - - error = kstrtoint(buf, 10, &value); - if (error) { - return error; - } - - if (value < 0 || value > FAN_MAX_DUTY_CYCLE) { - return -EINVAL; - } - - /* Disable the watchdog timer - */ - error = _reset_wtd(); - if (unlikely(error < 0)) { - dev_dbg(dev, "Unable to reset the watchdog timer\n"); - return error; - } - - as4224_fan_write_value(fan_reg[attr->index - FAN1_PWM], duty_cycle_to_reg_val(value)); - data->valid = 0; - - return count; -} - -static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct as4224_fan_data *data = as4224_fan_update_device(dev); - ssize_t ret = 0; - - if (data->valid) { - switch (attr->index) { - case FAN1_PWM: - case FAN2_PWM: - case FAN3_PWM: - case FAN4_PWM: - case FAN5_PWM: - case FAN6_PWM: - ret = sprintf(buf, "%u\n", reg_val_to_duty_cycle(data->reg_val[attr->index])); - break; - case FAN1_SPEED_RPM: - case FAN2_SPEED_RPM: - case FAN3_SPEED_RPM: - case FAN4_SPEED_RPM: - case FAN5_SPEED_RPM: - case FAN6_SPEED_RPM: - ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index], - data->reg_val[FAN_TECH_SETTING])); - break; - case FAN1_FAULT: - case FAN2_FAULT: - case FAN3_FAULT: - case FAN4_FAULT: - case FAN5_FAULT: - case FAN6_FAULT: - ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); - break; - case FAN_MAX_RPM: - ret = sprintf(buf, "%d\n", MAX_FAN_SPEED_RPM); - break; - case FAN_COUNT: - ret = sprintf(buf, "%d\n", data->fan_count); - break; - default: - break; - } - } - - return ret; -} - -static ssize_t show_wtd(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - int status = 0; - u8 reg = 0, mask = 0; - - switch (attr->index) { - case WTD_ENABLE: - reg = 0x60; - mask = 0x01; - break; - case WTD_CLOCK: - reg = 0x61; - mask = 0xC0; - break; - case WTD_COUNTER: - reg = 0x61; - mask = 0x3F; - break; - default: - return 0; - } - - mutex_lock(&data->update_lock); - status = as4224_fan_read_value(reg); - if (unlikely(status < 0)) { - goto exit; - } - mutex_unlock(&data->update_lock); - - while (!(mask & 0x1)) { - status >>= 1; - mask >>= 1; - } - - return sprintf(buf, "%d\n", (status & mask)); -exit: - mutex_unlock(&data->update_lock); - return status; -} - -#define VALIDATE_WTD_VAL_RETURN(value, mask) {if (value & ~mask) return -EINVAL;} - -static ssize_t set_wtd(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - long value; - int status; - u8 reg = 0, mask = 0; - - status = kstrtol(buf, 10, &value); - if (status) { - return status; - } - - switch (attr->index) { - case WTD_ENABLE: - reg = 0x60; - mask = 0x01; - value &= mask; - VALIDATE_WTD_VAL_RETURN(value, mask); - break; - case WTD_CLOCK: - reg = 0x61; - mask = 0xC0; - value <<= 6; - VALIDATE_WTD_VAL_RETURN(value, mask); - break; - case WTD_COUNTER: - reg = 0x61; - mask = 0x3F; - value &= mask; - VALIDATE_WTD_VAL_RETURN(value, mask); - break; - default: - return 0; - } - - /* Read current status */ - mutex_lock(&data->update_lock); - - status = as4224_fan_read_value(reg); - if (unlikely(status < 0)) { - goto exit; - } - - /* Update wtd status */ - status = (value & mask) | (status & ~mask); - status = as4224_fan_write_value(reg, status); - if (unlikely(status < 0)) { - goto exit; - } - - mutex_unlock(&data->update_lock); - return count; - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static int _reset_wtd(void) -{ - int status; - - /* Set value as 0->1 to reset wtd */ - status = as4224_fan_write_value(0x60, 0); - if (unlikely(status < 0)) { - return status; - } - - msleep(50); - status = as4224_fan_write_value(0x60, 1); - if (unlikely(status < 0)) { - return status; - } - - return status; -} - -static ssize_t reset_wtd(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - long value; - int status; - - status = kstrtol(buf, 10, &value); - if (status) { - return status; - } - - if (!value) { - return count; - } - - /* Read current status */ - mutex_lock(&data->update_lock); - - status = _reset_wtd(); - if (unlikely(status < 0)) { - dev_dbg(dev, "Unable to reset the watchdog timer\n"); - return status; - } - - mutex_unlock(&data->update_lock); - return count; -} - -static struct as4224_fan_data *as4224_fan_update_device(struct device *dev) -{ - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || - !data->valid) { - int i; - - dev_dbg(dev, "Starting as4224_fan update\n"); - data->valid = 0; - - /* Update fan data - */ - for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { - int status = as4224_fan_read_value(fan_reg[i]); - - if (status < 0) { - data->valid = 0; - mutex_unlock(&data->update_lock); - dev_dbg(dev, "reg %d, err %d\n", fan_reg[i], status); - return data; - } - else { - data->reg_val[i] = status; - } - } - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} - -static int as4224_fan_get_fan_count(void) -{ - int status; - - status = as4224_fan_read_value(BOARD_INFO_REG_OFFSET); - if (status < 0) { - return 0; - } - - if ((status & 0x10) || (status & 0x20)) { - return 4; - } - else if (status & 0x80) { - return 5; - } - else { - return 6; - } -} - -static int as4224_fan_probe(struct platform_device *pdev) -{ - int status = -1; - int i = 0; - - /* Register sysfs hooks */ - for (i = 0; i < (data->fan_count + 1); i++) { - /* Register sysfs hooks */ - status = sysfs_create_group(&pdev->dev.kobj, &fan_group[i]); - if (status) { - goto exit; - } - } - - dev_info(&pdev->dev, "device created\n"); - - return 0; - -exit: - for (--i; i >= 0; i--) { - sysfs_remove_group(&pdev->dev.kobj, &fan_group[i]); - } - return status; -} - -static int as4224_fan_remove(struct platform_device *pdev) -{ - int i = 0; - - for (i = 0; i < (data->fan_count + 1); i++) { - sysfs_remove_group(&pdev->dev.kobj, &fan_group[i]); - } - - return 0; -} - -static struct platform_driver as4224_fan_driver = { - .probe = as4224_fan_probe, - .remove = as4224_fan_remove, - .driver = { - .name = DRVNAME, - .owner = THIS_MODULE, - }, -}; - -static int __init as4224_fan_init(void) -{ - int ret; - - data = kzalloc(sizeof(struct as4224_fan_data), GFP_KERNEL); - if (!data) { - ret = -ENOMEM; - goto alloc_err; - } - - mutex_init(&data->update_lock); - - data->fan_count = as4224_fan_get_fan_count(); - if (!data->fan_count) { - return -EIO; - } - - ret = platform_driver_register(&as4224_fan_driver); - if (ret < 0) { - goto dri_reg_err; - } - - data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); - if (IS_ERR(data->pdev)) { - ret = PTR_ERR(data->pdev); - goto dev_reg_err; - } - - return 0; - -dev_reg_err: - platform_driver_unregister(&as4224_fan_driver); -dri_reg_err: - kfree(data); -alloc_err: - return ret; -} - -static void __exit as4224_fan_exit(void) -{ - platform_device_unregister(data->pdev); - platform_driver_unregister(&as4224_fan_driver); - kfree(data); -} - -module_init(as4224_fan_init); -module_exit(as4224_fan_exit); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("as4224_fan driver"); -MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_6/arm64-accton-as4224-gpio-i2c.c b/packages/platforms/accton/arm64/as4224/src/modules-5_6/arm64-accton-as4224-gpio-i2c.c deleted file mode 100644 index 4221d80a2..000000000 --- a/packages/platforms/accton/arm64/as4224/src/modules-5_6/arm64-accton-as4224-gpio-i2c.c +++ /dev/null @@ -1,245 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GPIO_I2C_NGPIOS 144 - -#define GPIO_I2C_RETRY_COUNT 10 -#define GPIO_I2C_RETRY_INTERVAL 60 /* ms */ - -extern int as4224_cpld_read(unsigned short cpld_addr, u8 reg); -extern int as4224_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); - -struct gpio_i2c_reg { - struct list_head head; - u32 gpio_num; - u32 reg_addr; - u32 reg_mask; -}; - -struct gpio_i2c_chip { - struct gpio_chip gpio_chip; - struct device *dev; - - struct list_head gpio_list; -}; - -static int gpio_i2c_read(struct gpio_i2c_chip *chip, u8 reg) -{ - int status = 0, retry = GPIO_I2C_RETRY_COUNT; - - while (retry) { - status = as4224_cpld_read(0x40, reg); - if (unlikely(status < 0)) { - msleep(GPIO_I2C_RETRY_INTERVAL); - retry--; - continue; - } - break; - } - - return status; -} - -static int gpio_i2c_write(struct gpio_i2c_chip *chip, u8 reg, u8 value) -{ - int status = 0, retry = GPIO_I2C_RETRY_COUNT; - - while (retry) { - status = as4224_cpld_write(0x40, reg, value); - if (unlikely(status < 0)) { - msleep(GPIO_I2C_RETRY_INTERVAL); - retry--; - continue; - } - break; - } - - return status; -} - -static struct gpio_i2c_reg *gpio_i2c_reg_by_num(struct gpio_i2c_chip *chip, - unsigned int offs) -{ - struct gpio_i2c_reg *gpio_reg; - - list_for_each_entry(gpio_reg, &chip->gpio_list, head) { - if (gpio_reg->gpio_num == offs) - return gpio_reg; - } - - return NULL; -} - -static int gpio_i2c_get_value(struct gpio_chip *gc, unsigned int offs) -{ - struct gpio_i2c_chip *chip = gpiochip_get_data(gc); - struct gpio_i2c_reg *gpio_reg; - int val; - - gpio_reg = gpio_i2c_reg_by_num(chip, offs); - if (!gpio_reg) { - dev_err(chip->dev, "invalid gpio offset (0x%x)\n", offs); - return -EINVAL; - } - - val = gpio_i2c_read(chip, gpio_reg->reg_addr); - val &= gpio_reg->reg_mask; - - return val; -} - -static void gpio_i2c_set_value(struct gpio_chip *gc, unsigned int offs, int set) -{ - struct gpio_i2c_chip *chip = gpiochip_get_data(gc); - struct gpio_i2c_reg *gpio_reg; - unsigned int val; - - gpio_reg = gpio_i2c_reg_by_num(chip, offs); - if (!gpio_reg) { - dev_err(chip->dev, "invalid gpio offset (0x%x)\n", offs); - return; - } - - val = gpio_i2c_read(chip, gpio_reg->reg_addr); - - val &= ~gpio_reg->reg_mask; - if (set) - val |= gpio_reg->reg_mask; - - gpio_i2c_write(chip, gpio_reg->reg_addr, val); -} - -static int gpio_i2c_reg_parse(struct gpio_i2c_chip *chip, struct device_node *np) -{ - struct gpio_i2c_reg *gpio_reg; - struct device *dev = chip->dev; - u32 gpio_reg_map[2]; - u32 gpio_num; - int err; - - err = of_property_read_u32_array(np, "reg-map", gpio_reg_map, - ARRAY_SIZE(gpio_reg_map)); - - if (err) { - dev_err(dev, "error while parsing 'reg-map' property\n"); - return err; - } - - err = of_property_read_u32(np, "gpio-num", &gpio_num); - if (err) { - dev_err(dev, "error while parsing 'gpio-num' property\n"); - return err; - } - - gpio_reg = devm_kmalloc(dev, sizeof(*gpio_reg), GFP_KERNEL); - if (!gpio_reg) - return err; - - gpio_reg->reg_addr = gpio_reg_map[0]; - gpio_reg->reg_mask = gpio_reg_map[1]; - gpio_reg->gpio_num = gpio_num; - - list_add(&gpio_reg->head, &chip->gpio_list); - - return 0; -} - -static int gpio_i2c_map_parse(struct gpio_i2c_chip *chip, - struct device_node *gpio_map_np) -{ - struct device_node *node; - - for_each_child_of_node(gpio_map_np, node) { - int err; - - err = gpio_i2c_reg_parse(chip, node); - if (err) - return err; - } - - return 0; -} - -static int gpio_i2c_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - struct device_node *gpio_map_np; - struct gpio_i2c_chip *chip; - int err; - - if (!np) - return -EINVAL; - - chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - INIT_LIST_HEAD(&chip->gpio_list); - chip->dev = dev; - - gpio_map_np = of_find_node_by_name(np, "gpio-map"); - if (gpio_map_np) { - err = gpio_i2c_map_parse(chip, gpio_map_np); - if (err) - return err; - } - - chip->gpio_chip.parent = dev; - - dev_set_drvdata(dev, chip); - - chip->gpio_chip.label = dev_name(dev); - chip->gpio_chip.get = gpio_i2c_get_value; - chip->gpio_chip.set = gpio_i2c_set_value; - chip->gpio_chip.base = -1; - - chip->gpio_chip.ngpio = GPIO_I2C_NGPIOS; - - chip->gpio_chip.owner = THIS_MODULE; - chip->gpio_chip.can_sleep = true; - - return devm_gpiochip_add_data(dev, &chip->gpio_chip, chip); -} - -static int gpio_i2c_remove(struct platform_device *pdev) -{ - return 0; -} - - -static const struct of_device_id gpio_i2c_id[] = { - { .compatible = "gpio-i2c" }, - { } -}; -MODULE_DEVICE_TABLE(of, gpio_i2c_id); - -static struct platform_driver gpio_i2c_driver = { - .driver = { - .name = "gpio-i2c", - .owner = THIS_MODULE, - .of_match_table = gpio_i2c_id, - }, - .probe = gpio_i2c_probe, - .remove = gpio_i2c_remove, -}; - -module_platform_driver(gpio_i2c_driver); - - -MODULE_AUTHOR("Vadym Kochan "); -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION("GPIO to I2C driver"); diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_6/arm64-accton-as4224-psu.c b/packages/platforms/accton/arm64/as4224/src/modules-5_6/arm64-accton-as4224-psu.c deleted file mode 100644 index e64294a43..000000000 --- a/packages/platforms/accton/arm64/as4224/src/modules-5_6/arm64-accton-as4224-psu.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * An hwmon driver for accton as4224 Power Module - * - * Copyright (C) 2014 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 -#include -#include - -#define DRVNAME "as4224_psu" - -#define BOARD_INFO_REG_OFFSET 0x00 -#define PSU_STATUS_I2C_ADDR 0x40 -#define PSU_STATUS_I2C_REG_OFFSET 0x03 - -#define IS_POWER_GOOD(id, value) (!!(value & BIT(id + 1))) - -static ssize_t show_count(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); -extern int as4224_cpld_read(unsigned short cpld_addr, u8 reg); -extern int as4224_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); - -enum Platform_Id { - AS5114_48X, - AS4224_52P, - AS4224_52T, - AS4224_52T_DAC -}; - -/* Each client has this additional data - */ -struct as4224_psu_data { - struct platform_device *pdev; - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - enum Platform_Id platform_id; - u8 status; /* power_good status read from CPLD */ - u8 psu_count; -}; - -struct as4224_psu_data *data = NULL; - -enum as4224_psu_sysfs_attributes { - PSU1_POWER_GOOD, - PSU2_POWER_GOOD, - PSU_COUNT -}; - -/* sysfs attributes for hwmon - */ -static SENSOR_DEVICE_ATTR(psu_count, S_IRUGO, show_count, NULL, PSU_COUNT); - -static struct attribute *psu_attributes_common[] = { - &sensor_dev_attr_psu_count.dev_attr.attr, - NULL -}; - -#define PSU_ATTRS_COMMON() { .attrs = psu_attributes_common } - -#define PSU_ATTRS(pid) \ - static struct sensor_device_attribute sensor_attr_psu##pid = \ - SENSOR_ATTR(psu##pid##_power_good, S_IRUGO, show_status, NULL, PSU##pid##_POWER_GOOD); \ - static struct attribute *psu_attributes##pid[] = { \ - &sensor_attr_psu##pid.dev_attr.attr, \ - NULL \ - } - -PSU_ATTRS(1); -PSU_ATTRS(2); - -#define PSU_ATTR_GROUP(pid) { .attrs = psu_attributes##pid } - -static struct attribute_group psu_group[] = { - PSU_ATTRS_COMMON(), - PSU_ATTR_GROUP(1), - PSU_ATTR_GROUP(2), -}; - -static int as4224_psu_read_value(u8 reg) -{ - return as4224_cpld_read(PSU_STATUS_I2C_ADDR, reg); -} - -static int as4224_psu_write_value(u8 reg, u8 value) -{ - return as4224_cpld_write(PSU_STATUS_I2C_ADDR, reg, value); -} - -static int as4224_psu_get_status_mask_reg(void) -{ - return (data->platform_id == AS5114_48X) ? 0x32 : 0x34; -} - -static struct as4224_psu_data *as4224_psu_update_device(struct device *dev) -{ - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - int status; - int reg; - int reg_mask = 0x6; - - dev_dbg(dev, "Starting as4224 update\n"); - data->valid = 0; - - /* Read psu status */ - reg = as4224_psu_get_status_mask_reg(); - status = as4224_psu_read_value(reg); - if (unlikely(status < 0)) { - dev_dbg(dev, "cpld read reg (0x%x) err %d\n", reg, status); - return data; - } - - /* Enable the interrupt to CPU */ - status = as4224_psu_write_value(reg, status & (~reg_mask)); - if (unlikely(status < 0)) { - dev_dbg(dev, "cpld write reg (0x%x) err %d\n", reg, status); - return data; - } - - status = as4224_psu_read_value(PSU_STATUS_I2C_REG_OFFSET); - - if (status < 0) { - dev_dbg(dev, "cpld read reg (0x%x) err %d\n", PSU_STATUS_I2C_REG_OFFSET, status); - return data; - } - else { - data->status = status; - } - - data->last_updated = jiffies; - data->valid = 1; - } - - return data; -} - -static ssize_t show_count(struct device *dev, struct device_attribute *da, char *buf) -{ - return sprintf(buf, "%d\n", data->psu_count); -} - -static ssize_t show_status(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - u8 status = 0; - - mutex_lock(&data->update_lock); - - data = as4224_psu_update_device(dev); - if (!data->valid) { - mutex_unlock(&data->update_lock); - return sprintf(buf, "0\n"); - } - - status = IS_POWER_GOOD(attr->index, data->status); - - mutex_unlock(&data->update_lock); - return sprintf(buf, "%d\n", status); -} - -static int as4224_psu_get_psu_count(void) -{ - int status; - - status = as4224_psu_read_value(BOARD_INFO_REG_OFFSET); - if (status < 0) { - return 0; - } - - return (status & 0x10) ? 1 : 2; -} - -static int get_platform_id(void) -{ - int status; - - status = as4224_psu_read_value(BOARD_INFO_REG_OFFSET); - if (status < 0) - return status; - - status &= 0xF0; - - if (status & 0x10) - return AS4224_52T; - else if (status & 0x20) - return AS4224_52T_DAC; - else if (status & 0x80) - return AS5114_48X; - else if (status & 0x40) - return -ENODEV; - else - return AS4224_52P; -} - -static int as4224_psu_probe(struct platform_device *pdev) -{ - int status = -1; - int i = 0; - - /* Register sysfs hooks */ - for (i = 0; i < (data->psu_count + 1); i++) { - /* Register sysfs hooks */ - status = sysfs_create_group(&pdev->dev.kobj, &psu_group[i]); - if (status) { - goto exit; - } - } - - dev_info(&pdev->dev, "device created\n"); - - return 0; - -exit: - for (--i; i >= 0; i--) { - sysfs_remove_group(&pdev->dev.kobj, &psu_group[i]); - } - return status; -} - - -static int as4224_psu_remove(struct platform_device *pdev) -{ - int i = 0; - - for (i = 0; i < (data->psu_count + 1); i++) { - sysfs_remove_group(&pdev->dev.kobj, &psu_group[i]); - } - - return 0; -} - -static struct platform_driver as4224_psu_driver = { - .probe = as4224_psu_probe, - .remove = as4224_psu_remove, - .driver = { - .name = DRVNAME, - .owner = THIS_MODULE, - }, -}; - -static int __init as4224_psu_init(void) -{ - int ret; - - data = kzalloc(sizeof(struct as4224_psu_data), GFP_KERNEL); - if (!data) { - ret = -ENOMEM; - goto alloc_err; - } - - mutex_init(&data->update_lock); - - data->psu_count = as4224_psu_get_psu_count(); - if (!data->psu_count) { - return -EIO; - } - - ret = get_platform_id(); - if (ret < 0) - return ret; - - data->platform_id = ret; - - ret = platform_driver_register(&as4224_psu_driver); - if (ret < 0) { - goto dri_reg_err; - } - - data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); - if (IS_ERR(data->pdev)) { - ret = PTR_ERR(data->pdev); - goto dev_reg_err; - } - - return 0; - -dev_reg_err: - platform_driver_unregister(&as4224_psu_driver); -dri_reg_err: - kfree(data); -alloc_err: - return ret; -} - -static void __exit as4224_psu_exit(void) -{ - platform_device_unregister(data->pdev); - platform_driver_unregister(&as4224_psu_driver); - kfree(data); -} - -module_init(as4224_psu_init); -module_exit(as4224_psu_exit); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("as4224_psu driver"); -MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_6/optoe.c b/packages/platforms/accton/arm64/as4224/src/modules-5_6/optoe.c deleted file mode 100644 index f682c574c..000000000 --- a/packages/platforms/accton/arm64/as4224/src/modules-5_6/optoe.c +++ /dev/null @@ -1,1148 +0,0 @@ -/* - * optoe.c - A driver to read and write the EEPROM on optical transceivers - * (SFP, QSFP and similar I2C based devices) - * - * Copyright (C) 2014 Cumulus networks Inc. - * Copyright (C) 2017 Finisar Corp. - * - * 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 Freeoftware Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -/* - * Description: - * a) Optical transceiver EEPROM read/write transactions are just like - * the at24 eeproms managed by the at24.c i2c driver - * b) The register/memory layout is up to 256 128 byte pages defined by - * a "pages valid" register and switched via a "page select" - * register as explained in below diagram. - * c) 256 bytes are mapped at a time. 'Lower page 00h' is the first 128 - * bytes of address space, and always references the same - * location, independent of the page select register. - * All mapped pages are mapped into the upper 128 bytes - * (offset 128-255) of the i2c address. - * d) Devices with one I2C address (eg QSFP) use I2C address 0x50 - * (A0h in the spec), and map all pages in the upper 128 bytes - * of that address. - * e) Devices with two I2C addresses (eg SFP) have 256 bytes of data - * at I2C address 0x50, and 256 bytes of data at I2C address - * 0x51 (A2h in the spec). Page selection and paged access - * only apply to this second I2C address (0x51). - * e) The address space is presented, by the driver, as a linear - * address space. For devices with one I2C client at address - * 0x50 (eg QSFP), offset 0-127 are in the lower - * half of address 50/A0h/client[0]. Offset 128-255 are in - * page 0, 256-383 are page 1, etc. More generally, offset - * 'n' resides in page (n/128)-1. ('page -1' is the lower - * half, offset 0-127). - * f) For devices with two I2C clients at address 0x50 and 0x51 (eg SFP), - * the address space places offset 0-127 in the lower - * half of 50/A0/client[0], offset 128-255 in the upper - * half. Offset 256-383 is in the lower half of 51/A2/client[1]. - * Offset 384-511 is in page 0, in the upper half of 51/A2/... - * Offset 512-639 is in page 1, in the upper half of 51/A2/... - * Offset 'n' is in page (n/128)-3 (for n > 383) - * - * One I2c addressed (eg QSFP) Memory Map - * - * 2-Wire Serial Address: 1010000x - * - * Lower Page 00h (128 bytes) - * ===================== - * | | - * | | - * | | - * | | - * | | - * | | - * | | - * | | - * | | - * | | - * |Page Select Byte(127)| - * ===================== - * | - * | - * | - * | - * V - * ------------------------------------------------------------ - * | | | | - * | | | | - * | | | | - * | | | | - * | | | | - * | | | | - * | | | | - * | | | | - * | | | | - * V V V V - * ------------ -------------- --------------- -------------- - * | | | | | | | | - * | Upper | | Upper | | Upper | | Upper | - * | Page 00h | | Page 01h | | Page 02h | | Page 03h | - * | | | (Optional) | | (Optional) | | (Optional | - * | | | | | | | for Cable | - * | | | | | | | Assemblies) | - * | ID | | AST | | User | | | - * | Fields | | Table | | EEPROM Data | | | - * | | | | | | | | - * | | | | | | | | - * | | | | | | | | - * ------------ -------------- --------------- -------------- - * - * The SFF 8436 (QSFP) spec only defines the 4 pages described above. - * In anticipation of future applications and devices, this driver - * supports access to the full architected range, 256 pages. - * - **/ - -/* #define DEBUG 1 */ - -#undef EEPROM_CLASS -#ifdef CONFIG_EEPROM_CLASS -#define EEPROM_CLASS -#endif -#ifdef CONFIG_EEPROM_CLASS_MODULE -#define EEPROM_CLASS -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef EEPROM_CLASS -#include -#endif - -#include - -/* The maximum length of a port name */ -#define MAX_PORT_NAME_LEN 20 - -struct optoe_platform_data { - u32 byte_len; /* size (sum of all addr) */ - u16 page_size; /* for writes */ - u8 flags; - void *dummy1; /* backward compatibility */ - void *dummy2; /* backward compatibility */ - -#ifdef EEPROM_CLASS - struct eeprom_platform_data *eeprom_data; -#endif - char port_name[MAX_PORT_NAME_LEN]; -}; - -/* fundamental unit of addressing for EEPROM */ -#define OPTOE_PAGE_SIZE 128 -/* - * Single address devices (eg QSFP) have 256 pages, plus the unpaged - * low 128 bytes. If the device does not support paging, it is - * only 2 'pages' long. - */ -#define OPTOE_ARCH_PAGES 256 -#define ONE_ADDR_EEPROM_SIZE ((1 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE) -#define ONE_ADDR_EEPROM_UNPAGED_SIZE (2 * OPTOE_PAGE_SIZE) -/* - * Dual address devices (eg SFP) have 256 pages, plus the unpaged - * low 128 bytes, plus 256 bytes at 0x50. If the device does not - * support paging, it is 4 'pages' long. - */ -#define TWO_ADDR_EEPROM_SIZE ((3 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE) -#define TWO_ADDR_EEPROM_UNPAGED_SIZE (4 * OPTOE_PAGE_SIZE) -#define TWO_ADDR_NO_0X51_SIZE (2 * OPTOE_PAGE_SIZE) - -/* a few constants to find our way around the EEPROM */ -#define OPTOE_PAGE_SELECT_REG 0x7F -#define ONE_ADDR_PAGEABLE_REG 0x02 -#define ONE_ADDR_NOT_PAGEABLE (1<<2) -#define TWO_ADDR_PAGEABLE_REG 0x40 -#define TWO_ADDR_PAGEABLE (1<<4) -#define TWO_ADDR_0X51_REG 92 -#define TWO_ADDR_0X51_SUPP (1<<6) -#define OPTOE_ID_REG 0 -#define OPTOE_READ_OP 0 -#define OPTOE_WRITE_OP 1 -#define OPTOE_EOF 0 /* used for access beyond end of device */ - -struct optoe_data { - struct optoe_platform_data chip; - int use_smbus; - char port_name[MAX_PORT_NAME_LEN]; - - /* - * Lock protects against activities from other Linux tasks, - * but not from changes by other I2C masters. - */ - struct mutex lock; - struct bin_attribute bin; - struct attribute_group attr_group; - - u8 *writebuf; - unsigned int write_max; - - unsigned int num_addresses; - -#ifdef EEPROM_CLASS - struct eeprom_device *eeprom_dev; -#endif - - /* dev_class: ONE_ADDR (QSFP) or TWO_ADDR (SFP) */ - int dev_class; - - struct i2c_client *client[]; -}; - - -/* - * This parameter is to help this driver avoid blocking other drivers out - * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C - * clock, one 256 byte read takes about 1/43 second which is excessive; - * but the 1/170 second it takes at 400 kHz may be quite reasonable; and - * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. - * - * This value is forced to be a power of two so that writes align on pages. - */ -static unsigned int io_limit = OPTOE_PAGE_SIZE; - -/* - * specs often allow 5 msec for a page write, sometimes 20 msec; - * it's important to recover from write timeouts. - */ -static unsigned int write_timeout = 25; - -/* - * flags to distinguish one-address (QSFP family) from two-address (SFP family) - * If the family is not known, figure it out when the device is accessed - */ -#define ONE_ADDR 1 -#define TWO_ADDR 2 - -static const struct i2c_device_id optoe_ids[] = { - { "optoe1", ONE_ADDR }, - { "optoe2", TWO_ADDR }, - { "sff8436", ONE_ADDR }, - { "24c04", TWO_ADDR }, - { /* END OF LIST */ } -}; -MODULE_DEVICE_TABLE(i2c, optoe_ids); - -/*-------------------------------------------------------------------------*/ -/* - * This routine computes the addressing information to be used for - * a given r/w request. - * - * Task is to calculate the client (0 = i2c addr 50, 1 = i2c addr 51), - * the page, and the offset. - * - * Handles both single address (eg QSFP) and two address (eg SFP). - * For SFP, offset 0-255 are on client[0], >255 is on client[1] - * Offset 256-383 are on the lower half of client[1] - * Pages are accessible on the upper half of client[1]. - * Offset >383 are in 128 byte pages mapped into the upper half - * - * For QSFP, all offsets are on client[0] - * offset 0-127 are on the lower half of client[0] (no paging) - * Pages are accessible on the upper half of client[1]. - * Offset >127 are in 128 byte pages mapped into the upper half - * - * Callers must not read/write beyond the end of a client or a page - * without recomputing the client/page. Hence offset (within page) - * plus length must be less than or equal to 128. (Note that this - * routine does not have access to the length of the call, hence - * cannot do the validity check.) - * - * Offset within Lower Page 00h and Upper Page 00h are not recomputed - */ - -static uint8_t optoe_translate_offset(struct optoe_data *optoe, - loff_t *offset, struct i2c_client **client) -{ - unsigned int page = 0; - - *client = optoe->client[0]; - - /* if SFP style, offset > 255, shift to i2c addr 0x51 */ - if (optoe->dev_class == TWO_ADDR) { - if (*offset > 255) { - /* like QSFP, but shifted to client[1] */ - *client = optoe->client[1]; - *offset -= 256; - } - } - - /* - * if offset is in the range 0-128... - * page doesn't matter (using lower half), return 0. - * offset is already correct (don't add 128 to get to paged area) - */ - if (*offset < OPTOE_PAGE_SIZE) - return page; - - /* note, page will always be positive since *offset >= 128 */ - page = (*offset >> 7)-1; - /* 0x80 places the offset in the top half, offset is last 7 bits */ - *offset = OPTOE_PAGE_SIZE + (*offset & 0x7f); - - return page; /* note also returning client and offset */ -} - -static ssize_t optoe_eeprom_read(struct optoe_data *optoe, - struct i2c_client *client, - char *buf, unsigned int offset, size_t count) -{ - struct i2c_msg msg[2]; - u8 msgbuf[2]; - unsigned long timeout, read_time; - int status, i; - - memset(msg, 0, sizeof(msg)); - - switch (optoe->use_smbus) { - case I2C_SMBUS_I2C_BLOCK_DATA: - /*smaller eeproms can work given some SMBus extension calls */ - if (count > I2C_SMBUS_BLOCK_MAX) - count = I2C_SMBUS_BLOCK_MAX; - break; - case I2C_SMBUS_WORD_DATA: - /* Check for odd length transaction */ - count = (count == 1) ? 1 : 2; - break; - case I2C_SMBUS_BYTE_DATA: - count = 1; - break; - default: - /* - * When we have a better choice than SMBus calls, use a - * combined I2C message. Write address; then read up to - * io_limit data bytes. msgbuf is u8 and will cast to our - * needs. - */ - i = 0; - msgbuf[i++] = offset; - - msg[0].addr = client->addr; - msg[0].buf = msgbuf; - msg[0].len = i; - - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].buf = buf; - msg[1].len = count; - } - - /* - * Reads fail if the previous write didn't complete yet. We may - * loop a few times until this one succeeds, waiting at least - * long enough for one entire page write to work. - */ - timeout = jiffies + msecs_to_jiffies(write_timeout); - do { - read_time = jiffies; - - switch (optoe->use_smbus) { - case I2C_SMBUS_I2C_BLOCK_DATA: - status = i2c_smbus_read_i2c_block_data(client, offset, - count, buf); - break; - case I2C_SMBUS_WORD_DATA: - status = i2c_smbus_read_word_data(client, offset); - if (status >= 0) { - buf[0] = status & 0xff; - if (count == 2) - buf[1] = status >> 8; - status = count; - } - break; - case I2C_SMBUS_BYTE_DATA: - status = i2c_smbus_read_byte_data(client, offset); - if (status >= 0) { - buf[0] = status; - status = count; - } - break; - default: - status = i2c_transfer(client->adapter, msg, 2); - if (status == 2) - status = count; - } - - dev_dbg(&client->dev, "eeprom read %zu@%d --> %d (%ld)\n", - count, offset, status, jiffies); - - if (status == count) /* happy path */ - return count; - - if (status == -ENXIO) /* no module present */ - return status; - - /* REVISIT: at HZ=100, this is sloooow */ - usleep_range(1000, 2000); - } while (time_before(read_time, timeout)); - - return -ETIMEDOUT; -} - -static ssize_t optoe_eeprom_write(struct optoe_data *optoe, - struct i2c_client *client, - const char *buf, - unsigned int offset, size_t count) -{ - struct i2c_msg msg; - ssize_t status; - unsigned long timeout, write_time; - unsigned int next_page_start; - int i = 0; - - /* write max is at most a page - * (In this driver, write_max is actually one byte!) - */ - if (count > optoe->write_max) - count = optoe->write_max; - - /* shorten count if necessary to avoid crossing page boundary */ - next_page_start = roundup(offset + 1, OPTOE_PAGE_SIZE); - if (offset + count > next_page_start) - count = next_page_start - offset; - - switch (optoe->use_smbus) { - case I2C_SMBUS_I2C_BLOCK_DATA: - /*smaller eeproms can work given some SMBus extension calls */ - if (count > I2C_SMBUS_BLOCK_MAX) - count = I2C_SMBUS_BLOCK_MAX; - break; - case I2C_SMBUS_WORD_DATA: - /* Check for odd length transaction */ - count = (count == 1) ? 1 : 2; - break; - case I2C_SMBUS_BYTE_DATA: - count = 1; - break; - default: - /* If we'll use I2C calls for I/O, set up the message */ - msg.addr = client->addr; - msg.flags = 0; - - /* msg.buf is u8 and casts will mask the values */ - msg.buf = optoe->writebuf; - - msg.buf[i++] = offset; - memcpy(&msg.buf[i], buf, count); - msg.len = i + count; - break; - } - - /* - * Reads fail if the previous write didn't complete yet. We may - * loop a few times until this one succeeds, waiting at least - * long enough for one entire page write to work. - */ - timeout = jiffies + msecs_to_jiffies(write_timeout); - do { - write_time = jiffies; - - switch (optoe->use_smbus) { - case I2C_SMBUS_I2C_BLOCK_DATA: - status = i2c_smbus_write_i2c_block_data(client, - offset, count, buf); - if (status == 0) - status = count; - break; - case I2C_SMBUS_WORD_DATA: - if (count == 2) { - status = i2c_smbus_write_word_data(client, - offset, (u16)((buf[0])|(buf[1] << 8))); - } else { - /* count = 1 */ - status = i2c_smbus_write_byte_data(client, - offset, buf[0]); - } - if (status == 0) - status = count; - break; - case I2C_SMBUS_BYTE_DATA: - status = i2c_smbus_write_byte_data(client, offset, - buf[0]); - if (status == 0) - status = count; - break; - default: - status = i2c_transfer(client->adapter, &msg, 1); - if (status == 1) - status = count; - break; - } - - dev_dbg(&client->dev, "eeprom write %zu@%d --> %ld (%lu)\n", - count, offset, (long int) status, jiffies); - - if (status == count) - return count; - - /* REVISIT: at HZ=100, this is sloooow */ - usleep_range(1000, 2000); - } while (time_before(write_time, timeout)); - - return -ETIMEDOUT; -} - - -static ssize_t optoe_eeprom_update_client(struct optoe_data *optoe, - char *buf, loff_t off, - size_t count, int opcode) -{ - struct i2c_client *client; - ssize_t retval = 0; - uint8_t page = 0; - loff_t phy_offset = off; - int ret = 0; - - page = optoe_translate_offset(optoe, &phy_offset, &client); - dev_dbg(&client->dev, - "%s off %lld page:%d phy_offset:%lld, count:%ld, opcode:%d\n", - __func__, off, page, phy_offset, (long int) count, opcode); - if (page > 0) { - ret = optoe_eeprom_write(optoe, client, &page, - OPTOE_PAGE_SELECT_REG, 1); - if (ret < 0) { - dev_dbg(&client->dev, - "Write page register for page %d failed ret:%d!\n", - page, ret); - return ret; - } - } - - while (count) { - ssize_t status; - - if (opcode == OPTOE_READ_OP) { - status = optoe_eeprom_read(optoe, client, - buf, phy_offset, count); - } else { - status = optoe_eeprom_write(optoe, client, - buf, phy_offset, count); - } - if (status <= 0) { - if (retval == 0) - retval = status; - break; - } - buf += status; - phy_offset += status; - count -= status; - retval += status; - } - - - if (page > 0) { - /* return the page register to page 0 (why?) */ - page = 0; - ret = optoe_eeprom_write(optoe, client, &page, - OPTOE_PAGE_SELECT_REG, 1); - if (ret < 0) { - dev_err(&client->dev, - "Restore page register to 0 failed:%d!\n", ret); - /* error only if nothing has been transferred */ - if (retval == 0) - retval = ret; - } - } - return retval; -} - -/* - * Figure out if this access is within the range of supported pages. - * Note this is called on every access because we don't know if the - * module has been replaced since the last call. - * If/when modules support more pages, this is the routine to update - * to validate and allow access to additional pages. - * - * Returns updated len for this access: - * - entire access is legal, original len is returned. - * - access begins legal but is too long, len is truncated to fit. - * - initial offset exceeds supported pages, return OPTOE_EOF (zero) - */ -static ssize_t optoe_page_legal(struct optoe_data *optoe, - loff_t off, size_t len) -{ - struct i2c_client *client = optoe->client[0]; - u8 regval; - int status; - size_t maxlen; - - if (off < 0) - return -EINVAL; - if (optoe->dev_class == TWO_ADDR) { - /* SFP case */ - /* if only using addr 0x50 (first 256 bytes) we're good */ - if ((off + len) <= TWO_ADDR_NO_0X51_SIZE) - return len; - /* if offset exceeds possible pages, we're not good */ - if (off >= TWO_ADDR_EEPROM_SIZE) - return OPTOE_EOF; - /* in between, are pages supported? */ - status = optoe_eeprom_read(optoe, client, ®val, - TWO_ADDR_PAGEABLE_REG, 1); - if (status < 0) - return status; /* error out (no module?) */ - if (regval & TWO_ADDR_PAGEABLE) { - /* Pages supported, trim len to the end of pages */ - maxlen = TWO_ADDR_EEPROM_SIZE - off; - } else { - /* pages not supported, trim len to unpaged size */ - if (off >= TWO_ADDR_EEPROM_UNPAGED_SIZE) - return OPTOE_EOF; - - /* will be accessing addr 0x51, is that supported? */ - /* byte 92, bit 6 implies DDM support, 0x51 support */ - status = optoe_eeprom_read(optoe, client, ®val, - TWO_ADDR_0X51_REG, 1); - if (status < 0) - return status; - if (regval & TWO_ADDR_0X51_SUPP) { - /* addr 0x51 is OK */ - maxlen = TWO_ADDR_EEPROM_UNPAGED_SIZE - off; - } else { - /* addr 0x51 NOT supported, trim to 256 max */ - if (off >= TWO_ADDR_NO_0X51_SIZE) - return OPTOE_EOF; - maxlen = TWO_ADDR_NO_0X51_SIZE - off; - } - } - len = (len > maxlen) ? maxlen : len; - dev_dbg(&client->dev, - "page_legal, SFP, off %lld len %ld\n", - off, (long int) len); - } else { - /* QSFP case */ - /* if no pages needed, we're good */ - if ((off + len) <= ONE_ADDR_EEPROM_UNPAGED_SIZE) - return len; - /* if offset exceeds possible pages, we're not good */ - if (off >= ONE_ADDR_EEPROM_SIZE) - return OPTOE_EOF; - /* in between, are pages supported? */ - status = optoe_eeprom_read(optoe, client, ®val, - ONE_ADDR_PAGEABLE_REG, 1); - if (status < 0) - return status; /* error out (no module?) */ - if (regval & ONE_ADDR_NOT_PAGEABLE) { - /* pages not supported, trim len to unpaged size */ - if (off >= ONE_ADDR_EEPROM_UNPAGED_SIZE) - return OPTOE_EOF; - maxlen = ONE_ADDR_EEPROM_UNPAGED_SIZE - off; - } else { - /* Pages supported, trim len to the end of pages */ - maxlen = ONE_ADDR_EEPROM_SIZE - off; - } - len = (len > maxlen) ? maxlen : len; - dev_dbg(&client->dev, - "page_legal, QSFP, off %lld len %ld\n", - off, (long int) len); - } - return len; -} - -static ssize_t optoe_read_write(struct optoe_data *optoe, - char *buf, loff_t off, size_t len, int opcode) -{ - struct i2c_client *client = optoe->client[0]; - int chunk; - int status = 0; - ssize_t retval; - size_t pending_len = 0, chunk_len = 0; - loff_t chunk_offset = 0, chunk_start_offset = 0; - loff_t chunk_end_offset = 0; - - dev_dbg(&client->dev, - "%s: off %lld len:%ld, opcode:%s\n", - __func__, off, (long int) len, - (opcode == OPTOE_READ_OP) ? "r" : "w"); - if (unlikely(!len)) - return len; - - /* - * Read data from chip, protecting against concurrent updates - * from this host, but not from other I2C masters. - */ - mutex_lock(&optoe->lock); - - /* - * Confirm this access fits within the device suppored addr range - */ - status = optoe_page_legal(optoe, off, len); - if ((status == OPTOE_EOF) || (status < 0)) { - mutex_unlock(&optoe->lock); - return status; - } - len = status; - - /* - * For each (128 byte) chunk involved in this request, issue a - * separate call to sff_eeprom_update_client(), to - * ensure that each access recalculates the client/page - * and writes the page register as needed. - * Note that chunk to page mapping is confusing, is different for - * QSFP and SFP, and never needs to be done. Don't try! - */ - pending_len = len; /* amount remaining to transfer */ - retval = 0; /* amount transferred */ - for (chunk = off >> 7; chunk <= (off + len - 1) >> 7; chunk++) { - - /* - * Compute the offset and number of bytes to be read/write - * - * 1. start at an offset not equal to 0 (within the chunk) - * and read/write less than the rest of the chunk - * 2. start at an offset not equal to 0 and read/write the rest - * of the chunk - * 3. start at offset 0 (within the chunk) and read/write less - * than entire chunk - * 4. start at offset 0 (within the chunk), and read/write - * the entire chunk - */ - chunk_start_offset = chunk * OPTOE_PAGE_SIZE; - chunk_end_offset = chunk_start_offset + OPTOE_PAGE_SIZE; - - if (chunk_start_offset < off) { - chunk_offset = off; - if ((off + pending_len) < chunk_end_offset) - chunk_len = pending_len; - else - chunk_len = chunk_end_offset - off; - } else { - chunk_offset = chunk_start_offset; - if (pending_len < OPTOE_PAGE_SIZE) - chunk_len = pending_len; - else - chunk_len = OPTOE_PAGE_SIZE; - } - - dev_dbg(&client->dev, - "sff_r/w: off %lld, len %ld, chunk_start_offset %lld, chunk_offset %lld, chunk_len %ld, pending_len %ld\n", - off, (long int) len, chunk_start_offset, chunk_offset, - (long int) chunk_len, (long int) pending_len); - - /* - * note: chunk_offset is from the start of the EEPROM, - * not the start of the chunk - */ - status = optoe_eeprom_update_client(optoe, buf, - chunk_offset, chunk_len, opcode); - if (status != chunk_len) { - /* This is another 'no device present' path */ - dev_dbg(&client->dev, - "o_u_c: chunk %d c_offset %lld c_len %ld failed %d!\n", - chunk, chunk_offset, (long int) chunk_len, status); - if (status > 0) - retval += status; - if (retval == 0) - retval = status; - break; - } - buf += status; - pending_len -= status; - retval += status; - } - mutex_unlock(&optoe->lock); - - return retval; -} - -static ssize_t optoe_bin_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t off, size_t count) -{ - struct i2c_client *client = to_i2c_client(container_of(kobj, - struct device, kobj)); - struct optoe_data *optoe = i2c_get_clientdata(client); - - return optoe_read_write(optoe, buf, off, count, OPTOE_READ_OP); -} - - -static ssize_t optoe_bin_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t off, size_t count) -{ - struct i2c_client *client = to_i2c_client(container_of(kobj, - struct device, kobj)); - struct optoe_data *optoe = i2c_get_clientdata(client); - - return optoe_read_write(optoe, buf, off, count, OPTOE_WRITE_OP); -} - -static int optoe_remove(struct i2c_client *client) -{ - struct optoe_data *optoe; - int i; - - optoe = i2c_get_clientdata(client); - sysfs_remove_group(&client->dev.kobj, &optoe->attr_group); - sysfs_remove_bin_file(&client->dev.kobj, &optoe->bin); - - for (i = 1; i < optoe->num_addresses; i++) - i2c_unregister_device(optoe->client[i]); - -#ifdef EEPROM_CLASS - eeprom_device_unregister(optoe->eeprom_dev); -#endif - - kfree(optoe->writebuf); - kfree(optoe); - return 0; -} - -static ssize_t show_dev_class(struct device *dev, - struct device_attribute *dattr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct optoe_data *optoe = i2c_get_clientdata(client); - ssize_t count; - - mutex_lock(&optoe->lock); - count = sprintf(buf, "%d\n", optoe->dev_class); - mutex_unlock(&optoe->lock); - - return count; -} - -static ssize_t set_dev_class(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct optoe_data *optoe = i2c_get_clientdata(client); - int dev_class; - - /* - * dev_class is actually the number of i2c addresses used, thus - * legal values are "1" (QSFP class) and "2" (SFP class) - */ - - if (kstrtoint(buf, 0, &dev_class) != 0 || - dev_class < 1 || dev_class > 2) - return -EINVAL; - - mutex_lock(&optoe->lock); - optoe->dev_class = dev_class; - mutex_unlock(&optoe->lock); - - return count; -} - -/* - * if using the EEPROM CLASS driver, we don't report a port_name, - * the EEPROM CLASS drive handles that. Hence all this code is - * only compiled if we are NOT using the EEPROM CLASS driver. - */ -#ifndef EEPROM_CLASS - -static ssize_t show_port_name(struct device *dev, - struct device_attribute *dattr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct optoe_data *optoe = i2c_get_clientdata(client); - ssize_t count; - - mutex_lock(&optoe->lock); - count = sprintf(buf, "%s\n", optoe->port_name); - mutex_unlock(&optoe->lock); - - return count; -} - -static ssize_t set_port_name(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct optoe_data *optoe = i2c_get_clientdata(client); - char port_name[MAX_PORT_NAME_LEN]; - - /* no checking, this value is not used except by show_port_name */ - - if (sscanf(buf, "%19s", port_name) != 1) - return -EINVAL; - - mutex_lock(&optoe->lock); - strcpy(optoe->port_name, port_name); - mutex_unlock(&optoe->lock); - - return count; -} - -static DEVICE_ATTR(port_name, 0644, show_port_name, set_port_name); -#endif /* if NOT defined EEPROM_CLASS, the common case */ - -static DEVICE_ATTR(dev_class, 0644, show_dev_class, set_dev_class); - -static struct attribute *optoe_attrs[] = { -#ifndef EEPROM_CLASS - &dev_attr_port_name.attr, -#endif - &dev_attr_dev_class.attr, - NULL, -}; - -static struct attribute_group optoe_attr_group = { - .attrs = optoe_attrs, -}; - -static int optoe_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int err; - int use_smbus = 0; - struct optoe_platform_data chip; - struct optoe_data *optoe; - int num_addresses = 0; - char port_name[MAX_PORT_NAME_LEN]; - - if (client->addr != 0x50) { - dev_dbg(&client->dev, "probe, bad i2c addr: 0x%x\n", - client->addr); - err = -EINVAL; - goto exit; - } - - if (client->dev.platform_data) { - chip = *(struct optoe_platform_data *)client->dev.platform_data; - /* take the port name from the supplied platform data */ -#ifdef EEPROM_CLASS - strncpy(port_name, chip.eeprom_data->label, MAX_PORT_NAME_LEN); -#else - memcpy(port_name, chip.port_name, MAX_PORT_NAME_LEN); -#endif - dev_dbg(&client->dev, - "probe, chip provided, flags:0x%x; name: %s\n", - chip.flags, client->name); - } else { - if (!id->driver_data) { - err = -ENODEV; - goto exit; - } - dev_dbg(&client->dev, "probe, building chip\n"); - strcpy(port_name, "unitialized"); - chip.flags = 0; -#ifdef EEPROM_CLASS - chip.eeprom_data = NULL; -#endif - } - - /* Use I2C operations unless we're stuck with SMBus extensions. */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - if (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { - use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; - } else if (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_WORD_DATA)) { - use_smbus = I2C_SMBUS_WORD_DATA; - } else if (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_BYTE_DATA)) { - use_smbus = I2C_SMBUS_BYTE_DATA; - } else { - err = -EPFNOSUPPORT; - goto exit; - } - } - - - /* - * Make room for two i2c clients - */ - num_addresses = 2; - - optoe = kzalloc(sizeof(struct optoe_data) + - num_addresses * sizeof(struct i2c_client *), - GFP_KERNEL); - if (!optoe) { - err = -ENOMEM; - goto exit; - } - - mutex_init(&optoe->lock); - - /* determine whether this is a one-address or two-address module */ - if ((strcmp(client->name, "optoe1") == 0) || - (strcmp(client->name, "sff8436") == 0)) { - /* one-address (eg QSFP) family */ - optoe->dev_class = ONE_ADDR; - chip.byte_len = ONE_ADDR_EEPROM_SIZE; - num_addresses = 1; - } else if ((strcmp(client->name, "optoe2") == 0) || - (strcmp(client->name, "24c04") == 0)) { - /* SFP family */ - optoe->dev_class = TWO_ADDR; - chip.byte_len = TWO_ADDR_EEPROM_SIZE; - } else { /* those were the only two choices */ - err = -EINVAL; - goto exit; - } - - dev_dbg(&client->dev, "dev_class: %d\n", optoe->dev_class); - optoe->use_smbus = use_smbus; - optoe->chip = chip; - optoe->num_addresses = num_addresses; - memcpy(optoe->port_name, port_name, MAX_PORT_NAME_LEN); - - /* - * Export the EEPROM bytes through sysfs, since that's convenient. - * By default, only root should see the data (maybe passwords etc) - */ - sysfs_bin_attr_init(&optoe->bin); - optoe->bin.attr.name = "eeprom"; - optoe->bin.attr.mode = 0444; - optoe->bin.read = optoe_bin_read; - optoe->bin.size = chip.byte_len; - - if (!use_smbus || - (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) || - i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_WRITE_WORD_DATA) || - i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { - /* - * NOTE: AN-2079 - * Finisar recommends that the host implement 1 byte writes - * only since this module only supports 32 byte page boundaries. - * 2 byte writes are acceptable for PE and Vout changes per - * Application Note AN-2071. - */ - unsigned int write_max = 1; - - optoe->bin.write = optoe_bin_write; - optoe->bin.attr.mode |= 0200; - - if (write_max > io_limit) - write_max = io_limit; - if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) - write_max = I2C_SMBUS_BLOCK_MAX; - optoe->write_max = write_max; - - /* buffer (data + address at the beginning) */ - optoe->writebuf = kmalloc(write_max + 2, GFP_KERNEL); - if (!optoe->writebuf) { - err = -ENOMEM; - goto exit_kfree; - } - } else { - dev_warn(&client->dev, - "cannot write due to controller restrictions."); - } - - optoe->client[0] = client; - - /* SFF-8472 spec requires that the second I2C address be 0x51 */ - if (num_addresses == 2) { - optoe->client[1] = i2c_new_dummy_device(client->adapter, 0x51); - if (IS_ERR(optoe->client[1])) { - dev_err(&client->dev, "address 0x51 unavailable\n"); - err = -EADDRINUSE; - goto err_struct; - } - } - - /* create the sysfs eeprom file */ - err = sysfs_create_bin_file(&client->dev.kobj, &optoe->bin); - if (err) - goto err_struct; - - optoe->attr_group = optoe_attr_group; - - err = sysfs_create_group(&client->dev.kobj, &optoe->attr_group); - if (err) { - dev_err(&client->dev, "failed to create sysfs attribute group.\n"); - goto err_struct; - } - -#ifdef EEPROM_CLASS - optoe->eeprom_dev = eeprom_device_register(&client->dev, - chip.eeprom_data); - if (IS_ERR(optoe->eeprom_dev)) { - dev_err(&client->dev, "error registering eeprom device.\n"); - err = PTR_ERR(optoe->eeprom_dev); - goto err_sysfs_cleanup; - } -#endif - - i2c_set_clientdata(client, optoe); - - dev_info(&client->dev, "%zu byte %s EEPROM, %s\n", - optoe->bin.size, client->name, - optoe->bin.write ? "read/write" : "read-only"); - - if (use_smbus == I2C_SMBUS_WORD_DATA || - use_smbus == I2C_SMBUS_BYTE_DATA) { - dev_notice(&client->dev, - "Falling back to %s reads, performance will suffer\n", - use_smbus == I2C_SMBUS_WORD_DATA ? "word" : "byte"); - } - - return 0; - -#ifdef EEPROM_CLASS -err_sysfs_cleanup: - sysfs_remove_group(&client->dev.kobj, &optoe->attr_group); - sysfs_remove_bin_file(&client->dev.kobj, &optoe->bin); -#endif - -err_struct: - if (num_addresses == 2) { - if (optoe->client[1]) - i2c_unregister_device(optoe->client[1]); - } - - kfree(optoe->writebuf); -exit_kfree: - kfree(optoe); -exit: - dev_dbg(&client->dev, "probe error %d\n", err); - - return err; -} - -/*-------------------------------------------------------------------------*/ - -static struct i2c_driver optoe_driver = { - .driver = { - .name = "optoe", - .owner = THIS_MODULE, - }, - .probe = optoe_probe, - .remove = optoe_remove, - .id_table = optoe_ids, -}; - -static int __init optoe_init(void) -{ - - if (!io_limit) { - pr_err("optoe: io_limit must not be 0!\n"); - return -EINVAL; - } - - io_limit = rounddown_pow_of_two(io_limit); - return i2c_add_driver(&optoe_driver); -} -module_init(optoe_init); - -static void __exit optoe_exit(void) -{ - i2c_del_driver(&optoe_driver); -} -module_exit(optoe_exit); - -MODULE_DESCRIPTION("Driver for optical transceiver (SFP, QSFP, ...) EEPROMs"); -MODULE_AUTHOR("DON BOLLINGER "); -MODULE_LICENSE("GPL"); diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_10/.gitignore b/packages/platforms/accton/arm64/as4224/src/modules/.gitignore similarity index 100% rename from packages/platforms/accton/arm64/as4224/src/modules-5_10/.gitignore rename to packages/platforms/accton/arm64/as4224/src/modules/.gitignore diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_10/Makefile b/packages/platforms/accton/arm64/as4224/src/modules/Makefile similarity index 100% rename from packages/platforms/accton/arm64/as4224/src/modules-5_10/Makefile rename to packages/platforms/accton/arm64/as4224/src/modules/Makefile diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_10/arm64-accton-as4224-cpld.c b/packages/platforms/accton/arm64/as4224/src/modules/arm64-accton-as4224-cpld.c similarity index 100% rename from packages/platforms/accton/arm64/as4224/src/modules-5_10/arm64-accton-as4224-cpld.c rename to packages/platforms/accton/arm64/as4224/src/modules/arm64-accton-as4224-cpld.c diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_10/arm64-accton-as4224-fan.c b/packages/platforms/accton/arm64/as4224/src/modules/arm64-accton-as4224-fan.c similarity index 100% rename from packages/platforms/accton/arm64/as4224/src/modules-5_10/arm64-accton-as4224-fan.c rename to packages/platforms/accton/arm64/as4224/src/modules/arm64-accton-as4224-fan.c diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_10/arm64-accton-as4224-gpio-i2c.c b/packages/platforms/accton/arm64/as4224/src/modules/arm64-accton-as4224-gpio-i2c.c similarity index 100% rename from packages/platforms/accton/arm64/as4224/src/modules-5_10/arm64-accton-as4224-gpio-i2c.c rename to packages/platforms/accton/arm64/as4224/src/modules/arm64-accton-as4224-gpio-i2c.c diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_10/arm64-accton-as4224-psu.c b/packages/platforms/accton/arm64/as4224/src/modules/arm64-accton-as4224-psu.c similarity index 100% rename from packages/platforms/accton/arm64/as4224/src/modules-5_10/arm64-accton-as4224-psu.c rename to packages/platforms/accton/arm64/as4224/src/modules/arm64-accton-as4224-psu.c diff --git a/packages/platforms/accton/arm64/as4224/src/modules-5_10/optoe.c b/packages/platforms/accton/arm64/as4224/src/modules/optoe.c similarity index 100% rename from packages/platforms/accton/arm64/as4224/src/modules-5_10/optoe.c rename to packages/platforms/accton/arm64/as4224/src/modules/optoe.c diff --git a/packages/platforms/accton/arm64/as4564-26p/modules/PKG.yml b/packages/platforms/accton/arm64/as4564-26p/modules/PKG.yml index 6ec199687..89434c91c 100644 --- a/packages/platforms/accton/arm64/as4564-26p/modules/PKG.yml +++ b/packages/platforms/accton/arm64/as4564-26p/modules/PKG.yml @@ -1 +1 @@ -!include $ONL_TEMPLATES/platform-modules.yml ARCH=arm64 VENDOR=accton BASENAME=arm64-accton-as4564-26p KERNELS="onl-kernel-5.10-lts-arm64-all:arm64" +!include $ONL_TEMPLATES/platform-modules.yml ARCH=arm64 VENDOR=accton BASENAME=arm64-accton-as4564-26p KERNELS="onl-kernel-5.15-lts-arm64-all:arm64" diff --git a/packages/platforms/accton/arm64/as4564-26p/modules/builds/Makefile b/packages/platforms/accton/arm64/as4564-26p/modules/builds/Makefile index f283ffd16..d0935d232 100644 --- a/packages/platforms/accton/arm64/as4564-26p/modules/builds/Makefile +++ b/packages/platforms/accton/arm64/as4564-26p/modules/builds/Makefile @@ -1,4 +1,4 @@ -KERNELS := onl-kernel-5.10-lts-arm64-all:arm64 +KERNELS := onl-kernel-5.15-lts-arm64-all:arm64 KMODULES := src VENDOR := accton BASENAME := arm64-accton-as4564-26p diff --git a/packages/platforms/accton/arm64/as4564-26p/platform-config/r0/src/lib/arm64-accton-as4564-26p-r0.yml b/packages/platforms/accton/arm64/as4564-26p/platform-config/r0/src/lib/arm64-accton-as4564-26p-r0.yml index 4f7ea2c6b..ca9d2bc63 100644 --- a/packages/platforms/accton/arm64/as4564-26p/platform-config/r0/src/lib/arm64-accton-as4564-26p-r0.yml +++ b/packages/platforms/accton/arm64/as4564-26p/platform-config/r0/src/lib/arm64-accton-as4564-26p-r0.yml @@ -9,10 +9,10 @@ arm64-accton-as4564-26p-r0: flat_image_tree: kernel: - <<: *arm64-kernel-5-10 + <<: *arm64-kernel-5-15 dtb: =: accton-as4564-26p.dtb - <<: *arm64-kernel-5-10-package + <<: *arm64-kernel-5-15-package itb: <<: *arm64-itb