xref: /openbmc/linux/sound/soc/codecs/rt711-sdw.c (revision 320b8b0d13b81f3697acff5b6ddb47f88a09c118)
1*320b8b0dSShuming Fan // SPDX-License-Identifier: GPL-2.0
2*320b8b0dSShuming Fan //
3*320b8b0dSShuming Fan // rt711-sdw.c -- rt711 ALSA SoC audio driver
4*320b8b0dSShuming Fan //
5*320b8b0dSShuming Fan // Copyright(c) 2019 Realtek Semiconductor Corp.
6*320b8b0dSShuming Fan //
7*320b8b0dSShuming Fan //
8*320b8b0dSShuming Fan 
9*320b8b0dSShuming Fan #include <linux/delay.h>
10*320b8b0dSShuming Fan #include <linux/device.h>
11*320b8b0dSShuming Fan #include <linux/mod_devicetable.h>
12*320b8b0dSShuming Fan #include <linux/soundwire/sdw.h>
13*320b8b0dSShuming Fan #include <linux/soundwire/sdw_type.h>
14*320b8b0dSShuming Fan #include <linux/module.h>
15*320b8b0dSShuming Fan #include <linux/regmap.h>
16*320b8b0dSShuming Fan #include <sound/soc.h>
17*320b8b0dSShuming Fan #include "rt711.h"
18*320b8b0dSShuming Fan #include "rt711-sdw.h"
19*320b8b0dSShuming Fan 
20*320b8b0dSShuming Fan static bool rt711_readable_register(struct device *dev, unsigned int reg)
21*320b8b0dSShuming Fan {
22*320b8b0dSShuming Fan 	switch (reg) {
23*320b8b0dSShuming Fan 	case 0x00e0:
24*320b8b0dSShuming Fan 	case 0x00f0:
25*320b8b0dSShuming Fan 	case 0x2012 ... 0x2016:
26*320b8b0dSShuming Fan 	case 0x201a ... 0x2027:
27*320b8b0dSShuming Fan 	case 0x2029 ... 0x202a:
28*320b8b0dSShuming Fan 	case 0x202d ... 0x2034:
29*320b8b0dSShuming Fan 	case 0x2201 ... 0x2204:
30*320b8b0dSShuming Fan 	case 0x2206 ... 0x2212:
31*320b8b0dSShuming Fan 	case 0x2220 ... 0x2223:
32*320b8b0dSShuming Fan 	case 0x2230 ... 0x2239:
33*320b8b0dSShuming Fan 	case 0x2f01 ... 0x2f0f:
34*320b8b0dSShuming Fan 	case 0x3000 ... 0x3fff:
35*320b8b0dSShuming Fan 	case 0x7000 ... 0x7fff:
36*320b8b0dSShuming Fan 	case 0x8300 ... 0x83ff:
37*320b8b0dSShuming Fan 	case 0x9c00 ... 0x9cff:
38*320b8b0dSShuming Fan 	case 0xb900 ... 0xb9ff:
39*320b8b0dSShuming Fan 	case 0x752009:
40*320b8b0dSShuming Fan 	case 0x752011:
41*320b8b0dSShuming Fan 	case 0x75201a:
42*320b8b0dSShuming Fan 	case 0x752045:
43*320b8b0dSShuming Fan 	case 0x752046:
44*320b8b0dSShuming Fan 	case 0x752048:
45*320b8b0dSShuming Fan 	case 0x75204a:
46*320b8b0dSShuming Fan 	case 0x75206b:
47*320b8b0dSShuming Fan 	case 0x75206f:
48*320b8b0dSShuming Fan 	case 0x752080:
49*320b8b0dSShuming Fan 	case 0x752081:
50*320b8b0dSShuming Fan 	case 0x752091:
51*320b8b0dSShuming Fan 	case 0x755800:
52*320b8b0dSShuming Fan 		return true;
53*320b8b0dSShuming Fan 	default:
54*320b8b0dSShuming Fan 		return false;
55*320b8b0dSShuming Fan 	}
56*320b8b0dSShuming Fan }
57*320b8b0dSShuming Fan 
58*320b8b0dSShuming Fan static bool rt711_volatile_register(struct device *dev, unsigned int reg)
59*320b8b0dSShuming Fan {
60*320b8b0dSShuming Fan 	switch (reg) {
61*320b8b0dSShuming Fan 	case 0x2016:
62*320b8b0dSShuming Fan 	case 0x201b:
63*320b8b0dSShuming Fan 	case 0x201c:
64*320b8b0dSShuming Fan 	case 0x201d:
65*320b8b0dSShuming Fan 	case 0x201f:
66*320b8b0dSShuming Fan 	case 0x2021:
67*320b8b0dSShuming Fan 	case 0x2023:
68*320b8b0dSShuming Fan 	case 0x2230:
69*320b8b0dSShuming Fan 	case 0x2012 ... 0x2015: /* HD-A read */
70*320b8b0dSShuming Fan 	case 0x202d ... 0x202f: /* BRA */
71*320b8b0dSShuming Fan 	case 0x2201 ... 0x2212: /* i2c debug */
72*320b8b0dSShuming Fan 	case 0x2220 ... 0x2223: /* decoded HD-A */
73*320b8b0dSShuming Fan 	case 0x9c00 ... 0x9cff:
74*320b8b0dSShuming Fan 	case 0xb900 ... 0xb9ff:
75*320b8b0dSShuming Fan 	case 0xff01:
76*320b8b0dSShuming Fan 	case 0x75201a:
77*320b8b0dSShuming Fan 	case 0x752046:
78*320b8b0dSShuming Fan 	case 0x752080:
79*320b8b0dSShuming Fan 	case 0x752081:
80*320b8b0dSShuming Fan 	case 0x755800:
81*320b8b0dSShuming Fan 		return true;
82*320b8b0dSShuming Fan 	default:
83*320b8b0dSShuming Fan 		return false;
84*320b8b0dSShuming Fan 	}
85*320b8b0dSShuming Fan }
86*320b8b0dSShuming Fan 
87*320b8b0dSShuming Fan static int rt711_sdw_read(void *context, unsigned int reg, unsigned int *val)
88*320b8b0dSShuming Fan {
89*320b8b0dSShuming Fan 	struct device *dev = context;
90*320b8b0dSShuming Fan 	struct rt711_priv *rt711 = dev_get_drvdata(dev);
91*320b8b0dSShuming Fan 	unsigned int sdw_data_3, sdw_data_2, sdw_data_1, sdw_data_0;
92*320b8b0dSShuming Fan 	unsigned int reg2 = 0, reg3 = 0, reg4 = 0, mask, nid, val2;
93*320b8b0dSShuming Fan 	unsigned int is_hda_reg = 1, is_index_reg = 0;
94*320b8b0dSShuming Fan 	int ret;
95*320b8b0dSShuming Fan 
96*320b8b0dSShuming Fan 	if (reg > 0xffff)
97*320b8b0dSShuming Fan 		is_index_reg = 1;
98*320b8b0dSShuming Fan 
99*320b8b0dSShuming Fan 	mask = reg & 0xf000;
100*320b8b0dSShuming Fan 
101*320b8b0dSShuming Fan 	if (is_index_reg) { /* index registers */
102*320b8b0dSShuming Fan 		val2 = reg & 0xff;
103*320b8b0dSShuming Fan 		reg = reg >> 8;
104*320b8b0dSShuming Fan 		nid = reg & 0xff;
105*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg, 0);
106*320b8b0dSShuming Fan 		if (ret < 0)
107*320b8b0dSShuming Fan 			return ret;
108*320b8b0dSShuming Fan 		reg2 = reg + 0x1000;
109*320b8b0dSShuming Fan 		reg2 |= 0x80;
110*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg2, val2);
111*320b8b0dSShuming Fan 		if (ret < 0)
112*320b8b0dSShuming Fan 			return ret;
113*320b8b0dSShuming Fan 
114*320b8b0dSShuming Fan 		reg3 = RT711_PRIV_DATA_R_H | nid;
115*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap,
116*320b8b0dSShuming Fan 			reg3, ((*val >> 8) & 0xff));
117*320b8b0dSShuming Fan 		if (ret < 0)
118*320b8b0dSShuming Fan 			return ret;
119*320b8b0dSShuming Fan 		reg4 = reg3 + 0x1000;
120*320b8b0dSShuming Fan 		reg4 |= 0x80;
121*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg4, (*val & 0xff));
122*320b8b0dSShuming Fan 		if (ret < 0)
123*320b8b0dSShuming Fan 			return ret;
124*320b8b0dSShuming Fan 	} else if (mask   == 0x3000) {
125*320b8b0dSShuming Fan 		reg += 0x8000;
126*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg, *val);
127*320b8b0dSShuming Fan 		if (ret < 0)
128*320b8b0dSShuming Fan 			return ret;
129*320b8b0dSShuming Fan 	} else if (mask == 0x7000) {
130*320b8b0dSShuming Fan 		reg += 0x2000;
131*320b8b0dSShuming Fan 		reg |= 0x800;
132*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap,
133*320b8b0dSShuming Fan 			reg, ((*val >> 8) & 0xff));
134*320b8b0dSShuming Fan 		if (ret < 0)
135*320b8b0dSShuming Fan 			return ret;
136*320b8b0dSShuming Fan 		reg2 = reg + 0x1000;
137*320b8b0dSShuming Fan 		reg2 |= 0x80;
138*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg2, (*val & 0xff));
139*320b8b0dSShuming Fan 		if (ret < 0)
140*320b8b0dSShuming Fan 			return ret;
141*320b8b0dSShuming Fan 	} else if ((reg & 0xff00) == 0x8300) { /* for R channel */
142*320b8b0dSShuming Fan 		reg2 = reg - 0x1000;
143*320b8b0dSShuming Fan 		reg2 &= ~0x80;
144*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap,
145*320b8b0dSShuming Fan 			reg2, ((*val >> 8) & 0xff));
146*320b8b0dSShuming Fan 		if (ret < 0)
147*320b8b0dSShuming Fan 			return ret;
148*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg, (*val & 0xff));
149*320b8b0dSShuming Fan 		if (ret < 0)
150*320b8b0dSShuming Fan 			return ret;
151*320b8b0dSShuming Fan 	} else if (mask == 0x9000) {
152*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap,
153*320b8b0dSShuming Fan 			reg, ((*val >> 8) & 0xff));
154*320b8b0dSShuming Fan 		if (ret < 0)
155*320b8b0dSShuming Fan 			return ret;
156*320b8b0dSShuming Fan 		reg2 = reg + 0x1000;
157*320b8b0dSShuming Fan 		reg2 |= 0x80;
158*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg2, (*val & 0xff));
159*320b8b0dSShuming Fan 		if (ret < 0)
160*320b8b0dSShuming Fan 			return ret;
161*320b8b0dSShuming Fan 	} else if (mask == 0xb000) {
162*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg, *val);
163*320b8b0dSShuming Fan 		if (ret < 0)
164*320b8b0dSShuming Fan 			return ret;
165*320b8b0dSShuming Fan 	} else {
166*320b8b0dSShuming Fan 		ret = regmap_read(rt711->sdw_regmap, reg, val);
167*320b8b0dSShuming Fan 		if (ret < 0)
168*320b8b0dSShuming Fan 			return ret;
169*320b8b0dSShuming Fan 		is_hda_reg = 0;
170*320b8b0dSShuming Fan 	}
171*320b8b0dSShuming Fan 
172*320b8b0dSShuming Fan 	if (is_hda_reg || is_index_reg) {
173*320b8b0dSShuming Fan 		sdw_data_3 = 0;
174*320b8b0dSShuming Fan 		sdw_data_2 = 0;
175*320b8b0dSShuming Fan 		sdw_data_1 = 0;
176*320b8b0dSShuming Fan 		sdw_data_0 = 0;
177*320b8b0dSShuming Fan 		ret = regmap_read(rt711->sdw_regmap,
178*320b8b0dSShuming Fan 			RT711_READ_HDA_3, &sdw_data_3);
179*320b8b0dSShuming Fan 		if (ret < 0)
180*320b8b0dSShuming Fan 			return ret;
181*320b8b0dSShuming Fan 		ret = regmap_read(rt711->sdw_regmap,
182*320b8b0dSShuming Fan 			RT711_READ_HDA_2, &sdw_data_2);
183*320b8b0dSShuming Fan 		if (ret < 0)
184*320b8b0dSShuming Fan 			return ret;
185*320b8b0dSShuming Fan 		ret = regmap_read(rt711->sdw_regmap,
186*320b8b0dSShuming Fan 			RT711_READ_HDA_1, &sdw_data_1);
187*320b8b0dSShuming Fan 		if (ret < 0)
188*320b8b0dSShuming Fan 			return ret;
189*320b8b0dSShuming Fan 		ret = regmap_read(rt711->sdw_regmap,
190*320b8b0dSShuming Fan 			RT711_READ_HDA_0, &sdw_data_0);
191*320b8b0dSShuming Fan 		if (ret < 0)
192*320b8b0dSShuming Fan 			return ret;
193*320b8b0dSShuming Fan 		*val = ((sdw_data_3 & 0xff) << 24) |
194*320b8b0dSShuming Fan 			((sdw_data_2 & 0xff) << 16) |
195*320b8b0dSShuming Fan 			((sdw_data_1 & 0xff) << 8) | (sdw_data_0 & 0xff);
196*320b8b0dSShuming Fan 	}
197*320b8b0dSShuming Fan 
198*320b8b0dSShuming Fan 	if (is_hda_reg == 0)
199*320b8b0dSShuming Fan 		dev_dbg(dev, "[%s] %04x => %08x\n", __func__, reg, *val);
200*320b8b0dSShuming Fan 	else if (is_index_reg)
201*320b8b0dSShuming Fan 		dev_dbg(dev, "[%s] %04x %04x %04x %04x => %08x\n",
202*320b8b0dSShuming Fan 			__func__, reg, reg2, reg3, reg4, *val);
203*320b8b0dSShuming Fan 	else
204*320b8b0dSShuming Fan 		dev_dbg(dev, "[%s] %04x %04x => %08x\n",
205*320b8b0dSShuming Fan 			__func__, reg, reg2, *val);
206*320b8b0dSShuming Fan 
207*320b8b0dSShuming Fan 	return 0;
208*320b8b0dSShuming Fan }
209*320b8b0dSShuming Fan 
210*320b8b0dSShuming Fan static int rt711_sdw_write(void *context, unsigned int reg, unsigned int val)
211*320b8b0dSShuming Fan {
212*320b8b0dSShuming Fan 	struct device *dev = context;
213*320b8b0dSShuming Fan 	struct rt711_priv *rt711 = dev_get_drvdata(dev);
214*320b8b0dSShuming Fan 	unsigned int reg2 = 0, reg3, reg4, nid, mask, val2;
215*320b8b0dSShuming Fan 	unsigned int is_index_reg = 0;
216*320b8b0dSShuming Fan 	int ret;
217*320b8b0dSShuming Fan 
218*320b8b0dSShuming Fan 	if (reg > 0xffff)
219*320b8b0dSShuming Fan 		is_index_reg = 1;
220*320b8b0dSShuming Fan 
221*320b8b0dSShuming Fan 	mask = reg & 0xf000;
222*320b8b0dSShuming Fan 
223*320b8b0dSShuming Fan 	if (is_index_reg) { /* index registers */
224*320b8b0dSShuming Fan 		val2 = reg & 0xff;
225*320b8b0dSShuming Fan 		reg = reg >> 8;
226*320b8b0dSShuming Fan 		nid = reg & 0xff;
227*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg, 0);
228*320b8b0dSShuming Fan 		if (ret < 0)
229*320b8b0dSShuming Fan 			return ret;
230*320b8b0dSShuming Fan 		reg2 = reg + 0x1000;
231*320b8b0dSShuming Fan 		reg2 |= 0x80;
232*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg2, val2);
233*320b8b0dSShuming Fan 		if (ret < 0)
234*320b8b0dSShuming Fan 			return ret;
235*320b8b0dSShuming Fan 
236*320b8b0dSShuming Fan 		reg3 = RT711_PRIV_DATA_W_H | nid;
237*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap,
238*320b8b0dSShuming Fan 			reg3, ((val >> 8) & 0xff));
239*320b8b0dSShuming Fan 		if (ret < 0)
240*320b8b0dSShuming Fan 			return ret;
241*320b8b0dSShuming Fan 		reg4 = reg3 + 0x1000;
242*320b8b0dSShuming Fan 		reg4 |= 0x80;
243*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg4, (val & 0xff));
244*320b8b0dSShuming Fan 		if (ret < 0)
245*320b8b0dSShuming Fan 			return ret;
246*320b8b0dSShuming Fan 		is_index_reg = 1;
247*320b8b0dSShuming Fan 	} else if (reg < 0x4fff) {
248*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg, val);
249*320b8b0dSShuming Fan 		if (ret < 0)
250*320b8b0dSShuming Fan 			return ret;
251*320b8b0dSShuming Fan 	} else if (reg == RT711_FUNC_RESET) {
252*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg, val);
253*320b8b0dSShuming Fan 		if (ret < 0)
254*320b8b0dSShuming Fan 			return ret;
255*320b8b0dSShuming Fan 	} else if (mask == 0x7000) {
256*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap,
257*320b8b0dSShuming Fan 			reg, ((val >> 8) & 0xff));
258*320b8b0dSShuming Fan 		if (ret < 0)
259*320b8b0dSShuming Fan 			return ret;
260*320b8b0dSShuming Fan 		reg2 = reg + 0x1000;
261*320b8b0dSShuming Fan 		reg2 |= 0x80;
262*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg2, (val & 0xff));
263*320b8b0dSShuming Fan 		if (ret < 0)
264*320b8b0dSShuming Fan 			return ret;
265*320b8b0dSShuming Fan 	} else if ((reg & 0xff00) == 0x8300) {  /* for R channel */
266*320b8b0dSShuming Fan 		reg2 = reg - 0x1000;
267*320b8b0dSShuming Fan 		reg2 &= ~0x80;
268*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap,
269*320b8b0dSShuming Fan 			reg2, ((val >> 8) & 0xff));
270*320b8b0dSShuming Fan 		if (ret < 0)
271*320b8b0dSShuming Fan 			return ret;
272*320b8b0dSShuming Fan 		ret = regmap_write(rt711->sdw_regmap, reg, (val & 0xff));
273*320b8b0dSShuming Fan 		if (ret < 0)
274*320b8b0dSShuming Fan 			return ret;
275*320b8b0dSShuming Fan 	}
276*320b8b0dSShuming Fan 
277*320b8b0dSShuming Fan 	if (reg2 == 0)
278*320b8b0dSShuming Fan 		dev_dbg(dev, "[%s] %04x <= %04x\n", __func__, reg, val);
279*320b8b0dSShuming Fan 	else if (is_index_reg)
280*320b8b0dSShuming Fan 		dev_dbg(dev, "[%s] %04x %04x %04x %04x <= %04x %04x\n",
281*320b8b0dSShuming Fan 			__func__, reg, reg2, reg3, reg4, val2, val);
282*320b8b0dSShuming Fan 	else
283*320b8b0dSShuming Fan 		dev_dbg(dev, "[%s] %04x %04x <= %04x\n",
284*320b8b0dSShuming Fan 			__func__, reg, reg2, val);
285*320b8b0dSShuming Fan 
286*320b8b0dSShuming Fan 	return 0;
287*320b8b0dSShuming Fan }
288*320b8b0dSShuming Fan 
289*320b8b0dSShuming Fan static const struct regmap_config rt711_regmap = {
290*320b8b0dSShuming Fan 	.reg_bits = 24,
291*320b8b0dSShuming Fan 	.val_bits = 32,
292*320b8b0dSShuming Fan 	.readable_reg = rt711_readable_register,
293*320b8b0dSShuming Fan 	.volatile_reg = rt711_volatile_register,
294*320b8b0dSShuming Fan 	.max_register = 0x755800,
295*320b8b0dSShuming Fan 	.reg_defaults = rt711_reg_defaults,
296*320b8b0dSShuming Fan 	.num_reg_defaults = ARRAY_SIZE(rt711_reg_defaults),
297*320b8b0dSShuming Fan 	.cache_type = REGCACHE_RBTREE,
298*320b8b0dSShuming Fan 	.use_single_read = true,
299*320b8b0dSShuming Fan 	.use_single_write = true,
300*320b8b0dSShuming Fan 	.reg_read = rt711_sdw_read,
301*320b8b0dSShuming Fan 	.reg_write = rt711_sdw_write,
302*320b8b0dSShuming Fan };
303*320b8b0dSShuming Fan 
304*320b8b0dSShuming Fan static const struct regmap_config rt711_sdw_regmap = {
305*320b8b0dSShuming Fan 	.name = "sdw",
306*320b8b0dSShuming Fan 	.reg_bits = 32,
307*320b8b0dSShuming Fan 	.val_bits = 8,
308*320b8b0dSShuming Fan 	.readable_reg = rt711_readable_register,
309*320b8b0dSShuming Fan 	.max_register = 0xff01,
310*320b8b0dSShuming Fan 	.cache_type = REGCACHE_NONE,
311*320b8b0dSShuming Fan 	.use_single_read = true,
312*320b8b0dSShuming Fan 	.use_single_write = true,
313*320b8b0dSShuming Fan };
314*320b8b0dSShuming Fan 
315*320b8b0dSShuming Fan static int rt711_update_status(struct sdw_slave *slave,
316*320b8b0dSShuming Fan 				enum sdw_slave_status status)
317*320b8b0dSShuming Fan {
318*320b8b0dSShuming Fan 	struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev);
319*320b8b0dSShuming Fan 
320*320b8b0dSShuming Fan 	/* Update the status */
321*320b8b0dSShuming Fan 	rt711->status = status;
322*320b8b0dSShuming Fan 
323*320b8b0dSShuming Fan 	if (status == SDW_SLAVE_UNATTACHED)
324*320b8b0dSShuming Fan 		rt711->hw_init = false;
325*320b8b0dSShuming Fan 
326*320b8b0dSShuming Fan 	/*
327*320b8b0dSShuming Fan 	 * Perform initialization only if slave status is present and
328*320b8b0dSShuming Fan 	 * hw_init flag is false
329*320b8b0dSShuming Fan 	 */
330*320b8b0dSShuming Fan 	if (rt711->hw_init || rt711->status != SDW_SLAVE_ATTACHED)
331*320b8b0dSShuming Fan 		return 0;
332*320b8b0dSShuming Fan 
333*320b8b0dSShuming Fan 	/* perform I/O transfers required for Slave initialization */
334*320b8b0dSShuming Fan 	return rt711_io_init(&slave->dev, slave);
335*320b8b0dSShuming Fan }
336*320b8b0dSShuming Fan 
337*320b8b0dSShuming Fan static int rt711_read_prop(struct sdw_slave *slave)
338*320b8b0dSShuming Fan {
339*320b8b0dSShuming Fan 	struct sdw_slave_prop *prop = &slave->prop;
340*320b8b0dSShuming Fan 	int nval, i, num_of_ports = 1;
341*320b8b0dSShuming Fan 	u32 bit;
342*320b8b0dSShuming Fan 	unsigned long addr;
343*320b8b0dSShuming Fan 	struct sdw_dpn_prop *dpn;
344*320b8b0dSShuming Fan 
345*320b8b0dSShuming Fan 	prop->paging_support = false;
346*320b8b0dSShuming Fan 
347*320b8b0dSShuming Fan 	/* first we need to allocate memory for set bits in port lists */
348*320b8b0dSShuming Fan 	prop->source_ports = 0x14; /* BITMAP: 00010100 */
349*320b8b0dSShuming Fan 	prop->sink_ports = 0x8; /* BITMAP:  00001000 */
350*320b8b0dSShuming Fan 
351*320b8b0dSShuming Fan 	nval = hweight32(prop->source_ports);
352*320b8b0dSShuming Fan 	num_of_ports += nval;
353*320b8b0dSShuming Fan 	prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval,
354*320b8b0dSShuming Fan 						sizeof(*prop->src_dpn_prop),
355*320b8b0dSShuming Fan 						GFP_KERNEL);
356*320b8b0dSShuming Fan 	if (!prop->src_dpn_prop)
357*320b8b0dSShuming Fan 		return -ENOMEM;
358*320b8b0dSShuming Fan 
359*320b8b0dSShuming Fan 	i = 0;
360*320b8b0dSShuming Fan 	dpn = prop->src_dpn_prop;
361*320b8b0dSShuming Fan 	addr = prop->source_ports;
362*320b8b0dSShuming Fan 	for_each_set_bit(bit, &addr, 32) {
363*320b8b0dSShuming Fan 		dpn[i].num = bit;
364*320b8b0dSShuming Fan 		dpn[i].type = SDW_DPN_FULL;
365*320b8b0dSShuming Fan 		dpn[i].simple_ch_prep_sm = true;
366*320b8b0dSShuming Fan 		dpn[i].ch_prep_timeout = 10;
367*320b8b0dSShuming Fan 		i++;
368*320b8b0dSShuming Fan 	}
369*320b8b0dSShuming Fan 
370*320b8b0dSShuming Fan 	/* do this again for sink now */
371*320b8b0dSShuming Fan 	nval = hweight32(prop->sink_ports);
372*320b8b0dSShuming Fan 	num_of_ports += nval;
373*320b8b0dSShuming Fan 	prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval,
374*320b8b0dSShuming Fan 						sizeof(*prop->sink_dpn_prop),
375*320b8b0dSShuming Fan 						GFP_KERNEL);
376*320b8b0dSShuming Fan 	if (!prop->sink_dpn_prop)
377*320b8b0dSShuming Fan 		return -ENOMEM;
378*320b8b0dSShuming Fan 
379*320b8b0dSShuming Fan 	i = 0;
380*320b8b0dSShuming Fan 	dpn = prop->sink_dpn_prop;
381*320b8b0dSShuming Fan 	addr = prop->sink_ports;
382*320b8b0dSShuming Fan 	for_each_set_bit(bit, &addr, 32) {
383*320b8b0dSShuming Fan 		dpn[i].num = bit;
384*320b8b0dSShuming Fan 		dpn[i].type = SDW_DPN_FULL;
385*320b8b0dSShuming Fan 		dpn[i].simple_ch_prep_sm = true;
386*320b8b0dSShuming Fan 		dpn[i].ch_prep_timeout = 10;
387*320b8b0dSShuming Fan 		i++;
388*320b8b0dSShuming Fan 	}
389*320b8b0dSShuming Fan 
390*320b8b0dSShuming Fan 	/* Allocate port_ready based on num_of_ports */
391*320b8b0dSShuming Fan 	slave->port_ready = devm_kcalloc(&slave->dev, num_of_ports,
392*320b8b0dSShuming Fan 					sizeof(*slave->port_ready),
393*320b8b0dSShuming Fan 					GFP_KERNEL);
394*320b8b0dSShuming Fan 	if (!slave->port_ready)
395*320b8b0dSShuming Fan 		return -ENOMEM;
396*320b8b0dSShuming Fan 
397*320b8b0dSShuming Fan 	/* Initialize completion */
398*320b8b0dSShuming Fan 	for (i = 0; i < num_of_ports; i++)
399*320b8b0dSShuming Fan 		init_completion(&slave->port_ready[i]);
400*320b8b0dSShuming Fan 
401*320b8b0dSShuming Fan 	/* set the timeout values */
402*320b8b0dSShuming Fan 	prop->clk_stop_timeout = 20;
403*320b8b0dSShuming Fan 
404*320b8b0dSShuming Fan 	/* wake-up event */
405*320b8b0dSShuming Fan 	prop->wake_capable = 1;
406*320b8b0dSShuming Fan 
407*320b8b0dSShuming Fan 	return 0;
408*320b8b0dSShuming Fan }
409*320b8b0dSShuming Fan 
410*320b8b0dSShuming Fan static int rt711_bus_config(struct sdw_slave *slave,
411*320b8b0dSShuming Fan 				struct sdw_bus_params *params)
412*320b8b0dSShuming Fan {
413*320b8b0dSShuming Fan 	struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev);
414*320b8b0dSShuming Fan 	int ret;
415*320b8b0dSShuming Fan 
416*320b8b0dSShuming Fan 	memcpy(&rt711->params, params, sizeof(*params));
417*320b8b0dSShuming Fan 
418*320b8b0dSShuming Fan 	ret = rt711_clock_config(&slave->dev);
419*320b8b0dSShuming Fan 	if (ret < 0)
420*320b8b0dSShuming Fan 		dev_err(&slave->dev, "Invalid clk config");
421*320b8b0dSShuming Fan 
422*320b8b0dSShuming Fan 	return ret;
423*320b8b0dSShuming Fan }
424*320b8b0dSShuming Fan 
425*320b8b0dSShuming Fan static int rt711_interrupt_callback(struct sdw_slave *slave,
426*320b8b0dSShuming Fan 					struct sdw_slave_intr_status *status)
427*320b8b0dSShuming Fan {
428*320b8b0dSShuming Fan 	struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev);
429*320b8b0dSShuming Fan 
430*320b8b0dSShuming Fan 	dev_dbg(&slave->dev,
431*320b8b0dSShuming Fan 		"%s control_port_stat=%x", __func__, status->control_port);
432*320b8b0dSShuming Fan 
433*320b8b0dSShuming Fan 	if (status->control_port & 0x4) {
434*320b8b0dSShuming Fan 		mod_delayed_work(system_power_efficient_wq,
435*320b8b0dSShuming Fan 			&rt711->jack_detect_work, msecs_to_jiffies(250));
436*320b8b0dSShuming Fan 	}
437*320b8b0dSShuming Fan 
438*320b8b0dSShuming Fan 	return 0;
439*320b8b0dSShuming Fan }
440*320b8b0dSShuming Fan 
441*320b8b0dSShuming Fan static struct sdw_slave_ops rt711_slave_ops = {
442*320b8b0dSShuming Fan 	.read_prop = rt711_read_prop,
443*320b8b0dSShuming Fan 	.interrupt_callback = rt711_interrupt_callback,
444*320b8b0dSShuming Fan 	.update_status = rt711_update_status,
445*320b8b0dSShuming Fan 	.bus_config = rt711_bus_config,
446*320b8b0dSShuming Fan };
447*320b8b0dSShuming Fan 
448*320b8b0dSShuming Fan static int rt711_sdw_probe(struct sdw_slave *slave,
449*320b8b0dSShuming Fan 				const struct sdw_device_id *id)
450*320b8b0dSShuming Fan {
451*320b8b0dSShuming Fan 	struct regmap *sdw_regmap, *regmap;
452*320b8b0dSShuming Fan 
453*320b8b0dSShuming Fan 	/* Assign ops */
454*320b8b0dSShuming Fan 	slave->ops = &rt711_slave_ops;
455*320b8b0dSShuming Fan 
456*320b8b0dSShuming Fan 	/* Regmap Initialization */
457*320b8b0dSShuming Fan 	sdw_regmap = devm_regmap_init_sdw(slave, &rt711_sdw_regmap);
458*320b8b0dSShuming Fan 	if (!sdw_regmap)
459*320b8b0dSShuming Fan 		return -EINVAL;
460*320b8b0dSShuming Fan 
461*320b8b0dSShuming Fan 	regmap = devm_regmap_init(&slave->dev, NULL,
462*320b8b0dSShuming Fan 		&slave->dev, &rt711_regmap);
463*320b8b0dSShuming Fan 	if (!regmap)
464*320b8b0dSShuming Fan 		return -EINVAL;
465*320b8b0dSShuming Fan 
466*320b8b0dSShuming Fan 	rt711_init(&slave->dev, sdw_regmap, regmap, slave);
467*320b8b0dSShuming Fan 
468*320b8b0dSShuming Fan 	return 0;
469*320b8b0dSShuming Fan }
470*320b8b0dSShuming Fan 
471*320b8b0dSShuming Fan static int rt711_sdw_remove(struct sdw_slave *slave)
472*320b8b0dSShuming Fan {
473*320b8b0dSShuming Fan 	struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev);
474*320b8b0dSShuming Fan 
475*320b8b0dSShuming Fan 	if (rt711 && rt711->hw_init) {
476*320b8b0dSShuming Fan 		cancel_delayed_work(&rt711->jack_detect_work);
477*320b8b0dSShuming Fan 		cancel_delayed_work(&rt711->jack_btn_check_work);
478*320b8b0dSShuming Fan 		cancel_work_sync(&rt711->calibration_work);
479*320b8b0dSShuming Fan 	}
480*320b8b0dSShuming Fan 
481*320b8b0dSShuming Fan 	return 0;
482*320b8b0dSShuming Fan }
483*320b8b0dSShuming Fan 
484*320b8b0dSShuming Fan static const struct sdw_device_id rt711_id[] = {
485*320b8b0dSShuming Fan 	SDW_SLAVE_ENTRY(0x025d, 0x711, 0),
486*320b8b0dSShuming Fan 	{},
487*320b8b0dSShuming Fan };
488*320b8b0dSShuming Fan MODULE_DEVICE_TABLE(sdw, rt711_id);
489*320b8b0dSShuming Fan 
490*320b8b0dSShuming Fan static int rt711_dev_suspend(struct device *dev)
491*320b8b0dSShuming Fan {
492*320b8b0dSShuming Fan 	struct rt711_priv *rt711 = dev_get_drvdata(dev);
493*320b8b0dSShuming Fan 
494*320b8b0dSShuming Fan 	if (!rt711->hw_init)
495*320b8b0dSShuming Fan 		return 0;
496*320b8b0dSShuming Fan 
497*320b8b0dSShuming Fan 	regcache_cache_only(rt711->regmap, true);
498*320b8b0dSShuming Fan 
499*320b8b0dSShuming Fan 	return 0;
500*320b8b0dSShuming Fan }
501*320b8b0dSShuming Fan 
502*320b8b0dSShuming Fan #define RT711_PROBE_TIMEOUT 2000
503*320b8b0dSShuming Fan 
504*320b8b0dSShuming Fan static int rt711_dev_resume(struct device *dev)
505*320b8b0dSShuming Fan {
506*320b8b0dSShuming Fan 	struct sdw_slave *slave = dev_to_sdw_dev(dev);
507*320b8b0dSShuming Fan 	struct rt711_priv *rt711 = dev_get_drvdata(dev);
508*320b8b0dSShuming Fan 	unsigned long time;
509*320b8b0dSShuming Fan 
510*320b8b0dSShuming Fan 	if (!rt711->hw_init)
511*320b8b0dSShuming Fan 		return 0;
512*320b8b0dSShuming Fan 
513*320b8b0dSShuming Fan 	if (!slave->unattach_request)
514*320b8b0dSShuming Fan 		goto regmap_sync;
515*320b8b0dSShuming Fan 
516*320b8b0dSShuming Fan 	time = wait_for_completion_timeout(&slave->initialization_complete,
517*320b8b0dSShuming Fan 				msecs_to_jiffies(RT711_PROBE_TIMEOUT));
518*320b8b0dSShuming Fan 	if (!time) {
519*320b8b0dSShuming Fan 		dev_err(&slave->dev, "Initialization not complete, timed out\n");
520*320b8b0dSShuming Fan 		return -ETIMEDOUT;
521*320b8b0dSShuming Fan 	}
522*320b8b0dSShuming Fan 
523*320b8b0dSShuming Fan regmap_sync:
524*320b8b0dSShuming Fan 	slave->unattach_request = 0;
525*320b8b0dSShuming Fan 	regcache_cache_only(rt711->regmap, false);
526*320b8b0dSShuming Fan 	regcache_sync_region(rt711->regmap, 0x3000, 0x8fff);
527*320b8b0dSShuming Fan 	regcache_sync_region(rt711->regmap, 0x752009, 0x752091);
528*320b8b0dSShuming Fan 
529*320b8b0dSShuming Fan 	return 0;
530*320b8b0dSShuming Fan }
531*320b8b0dSShuming Fan 
532*320b8b0dSShuming Fan static const struct dev_pm_ops rt711_pm = {
533*320b8b0dSShuming Fan 	SET_SYSTEM_SLEEP_PM_OPS(rt711_dev_suspend, rt711_dev_resume)
534*320b8b0dSShuming Fan 	SET_RUNTIME_PM_OPS(rt711_dev_suspend, rt711_dev_resume, NULL)
535*320b8b0dSShuming Fan };
536*320b8b0dSShuming Fan 
537*320b8b0dSShuming Fan static struct sdw_driver rt711_sdw_driver = {
538*320b8b0dSShuming Fan 	.driver = {
539*320b8b0dSShuming Fan 		.name = "rt711",
540*320b8b0dSShuming Fan 		.owner = THIS_MODULE,
541*320b8b0dSShuming Fan 		.pm = &rt711_pm,
542*320b8b0dSShuming Fan 	},
543*320b8b0dSShuming Fan 	.probe = rt711_sdw_probe,
544*320b8b0dSShuming Fan 	.remove = rt711_sdw_remove,
545*320b8b0dSShuming Fan 	.ops = &rt711_slave_ops,
546*320b8b0dSShuming Fan 	.id_table = rt711_id,
547*320b8b0dSShuming Fan };
548*320b8b0dSShuming Fan module_sdw_driver(rt711_sdw_driver);
549*320b8b0dSShuming Fan 
550*320b8b0dSShuming Fan MODULE_DESCRIPTION("ASoC RT711 SDW driver");
551*320b8b0dSShuming Fan MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");
552*320b8b0dSShuming Fan MODULE_LICENSE("GPL");
553