1a0aab9e1SSrinivas Kandagatla // SPDX-License-Identifier: GPL-2.0
2a0aab9e1SSrinivas Kandagatla // Copyright (c) 2015-2017, The Linux Foundation.
3a0aab9e1SSrinivas Kandagatla // Copyright (c) 2019, Linaro Limited
4a0aab9e1SSrinivas Kandagatla
5a0aab9e1SSrinivas Kandagatla #include <linux/bitops.h>
6a0aab9e1SSrinivas Kandagatla #include <linux/gpio.h>
7a0aab9e1SSrinivas Kandagatla #include <linux/gpio/consumer.h>
8a0aab9e1SSrinivas Kandagatla #include <linux/module.h>
9a0aab9e1SSrinivas Kandagatla #include <linux/regmap.h>
10a0aab9e1SSrinivas Kandagatla #include <linux/slab.h>
118dd55245SSrinivas Kandagatla #include <linux/pm_runtime.h>
12a0aab9e1SSrinivas Kandagatla #include <linux/soundwire/sdw.h>
13a0aab9e1SSrinivas Kandagatla #include <linux/soundwire/sdw_registers.h>
14a0aab9e1SSrinivas Kandagatla #include <linux/soundwire/sdw_type.h>
15a0aab9e1SSrinivas Kandagatla #include <sound/soc.h>
16a0aab9e1SSrinivas Kandagatla #include <sound/tlv.h>
17a0aab9e1SSrinivas Kandagatla
18a0aab9e1SSrinivas Kandagatla #define WSA881X_DIGITAL_BASE 0x3000
19a0aab9e1SSrinivas Kandagatla #define WSA881X_ANALOG_BASE 0x3100
20a0aab9e1SSrinivas Kandagatla
21a0aab9e1SSrinivas Kandagatla /* Digital register address space */
22a0aab9e1SSrinivas Kandagatla #define WSA881X_CHIP_ID0 (WSA881X_DIGITAL_BASE + 0x0000)
23a0aab9e1SSrinivas Kandagatla #define WSA881X_CHIP_ID1 (WSA881X_DIGITAL_BASE + 0x0001)
24a0aab9e1SSrinivas Kandagatla #define WSA881X_CHIP_ID2 (WSA881X_DIGITAL_BASE + 0x0002)
25a0aab9e1SSrinivas Kandagatla #define WSA881X_CHIP_ID3 (WSA881X_DIGITAL_BASE + 0x0003)
26a0aab9e1SSrinivas Kandagatla #define WSA881X_BUS_ID (WSA881X_DIGITAL_BASE + 0x0004)
27a0aab9e1SSrinivas Kandagatla #define WSA881X_CDC_RST_CTL (WSA881X_DIGITAL_BASE + 0x0005)
28a0aab9e1SSrinivas Kandagatla #define WSA881X_CDC_TOP_CLK_CTL (WSA881X_DIGITAL_BASE + 0x0006)
29a0aab9e1SSrinivas Kandagatla #define WSA881X_CDC_ANA_CLK_CTL (WSA881X_DIGITAL_BASE + 0x0007)
30a0aab9e1SSrinivas Kandagatla #define WSA881X_CDC_DIG_CLK_CTL (WSA881X_DIGITAL_BASE + 0x0008)
31a0aab9e1SSrinivas Kandagatla #define WSA881X_CLOCK_CONFIG (WSA881X_DIGITAL_BASE + 0x0009)
32a0aab9e1SSrinivas Kandagatla #define WSA881X_ANA_CTL (WSA881X_DIGITAL_BASE + 0x000A)
33a0aab9e1SSrinivas Kandagatla #define WSA881X_SWR_RESET_EN (WSA881X_DIGITAL_BASE + 0x000B)
34a0aab9e1SSrinivas Kandagatla #define WSA881X_RESET_CTL (WSA881X_DIGITAL_BASE + 0x000C)
35a0aab9e1SSrinivas Kandagatla #define WSA881X_TADC_VALUE_CTL (WSA881X_DIGITAL_BASE + 0x000F)
36a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_DETECT_CTL (WSA881X_DIGITAL_BASE + 0x0010)
37a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_MSB (WSA881X_DIGITAL_BASE + 0x0011)
38a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_LSB (WSA881X_DIGITAL_BASE + 0x0012)
39a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_CONFIG0 (WSA881X_DIGITAL_BASE + 0x0013)
40a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_CONFIG1 (WSA881X_DIGITAL_BASE + 0x0014)
41a0aab9e1SSrinivas Kandagatla #define WSA881X_CDC_CLIP_CTL (WSA881X_DIGITAL_BASE + 0x0015)
42a0aab9e1SSrinivas Kandagatla #define WSA881X_SDM_PDM9_LSB (WSA881X_DIGITAL_BASE + 0x0016)
43a0aab9e1SSrinivas Kandagatla #define WSA881X_SDM_PDM9_MSB (WSA881X_DIGITAL_BASE + 0x0017)
44a0aab9e1SSrinivas Kandagatla #define WSA881X_CDC_RX_CTL (WSA881X_DIGITAL_BASE + 0x0018)
45a0aab9e1SSrinivas Kandagatla #define WSA881X_DEM_BYPASS_DATA0 (WSA881X_DIGITAL_BASE + 0x0019)
46a0aab9e1SSrinivas Kandagatla #define WSA881X_DEM_BYPASS_DATA1 (WSA881X_DIGITAL_BASE + 0x001A)
47a0aab9e1SSrinivas Kandagatla #define WSA881X_DEM_BYPASS_DATA2 (WSA881X_DIGITAL_BASE + 0x001B)
48a0aab9e1SSrinivas Kandagatla #define WSA881X_DEM_BYPASS_DATA3 (WSA881X_DIGITAL_BASE + 0x001C)
49a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_CTRL0 (WSA881X_DIGITAL_BASE + 0x001D)
50a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_CTRL1 (WSA881X_DIGITAL_BASE + 0x001E)
51a0aab9e1SSrinivas Kandagatla #define WSA881X_HDRIVE_CTL_GROUP1 (WSA881X_DIGITAL_BASE + 0x001F)
52a0aab9e1SSrinivas Kandagatla #define WSA881X_INTR_MODE (WSA881X_DIGITAL_BASE + 0x0020)
53a0aab9e1SSrinivas Kandagatla #define WSA881X_INTR_MASK (WSA881X_DIGITAL_BASE + 0x0021)
54a0aab9e1SSrinivas Kandagatla #define WSA881X_INTR_STATUS (WSA881X_DIGITAL_BASE + 0x0022)
55a0aab9e1SSrinivas Kandagatla #define WSA881X_INTR_CLEAR (WSA881X_DIGITAL_BASE + 0x0023)
56a0aab9e1SSrinivas Kandagatla #define WSA881X_INTR_LEVEL (WSA881X_DIGITAL_BASE + 0x0024)
57a0aab9e1SSrinivas Kandagatla #define WSA881X_INTR_SET (WSA881X_DIGITAL_BASE + 0x0025)
58a0aab9e1SSrinivas Kandagatla #define WSA881X_INTR_TEST (WSA881X_DIGITAL_BASE + 0x0026)
59a0aab9e1SSrinivas Kandagatla #define WSA881X_PDM_TEST_MODE (WSA881X_DIGITAL_BASE + 0x0030)
60a0aab9e1SSrinivas Kandagatla #define WSA881X_ATE_TEST_MODE (WSA881X_DIGITAL_BASE + 0x0031)
61a0aab9e1SSrinivas Kandagatla #define WSA881X_PIN_CTL_MODE (WSA881X_DIGITAL_BASE + 0x0032)
62a0aab9e1SSrinivas Kandagatla #define WSA881X_PIN_CTL_OE (WSA881X_DIGITAL_BASE + 0x0033)
63a0aab9e1SSrinivas Kandagatla #define WSA881X_PIN_WDATA_IOPAD (WSA881X_DIGITAL_BASE + 0x0034)
64a0aab9e1SSrinivas Kandagatla #define WSA881X_PIN_STATUS (WSA881X_DIGITAL_BASE + 0x0035)
65a0aab9e1SSrinivas Kandagatla #define WSA881X_DIG_DEBUG_MODE (WSA881X_DIGITAL_BASE + 0x0037)
66a0aab9e1SSrinivas Kandagatla #define WSA881X_DIG_DEBUG_SEL (WSA881X_DIGITAL_BASE + 0x0038)
67a0aab9e1SSrinivas Kandagatla #define WSA881X_DIG_DEBUG_EN (WSA881X_DIGITAL_BASE + 0x0039)
68a0aab9e1SSrinivas Kandagatla #define WSA881X_SWR_HM_TEST1 (WSA881X_DIGITAL_BASE + 0x003B)
69a0aab9e1SSrinivas Kandagatla #define WSA881X_SWR_HM_TEST2 (WSA881X_DIGITAL_BASE + 0x003C)
70a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_DETECT_DBG_CTL (WSA881X_DIGITAL_BASE + 0x003D)
71a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_DEBUG_MSB (WSA881X_DIGITAL_BASE + 0x003E)
72a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_DEBUG_LSB (WSA881X_DIGITAL_BASE + 0x003F)
73a0aab9e1SSrinivas Kandagatla #define WSA881X_SAMPLE_EDGE_SEL (WSA881X_DIGITAL_BASE + 0x0044)
74a0aab9e1SSrinivas Kandagatla #define WSA881X_IOPAD_CTL (WSA881X_DIGITAL_BASE + 0x0045)
75a0aab9e1SSrinivas Kandagatla #define WSA881X_SPARE_0 (WSA881X_DIGITAL_BASE + 0x0050)
76a0aab9e1SSrinivas Kandagatla #define WSA881X_SPARE_1 (WSA881X_DIGITAL_BASE + 0x0051)
77a0aab9e1SSrinivas Kandagatla #define WSA881X_SPARE_2 (WSA881X_DIGITAL_BASE + 0x0052)
78a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_0 (WSA881X_DIGITAL_BASE + 0x0080)
79a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_1 (WSA881X_DIGITAL_BASE + 0x0081)
80a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_2 (WSA881X_DIGITAL_BASE + 0x0082)
81a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_3 (WSA881X_DIGITAL_BASE + 0x0083)
82a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_4 (WSA881X_DIGITAL_BASE + 0x0084)
83a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_5 (WSA881X_DIGITAL_BASE + 0x0085)
84a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_6 (WSA881X_DIGITAL_BASE + 0x0086)
85a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_7 (WSA881X_DIGITAL_BASE + 0x0087)
86a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_8 (WSA881X_DIGITAL_BASE + 0x0088)
87a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_9 (WSA881X_DIGITAL_BASE + 0x0089)
88a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_10 (WSA881X_DIGITAL_BASE + 0x008A)
89a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_11 (WSA881X_DIGITAL_BASE + 0x008B)
90a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_12 (WSA881X_DIGITAL_BASE + 0x008C)
91a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_13 (WSA881X_DIGITAL_BASE + 0x008D)
92a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_14 (WSA881X_DIGITAL_BASE + 0x008E)
93a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_15 (WSA881X_DIGITAL_BASE + 0x008F)
94a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_16 (WSA881X_DIGITAL_BASE + 0x0090)
95a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_17 (WSA881X_DIGITAL_BASE + 0x0091)
96a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_18 (WSA881X_DIGITAL_BASE + 0x0092)
97a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_19 (WSA881X_DIGITAL_BASE + 0x0093)
98a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_20 (WSA881X_DIGITAL_BASE + 0x0094)
99a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_21 (WSA881X_DIGITAL_BASE + 0x0095)
100a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_22 (WSA881X_DIGITAL_BASE + 0x0096)
101a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_23 (WSA881X_DIGITAL_BASE + 0x0097)
102a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_24 (WSA881X_DIGITAL_BASE + 0x0098)
103a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_25 (WSA881X_DIGITAL_BASE + 0x0099)
104a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_26 (WSA881X_DIGITAL_BASE + 0x009A)
105a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_27 (WSA881X_DIGITAL_BASE + 0x009B)
106a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_28 (WSA881X_DIGITAL_BASE + 0x009C)
107a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_29 (WSA881X_DIGITAL_BASE + 0x009D)
108a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_30 (WSA881X_DIGITAL_BASE + 0x009E)
109a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_31 (WSA881X_DIGITAL_BASE + 0x009F)
110a0aab9e1SSrinivas Kandagatla #define WSA881X_OTP_REG_63 (WSA881X_DIGITAL_BASE + 0x00BF)
111a0aab9e1SSrinivas Kandagatla
112a0aab9e1SSrinivas Kandagatla /* Analog Register address space */
113a0aab9e1SSrinivas Kandagatla #define WSA881X_BIAS_REF_CTRL (WSA881X_ANALOG_BASE + 0x0000)
114a0aab9e1SSrinivas Kandagatla #define WSA881X_BIAS_TEST (WSA881X_ANALOG_BASE + 0x0001)
115a0aab9e1SSrinivas Kandagatla #define WSA881X_BIAS_BIAS (WSA881X_ANALOG_BASE + 0x0002)
116a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_OP (WSA881X_ANALOG_BASE + 0x0003)
117a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_IREF_CTRL (WSA881X_ANALOG_BASE + 0x0004)
118a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_ISENS_CTRL (WSA881X_ANALOG_BASE + 0x0005)
119a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_CLK_CTRL (WSA881X_ANALOG_BASE + 0x0006)
120a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_TEST (WSA881X_ANALOG_BASE + 0x0007)
121a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_BIAS (WSA881X_ANALOG_BASE + 0x0008)
122a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_ADC_CTRL (WSA881X_ANALOG_BASE + 0x0009)
123a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_DOUT_MSB (WSA881X_ANALOG_BASE + 0x000A)
124a0aab9e1SSrinivas Kandagatla #define WSA881X_TEMP_DOUT_LSB (WSA881X_ANALOG_BASE + 0x000B)
125a0aab9e1SSrinivas Kandagatla #define WSA881X_ADC_EN_MODU_V (WSA881X_ANALOG_BASE + 0x0010)
126a0aab9e1SSrinivas Kandagatla #define WSA881X_ADC_EN_MODU_I (WSA881X_ANALOG_BASE + 0x0011)
127a0aab9e1SSrinivas Kandagatla #define WSA881X_ADC_EN_DET_TEST_V (WSA881X_ANALOG_BASE + 0x0012)
128a0aab9e1SSrinivas Kandagatla #define WSA881X_ADC_EN_DET_TEST_I (WSA881X_ANALOG_BASE + 0x0013)
129a0aab9e1SSrinivas Kandagatla #define WSA881X_ADC_SEL_IBIAS (WSA881X_ANALOG_BASE + 0x0014)
130a0aab9e1SSrinivas Kandagatla #define WSA881X_ADC_EN_SEL_IBAIS (WSA881X_ANALOG_BASE + 0x0015)
131a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_DRV_EN (WSA881X_ANALOG_BASE + 0x001A)
132a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_DRV_GAIN (WSA881X_ANALOG_BASE + 0x001B)
133a0aab9e1SSrinivas Kandagatla #define WSA881X_PA_GAIN_SEL_MASK BIT(3)
134a0aab9e1SSrinivas Kandagatla #define WSA881X_PA_GAIN_SEL_REG BIT(3)
135a0aab9e1SSrinivas Kandagatla #define WSA881X_PA_GAIN_SEL_DRE 0
136a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_PAG_GAIN_MASK GENMASK(7, 4)
137a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_DAC_CTL (WSA881X_ANALOG_BASE + 0x001C)
138a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_DRV_DBG (WSA881X_ANALOG_BASE + 0x001D)
139a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_PWRSTG_DBG (WSA881X_ANALOG_BASE + 0x001E)
140a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_OCP_CTL (WSA881X_ANALOG_BASE + 0x001F)
141a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_OCP_MASK GENMASK(7, 6)
142a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_OCP_EN BIT(7)
143a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_OCP_HOLD BIT(6)
144a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_CLIP_CTL (WSA881X_ANALOG_BASE + 0x0020)
145a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_BBM_CTL (WSA881X_ANALOG_BASE + 0x0021)
146a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_MISC_CTL1 (WSA881X_ANALOG_BASE + 0x0022)
147a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_MISC_CTL2 (WSA881X_ANALOG_BASE + 0x0023)
148a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_BIAS_INT (WSA881X_ANALOG_BASE + 0x0024)
149a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_PA_INT (WSA881X_ANALOG_BASE + 0x0025)
150a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_BIAS_CAL (WSA881X_ANALOG_BASE + 0x0026)
151a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_BIAS_PSRR (WSA881X_ANALOG_BASE + 0x0027)
152a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_STATUS1 (WSA881X_ANALOG_BASE + 0x0028)
153a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_STATUS2 (WSA881X_ANALOG_BASE + 0x0029)
154a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_EN_CTL (WSA881X_ANALOG_BASE + 0x002A)
155a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_EN_MASK BIT(7)
156a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_EN BIT(7)
157a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_CURRENT_LIMIT (WSA881X_ANALOG_BASE + 0x002B)
158a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_PS_CTL (WSA881X_ANALOG_BASE + 0x002C)
159a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_PRESET_OUT1 (WSA881X_ANALOG_BASE + 0x002D)
160a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_PRESET_OUT2 (WSA881X_ANALOG_BASE + 0x002E)
161a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_FORCE_OUT (WSA881X_ANALOG_BASE + 0x002F)
162a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_LDO_PROG (WSA881X_ANALOG_BASE + 0x0030)
163a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_SLOPE_COMP_ISENSE_FB (WSA881X_ANALOG_BASE + 0x0031)
164a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_RON_CTL (WSA881X_ANALOG_BASE + 0x0032)
165a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_LOOP_STABILITY (WSA881X_ANALOG_BASE + 0x0033)
166a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_ZX_CTL (WSA881X_ANALOG_BASE + 0x0034)
167a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_START_CTL (WSA881X_ANALOG_BASE + 0x0035)
168a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_MISC1_CTL (WSA881X_ANALOG_BASE + 0x0036)
169a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_MISC2_CTL (WSA881X_ANALOG_BASE + 0x0037)
170a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_MISC3_CTL (WSA881X_ANALOG_BASE + 0x0038)
171a0aab9e1SSrinivas Kandagatla #define WSA881X_BOOST_ATEST_CTL (WSA881X_ANALOG_BASE + 0x0039)
172a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_PROT_FE_GAIN (WSA881X_ANALOG_BASE + 0x003A)
173a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_PROT_FE_CM_LDO_SET (WSA881X_ANALOG_BASE + 0x003B)
174a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1 (WSA881X_ANALOG_BASE + 0x003C)
175a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2 (WSA881X_ANALOG_BASE + 0x003D)
176a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_PROT_ATEST1 (WSA881X_ANALOG_BASE + 0x003E)
177a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_PROT_ATEST2 (WSA881X_ANALOG_BASE + 0x003F)
178a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_PROT_FE_VSENSE_VCM (WSA881X_ANALOG_BASE + 0x0040)
179a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1 (WSA881X_ANALOG_BASE + 0x0041)
180a0aab9e1SSrinivas Kandagatla #define WSA881X_BONGO_RESRV_REG1 (WSA881X_ANALOG_BASE + 0x0042)
181a0aab9e1SSrinivas Kandagatla #define WSA881X_BONGO_RESRV_REG2 (WSA881X_ANALOG_BASE + 0x0043)
182a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_PROT_SAR (WSA881X_ANALOG_BASE + 0x0044)
183a0aab9e1SSrinivas Kandagatla #define WSA881X_SPKR_STATUS3 (WSA881X_ANALOG_BASE + 0x0045)
184a0aab9e1SSrinivas Kandagatla
185a0aab9e1SSrinivas Kandagatla #define SWRS_SCP_FRAME_CTRL_BANK(m) (0x60 + 0x10 * (m))
186a0aab9e1SSrinivas Kandagatla #define SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(m) (0xE0 + 0x10 * (m))
187a0aab9e1SSrinivas Kandagatla #define SWR_SLV_MAX_REG_ADDR 0x390
188a0aab9e1SSrinivas Kandagatla #define SWR_SLV_START_REG_ADDR 0x40
189a0aab9e1SSrinivas Kandagatla #define SWR_SLV_MAX_BUF_LEN 20
190a0aab9e1SSrinivas Kandagatla #define BYTES_PER_LINE 12
191a0aab9e1SSrinivas Kandagatla #define SWR_SLV_RD_BUF_LEN 8
192a0aab9e1SSrinivas Kandagatla #define SWR_SLV_WR_BUF_LEN 32
193a0aab9e1SSrinivas Kandagatla #define SWR_SLV_MAX_DEVICES 2
194a0aab9e1SSrinivas Kandagatla #define WSA881X_MAX_SWR_PORTS 4
195a0aab9e1SSrinivas Kandagatla #define WSA881X_VERSION_ENTRY_SIZE 27
196a0aab9e1SSrinivas Kandagatla #define WSA881X_OCP_CTL_TIMER_SEC 2
197a0aab9e1SSrinivas Kandagatla #define WSA881X_OCP_CTL_TEMP_CELSIUS 25
198a0aab9e1SSrinivas Kandagatla #define WSA881X_OCP_CTL_POLL_TIMER_SEC 60
1998dd55245SSrinivas Kandagatla #define WSA881X_PROBE_TIMEOUT 1000
200a0aab9e1SSrinivas Kandagatla
201a0aab9e1SSrinivas Kandagatla #define WSA881X_PA_GAIN_TLV(xname, reg, shift, max, invert, tlv_array) \
202a0aab9e1SSrinivas Kandagatla { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
203a0aab9e1SSrinivas Kandagatla .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
204a0aab9e1SSrinivas Kandagatla SNDRV_CTL_ELEM_ACCESS_READWRITE,\
205a0aab9e1SSrinivas Kandagatla .tlv.p = (tlv_array), \
206a0aab9e1SSrinivas Kandagatla .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
207a0aab9e1SSrinivas Kandagatla .put = wsa881x_put_pa_gain, \
208a0aab9e1SSrinivas Kandagatla .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
209a0aab9e1SSrinivas Kandagatla
210a0aab9e1SSrinivas Kandagatla static struct reg_default wsa881x_defaults[] = {
211a0aab9e1SSrinivas Kandagatla { WSA881X_CHIP_ID0, 0x00 },
212a0aab9e1SSrinivas Kandagatla { WSA881X_CHIP_ID1, 0x00 },
213a0aab9e1SSrinivas Kandagatla { WSA881X_CHIP_ID2, 0x00 },
214a0aab9e1SSrinivas Kandagatla { WSA881X_CHIP_ID3, 0x02 },
215a0aab9e1SSrinivas Kandagatla { WSA881X_BUS_ID, 0x00 },
216a0aab9e1SSrinivas Kandagatla { WSA881X_CDC_RST_CTL, 0x00 },
217a0aab9e1SSrinivas Kandagatla { WSA881X_CDC_TOP_CLK_CTL, 0x03 },
218a0aab9e1SSrinivas Kandagatla { WSA881X_CDC_ANA_CLK_CTL, 0x00 },
219a0aab9e1SSrinivas Kandagatla { WSA881X_CDC_DIG_CLK_CTL, 0x00 },
220a0aab9e1SSrinivas Kandagatla { WSA881X_CLOCK_CONFIG, 0x00 },
221a0aab9e1SSrinivas Kandagatla { WSA881X_ANA_CTL, 0x08 },
222a0aab9e1SSrinivas Kandagatla { WSA881X_SWR_RESET_EN, 0x00 },
223a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_DETECT_CTL, 0x01 },
224a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_MSB, 0x00 },
225a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_LSB, 0x00 },
226a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_CONFIG0, 0x00 },
227a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_CONFIG1, 0x00 },
228a0aab9e1SSrinivas Kandagatla { WSA881X_CDC_CLIP_CTL, 0x03 },
229a0aab9e1SSrinivas Kandagatla { WSA881X_SDM_PDM9_LSB, 0x00 },
230a0aab9e1SSrinivas Kandagatla { WSA881X_SDM_PDM9_MSB, 0x00 },
231a0aab9e1SSrinivas Kandagatla { WSA881X_CDC_RX_CTL, 0x7E },
232a0aab9e1SSrinivas Kandagatla { WSA881X_DEM_BYPASS_DATA0, 0x00 },
233a0aab9e1SSrinivas Kandagatla { WSA881X_DEM_BYPASS_DATA1, 0x00 },
234a0aab9e1SSrinivas Kandagatla { WSA881X_DEM_BYPASS_DATA2, 0x00 },
235a0aab9e1SSrinivas Kandagatla { WSA881X_DEM_BYPASS_DATA3, 0x00 },
236a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_CTRL0, 0x00 },
237a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_CTRL1, 0x00 },
238a0aab9e1SSrinivas Kandagatla { WSA881X_HDRIVE_CTL_GROUP1, 0x00 },
239a0aab9e1SSrinivas Kandagatla { WSA881X_INTR_MODE, 0x00 },
240a0aab9e1SSrinivas Kandagatla { WSA881X_INTR_STATUS, 0x00 },
241a0aab9e1SSrinivas Kandagatla { WSA881X_INTR_CLEAR, 0x00 },
242a0aab9e1SSrinivas Kandagatla { WSA881X_INTR_LEVEL, 0x00 },
243a0aab9e1SSrinivas Kandagatla { WSA881X_INTR_SET, 0x00 },
244a0aab9e1SSrinivas Kandagatla { WSA881X_INTR_TEST, 0x00 },
245a0aab9e1SSrinivas Kandagatla { WSA881X_PDM_TEST_MODE, 0x00 },
246a0aab9e1SSrinivas Kandagatla { WSA881X_ATE_TEST_MODE, 0x00 },
247a0aab9e1SSrinivas Kandagatla { WSA881X_PIN_CTL_MODE, 0x00 },
248a0aab9e1SSrinivas Kandagatla { WSA881X_PIN_CTL_OE, 0x00 },
249a0aab9e1SSrinivas Kandagatla { WSA881X_PIN_WDATA_IOPAD, 0x00 },
250a0aab9e1SSrinivas Kandagatla { WSA881X_PIN_STATUS, 0x00 },
251a0aab9e1SSrinivas Kandagatla { WSA881X_DIG_DEBUG_MODE, 0x00 },
252a0aab9e1SSrinivas Kandagatla { WSA881X_DIG_DEBUG_SEL, 0x00 },
253a0aab9e1SSrinivas Kandagatla { WSA881X_DIG_DEBUG_EN, 0x00 },
254a0aab9e1SSrinivas Kandagatla { WSA881X_SWR_HM_TEST1, 0x08 },
255a0aab9e1SSrinivas Kandagatla { WSA881X_SWR_HM_TEST2, 0x00 },
256a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_DETECT_DBG_CTL, 0x00 },
257a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_DEBUG_MSB, 0x00 },
258a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_DEBUG_LSB, 0x00 },
259a0aab9e1SSrinivas Kandagatla { WSA881X_SAMPLE_EDGE_SEL, 0x0C },
260a0aab9e1SSrinivas Kandagatla { WSA881X_SPARE_0, 0x00 },
261a0aab9e1SSrinivas Kandagatla { WSA881X_SPARE_1, 0x00 },
262a0aab9e1SSrinivas Kandagatla { WSA881X_SPARE_2, 0x00 },
263a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_0, 0x01 },
264a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_1, 0xFF },
265a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_2, 0xC0 },
266a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_3, 0xFF },
267a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_4, 0xC0 },
268a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_5, 0xFF },
269a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_6, 0xFF },
270a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_7, 0xFF },
271a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_8, 0xFF },
272a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_9, 0xFF },
273a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_10, 0xFF },
274a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_11, 0xFF },
275a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_12, 0xFF },
276a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_13, 0xFF },
277a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_14, 0xFF },
278a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_15, 0xFF },
279a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_16, 0xFF },
280a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_17, 0xFF },
281a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_18, 0xFF },
282a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_19, 0xFF },
283a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_20, 0xFF },
284a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_21, 0xFF },
285a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_22, 0xFF },
286a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_23, 0xFF },
287a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_24, 0x03 },
288a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_25, 0x01 },
289a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_26, 0x03 },
290a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_27, 0x11 },
291a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_63, 0x40 },
292a0aab9e1SSrinivas Kandagatla /* WSA881x Analog registers */
293a0aab9e1SSrinivas Kandagatla { WSA881X_BIAS_REF_CTRL, 0x6C },
294a0aab9e1SSrinivas Kandagatla { WSA881X_BIAS_TEST, 0x16 },
295a0aab9e1SSrinivas Kandagatla { WSA881X_BIAS_BIAS, 0xF0 },
296a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_OP, 0x00 },
297a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_IREF_CTRL, 0x56 },
298a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_ISENS_CTRL, 0x47 },
299a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_CLK_CTRL, 0x87 },
300a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_TEST, 0x00 },
301a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_BIAS, 0x51 },
302a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_DOUT_MSB, 0x00 },
303a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_DOUT_LSB, 0x00 },
304a0aab9e1SSrinivas Kandagatla { WSA881X_ADC_EN_MODU_V, 0x00 },
305a0aab9e1SSrinivas Kandagatla { WSA881X_ADC_EN_MODU_I, 0x00 },
306a0aab9e1SSrinivas Kandagatla { WSA881X_ADC_EN_DET_TEST_V, 0x00 },
307a0aab9e1SSrinivas Kandagatla { WSA881X_ADC_EN_DET_TEST_I, 0x00 },
308a0aab9e1SSrinivas Kandagatla { WSA881X_ADC_EN_SEL_IBAIS, 0x10 },
309a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_DRV_EN, 0x74 },
310a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_DRV_DBG, 0x15 },
311a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PWRSTG_DBG, 0x00 },
312a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_OCP_CTL, 0xD4 },
313a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_CLIP_CTL, 0x90 },
314a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PA_INT, 0x54 },
315a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_BIAS_CAL, 0xAC },
316a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_STATUS1, 0x00 },
317a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_STATUS2, 0x00 },
318a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_EN_CTL, 0x18 },
319a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_CURRENT_LIMIT, 0x7A },
320a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_PRESET_OUT2, 0x70 },
321a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_FORCE_OUT, 0x0E },
322a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_LDO_PROG, 0x16 },
323a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, 0x71 },
324a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_RON_CTL, 0x0F },
325a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_ZX_CTL, 0x34 },
326a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_START_CTL, 0x23 },
327a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_MISC1_CTL, 0x80 },
328a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_MISC2_CTL, 0x00 },
329a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_MISC3_CTL, 0x00 },
330a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_ATEST_CTL, 0x00 },
331a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PROT_FE_GAIN, 0x46 },
332a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PROT_FE_CM_LDO_SET, 0x3B },
333a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1, 0x8D },
334a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2, 0x8D },
335a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PROT_ATEST1, 0x01 },
336a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x8D },
337a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1, 0x4D },
338a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PROT_SAR, 0x00 },
339a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_STATUS3, 0x00 },
340a0aab9e1SSrinivas Kandagatla };
341a0aab9e1SSrinivas Kandagatla
342a0aab9e1SSrinivas Kandagatla static const struct reg_sequence wsa881x_pre_pmu_pa_2_0[] = {
343a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_DRV_GAIN, 0x41, 0 },
344a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_MISC_CTL1, 0x87, 0 },
345a0aab9e1SSrinivas Kandagatla };
346a0aab9e1SSrinivas Kandagatla
347a0aab9e1SSrinivas Kandagatla static const struct reg_sequence wsa881x_vi_txfe_en_2_0[] = {
348a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x85, 0 },
349a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PROT_ATEST2, 0x0A, 0 },
350a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PROT_FE_GAIN, 0x47, 0 },
351a0aab9e1SSrinivas Kandagatla };
352a0aab9e1SSrinivas Kandagatla
353a0aab9e1SSrinivas Kandagatla /* Default register reset values for WSA881x rev 2.0 */
354a0aab9e1SSrinivas Kandagatla static struct reg_sequence wsa881x_rev_2_0[] = {
355a0aab9e1SSrinivas Kandagatla { WSA881X_RESET_CTL, 0x00, 0x00 },
356a0aab9e1SSrinivas Kandagatla { WSA881X_TADC_VALUE_CTL, 0x01, 0x00 },
357a0aab9e1SSrinivas Kandagatla { WSA881X_INTR_MASK, 0x1B, 0x00 },
358a0aab9e1SSrinivas Kandagatla { WSA881X_IOPAD_CTL, 0x00, 0x00 },
359a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_28, 0x3F, 0x00 },
360a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_29, 0x3F, 0x00 },
361a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_30, 0x01, 0x00 },
362a0aab9e1SSrinivas Kandagatla { WSA881X_OTP_REG_31, 0x01, 0x00 },
363a0aab9e1SSrinivas Kandagatla { WSA881X_TEMP_ADC_CTRL, 0x03, 0x00 },
364a0aab9e1SSrinivas Kandagatla { WSA881X_ADC_SEL_IBIAS, 0x45, 0x00 },
365a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_DRV_GAIN, 0xC1, 0x00 },
366a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_DAC_CTL, 0x42, 0x00 },
367a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_BBM_CTL, 0x02, 0x00 },
368a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_MISC_CTL1, 0x40, 0x00 },
369a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_MISC_CTL2, 0x07, 0x00 },
370a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_BIAS_INT, 0x5F, 0x00 },
371a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_BIAS_PSRR, 0x44, 0x00 },
372a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_PS_CTL, 0xA0, 0x00 },
373a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_PRESET_OUT1, 0xB7, 0x00 },
374a0aab9e1SSrinivas Kandagatla { WSA881X_BOOST_LOOP_STABILITY, 0x8D, 0x00 },
375a0aab9e1SSrinivas Kandagatla { WSA881X_SPKR_PROT_ATEST2, 0x02, 0x00 },
376a0aab9e1SSrinivas Kandagatla { WSA881X_BONGO_RESRV_REG1, 0x5E, 0x00 },
377a0aab9e1SSrinivas Kandagatla { WSA881X_BONGO_RESRV_REG2, 0x07, 0x00 },
378a0aab9e1SSrinivas Kandagatla };
379a0aab9e1SSrinivas Kandagatla
380a0aab9e1SSrinivas Kandagatla enum wsa_port_ids {
381a0aab9e1SSrinivas Kandagatla WSA881X_PORT_DAC,
382a0aab9e1SSrinivas Kandagatla WSA881X_PORT_COMP,
383a0aab9e1SSrinivas Kandagatla WSA881X_PORT_BOOST,
384a0aab9e1SSrinivas Kandagatla WSA881X_PORT_VISENSE,
385a0aab9e1SSrinivas Kandagatla };
386a0aab9e1SSrinivas Kandagatla
387a0aab9e1SSrinivas Kandagatla /* 4 ports */
388a0aab9e1SSrinivas Kandagatla static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA881X_MAX_SWR_PORTS] = {
389a0aab9e1SSrinivas Kandagatla {
390a0aab9e1SSrinivas Kandagatla /* DAC */
391a0aab9e1SSrinivas Kandagatla .num = 1,
392a0aab9e1SSrinivas Kandagatla .type = SDW_DPN_SIMPLE,
393a0aab9e1SSrinivas Kandagatla .min_ch = 1,
394a0aab9e1SSrinivas Kandagatla .max_ch = 1,
395a0aab9e1SSrinivas Kandagatla .simple_ch_prep_sm = true,
3960f2a3b02SSrinivas Kandagatla .read_only_wordlength = true,
397a0aab9e1SSrinivas Kandagatla }, {
398a0aab9e1SSrinivas Kandagatla /* COMP */
399a0aab9e1SSrinivas Kandagatla .num = 2,
400a0aab9e1SSrinivas Kandagatla .type = SDW_DPN_SIMPLE,
401a0aab9e1SSrinivas Kandagatla .min_ch = 1,
402a0aab9e1SSrinivas Kandagatla .max_ch = 1,
403a0aab9e1SSrinivas Kandagatla .simple_ch_prep_sm = true,
4040f2a3b02SSrinivas Kandagatla .read_only_wordlength = true,
405a0aab9e1SSrinivas Kandagatla }, {
406a0aab9e1SSrinivas Kandagatla /* BOOST */
407a0aab9e1SSrinivas Kandagatla .num = 3,
408a0aab9e1SSrinivas Kandagatla .type = SDW_DPN_SIMPLE,
409a0aab9e1SSrinivas Kandagatla .min_ch = 1,
410a0aab9e1SSrinivas Kandagatla .max_ch = 1,
411a0aab9e1SSrinivas Kandagatla .simple_ch_prep_sm = true,
4120f2a3b02SSrinivas Kandagatla .read_only_wordlength = true,
413a0aab9e1SSrinivas Kandagatla }, {
414a0aab9e1SSrinivas Kandagatla /* VISENSE */
415a0aab9e1SSrinivas Kandagatla .num = 4,
416a0aab9e1SSrinivas Kandagatla .type = SDW_DPN_SIMPLE,
417a0aab9e1SSrinivas Kandagatla .min_ch = 1,
418a0aab9e1SSrinivas Kandagatla .max_ch = 1,
419a0aab9e1SSrinivas Kandagatla .simple_ch_prep_sm = true,
4200f2a3b02SSrinivas Kandagatla .read_only_wordlength = true,
421a0aab9e1SSrinivas Kandagatla }
422a0aab9e1SSrinivas Kandagatla };
423a0aab9e1SSrinivas Kandagatla
42457dc05c4SKrzysztof Kozlowski static const struct sdw_port_config wsa881x_pconfig[WSA881X_MAX_SWR_PORTS] = {
425a0aab9e1SSrinivas Kandagatla {
426a0aab9e1SSrinivas Kandagatla .num = 1,
427a0aab9e1SSrinivas Kandagatla .ch_mask = 0x1,
428a0aab9e1SSrinivas Kandagatla }, {
429a0aab9e1SSrinivas Kandagatla .num = 2,
430a0aab9e1SSrinivas Kandagatla .ch_mask = 0xf,
431a0aab9e1SSrinivas Kandagatla }, {
432a0aab9e1SSrinivas Kandagatla .num = 3,
433a0aab9e1SSrinivas Kandagatla .ch_mask = 0x3,
434a0aab9e1SSrinivas Kandagatla }, { /* IV feedback */
435a0aab9e1SSrinivas Kandagatla .num = 4,
436a0aab9e1SSrinivas Kandagatla .ch_mask = 0x3,
437a0aab9e1SSrinivas Kandagatla },
438a0aab9e1SSrinivas Kandagatla };
439a0aab9e1SSrinivas Kandagatla
wsa881x_readable_register(struct device * dev,unsigned int reg)440a0aab9e1SSrinivas Kandagatla static bool wsa881x_readable_register(struct device *dev, unsigned int reg)
441a0aab9e1SSrinivas Kandagatla {
442a0aab9e1SSrinivas Kandagatla switch (reg) {
443a0aab9e1SSrinivas Kandagatla case WSA881X_CHIP_ID0:
444a0aab9e1SSrinivas Kandagatla case WSA881X_CHIP_ID1:
445a0aab9e1SSrinivas Kandagatla case WSA881X_CHIP_ID2:
446a0aab9e1SSrinivas Kandagatla case WSA881X_CHIP_ID3:
447a0aab9e1SSrinivas Kandagatla case WSA881X_BUS_ID:
448a0aab9e1SSrinivas Kandagatla case WSA881X_CDC_RST_CTL:
449a0aab9e1SSrinivas Kandagatla case WSA881X_CDC_TOP_CLK_CTL:
450a0aab9e1SSrinivas Kandagatla case WSA881X_CDC_ANA_CLK_CTL:
451a0aab9e1SSrinivas Kandagatla case WSA881X_CDC_DIG_CLK_CTL:
452a0aab9e1SSrinivas Kandagatla case WSA881X_CLOCK_CONFIG:
453a0aab9e1SSrinivas Kandagatla case WSA881X_ANA_CTL:
454a0aab9e1SSrinivas Kandagatla case WSA881X_SWR_RESET_EN:
455a0aab9e1SSrinivas Kandagatla case WSA881X_RESET_CTL:
456a0aab9e1SSrinivas Kandagatla case WSA881X_TADC_VALUE_CTL:
457a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_DETECT_CTL:
458a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_MSB:
459a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_LSB:
460a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_CONFIG0:
461a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_CONFIG1:
462a0aab9e1SSrinivas Kandagatla case WSA881X_CDC_CLIP_CTL:
463a0aab9e1SSrinivas Kandagatla case WSA881X_SDM_PDM9_LSB:
464a0aab9e1SSrinivas Kandagatla case WSA881X_SDM_PDM9_MSB:
465a0aab9e1SSrinivas Kandagatla case WSA881X_CDC_RX_CTL:
466a0aab9e1SSrinivas Kandagatla case WSA881X_DEM_BYPASS_DATA0:
467a0aab9e1SSrinivas Kandagatla case WSA881X_DEM_BYPASS_DATA1:
468a0aab9e1SSrinivas Kandagatla case WSA881X_DEM_BYPASS_DATA2:
469a0aab9e1SSrinivas Kandagatla case WSA881X_DEM_BYPASS_DATA3:
470a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_CTRL0:
471a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_CTRL1:
472a0aab9e1SSrinivas Kandagatla case WSA881X_HDRIVE_CTL_GROUP1:
473a0aab9e1SSrinivas Kandagatla case WSA881X_INTR_MODE:
474a0aab9e1SSrinivas Kandagatla case WSA881X_INTR_MASK:
475a0aab9e1SSrinivas Kandagatla case WSA881X_INTR_STATUS:
476a0aab9e1SSrinivas Kandagatla case WSA881X_INTR_CLEAR:
477a0aab9e1SSrinivas Kandagatla case WSA881X_INTR_LEVEL:
478a0aab9e1SSrinivas Kandagatla case WSA881X_INTR_SET:
479a0aab9e1SSrinivas Kandagatla case WSA881X_INTR_TEST:
480a0aab9e1SSrinivas Kandagatla case WSA881X_PDM_TEST_MODE:
481a0aab9e1SSrinivas Kandagatla case WSA881X_ATE_TEST_MODE:
482a0aab9e1SSrinivas Kandagatla case WSA881X_PIN_CTL_MODE:
483a0aab9e1SSrinivas Kandagatla case WSA881X_PIN_CTL_OE:
484a0aab9e1SSrinivas Kandagatla case WSA881X_PIN_WDATA_IOPAD:
485a0aab9e1SSrinivas Kandagatla case WSA881X_PIN_STATUS:
486a0aab9e1SSrinivas Kandagatla case WSA881X_DIG_DEBUG_MODE:
487a0aab9e1SSrinivas Kandagatla case WSA881X_DIG_DEBUG_SEL:
488a0aab9e1SSrinivas Kandagatla case WSA881X_DIG_DEBUG_EN:
489a0aab9e1SSrinivas Kandagatla case WSA881X_SWR_HM_TEST1:
490a0aab9e1SSrinivas Kandagatla case WSA881X_SWR_HM_TEST2:
491a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_DETECT_DBG_CTL:
492a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_DEBUG_MSB:
493a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_DEBUG_LSB:
494a0aab9e1SSrinivas Kandagatla case WSA881X_SAMPLE_EDGE_SEL:
495a0aab9e1SSrinivas Kandagatla case WSA881X_IOPAD_CTL:
496a0aab9e1SSrinivas Kandagatla case WSA881X_SPARE_0:
497a0aab9e1SSrinivas Kandagatla case WSA881X_SPARE_1:
498a0aab9e1SSrinivas Kandagatla case WSA881X_SPARE_2:
499a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_0:
500a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_1:
501a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_2:
502a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_3:
503a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_4:
504a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_5:
505a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_6:
506a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_7:
507a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_8:
508a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_9:
509a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_10:
510a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_11:
511a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_12:
512a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_13:
513a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_14:
514a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_15:
515a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_16:
516a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_17:
517a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_18:
518a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_19:
519a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_20:
520a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_21:
521a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_22:
522a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_23:
523a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_24:
524a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_25:
525a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_26:
526a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_27:
527a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_28:
528a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_29:
529a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_30:
530a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_31:
531a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_63:
532a0aab9e1SSrinivas Kandagatla case WSA881X_BIAS_REF_CTRL:
533a0aab9e1SSrinivas Kandagatla case WSA881X_BIAS_TEST:
534a0aab9e1SSrinivas Kandagatla case WSA881X_BIAS_BIAS:
535a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_OP:
536a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_IREF_CTRL:
537a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_ISENS_CTRL:
538a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_CLK_CTRL:
539a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_TEST:
540a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_BIAS:
541a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_ADC_CTRL:
542a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_DOUT_MSB:
543a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_DOUT_LSB:
544a0aab9e1SSrinivas Kandagatla case WSA881X_ADC_EN_MODU_V:
545a0aab9e1SSrinivas Kandagatla case WSA881X_ADC_EN_MODU_I:
546a0aab9e1SSrinivas Kandagatla case WSA881X_ADC_EN_DET_TEST_V:
547a0aab9e1SSrinivas Kandagatla case WSA881X_ADC_EN_DET_TEST_I:
548a0aab9e1SSrinivas Kandagatla case WSA881X_ADC_SEL_IBIAS:
549a0aab9e1SSrinivas Kandagatla case WSA881X_ADC_EN_SEL_IBAIS:
550a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_DRV_EN:
551a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_DRV_GAIN:
552a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_DAC_CTL:
553a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_DRV_DBG:
554a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_PWRSTG_DBG:
555a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_OCP_CTL:
556a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_CLIP_CTL:
557a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_BBM_CTL:
558a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_MISC_CTL1:
559a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_MISC_CTL2:
560a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_BIAS_INT:
561a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_PA_INT:
562a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_BIAS_CAL:
563a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_BIAS_PSRR:
564a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_STATUS1:
565a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_STATUS2:
566a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_EN_CTL:
567a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_CURRENT_LIMIT:
568a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_PS_CTL:
569a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_PRESET_OUT1:
570a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_PRESET_OUT2:
571a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_FORCE_OUT:
572a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_LDO_PROG:
573a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_SLOPE_COMP_ISENSE_FB:
574a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_RON_CTL:
575a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_LOOP_STABILITY:
576a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_ZX_CTL:
577a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_START_CTL:
578a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_MISC1_CTL:
579a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_MISC2_CTL:
580a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_MISC3_CTL:
581a0aab9e1SSrinivas Kandagatla case WSA881X_BOOST_ATEST_CTL:
582a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_PROT_FE_GAIN:
583a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_PROT_FE_CM_LDO_SET:
584a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1:
585a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2:
586a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_PROT_ATEST1:
587a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_PROT_ATEST2:
588a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_PROT_FE_VSENSE_VCM:
589a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1:
590a0aab9e1SSrinivas Kandagatla case WSA881X_BONGO_RESRV_REG1:
591a0aab9e1SSrinivas Kandagatla case WSA881X_BONGO_RESRV_REG2:
592a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_PROT_SAR:
593a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_STATUS3:
594a0aab9e1SSrinivas Kandagatla return true;
595a0aab9e1SSrinivas Kandagatla default:
596a0aab9e1SSrinivas Kandagatla return false;
597a0aab9e1SSrinivas Kandagatla }
598a0aab9e1SSrinivas Kandagatla }
599a0aab9e1SSrinivas Kandagatla
wsa881x_volatile_register(struct device * dev,unsigned int reg)600a0aab9e1SSrinivas Kandagatla static bool wsa881x_volatile_register(struct device *dev, unsigned int reg)
601a0aab9e1SSrinivas Kandagatla {
602a0aab9e1SSrinivas Kandagatla switch (reg) {
603a0aab9e1SSrinivas Kandagatla case WSA881X_CHIP_ID0:
604a0aab9e1SSrinivas Kandagatla case WSA881X_CHIP_ID1:
605a0aab9e1SSrinivas Kandagatla case WSA881X_CHIP_ID2:
606a0aab9e1SSrinivas Kandagatla case WSA881X_CHIP_ID3:
607a0aab9e1SSrinivas Kandagatla case WSA881X_BUS_ID:
608a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_MSB:
609a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_LSB:
610a0aab9e1SSrinivas Kandagatla case WSA881X_SDM_PDM9_LSB:
611a0aab9e1SSrinivas Kandagatla case WSA881X_SDM_PDM9_MSB:
612a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_CTRL1:
613a0aab9e1SSrinivas Kandagatla case WSA881X_INTR_STATUS:
614a0aab9e1SSrinivas Kandagatla case WSA881X_ATE_TEST_MODE:
615a0aab9e1SSrinivas Kandagatla case WSA881X_PIN_STATUS:
616a0aab9e1SSrinivas Kandagatla case WSA881X_SWR_HM_TEST2:
617a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_STATUS1:
618a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_STATUS2:
619a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_STATUS3:
620a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_0:
621a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_1:
622a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_2:
623a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_3:
624a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_4:
625a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_5:
626a0aab9e1SSrinivas Kandagatla case WSA881X_OTP_REG_31:
627a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_DOUT_MSB:
628a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_DOUT_LSB:
629a0aab9e1SSrinivas Kandagatla case WSA881X_TEMP_OP:
630a0aab9e1SSrinivas Kandagatla case WSA881X_SPKR_PROT_SAR:
631a0aab9e1SSrinivas Kandagatla return true;
632a0aab9e1SSrinivas Kandagatla default:
633a0aab9e1SSrinivas Kandagatla return false;
634a0aab9e1SSrinivas Kandagatla }
635a0aab9e1SSrinivas Kandagatla }
636a0aab9e1SSrinivas Kandagatla
637a0aab9e1SSrinivas Kandagatla static struct regmap_config wsa881x_regmap_config = {
638a0aab9e1SSrinivas Kandagatla .reg_bits = 32,
639a0aab9e1SSrinivas Kandagatla .val_bits = 8,
640daf95b06SMark Brown .cache_type = REGCACHE_MAPLE,
641a0aab9e1SSrinivas Kandagatla .reg_defaults = wsa881x_defaults,
642e8820dbdSSrinivas Kandagatla .max_register = WSA881X_SPKR_STATUS3,
643a0aab9e1SSrinivas Kandagatla .num_reg_defaults = ARRAY_SIZE(wsa881x_defaults),
644a0aab9e1SSrinivas Kandagatla .volatile_reg = wsa881x_volatile_register,
645a0aab9e1SSrinivas Kandagatla .readable_reg = wsa881x_readable_register,
646a0aab9e1SSrinivas Kandagatla .reg_format_endian = REGMAP_ENDIAN_NATIVE,
647a0aab9e1SSrinivas Kandagatla .val_format_endian = REGMAP_ENDIAN_NATIVE,
648a0aab9e1SSrinivas Kandagatla };
649a0aab9e1SSrinivas Kandagatla
650a0aab9e1SSrinivas Kandagatla enum {
651a0aab9e1SSrinivas Kandagatla G_18DB = 0,
652a0aab9e1SSrinivas Kandagatla G_16P5DB,
653a0aab9e1SSrinivas Kandagatla G_15DB,
654a0aab9e1SSrinivas Kandagatla G_13P5DB,
655a0aab9e1SSrinivas Kandagatla G_12DB,
656a0aab9e1SSrinivas Kandagatla G_10P5DB,
657a0aab9e1SSrinivas Kandagatla G_9DB,
658a0aab9e1SSrinivas Kandagatla G_7P5DB,
659a0aab9e1SSrinivas Kandagatla G_6DB,
660a0aab9e1SSrinivas Kandagatla G_4P5DB,
661a0aab9e1SSrinivas Kandagatla G_3DB,
662a0aab9e1SSrinivas Kandagatla G_1P5DB,
663a0aab9e1SSrinivas Kandagatla G_0DB,
664a0aab9e1SSrinivas Kandagatla };
665a0aab9e1SSrinivas Kandagatla
666a0aab9e1SSrinivas Kandagatla /*
667a0aab9e1SSrinivas Kandagatla * Private data Structure for wsa881x. All parameters related to
668a0aab9e1SSrinivas Kandagatla * WSA881X codec needs to be defined here.
669a0aab9e1SSrinivas Kandagatla */
670a0aab9e1SSrinivas Kandagatla struct wsa881x_priv {
671a0aab9e1SSrinivas Kandagatla struct regmap *regmap;
672a0aab9e1SSrinivas Kandagatla struct device *dev;
673a0aab9e1SSrinivas Kandagatla struct sdw_slave *slave;
674a0aab9e1SSrinivas Kandagatla struct sdw_stream_config sconfig;
675a0aab9e1SSrinivas Kandagatla struct sdw_stream_runtime *sruntime;
676a0aab9e1SSrinivas Kandagatla struct sdw_port_config port_config[WSA881X_MAX_SWR_PORTS];
677a0aab9e1SSrinivas Kandagatla struct gpio_desc *sd_n;
67873845585SKrzysztof Kozlowski /*
67973845585SKrzysztof Kozlowski * Logical state for SD_N GPIO: high for shutdown, low for enable.
68073845585SKrzysztof Kozlowski * For backwards compatibility.
68173845585SKrzysztof Kozlowski */
68273845585SKrzysztof Kozlowski unsigned int sd_n_val;
683a0aab9e1SSrinivas Kandagatla int version;
684a0aab9e1SSrinivas Kandagatla int active_ports;
685a0aab9e1SSrinivas Kandagatla bool port_prepared[WSA881X_MAX_SWR_PORTS];
686a0aab9e1SSrinivas Kandagatla bool port_enable[WSA881X_MAX_SWR_PORTS];
687a0aab9e1SSrinivas Kandagatla };
688a0aab9e1SSrinivas Kandagatla
wsa881x_init(struct wsa881x_priv * wsa881x)689a0aab9e1SSrinivas Kandagatla static void wsa881x_init(struct wsa881x_priv *wsa881x)
690a0aab9e1SSrinivas Kandagatla {
691a0aab9e1SSrinivas Kandagatla struct regmap *rm = wsa881x->regmap;
692a0aab9e1SSrinivas Kandagatla unsigned int val = 0;
693a0aab9e1SSrinivas Kandagatla
694a0aab9e1SSrinivas Kandagatla regmap_read(rm, WSA881X_CHIP_ID1, &wsa881x->version);
695a0aab9e1SSrinivas Kandagatla regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0,
696a0aab9e1SSrinivas Kandagatla ARRAY_SIZE(wsa881x_rev_2_0));
697a0aab9e1SSrinivas Kandagatla
698a0aab9e1SSrinivas Kandagatla /* Enable software reset output from soundwire slave */
699a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_SWR_RESET_EN, 0x07, 0x07);
700a0aab9e1SSrinivas Kandagatla
701a0aab9e1SSrinivas Kandagatla /* Bring out of analog reset */
702a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_CDC_RST_CTL, 0x02, 0x02);
703a0aab9e1SSrinivas Kandagatla
704a0aab9e1SSrinivas Kandagatla /* Bring out of digital reset */
705a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_CDC_RST_CTL, 0x01, 0x01);
706a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_CLOCK_CONFIG, 0x10, 0x10);
707a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_SPKR_OCP_CTL, 0x02, 0x02);
708a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_SPKR_MISC_CTL1, 0xC0, 0x80);
709a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_SPKR_MISC_CTL1, 0x06, 0x06);
710a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_SPKR_BIAS_INT, 0xFF, 0x00);
711a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_SPKR_PA_INT, 0xF0, 0x40);
712a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_SPKR_PA_INT, 0x0E, 0x0E);
713a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_BOOST_LOOP_STABILITY, 0x03, 0x03);
714a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_BOOST_MISC2_CTL, 0xFF, 0x14);
715a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_BOOST_START_CTL, 0x80, 0x80);
716a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_BOOST_START_CTL, 0x03, 0x00);
717a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, 0x0C, 0x04);
718a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, 0x03, 0x00);
719a0aab9e1SSrinivas Kandagatla
720a0aab9e1SSrinivas Kandagatla regmap_read(rm, WSA881X_OTP_REG_0, &val);
721a0aab9e1SSrinivas Kandagatla if (val)
722a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_BOOST_PRESET_OUT1, 0xF0, 0x70);
723a0aab9e1SSrinivas Kandagatla
724a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_BOOST_PRESET_OUT2, 0xF0, 0x30);
725a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_SPKR_DRV_EN, 0x08, 0x08);
726a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_BOOST_CURRENT_LIMIT, 0x0F, 0x08);
727a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_SPKR_OCP_CTL, 0x30, 0x30);
728a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_SPKR_OCP_CTL, 0x0C, 0x00);
729a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_OTP_REG_28, 0x3F, 0x3A);
730a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG1, 0xFF, 0xB2);
731a0aab9e1SSrinivas Kandagatla regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG2, 0xFF, 0x05);
732a0aab9e1SSrinivas Kandagatla }
733a0aab9e1SSrinivas Kandagatla
wsa881x_component_probe(struct snd_soc_component * comp)734a0aab9e1SSrinivas Kandagatla static int wsa881x_component_probe(struct snd_soc_component *comp)
735a0aab9e1SSrinivas Kandagatla {
736a0aab9e1SSrinivas Kandagatla struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(comp);
737a0aab9e1SSrinivas Kandagatla
738a0aab9e1SSrinivas Kandagatla snd_soc_component_init_regmap(comp, wsa881x->regmap);
739a0aab9e1SSrinivas Kandagatla
740a0aab9e1SSrinivas Kandagatla return 0;
741a0aab9e1SSrinivas Kandagatla }
742a0aab9e1SSrinivas Kandagatla
wsa881x_put_pa_gain(struct snd_kcontrol * kc,struct snd_ctl_elem_value * ucontrol)743a0aab9e1SSrinivas Kandagatla static int wsa881x_put_pa_gain(struct snd_kcontrol *kc,
744a0aab9e1SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
745a0aab9e1SSrinivas Kandagatla {
746a0aab9e1SSrinivas Kandagatla struct snd_soc_component *comp = snd_soc_kcontrol_component(kc);
747a0aab9e1SSrinivas Kandagatla struct soc_mixer_control *mc =
748a0aab9e1SSrinivas Kandagatla (struct soc_mixer_control *)kc->private_value;
749a0aab9e1SSrinivas Kandagatla int max = mc->max;
750a0aab9e1SSrinivas Kandagatla unsigned int mask = (1 << fls(max)) - 1;
751a0aab9e1SSrinivas Kandagatla int val, ret, min_gain, max_gain;
752a0aab9e1SSrinivas Kandagatla
7539a1a2861SPierre-Louis Bossart ret = pm_runtime_resume_and_get(comp->dev);
7549a1a2861SPierre-Louis Bossart if (ret < 0 && ret != -EACCES)
7558dd55245SSrinivas Kandagatla return ret;
7568dd55245SSrinivas Kandagatla
757a0aab9e1SSrinivas Kandagatla max_gain = (max - ucontrol->value.integer.value[0]) & mask;
758a0aab9e1SSrinivas Kandagatla /*
759a0aab9e1SSrinivas Kandagatla * Gain has to set incrementally in 4 steps
760a0aab9e1SSrinivas Kandagatla * as per HW sequence
761a0aab9e1SSrinivas Kandagatla */
762a0aab9e1SSrinivas Kandagatla if (max_gain > G_4P5DB)
763a0aab9e1SSrinivas Kandagatla min_gain = G_0DB;
764a0aab9e1SSrinivas Kandagatla else
765a0aab9e1SSrinivas Kandagatla min_gain = max_gain + 3;
766a0aab9e1SSrinivas Kandagatla /*
767a0aab9e1SSrinivas Kandagatla * 1ms delay is needed before change in gain
768a0aab9e1SSrinivas Kandagatla * as per HW requirement.
769a0aab9e1SSrinivas Kandagatla */
770a0aab9e1SSrinivas Kandagatla usleep_range(1000, 1010);
771a0aab9e1SSrinivas Kandagatla
772a0aab9e1SSrinivas Kandagatla for (val = min_gain; max_gain <= val; val--) {
773a0aab9e1SSrinivas Kandagatla ret = snd_soc_component_update_bits(comp,
774a0aab9e1SSrinivas Kandagatla WSA881X_SPKR_DRV_GAIN,
775a0aab9e1SSrinivas Kandagatla WSA881X_SPKR_PAG_GAIN_MASK,
776a0aab9e1SSrinivas Kandagatla val << 4);
777a0aab9e1SSrinivas Kandagatla if (ret < 0)
778a0aab9e1SSrinivas Kandagatla dev_err(comp->dev, "Failed to change PA gain");
779a0aab9e1SSrinivas Kandagatla
780a0aab9e1SSrinivas Kandagatla usleep_range(1000, 1010);
781a0aab9e1SSrinivas Kandagatla }
7823fc27e9aSSrinivas Kandagatla
7838dd55245SSrinivas Kandagatla pm_runtime_mark_last_busy(comp->dev);
7848dd55245SSrinivas Kandagatla pm_runtime_put_autosuspend(comp->dev);
7858dd55245SSrinivas Kandagatla
7863fc27e9aSSrinivas Kandagatla return 1;
787a0aab9e1SSrinivas Kandagatla }
788a0aab9e1SSrinivas Kandagatla
wsa881x_get_port(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)789a0aab9e1SSrinivas Kandagatla static int wsa881x_get_port(struct snd_kcontrol *kcontrol,
790a0aab9e1SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
791a0aab9e1SSrinivas Kandagatla {
792a0aab9e1SSrinivas Kandagatla struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
793a0aab9e1SSrinivas Kandagatla struct wsa881x_priv *data = snd_soc_component_get_drvdata(comp);
794a0aab9e1SSrinivas Kandagatla struct soc_mixer_control *mixer =
795a0aab9e1SSrinivas Kandagatla (struct soc_mixer_control *)kcontrol->private_value;
796a0aab9e1SSrinivas Kandagatla int portidx = mixer->reg;
797a0aab9e1SSrinivas Kandagatla
798a0aab9e1SSrinivas Kandagatla ucontrol->value.integer.value[0] = data->port_enable[portidx];
799a0aab9e1SSrinivas Kandagatla
800a0aab9e1SSrinivas Kandagatla
801a0aab9e1SSrinivas Kandagatla return 0;
802a0aab9e1SSrinivas Kandagatla }
803a0aab9e1SSrinivas Kandagatla
wsa881x_boost_ctrl(struct snd_soc_component * comp,bool enable)804a0aab9e1SSrinivas Kandagatla static int wsa881x_boost_ctrl(struct snd_soc_component *comp, bool enable)
805a0aab9e1SSrinivas Kandagatla {
806a0aab9e1SSrinivas Kandagatla if (enable)
807a0aab9e1SSrinivas Kandagatla snd_soc_component_update_bits(comp, WSA881X_BOOST_EN_CTL,
808a0aab9e1SSrinivas Kandagatla WSA881X_BOOST_EN_MASK,
809a0aab9e1SSrinivas Kandagatla WSA881X_BOOST_EN);
810a0aab9e1SSrinivas Kandagatla else
811a0aab9e1SSrinivas Kandagatla snd_soc_component_update_bits(comp, WSA881X_BOOST_EN_CTL,
812a0aab9e1SSrinivas Kandagatla WSA881X_BOOST_EN_MASK, 0);
813a0aab9e1SSrinivas Kandagatla /*
814a0aab9e1SSrinivas Kandagatla * 1.5ms sleep is needed after boost enable/disable as per
815a0aab9e1SSrinivas Kandagatla * HW requirement
816a0aab9e1SSrinivas Kandagatla */
817a0aab9e1SSrinivas Kandagatla usleep_range(1500, 1510);
818a0aab9e1SSrinivas Kandagatla return 0;
819a0aab9e1SSrinivas Kandagatla }
820a0aab9e1SSrinivas Kandagatla
wsa881x_set_port(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)821a0aab9e1SSrinivas Kandagatla static int wsa881x_set_port(struct snd_kcontrol *kcontrol,
822a0aab9e1SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
823a0aab9e1SSrinivas Kandagatla {
824a0aab9e1SSrinivas Kandagatla struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
825a0aab9e1SSrinivas Kandagatla struct wsa881x_priv *data = snd_soc_component_get_drvdata(comp);
826a0aab9e1SSrinivas Kandagatla struct soc_mixer_control *mixer =
827a0aab9e1SSrinivas Kandagatla (struct soc_mixer_control *)kcontrol->private_value;
828a0aab9e1SSrinivas Kandagatla int portidx = mixer->reg;
829a0aab9e1SSrinivas Kandagatla
8303fc27e9aSSrinivas Kandagatla if (ucontrol->value.integer.value[0]) {
8313fc27e9aSSrinivas Kandagatla if (data->port_enable[portidx])
8323fc27e9aSSrinivas Kandagatla return 0;
8333fc27e9aSSrinivas Kandagatla
834a0aab9e1SSrinivas Kandagatla data->port_enable[portidx] = true;
8353fc27e9aSSrinivas Kandagatla } else {
8363fc27e9aSSrinivas Kandagatla if (!data->port_enable[portidx])
8373fc27e9aSSrinivas Kandagatla return 0;
8383fc27e9aSSrinivas Kandagatla
839a0aab9e1SSrinivas Kandagatla data->port_enable[portidx] = false;
8403fc27e9aSSrinivas Kandagatla }
841a0aab9e1SSrinivas Kandagatla
842a0aab9e1SSrinivas Kandagatla if (portidx == WSA881X_PORT_BOOST) /* Boost Switch */
843a0aab9e1SSrinivas Kandagatla wsa881x_boost_ctrl(comp, data->port_enable[portidx]);
844a0aab9e1SSrinivas Kandagatla
8453fc27e9aSSrinivas Kandagatla return 1;
846a0aab9e1SSrinivas Kandagatla }
847a0aab9e1SSrinivas Kandagatla
848a0aab9e1SSrinivas Kandagatla static const char * const smart_boost_lvl_text[] = {
849a0aab9e1SSrinivas Kandagatla "6.625 V", "6.750 V", "6.875 V", "7.000 V",
850a0aab9e1SSrinivas Kandagatla "7.125 V", "7.250 V", "7.375 V", "7.500 V",
851a0aab9e1SSrinivas Kandagatla "7.625 V", "7.750 V", "7.875 V", "8.000 V",
852a0aab9e1SSrinivas Kandagatla "8.125 V", "8.250 V", "8.375 V", "8.500 V"
853a0aab9e1SSrinivas Kandagatla };
854a0aab9e1SSrinivas Kandagatla
855a0aab9e1SSrinivas Kandagatla static const struct soc_enum smart_boost_lvl_enum =
856a0aab9e1SSrinivas Kandagatla SOC_ENUM_SINGLE(WSA881X_BOOST_PRESET_OUT1, 0,
857a0aab9e1SSrinivas Kandagatla ARRAY_SIZE(smart_boost_lvl_text),
858a0aab9e1SSrinivas Kandagatla smart_boost_lvl_text);
859a0aab9e1SSrinivas Kandagatla
860a0aab9e1SSrinivas Kandagatla static const DECLARE_TLV_DB_SCALE(pa_gain, 0, 150, 0);
861a0aab9e1SSrinivas Kandagatla
862a0aab9e1SSrinivas Kandagatla static const struct snd_kcontrol_new wsa881x_snd_controls[] = {
863a0aab9e1SSrinivas Kandagatla SOC_ENUM("Smart Boost Level", smart_boost_lvl_enum),
864a0aab9e1SSrinivas Kandagatla WSA881X_PA_GAIN_TLV("PA Volume", WSA881X_SPKR_DRV_GAIN,
865a0aab9e1SSrinivas Kandagatla 4, 0xC, 1, pa_gain),
866a0aab9e1SSrinivas Kandagatla SOC_SINGLE_EXT("DAC Switch", WSA881X_PORT_DAC, 0, 1, 0,
867a0aab9e1SSrinivas Kandagatla wsa881x_get_port, wsa881x_set_port),
868a0aab9e1SSrinivas Kandagatla SOC_SINGLE_EXT("COMP Switch", WSA881X_PORT_COMP, 0, 1, 0,
869a0aab9e1SSrinivas Kandagatla wsa881x_get_port, wsa881x_set_port),
870a0aab9e1SSrinivas Kandagatla SOC_SINGLE_EXT("BOOST Switch", WSA881X_PORT_BOOST, 0, 1, 0,
871a0aab9e1SSrinivas Kandagatla wsa881x_get_port, wsa881x_set_port),
872a0aab9e1SSrinivas Kandagatla SOC_SINGLE_EXT("VISENSE Switch", WSA881X_PORT_VISENSE, 0, 1, 0,
873a0aab9e1SSrinivas Kandagatla wsa881x_get_port, wsa881x_set_port),
874a0aab9e1SSrinivas Kandagatla };
875a0aab9e1SSrinivas Kandagatla
876a0aab9e1SSrinivas Kandagatla static const struct snd_soc_dapm_route wsa881x_audio_map[] = {
877a0aab9e1SSrinivas Kandagatla { "RDAC", NULL, "IN" },
878a0aab9e1SSrinivas Kandagatla { "RDAC", NULL, "DCLK" },
879a0aab9e1SSrinivas Kandagatla { "RDAC", NULL, "ACLK" },
880a0aab9e1SSrinivas Kandagatla { "RDAC", NULL, "Bandgap" },
881a0aab9e1SSrinivas Kandagatla { "SPKR PGA", NULL, "RDAC" },
882a0aab9e1SSrinivas Kandagatla { "SPKR", NULL, "SPKR PGA" },
883a0aab9e1SSrinivas Kandagatla };
884a0aab9e1SSrinivas Kandagatla
wsa881x_visense_txfe_ctrl(struct snd_soc_component * comp,bool enable)885a0aab9e1SSrinivas Kandagatla static int wsa881x_visense_txfe_ctrl(struct snd_soc_component *comp,
886a0aab9e1SSrinivas Kandagatla bool enable)
887a0aab9e1SSrinivas Kandagatla {
888a0aab9e1SSrinivas Kandagatla struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(comp);
889a0aab9e1SSrinivas Kandagatla
890a0aab9e1SSrinivas Kandagatla if (enable) {
891a0aab9e1SSrinivas Kandagatla regmap_multi_reg_write(wsa881x->regmap, wsa881x_vi_txfe_en_2_0,
892a0aab9e1SSrinivas Kandagatla ARRAY_SIZE(wsa881x_vi_txfe_en_2_0));
893a0aab9e1SSrinivas Kandagatla } else {
894a0aab9e1SSrinivas Kandagatla snd_soc_component_update_bits(comp,
895a0aab9e1SSrinivas Kandagatla WSA881X_SPKR_PROT_FE_VSENSE_VCM,
896a0aab9e1SSrinivas Kandagatla 0x08, 0x08);
897a0aab9e1SSrinivas Kandagatla /*
898a0aab9e1SSrinivas Kandagatla * 200us sleep is needed after visense txfe disable as per
899a0aab9e1SSrinivas Kandagatla * HW requirement.
900a0aab9e1SSrinivas Kandagatla */
901a0aab9e1SSrinivas Kandagatla usleep_range(200, 210);
902a0aab9e1SSrinivas Kandagatla snd_soc_component_update_bits(comp, WSA881X_SPKR_PROT_FE_GAIN,
903a0aab9e1SSrinivas Kandagatla 0x01, 0x00);
904a0aab9e1SSrinivas Kandagatla }
905a0aab9e1SSrinivas Kandagatla return 0;
906a0aab9e1SSrinivas Kandagatla }
907a0aab9e1SSrinivas Kandagatla
wsa881x_visense_adc_ctrl(struct snd_soc_component * comp,bool enable)908a0aab9e1SSrinivas Kandagatla static int wsa881x_visense_adc_ctrl(struct snd_soc_component *comp,
909a0aab9e1SSrinivas Kandagatla bool enable)
910a0aab9e1SSrinivas Kandagatla {
911a0aab9e1SSrinivas Kandagatla snd_soc_component_update_bits(comp, WSA881X_ADC_EN_MODU_V, BIT(7),
912a0aab9e1SSrinivas Kandagatla (enable << 7));
913a0aab9e1SSrinivas Kandagatla snd_soc_component_update_bits(comp, WSA881X_ADC_EN_MODU_I, BIT(7),
914a0aab9e1SSrinivas Kandagatla (enable << 7));
915a0aab9e1SSrinivas Kandagatla return 0;
916a0aab9e1SSrinivas Kandagatla }
917a0aab9e1SSrinivas Kandagatla
wsa881x_spkr_pa_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)918a0aab9e1SSrinivas Kandagatla static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w,
919a0aab9e1SSrinivas Kandagatla struct snd_kcontrol *kcontrol, int event)
920a0aab9e1SSrinivas Kandagatla {
921a0aab9e1SSrinivas Kandagatla struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
922a0aab9e1SSrinivas Kandagatla struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(comp);
923a0aab9e1SSrinivas Kandagatla
924a0aab9e1SSrinivas Kandagatla switch (event) {
925a0aab9e1SSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
926a0aab9e1SSrinivas Kandagatla snd_soc_component_update_bits(comp, WSA881X_SPKR_OCP_CTL,
927a0aab9e1SSrinivas Kandagatla WSA881X_SPKR_OCP_MASK,
928a0aab9e1SSrinivas Kandagatla WSA881X_SPKR_OCP_EN);
929a0aab9e1SSrinivas Kandagatla regmap_multi_reg_write(wsa881x->regmap, wsa881x_pre_pmu_pa_2_0,
930a0aab9e1SSrinivas Kandagatla ARRAY_SIZE(wsa881x_pre_pmu_pa_2_0));
931a0aab9e1SSrinivas Kandagatla
932a0aab9e1SSrinivas Kandagatla snd_soc_component_update_bits(comp, WSA881X_SPKR_DRV_GAIN,
933a0aab9e1SSrinivas Kandagatla WSA881X_PA_GAIN_SEL_MASK,
934a0aab9e1SSrinivas Kandagatla WSA881X_PA_GAIN_SEL_REG);
935a0aab9e1SSrinivas Kandagatla break;
936a0aab9e1SSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
937a0aab9e1SSrinivas Kandagatla if (wsa881x->port_prepared[WSA881X_PORT_VISENSE]) {
938a0aab9e1SSrinivas Kandagatla wsa881x_visense_txfe_ctrl(comp, true);
939a0aab9e1SSrinivas Kandagatla snd_soc_component_update_bits(comp,
940a0aab9e1SSrinivas Kandagatla WSA881X_ADC_EN_SEL_IBAIS,
941a0aab9e1SSrinivas Kandagatla 0x07, 0x01);
942a0aab9e1SSrinivas Kandagatla wsa881x_visense_adc_ctrl(comp, true);
943a0aab9e1SSrinivas Kandagatla }
944a0aab9e1SSrinivas Kandagatla
945a0aab9e1SSrinivas Kandagatla break;
946a0aab9e1SSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
947a0aab9e1SSrinivas Kandagatla if (wsa881x->port_prepared[WSA881X_PORT_VISENSE]) {
948a0aab9e1SSrinivas Kandagatla wsa881x_visense_adc_ctrl(comp, false);
949a0aab9e1SSrinivas Kandagatla wsa881x_visense_txfe_ctrl(comp, false);
950a0aab9e1SSrinivas Kandagatla }
951a0aab9e1SSrinivas Kandagatla
952a0aab9e1SSrinivas Kandagatla snd_soc_component_update_bits(comp, WSA881X_SPKR_OCP_CTL,
953a0aab9e1SSrinivas Kandagatla WSA881X_SPKR_OCP_MASK,
954a0aab9e1SSrinivas Kandagatla WSA881X_SPKR_OCP_EN |
955a0aab9e1SSrinivas Kandagatla WSA881X_SPKR_OCP_HOLD);
956a0aab9e1SSrinivas Kandagatla break;
957a0aab9e1SSrinivas Kandagatla }
958a0aab9e1SSrinivas Kandagatla return 0;
959a0aab9e1SSrinivas Kandagatla }
960a0aab9e1SSrinivas Kandagatla
961a0aab9e1SSrinivas Kandagatla static const struct snd_soc_dapm_widget wsa881x_dapm_widgets[] = {
962a0aab9e1SSrinivas Kandagatla SND_SOC_DAPM_INPUT("IN"),
963a0aab9e1SSrinivas Kandagatla SND_SOC_DAPM_DAC_E("RDAC", NULL, WSA881X_SPKR_DAC_CTL, 7, 0,
964a0aab9e1SSrinivas Kandagatla NULL,
965a0aab9e1SSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
966a0aab9e1SSrinivas Kandagatla SND_SOC_DAPM_PGA_E("SPKR PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
967a0aab9e1SSrinivas Kandagatla wsa881x_spkr_pa_event, SND_SOC_DAPM_PRE_PMU |
968a0aab9e1SSrinivas Kandagatla SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
969a0aab9e1SSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("DCLK", WSA881X_CDC_DIG_CLK_CTL, 0, 0, NULL,
970a0aab9e1SSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
971a0aab9e1SSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("ACLK", WSA881X_CDC_ANA_CLK_CTL, 0, 0, NULL,
972a0aab9e1SSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
973a0aab9e1SSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("Bandgap", WSA881X_TEMP_OP, 3, 0,
974a0aab9e1SSrinivas Kandagatla NULL,
975a0aab9e1SSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
976a0aab9e1SSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("SPKR"),
977a0aab9e1SSrinivas Kandagatla };
978a0aab9e1SSrinivas Kandagatla
wsa881x_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)979a0aab9e1SSrinivas Kandagatla static int wsa881x_hw_params(struct snd_pcm_substream *substream,
980a0aab9e1SSrinivas Kandagatla struct snd_pcm_hw_params *params,
981a0aab9e1SSrinivas Kandagatla struct snd_soc_dai *dai)
982a0aab9e1SSrinivas Kandagatla {
983a0aab9e1SSrinivas Kandagatla struct wsa881x_priv *wsa881x = dev_get_drvdata(dai->dev);
984a0aab9e1SSrinivas Kandagatla int i;
985a0aab9e1SSrinivas Kandagatla
986a0aab9e1SSrinivas Kandagatla wsa881x->active_ports = 0;
987a0aab9e1SSrinivas Kandagatla for (i = 0; i < WSA881X_MAX_SWR_PORTS; i++) {
988a0aab9e1SSrinivas Kandagatla if (!wsa881x->port_enable[i])
989a0aab9e1SSrinivas Kandagatla continue;
990a0aab9e1SSrinivas Kandagatla
991a0aab9e1SSrinivas Kandagatla wsa881x->port_config[wsa881x->active_ports] =
992a0aab9e1SSrinivas Kandagatla wsa881x_pconfig[i];
993a0aab9e1SSrinivas Kandagatla wsa881x->active_ports++;
994a0aab9e1SSrinivas Kandagatla }
995a0aab9e1SSrinivas Kandagatla
996a0aab9e1SSrinivas Kandagatla return sdw_stream_add_slave(wsa881x->slave, &wsa881x->sconfig,
997a0aab9e1SSrinivas Kandagatla wsa881x->port_config, wsa881x->active_ports,
998a0aab9e1SSrinivas Kandagatla wsa881x->sruntime);
999a0aab9e1SSrinivas Kandagatla }
1000a0aab9e1SSrinivas Kandagatla
wsa881x_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)1001a0aab9e1SSrinivas Kandagatla static int wsa881x_hw_free(struct snd_pcm_substream *substream,
1002a0aab9e1SSrinivas Kandagatla struct snd_soc_dai *dai)
1003a0aab9e1SSrinivas Kandagatla {
1004a0aab9e1SSrinivas Kandagatla struct wsa881x_priv *wsa881x = dev_get_drvdata(dai->dev);
1005a0aab9e1SSrinivas Kandagatla
1006a0aab9e1SSrinivas Kandagatla sdw_stream_remove_slave(wsa881x->slave, wsa881x->sruntime);
1007a0aab9e1SSrinivas Kandagatla
1008a0aab9e1SSrinivas Kandagatla return 0;
1009a0aab9e1SSrinivas Kandagatla }
1010a0aab9e1SSrinivas Kandagatla
wsa881x_set_sdw_stream(struct snd_soc_dai * dai,void * stream,int direction)1011a0aab9e1SSrinivas Kandagatla static int wsa881x_set_sdw_stream(struct snd_soc_dai *dai,
1012a0aab9e1SSrinivas Kandagatla void *stream, int direction)
1013a0aab9e1SSrinivas Kandagatla {
1014a0aab9e1SSrinivas Kandagatla struct wsa881x_priv *wsa881x = dev_get_drvdata(dai->dev);
1015a0aab9e1SSrinivas Kandagatla
1016a0aab9e1SSrinivas Kandagatla wsa881x->sruntime = stream;
1017a0aab9e1SSrinivas Kandagatla
1018a0aab9e1SSrinivas Kandagatla return 0;
1019a0aab9e1SSrinivas Kandagatla }
1020a0aab9e1SSrinivas Kandagatla
wsa881x_digital_mute(struct snd_soc_dai * dai,int mute,int stream)1021a0aab9e1SSrinivas Kandagatla static int wsa881x_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
1022a0aab9e1SSrinivas Kandagatla {
1023a0aab9e1SSrinivas Kandagatla struct wsa881x_priv *wsa881x = dev_get_drvdata(dai->dev);
1024a0aab9e1SSrinivas Kandagatla
1025a0aab9e1SSrinivas Kandagatla if (mute)
1026a0aab9e1SSrinivas Kandagatla regmap_update_bits(wsa881x->regmap, WSA881X_SPKR_DRV_EN, 0x80,
1027a0aab9e1SSrinivas Kandagatla 0x00);
1028a0aab9e1SSrinivas Kandagatla else
1029a0aab9e1SSrinivas Kandagatla regmap_update_bits(wsa881x->regmap, WSA881X_SPKR_DRV_EN, 0x80,
1030a0aab9e1SSrinivas Kandagatla 0x80);
1031a0aab9e1SSrinivas Kandagatla
1032a0aab9e1SSrinivas Kandagatla return 0;
1033a0aab9e1SSrinivas Kandagatla }
1034a0aab9e1SSrinivas Kandagatla
1035f9858380SYe Bin static const struct snd_soc_dai_ops wsa881x_dai_ops = {
1036a0aab9e1SSrinivas Kandagatla .hw_params = wsa881x_hw_params,
1037a0aab9e1SSrinivas Kandagatla .hw_free = wsa881x_hw_free,
1038a0aab9e1SSrinivas Kandagatla .mute_stream = wsa881x_digital_mute,
1039e8444560SPierre-Louis Bossart .set_stream = wsa881x_set_sdw_stream,
1040a0aab9e1SSrinivas Kandagatla };
1041a0aab9e1SSrinivas Kandagatla
1042a0aab9e1SSrinivas Kandagatla static struct snd_soc_dai_driver wsa881x_dais[] = {
1043a0aab9e1SSrinivas Kandagatla {
1044a0aab9e1SSrinivas Kandagatla .name = "SPKR",
1045a0aab9e1SSrinivas Kandagatla .id = 0,
1046a0aab9e1SSrinivas Kandagatla .playback = {
1047a0aab9e1SSrinivas Kandagatla .stream_name = "SPKR Playback",
1048f47d0742SSrinivas Kandagatla .rates = SNDRV_PCM_RATE_48000,
1049f47d0742SSrinivas Kandagatla .formats = SNDRV_PCM_FMTBIT_S16_LE,
1050a0aab9e1SSrinivas Kandagatla .rate_max = 48000,
1051a0aab9e1SSrinivas Kandagatla .rate_min = 48000,
1052a0aab9e1SSrinivas Kandagatla .channels_min = 1,
1053a0aab9e1SSrinivas Kandagatla .channels_max = 1,
1054a0aab9e1SSrinivas Kandagatla },
1055a0aab9e1SSrinivas Kandagatla .ops = &wsa881x_dai_ops,
1056a0aab9e1SSrinivas Kandagatla },
1057a0aab9e1SSrinivas Kandagatla };
1058a0aab9e1SSrinivas Kandagatla
1059a0aab9e1SSrinivas Kandagatla static const struct snd_soc_component_driver wsa881x_component_drv = {
1060a0aab9e1SSrinivas Kandagatla .name = "WSA881x",
1061a0aab9e1SSrinivas Kandagatla .probe = wsa881x_component_probe,
1062a0aab9e1SSrinivas Kandagatla .controls = wsa881x_snd_controls,
1063a0aab9e1SSrinivas Kandagatla .num_controls = ARRAY_SIZE(wsa881x_snd_controls),
1064a0aab9e1SSrinivas Kandagatla .dapm_widgets = wsa881x_dapm_widgets,
1065a0aab9e1SSrinivas Kandagatla .num_dapm_widgets = ARRAY_SIZE(wsa881x_dapm_widgets),
1066a0aab9e1SSrinivas Kandagatla .dapm_routes = wsa881x_audio_map,
1067a0aab9e1SSrinivas Kandagatla .num_dapm_routes = ARRAY_SIZE(wsa881x_audio_map),
106896bc59d0SCharles Keepax .endianness = 1,
1069a0aab9e1SSrinivas Kandagatla };
1070a0aab9e1SSrinivas Kandagatla
wsa881x_update_status(struct sdw_slave * slave,enum sdw_slave_status status)1071a0aab9e1SSrinivas Kandagatla static int wsa881x_update_status(struct sdw_slave *slave,
1072a0aab9e1SSrinivas Kandagatla enum sdw_slave_status status)
1073a0aab9e1SSrinivas Kandagatla {
1074a0aab9e1SSrinivas Kandagatla struct wsa881x_priv *wsa881x = dev_get_drvdata(&slave->dev);
1075a0aab9e1SSrinivas Kandagatla
1076a0aab9e1SSrinivas Kandagatla if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0)
1077a0aab9e1SSrinivas Kandagatla wsa881x_init(wsa881x);
1078a0aab9e1SSrinivas Kandagatla
1079a0aab9e1SSrinivas Kandagatla return 0;
1080a0aab9e1SSrinivas Kandagatla }
1081a0aab9e1SSrinivas Kandagatla
wsa881x_port_prep(struct sdw_slave * slave,struct sdw_prepare_ch * prepare_ch,enum sdw_port_prep_ops state)1082a0aab9e1SSrinivas Kandagatla static int wsa881x_port_prep(struct sdw_slave *slave,
1083a0aab9e1SSrinivas Kandagatla struct sdw_prepare_ch *prepare_ch,
1084a0aab9e1SSrinivas Kandagatla enum sdw_port_prep_ops state)
1085a0aab9e1SSrinivas Kandagatla {
1086a0aab9e1SSrinivas Kandagatla struct wsa881x_priv *wsa881x = dev_get_drvdata(&slave->dev);
1087a0aab9e1SSrinivas Kandagatla
1088a0aab9e1SSrinivas Kandagatla if (state == SDW_OPS_PORT_POST_PREP)
1089a0aab9e1SSrinivas Kandagatla wsa881x->port_prepared[prepare_ch->num - 1] = true;
1090a0aab9e1SSrinivas Kandagatla else
1091a0aab9e1SSrinivas Kandagatla wsa881x->port_prepared[prepare_ch->num - 1] = false;
1092a0aab9e1SSrinivas Kandagatla
1093a0aab9e1SSrinivas Kandagatla return 0;
1094a0aab9e1SSrinivas Kandagatla }
1095a0aab9e1SSrinivas Kandagatla
wsa881x_bus_config(struct sdw_slave * slave,struct sdw_bus_params * params)1096a0aab9e1SSrinivas Kandagatla static int wsa881x_bus_config(struct sdw_slave *slave,
1097a0aab9e1SSrinivas Kandagatla struct sdw_bus_params *params)
1098a0aab9e1SSrinivas Kandagatla {
1099a0aab9e1SSrinivas Kandagatla sdw_write(slave, SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(params->next_bank),
1100a0aab9e1SSrinivas Kandagatla 0x01);
1101a0aab9e1SSrinivas Kandagatla
1102a0aab9e1SSrinivas Kandagatla return 0;
1103a0aab9e1SSrinivas Kandagatla }
1104a0aab9e1SSrinivas Kandagatla
110565b7b869SKrzysztof Kozlowski static const struct sdw_slave_ops wsa881x_slave_ops = {
1106a0aab9e1SSrinivas Kandagatla .update_status = wsa881x_update_status,
1107a0aab9e1SSrinivas Kandagatla .bus_config = wsa881x_bus_config,
1108a0aab9e1SSrinivas Kandagatla .port_prep = wsa881x_port_prep,
1109a0aab9e1SSrinivas Kandagatla };
1110a0aab9e1SSrinivas Kandagatla
wsa881x_probe(struct sdw_slave * pdev,const struct sdw_device_id * id)1111a0aab9e1SSrinivas Kandagatla static int wsa881x_probe(struct sdw_slave *pdev,
1112a0aab9e1SSrinivas Kandagatla const struct sdw_device_id *id)
1113a0aab9e1SSrinivas Kandagatla {
1114a0aab9e1SSrinivas Kandagatla struct wsa881x_priv *wsa881x;
11158dd55245SSrinivas Kandagatla struct device *dev = &pdev->dev;
1116a0aab9e1SSrinivas Kandagatla
1117c617c9e7SKrzysztof Kozlowski wsa881x = devm_kzalloc(dev, sizeof(*wsa881x), GFP_KERNEL);
1118a0aab9e1SSrinivas Kandagatla if (!wsa881x)
1119a0aab9e1SSrinivas Kandagatla return -ENOMEM;
1120a0aab9e1SSrinivas Kandagatla
1121c617c9e7SKrzysztof Kozlowski wsa881x->sd_n = devm_gpiod_get_optional(dev, "powerdown",
1122a0aab9e1SSrinivas Kandagatla GPIOD_FLAGS_BIT_NONEXCLUSIVE);
112331a90367SKrzysztof Kozlowski if (IS_ERR(wsa881x->sd_n))
112431a90367SKrzysztof Kozlowski return dev_err_probe(dev, PTR_ERR(wsa881x->sd_n),
112531a90367SKrzysztof Kozlowski "Shutdown Control GPIO not found\n");
1126a0aab9e1SSrinivas Kandagatla
112773845585SKrzysztof Kozlowski /*
112873845585SKrzysztof Kozlowski * Backwards compatibility work-around.
112973845585SKrzysztof Kozlowski *
113073845585SKrzysztof Kozlowski * The SD_N GPIO is active low, however upstream DTS used always active
113173845585SKrzysztof Kozlowski * high. Changing the flag in driver and DTS will break backwards
113273845585SKrzysztof Kozlowski * compatibility, so add a simple value inversion to work with both old
113373845585SKrzysztof Kozlowski * and new DTS.
113473845585SKrzysztof Kozlowski *
113573845585SKrzysztof Kozlowski * This won't work properly with DTS using the flags properly in cases:
113673845585SKrzysztof Kozlowski * 1. Old DTS with proper ACTIVE_LOW, however such case was broken
113773845585SKrzysztof Kozlowski * before as the driver required the active high.
113873845585SKrzysztof Kozlowski * 2. New DTS with proper ACTIVE_HIGH (intended), which is rare case
113973845585SKrzysztof Kozlowski * (not existing upstream) but possible. This is the price of
114073845585SKrzysztof Kozlowski * backwards compatibility, therefore this hack should be removed at
114173845585SKrzysztof Kozlowski * some point.
114273845585SKrzysztof Kozlowski */
114373845585SKrzysztof Kozlowski wsa881x->sd_n_val = gpiod_is_active_low(wsa881x->sd_n);
114473845585SKrzysztof Kozlowski if (!wsa881x->sd_n_val)
114573845585SKrzysztof Kozlowski dev_warn(dev, "Using ACTIVE_HIGH for shutdown GPIO. Your DTB might be outdated or you use unsupported configuration for the GPIO.");
114673845585SKrzysztof Kozlowski
1147c617c9e7SKrzysztof Kozlowski dev_set_drvdata(dev, wsa881x);
1148a0aab9e1SSrinivas Kandagatla wsa881x->slave = pdev;
1149c617c9e7SKrzysztof Kozlowski wsa881x->dev = dev;
1150a0aab9e1SSrinivas Kandagatla wsa881x->sconfig.ch_count = 1;
1151a0aab9e1SSrinivas Kandagatla wsa881x->sconfig.bps = 1;
1152a0aab9e1SSrinivas Kandagatla wsa881x->sconfig.frame_rate = 48000;
1153a0aab9e1SSrinivas Kandagatla wsa881x->sconfig.direction = SDW_DATA_DIR_RX;
1154a0aab9e1SSrinivas Kandagatla wsa881x->sconfig.type = SDW_STREAM_PDM;
1155*f4bbf2f2SKrzysztof Kozlowski pdev->prop.sink_ports = GENMASK(WSA881X_MAX_SWR_PORTS - 1, 0);
1156a0aab9e1SSrinivas Kandagatla pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop;
11572acd30b9SPierre-Louis Bossart pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
115827f69caaSSrinivas Kandagatla pdev->prop.clk_stop_mode1 = true;
115973845585SKrzysztof Kozlowski gpiod_direction_output(wsa881x->sd_n, !wsa881x->sd_n_val);
1160a0aab9e1SSrinivas Kandagatla
1161a0aab9e1SSrinivas Kandagatla wsa881x->regmap = devm_regmap_init_sdw(pdev, &wsa881x_regmap_config);
116231a90367SKrzysztof Kozlowski if (IS_ERR(wsa881x->regmap))
116331a90367SKrzysztof Kozlowski return dev_err_probe(dev, PTR_ERR(wsa881x->regmap), "regmap_init failed\n");
1164a0aab9e1SSrinivas Kandagatla
11658dd55245SSrinivas Kandagatla pm_runtime_set_autosuspend_delay(dev, 3000);
11668dd55245SSrinivas Kandagatla pm_runtime_use_autosuspend(dev);
11678dd55245SSrinivas Kandagatla pm_runtime_mark_last_busy(dev);
11688dd55245SSrinivas Kandagatla pm_runtime_set_active(dev);
11698dd55245SSrinivas Kandagatla pm_runtime_enable(dev);
11708dd55245SSrinivas Kandagatla
1171c617c9e7SKrzysztof Kozlowski return devm_snd_soc_register_component(dev,
1172a0aab9e1SSrinivas Kandagatla &wsa881x_component_drv,
1173a0aab9e1SSrinivas Kandagatla wsa881x_dais,
1174a0aab9e1SSrinivas Kandagatla ARRAY_SIZE(wsa881x_dais));
1175a0aab9e1SSrinivas Kandagatla }
1176a0aab9e1SSrinivas Kandagatla
wsa881x_runtime_suspend(struct device * dev)11778dd55245SSrinivas Kandagatla static int __maybe_unused wsa881x_runtime_suspend(struct device *dev)
11788dd55245SSrinivas Kandagatla {
11798dd55245SSrinivas Kandagatla struct regmap *regmap = dev_get_regmap(dev, NULL);
11808dd55245SSrinivas Kandagatla struct wsa881x_priv *wsa881x = dev_get_drvdata(dev);
11818dd55245SSrinivas Kandagatla
118273845585SKrzysztof Kozlowski gpiod_direction_output(wsa881x->sd_n, wsa881x->sd_n_val);
11838dd55245SSrinivas Kandagatla
11848dd55245SSrinivas Kandagatla regcache_cache_only(regmap, true);
11858dd55245SSrinivas Kandagatla regcache_mark_dirty(regmap);
11868dd55245SSrinivas Kandagatla
11878dd55245SSrinivas Kandagatla return 0;
11888dd55245SSrinivas Kandagatla }
11898dd55245SSrinivas Kandagatla
wsa881x_runtime_resume(struct device * dev)11908dd55245SSrinivas Kandagatla static int __maybe_unused wsa881x_runtime_resume(struct device *dev)
11918dd55245SSrinivas Kandagatla {
11928dd55245SSrinivas Kandagatla struct sdw_slave *slave = dev_to_sdw_dev(dev);
11938dd55245SSrinivas Kandagatla struct regmap *regmap = dev_get_regmap(dev, NULL);
11948dd55245SSrinivas Kandagatla struct wsa881x_priv *wsa881x = dev_get_drvdata(dev);
1195cf6af24bSSrinivas Kandagatla unsigned long time;
11968dd55245SSrinivas Kandagatla
119773845585SKrzysztof Kozlowski gpiod_direction_output(wsa881x->sd_n, !wsa881x->sd_n_val);
11988dd55245SSrinivas Kandagatla
1199cf6af24bSSrinivas Kandagatla time = wait_for_completion_timeout(&slave->initialization_complete,
12008dd55245SSrinivas Kandagatla msecs_to_jiffies(WSA881X_PROBE_TIMEOUT));
1201cf6af24bSSrinivas Kandagatla if (!time) {
1202cf6af24bSSrinivas Kandagatla dev_err(dev, "Initialization not complete, timed out\n");
120373845585SKrzysztof Kozlowski gpiod_direction_output(wsa881x->sd_n, wsa881x->sd_n_val);
1204cf6af24bSSrinivas Kandagatla return -ETIMEDOUT;
1205cf6af24bSSrinivas Kandagatla }
12068dd55245SSrinivas Kandagatla
12078dd55245SSrinivas Kandagatla regcache_cache_only(regmap, false);
12088dd55245SSrinivas Kandagatla regcache_sync(regmap);
12098dd55245SSrinivas Kandagatla
12108dd55245SSrinivas Kandagatla return 0;
12118dd55245SSrinivas Kandagatla }
12128dd55245SSrinivas Kandagatla
12138dd55245SSrinivas Kandagatla static const struct dev_pm_ops wsa881x_pm_ops = {
12148dd55245SSrinivas Kandagatla SET_RUNTIME_PM_OPS(wsa881x_runtime_suspend, wsa881x_runtime_resume, NULL)
12158dd55245SSrinivas Kandagatla };
12168dd55245SSrinivas Kandagatla
1217a0aab9e1SSrinivas Kandagatla static const struct sdw_device_id wsa881x_slave_id[] = {
1218a0aab9e1SSrinivas Kandagatla SDW_SLAVE_ENTRY(0x0217, 0x2010, 0),
1219a0aab9e1SSrinivas Kandagatla SDW_SLAVE_ENTRY(0x0217, 0x2110, 0),
1220a0aab9e1SSrinivas Kandagatla {},
1221a0aab9e1SSrinivas Kandagatla };
1222a0aab9e1SSrinivas Kandagatla MODULE_DEVICE_TABLE(sdw, wsa881x_slave_id);
1223a0aab9e1SSrinivas Kandagatla
1224a0aab9e1SSrinivas Kandagatla static struct sdw_driver wsa881x_codec_driver = {
1225a0aab9e1SSrinivas Kandagatla .probe = wsa881x_probe,
1226a0aab9e1SSrinivas Kandagatla .ops = &wsa881x_slave_ops,
1227a0aab9e1SSrinivas Kandagatla .id_table = wsa881x_slave_id,
1228a0aab9e1SSrinivas Kandagatla .driver = {
1229a0aab9e1SSrinivas Kandagatla .name = "wsa881x-codec",
12308dd55245SSrinivas Kandagatla .pm = &wsa881x_pm_ops,
1231a0aab9e1SSrinivas Kandagatla }
1232a0aab9e1SSrinivas Kandagatla };
1233a0aab9e1SSrinivas Kandagatla module_sdw_driver(wsa881x_codec_driver);
1234a0aab9e1SSrinivas Kandagatla
1235a0aab9e1SSrinivas Kandagatla MODULE_DESCRIPTION("WSA881x codec driver");
1236a0aab9e1SSrinivas Kandagatla MODULE_LICENSE("GPL v2");
1237