xref: /openbmc/linux/sound/soc/codecs/rt711.c (revision 49ae74abc76b2d9be4777e7ac833674fa4749071)
1320b8b0dSShuming Fan // SPDX-License-Identifier: GPL-2.0
2320b8b0dSShuming Fan //
3320b8b0dSShuming Fan // rt711.c -- rt711 ALSA SoC audio driver
4320b8b0dSShuming Fan //
5320b8b0dSShuming Fan // Copyright(c) 2019 Realtek Semiconductor Corp.
6320b8b0dSShuming Fan //
7320b8b0dSShuming Fan //
8320b8b0dSShuming Fan 
9320b8b0dSShuming Fan #include <linux/module.h>
10320b8b0dSShuming Fan #include <linux/moduleparam.h>
11320b8b0dSShuming Fan #include <linux/kernel.h>
12320b8b0dSShuming Fan #include <linux/init.h>
13320b8b0dSShuming Fan #include <linux/delay.h>
14320b8b0dSShuming Fan #include <linux/pm_runtime.h>
15320b8b0dSShuming Fan #include <linux/pm.h>
16320b8b0dSShuming Fan #include <linux/soundwire/sdw.h>
17320b8b0dSShuming Fan #include <linux/regmap.h>
18320b8b0dSShuming Fan #include <linux/slab.h>
19320b8b0dSShuming Fan #include <sound/core.h>
20320b8b0dSShuming Fan #include <sound/pcm.h>
21320b8b0dSShuming Fan #include <sound/pcm_params.h>
22754bef67SCharles Keepax #include <sound/sdw.h>
23320b8b0dSShuming Fan #include <sound/soc.h>
24320b8b0dSShuming Fan #include <sound/soc-dapm.h>
25320b8b0dSShuming Fan #include <sound/initval.h>
26320b8b0dSShuming Fan #include <sound/tlv.h>
27320b8b0dSShuming Fan #include <sound/hda_verbs.h>
28320b8b0dSShuming Fan #include <sound/jack.h>
29320b8b0dSShuming Fan 
30320b8b0dSShuming Fan #include "rt711.h"
31320b8b0dSShuming Fan 
32320b8b0dSShuming Fan static int rt711_index_write(struct regmap *regmap,
33320b8b0dSShuming Fan 		unsigned int nid, unsigned int reg, unsigned int value)
34320b8b0dSShuming Fan {
35320b8b0dSShuming Fan 	int ret;
36320b8b0dSShuming Fan 	unsigned int addr = ((RT711_PRIV_INDEX_W_H | nid) << 8) | reg;
37320b8b0dSShuming Fan 
38320b8b0dSShuming Fan 	ret = regmap_write(regmap, addr, value);
39320b8b0dSShuming Fan 	if (ret < 0)
40320b8b0dSShuming Fan 		pr_err("Failed to set private value: %06x <= %04x ret=%d\n",
41320b8b0dSShuming Fan 			addr, value, ret);
42320b8b0dSShuming Fan 
43320b8b0dSShuming Fan 	return ret;
44320b8b0dSShuming Fan }
45320b8b0dSShuming Fan 
46320b8b0dSShuming Fan static int rt711_index_read(struct regmap *regmap,
47320b8b0dSShuming Fan 		unsigned int nid, unsigned int reg, unsigned int *value)
48320b8b0dSShuming Fan {
49320b8b0dSShuming Fan 	int ret;
50320b8b0dSShuming Fan 	unsigned int addr = ((RT711_PRIV_INDEX_W_H | nid) << 8) | reg;
51320b8b0dSShuming Fan 
52320b8b0dSShuming Fan 	*value = 0;
53320b8b0dSShuming Fan 	ret = regmap_read(regmap, addr, value);
54320b8b0dSShuming Fan 	if (ret < 0)
55320b8b0dSShuming Fan 		pr_err("Failed to get private value: %06x => %04x ret=%d\n",
56320b8b0dSShuming Fan 			addr, *value, ret);
57320b8b0dSShuming Fan 
58320b8b0dSShuming Fan 	return ret;
59320b8b0dSShuming Fan }
60320b8b0dSShuming Fan 
61320b8b0dSShuming Fan static int rt711_index_update_bits(struct regmap *regmap, unsigned int nid,
62320b8b0dSShuming Fan 			unsigned int reg, unsigned int mask, unsigned int val)
63320b8b0dSShuming Fan {
64320b8b0dSShuming Fan 	unsigned int tmp, orig;
65320b8b0dSShuming Fan 	int ret;
66320b8b0dSShuming Fan 
67320b8b0dSShuming Fan 	ret = rt711_index_read(regmap, nid, reg, &orig);
68320b8b0dSShuming Fan 	if (ret < 0)
69320b8b0dSShuming Fan 		return ret;
70320b8b0dSShuming Fan 
71320b8b0dSShuming Fan 	tmp = orig & ~mask;
72320b8b0dSShuming Fan 	tmp |= val & mask;
73320b8b0dSShuming Fan 
74320b8b0dSShuming Fan 	return rt711_index_write(regmap, nid, reg, tmp);
75320b8b0dSShuming Fan }
76320b8b0dSShuming Fan 
77320b8b0dSShuming Fan static void rt711_reset(struct regmap *regmap)
78320b8b0dSShuming Fan {
79320b8b0dSShuming Fan 	regmap_write(regmap, RT711_FUNC_RESET, 0);
80320b8b0dSShuming Fan 	rt711_index_update_bits(regmap, RT711_VENDOR_REG,
81320b8b0dSShuming Fan 		RT711_PARA_VERB_CTL, RT711_HIDDEN_REG_SW_RESET,
82320b8b0dSShuming Fan 		RT711_HIDDEN_REG_SW_RESET);
83320b8b0dSShuming Fan }
84320b8b0dSShuming Fan 
85320b8b0dSShuming Fan static int rt711_calibration(struct rt711_priv *rt711)
86320b8b0dSShuming Fan {
87320b8b0dSShuming Fan 	unsigned int val, loop = 0;
88320b8b0dSShuming Fan 	struct device *dev;
89320b8b0dSShuming Fan 	struct regmap *regmap = rt711->regmap;
90320b8b0dSShuming Fan 	int ret = 0;
91320b8b0dSShuming Fan 
92320b8b0dSShuming Fan 	mutex_lock(&rt711->calibrate_mutex);
93320b8b0dSShuming Fan 	regmap_write(rt711->regmap,
94320b8b0dSShuming Fan 		RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D0);
95320b8b0dSShuming Fan 
96320b8b0dSShuming Fan 	dev = regmap_get_device(regmap);
97320b8b0dSShuming Fan 
98320b8b0dSShuming Fan 	/* Calibration manual mode */
99320b8b0dSShuming Fan 	rt711_index_update_bits(regmap, RT711_VENDOR_REG, RT711_FSM_CTL,
100320b8b0dSShuming Fan 		0xf, 0x0);
101320b8b0dSShuming Fan 
102320b8b0dSShuming Fan 	/* trigger */
103320b8b0dSShuming Fan 	rt711_index_update_bits(regmap, RT711_VENDOR_CALI,
104320b8b0dSShuming Fan 		RT711_DAC_DC_CALI_CTL1, RT711_DAC_DC_CALI_TRIGGER,
105320b8b0dSShuming Fan 		RT711_DAC_DC_CALI_TRIGGER);
106320b8b0dSShuming Fan 
107320b8b0dSShuming Fan 	/* wait for calibration process */
108320b8b0dSShuming Fan 	rt711_index_read(regmap, RT711_VENDOR_CALI,
109320b8b0dSShuming Fan 		RT711_DAC_DC_CALI_CTL1, &val);
110320b8b0dSShuming Fan 
111320b8b0dSShuming Fan 	while (val & RT711_DAC_DC_CALI_TRIGGER) {
112320b8b0dSShuming Fan 		if (loop >= 500) {
113320b8b0dSShuming Fan 			pr_err("%s, calibration time-out!\n",
114320b8b0dSShuming Fan 							__func__);
115320b8b0dSShuming Fan 			ret = -ETIMEDOUT;
116320b8b0dSShuming Fan 			break;
117320b8b0dSShuming Fan 		}
118320b8b0dSShuming Fan 		loop++;
119320b8b0dSShuming Fan 
120320b8b0dSShuming Fan 		usleep_range(10000, 11000);
121320b8b0dSShuming Fan 		rt711_index_read(regmap, RT711_VENDOR_CALI,
122320b8b0dSShuming Fan 			RT711_DAC_DC_CALI_CTL1, &val);
123320b8b0dSShuming Fan 	}
124320b8b0dSShuming Fan 
125320b8b0dSShuming Fan 	/* depop mode */
126320b8b0dSShuming Fan 	rt711_index_update_bits(regmap, RT711_VENDOR_REG,
127320b8b0dSShuming Fan 		RT711_FSM_CTL, 0xf, RT711_DEPOP_CTL);
128320b8b0dSShuming Fan 
129320b8b0dSShuming Fan 	regmap_write(rt711->regmap,
130320b8b0dSShuming Fan 		RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D3);
131320b8b0dSShuming Fan 	mutex_unlock(&rt711->calibrate_mutex);
132320b8b0dSShuming Fan 
133320b8b0dSShuming Fan 	dev_dbg(dev, "%s calibration complete, ret=%d\n", __func__, ret);
134320b8b0dSShuming Fan 	return ret;
135320b8b0dSShuming Fan }
136320b8b0dSShuming Fan 
137320b8b0dSShuming Fan static unsigned int rt711_button_detect(struct rt711_priv *rt711)
138320b8b0dSShuming Fan {
139320b8b0dSShuming Fan 	unsigned int btn_type = 0, val80, val81;
140320b8b0dSShuming Fan 	int ret;
141320b8b0dSShuming Fan 
142320b8b0dSShuming Fan 	ret = rt711_index_read(rt711->regmap, RT711_VENDOR_REG,
143320b8b0dSShuming Fan 				RT711_IRQ_FLAG_TABLE1, &val80);
144320b8b0dSShuming Fan 	if (ret < 0)
145320b8b0dSShuming Fan 		goto read_error;
146320b8b0dSShuming Fan 	ret = rt711_index_read(rt711->regmap, RT711_VENDOR_REG,
147320b8b0dSShuming Fan 					RT711_IRQ_FLAG_TABLE2, &val81);
148320b8b0dSShuming Fan 	if (ret < 0)
149320b8b0dSShuming Fan 		goto read_error;
150320b8b0dSShuming Fan 
151320b8b0dSShuming Fan 	val80 &= 0x0381;
152320b8b0dSShuming Fan 	val81 &= 0xff00;
153320b8b0dSShuming Fan 
154320b8b0dSShuming Fan 	switch (val80) {
155320b8b0dSShuming Fan 	case 0x0200:
156320b8b0dSShuming Fan 	case 0x0100:
157320b8b0dSShuming Fan 	case 0x0080:
158320b8b0dSShuming Fan 		btn_type |= SND_JACK_BTN_0;
159320b8b0dSShuming Fan 		break;
160320b8b0dSShuming Fan 	case 0x0001:
161320b8b0dSShuming Fan 		btn_type |= SND_JACK_BTN_3;
162320b8b0dSShuming Fan 		break;
163320b8b0dSShuming Fan 	}
164320b8b0dSShuming Fan 	switch (val81) {
165320b8b0dSShuming Fan 	case 0x8000:
166320b8b0dSShuming Fan 	case 0x4000:
167320b8b0dSShuming Fan 	case 0x2000:
168320b8b0dSShuming Fan 		btn_type |= SND_JACK_BTN_1;
169320b8b0dSShuming Fan 		break;
170320b8b0dSShuming Fan 	case 0x1000:
171320b8b0dSShuming Fan 	case 0x0800:
172320b8b0dSShuming Fan 	case 0x0400:
173320b8b0dSShuming Fan 		btn_type |= SND_JACK_BTN_2;
174320b8b0dSShuming Fan 		break;
175320b8b0dSShuming Fan 	case 0x0200:
176320b8b0dSShuming Fan 	case 0x0100:
177320b8b0dSShuming Fan 		btn_type |= SND_JACK_BTN_3;
178320b8b0dSShuming Fan 		break;
179320b8b0dSShuming Fan 	}
180320b8b0dSShuming Fan read_error:
181320b8b0dSShuming Fan 	return btn_type;
182320b8b0dSShuming Fan }
183320b8b0dSShuming Fan 
184320b8b0dSShuming Fan static int rt711_headset_detect(struct rt711_priv *rt711)
185320b8b0dSShuming Fan {
186320b8b0dSShuming Fan 	unsigned int buf, loop = 0;
187320b8b0dSShuming Fan 	int ret;
188320b8b0dSShuming Fan 	unsigned int jack_status = 0, reg;
189320b8b0dSShuming Fan 
190320b8b0dSShuming Fan 	ret = rt711_index_read(rt711->regmap, RT711_VENDOR_REG,
191320b8b0dSShuming Fan 				RT711_COMBO_JACK_AUTO_CTL2, &buf);
192320b8b0dSShuming Fan 	if (ret < 0)
193320b8b0dSShuming Fan 		goto io_error;
194320b8b0dSShuming Fan 
195320b8b0dSShuming Fan 	while (loop < 500 &&
196320b8b0dSShuming Fan 		(buf & RT711_COMBOJACK_AUTO_DET_STATUS) == 0) {
197320b8b0dSShuming Fan 		loop++;
198320b8b0dSShuming Fan 
199320b8b0dSShuming Fan 		usleep_range(9000, 10000);
200320b8b0dSShuming Fan 		ret = rt711_index_read(rt711->regmap, RT711_VENDOR_REG,
201320b8b0dSShuming Fan 					RT711_COMBO_JACK_AUTO_CTL2, &buf);
202320b8b0dSShuming Fan 		if (ret < 0)
203320b8b0dSShuming Fan 			goto io_error;
204320b8b0dSShuming Fan 
205320b8b0dSShuming Fan 		reg = RT711_VERB_GET_PIN_SENSE | RT711_HP_OUT;
206320b8b0dSShuming Fan 		ret = regmap_read(rt711->regmap, reg, &jack_status);
207320b8b0dSShuming Fan 		if (ret < 0)
208320b8b0dSShuming Fan 			goto io_error;
209320b8b0dSShuming Fan 		if ((jack_status & (1 << 31)) == 0)
210320b8b0dSShuming Fan 			goto remove_error;
211320b8b0dSShuming Fan 	}
212320b8b0dSShuming Fan 
213320b8b0dSShuming Fan 	if (loop >= 500)
214320b8b0dSShuming Fan 		goto to_error;
215320b8b0dSShuming Fan 
216320b8b0dSShuming Fan 	if (buf & RT711_COMBOJACK_AUTO_DET_TRS)
217320b8b0dSShuming Fan 		rt711->jack_type = SND_JACK_HEADPHONE;
218320b8b0dSShuming Fan 	else if ((buf & RT711_COMBOJACK_AUTO_DET_CTIA) ||
219320b8b0dSShuming Fan 		(buf & RT711_COMBOJACK_AUTO_DET_OMTP))
220320b8b0dSShuming Fan 		rt711->jack_type = SND_JACK_HEADSET;
221320b8b0dSShuming Fan 
222320b8b0dSShuming Fan 	return 0;
223320b8b0dSShuming Fan 
224320b8b0dSShuming Fan to_error:
225320b8b0dSShuming Fan 	ret = -ETIMEDOUT;
226320b8b0dSShuming Fan 	pr_err_ratelimited("Time-out error in %s\n", __func__);
227320b8b0dSShuming Fan 	return ret;
228320b8b0dSShuming Fan io_error:
229320b8b0dSShuming Fan 	pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret);
230320b8b0dSShuming Fan 	return ret;
231320b8b0dSShuming Fan remove_error:
232320b8b0dSShuming Fan 	pr_err_ratelimited("Jack removal in %s\n", __func__);
233320b8b0dSShuming Fan 	return -ENODEV;
234320b8b0dSShuming Fan }
235320b8b0dSShuming Fan 
236320b8b0dSShuming Fan static void rt711_jack_detect_handler(struct work_struct *work)
237320b8b0dSShuming Fan {
238320b8b0dSShuming Fan 	struct rt711_priv *rt711 =
239320b8b0dSShuming Fan 		container_of(work, struct rt711_priv, jack_detect_work.work);
240320b8b0dSShuming Fan 	int btn_type = 0, ret;
241320b8b0dSShuming Fan 	unsigned int jack_status = 0, reg;
242320b8b0dSShuming Fan 
243320b8b0dSShuming Fan 	if (!rt711->hs_jack)
244320b8b0dSShuming Fan 		return;
245320b8b0dSShuming Fan 
2468ec35236SKuninori Morimoto 	if (!snd_soc_card_is_instantiated(rt711->component->card))
247320b8b0dSShuming Fan 		return;
248320b8b0dSShuming Fan 
249770f3d99SPierre-Louis Bossart 	if (pm_runtime_status_suspended(rt711->slave->dev.parent)) {
250770f3d99SPierre-Louis Bossart 		dev_dbg(&rt711->slave->dev,
251770f3d99SPierre-Louis Bossart 			"%s: parent device is pm_runtime_status_suspended, skipping jack detection\n",
252770f3d99SPierre-Louis Bossart 			__func__);
253770f3d99SPierre-Louis Bossart 		return;
254770f3d99SPierre-Louis Bossart 	}
255770f3d99SPierre-Louis Bossart 
256320b8b0dSShuming Fan 	reg = RT711_VERB_GET_PIN_SENSE | RT711_HP_OUT;
257320b8b0dSShuming Fan 	ret = regmap_read(rt711->regmap, reg, &jack_status);
258320b8b0dSShuming Fan 	if (ret < 0)
259320b8b0dSShuming Fan 		goto io_error;
260320b8b0dSShuming Fan 
261320b8b0dSShuming Fan 	/* pin attached */
262320b8b0dSShuming Fan 	if (jack_status & (1 << 31)) {
263320b8b0dSShuming Fan 		/* jack in */
264320b8b0dSShuming Fan 		if (rt711->jack_type == 0) {
265320b8b0dSShuming Fan 			ret = rt711_headset_detect(rt711);
266320b8b0dSShuming Fan 			if (ret < 0)
267320b8b0dSShuming Fan 				return;
268320b8b0dSShuming Fan 			if (rt711->jack_type == SND_JACK_HEADSET)
269320b8b0dSShuming Fan 				btn_type = rt711_button_detect(rt711);
270320b8b0dSShuming Fan 		} else if (rt711->jack_type == SND_JACK_HEADSET) {
271320b8b0dSShuming Fan 			/* jack is already in, report button event */
272320b8b0dSShuming Fan 			btn_type = rt711_button_detect(rt711);
273320b8b0dSShuming Fan 		}
274320b8b0dSShuming Fan 	} else {
275320b8b0dSShuming Fan 		/* jack out */
276320b8b0dSShuming Fan 		rt711->jack_type = 0;
277320b8b0dSShuming Fan 	}
278320b8b0dSShuming Fan 
279320b8b0dSShuming Fan 	dev_dbg(&rt711->slave->dev,
280320b8b0dSShuming Fan 		"in %s, jack_type=0x%x\n", __func__, rt711->jack_type);
281320b8b0dSShuming Fan 	dev_dbg(&rt711->slave->dev,
282320b8b0dSShuming Fan 		"in %s, btn_type=0x%x\n", __func__, btn_type);
283320b8b0dSShuming Fan 
284320b8b0dSShuming Fan 	snd_soc_jack_report(rt711->hs_jack, rt711->jack_type | btn_type,
285320b8b0dSShuming Fan 			SND_JACK_HEADSET |
286320b8b0dSShuming Fan 			SND_JACK_BTN_0 | SND_JACK_BTN_1 |
287320b8b0dSShuming Fan 			SND_JACK_BTN_2 | SND_JACK_BTN_3);
288320b8b0dSShuming Fan 
289320b8b0dSShuming Fan 	if (btn_type) {
290320b8b0dSShuming Fan 		/* button released */
291320b8b0dSShuming Fan 		snd_soc_jack_report(rt711->hs_jack, rt711->jack_type,
292320b8b0dSShuming Fan 			SND_JACK_HEADSET |
293320b8b0dSShuming Fan 			SND_JACK_BTN_0 | SND_JACK_BTN_1 |
294320b8b0dSShuming Fan 			SND_JACK_BTN_2 | SND_JACK_BTN_3);
295320b8b0dSShuming Fan 
296320b8b0dSShuming Fan 		mod_delayed_work(system_power_efficient_wq,
297320b8b0dSShuming Fan 			&rt711->jack_btn_check_work, msecs_to_jiffies(200));
298320b8b0dSShuming Fan 	}
299320b8b0dSShuming Fan 
300320b8b0dSShuming Fan 	return;
301320b8b0dSShuming Fan 
302320b8b0dSShuming Fan io_error:
303320b8b0dSShuming Fan 	pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret);
304320b8b0dSShuming Fan }
305320b8b0dSShuming Fan 
306320b8b0dSShuming Fan static void rt711_btn_check_handler(struct work_struct *work)
307320b8b0dSShuming Fan {
308320b8b0dSShuming Fan 	struct rt711_priv *rt711 = container_of(work, struct rt711_priv,
309320b8b0dSShuming Fan 		jack_btn_check_work.work);
310320b8b0dSShuming Fan 	int btn_type = 0, ret;
311320b8b0dSShuming Fan 	unsigned int jack_status = 0, reg;
312320b8b0dSShuming Fan 
313320b8b0dSShuming Fan 	reg = RT711_VERB_GET_PIN_SENSE | RT711_HP_OUT;
314320b8b0dSShuming Fan 	ret = regmap_read(rt711->regmap, reg, &jack_status);
315320b8b0dSShuming Fan 	if (ret < 0)
316320b8b0dSShuming Fan 		goto io_error;
317320b8b0dSShuming Fan 
318320b8b0dSShuming Fan 	/* pin attached */
319320b8b0dSShuming Fan 	if (jack_status & (1 << 31)) {
320320b8b0dSShuming Fan 		if (rt711->jack_type == SND_JACK_HEADSET) {
321320b8b0dSShuming Fan 			/* jack is already in, report button event */
322320b8b0dSShuming Fan 			btn_type = rt711_button_detect(rt711);
323320b8b0dSShuming Fan 		}
324320b8b0dSShuming Fan 	} else {
325320b8b0dSShuming Fan 		rt711->jack_type = 0;
326320b8b0dSShuming Fan 	}
327320b8b0dSShuming Fan 
328320b8b0dSShuming Fan 	/* cbj comparator */
329320b8b0dSShuming Fan 	ret = rt711_index_read(rt711->regmap, RT711_VENDOR_REG,
330320b8b0dSShuming Fan 		RT711_COMBO_JACK_AUTO_CTL2, &reg);
331320b8b0dSShuming Fan 	if (ret < 0)
332320b8b0dSShuming Fan 		goto io_error;
333320b8b0dSShuming Fan 
334320b8b0dSShuming Fan 	if ((reg & 0xf0) == 0xf0)
335320b8b0dSShuming Fan 		btn_type = 0;
336320b8b0dSShuming Fan 
337320b8b0dSShuming Fan 	dev_dbg(&rt711->slave->dev,
338320b8b0dSShuming Fan 		"%s, btn_type=0x%x\n",	__func__, btn_type);
339320b8b0dSShuming Fan 	snd_soc_jack_report(rt711->hs_jack, rt711->jack_type | btn_type,
340320b8b0dSShuming Fan 			SND_JACK_HEADSET |
341320b8b0dSShuming Fan 			SND_JACK_BTN_0 | SND_JACK_BTN_1 |
342320b8b0dSShuming Fan 			SND_JACK_BTN_2 | SND_JACK_BTN_3);
343320b8b0dSShuming Fan 
344320b8b0dSShuming Fan 	if (btn_type) {
345320b8b0dSShuming Fan 		/* button released */
346320b8b0dSShuming Fan 		snd_soc_jack_report(rt711->hs_jack, rt711->jack_type,
347320b8b0dSShuming Fan 			SND_JACK_HEADSET |
348320b8b0dSShuming Fan 			SND_JACK_BTN_0 | SND_JACK_BTN_1 |
349320b8b0dSShuming Fan 			SND_JACK_BTN_2 | SND_JACK_BTN_3);
350320b8b0dSShuming Fan 
351320b8b0dSShuming Fan 		mod_delayed_work(system_power_efficient_wq,
352320b8b0dSShuming Fan 			&rt711->jack_btn_check_work, msecs_to_jiffies(200));
353320b8b0dSShuming Fan 	}
354320b8b0dSShuming Fan 
355320b8b0dSShuming Fan 	return;
356320b8b0dSShuming Fan 
357320b8b0dSShuming Fan io_error:
358320b8b0dSShuming Fan 	pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret);
359320b8b0dSShuming Fan }
360320b8b0dSShuming Fan 
361320b8b0dSShuming Fan static void rt711_jack_init(struct rt711_priv *rt711)
362320b8b0dSShuming Fan {
363320b8b0dSShuming Fan 	struct snd_soc_dapm_context *dapm =
364320b8b0dSShuming Fan 		snd_soc_component_get_dapm(rt711->component);
365320b8b0dSShuming Fan 
366320b8b0dSShuming Fan 	mutex_lock(&rt711->calibrate_mutex);
367320b8b0dSShuming Fan 	/* power on */
368320b8b0dSShuming Fan 	if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)
369320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
370320b8b0dSShuming Fan 			RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D0);
371320b8b0dSShuming Fan 
372320b8b0dSShuming Fan 	if (rt711->hs_jack) {
373320b8b0dSShuming Fan 		/* unsolicited response & IRQ control */
374320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
375320b8b0dSShuming Fan 			RT711_SET_MIC2_UNSOLICITED_ENABLE, 0x82);
376320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
377320b8b0dSShuming Fan 			RT711_SET_HP_UNSOLICITED_ENABLE, 0x81);
378320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
379320b8b0dSShuming Fan 			RT711_SET_INLINE_UNSOLICITED_ENABLE, 0x83);
380320b8b0dSShuming Fan 		rt711_index_write(rt711->regmap, RT711_VENDOR_REG,
381320b8b0dSShuming Fan 			0x10, 0x2420);
382320b8b0dSShuming Fan 		rt711_index_write(rt711->regmap, RT711_VENDOR_REG,
383320b8b0dSShuming Fan 			0x19, 0x2e11);
384320b8b0dSShuming Fan 
385320b8b0dSShuming Fan 		switch (rt711->jd_src) {
386320b8b0dSShuming Fan 		case RT711_JD1:
387320b8b0dSShuming Fan 			/* default settings was already for JD1 */
388320b8b0dSShuming Fan 			break;
389320b8b0dSShuming Fan 		case RT711_JD2:
390320b8b0dSShuming Fan 			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
391320b8b0dSShuming Fan 				RT711_JD_CTL2, RT711_JD2_2PORT_200K_DECODE_HP |
392320b8b0dSShuming Fan 				RT711_HP_JD_SEL_JD2,
393320b8b0dSShuming Fan 				RT711_JD2_2PORT_200K_DECODE_HP |
394320b8b0dSShuming Fan 				RT711_HP_JD_SEL_JD2);
395320b8b0dSShuming Fan 			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
396320b8b0dSShuming Fan 				RT711_CC_DET1,
397320b8b0dSShuming Fan 				RT711_HP_JD_FINAL_RESULT_CTL_JD12,
398320b8b0dSShuming Fan 				RT711_HP_JD_FINAL_RESULT_CTL_JD12);
399320b8b0dSShuming Fan 			break;
400683b0df2SShuming Fan 		case RT711_JD2_100K:
401683b0df2SShuming Fan 			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
402683b0df2SShuming Fan 				RT711_JD_CTL2, RT711_JD2_2PORT_100K_DECODE | RT711_JD2_1PORT_TYPE_DECODE |
403683b0df2SShuming Fan 				RT711_HP_JD_SEL_JD2 | RT711_JD1_2PORT_TYPE_100K_DECODE,
404683b0df2SShuming Fan 				RT711_JD2_2PORT_100K_DECODE_HP | RT711_JD2_1PORT_JD_HP |
405683b0df2SShuming Fan 				RT711_HP_JD_SEL_JD2 | RT711_JD1_2PORT_JD_RESERVED);
406683b0df2SShuming Fan 			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
407683b0df2SShuming Fan 				RT711_CC_DET1,
408683b0df2SShuming Fan 				RT711_HP_JD_FINAL_RESULT_CTL_JD12,
409683b0df2SShuming Fan 				RT711_HP_JD_FINAL_RESULT_CTL_JD12);
410683b0df2SShuming Fan 			break;
411683b0df2SShuming Fan 		case RT711_JD2_1P8V_1PORT:
412683b0df2SShuming Fan 			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
413683b0df2SShuming Fan 				RT711_JD_CTL1, RT711_JD2_DIGITAL_JD_MODE_SEL,
414683b0df2SShuming Fan 				RT711_JD2_1_JD_MODE);
415683b0df2SShuming Fan 			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
416683b0df2SShuming Fan 				RT711_JD_CTL2, RT711_JD2_1PORT_TYPE_DECODE |
417683b0df2SShuming Fan 				RT711_HP_JD_SEL_JD2,
418683b0df2SShuming Fan 				RT711_JD2_1PORT_JD_HP |
419683b0df2SShuming Fan 				RT711_HP_JD_SEL_JD2);
420683b0df2SShuming Fan 			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
421683b0df2SShuming Fan 				RT711_JD_CTL4, RT711_JD2_PAD_PULL_UP_MASK |
422683b0df2SShuming Fan 				RT711_JD2_MODE_SEL_MASK,
423683b0df2SShuming Fan 				RT711_JD2_PAD_PULL_UP |
424683b0df2SShuming Fan 				RT711_JD2_MODE2_1P8V_1PORT);
425683b0df2SShuming Fan 			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
426683b0df2SShuming Fan 				RT711_CC_DET1,
427683b0df2SShuming Fan 				RT711_HP_JD_FINAL_RESULT_CTL_JD12,
428683b0df2SShuming Fan 				RT711_HP_JD_FINAL_RESULT_CTL_JD12);
429683b0df2SShuming Fan 			break;
430320b8b0dSShuming Fan 		default:
431320b8b0dSShuming Fan 			dev_warn(rt711->component->dev, "Wrong JD source\n");
432320b8b0dSShuming Fan 			break;
433320b8b0dSShuming Fan 		}
434320b8b0dSShuming Fan 
435320b8b0dSShuming Fan 		dev_dbg(&rt711->slave->dev, "in %s enable\n", __func__);
436320b8b0dSShuming Fan 
437320b8b0dSShuming Fan 		mod_delayed_work(system_power_efficient_wq,
438320b8b0dSShuming Fan 			&rt711->jack_detect_work, msecs_to_jiffies(250));
439320b8b0dSShuming Fan 	} else {
440320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
441320b8b0dSShuming Fan 			RT711_SET_MIC2_UNSOLICITED_ENABLE, 0x00);
442320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
443320b8b0dSShuming Fan 			RT711_SET_HP_UNSOLICITED_ENABLE, 0x00);
444320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
445320b8b0dSShuming Fan 			RT711_SET_INLINE_UNSOLICITED_ENABLE, 0x00);
446320b8b0dSShuming Fan 
447320b8b0dSShuming Fan 		dev_dbg(&rt711->slave->dev, "in %s disable\n", __func__);
448320b8b0dSShuming Fan 	}
449320b8b0dSShuming Fan 
450320b8b0dSShuming Fan 	/* power off */
451320b8b0dSShuming Fan 	if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)
452320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
453320b8b0dSShuming Fan 			RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D3);
454320b8b0dSShuming Fan 	mutex_unlock(&rt711->calibrate_mutex);
455320b8b0dSShuming Fan }
456320b8b0dSShuming Fan 
457320b8b0dSShuming Fan static int rt711_set_jack_detect(struct snd_soc_component *component,
458320b8b0dSShuming Fan 	struct snd_soc_jack *hs_jack, void *data)
459320b8b0dSShuming Fan {
460320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
461e02b99e9SPierre-Louis Bossart 	int ret;
462320b8b0dSShuming Fan 
463320b8b0dSShuming Fan 	rt711->hs_jack = hs_jack;
464320b8b0dSShuming Fan 
465e02b99e9SPierre-Louis Bossart 	ret = pm_runtime_resume_and_get(component->dev);
466e02b99e9SPierre-Louis Bossart 	if (ret < 0) {
467e02b99e9SPierre-Louis Bossart 		if (ret != -EACCES) {
468e02b99e9SPierre-Louis Bossart 			dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);
469e02b99e9SPierre-Louis Bossart 			return ret;
470e02b99e9SPierre-Louis Bossart 		}
471e02b99e9SPierre-Louis Bossart 
472e02b99e9SPierre-Louis Bossart 		/* pm_runtime not enabled yet */
473e02b99e9SPierre-Louis Bossart 		dev_dbg(component->dev,	"%s: skipping jack init for now\n", __func__);
474320b8b0dSShuming Fan 		return 0;
475320b8b0dSShuming Fan 	}
476320b8b0dSShuming Fan 
477320b8b0dSShuming Fan 	rt711_jack_init(rt711);
478320b8b0dSShuming Fan 
479e02b99e9SPierre-Louis Bossart 	pm_runtime_mark_last_busy(component->dev);
480e02b99e9SPierre-Louis Bossart 	pm_runtime_put_autosuspend(component->dev);
481e02b99e9SPierre-Louis Bossart 
482320b8b0dSShuming Fan 	return 0;
483320b8b0dSShuming Fan }
484320b8b0dSShuming Fan 
485320b8b0dSShuming Fan static void rt711_get_gain(struct rt711_priv *rt711, unsigned int addr_h,
486320b8b0dSShuming Fan 				unsigned int addr_l, unsigned int val_h,
487320b8b0dSShuming Fan 				unsigned int *r_val, unsigned int *l_val)
488320b8b0dSShuming Fan {
489320b8b0dSShuming Fan 	/* R Channel */
490320b8b0dSShuming Fan 	*r_val = (val_h << 8);
491320b8b0dSShuming Fan 	regmap_read(rt711->regmap, addr_l, r_val);
492320b8b0dSShuming Fan 
493320b8b0dSShuming Fan 	/* L Channel */
494320b8b0dSShuming Fan 	val_h |= 0x20;
495320b8b0dSShuming Fan 	*l_val = (val_h << 8);
496320b8b0dSShuming Fan 	regmap_read(rt711->regmap, addr_h, l_val);
497320b8b0dSShuming Fan }
498320b8b0dSShuming Fan 
499320b8b0dSShuming Fan /* For Verb-Set Amplifier Gain (Verb ID = 3h) */
500320b8b0dSShuming Fan static int rt711_set_amp_gain_put(struct snd_kcontrol *kcontrol,
501320b8b0dSShuming Fan 		struct snd_ctl_elem_value *ucontrol)
502320b8b0dSShuming Fan {
503320b8b0dSShuming Fan 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
504320b8b0dSShuming Fan 	struct snd_soc_dapm_context *dapm =
505320b8b0dSShuming Fan 		snd_soc_component_get_dapm(component);
506320b8b0dSShuming Fan 	struct soc_mixer_control *mc =
507320b8b0dSShuming Fan 		(struct soc_mixer_control *)kcontrol->private_value;
508320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
509320b8b0dSShuming Fan 	unsigned int addr_h, addr_l, val_h, val_ll, val_lr;
510320b8b0dSShuming Fan 	unsigned int read_ll, read_rl;
511320b8b0dSShuming Fan 	int i;
512320b8b0dSShuming Fan 
5136108f990SShuming Fan 	mutex_lock(&rt711->calibrate_mutex);
5146108f990SShuming Fan 
515320b8b0dSShuming Fan 	/* Can't use update bit function, so read the original value first */
516320b8b0dSShuming Fan 	addr_h = mc->reg;
517320b8b0dSShuming Fan 	addr_l = mc->rreg;
518320b8b0dSShuming Fan 	if (mc->shift == RT711_DIR_OUT_SFT) /* output */
519320b8b0dSShuming Fan 		val_h = 0x80;
520320b8b0dSShuming Fan 	else /* input */
521320b8b0dSShuming Fan 		val_h = 0x0;
522320b8b0dSShuming Fan 
523320b8b0dSShuming Fan 	rt711_get_gain(rt711, addr_h, addr_l, val_h, &read_rl, &read_ll);
524320b8b0dSShuming Fan 
525320b8b0dSShuming Fan 	/* L Channel */
526320b8b0dSShuming Fan 	if (mc->invert) {
527320b8b0dSShuming Fan 		/* for mute/unmute */
528320b8b0dSShuming Fan 		val_ll = (mc->max - ucontrol->value.integer.value[0])
529320b8b0dSShuming Fan 					<< RT711_MUTE_SFT;
530320b8b0dSShuming Fan 		/* keep gain */
531320b8b0dSShuming Fan 		read_ll = read_ll & 0x7f;
532320b8b0dSShuming Fan 		val_ll |= read_ll;
533320b8b0dSShuming Fan 	} else {
534320b8b0dSShuming Fan 		/* for gain */
535320b8b0dSShuming Fan 		val_ll = ((ucontrol->value.integer.value[0]) & 0x7f);
536320b8b0dSShuming Fan 		if (val_ll > mc->max)
537320b8b0dSShuming Fan 			val_ll = mc->max;
538320b8b0dSShuming Fan 		/* keep mute status */
539320b8b0dSShuming Fan 		read_ll = read_ll & (1 << RT711_MUTE_SFT);
540320b8b0dSShuming Fan 		val_ll |= read_ll;
541320b8b0dSShuming Fan 	}
542320b8b0dSShuming Fan 
543320b8b0dSShuming Fan 	if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)
544320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
545320b8b0dSShuming Fan 				RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D0);
546320b8b0dSShuming Fan 
547320b8b0dSShuming Fan 	/* R Channel */
548320b8b0dSShuming Fan 	if (mc->invert) {
549320b8b0dSShuming Fan 		/* for mute/unmute */
550320b8b0dSShuming Fan 		val_lr = (mc->max - ucontrol->value.integer.value[1])
551320b8b0dSShuming Fan 					<< RT711_MUTE_SFT;
552320b8b0dSShuming Fan 		/* keep gain */
553320b8b0dSShuming Fan 		read_rl = read_rl & 0x7f;
554320b8b0dSShuming Fan 		val_lr |= read_rl;
555320b8b0dSShuming Fan 	} else {
556320b8b0dSShuming Fan 		/* for gain */
557320b8b0dSShuming Fan 		val_lr = ((ucontrol->value.integer.value[1]) & 0x7f);
558320b8b0dSShuming Fan 		if (val_lr > mc->max)
559320b8b0dSShuming Fan 			val_lr = mc->max;
560320b8b0dSShuming Fan 		/* keep mute status */
561320b8b0dSShuming Fan 		read_rl = read_rl & (1 << RT711_MUTE_SFT);
562320b8b0dSShuming Fan 		val_lr |= read_rl;
563320b8b0dSShuming Fan 	}
564320b8b0dSShuming Fan 
565320b8b0dSShuming Fan 	for (i = 0; i < 3; i++) { /* retry 3 times at most */
566320b8b0dSShuming Fan 
567320b8b0dSShuming Fan 		if (val_ll == val_lr) {
568320b8b0dSShuming Fan 			/* Set both L/R channels at the same time */
569320b8b0dSShuming Fan 			val_h = (1 << mc->shift) | (3 << 4);
570320b8b0dSShuming Fan 			regmap_write(rt711->regmap,
571320b8b0dSShuming Fan 				addr_h, (val_h << 8 | val_ll));
572320b8b0dSShuming Fan 			regmap_write(rt711->regmap,
573320b8b0dSShuming Fan 				addr_l, (val_h << 8 | val_ll));
574320b8b0dSShuming Fan 		} else {
575320b8b0dSShuming Fan 			/* Lch*/
576320b8b0dSShuming Fan 			val_h = (1 << mc->shift) | (1 << 5);
577320b8b0dSShuming Fan 			regmap_write(rt711->regmap,
578320b8b0dSShuming Fan 				addr_h, (val_h << 8 | val_ll));
579320b8b0dSShuming Fan 
580320b8b0dSShuming Fan 			/* Rch */
581320b8b0dSShuming Fan 			val_h = (1 << mc->shift) | (1 << 4);
582320b8b0dSShuming Fan 			regmap_write(rt711->regmap,
583320b8b0dSShuming Fan 				addr_l, (val_h << 8 | val_lr));
584320b8b0dSShuming Fan 		}
585320b8b0dSShuming Fan 		/* check result */
586320b8b0dSShuming Fan 		if (mc->shift == RT711_DIR_OUT_SFT) /* output */
587320b8b0dSShuming Fan 			val_h = 0x80;
588320b8b0dSShuming Fan 		else /* input */
589320b8b0dSShuming Fan 			val_h = 0x0;
590320b8b0dSShuming Fan 
591320b8b0dSShuming Fan 		rt711_get_gain(rt711, addr_h, addr_l, val_h,
592320b8b0dSShuming Fan 					&read_rl, &read_ll);
593320b8b0dSShuming Fan 		if (read_rl == val_lr && read_ll == val_ll)
594320b8b0dSShuming Fan 			break;
595320b8b0dSShuming Fan 	}
596320b8b0dSShuming Fan 
597320b8b0dSShuming Fan 	if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)
598320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
599320b8b0dSShuming Fan 				RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D3);
6006108f990SShuming Fan 
6016108f990SShuming Fan 	mutex_unlock(&rt711->calibrate_mutex);
602320b8b0dSShuming Fan 	return 0;
603320b8b0dSShuming Fan }
604320b8b0dSShuming Fan 
605320b8b0dSShuming Fan static int rt711_set_amp_gain_get(struct snd_kcontrol *kcontrol,
606320b8b0dSShuming Fan 		struct snd_ctl_elem_value *ucontrol)
607320b8b0dSShuming Fan {
608320b8b0dSShuming Fan 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
609320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
610320b8b0dSShuming Fan 	struct soc_mixer_control *mc =
611320b8b0dSShuming Fan 		(struct soc_mixer_control *)kcontrol->private_value;
612320b8b0dSShuming Fan 	unsigned int addr_h, addr_l, val_h;
613320b8b0dSShuming Fan 	unsigned int read_ll, read_rl;
614320b8b0dSShuming Fan 
615320b8b0dSShuming Fan 	/* switch to get command */
616320b8b0dSShuming Fan 	addr_h = mc->reg;
617320b8b0dSShuming Fan 	addr_l = mc->rreg;
618320b8b0dSShuming Fan 	if (mc->shift == RT711_DIR_OUT_SFT) /* output */
619320b8b0dSShuming Fan 		val_h = 0x80;
620320b8b0dSShuming Fan 	else /* input */
621320b8b0dSShuming Fan 		val_h = 0x0;
622320b8b0dSShuming Fan 
623320b8b0dSShuming Fan 	rt711_get_gain(rt711, addr_h, addr_l, val_h, &read_rl, &read_ll);
624320b8b0dSShuming Fan 
625320b8b0dSShuming Fan 	if (mc->invert) {
626320b8b0dSShuming Fan 		/* mute/unmute for switch controls */
627320b8b0dSShuming Fan 		read_ll = !((read_ll & 0x80) >> RT711_MUTE_SFT);
628320b8b0dSShuming Fan 		read_rl = !((read_rl & 0x80) >> RT711_MUTE_SFT);
629320b8b0dSShuming Fan 	} else {
630320b8b0dSShuming Fan 		/* for gain volume controls */
631320b8b0dSShuming Fan 		read_ll = read_ll & 0x7f;
632320b8b0dSShuming Fan 		read_rl = read_rl & 0x7f;
633320b8b0dSShuming Fan 	}
634320b8b0dSShuming Fan 	ucontrol->value.integer.value[0] = read_ll;
635320b8b0dSShuming Fan 	ucontrol->value.integer.value[1] = read_rl;
636320b8b0dSShuming Fan 
637320b8b0dSShuming Fan 	return 0;
638320b8b0dSShuming Fan }
639320b8b0dSShuming Fan 
640320b8b0dSShuming Fan static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6525, 75, 0);
641320b8b0dSShuming Fan static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0);
642320b8b0dSShuming Fan static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
643320b8b0dSShuming Fan 
644320b8b0dSShuming Fan static const struct snd_kcontrol_new rt711_snd_controls[] = {
645320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT_TLV("DAC Surr Playback Volume",
646320b8b0dSShuming Fan 		RT711_SET_GAIN_DAC2_H, RT711_SET_GAIN_DAC2_L,
647320b8b0dSShuming Fan 		RT711_DIR_OUT_SFT, 0x57, 0,
648320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put, out_vol_tlv),
649320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT("ADC 08 Capture Switch",
650320b8b0dSShuming Fan 		RT711_SET_GAIN_ADC2_H, RT711_SET_GAIN_ADC2_L,
651320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 1, 1,
652320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put),
653320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT("ADC 09 Capture Switch",
654320b8b0dSShuming Fan 		RT711_SET_GAIN_ADC1_H, RT711_SET_GAIN_ADC1_L,
655320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 1, 1,
656320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put),
657320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT_TLV("ADC 08 Capture Volume",
658320b8b0dSShuming Fan 		RT711_SET_GAIN_ADC2_H, RT711_SET_GAIN_ADC2_L,
659320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 0x3f, 0,
660320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put, in_vol_tlv),
661320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT_TLV("ADC 09 Capture Volume",
662320b8b0dSShuming Fan 		RT711_SET_GAIN_ADC1_H, RT711_SET_GAIN_ADC1_L,
663320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 0x3f, 0,
664320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put, in_vol_tlv),
665320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT_TLV("AMIC Volume",
666320b8b0dSShuming Fan 		RT711_SET_GAIN_AMIC_H, RT711_SET_GAIN_AMIC_L,
667320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 3, 0,
668320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put, mic_vol_tlv),
669320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT_TLV("DMIC1 Volume",
670320b8b0dSShuming Fan 		RT711_SET_GAIN_DMIC1_H, RT711_SET_GAIN_DMIC1_L,
671320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 3, 0,
672320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put, mic_vol_tlv),
673320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT_TLV("DMIC2 Volume",
674320b8b0dSShuming Fan 		RT711_SET_GAIN_DMIC2_H, RT711_SET_GAIN_DMIC2_L,
675320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 3, 0,
676320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put, mic_vol_tlv),
677320b8b0dSShuming Fan };
678320b8b0dSShuming Fan 
679320b8b0dSShuming Fan static int rt711_mux_get(struct snd_kcontrol *kcontrol,
680320b8b0dSShuming Fan 			struct snd_ctl_elem_value *ucontrol)
681320b8b0dSShuming Fan {
682320b8b0dSShuming Fan 	struct snd_soc_component *component =
683320b8b0dSShuming Fan 		snd_soc_dapm_kcontrol_component(kcontrol);
684320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
685320b8b0dSShuming Fan 	unsigned int reg, val = 0, nid;
686320b8b0dSShuming Fan 	int ret;
687320b8b0dSShuming Fan 
688320b8b0dSShuming Fan 	if (strstr(ucontrol->id.name, "ADC 22 Mux"))
689320b8b0dSShuming Fan 		nid = RT711_MIXER_IN1;
690320b8b0dSShuming Fan 	else if (strstr(ucontrol->id.name, "ADC 23 Mux"))
691320b8b0dSShuming Fan 		nid = RT711_MIXER_IN2;
692320b8b0dSShuming Fan 	else
693320b8b0dSShuming Fan 		return -EINVAL;
694320b8b0dSShuming Fan 
695320b8b0dSShuming Fan 	/* vid = 0xf01 */
696320b8b0dSShuming Fan 	reg = RT711_VERB_SET_CONNECT_SEL | nid;
697320b8b0dSShuming Fan 	ret = regmap_read(rt711->regmap, reg, &val);
698320b8b0dSShuming Fan 	if (ret < 0) {
699320b8b0dSShuming Fan 		dev_err(component->dev, "%s: sdw read failed: %d\n",
700320b8b0dSShuming Fan 			__func__, ret);
701320b8b0dSShuming Fan 		return ret;
702320b8b0dSShuming Fan 	}
703320b8b0dSShuming Fan 
704320b8b0dSShuming Fan 	ucontrol->value.enumerated.item[0] = val;
705320b8b0dSShuming Fan 
706320b8b0dSShuming Fan 	return 0;
707320b8b0dSShuming Fan }
708320b8b0dSShuming Fan 
709320b8b0dSShuming Fan static int rt711_mux_put(struct snd_kcontrol *kcontrol,
710320b8b0dSShuming Fan 			struct snd_ctl_elem_value *ucontrol)
711320b8b0dSShuming Fan {
712320b8b0dSShuming Fan 	struct snd_soc_component *component =
713320b8b0dSShuming Fan 		snd_soc_dapm_kcontrol_component(kcontrol);
714320b8b0dSShuming Fan 	struct snd_soc_dapm_context *dapm =
715320b8b0dSShuming Fan 		snd_soc_dapm_kcontrol_dapm(kcontrol);
716320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
717320b8b0dSShuming Fan 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
718320b8b0dSShuming Fan 	unsigned int *item = ucontrol->value.enumerated.item;
719320b8b0dSShuming Fan 	unsigned int val, val2 = 0, change, reg, nid;
720320b8b0dSShuming Fan 	int ret;
721320b8b0dSShuming Fan 
722320b8b0dSShuming Fan 	if (item[0] >= e->items)
723320b8b0dSShuming Fan 		return -EINVAL;
724320b8b0dSShuming Fan 
725320b8b0dSShuming Fan 	if (strstr(ucontrol->id.name, "ADC 22 Mux"))
726320b8b0dSShuming Fan 		nid = RT711_MIXER_IN1;
727320b8b0dSShuming Fan 	else if (strstr(ucontrol->id.name, "ADC 23 Mux"))
728320b8b0dSShuming Fan 		nid = RT711_MIXER_IN2;
729320b8b0dSShuming Fan 	else
730320b8b0dSShuming Fan 		return -EINVAL;
731320b8b0dSShuming Fan 
732320b8b0dSShuming Fan 	/* Verb ID = 0x701h */
733320b8b0dSShuming Fan 	val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
734320b8b0dSShuming Fan 
735320b8b0dSShuming Fan 	reg = RT711_VERB_SET_CONNECT_SEL | nid;
736320b8b0dSShuming Fan 	ret = regmap_read(rt711->regmap, reg, &val2);
737320b8b0dSShuming Fan 	if (ret < 0) {
738320b8b0dSShuming Fan 		dev_err(component->dev, "%s: sdw read failed: %d\n",
739320b8b0dSShuming Fan 			__func__, ret);
740320b8b0dSShuming Fan 		return ret;
741320b8b0dSShuming Fan 	}
742320b8b0dSShuming Fan 
743320b8b0dSShuming Fan 	if (val == val2)
744320b8b0dSShuming Fan 		change = 0;
745320b8b0dSShuming Fan 	else
746320b8b0dSShuming Fan 		change = 1;
747320b8b0dSShuming Fan 
748320b8b0dSShuming Fan 	if (change) {
749320b8b0dSShuming Fan 		reg = RT711_VERB_SET_CONNECT_SEL | nid;
750320b8b0dSShuming Fan 		regmap_write(rt711->regmap, reg, val);
751320b8b0dSShuming Fan 	}
752320b8b0dSShuming Fan 
753320b8b0dSShuming Fan 	snd_soc_dapm_mux_update_power(dapm, kcontrol,
754320b8b0dSShuming Fan 						item[0], e, NULL);
755320b8b0dSShuming Fan 
756320b8b0dSShuming Fan 	return change;
757320b8b0dSShuming Fan }
758320b8b0dSShuming Fan 
759320b8b0dSShuming Fan static const char * const adc_mux_text[] = {
760320b8b0dSShuming Fan 	"MIC2",
761320b8b0dSShuming Fan 	"LINE1",
762320b8b0dSShuming Fan 	"LINE2",
763320b8b0dSShuming Fan 	"DMIC",
764320b8b0dSShuming Fan };
765320b8b0dSShuming Fan 
766320b8b0dSShuming Fan static SOC_ENUM_SINGLE_DECL(
767320b8b0dSShuming Fan 	rt711_adc22_enum, SND_SOC_NOPM, 0, adc_mux_text);
768320b8b0dSShuming Fan 
769320b8b0dSShuming Fan static SOC_ENUM_SINGLE_DECL(
770320b8b0dSShuming Fan 	rt711_adc23_enum, SND_SOC_NOPM, 0, adc_mux_text);
771320b8b0dSShuming Fan 
772320b8b0dSShuming Fan static const struct snd_kcontrol_new rt711_adc22_mux =
773320b8b0dSShuming Fan 	SOC_DAPM_ENUM_EXT("ADC 22 Mux", rt711_adc22_enum,
774320b8b0dSShuming Fan 			rt711_mux_get, rt711_mux_put);
775320b8b0dSShuming Fan 
776320b8b0dSShuming Fan static const struct snd_kcontrol_new rt711_adc23_mux =
777320b8b0dSShuming Fan 	SOC_DAPM_ENUM_EXT("ADC 23 Mux", rt711_adc23_enum,
778320b8b0dSShuming Fan 			rt711_mux_get, rt711_mux_put);
779320b8b0dSShuming Fan 
780320b8b0dSShuming Fan static int rt711_dac_surround_event(struct snd_soc_dapm_widget *w,
781320b8b0dSShuming Fan 	struct snd_kcontrol *kcontrol, int event)
782320b8b0dSShuming Fan {
783320b8b0dSShuming Fan 	struct snd_soc_component *component =
784320b8b0dSShuming Fan 		snd_soc_dapm_to_component(w->dapm);
785320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
786320b8b0dSShuming Fan 	unsigned int val_h = (1 << RT711_DIR_OUT_SFT) | (0x3 << 4);
787320b8b0dSShuming Fan 	unsigned int val_l;
788320b8b0dSShuming Fan 
789320b8b0dSShuming Fan 	switch (event) {
790320b8b0dSShuming Fan 	case SND_SOC_DAPM_POST_PMU:
791320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
792320b8b0dSShuming Fan 			RT711_SET_STREAMID_DAC2, 0x10);
793320b8b0dSShuming Fan 
794320b8b0dSShuming Fan 		val_l = 0x00;
795320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
796320b8b0dSShuming Fan 			RT711_SET_GAIN_HP_H, (val_h << 8 | val_l));
797320b8b0dSShuming Fan 		break;
798320b8b0dSShuming Fan 	case SND_SOC_DAPM_PRE_PMD:
799320b8b0dSShuming Fan 		val_l = (1 << RT711_MUTE_SFT);
800320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
801320b8b0dSShuming Fan 			RT711_SET_GAIN_HP_H, (val_h << 8 | val_l));
802320b8b0dSShuming Fan 		usleep_range(50000, 55000);
803320b8b0dSShuming Fan 
804320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
805320b8b0dSShuming Fan 			RT711_SET_STREAMID_DAC2, 0x00);
806320b8b0dSShuming Fan 		break;
807320b8b0dSShuming Fan 	}
808320b8b0dSShuming Fan 	return 0;
809320b8b0dSShuming Fan }
810320b8b0dSShuming Fan 
811320b8b0dSShuming Fan static int rt711_adc_09_event(struct snd_soc_dapm_widget *w,
812320b8b0dSShuming Fan 	struct snd_kcontrol *kcontrol, int event)
813320b8b0dSShuming Fan {
814320b8b0dSShuming Fan 	struct snd_soc_component *component =
815320b8b0dSShuming Fan 		snd_soc_dapm_to_component(w->dapm);
816320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
817320b8b0dSShuming Fan 
818320b8b0dSShuming Fan 	switch (event) {
819320b8b0dSShuming Fan 	case SND_SOC_DAPM_POST_PMU:
820320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
821320b8b0dSShuming Fan 			RT711_SET_STREAMID_ADC1, 0x10);
822320b8b0dSShuming Fan 		break;
823320b8b0dSShuming Fan 	case SND_SOC_DAPM_PRE_PMD:
824320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
825320b8b0dSShuming Fan 			RT711_SET_STREAMID_ADC1, 0x00);
826320b8b0dSShuming Fan 		break;
827320b8b0dSShuming Fan 	}
828320b8b0dSShuming Fan 	return 0;
829320b8b0dSShuming Fan }
830320b8b0dSShuming Fan 
831320b8b0dSShuming Fan static int rt711_adc_08_event(struct snd_soc_dapm_widget *w,
832320b8b0dSShuming Fan 	struct snd_kcontrol *kcontrol, int event)
833320b8b0dSShuming Fan {
834320b8b0dSShuming Fan 	struct snd_soc_component *component =
835320b8b0dSShuming Fan 		snd_soc_dapm_to_component(w->dapm);
836320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
837320b8b0dSShuming Fan 
838320b8b0dSShuming Fan 	switch (event) {
839320b8b0dSShuming Fan 	case SND_SOC_DAPM_POST_PMU:
840320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
841320b8b0dSShuming Fan 			RT711_SET_STREAMID_ADC2, 0x10);
842320b8b0dSShuming Fan 		break;
843320b8b0dSShuming Fan 	case SND_SOC_DAPM_PRE_PMD:
844320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
845320b8b0dSShuming Fan 			RT711_SET_STREAMID_ADC2, 0x00);
846320b8b0dSShuming Fan 		break;
847320b8b0dSShuming Fan 	}
848320b8b0dSShuming Fan 	return 0;
849320b8b0dSShuming Fan }
850320b8b0dSShuming Fan 
851320b8b0dSShuming Fan static const struct snd_soc_dapm_widget rt711_dapm_widgets[] = {
852320b8b0dSShuming Fan 	SND_SOC_DAPM_OUTPUT("HP"),
853320b8b0dSShuming Fan 	SND_SOC_DAPM_INPUT("MIC2"),
854320b8b0dSShuming Fan 	SND_SOC_DAPM_INPUT("DMIC1"),
855320b8b0dSShuming Fan 	SND_SOC_DAPM_INPUT("DMIC2"),
856320b8b0dSShuming Fan 	SND_SOC_DAPM_INPUT("LINE1"),
857320b8b0dSShuming Fan 	SND_SOC_DAPM_INPUT("LINE2"),
858320b8b0dSShuming Fan 
859320b8b0dSShuming Fan 	SND_SOC_DAPM_DAC_E("DAC Surround", NULL, SND_SOC_NOPM, 0, 0,
860320b8b0dSShuming Fan 		rt711_dac_surround_event,
861320b8b0dSShuming Fan 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
862320b8b0dSShuming Fan 	SND_SOC_DAPM_ADC_E("ADC 09", NULL, SND_SOC_NOPM, 0, 0,
863320b8b0dSShuming Fan 		rt711_adc_09_event,
864320b8b0dSShuming Fan 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
865320b8b0dSShuming Fan 	SND_SOC_DAPM_ADC_E("ADC 08", NULL, SND_SOC_NOPM, 0, 0,
866320b8b0dSShuming Fan 		rt711_adc_08_event,
867320b8b0dSShuming Fan 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
868320b8b0dSShuming Fan 	SND_SOC_DAPM_MUX("ADC 22 Mux", SND_SOC_NOPM, 0, 0,
869320b8b0dSShuming Fan 		&rt711_adc22_mux),
870320b8b0dSShuming Fan 	SND_SOC_DAPM_MUX("ADC 23 Mux", SND_SOC_NOPM, 0, 0,
871320b8b0dSShuming Fan 		&rt711_adc23_mux),
872320b8b0dSShuming Fan 
873320b8b0dSShuming Fan 	SND_SOC_DAPM_AIF_IN("DP3RX", "DP3 Playback", 0, SND_SOC_NOPM, 0, 0),
874320b8b0dSShuming Fan 	SND_SOC_DAPM_AIF_OUT("DP2TX", "DP2 Capture", 0, SND_SOC_NOPM, 0, 0),
875320b8b0dSShuming Fan 	SND_SOC_DAPM_AIF_OUT("DP4TX", "DP4 Capture", 0, SND_SOC_NOPM, 0, 0),
876320b8b0dSShuming Fan };
877320b8b0dSShuming Fan 
878320b8b0dSShuming Fan static const struct snd_soc_dapm_route rt711_audio_map[] = {
879320b8b0dSShuming Fan 	{"DAC Surround", NULL, "DP3RX"},
880320b8b0dSShuming Fan 	{"DP2TX", NULL, "ADC 09"},
881320b8b0dSShuming Fan 	{"DP4TX", NULL, "ADC 08"},
882320b8b0dSShuming Fan 
883320b8b0dSShuming Fan 	{"ADC 09", NULL, "ADC 22 Mux"},
884320b8b0dSShuming Fan 	{"ADC 08", NULL, "ADC 23 Mux"},
885320b8b0dSShuming Fan 	{"ADC 22 Mux", "DMIC", "DMIC1"},
886320b8b0dSShuming Fan 	{"ADC 22 Mux", "LINE1", "LINE1"},
887320b8b0dSShuming Fan 	{"ADC 22 Mux", "LINE2", "LINE2"},
888320b8b0dSShuming Fan 	{"ADC 22 Mux", "MIC2", "MIC2"},
889320b8b0dSShuming Fan 	{"ADC 23 Mux", "DMIC", "DMIC2"},
890320b8b0dSShuming Fan 	{"ADC 23 Mux", "LINE1", "LINE1"},
891320b8b0dSShuming Fan 	{"ADC 23 Mux", "LINE2", "LINE2"},
892320b8b0dSShuming Fan 	{"ADC 23 Mux", "MIC2", "MIC2"},
893320b8b0dSShuming Fan 
894320b8b0dSShuming Fan 	{"HP", NULL, "DAC Surround"},
895320b8b0dSShuming Fan };
896320b8b0dSShuming Fan 
897320b8b0dSShuming Fan static int rt711_set_bias_level(struct snd_soc_component *component,
898320b8b0dSShuming Fan 				enum snd_soc_bias_level level)
899320b8b0dSShuming Fan {
900320b8b0dSShuming Fan 	struct snd_soc_dapm_context *dapm =
901320b8b0dSShuming Fan 		snd_soc_component_get_dapm(component);
902320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
903320b8b0dSShuming Fan 
904320b8b0dSShuming Fan 	switch (level) {
905320b8b0dSShuming Fan 	case SND_SOC_BIAS_PREPARE:
906320b8b0dSShuming Fan 		if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
907320b8b0dSShuming Fan 			regmap_write(rt711->regmap,
908320b8b0dSShuming Fan 				RT711_SET_AUDIO_POWER_STATE,
909320b8b0dSShuming Fan 				AC_PWRST_D0);
910320b8b0dSShuming Fan 		}
911320b8b0dSShuming Fan 		break;
912320b8b0dSShuming Fan 
913320b8b0dSShuming Fan 	case SND_SOC_BIAS_STANDBY:
9146108f990SShuming Fan 		mutex_lock(&rt711->calibrate_mutex);
915320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
916320b8b0dSShuming Fan 			RT711_SET_AUDIO_POWER_STATE,
917320b8b0dSShuming Fan 			AC_PWRST_D3);
9186108f990SShuming Fan 		mutex_unlock(&rt711->calibrate_mutex);
919320b8b0dSShuming Fan 		break;
920320b8b0dSShuming Fan 
921320b8b0dSShuming Fan 	default:
922320b8b0dSShuming Fan 		break;
923320b8b0dSShuming Fan 	}
924320b8b0dSShuming Fan 
925320b8b0dSShuming Fan 	return 0;
926320b8b0dSShuming Fan }
927320b8b0dSShuming Fan 
928320b8b0dSShuming Fan static int rt711_parse_dt(struct rt711_priv *rt711, struct device *dev)
929320b8b0dSShuming Fan {
930320b8b0dSShuming Fan 	device_property_read_u32(dev, "realtek,jd-src",
931320b8b0dSShuming Fan 		&rt711->jd_src);
932320b8b0dSShuming Fan 
933320b8b0dSShuming Fan 	return 0;
934320b8b0dSShuming Fan }
935320b8b0dSShuming Fan 
936320b8b0dSShuming Fan static int rt711_probe(struct snd_soc_component *component)
937320b8b0dSShuming Fan {
938320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
939011e397fSPierre-Louis Bossart 	int ret;
940320b8b0dSShuming Fan 
941320b8b0dSShuming Fan 	rt711_parse_dt(rt711, &rt711->slave->dev);
942320b8b0dSShuming Fan 	rt711->component = component;
943320b8b0dSShuming Fan 
944011e397fSPierre-Louis Bossart 	ret = pm_runtime_resume(component->dev);
945011e397fSPierre-Louis Bossart 	if (ret < 0 && ret != -EACCES)
946011e397fSPierre-Louis Bossart 		return ret;
947011e397fSPierre-Louis Bossart 
948320b8b0dSShuming Fan 	return 0;
949320b8b0dSShuming Fan }
950320b8b0dSShuming Fan 
951320b8b0dSShuming Fan static const struct snd_soc_component_driver soc_codec_dev_rt711 = {
952320b8b0dSShuming Fan 	.probe = rt711_probe,
953320b8b0dSShuming Fan 	.set_bias_level = rt711_set_bias_level,
954320b8b0dSShuming Fan 	.controls = rt711_snd_controls,
955320b8b0dSShuming Fan 	.num_controls = ARRAY_SIZE(rt711_snd_controls),
956320b8b0dSShuming Fan 	.dapm_widgets = rt711_dapm_widgets,
957320b8b0dSShuming Fan 	.num_dapm_widgets = ARRAY_SIZE(rt711_dapm_widgets),
958320b8b0dSShuming Fan 	.dapm_routes = rt711_audio_map,
959320b8b0dSShuming Fan 	.num_dapm_routes = ARRAY_SIZE(rt711_audio_map),
960320b8b0dSShuming Fan 	.set_jack = rt711_set_jack_detect,
96133f06beaSCharles Keepax 	.endianness = 1,
962320b8b0dSShuming Fan };
963320b8b0dSShuming Fan 
964320b8b0dSShuming Fan static int rt711_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
965320b8b0dSShuming Fan 				int direction)
966320b8b0dSShuming Fan {
967fa55b31fSPierre-Louis Bossart 	snd_soc_dai_dma_data_set(dai, direction, sdw_stream);
968320b8b0dSShuming Fan 
969320b8b0dSShuming Fan 	return 0;
970320b8b0dSShuming Fan }
971320b8b0dSShuming Fan 
972320b8b0dSShuming Fan static void rt711_shutdown(struct snd_pcm_substream *substream,
973320b8b0dSShuming Fan 				struct snd_soc_dai *dai)
974320b8b0dSShuming Fan {
975320b8b0dSShuming Fan 	snd_soc_dai_set_dma_data(dai, substream, NULL);
976320b8b0dSShuming Fan }
977320b8b0dSShuming Fan 
978320b8b0dSShuming Fan static int rt711_pcm_hw_params(struct snd_pcm_substream *substream,
979320b8b0dSShuming Fan 				struct snd_pcm_hw_params *params,
980320b8b0dSShuming Fan 				struct snd_soc_dai *dai)
981320b8b0dSShuming Fan {
982320b8b0dSShuming Fan 	struct snd_soc_component *component = dai->component;
983320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
984754bef67SCharles Keepax 	struct sdw_stream_config stream_config = {0};
985754bef67SCharles Keepax 	struct sdw_port_config port_config = {0};
986fa55b31fSPierre-Louis Bossart 	struct sdw_stream_runtime *sdw_stream;
987754bef67SCharles Keepax 	int retval;
988320b8b0dSShuming Fan 	unsigned int val = 0;
989320b8b0dSShuming Fan 
990320b8b0dSShuming Fan 	dev_dbg(dai->dev, "%s %s", __func__, dai->name);
991fa55b31fSPierre-Louis Bossart 	sdw_stream = snd_soc_dai_get_dma_data(dai, substream);
992320b8b0dSShuming Fan 
993fa55b31fSPierre-Louis Bossart 	if (!sdw_stream)
994320b8b0dSShuming Fan 		return -EINVAL;
995320b8b0dSShuming Fan 
996320b8b0dSShuming Fan 	if (!rt711->slave)
997320b8b0dSShuming Fan 		return -EINVAL;
998320b8b0dSShuming Fan 
999320b8b0dSShuming Fan 	/* SoundWire specific configuration */
1000754bef67SCharles Keepax 	snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
1001754bef67SCharles Keepax 
1002320b8b0dSShuming Fan 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1003754bef67SCharles Keepax 		port_config.num = 3;
1004320b8b0dSShuming Fan 	} else {
1005320b8b0dSShuming Fan 		if (dai->id == RT711_AIF1)
1006754bef67SCharles Keepax 			port_config.num = 4;
1007320b8b0dSShuming Fan 		else if (dai->id == RT711_AIF2)
1008754bef67SCharles Keepax 			port_config.num = 2;
1009320b8b0dSShuming Fan 		else
1010320b8b0dSShuming Fan 			return -EINVAL;
1011320b8b0dSShuming Fan 	}
1012320b8b0dSShuming Fan 
1013320b8b0dSShuming Fan 	retval = sdw_stream_add_slave(rt711->slave, &stream_config,
1014fa55b31fSPierre-Louis Bossart 					&port_config, 1, sdw_stream);
1015320b8b0dSShuming Fan 	if (retval) {
1016320b8b0dSShuming Fan 		dev_err(dai->dev, "Unable to configure port\n");
1017320b8b0dSShuming Fan 		return retval;
1018320b8b0dSShuming Fan 	}
1019320b8b0dSShuming Fan 
1020320b8b0dSShuming Fan 	if (params_channels(params) <= 16) {
1021320b8b0dSShuming Fan 		/* bit 3:0 Number of Channel */
1022320b8b0dSShuming Fan 		val |= (params_channels(params) - 1);
1023320b8b0dSShuming Fan 	} else {
1024320b8b0dSShuming Fan 		dev_err(component->dev, "Unsupported channels %d\n",
1025320b8b0dSShuming Fan 			params_channels(params));
1026320b8b0dSShuming Fan 		return -EINVAL;
1027320b8b0dSShuming Fan 	}
1028320b8b0dSShuming Fan 
1029320b8b0dSShuming Fan 	switch (params_width(params)) {
1030320b8b0dSShuming Fan 	/* bit 6:4 Bits per Sample */
1031320b8b0dSShuming Fan 	case 8:
1032320b8b0dSShuming Fan 		break;
1033320b8b0dSShuming Fan 	case 16:
1034320b8b0dSShuming Fan 		val |= (0x1 << 4);
1035320b8b0dSShuming Fan 		break;
1036320b8b0dSShuming Fan 	case 20:
1037320b8b0dSShuming Fan 		val |= (0x2 << 4);
1038320b8b0dSShuming Fan 		break;
1039320b8b0dSShuming Fan 	case 24:
1040320b8b0dSShuming Fan 		val |= (0x3 << 4);
1041320b8b0dSShuming Fan 		break;
1042320b8b0dSShuming Fan 	case 32:
1043320b8b0dSShuming Fan 		val |= (0x4 << 4);
1044320b8b0dSShuming Fan 		break;
1045320b8b0dSShuming Fan 	default:
1046320b8b0dSShuming Fan 		return -EINVAL;
1047320b8b0dSShuming Fan 	}
1048320b8b0dSShuming Fan 
1049320b8b0dSShuming Fan 	/* 48Khz */
1050320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_DAC_FORMAT_H, val);
1051320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_ADC1_FORMAT_H, val);
1052320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_ADC2_FORMAT_H, val);
1053320b8b0dSShuming Fan 
1054320b8b0dSShuming Fan 	return retval;
1055320b8b0dSShuming Fan }
1056320b8b0dSShuming Fan 
1057320b8b0dSShuming Fan static int rt711_pcm_hw_free(struct snd_pcm_substream *substream,
1058320b8b0dSShuming Fan 				struct snd_soc_dai *dai)
1059320b8b0dSShuming Fan {
1060320b8b0dSShuming Fan 	struct snd_soc_component *component = dai->component;
1061320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
1062fa55b31fSPierre-Louis Bossart 	struct sdw_stream_runtime *sdw_stream =
1063320b8b0dSShuming Fan 		snd_soc_dai_get_dma_data(dai, substream);
1064320b8b0dSShuming Fan 
1065320b8b0dSShuming Fan 	if (!rt711->slave)
1066320b8b0dSShuming Fan 		return -EINVAL;
1067320b8b0dSShuming Fan 
1068fa55b31fSPierre-Louis Bossart 	sdw_stream_remove_slave(rt711->slave, sdw_stream);
1069320b8b0dSShuming Fan 	return 0;
1070320b8b0dSShuming Fan }
1071320b8b0dSShuming Fan 
1072320b8b0dSShuming Fan #define RT711_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
1073320b8b0dSShuming Fan #define RT711_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1074320b8b0dSShuming Fan 			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
1075320b8b0dSShuming Fan 
1076f9e56a34SRikard Falkeborn static const struct snd_soc_dai_ops rt711_ops = {
1077320b8b0dSShuming Fan 	.hw_params	= rt711_pcm_hw_params,
1078320b8b0dSShuming Fan 	.hw_free	= rt711_pcm_hw_free,
1079e8444560SPierre-Louis Bossart 	.set_stream	= rt711_set_sdw_stream,
1080320b8b0dSShuming Fan 	.shutdown	= rt711_shutdown,
1081320b8b0dSShuming Fan };
1082320b8b0dSShuming Fan 
1083320b8b0dSShuming Fan static struct snd_soc_dai_driver rt711_dai[] = {
1084320b8b0dSShuming Fan 	{
1085320b8b0dSShuming Fan 		.name = "rt711-aif1",
1086320b8b0dSShuming Fan 		.id = RT711_AIF1,
1087320b8b0dSShuming Fan 		.playback = {
1088320b8b0dSShuming Fan 			.stream_name = "DP3 Playback",
1089320b8b0dSShuming Fan 			.channels_min = 1,
1090320b8b0dSShuming Fan 			.channels_max = 2,
1091320b8b0dSShuming Fan 			.rates = RT711_STEREO_RATES,
1092320b8b0dSShuming Fan 			.formats = RT711_FORMATS,
1093320b8b0dSShuming Fan 		},
1094320b8b0dSShuming Fan 		.capture = {
1095320b8b0dSShuming Fan 			.stream_name = "DP4 Capture",
1096320b8b0dSShuming Fan 			.channels_min = 1,
1097320b8b0dSShuming Fan 			.channels_max = 2,
1098320b8b0dSShuming Fan 			.rates = RT711_STEREO_RATES,
1099320b8b0dSShuming Fan 			.formats = RT711_FORMATS,
1100320b8b0dSShuming Fan 		},
1101320b8b0dSShuming Fan 		.ops = &rt711_ops,
1102320b8b0dSShuming Fan 	},
1103320b8b0dSShuming Fan 	{
1104320b8b0dSShuming Fan 		.name = "rt711-aif2",
1105320b8b0dSShuming Fan 		.id = RT711_AIF2,
1106320b8b0dSShuming Fan 		.capture = {
1107320b8b0dSShuming Fan 			.stream_name = "DP2 Capture",
1108320b8b0dSShuming Fan 			.channels_min = 1,
1109320b8b0dSShuming Fan 			.channels_max = 2,
1110320b8b0dSShuming Fan 			.rates = RT711_STEREO_RATES,
1111320b8b0dSShuming Fan 			.formats = RT711_FORMATS,
1112320b8b0dSShuming Fan 		},
1113320b8b0dSShuming Fan 		.ops = &rt711_ops,
1114320b8b0dSShuming Fan 	}
1115320b8b0dSShuming Fan };
1116320b8b0dSShuming Fan 
1117320b8b0dSShuming Fan /* Bus clock frequency */
1118320b8b0dSShuming Fan #define RT711_CLK_FREQ_9600000HZ 9600000
1119320b8b0dSShuming Fan #define RT711_CLK_FREQ_12000000HZ 12000000
1120320b8b0dSShuming Fan #define RT711_CLK_FREQ_6000000HZ 6000000
1121320b8b0dSShuming Fan #define RT711_CLK_FREQ_4800000HZ 4800000
1122320b8b0dSShuming Fan #define RT711_CLK_FREQ_2400000HZ 2400000
1123320b8b0dSShuming Fan #define RT711_CLK_FREQ_12288000HZ 12288000
1124320b8b0dSShuming Fan 
1125320b8b0dSShuming Fan int rt711_clock_config(struct device *dev)
1126320b8b0dSShuming Fan {
1127320b8b0dSShuming Fan 	struct rt711_priv *rt711 = dev_get_drvdata(dev);
1128320b8b0dSShuming Fan 	unsigned int clk_freq, value;
1129320b8b0dSShuming Fan 
1130320b8b0dSShuming Fan 	clk_freq = (rt711->params.curr_dr_freq >> 1);
1131320b8b0dSShuming Fan 
1132320b8b0dSShuming Fan 	switch (clk_freq) {
1133320b8b0dSShuming Fan 	case RT711_CLK_FREQ_12000000HZ:
1134320b8b0dSShuming Fan 		value = 0x0;
1135320b8b0dSShuming Fan 		break;
1136320b8b0dSShuming Fan 	case RT711_CLK_FREQ_6000000HZ:
1137320b8b0dSShuming Fan 		value = 0x1;
1138320b8b0dSShuming Fan 		break;
1139320b8b0dSShuming Fan 	case RT711_CLK_FREQ_9600000HZ:
1140320b8b0dSShuming Fan 		value = 0x2;
1141320b8b0dSShuming Fan 		break;
1142320b8b0dSShuming Fan 	case RT711_CLK_FREQ_4800000HZ:
1143320b8b0dSShuming Fan 		value = 0x3;
1144320b8b0dSShuming Fan 		break;
1145320b8b0dSShuming Fan 	case RT711_CLK_FREQ_2400000HZ:
1146320b8b0dSShuming Fan 		value = 0x4;
1147320b8b0dSShuming Fan 		break;
1148320b8b0dSShuming Fan 	case RT711_CLK_FREQ_12288000HZ:
1149320b8b0dSShuming Fan 		value = 0x5;
1150320b8b0dSShuming Fan 		break;
1151320b8b0dSShuming Fan 	default:
1152320b8b0dSShuming Fan 		return -EINVAL;
1153320b8b0dSShuming Fan 	}
1154320b8b0dSShuming Fan 
1155320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0xe0, value);
1156320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0xf0, value);
1157320b8b0dSShuming Fan 
1158320b8b0dSShuming Fan 	dev_dbg(dev, "%s complete, clk_freq=%d\n", __func__, clk_freq);
1159320b8b0dSShuming Fan 
1160320b8b0dSShuming Fan 	return 0;
1161320b8b0dSShuming Fan }
1162320b8b0dSShuming Fan 
1163320b8b0dSShuming Fan static void rt711_calibration_work(struct work_struct *work)
1164320b8b0dSShuming Fan {
1165320b8b0dSShuming Fan 	struct rt711_priv *rt711 =
1166320b8b0dSShuming Fan 		container_of(work, struct rt711_priv, calibration_work);
1167320b8b0dSShuming Fan 
1168320b8b0dSShuming Fan 	rt711_calibration(rt711);
1169320b8b0dSShuming Fan }
1170320b8b0dSShuming Fan 
1171320b8b0dSShuming Fan int rt711_init(struct device *dev, struct regmap *sdw_regmap,
1172320b8b0dSShuming Fan 			struct regmap *regmap, struct sdw_slave *slave)
1173320b8b0dSShuming Fan {
1174320b8b0dSShuming Fan 	struct rt711_priv *rt711;
1175320b8b0dSShuming Fan 	int ret;
1176320b8b0dSShuming Fan 
1177320b8b0dSShuming Fan 	rt711 = devm_kzalloc(dev, sizeof(*rt711), GFP_KERNEL);
1178320b8b0dSShuming Fan 	if (!rt711)
1179320b8b0dSShuming Fan 		return -ENOMEM;
1180320b8b0dSShuming Fan 
1181320b8b0dSShuming Fan 	dev_set_drvdata(dev, rt711);
1182320b8b0dSShuming Fan 	rt711->slave = slave;
1183320b8b0dSShuming Fan 	rt711->sdw_regmap = sdw_regmap;
1184320b8b0dSShuming Fan 	rt711->regmap = regmap;
1185320b8b0dSShuming Fan 
1186*49ae74abSPierre-Louis Bossart 	regcache_cache_only(rt711->regmap, true);
1187*49ae74abSPierre-Louis Bossart 
118874d40901SPierre-Louis Bossart 	mutex_init(&rt711->calibrate_mutex);
118918236370SPierre-Louis Bossart 	mutex_init(&rt711->disable_irq_lock);
119018236370SPierre-Louis Bossart 
1191a49267a3SPierre-Louis Bossart 	INIT_DELAYED_WORK(&rt711->jack_detect_work, rt711_jack_detect_handler);
1192a49267a3SPierre-Louis Bossart 	INIT_DELAYED_WORK(&rt711->jack_btn_check_work, rt711_btn_check_handler);
1193a49267a3SPierre-Louis Bossart 	INIT_WORK(&rt711->calibration_work, rt711_calibration_work);
1194a49267a3SPierre-Louis Bossart 
1195320b8b0dSShuming Fan 	/*
1196320b8b0dSShuming Fan 	 * Mark hw_init to false
1197320b8b0dSShuming Fan 	 * HW init will be performed when device reports present
1198320b8b0dSShuming Fan 	 */
1199320b8b0dSShuming Fan 	rt711->hw_init = false;
1200320b8b0dSShuming Fan 	rt711->first_hw_init = false;
1201320b8b0dSShuming Fan 
1202320b8b0dSShuming Fan 	/* JD source uses JD2 in default */
1203320b8b0dSShuming Fan 	rt711->jd_src = RT711_JD2;
1204320b8b0dSShuming Fan 
1205320b8b0dSShuming Fan 	ret =  devm_snd_soc_register_component(dev,
1206320b8b0dSShuming Fan 				&soc_codec_dev_rt711,
1207320b8b0dSShuming Fan 				rt711_dai,
1208320b8b0dSShuming Fan 				ARRAY_SIZE(rt711_dai));
1209320b8b0dSShuming Fan 
1210320b8b0dSShuming Fan 	dev_dbg(&slave->dev, "%s\n", __func__);
1211320b8b0dSShuming Fan 
1212320b8b0dSShuming Fan 	return ret;
1213320b8b0dSShuming Fan }
1214320b8b0dSShuming Fan 
1215320b8b0dSShuming Fan int rt711_io_init(struct device *dev, struct sdw_slave *slave)
1216320b8b0dSShuming Fan {
1217320b8b0dSShuming Fan 	struct rt711_priv *rt711 = dev_get_drvdata(dev);
1218320b8b0dSShuming Fan 
121918236370SPierre-Louis Bossart 	rt711->disable_irq = false;
122018236370SPierre-Louis Bossart 
1221320b8b0dSShuming Fan 	if (rt711->hw_init)
1222320b8b0dSShuming Fan 		return 0;
1223320b8b0dSShuming Fan 
1224320b8b0dSShuming Fan 	regcache_cache_only(rt711->regmap, false);
1225*49ae74abSPierre-Louis Bossart 	if (rt711->first_hw_init)
1226320b8b0dSShuming Fan 		regcache_cache_bypass(rt711->regmap, true);
1227320b8b0dSShuming Fan 
1228320b8b0dSShuming Fan 	/*
1229320b8b0dSShuming Fan 	 * PM runtime is only enabled when a Slave reports as Attached
1230320b8b0dSShuming Fan 	 */
1231320b8b0dSShuming Fan 	if (!rt711->first_hw_init) {
1232320b8b0dSShuming Fan 		/* set autosuspend parameters */
1233320b8b0dSShuming Fan 		pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
1234320b8b0dSShuming Fan 		pm_runtime_use_autosuspend(&slave->dev);
1235320b8b0dSShuming Fan 
1236320b8b0dSShuming Fan 		/* update count of parent 'active' children */
1237320b8b0dSShuming Fan 		pm_runtime_set_active(&slave->dev);
1238320b8b0dSShuming Fan 
1239320b8b0dSShuming Fan 		/* make sure the device does not suspend immediately */
1240320b8b0dSShuming Fan 		pm_runtime_mark_last_busy(&slave->dev);
1241320b8b0dSShuming Fan 
1242320b8b0dSShuming Fan 		pm_runtime_enable(&slave->dev);
1243320b8b0dSShuming Fan 	}
1244320b8b0dSShuming Fan 
1245320b8b0dSShuming Fan 	pm_runtime_get_noresume(&slave->dev);
1246320b8b0dSShuming Fan 
1247320b8b0dSShuming Fan 	rt711_reset(rt711->regmap);
1248320b8b0dSShuming Fan 
1249320b8b0dSShuming Fan 	/* power on */
1250320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D0);
1251320b8b0dSShuming Fan 
1252320b8b0dSShuming Fan 	/* Set Pin Widget */
1253320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_PIN_MIC2, 0x25);
1254320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_PIN_HP, 0xc0);
1255320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_PIN_DMIC1, 0x20);
1256320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_PIN_DMIC2, 0x20);
1257320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_PIN_LINE1, 0x20);
1258320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_PIN_LINE2, 0x20);
1259320b8b0dSShuming Fan 
1260320b8b0dSShuming Fan 	/* Mute HP/ADC1/ADC2 */
1261320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_GAIN_HP_H, 0xa080);
1262320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_GAIN_HP_H, 0x9080);
1263320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_GAIN_ADC2_H, 0x6080);
1264320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_GAIN_ADC2_H, 0x5080);
1265320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_GAIN_ADC1_H, 0x6080);
1266320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_GAIN_ADC1_H, 0x5080);
1267320b8b0dSShuming Fan 
1268320b8b0dSShuming Fan 	/* Set Configuration Default */
1269320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4f12, 0x91);
1270320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4e12, 0xd6);
1271320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4d12, 0x11);
1272320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4c12, 0x20);
1273320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4f13, 0x91);
1274320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4e13, 0xd6);
1275320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4d13, 0x11);
1276320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4c13, 0x21);
1277320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4c21, 0xf0);
1278320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4d21, 0x11);
1279320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4e21, 0x11);
1280320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4f21, 0x01);
1281320b8b0dSShuming Fan 
1282320b8b0dSShuming Fan 	/* Data port arrangement */
1283320b8b0dSShuming Fan 	rt711_index_write(rt711->regmap, RT711_VENDOR_REG,
1284320b8b0dSShuming Fan 		RT711_TX_RX_MUX_CTL, 0x0154);
1285320b8b0dSShuming Fan 
1286320b8b0dSShuming Fan 	/* Set index */
1287320b8b0dSShuming Fan 	rt711_index_write(rt711->regmap, RT711_VENDOR_REG,
1288320b8b0dSShuming Fan 		RT711_DIGITAL_MISC_CTRL4, 0x201b);
1289320b8b0dSShuming Fan 	rt711_index_write(rt711->regmap, RT711_VENDOR_REG,
1290320b8b0dSShuming Fan 		RT711_COMBO_JACK_AUTO_CTL1, 0x5089);
1291320b8b0dSShuming Fan 	rt711_index_write(rt711->regmap, RT711_VENDOR_REG,
1292320b8b0dSShuming Fan 		RT711_VREFOUT_CTL, 0x5064);
1293320b8b0dSShuming Fan 	rt711_index_write(rt711->regmap, RT711_VENDOR_REG,
1294320b8b0dSShuming Fan 		RT711_INLINE_CMD_CTL, 0xd249);
1295320b8b0dSShuming Fan 
1296320b8b0dSShuming Fan 	/* Finish Initial Settings, set power to D3 */
1297320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D3);
1298320b8b0dSShuming Fan 
1299320b8b0dSShuming Fan 	if (rt711->first_hw_init)
1300320b8b0dSShuming Fan 		rt711_calibration(rt711);
1301a49267a3SPierre-Louis Bossart 	else
1302320b8b0dSShuming Fan 		schedule_work(&rt711->calibration_work);
1303320b8b0dSShuming Fan 
1304320b8b0dSShuming Fan 	/*
1305320b8b0dSShuming Fan 	 * if set_jack callback occurred early than io_init,
1306320b8b0dSShuming Fan 	 * we set up the jack detection function now
1307320b8b0dSShuming Fan 	 */
1308320b8b0dSShuming Fan 	if (rt711->hs_jack)
1309320b8b0dSShuming Fan 		rt711_jack_init(rt711);
1310320b8b0dSShuming Fan 
1311320b8b0dSShuming Fan 	if (rt711->first_hw_init) {
1312320b8b0dSShuming Fan 		regcache_cache_bypass(rt711->regmap, false);
1313320b8b0dSShuming Fan 		regcache_mark_dirty(rt711->regmap);
1314320b8b0dSShuming Fan 	} else
1315320b8b0dSShuming Fan 		rt711->first_hw_init = true;
1316320b8b0dSShuming Fan 
1317320b8b0dSShuming Fan 	/* Mark Slave initialization complete */
1318320b8b0dSShuming Fan 	rt711->hw_init = true;
1319320b8b0dSShuming Fan 
1320320b8b0dSShuming Fan 	pm_runtime_mark_last_busy(&slave->dev);
1321320b8b0dSShuming Fan 	pm_runtime_put_autosuspend(&slave->dev);
1322320b8b0dSShuming Fan 
1323320b8b0dSShuming Fan 	dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);
1324320b8b0dSShuming Fan 	return 0;
1325320b8b0dSShuming Fan }
1326320b8b0dSShuming Fan 
1327320b8b0dSShuming Fan MODULE_DESCRIPTION("ASoC RT711 SDW driver");
1328320b8b0dSShuming Fan MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");
1329320b8b0dSShuming Fan MODULE_LICENSE("GPL");
1330