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