xref: /openbmc/linux/drivers/platform/mellanox/nvsw-sn2201.c (revision 79e90ca02d7d45898c52fd8523cd4a2a304e409c)
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