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