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