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