1662f2482SMichael Shych // SPDX-License-Identifier: GPL-2.0+ 2662f2482SMichael Shych /* 3662f2482SMichael Shych * Nvidia sn2201 driver 4662f2482SMichael Shych * 5662f2482SMichael Shych * Copyright (C) 2022 Nvidia Technologies Ltd. 6662f2482SMichael Shych */ 7662f2482SMichael Shych 8662f2482SMichael Shych #include <linux/device.h> 9662f2482SMichael Shych #include <linux/i2c.h> 10662f2482SMichael Shych #include <linux/interrupt.h> 11662f2482SMichael Shych #include <linux/irq.h> 12662f2482SMichael Shych #include <linux/gpio.h> 13662f2482SMichael Shych #include <linux/module.h> 14662f2482SMichael Shych #include <linux/platform_data/mlxcpld.h> 15662f2482SMichael Shych #include <linux/platform_data/mlxreg.h> 16662f2482SMichael Shych #include <linux/platform_device.h> 17662f2482SMichael Shych #include <linux/regmap.h> 18662f2482SMichael Shych 19662f2482SMichael Shych /* SN2201 CPLD register offset. */ 20662f2482SMichael Shych #define NVSW_SN2201_CPLD_LPC_I2C_BASE_ADRR 0x2000 21662f2482SMichael Shych #define NVSW_SN2201_CPLD_LPC_IO_RANGE 0x100 22662f2482SMichael Shych #define NVSW_SN2201_HW_VER_ID_OFFSET 0x00 23662f2482SMichael Shych #define NVSW_SN2201_BOARD_ID_OFFSET 0x01 24662f2482SMichael Shych #define NVSW_SN2201_CPLD_VER_OFFSET 0x02 25662f2482SMichael Shych #define NVSW_SN2201_CPLD_MVER_OFFSET 0x03 26662f2482SMichael Shych #define NVSW_SN2201_CPLD_ID_OFFSET 0x04 27662f2482SMichael Shych #define NVSW_SN2201_CPLD_PN_OFFSET 0x05 28662f2482SMichael Shych #define NVSW_SN2201_CPLD_PN1_OFFSET 0x06 29662f2482SMichael Shych #define NVSW_SN2201_PSU_CTRL_OFFSET 0x0a 30662f2482SMichael Shych #define NVSW_SN2201_QSFP28_STATUS_OFFSET 0x0b 31662f2482SMichael Shych #define NVSW_SN2201_QSFP28_INT_STATUS_OFFSET 0x0c 32662f2482SMichael Shych #define NVSW_SN2201_QSFP28_LP_STATUS_OFFSET 0x0d 33662f2482SMichael Shych #define NVSW_SN2201_QSFP28_RST_STATUS_OFFSET 0x0e 34662f2482SMichael Shych #define NVSW_SN2201_SYS_STATUS_OFFSET 0x0f 35662f2482SMichael Shych #define NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET 0x10 36662f2482SMichael Shych #define NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET 0x12 37662f2482SMichael Shych #define NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET 0x13 38662f2482SMichael Shych #define NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET 0x14 39662f2482SMichael Shych #define NVSW_SN2201_SYS_RST_STATUS_OFFSET 0x15 40662f2482SMichael Shych #define NVSW_SN2201_SYS_INT_STATUS_OFFSET 0x21 41662f2482SMichael Shych #define NVSW_SN2201_SYS_INT_MASK_OFFSET 0x22 42662f2482SMichael Shych #define NVSW_SN2201_ASIC_STATUS_OFFSET 0x24 43662f2482SMichael Shych #define NVSW_SN2201_ASIC_EVENT_OFFSET 0x25 44662f2482SMichael Shych #define NVSW_SN2201_ASIC_MAKS_OFFSET 0x26 45662f2482SMichael Shych #define NVSW_SN2201_THML_STATUS_OFFSET 0x27 46662f2482SMichael Shych #define NVSW_SN2201_THML_EVENT_OFFSET 0x28 47662f2482SMichael Shych #define NVSW_SN2201_THML_MASK_OFFSET 0x29 48662f2482SMichael Shych #define NVSW_SN2201_PS_ALT_STATUS_OFFSET 0x2a 49662f2482SMichael Shych #define NVSW_SN2201_PS_ALT_EVENT_OFFSET 0x2b 50662f2482SMichael Shych #define NVSW_SN2201_PS_ALT_MASK_OFFSET 0x2c 51662f2482SMichael Shych #define NVSW_SN2201_PS_PRSNT_STATUS_OFFSET 0x30 52662f2482SMichael Shych #define NVSW_SN2201_PS_PRSNT_EVENT_OFFSET 0x31 53662f2482SMichael Shych #define NVSW_SN2201_PS_PRSNT_MASK_OFFSET 0x32 54662f2482SMichael Shych #define NVSW_SN2201_PS_DC_OK_STATUS_OFFSET 0x33 55662f2482SMichael Shych #define NVSW_SN2201_PS_DC_OK_EVENT_OFFSET 0x34 56662f2482SMichael Shych #define NVSW_SN2201_PS_DC_OK_MASK_OFFSET 0x35 57662f2482SMichael Shych #define NVSW_SN2201_RST_CAUSE1_OFFSET 0x36 58662f2482SMichael Shych #define NVSW_SN2201_RST_CAUSE2_OFFSET 0x37 59662f2482SMichael Shych #define NVSW_SN2201_RST_SW_CTRL_OFFSET 0x38 60662f2482SMichael Shych #define NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET 0x3a 61662f2482SMichael Shych #define NVSW_SN2201_FAN_PRSNT_EVENT_OFFSET 0x3b 62662f2482SMichael Shych #define NVSW_SN2201_FAN_PRSNT_MASK_OFFSET 0x3c 63662f2482SMichael Shych #define NVSW_SN2201_WD_TMR_OFFSET_LSB 0x40 64662f2482SMichael Shych #define NVSW_SN2201_WD_TMR_OFFSET_MSB 0x41 65662f2482SMichael Shych #define NVSW_SN2201_WD_ACT_OFFSET 0x42 66662f2482SMichael Shych #define NVSW_SN2201_FAN_LED1_CTRL_OFFSET 0x50 67662f2482SMichael Shych #define NVSW_SN2201_FAN_LED2_CTRL_OFFSET 0x51 68662f2482SMichael Shych #define NVSW_SN2201_REG_MAX 0x52 69662f2482SMichael Shych 70662f2482SMichael Shych /* Number of physical I2C busses. */ 71662f2482SMichael Shych #define NVSW_SN2201_PHY_I2C_BUS_NUM 2 72662f2482SMichael Shych /* Number of main mux channels. */ 73662f2482SMichael Shych #define NVSW_SN2201_MAIN_MUX_CHNL_NUM 8 74662f2482SMichael Shych 75662f2482SMichael Shych #define NVSW_SN2201_MAIN_NR 0 76662f2482SMichael Shych #define NVSW_SN2201_MAIN_MUX_NR 1 77662f2482SMichael Shych #define NVSW_SN2201_MAIN_MUX_DEFER_NR (NVSW_SN2201_PHY_I2C_BUS_NUM + \ 78662f2482SMichael Shych NVSW_SN2201_MAIN_MUX_CHNL_NUM - 1) 79662f2482SMichael Shych 80662f2482SMichael Shych #define NVSW_SN2201_MAIN_MUX_CH0_NR NVSW_SN2201_PHY_I2C_BUS_NUM 81662f2482SMichael Shych #define NVSW_SN2201_MAIN_MUX_CH1_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 1) 82662f2482SMichael Shych #define NVSW_SN2201_MAIN_MUX_CH2_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 2) 83662f2482SMichael Shych #define NVSW_SN2201_MAIN_MUX_CH3_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 3) 84662f2482SMichael Shych #define NVSW_SN2201_MAIN_MUX_CH5_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 5) 85662f2482SMichael Shych #define NVSW_SN2201_MAIN_MUX_CH6_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 6) 86662f2482SMichael Shych #define NVSW_SN2201_MAIN_MUX_CH7_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 7) 87*e2aabb7cSMichael Shych #define NVSW_SN2201_2ND_MUX_CH0_NR (NVSW_SN2201_MAIN_MUX_CH7_NR + 1) 88*e2aabb7cSMichael Shych #define NVSW_SN2201_2ND_MUX_CH1_NR (NVSW_SN2201_MAIN_MUX_CH7_NR + 2) 89*e2aabb7cSMichael Shych #define NVSW_SN2201_2ND_MUX_CH2_NR (NVSW_SN2201_MAIN_MUX_CH7_NR + 3) 90*e2aabb7cSMichael Shych #define NVSW_SN2201_2ND_MUX_CH3_NR (NVSW_SN2201_MAIN_MUX_CH7_NR + 4) 91662f2482SMichael Shych 92662f2482SMichael Shych #define NVSW_SN2201_CPLD_NR NVSW_SN2201_MAIN_MUX_CH0_NR 93662f2482SMichael Shych #define NVSW_SN2201_NR_NONE -1 94662f2482SMichael Shych 95662f2482SMichael Shych /* Masks for aggregation, PSU presence and power, ASIC events 96662f2482SMichael Shych * in CPLD related registers. 97662f2482SMichael Shych */ 98662f2482SMichael Shych #define NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF 0xe0 99662f2482SMichael Shych #define NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF 0x04 100662f2482SMichael Shych #define NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF 0x02 101662f2482SMichael Shych #define NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF 0x10 102662f2482SMichael Shych #define NVSW_SN2201_CPLD_AGGR_MASK_DEF \ 103662f2482SMichael Shych (NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF \ 104662f2482SMichael Shych | NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF \ 105662f2482SMichael Shych | NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF \ 106662f2482SMichael Shych | NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF) 107662f2482SMichael Shych 108662f2482SMichael Shych #define NVSW_SN2201_CPLD_ASIC_MASK GENMASK(3, 1) 109662f2482SMichael Shych #define NVSW_SN2201_CPLD_PSU_MASK GENMASK(1, 0) 110662f2482SMichael Shych #define NVSW_SN2201_CPLD_PWR_MASK GENMASK(1, 0) 111662f2482SMichael Shych #define NVSW_SN2201_CPLD_FAN_MASK GENMASK(3, 0) 112662f2482SMichael Shych 113662f2482SMichael Shych #define NVSW_SN2201_CPLD_SYSIRQ 26 114662f2482SMichael Shych #define NVSW_SN2201_LPC_SYSIRQ 28 115662f2482SMichael Shych #define NVSW_SN2201_CPLD_I2CADDR 0x41 116662f2482SMichael Shych 117662f2482SMichael Shych #define NVSW_SN2201_WD_DFLT_TIMEOUT 600 118662f2482SMichael Shych 119662f2482SMichael Shych /* nvsw_sn2201 - device private data 120662f2482SMichael Shych * @dev: platform device; 121662f2482SMichael Shych * @io_data: register access platform data; 122662f2482SMichael Shych * @led_data: LED platform data; 123662f2482SMichael Shych * @hotplug_data: hotplug platform data; 124662f2482SMichael Shych * @i2c_data: I2C controller platform data; 125662f2482SMichael Shych * @led: LED device; 126662f2482SMichael Shych * @io_regs: register access device; 127662f2482SMichael Shych * @pdev_hotplug: hotplug device; 128662f2482SMichael Shych * @sn2201_devs: I2C devices for sn2201 devices; 129662f2482SMichael Shych * @sn2201_devs_num: number of I2C devices for sn2201 device; 130662f2482SMichael Shych * @main_mux_devs: I2C devices for main mux; 131662f2482SMichael Shych * @main_mux_devs_num: number of I2C devices for main mux; 132662f2482SMichael Shych * @cpld_devs: I2C devices for cpld; 133662f2482SMichael Shych * @cpld_devs_num: number of I2C devices for cpld; 134662f2482SMichael Shych * @main_mux_deferred_nr: I2C adapter number must be exist prior creating devices execution; 135662f2482SMichael Shych */ 136662f2482SMichael Shych struct nvsw_sn2201 { 137662f2482SMichael Shych struct device *dev; 138662f2482SMichael Shych struct mlxreg_core_platform_data *io_data; 139662f2482SMichael Shych struct mlxreg_core_platform_data *led_data; 140662f2482SMichael Shych struct mlxreg_core_platform_data *wd_data; 141662f2482SMichael Shych struct mlxreg_core_hotplug_platform_data *hotplug_data; 142662f2482SMichael Shych struct mlxreg_core_hotplug_platform_data *i2c_data; 143662f2482SMichael Shych struct platform_device *led; 144662f2482SMichael Shych struct platform_device *wd; 145662f2482SMichael Shych struct platform_device *io_regs; 146662f2482SMichael Shych struct platform_device *pdev_hotplug; 147662f2482SMichael Shych struct platform_device *pdev_i2c; 148662f2482SMichael Shych struct mlxreg_hotplug_device *sn2201_devs; 149662f2482SMichael Shych int sn2201_devs_num; 150662f2482SMichael Shych struct mlxreg_hotplug_device *main_mux_devs; 151662f2482SMichael Shych int main_mux_devs_num; 152662f2482SMichael Shych struct mlxreg_hotplug_device *cpld_devs; 153662f2482SMichael Shych int cpld_devs_num; 154662f2482SMichael Shych int main_mux_deferred_nr; 155662f2482SMichael Shych }; 156662f2482SMichael Shych 157662f2482SMichael Shych static bool nvsw_sn2201_writeable_reg(struct device *dev, unsigned int reg) 158662f2482SMichael Shych { 159662f2482SMichael Shych switch (reg) { 160662f2482SMichael Shych case NVSW_SN2201_PSU_CTRL_OFFSET: 161662f2482SMichael Shych case NVSW_SN2201_QSFP28_LP_STATUS_OFFSET: 162662f2482SMichael Shych case NVSW_SN2201_QSFP28_RST_STATUS_OFFSET: 163662f2482SMichael Shych case NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET: 164662f2482SMichael Shych case NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET: 165662f2482SMichael Shych case NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET: 166662f2482SMichael Shych case NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET: 167662f2482SMichael Shych case NVSW_SN2201_SYS_RST_STATUS_OFFSET: 168662f2482SMichael Shych case NVSW_SN2201_SYS_INT_MASK_OFFSET: 169662f2482SMichael Shych case NVSW_SN2201_ASIC_EVENT_OFFSET: 170662f2482SMichael Shych case NVSW_SN2201_ASIC_MAKS_OFFSET: 171662f2482SMichael Shych case NVSW_SN2201_THML_EVENT_OFFSET: 172662f2482SMichael Shych case NVSW_SN2201_THML_MASK_OFFSET: 173662f2482SMichael Shych case NVSW_SN2201_PS_ALT_EVENT_OFFSET: 174662f2482SMichael Shych case NVSW_SN2201_PS_ALT_MASK_OFFSET: 175662f2482SMichael Shych case NVSW_SN2201_PS_PRSNT_EVENT_OFFSET: 176662f2482SMichael Shych case NVSW_SN2201_PS_PRSNT_MASK_OFFSET: 177662f2482SMichael Shych case NVSW_SN2201_PS_DC_OK_EVENT_OFFSET: 178662f2482SMichael Shych case NVSW_SN2201_PS_DC_OK_MASK_OFFSET: 179662f2482SMichael Shych case NVSW_SN2201_RST_SW_CTRL_OFFSET: 180662f2482SMichael Shych case NVSW_SN2201_FAN_PRSNT_EVENT_OFFSET: 181662f2482SMichael Shych case NVSW_SN2201_FAN_PRSNT_MASK_OFFSET: 182662f2482SMichael Shych case NVSW_SN2201_WD_TMR_OFFSET_LSB: 183662f2482SMichael Shych case NVSW_SN2201_WD_TMR_OFFSET_MSB: 184662f2482SMichael Shych case NVSW_SN2201_WD_ACT_OFFSET: 185662f2482SMichael Shych case NVSW_SN2201_FAN_LED1_CTRL_OFFSET: 186662f2482SMichael Shych case NVSW_SN2201_FAN_LED2_CTRL_OFFSET: 187662f2482SMichael Shych return true; 188662f2482SMichael Shych } 189662f2482SMichael Shych return false; 190662f2482SMichael Shych } 191662f2482SMichael Shych 192662f2482SMichael Shych static bool nvsw_sn2201_readable_reg(struct device *dev, unsigned int reg) 193662f2482SMichael Shych { 194662f2482SMichael Shych switch (reg) { 195662f2482SMichael Shych case NVSW_SN2201_HW_VER_ID_OFFSET: 196662f2482SMichael Shych case NVSW_SN2201_BOARD_ID_OFFSET: 197662f2482SMichael Shych case NVSW_SN2201_CPLD_VER_OFFSET: 198662f2482SMichael Shych case NVSW_SN2201_CPLD_MVER_OFFSET: 199662f2482SMichael Shych case NVSW_SN2201_CPLD_ID_OFFSET: 200662f2482SMichael Shych case NVSW_SN2201_CPLD_PN_OFFSET: 201662f2482SMichael Shych case NVSW_SN2201_CPLD_PN1_OFFSET: 202662f2482SMichael Shych case NVSW_SN2201_PSU_CTRL_OFFSET: 203662f2482SMichael Shych case NVSW_SN2201_QSFP28_STATUS_OFFSET: 204662f2482SMichael Shych case NVSW_SN2201_QSFP28_INT_STATUS_OFFSET: 205662f2482SMichael Shych case NVSW_SN2201_QSFP28_LP_STATUS_OFFSET: 206662f2482SMichael Shych case NVSW_SN2201_QSFP28_RST_STATUS_OFFSET: 207662f2482SMichael Shych case NVSW_SN2201_SYS_STATUS_OFFSET: 208662f2482SMichael Shych case NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET: 209662f2482SMichael Shych case NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET: 210662f2482SMichael Shych case NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET: 211662f2482SMichael Shych case NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET: 212662f2482SMichael Shych case NVSW_SN2201_SYS_RST_STATUS_OFFSET: 213662f2482SMichael Shych case NVSW_SN2201_RST_CAUSE1_OFFSET: 214662f2482SMichael Shych case NVSW_SN2201_RST_CAUSE2_OFFSET: 215662f2482SMichael Shych case NVSW_SN2201_SYS_INT_STATUS_OFFSET: 216662f2482SMichael Shych case NVSW_SN2201_SYS_INT_MASK_OFFSET: 217662f2482SMichael Shych case NVSW_SN2201_ASIC_STATUS_OFFSET: 218662f2482SMichael Shych case NVSW_SN2201_ASIC_EVENT_OFFSET: 219662f2482SMichael Shych case NVSW_SN2201_ASIC_MAKS_OFFSET: 220662f2482SMichael Shych case NVSW_SN2201_THML_STATUS_OFFSET: 221662f2482SMichael Shych case NVSW_SN2201_THML_EVENT_OFFSET: 222662f2482SMichael Shych case NVSW_SN2201_THML_MASK_OFFSET: 223662f2482SMichael Shych case NVSW_SN2201_PS_ALT_STATUS_OFFSET: 224662f2482SMichael Shych case NVSW_SN2201_PS_ALT_EVENT_OFFSET: 225662f2482SMichael Shych case NVSW_SN2201_PS_ALT_MASK_OFFSET: 226662f2482SMichael Shych case NVSW_SN2201_PS_PRSNT_STATUS_OFFSET: 227662f2482SMichael Shych case NVSW_SN2201_PS_PRSNT_EVENT_OFFSET: 228662f2482SMichael Shych case NVSW_SN2201_PS_PRSNT_MASK_OFFSET: 229662f2482SMichael Shych case NVSW_SN2201_PS_DC_OK_STATUS_OFFSET: 230662f2482SMichael Shych case NVSW_SN2201_PS_DC_OK_EVENT_OFFSET: 231662f2482SMichael Shych case NVSW_SN2201_PS_DC_OK_MASK_OFFSET: 232662f2482SMichael Shych case NVSW_SN2201_RST_SW_CTRL_OFFSET: 233662f2482SMichael Shych case NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET: 234662f2482SMichael Shych case NVSW_SN2201_FAN_PRSNT_EVENT_OFFSET: 235662f2482SMichael Shych case NVSW_SN2201_FAN_PRSNT_MASK_OFFSET: 236662f2482SMichael Shych case NVSW_SN2201_WD_TMR_OFFSET_LSB: 237662f2482SMichael Shych case NVSW_SN2201_WD_TMR_OFFSET_MSB: 238662f2482SMichael Shych case NVSW_SN2201_WD_ACT_OFFSET: 239662f2482SMichael Shych case NVSW_SN2201_FAN_LED1_CTRL_OFFSET: 240662f2482SMichael Shych case NVSW_SN2201_FAN_LED2_CTRL_OFFSET: 241662f2482SMichael Shych return true; 242662f2482SMichael Shych } 243662f2482SMichael Shych return false; 244662f2482SMichael Shych } 245662f2482SMichael Shych 246662f2482SMichael Shych static bool nvsw_sn2201_volatile_reg(struct device *dev, unsigned int reg) 247662f2482SMichael Shych { 248662f2482SMichael Shych switch (reg) { 249662f2482SMichael Shych case NVSW_SN2201_HW_VER_ID_OFFSET: 250662f2482SMichael Shych case NVSW_SN2201_BOARD_ID_OFFSET: 251662f2482SMichael Shych case NVSW_SN2201_CPLD_VER_OFFSET: 252662f2482SMichael Shych case NVSW_SN2201_CPLD_MVER_OFFSET: 253662f2482SMichael Shych case NVSW_SN2201_CPLD_ID_OFFSET: 254662f2482SMichael Shych case NVSW_SN2201_CPLD_PN_OFFSET: 255662f2482SMichael Shych case NVSW_SN2201_CPLD_PN1_OFFSET: 256662f2482SMichael Shych case NVSW_SN2201_PSU_CTRL_OFFSET: 257662f2482SMichael Shych case NVSW_SN2201_QSFP28_STATUS_OFFSET: 258662f2482SMichael Shych case NVSW_SN2201_QSFP28_INT_STATUS_OFFSET: 259662f2482SMichael Shych case NVSW_SN2201_QSFP28_LP_STATUS_OFFSET: 260662f2482SMichael Shych case NVSW_SN2201_QSFP28_RST_STATUS_OFFSET: 261662f2482SMichael Shych case NVSW_SN2201_SYS_STATUS_OFFSET: 262662f2482SMichael Shych case NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET: 263662f2482SMichael Shych case NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET: 264662f2482SMichael Shych case NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET: 265662f2482SMichael Shych case NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET: 266662f2482SMichael Shych case NVSW_SN2201_SYS_RST_STATUS_OFFSET: 267662f2482SMichael Shych case NVSW_SN2201_RST_CAUSE1_OFFSET: 268662f2482SMichael Shych case NVSW_SN2201_RST_CAUSE2_OFFSET: 269662f2482SMichael Shych case NVSW_SN2201_SYS_INT_STATUS_OFFSET: 270662f2482SMichael Shych case NVSW_SN2201_SYS_INT_MASK_OFFSET: 271662f2482SMichael Shych case NVSW_SN2201_ASIC_STATUS_OFFSET: 272662f2482SMichael Shych case NVSW_SN2201_ASIC_EVENT_OFFSET: 273662f2482SMichael Shych case NVSW_SN2201_ASIC_MAKS_OFFSET: 274662f2482SMichael Shych case NVSW_SN2201_THML_STATUS_OFFSET: 275662f2482SMichael Shych case NVSW_SN2201_THML_EVENT_OFFSET: 276662f2482SMichael Shych case NVSW_SN2201_THML_MASK_OFFSET: 277662f2482SMichael Shych case NVSW_SN2201_PS_ALT_STATUS_OFFSET: 278662f2482SMichael Shych case NVSW_SN2201_PS_ALT_EVENT_OFFSET: 279662f2482SMichael Shych case NVSW_SN2201_PS_ALT_MASK_OFFSET: 280662f2482SMichael Shych case NVSW_SN2201_PS_PRSNT_STATUS_OFFSET: 281662f2482SMichael Shych case NVSW_SN2201_PS_PRSNT_EVENT_OFFSET: 282662f2482SMichael Shych case NVSW_SN2201_PS_PRSNT_MASK_OFFSET: 283662f2482SMichael Shych case NVSW_SN2201_PS_DC_OK_STATUS_OFFSET: 284662f2482SMichael Shych case NVSW_SN2201_PS_DC_OK_EVENT_OFFSET: 285662f2482SMichael Shych case NVSW_SN2201_PS_DC_OK_MASK_OFFSET: 286662f2482SMichael Shych case NVSW_SN2201_RST_SW_CTRL_OFFSET: 287662f2482SMichael Shych case NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET: 288662f2482SMichael Shych case NVSW_SN2201_FAN_PRSNT_EVENT_OFFSET: 289662f2482SMichael Shych case NVSW_SN2201_FAN_PRSNT_MASK_OFFSET: 290662f2482SMichael Shych case NVSW_SN2201_WD_TMR_OFFSET_LSB: 291662f2482SMichael Shych case NVSW_SN2201_WD_TMR_OFFSET_MSB: 292662f2482SMichael Shych case NVSW_SN2201_FAN_LED1_CTRL_OFFSET: 293662f2482SMichael Shych case NVSW_SN2201_FAN_LED2_CTRL_OFFSET: 294662f2482SMichael Shych return true; 295662f2482SMichael Shych } 296662f2482SMichael Shych return false; 297662f2482SMichael Shych } 298662f2482SMichael Shych 299662f2482SMichael Shych static const struct reg_default nvsw_sn2201_regmap_default[] = { 300662f2482SMichael Shych { NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET, 0x00 }, 301662f2482SMichael Shych { NVSW_SN2201_WD_ACT_OFFSET, 0x00 }, 302662f2482SMichael Shych }; 303662f2482SMichael Shych 304662f2482SMichael Shych /* Configuration for the register map of a device with 1 bytes address space. */ 305662f2482SMichael Shych static const struct regmap_config nvsw_sn2201_regmap_conf = { 306662f2482SMichael Shych .reg_bits = 8, 307662f2482SMichael Shych .val_bits = 8, 308662f2482SMichael Shych .max_register = NVSW_SN2201_REG_MAX, 309662f2482SMichael Shych .cache_type = REGCACHE_FLAT, 310662f2482SMichael Shych .writeable_reg = nvsw_sn2201_writeable_reg, 311662f2482SMichael Shych .readable_reg = nvsw_sn2201_readable_reg, 312662f2482SMichael Shych .volatile_reg = nvsw_sn2201_volatile_reg, 313662f2482SMichael Shych .reg_defaults = nvsw_sn2201_regmap_default, 314662f2482SMichael Shych .num_reg_defaults = ARRAY_SIZE(nvsw_sn2201_regmap_default), 315662f2482SMichael Shych }; 316662f2482SMichael Shych 317662f2482SMichael Shych /* Regions for LPC I2C controller and LPC base register space. */ 318662f2482SMichael Shych static const struct resource nvsw_sn2201_lpc_io_resources[] = { 319662f2482SMichael Shych [0] = DEFINE_RES_NAMED(NVSW_SN2201_CPLD_LPC_I2C_BASE_ADRR, 320662f2482SMichael Shych NVSW_SN2201_CPLD_LPC_IO_RANGE, 321662f2482SMichael Shych "mlxplat_cpld_lpc_i2c_ctrl", IORESOURCE_IO), 322662f2482SMichael Shych }; 323662f2482SMichael Shych 324662f2482SMichael Shych static struct resource nvsw_sn2201_cpld_res[] = { 325662f2482SMichael Shych [0] = DEFINE_RES_IRQ_NAMED(NVSW_SN2201_CPLD_SYSIRQ, "mlxreg-hotplug"), 326662f2482SMichael Shych }; 327662f2482SMichael Shych 328662f2482SMichael Shych static struct resource nvsw_sn2201_lpc_res[] = { 329662f2482SMichael Shych [0] = DEFINE_RES_IRQ_NAMED(NVSW_SN2201_LPC_SYSIRQ, "i2c-mlxcpld"), 330662f2482SMichael Shych }; 331662f2482SMichael Shych 332662f2482SMichael Shych /* SN2201 I2C platform data. */ 333b9c29f39SMichael Shych static struct mlxreg_core_hotplug_platform_data nvsw_sn2201_i2c_data = { 334662f2482SMichael Shych .irq = NVSW_SN2201_CPLD_SYSIRQ, 335662f2482SMichael Shych }; 336662f2482SMichael Shych 337662f2482SMichael Shych /* SN2201 CPLD device. */ 338662f2482SMichael Shych static struct i2c_board_info nvsw_sn2201_cpld_devices[] = { 339662f2482SMichael Shych { 340662f2482SMichael Shych I2C_BOARD_INFO("nvsw-sn2201", 0x41), 341662f2482SMichael Shych }, 342662f2482SMichael Shych }; 343662f2482SMichael Shych 344662f2482SMichael Shych /* SN2201 CPLD board info. */ 345662f2482SMichael Shych static struct mlxreg_hotplug_device nvsw_sn2201_cpld_brdinfo[] = { 346662f2482SMichael Shych { 347662f2482SMichael Shych .brdinfo = &nvsw_sn2201_cpld_devices[0], 348662f2482SMichael Shych .nr = NVSW_SN2201_CPLD_NR, 349662f2482SMichael Shych }, 350662f2482SMichael Shych }; 351662f2482SMichael Shych 352662f2482SMichael Shych /* SN2201 main mux device. */ 353662f2482SMichael Shych static struct i2c_board_info nvsw_sn2201_main_mux_devices[] = { 354662f2482SMichael Shych { 355662f2482SMichael Shych I2C_BOARD_INFO("pca9548", 0x70), 356662f2482SMichael Shych }, 357662f2482SMichael Shych }; 358662f2482SMichael Shych 359662f2482SMichael Shych /* SN2201 main mux board info. */ 360662f2482SMichael Shych static struct mlxreg_hotplug_device nvsw_sn2201_main_mux_brdinfo[] = { 361662f2482SMichael Shych { 362662f2482SMichael Shych .brdinfo = &nvsw_sn2201_main_mux_devices[0], 363662f2482SMichael Shych .nr = NVSW_SN2201_MAIN_MUX_NR, 364662f2482SMichael Shych }, 365662f2482SMichael Shych }; 366662f2482SMichael Shych 367662f2482SMichael Shych /* SN2201 power devices. */ 368662f2482SMichael Shych static struct i2c_board_info nvsw_sn2201_pwr_devices[] = { 369662f2482SMichael Shych { 370662f2482SMichael Shych I2C_BOARD_INFO("pmbus", 0x58), 371662f2482SMichael Shych }, 372662f2482SMichael Shych { 373662f2482SMichael Shych I2C_BOARD_INFO("pmbus", 0x58), 374662f2482SMichael Shych }, 375662f2482SMichael Shych }; 376662f2482SMichael Shych 377662f2482SMichael Shych /* SN2201 fan devices. */ 378662f2482SMichael Shych static struct i2c_board_info nvsw_sn2201_fan_devices[] = { 379662f2482SMichael Shych { 380662f2482SMichael Shych I2C_BOARD_INFO("24c02", 0x50), 381662f2482SMichael Shych }, 382662f2482SMichael Shych { 383662f2482SMichael Shych I2C_BOARD_INFO("24c02", 0x51), 384662f2482SMichael Shych }, 385662f2482SMichael Shych { 386662f2482SMichael Shych I2C_BOARD_INFO("24c02", 0x52), 387662f2482SMichael Shych }, 388662f2482SMichael Shych { 389662f2482SMichael Shych I2C_BOARD_INFO("24c02", 0x53), 390662f2482SMichael Shych }, 391662f2482SMichael Shych }; 392662f2482SMichael Shych 393662f2482SMichael Shych /* SN2201 hotplug default data. */ 394662f2482SMichael Shych static struct mlxreg_core_data nvsw_sn2201_psu_items_data[] = { 395662f2482SMichael Shych { 396662f2482SMichael Shych .label = "psu1", 397662f2482SMichael Shych .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET, 398662f2482SMichael Shych .mask = BIT(0), 399662f2482SMichael Shych .hpdev.nr = NVSW_SN2201_NR_NONE, 400662f2482SMichael Shych }, 401662f2482SMichael Shych { 402662f2482SMichael Shych .label = "psu2", 403662f2482SMichael Shych .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET, 404662f2482SMichael Shych .mask = BIT(1), 405662f2482SMichael Shych .hpdev.nr = NVSW_SN2201_NR_NONE, 406662f2482SMichael Shych }, 407662f2482SMichael Shych }; 408662f2482SMichael Shych 409662f2482SMichael Shych static struct mlxreg_core_data nvsw_sn2201_pwr_items_data[] = { 410662f2482SMichael Shych { 411662f2482SMichael Shych .label = "pwr1", 412662f2482SMichael Shych .reg = NVSW_SN2201_PS_DC_OK_STATUS_OFFSET, 413662f2482SMichael Shych .mask = BIT(0), 414662f2482SMichael Shych .hpdev.brdinfo = &nvsw_sn2201_pwr_devices[0], 415662f2482SMichael Shych .hpdev.nr = NVSW_SN2201_MAIN_MUX_CH1_NR, 416662f2482SMichael Shych }, 417662f2482SMichael Shych { 418662f2482SMichael Shych .label = "pwr2", 419662f2482SMichael Shych .reg = NVSW_SN2201_PS_DC_OK_STATUS_OFFSET, 420662f2482SMichael Shych .mask = BIT(1), 421662f2482SMichael Shych .hpdev.brdinfo = &nvsw_sn2201_pwr_devices[1], 422662f2482SMichael Shych .hpdev.nr = NVSW_SN2201_MAIN_MUX_CH2_NR, 423662f2482SMichael Shych }, 424662f2482SMichael Shych }; 425662f2482SMichael Shych 426662f2482SMichael Shych static struct mlxreg_core_data nvsw_sn2201_fan_items_data[] = { 427662f2482SMichael Shych { 428662f2482SMichael Shych .label = "fan1", 429662f2482SMichael Shych .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, 430662f2482SMichael Shych .mask = BIT(0), 431662f2482SMichael Shych .hpdev.brdinfo = &nvsw_sn2201_fan_devices[0], 432*e2aabb7cSMichael Shych .hpdev.nr = NVSW_SN2201_2ND_MUX_CH0_NR, 433662f2482SMichael Shych }, 434662f2482SMichael Shych { 435662f2482SMichael Shych .label = "fan2", 436662f2482SMichael Shych .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, 437662f2482SMichael Shych .mask = BIT(1), 438662f2482SMichael Shych .hpdev.brdinfo = &nvsw_sn2201_fan_devices[1], 439*e2aabb7cSMichael Shych .hpdev.nr = NVSW_SN2201_2ND_MUX_CH1_NR, 440662f2482SMichael Shych }, 441662f2482SMichael Shych { 442662f2482SMichael Shych .label = "fan3", 443662f2482SMichael Shych .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, 444662f2482SMichael Shych .mask = BIT(2), 445662f2482SMichael Shych .hpdev.brdinfo = &nvsw_sn2201_fan_devices[2], 446*e2aabb7cSMichael Shych .hpdev.nr = NVSW_SN2201_2ND_MUX_CH2_NR, 447662f2482SMichael Shych }, 448662f2482SMichael Shych { 449662f2482SMichael Shych .label = "fan4", 450662f2482SMichael Shych .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, 451662f2482SMichael Shych .mask = BIT(3), 452662f2482SMichael Shych .hpdev.brdinfo = &nvsw_sn2201_fan_devices[3], 453*e2aabb7cSMichael Shych .hpdev.nr = NVSW_SN2201_2ND_MUX_CH3_NR, 454662f2482SMichael Shych }, 455662f2482SMichael Shych }; 456662f2482SMichael Shych 457662f2482SMichael Shych static struct mlxreg_core_data nvsw_sn2201_sys_items_data[] = { 458662f2482SMichael Shych { 459662f2482SMichael Shych .label = "nic_smb_alert", 460662f2482SMichael Shych .reg = NVSW_SN2201_ASIC_STATUS_OFFSET, 461662f2482SMichael Shych .mask = BIT(1), 462662f2482SMichael Shych .hpdev.nr = NVSW_SN2201_NR_NONE, 463662f2482SMichael Shych }, 464662f2482SMichael Shych { 465662f2482SMichael Shych .label = "cpu_sd", 466662f2482SMichael Shych .reg = NVSW_SN2201_ASIC_STATUS_OFFSET, 467662f2482SMichael Shych .mask = BIT(2), 468662f2482SMichael Shych .hpdev.nr = NVSW_SN2201_NR_NONE, 469662f2482SMichael Shych }, 470662f2482SMichael Shych { 471662f2482SMichael Shych .label = "mac_health", 472662f2482SMichael Shych .reg = NVSW_SN2201_ASIC_STATUS_OFFSET, 473662f2482SMichael Shych .mask = BIT(3), 474662f2482SMichael Shych .hpdev.nr = NVSW_SN2201_NR_NONE, 475662f2482SMichael Shych }, 476662f2482SMichael Shych }; 477662f2482SMichael Shych 478662f2482SMichael Shych static struct mlxreg_core_item nvsw_sn2201_items[] = { 479662f2482SMichael Shych { 480662f2482SMichael Shych .data = nvsw_sn2201_psu_items_data, 481662f2482SMichael Shych .aggr_mask = NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF, 482662f2482SMichael Shych .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET, 483662f2482SMichael Shych .mask = NVSW_SN2201_CPLD_PSU_MASK, 484662f2482SMichael Shych .count = ARRAY_SIZE(nvsw_sn2201_psu_items_data), 485662f2482SMichael Shych .inversed = 1, 486662f2482SMichael Shych .health = false, 487662f2482SMichael Shych }, 488662f2482SMichael Shych { 489662f2482SMichael Shych .data = nvsw_sn2201_pwr_items_data, 490662f2482SMichael Shych .aggr_mask = NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF, 491662f2482SMichael Shych .reg = NVSW_SN2201_PS_DC_OK_STATUS_OFFSET, 492662f2482SMichael Shych .mask = NVSW_SN2201_CPLD_PWR_MASK, 493662f2482SMichael Shych .count = ARRAY_SIZE(nvsw_sn2201_pwr_items_data), 494662f2482SMichael Shych .inversed = 0, 495662f2482SMichael Shych .health = false, 496662f2482SMichael Shych }, 497662f2482SMichael Shych { 498662f2482SMichael Shych .data = nvsw_sn2201_fan_items_data, 499662f2482SMichael Shych .aggr_mask = NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF, 500662f2482SMichael Shych .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, 501662f2482SMichael Shych .mask = NVSW_SN2201_CPLD_FAN_MASK, 502662f2482SMichael Shych .count = ARRAY_SIZE(nvsw_sn2201_fan_items_data), 503662f2482SMichael Shych .inversed = 1, 504662f2482SMichael Shych .health = false, 505662f2482SMichael Shych }, 506662f2482SMichael Shych { 507662f2482SMichael Shych .data = nvsw_sn2201_sys_items_data, 508662f2482SMichael Shych .aggr_mask = NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF, 509662f2482SMichael Shych .reg = NVSW_SN2201_ASIC_STATUS_OFFSET, 510662f2482SMichael Shych .mask = NVSW_SN2201_CPLD_ASIC_MASK, 511662f2482SMichael Shych .count = ARRAY_SIZE(nvsw_sn2201_sys_items_data), 512662f2482SMichael Shych .inversed = 1, 513662f2482SMichael Shych .health = false, 514662f2482SMichael Shych }, 515662f2482SMichael Shych }; 516662f2482SMichael Shych 517662f2482SMichael Shych static 518662f2482SMichael Shych struct mlxreg_core_hotplug_platform_data nvsw_sn2201_hotplug = { 519662f2482SMichael Shych .items = nvsw_sn2201_items, 520662f2482SMichael Shych .counter = ARRAY_SIZE(nvsw_sn2201_items), 521662f2482SMichael Shych .cell = NVSW_SN2201_SYS_INT_STATUS_OFFSET, 522662f2482SMichael Shych .mask = NVSW_SN2201_CPLD_AGGR_MASK_DEF, 523662f2482SMichael Shych }; 524662f2482SMichael Shych 525662f2482SMichael Shych /* SN2201 static devices. */ 526662f2482SMichael Shych static struct i2c_board_info nvsw_sn2201_static_devices[] = { 527662f2482SMichael Shych { 528662f2482SMichael Shych I2C_BOARD_INFO("24c02", 0x57), 529662f2482SMichael Shych }, 530662f2482SMichael Shych { 531662f2482SMichael Shych I2C_BOARD_INFO("lm75", 0x4b), 532662f2482SMichael Shych }, 533662f2482SMichael Shych { 534662f2482SMichael Shych I2C_BOARD_INFO("24c64", 0x56), 535662f2482SMichael Shych }, 536662f2482SMichael Shych { 537662f2482SMichael Shych I2C_BOARD_INFO("ads1015", 0x49), 538662f2482SMichael Shych }, 539662f2482SMichael Shych { 540662f2482SMichael Shych I2C_BOARD_INFO("pca9546", 0x71), 541662f2482SMichael Shych }, 542662f2482SMichael Shych { 543662f2482SMichael Shych I2C_BOARD_INFO("emc2305", 0x4d), 544662f2482SMichael Shych }, 545662f2482SMichael Shych { 546662f2482SMichael Shych I2C_BOARD_INFO("lm75", 0x49), 547662f2482SMichael Shych }, 548662f2482SMichael Shych { 549662f2482SMichael Shych I2C_BOARD_INFO("pca9555", 0x27), 550662f2482SMichael Shych }, 551662f2482SMichael Shych { 552662f2482SMichael Shych I2C_BOARD_INFO("powr1014", 0x37), 553662f2482SMichael Shych }, 554662f2482SMichael Shych { 555662f2482SMichael Shych I2C_BOARD_INFO("lm75", 0x4f), 556662f2482SMichael Shych }, 557662f2482SMichael Shych { 558662f2482SMichael Shych I2C_BOARD_INFO("pmbus", 0x40), 559662f2482SMichael Shych }, 560662f2482SMichael Shych }; 561662f2482SMichael Shych 562662f2482SMichael Shych /* SN2201 default static board info. */ 563662f2482SMichael Shych static struct mlxreg_hotplug_device nvsw_sn2201_static_brdinfo[] = { 564662f2482SMichael Shych { 565662f2482SMichael Shych .brdinfo = &nvsw_sn2201_static_devices[0], 566662f2482SMichael Shych .nr = NVSW_SN2201_MAIN_NR, 567662f2482SMichael Shych }, 568662f2482SMichael Shych { 569662f2482SMichael Shych .brdinfo = &nvsw_sn2201_static_devices[1], 570662f2482SMichael Shych .nr = NVSW_SN2201_MAIN_MUX_CH0_NR, 571662f2482SMichael Shych }, 572662f2482SMichael Shych { 573662f2482SMichael Shych .brdinfo = &nvsw_sn2201_static_devices[2], 574662f2482SMichael Shych .nr = NVSW_SN2201_MAIN_MUX_CH0_NR, 575662f2482SMichael Shych }, 576662f2482SMichael Shych { 577662f2482SMichael Shych .brdinfo = &nvsw_sn2201_static_devices[3], 578662f2482SMichael Shych .nr = NVSW_SN2201_MAIN_MUX_CH0_NR, 579662f2482SMichael Shych }, 580662f2482SMichael Shych { 581662f2482SMichael Shych .brdinfo = &nvsw_sn2201_static_devices[4], 582662f2482SMichael Shych .nr = NVSW_SN2201_MAIN_MUX_CH3_NR, 583662f2482SMichael Shych }, 584662f2482SMichael Shych { 585662f2482SMichael Shych .brdinfo = &nvsw_sn2201_static_devices[5], 586662f2482SMichael Shych .nr = NVSW_SN2201_MAIN_MUX_CH5_NR, 587662f2482SMichael Shych }, 588662f2482SMichael Shych { 589662f2482SMichael Shych .brdinfo = &nvsw_sn2201_static_devices[6], 590662f2482SMichael Shych .nr = NVSW_SN2201_MAIN_MUX_CH5_NR, 591662f2482SMichael Shych }, 592662f2482SMichael Shych { 593662f2482SMichael Shych .brdinfo = &nvsw_sn2201_static_devices[7], 594662f2482SMichael Shych .nr = NVSW_SN2201_MAIN_MUX_CH5_NR, 595662f2482SMichael Shych }, 596662f2482SMichael Shych { 597662f2482SMichael Shych .brdinfo = &nvsw_sn2201_static_devices[8], 598662f2482SMichael Shych .nr = NVSW_SN2201_MAIN_MUX_CH6_NR, 599662f2482SMichael Shych }, 600662f2482SMichael Shych { 601662f2482SMichael Shych .brdinfo = &nvsw_sn2201_static_devices[9], 602662f2482SMichael Shych .nr = NVSW_SN2201_MAIN_MUX_CH6_NR, 603662f2482SMichael Shych }, 604662f2482SMichael Shych { 605662f2482SMichael Shych .brdinfo = &nvsw_sn2201_static_devices[10], 606662f2482SMichael Shych .nr = NVSW_SN2201_MAIN_MUX_CH7_NR, 607662f2482SMichael Shych }, 608662f2482SMichael Shych }; 609662f2482SMichael Shych 610662f2482SMichael Shych /* LED default data. */ 611662f2482SMichael Shych static struct mlxreg_core_data nvsw_sn2201_led_data[] = { 612662f2482SMichael Shych { 613662f2482SMichael Shych .label = "status:green", 614662f2482SMichael Shych .reg = NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET, 615662f2482SMichael Shych .mask = GENMASK(7, 4), 616662f2482SMichael Shych }, 617662f2482SMichael Shych { 618662f2482SMichael Shych .label = "status:orange", 619662f2482SMichael Shych .reg = NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET, 620662f2482SMichael Shych .mask = GENMASK(7, 4), 621662f2482SMichael Shych }, 622662f2482SMichael Shych { 623662f2482SMichael Shych .label = "psu:green", 624662f2482SMichael Shych .reg = NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET, 625662f2482SMichael Shych .mask = GENMASK(7, 4), 626662f2482SMichael Shych }, 627662f2482SMichael Shych { 628662f2482SMichael Shych .label = "psu:orange", 629662f2482SMichael Shych .reg = NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET, 630662f2482SMichael Shych .mask = GENMASK(7, 4), 631662f2482SMichael Shych }, 632662f2482SMichael Shych { 633662f2482SMichael Shych .label = "uid:blue", 634662f2482SMichael Shych .reg = NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET, 635662f2482SMichael Shych .mask = GENMASK(7, 4), 636662f2482SMichael Shych }, 637662f2482SMichael Shych { 638662f2482SMichael Shych .label = "fan1:green", 639662f2482SMichael Shych .reg = NVSW_SN2201_FAN_LED1_CTRL_OFFSET, 640662f2482SMichael Shych .mask = GENMASK(7, 4), 641662f2482SMichael Shych }, 642662f2482SMichael Shych { 643662f2482SMichael Shych .label = "fan1:orange", 644662f2482SMichael Shych .reg = NVSW_SN2201_FAN_LED1_CTRL_OFFSET, 645662f2482SMichael Shych .mask = GENMASK(7, 4), 646662f2482SMichael Shych }, 647662f2482SMichael Shych { 648662f2482SMichael Shych .label = "fan2:green", 649662f2482SMichael Shych .reg = NVSW_SN2201_FAN_LED1_CTRL_OFFSET, 650662f2482SMichael Shych .mask = GENMASK(3, 0), 651662f2482SMichael Shych }, 652662f2482SMichael Shych { 653662f2482SMichael Shych .label = "fan2:orange", 654662f2482SMichael Shych .reg = NVSW_SN2201_FAN_LED1_CTRL_OFFSET, 655662f2482SMichael Shych .mask = GENMASK(3, 0), 656662f2482SMichael Shych }, 657662f2482SMichael Shych { 658662f2482SMichael Shych .label = "fan3:green", 659662f2482SMichael Shych .reg = NVSW_SN2201_FAN_LED2_CTRL_OFFSET, 660662f2482SMichael Shych .mask = GENMASK(7, 4), 661662f2482SMichael Shych }, 662662f2482SMichael Shych { 663662f2482SMichael Shych .label = "fan3:orange", 664662f2482SMichael Shych .reg = NVSW_SN2201_FAN_LED2_CTRL_OFFSET, 665662f2482SMichael Shych .mask = GENMASK(7, 4), 666662f2482SMichael Shych }, 667662f2482SMichael Shych { 668662f2482SMichael Shych .label = "fan4:green", 669662f2482SMichael Shych .reg = NVSW_SN2201_FAN_LED2_CTRL_OFFSET, 670662f2482SMichael Shych .mask = GENMASK(3, 0), 671662f2482SMichael Shych }, 672662f2482SMichael Shych { 673662f2482SMichael Shych .label = "fan4:orange", 674662f2482SMichael Shych .reg = NVSW_SN2201_FAN_LED2_CTRL_OFFSET, 675662f2482SMichael Shych .mask = GENMASK(3, 0), 676662f2482SMichael Shych }, 677662f2482SMichael Shych }; 678662f2482SMichael Shych 679662f2482SMichael Shych static struct mlxreg_core_platform_data nvsw_sn2201_led = { 680662f2482SMichael Shych .data = nvsw_sn2201_led_data, 681662f2482SMichael Shych .counter = ARRAY_SIZE(nvsw_sn2201_led_data), 682662f2482SMichael Shych }; 683662f2482SMichael Shych 684662f2482SMichael Shych /* Default register access data. */ 685662f2482SMichael Shych static struct mlxreg_core_data nvsw_sn2201_io_data[] = { 686662f2482SMichael Shych { 687662f2482SMichael Shych .label = "cpld1_version", 688662f2482SMichael Shych .reg = NVSW_SN2201_CPLD_VER_OFFSET, 689662f2482SMichael Shych .bit = GENMASK(7, 0), 690662f2482SMichael Shych .mode = 0444, 691662f2482SMichael Shych }, 692662f2482SMichael Shych { 693662f2482SMichael Shych .label = "cpld1_version_min", 694662f2482SMichael Shych .reg = NVSW_SN2201_CPLD_MVER_OFFSET, 695662f2482SMichael Shych .bit = GENMASK(7, 0), 696662f2482SMichael Shych .mode = 0444, 697662f2482SMichael Shych }, 698662f2482SMichael Shych { 699662f2482SMichael Shych .label = "cpld1_pn", 700662f2482SMichael Shych .reg = NVSW_SN2201_CPLD_PN_OFFSET, 701662f2482SMichael Shych .bit = GENMASK(15, 0), 702662f2482SMichael Shych .mode = 0444, 703662f2482SMichael Shych .regnum = 2, 704662f2482SMichael Shych }, 705662f2482SMichael Shych { 706662f2482SMichael Shych .label = "psu1_on", 707662f2482SMichael Shych .reg = NVSW_SN2201_PSU_CTRL_OFFSET, 708662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(0), 709662f2482SMichael Shych .mode = 0644, 710662f2482SMichael Shych }, 711662f2482SMichael Shych { 712662f2482SMichael Shych .label = "psu2_on", 713662f2482SMichael Shych .reg = NVSW_SN2201_PSU_CTRL_OFFSET, 714662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(1), 715662f2482SMichael Shych .mode = 0644, 716662f2482SMichael Shych }, 717662f2482SMichael Shych { 718662f2482SMichael Shych .label = "pwr_cycle", 719662f2482SMichael Shych .reg = NVSW_SN2201_PSU_CTRL_OFFSET, 720662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(2), 721662f2482SMichael Shych .mode = 0644, 722662f2482SMichael Shych }, 723662f2482SMichael Shych { 724662f2482SMichael Shych .label = "asic_health", 725662f2482SMichael Shych .reg = NVSW_SN2201_SYS_STATUS_OFFSET, 726662f2482SMichael Shych .mask = GENMASK(4, 3), 727662f2482SMichael Shych .bit = 4, 728662f2482SMichael Shych .mode = 0444, 729662f2482SMichael Shych }, 730662f2482SMichael Shych { 731662f2482SMichael Shych .label = "qsfp_pwr_good", 732662f2482SMichael Shych .reg = NVSW_SN2201_SYS_STATUS_OFFSET, 733662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(0), 734662f2482SMichael Shych .mode = 0444, 735662f2482SMichael Shych }, 736662f2482SMichael Shych { 737662f2482SMichael Shych .label = "phy_reset", 738662f2482SMichael Shych .reg = NVSW_SN2201_SYS_RST_STATUS_OFFSET, 739662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(3), 740662f2482SMichael Shych .mode = 0644, 741662f2482SMichael Shych }, 742662f2482SMichael Shych { 743662f2482SMichael Shych .label = "mac_reset", 744662f2482SMichael Shych .reg = NVSW_SN2201_SYS_RST_STATUS_OFFSET, 745662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(2), 746662f2482SMichael Shych .mode = 0644, 747662f2482SMichael Shych }, 748662f2482SMichael Shych { 749662f2482SMichael Shych .label = "pwr_down", 750662f2482SMichael Shych .reg = NVSW_SN2201_RST_SW_CTRL_OFFSET, 751662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(0), 752662f2482SMichael Shych .mode = 0644, 753662f2482SMichael Shych }, 754662f2482SMichael Shych { 755662f2482SMichael Shych .label = "reset_long_pb", 756662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 757662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(0), 758662f2482SMichael Shych .mode = 0444, 759662f2482SMichael Shych }, 760662f2482SMichael Shych { 761662f2482SMichael Shych .label = "reset_short_pb", 762662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 763662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(1), 764662f2482SMichael Shych .mode = 0444, 765662f2482SMichael Shych }, 766662f2482SMichael Shych { 767662f2482SMichael Shych .label = "reset_aux_pwr_or_fu", 768662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 769662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(2), 770662f2482SMichael Shych .mode = 0444, 771662f2482SMichael Shych }, 772662f2482SMichael Shych { 773662f2482SMichael Shych .label = "reset_swb_dc_dc_pwr_fail", 774662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 775662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(3), 776662f2482SMichael Shych .mode = 0444, 777662f2482SMichael Shych }, 778662f2482SMichael Shych { 779662f2482SMichael Shych .label = "reset_sw_reset", 780662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 781662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(4), 782662f2482SMichael Shych .mode = 0444, 783662f2482SMichael Shych }, 784662f2482SMichael Shych { 785662f2482SMichael Shych .label = "reset_fw_reset", 786662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 787662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(5), 788662f2482SMichael Shych .mode = 0444, 789662f2482SMichael Shych }, 790662f2482SMichael Shych { 791662f2482SMichael Shych .label = "reset_swb_wd", 792662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 793662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(6), 794662f2482SMichael Shych .mode = 0444, 795662f2482SMichael Shych }, 796662f2482SMichael Shych { 797662f2482SMichael Shych .label = "reset_asic_thermal", 798662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 799662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(7), 800662f2482SMichael Shych .mode = 0444, 801662f2482SMichael Shych }, 802662f2482SMichael Shych { 803662f2482SMichael Shych .label = "reset_system", 804662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE2_OFFSET, 805662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(1), 806662f2482SMichael Shych .mode = 0444, 807662f2482SMichael Shych }, 808662f2482SMichael Shych { 809662f2482SMichael Shych .label = "reset_sw_pwr_off", 810662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE2_OFFSET, 811662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(2), 812662f2482SMichael Shych .mode = 0444, 813662f2482SMichael Shych }, 814662f2482SMichael Shych { 815662f2482SMichael Shych .label = "reset_cpu_pwr_fail_thermal", 816662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE2_OFFSET, 817662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(4), 818662f2482SMichael Shych .mode = 0444, 819662f2482SMichael Shych }, 820662f2482SMichael Shych { 821662f2482SMichael Shych .label = "reset_reload_bios", 822662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE2_OFFSET, 823662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(5), 824662f2482SMichael Shych .mode = 0444, 825662f2482SMichael Shych }, 826662f2482SMichael Shych { 827662f2482SMichael Shych .label = "reset_ac_pwr_fail", 828662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE2_OFFSET, 829662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(6), 830662f2482SMichael Shych .mode = 0444, 831662f2482SMichael Shych }, 832662f2482SMichael Shych { 833662f2482SMichael Shych .label = "psu1", 834662f2482SMichael Shych .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET, 835662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(0), 836662f2482SMichael Shych .mode = 0444, 837662f2482SMichael Shych }, 838662f2482SMichael Shych { 839662f2482SMichael Shych .label = "psu2", 840662f2482SMichael Shych .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET, 841662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(1), 842662f2482SMichael Shych .mode = 0444, 843662f2482SMichael Shych }, 844662f2482SMichael Shych }; 845662f2482SMichael Shych 846662f2482SMichael Shych static struct mlxreg_core_platform_data nvsw_sn2201_regs_io = { 847662f2482SMichael Shych .data = nvsw_sn2201_io_data, 848662f2482SMichael Shych .counter = ARRAY_SIZE(nvsw_sn2201_io_data), 849662f2482SMichael Shych }; 850662f2482SMichael Shych 851662f2482SMichael Shych /* Default watchdog data. */ 852662f2482SMichael Shych static struct mlxreg_core_data nvsw_sn2201_wd_data[] = { 853662f2482SMichael Shych { 854662f2482SMichael Shych .label = "action", 855662f2482SMichael Shych .reg = NVSW_SN2201_WD_ACT_OFFSET, 856662f2482SMichael Shych .mask = GENMASK(7, 1), 857662f2482SMichael Shych .bit = 0, 858662f2482SMichael Shych }, 859662f2482SMichael Shych { 860662f2482SMichael Shych .label = "timeout", 861662f2482SMichael Shych .reg = NVSW_SN2201_WD_TMR_OFFSET_LSB, 862662f2482SMichael Shych .mask = 0, 863662f2482SMichael Shych .health_cntr = NVSW_SN2201_WD_DFLT_TIMEOUT, 864662f2482SMichael Shych }, 865662f2482SMichael Shych { 866662f2482SMichael Shych .label = "timeleft", 867662f2482SMichael Shych .reg = NVSW_SN2201_WD_TMR_OFFSET_LSB, 868662f2482SMichael Shych .mask = 0, 869662f2482SMichael Shych }, 870662f2482SMichael Shych { 871662f2482SMichael Shych .label = "ping", 872662f2482SMichael Shych .reg = NVSW_SN2201_WD_ACT_OFFSET, 873662f2482SMichael Shych .mask = GENMASK(7, 1), 874662f2482SMichael Shych .bit = 0, 875662f2482SMichael Shych }, 876662f2482SMichael Shych { 877662f2482SMichael Shych .label = "reset", 878662f2482SMichael Shych .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 879662f2482SMichael Shych .mask = GENMASK(7, 0) & ~BIT(6), 880662f2482SMichael Shych .bit = 6, 881662f2482SMichael Shych }, 882662f2482SMichael Shych }; 883662f2482SMichael Shych 884662f2482SMichael Shych static struct mlxreg_core_platform_data nvsw_sn2201_wd = { 885662f2482SMichael Shych .data = nvsw_sn2201_wd_data, 886662f2482SMichael Shych .counter = ARRAY_SIZE(nvsw_sn2201_wd_data), 887662f2482SMichael Shych .version = MLX_WDT_TYPE3, 888662f2482SMichael Shych .identity = "mlx-wdt-main", 889662f2482SMichael Shych }; 890662f2482SMichael Shych 891662f2482SMichael Shych static int 892662f2482SMichael Shych nvsw_sn2201_create_static_devices(struct nvsw_sn2201 *nvsw_sn2201, 893662f2482SMichael Shych struct mlxreg_hotplug_device *devs, 894662f2482SMichael Shych int size) 895662f2482SMichael Shych { 896662f2482SMichael Shych struct mlxreg_hotplug_device *dev = devs; 89779e90ca0SDan Carpenter int ret; 898662f2482SMichael Shych int i; 899662f2482SMichael Shych 900662f2482SMichael Shych /* Create I2C static devices. */ 901662f2482SMichael Shych for (i = 0; i < size; i++, dev++) { 902662f2482SMichael Shych dev->client = i2c_new_client_device(dev->adapter, dev->brdinfo); 903662f2482SMichael Shych if (IS_ERR(dev->client)) { 904662f2482SMichael Shych dev_err(nvsw_sn2201->dev, "Failed to create client %s at bus %d at addr 0x%02x\n", 905662f2482SMichael Shych dev->brdinfo->type, 906662f2482SMichael Shych dev->nr, dev->brdinfo->addr); 907662f2482SMichael Shych 908662f2482SMichael Shych dev->adapter = NULL; 90979e90ca0SDan Carpenter ret = PTR_ERR(dev->client); 910662f2482SMichael Shych goto fail_create_static_devices; 911662f2482SMichael Shych } 912662f2482SMichael Shych } 913662f2482SMichael Shych 914662f2482SMichael Shych return 0; 915662f2482SMichael Shych 916662f2482SMichael Shych fail_create_static_devices: 917662f2482SMichael Shych while (--i >= 0) { 918662f2482SMichael Shych dev = devs + i; 919662f2482SMichael Shych i2c_unregister_device(dev->client); 920662f2482SMichael Shych dev->client = NULL; 921662f2482SMichael Shych dev->adapter = NULL; 922662f2482SMichael Shych } 92379e90ca0SDan Carpenter return ret; 924662f2482SMichael Shych } 925662f2482SMichael Shych 926662f2482SMichael Shych static void nvsw_sn2201_destroy_static_devices(struct nvsw_sn2201 *nvsw_sn2201, 927662f2482SMichael Shych struct mlxreg_hotplug_device *devs, int size) 928662f2482SMichael Shych { 929662f2482SMichael Shych struct mlxreg_hotplug_device *dev = devs; 930662f2482SMichael Shych int i; 931662f2482SMichael Shych 932662f2482SMichael Shych /* Destroy static I2C device for SN2201 static devices. */ 933662f2482SMichael Shych for (i = 0; i < size; i++, dev++) { 934662f2482SMichael Shych if (dev->client) { 935662f2482SMichael Shych i2c_unregister_device(dev->client); 936662f2482SMichael Shych dev->client = NULL; 937662f2482SMichael Shych i2c_put_adapter(dev->adapter); 938662f2482SMichael Shych dev->adapter = NULL; 939662f2482SMichael Shych } 940662f2482SMichael Shych } 941662f2482SMichael Shych } 942662f2482SMichael Shych 943662f2482SMichael Shych static int nvsw_sn2201_config_post_init(struct nvsw_sn2201 *nvsw_sn2201) 944662f2482SMichael Shych { 945662f2482SMichael Shych struct mlxreg_hotplug_device *sn2201_dev; 946662f2482SMichael Shych struct i2c_adapter *adap; 947662f2482SMichael Shych struct device *dev; 948662f2482SMichael Shych int i, err; 949662f2482SMichael Shych 950662f2482SMichael Shych dev = nvsw_sn2201->dev; 951662f2482SMichael Shych adap = i2c_get_adapter(nvsw_sn2201->main_mux_deferred_nr); 952662f2482SMichael Shych if (!adap) { 953662f2482SMichael Shych dev_err(dev, "Failed to get adapter for bus %d\n", 954662f2482SMichael Shych nvsw_sn2201->main_mux_deferred_nr); 955662f2482SMichael Shych return -ENODEV; 956662f2482SMichael Shych } 957662f2482SMichael Shych i2c_put_adapter(adap); 958662f2482SMichael Shych 959662f2482SMichael Shych /* Update board info. */ 960662f2482SMichael Shych sn2201_dev = nvsw_sn2201->sn2201_devs; 961662f2482SMichael Shych for (i = 0; i < nvsw_sn2201->sn2201_devs_num; i++, sn2201_dev++) { 962662f2482SMichael Shych sn2201_dev->adapter = i2c_get_adapter(sn2201_dev->nr); 963662f2482SMichael Shych if (!sn2201_dev->adapter) 964662f2482SMichael Shych return -ENODEV; 965662f2482SMichael Shych i2c_put_adapter(sn2201_dev->adapter); 966662f2482SMichael Shych } 967662f2482SMichael Shych 968662f2482SMichael Shych err = nvsw_sn2201_create_static_devices(nvsw_sn2201, nvsw_sn2201->sn2201_devs, 969662f2482SMichael Shych nvsw_sn2201->sn2201_devs_num); 970662f2482SMichael Shych if (err) 971662f2482SMichael Shych dev_err(dev, "Failed to create static devices\n"); 972662f2482SMichael Shych 973662f2482SMichael Shych return err; 974662f2482SMichael Shych } 975662f2482SMichael Shych 976662f2482SMichael Shych static int nvsw_sn2201_config_init(struct nvsw_sn2201 *nvsw_sn2201, void *regmap) 977662f2482SMichael Shych { 978662f2482SMichael Shych struct device *dev = nvsw_sn2201->dev; 979662f2482SMichael Shych int err; 980662f2482SMichael Shych 981662f2482SMichael Shych nvsw_sn2201->io_data = &nvsw_sn2201_regs_io; 982662f2482SMichael Shych nvsw_sn2201->led_data = &nvsw_sn2201_led; 983662f2482SMichael Shych nvsw_sn2201->wd_data = &nvsw_sn2201_wd; 984662f2482SMichael Shych nvsw_sn2201->hotplug_data = &nvsw_sn2201_hotplug; 985662f2482SMichael Shych 986662f2482SMichael Shych /* Register IO access driver. */ 987662f2482SMichael Shych if (nvsw_sn2201->io_data) { 988662f2482SMichael Shych nvsw_sn2201->io_data->regmap = regmap; 989662f2482SMichael Shych nvsw_sn2201->io_regs = 990662f2482SMichael Shych platform_device_register_resndata(dev, "mlxreg-io", PLATFORM_DEVID_NONE, NULL, 0, 991662f2482SMichael Shych nvsw_sn2201->io_data, 992662f2482SMichael Shych sizeof(*nvsw_sn2201->io_data)); 993662f2482SMichael Shych if (IS_ERR(nvsw_sn2201->io_regs)) { 994662f2482SMichael Shych err = PTR_ERR(nvsw_sn2201->io_regs); 995662f2482SMichael Shych goto fail_register_io; 996662f2482SMichael Shych } 997662f2482SMichael Shych } 998662f2482SMichael Shych 999662f2482SMichael Shych /* Register LED driver. */ 1000662f2482SMichael Shych if (nvsw_sn2201->led_data) { 1001662f2482SMichael Shych nvsw_sn2201->led_data->regmap = regmap; 1002662f2482SMichael Shych nvsw_sn2201->led = 1003662f2482SMichael Shych platform_device_register_resndata(dev, "leds-mlxreg", PLATFORM_DEVID_NONE, NULL, 0, 1004662f2482SMichael Shych nvsw_sn2201->led_data, 1005662f2482SMichael Shych sizeof(*nvsw_sn2201->led_data)); 1006662f2482SMichael Shych if (IS_ERR(nvsw_sn2201->led)) { 1007662f2482SMichael Shych err = PTR_ERR(nvsw_sn2201->led); 1008662f2482SMichael Shych goto fail_register_led; 1009662f2482SMichael Shych } 1010662f2482SMichael Shych } 1011662f2482SMichael Shych 1012662f2482SMichael Shych /* Register WD driver. */ 1013662f2482SMichael Shych if (nvsw_sn2201->wd_data) { 1014662f2482SMichael Shych nvsw_sn2201->wd_data->regmap = regmap; 1015662f2482SMichael Shych nvsw_sn2201->wd = 1016662f2482SMichael Shych platform_device_register_resndata(dev, "mlx-wdt", PLATFORM_DEVID_NONE, NULL, 0, 1017662f2482SMichael Shych nvsw_sn2201->wd_data, 1018662f2482SMichael Shych sizeof(*nvsw_sn2201->wd_data)); 1019662f2482SMichael Shych if (IS_ERR(nvsw_sn2201->wd)) { 1020662f2482SMichael Shych err = PTR_ERR(nvsw_sn2201->wd); 1021662f2482SMichael Shych goto fail_register_wd; 1022662f2482SMichael Shych } 1023662f2482SMichael Shych } 1024662f2482SMichael Shych 1025662f2482SMichael Shych /* Register hotplug driver. */ 1026662f2482SMichael Shych if (nvsw_sn2201->hotplug_data) { 1027662f2482SMichael Shych nvsw_sn2201->hotplug_data->regmap = regmap; 1028662f2482SMichael Shych nvsw_sn2201->pdev_hotplug = 1029662f2482SMichael Shych platform_device_register_resndata(dev, "mlxreg-hotplug", PLATFORM_DEVID_NONE, 1030662f2482SMichael Shych nvsw_sn2201_cpld_res, 1031662f2482SMichael Shych ARRAY_SIZE(nvsw_sn2201_cpld_res), 1032662f2482SMichael Shych nvsw_sn2201->hotplug_data, 1033662f2482SMichael Shych sizeof(*nvsw_sn2201->hotplug_data)); 1034662f2482SMichael Shych if (IS_ERR(nvsw_sn2201->pdev_hotplug)) { 1035662f2482SMichael Shych err = PTR_ERR(nvsw_sn2201->pdev_hotplug); 1036662f2482SMichael Shych goto fail_register_hotplug; 1037662f2482SMichael Shych } 1038662f2482SMichael Shych } 1039662f2482SMichael Shych 1040662f2482SMichael Shych return nvsw_sn2201_config_post_init(nvsw_sn2201); 1041662f2482SMichael Shych 1042662f2482SMichael Shych fail_register_hotplug: 1043662f2482SMichael Shych if (nvsw_sn2201->wd) 1044662f2482SMichael Shych platform_device_unregister(nvsw_sn2201->wd); 1045662f2482SMichael Shych fail_register_wd: 1046662f2482SMichael Shych if (nvsw_sn2201->led) 1047662f2482SMichael Shych platform_device_unregister(nvsw_sn2201->led); 1048662f2482SMichael Shych fail_register_led: 1049662f2482SMichael Shych if (nvsw_sn2201->io_regs) 1050662f2482SMichael Shych platform_device_unregister(nvsw_sn2201->io_regs); 1051662f2482SMichael Shych fail_register_io: 1052662f2482SMichael Shych 1053662f2482SMichael Shych return err; 1054662f2482SMichael Shych } 1055662f2482SMichael Shych 1056662f2482SMichael Shych static void nvsw_sn2201_config_exit(struct nvsw_sn2201 *nvsw_sn2201) 1057662f2482SMichael Shych { 1058662f2482SMichael Shych /* Unregister hotplug driver. */ 1059662f2482SMichael Shych if (nvsw_sn2201->pdev_hotplug) 1060662f2482SMichael Shych platform_device_unregister(nvsw_sn2201->pdev_hotplug); 1061662f2482SMichael Shych /* Unregister WD driver. */ 1062662f2482SMichael Shych if (nvsw_sn2201->wd) 1063662f2482SMichael Shych platform_device_unregister(nvsw_sn2201->wd); 1064662f2482SMichael Shych /* Unregister LED driver. */ 1065662f2482SMichael Shych if (nvsw_sn2201->led) 1066662f2482SMichael Shych platform_device_unregister(nvsw_sn2201->led); 1067662f2482SMichael Shych /* Unregister IO access driver. */ 1068662f2482SMichael Shych if (nvsw_sn2201->io_regs) 1069662f2482SMichael Shych platform_device_unregister(nvsw_sn2201->io_regs); 1070662f2482SMichael Shych } 1071662f2482SMichael Shych 1072662f2482SMichael Shych /* 1073662f2482SMichael Shych * Initialization is divided into two parts: 1074662f2482SMichael Shych * - I2C main bus init. 1075662f2482SMichael Shych * - Mux creation and attaching devices to the mux, 1076662f2482SMichael Shych * which assumes that the main bus is already created. 1077662f2482SMichael Shych * This separation is required for synchronization between these two parts. 1078662f2482SMichael Shych * Completion notify callback is used to make this flow synchronized. 1079662f2482SMichael Shych */ 1080662f2482SMichael Shych static int nvsw_sn2201_i2c_completion_notify(void *handle, int id) 1081662f2482SMichael Shych { 1082662f2482SMichael Shych struct nvsw_sn2201 *nvsw_sn2201 = handle; 1083662f2482SMichael Shych void *regmap; 1084662f2482SMichael Shych int i, err; 1085662f2482SMichael Shych 1086662f2482SMichael Shych /* Create main mux. */ 1087662f2482SMichael Shych nvsw_sn2201->main_mux_devs->adapter = i2c_get_adapter(nvsw_sn2201->main_mux_devs->nr); 1088662f2482SMichael Shych if (!nvsw_sn2201->main_mux_devs->adapter) { 1089662f2482SMichael Shych err = -ENODEV; 1090662f2482SMichael Shych dev_err(nvsw_sn2201->dev, "Failed to get adapter for bus %d\n", 1091662f2482SMichael Shych nvsw_sn2201->cpld_devs->nr); 1092662f2482SMichael Shych goto i2c_get_adapter_main_fail; 1093662f2482SMichael Shych } 1094662f2482SMichael Shych 1095662f2482SMichael Shych nvsw_sn2201->main_mux_devs_num = ARRAY_SIZE(nvsw_sn2201_main_mux_brdinfo); 1096662f2482SMichael Shych err = nvsw_sn2201_create_static_devices(nvsw_sn2201, nvsw_sn2201->main_mux_devs, 1097662f2482SMichael Shych nvsw_sn2201->main_mux_devs_num); 1098662f2482SMichael Shych if (err) { 1099662f2482SMichael Shych dev_err(nvsw_sn2201->dev, "Failed to create main mux devices\n"); 1100662f2482SMichael Shych goto nvsw_sn2201_create_static_devices_fail; 1101662f2482SMichael Shych } 1102662f2482SMichael Shych 1103662f2482SMichael Shych nvsw_sn2201->cpld_devs->adapter = i2c_get_adapter(nvsw_sn2201->cpld_devs->nr); 1104662f2482SMichael Shych if (!nvsw_sn2201->cpld_devs->adapter) { 1105662f2482SMichael Shych err = -ENODEV; 1106662f2482SMichael Shych dev_err(nvsw_sn2201->dev, "Failed to get adapter for bus %d\n", 1107662f2482SMichael Shych nvsw_sn2201->cpld_devs->nr); 1108662f2482SMichael Shych goto i2c_get_adapter_fail; 1109662f2482SMichael Shych } 1110662f2482SMichael Shych 1111662f2482SMichael Shych /* Create CPLD device. */ 1112662f2482SMichael Shych nvsw_sn2201->cpld_devs->client = i2c_new_dummy_device(nvsw_sn2201->cpld_devs->adapter, 1113662f2482SMichael Shych NVSW_SN2201_CPLD_I2CADDR); 1114662f2482SMichael Shych if (IS_ERR(nvsw_sn2201->cpld_devs->client)) { 1115662f2482SMichael Shych err = PTR_ERR(nvsw_sn2201->cpld_devs->client); 1116662f2482SMichael Shych dev_err(nvsw_sn2201->dev, "Failed to create %s cpld device at bus %d at addr 0x%02x\n", 1117662f2482SMichael Shych nvsw_sn2201->cpld_devs->brdinfo->type, nvsw_sn2201->cpld_devs->nr, 1118662f2482SMichael Shych nvsw_sn2201->cpld_devs->brdinfo->addr); 1119662f2482SMichael Shych goto i2c_new_dummy_fail; 1120662f2482SMichael Shych } 1121662f2482SMichael Shych 1122662f2482SMichael Shych regmap = devm_regmap_init_i2c(nvsw_sn2201->cpld_devs->client, &nvsw_sn2201_regmap_conf); 1123662f2482SMichael Shych if (IS_ERR(regmap)) { 1124662f2482SMichael Shych err = PTR_ERR(regmap); 1125662f2482SMichael Shych dev_err(nvsw_sn2201->dev, "Failed to initialise managed register map\n"); 1126662f2482SMichael Shych goto devm_regmap_init_i2c_fail; 1127662f2482SMichael Shych } 1128662f2482SMichael Shych 1129662f2482SMichael Shych /* Set default registers. */ 1130662f2482SMichael Shych for (i = 0; i < nvsw_sn2201_regmap_conf.num_reg_defaults; i++) { 1131662f2482SMichael Shych err = regmap_write(regmap, nvsw_sn2201_regmap_default[i].reg, 1132662f2482SMichael Shych nvsw_sn2201_regmap_default[i].def); 1133662f2482SMichael Shych if (err) { 1134662f2482SMichael Shych dev_err(nvsw_sn2201->dev, "Failed to set register at offset 0x%02x to default value: 0x%02x\n", 1135662f2482SMichael Shych nvsw_sn2201_regmap_default[i].reg, 1136662f2482SMichael Shych nvsw_sn2201_regmap_default[i].def); 1137662f2482SMichael Shych goto regmap_write_fail; 1138662f2482SMichael Shych } 1139662f2482SMichael Shych } 1140662f2482SMichael Shych 1141662f2482SMichael Shych /* Sync registers with hardware. */ 1142662f2482SMichael Shych regcache_mark_dirty(regmap); 1143662f2482SMichael Shych err = regcache_sync(regmap); 1144662f2482SMichael Shych if (err) { 1145662f2482SMichael Shych dev_err(nvsw_sn2201->dev, "Failed to Sync registers with hardware\n"); 1146662f2482SMichael Shych goto regcache_sync_fail; 1147662f2482SMichael Shych } 1148662f2482SMichael Shych 1149662f2482SMichael Shych /* Configure SN2201 board. */ 1150662f2482SMichael Shych err = nvsw_sn2201_config_init(nvsw_sn2201, regmap); 1151662f2482SMichael Shych if (err) { 1152662f2482SMichael Shych dev_err(nvsw_sn2201->dev, "Failed to configure board\n"); 1153662f2482SMichael Shych goto nvsw_sn2201_config_init_fail; 1154662f2482SMichael Shych } 1155662f2482SMichael Shych 1156662f2482SMichael Shych return 0; 1157662f2482SMichael Shych 1158662f2482SMichael Shych nvsw_sn2201_config_init_fail: 1159662f2482SMichael Shych nvsw_sn2201_config_exit(nvsw_sn2201); 1160662f2482SMichael Shych regcache_sync_fail: 1161662f2482SMichael Shych regmap_write_fail: 1162662f2482SMichael Shych devm_regmap_init_i2c_fail: 1163662f2482SMichael Shych i2c_new_dummy_fail: 1164662f2482SMichael Shych i2c_put_adapter(nvsw_sn2201->cpld_devs->adapter); 1165662f2482SMichael Shych nvsw_sn2201->cpld_devs->adapter = NULL; 1166662f2482SMichael Shych i2c_get_adapter_fail: 1167662f2482SMichael Shych /* Destroy SN2201 static I2C devices. */ 1168662f2482SMichael Shych nvsw_sn2201_destroy_static_devices(nvsw_sn2201, nvsw_sn2201->sn2201_devs, 1169662f2482SMichael Shych nvsw_sn2201->sn2201_devs_num); 1170662f2482SMichael Shych /* Destroy main mux device. */ 1171662f2482SMichael Shych nvsw_sn2201_destroy_static_devices(nvsw_sn2201, nvsw_sn2201->main_mux_devs, 1172662f2482SMichael Shych nvsw_sn2201->main_mux_devs_num); 1173662f2482SMichael Shych nvsw_sn2201_create_static_devices_fail: 1174662f2482SMichael Shych i2c_put_adapter(nvsw_sn2201->main_mux_devs->adapter); 1175662f2482SMichael Shych i2c_get_adapter_main_fail: 1176662f2482SMichael Shych return err; 1177662f2482SMichael Shych } 1178662f2482SMichael Shych 1179662f2482SMichael Shych static int nvsw_sn2201_config_pre_init(struct nvsw_sn2201 *nvsw_sn2201) 1180662f2482SMichael Shych { 1181662f2482SMichael Shych nvsw_sn2201->i2c_data = &nvsw_sn2201_i2c_data; 1182662f2482SMichael Shych 1183662f2482SMichael Shych /* Register I2C controller. */ 1184662f2482SMichael Shych nvsw_sn2201->i2c_data->handle = nvsw_sn2201; 1185662f2482SMichael Shych nvsw_sn2201->i2c_data->completion_notify = nvsw_sn2201_i2c_completion_notify; 1186662f2482SMichael Shych nvsw_sn2201->pdev_i2c = platform_device_register_resndata(nvsw_sn2201->dev, "i2c_mlxcpld", 1187662f2482SMichael Shych NVSW_SN2201_MAIN_MUX_NR, 1188662f2482SMichael Shych nvsw_sn2201_lpc_res, 1189662f2482SMichael Shych ARRAY_SIZE(nvsw_sn2201_lpc_res), 1190662f2482SMichael Shych nvsw_sn2201->i2c_data, 1191662f2482SMichael Shych sizeof(*nvsw_sn2201->i2c_data)); 1192662f2482SMichael Shych if (IS_ERR(nvsw_sn2201->pdev_i2c)) 1193662f2482SMichael Shych return PTR_ERR(nvsw_sn2201->pdev_i2c); 1194662f2482SMichael Shych 1195662f2482SMichael Shych return 0; 1196662f2482SMichael Shych } 1197662f2482SMichael Shych 1198662f2482SMichael Shych static int nvsw_sn2201_probe(struct platform_device *pdev) 1199662f2482SMichael Shych { 1200662f2482SMichael Shych struct nvsw_sn2201 *nvsw_sn2201; 1201662f2482SMichael Shych 1202662f2482SMichael Shych nvsw_sn2201 = devm_kzalloc(&pdev->dev, sizeof(*nvsw_sn2201), GFP_KERNEL); 1203662f2482SMichael Shych if (!nvsw_sn2201) 1204662f2482SMichael Shych return -ENOMEM; 1205662f2482SMichael Shych 1206662f2482SMichael Shych nvsw_sn2201->dev = &pdev->dev; 1207662f2482SMichael Shych platform_set_drvdata(pdev, nvsw_sn2201); 1208662f2482SMichael Shych platform_device_add_resources(pdev, nvsw_sn2201_lpc_io_resources, 1209662f2482SMichael Shych ARRAY_SIZE(nvsw_sn2201_lpc_io_resources)); 1210662f2482SMichael Shych 1211662f2482SMichael Shych nvsw_sn2201->main_mux_deferred_nr = NVSW_SN2201_MAIN_MUX_DEFER_NR; 1212662f2482SMichael Shych nvsw_sn2201->main_mux_devs = nvsw_sn2201_main_mux_brdinfo; 1213662f2482SMichael Shych nvsw_sn2201->cpld_devs = nvsw_sn2201_cpld_brdinfo; 1214662f2482SMichael Shych nvsw_sn2201->sn2201_devs = nvsw_sn2201_static_brdinfo; 1215662f2482SMichael Shych nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_static_brdinfo); 1216662f2482SMichael Shych 1217662f2482SMichael Shych return nvsw_sn2201_config_pre_init(nvsw_sn2201); 1218662f2482SMichael Shych } 1219662f2482SMichael Shych 1220662f2482SMichael Shych static int nvsw_sn2201_remove(struct platform_device *pdev) 1221662f2482SMichael Shych { 1222662f2482SMichael Shych struct nvsw_sn2201 *nvsw_sn2201 = platform_get_drvdata(pdev); 1223662f2482SMichael Shych 1224662f2482SMichael Shych /* Unregister underlying drivers. */ 1225662f2482SMichael Shych nvsw_sn2201_config_exit(nvsw_sn2201); 1226662f2482SMichael Shych 1227662f2482SMichael Shych /* Destroy SN2201 static I2C devices. */ 1228662f2482SMichael Shych nvsw_sn2201_destroy_static_devices(nvsw_sn2201, 1229662f2482SMichael Shych nvsw_sn2201->sn2201_devs, 1230662f2482SMichael Shych nvsw_sn2201->sn2201_devs_num); 1231662f2482SMichael Shych 1232662f2482SMichael Shych i2c_put_adapter(nvsw_sn2201->cpld_devs->adapter); 1233662f2482SMichael Shych nvsw_sn2201->cpld_devs->adapter = NULL; 1234662f2482SMichael Shych /* Destroy main mux device. */ 1235662f2482SMichael Shych nvsw_sn2201_destroy_static_devices(nvsw_sn2201, 1236662f2482SMichael Shych nvsw_sn2201->main_mux_devs, 1237662f2482SMichael Shych nvsw_sn2201->main_mux_devs_num); 1238662f2482SMichael Shych 1239662f2482SMichael Shych /* Unregister I2C controller. */ 1240662f2482SMichael Shych if (nvsw_sn2201->pdev_i2c) 1241662f2482SMichael Shych platform_device_unregister(nvsw_sn2201->pdev_i2c); 1242662f2482SMichael Shych 1243662f2482SMichael Shych return 0; 1244662f2482SMichael Shych } 1245662f2482SMichael Shych 1246662f2482SMichael Shych static const struct acpi_device_id nvsw_sn2201_acpi_ids[] = { 1247662f2482SMichael Shych {"NVSN2201", 0}, 1248662f2482SMichael Shych {} 1249662f2482SMichael Shych }; 1250662f2482SMichael Shych 1251662f2482SMichael Shych MODULE_DEVICE_TABLE(acpi, nvsw_sn2201_acpi_ids); 1252662f2482SMichael Shych 1253662f2482SMichael Shych static struct platform_driver nvsw_sn2201_driver = { 1254662f2482SMichael Shych .probe = nvsw_sn2201_probe, 1255662f2482SMichael Shych .remove = nvsw_sn2201_remove, 1256662f2482SMichael Shych .driver = { 1257662f2482SMichael Shych .name = "nvsw-sn2201", 1258662f2482SMichael Shych .acpi_match_table = nvsw_sn2201_acpi_ids, 1259662f2482SMichael Shych }, 1260662f2482SMichael Shych }; 1261662f2482SMichael Shych 1262662f2482SMichael Shych module_platform_driver(nvsw_sn2201_driver); 1263662f2482SMichael Shych 1264662f2482SMichael Shych MODULE_AUTHOR("Nvidia"); 1265662f2482SMichael Shych MODULE_DESCRIPTION("Nvidia sn2201 platform driver"); 1266662f2482SMichael Shych MODULE_LICENSE("Dual BSD/GPL"); 1267662f2482SMichael Shych MODULE_ALIAS("platform:nvsw-sn2201"); 1268