xref: /openbmc/linux/sound/soc/codecs/rt711.c (revision 899b12542b0897f92de9ba30944937c39ebb246d)
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;
392320b8b0dSShuming Fan 		default:
393320b8b0dSShuming Fan 			dev_warn(rt711->component->dev, "Wrong JD source\n");
394320b8b0dSShuming Fan 			break;
395320b8b0dSShuming Fan 		}
396320b8b0dSShuming Fan 
397320b8b0dSShuming Fan 		dev_dbg(&rt711->slave->dev, "in %s enable\n", __func__);
398320b8b0dSShuming Fan 
399320b8b0dSShuming Fan 		mod_delayed_work(system_power_efficient_wq,
400320b8b0dSShuming Fan 			&rt711->jack_detect_work, msecs_to_jiffies(250));
401320b8b0dSShuming Fan 	} else {
402320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
403320b8b0dSShuming Fan 			RT711_SET_MIC2_UNSOLICITED_ENABLE, 0x00);
404320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
405320b8b0dSShuming Fan 			RT711_SET_HP_UNSOLICITED_ENABLE, 0x00);
406320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
407320b8b0dSShuming Fan 			RT711_SET_INLINE_UNSOLICITED_ENABLE, 0x00);
408320b8b0dSShuming Fan 
409320b8b0dSShuming Fan 		dev_dbg(&rt711->slave->dev, "in %s disable\n", __func__);
410320b8b0dSShuming Fan 	}
411320b8b0dSShuming Fan 
412320b8b0dSShuming Fan 	/* power off */
413320b8b0dSShuming Fan 	if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)
414320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
415320b8b0dSShuming Fan 			RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D3);
416320b8b0dSShuming Fan 	mutex_unlock(&rt711->calibrate_mutex);
417320b8b0dSShuming Fan }
418320b8b0dSShuming Fan 
419320b8b0dSShuming Fan static int rt711_set_jack_detect(struct snd_soc_component *component,
420320b8b0dSShuming Fan 	struct snd_soc_jack *hs_jack, void *data)
421320b8b0dSShuming Fan {
422320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
423320b8b0dSShuming Fan 
424320b8b0dSShuming Fan 	rt711->hs_jack = hs_jack;
425320b8b0dSShuming Fan 
426320b8b0dSShuming Fan 	if (!rt711->hw_init) {
427320b8b0dSShuming Fan 		dev_dbg(&rt711->slave->dev,
428320b8b0dSShuming Fan 			"%s hw_init not ready yet\n", __func__);
429320b8b0dSShuming Fan 		return 0;
430320b8b0dSShuming Fan 	}
431320b8b0dSShuming Fan 
432320b8b0dSShuming Fan 	rt711_jack_init(rt711);
433320b8b0dSShuming Fan 
434320b8b0dSShuming Fan 	return 0;
435320b8b0dSShuming Fan }
436320b8b0dSShuming Fan 
437320b8b0dSShuming Fan static void rt711_get_gain(struct rt711_priv *rt711, unsigned int addr_h,
438320b8b0dSShuming Fan 				unsigned int addr_l, unsigned int val_h,
439320b8b0dSShuming Fan 				unsigned int *r_val, unsigned int *l_val)
440320b8b0dSShuming Fan {
441320b8b0dSShuming Fan 	/* R Channel */
442320b8b0dSShuming Fan 	*r_val = (val_h << 8);
443320b8b0dSShuming Fan 	regmap_read(rt711->regmap, addr_l, r_val);
444320b8b0dSShuming Fan 
445320b8b0dSShuming Fan 	/* L Channel */
446320b8b0dSShuming Fan 	val_h |= 0x20;
447320b8b0dSShuming Fan 	*l_val = (val_h << 8);
448320b8b0dSShuming Fan 	regmap_read(rt711->regmap, addr_h, l_val);
449320b8b0dSShuming Fan }
450320b8b0dSShuming Fan 
451320b8b0dSShuming Fan /* For Verb-Set Amplifier Gain (Verb ID = 3h) */
452320b8b0dSShuming Fan static int rt711_set_amp_gain_put(struct snd_kcontrol *kcontrol,
453320b8b0dSShuming Fan 		struct snd_ctl_elem_value *ucontrol)
454320b8b0dSShuming Fan {
455320b8b0dSShuming Fan 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
456320b8b0dSShuming Fan 	struct snd_soc_dapm_context *dapm =
457320b8b0dSShuming Fan 		snd_soc_component_get_dapm(component);
458320b8b0dSShuming Fan 	struct soc_mixer_control *mc =
459320b8b0dSShuming Fan 		(struct soc_mixer_control *)kcontrol->private_value;
460320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
461320b8b0dSShuming Fan 	unsigned int addr_h, addr_l, val_h, val_ll, val_lr;
462320b8b0dSShuming Fan 	unsigned int read_ll, read_rl;
463320b8b0dSShuming Fan 	int i;
464320b8b0dSShuming Fan 
4656108f990SShuming Fan 	mutex_lock(&rt711->calibrate_mutex);
4666108f990SShuming Fan 
467320b8b0dSShuming Fan 	/* Can't use update bit function, so read the original value first */
468320b8b0dSShuming Fan 	addr_h = mc->reg;
469320b8b0dSShuming Fan 	addr_l = mc->rreg;
470320b8b0dSShuming Fan 	if (mc->shift == RT711_DIR_OUT_SFT) /* output */
471320b8b0dSShuming Fan 		val_h = 0x80;
472320b8b0dSShuming Fan 	else /* input */
473320b8b0dSShuming Fan 		val_h = 0x0;
474320b8b0dSShuming Fan 
475320b8b0dSShuming Fan 	rt711_get_gain(rt711, addr_h, addr_l, val_h, &read_rl, &read_ll);
476320b8b0dSShuming Fan 
477320b8b0dSShuming Fan 	/* L Channel */
478320b8b0dSShuming Fan 	if (mc->invert) {
479320b8b0dSShuming Fan 		/* for mute/unmute */
480320b8b0dSShuming Fan 		val_ll = (mc->max - ucontrol->value.integer.value[0])
481320b8b0dSShuming Fan 					<< RT711_MUTE_SFT;
482320b8b0dSShuming Fan 		/* keep gain */
483320b8b0dSShuming Fan 		read_ll = read_ll & 0x7f;
484320b8b0dSShuming Fan 		val_ll |= read_ll;
485320b8b0dSShuming Fan 	} else {
486320b8b0dSShuming Fan 		/* for gain */
487320b8b0dSShuming Fan 		val_ll = ((ucontrol->value.integer.value[0]) & 0x7f);
488320b8b0dSShuming Fan 		if (val_ll > mc->max)
489320b8b0dSShuming Fan 			val_ll = mc->max;
490320b8b0dSShuming Fan 		/* keep mute status */
491320b8b0dSShuming Fan 		read_ll = read_ll & (1 << RT711_MUTE_SFT);
492320b8b0dSShuming Fan 		val_ll |= read_ll;
493320b8b0dSShuming Fan 	}
494320b8b0dSShuming Fan 
495320b8b0dSShuming Fan 	if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)
496320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
497320b8b0dSShuming Fan 				RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D0);
498320b8b0dSShuming Fan 
499320b8b0dSShuming Fan 	/* R Channel */
500320b8b0dSShuming Fan 	if (mc->invert) {
501320b8b0dSShuming Fan 		/* for mute/unmute */
502320b8b0dSShuming Fan 		val_lr = (mc->max - ucontrol->value.integer.value[1])
503320b8b0dSShuming Fan 					<< RT711_MUTE_SFT;
504320b8b0dSShuming Fan 		/* keep gain */
505320b8b0dSShuming Fan 		read_rl = read_rl & 0x7f;
506320b8b0dSShuming Fan 		val_lr |= read_rl;
507320b8b0dSShuming Fan 	} else {
508320b8b0dSShuming Fan 		/* for gain */
509320b8b0dSShuming Fan 		val_lr = ((ucontrol->value.integer.value[1]) & 0x7f);
510320b8b0dSShuming Fan 		if (val_lr > mc->max)
511320b8b0dSShuming Fan 			val_lr = mc->max;
512320b8b0dSShuming Fan 		/* keep mute status */
513320b8b0dSShuming Fan 		read_rl = read_rl & (1 << RT711_MUTE_SFT);
514320b8b0dSShuming Fan 		val_lr |= read_rl;
515320b8b0dSShuming Fan 	}
516320b8b0dSShuming Fan 
517320b8b0dSShuming Fan 	for (i = 0; i < 3; i++) { /* retry 3 times at most */
518320b8b0dSShuming Fan 
519320b8b0dSShuming Fan 		if (val_ll == val_lr) {
520320b8b0dSShuming Fan 			/* Set both L/R channels at the same time */
521320b8b0dSShuming Fan 			val_h = (1 << mc->shift) | (3 << 4);
522320b8b0dSShuming Fan 			regmap_write(rt711->regmap,
523320b8b0dSShuming Fan 				addr_h, (val_h << 8 | val_ll));
524320b8b0dSShuming Fan 			regmap_write(rt711->regmap,
525320b8b0dSShuming Fan 				addr_l, (val_h << 8 | val_ll));
526320b8b0dSShuming Fan 		} else {
527320b8b0dSShuming Fan 			/* Lch*/
528320b8b0dSShuming Fan 			val_h = (1 << mc->shift) | (1 << 5);
529320b8b0dSShuming Fan 			regmap_write(rt711->regmap,
530320b8b0dSShuming Fan 				addr_h, (val_h << 8 | val_ll));
531320b8b0dSShuming Fan 
532320b8b0dSShuming Fan 			/* Rch */
533320b8b0dSShuming Fan 			val_h = (1 << mc->shift) | (1 << 4);
534320b8b0dSShuming Fan 			regmap_write(rt711->regmap,
535320b8b0dSShuming Fan 				addr_l, (val_h << 8 | val_lr));
536320b8b0dSShuming Fan 		}
537320b8b0dSShuming Fan 		/* check result */
538320b8b0dSShuming Fan 		if (mc->shift == RT711_DIR_OUT_SFT) /* output */
539320b8b0dSShuming Fan 			val_h = 0x80;
540320b8b0dSShuming Fan 		else /* input */
541320b8b0dSShuming Fan 			val_h = 0x0;
542320b8b0dSShuming Fan 
543320b8b0dSShuming Fan 		rt711_get_gain(rt711, addr_h, addr_l, val_h,
544320b8b0dSShuming Fan 					&read_rl, &read_ll);
545320b8b0dSShuming Fan 		if (read_rl == val_lr && read_ll == val_ll)
546320b8b0dSShuming Fan 			break;
547320b8b0dSShuming Fan 	}
548320b8b0dSShuming Fan 
549320b8b0dSShuming Fan 	if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)
550320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
551320b8b0dSShuming Fan 				RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D3);
5526108f990SShuming Fan 
5536108f990SShuming Fan 	mutex_unlock(&rt711->calibrate_mutex);
554320b8b0dSShuming Fan 	return 0;
555320b8b0dSShuming Fan }
556320b8b0dSShuming Fan 
557320b8b0dSShuming Fan static int rt711_set_amp_gain_get(struct snd_kcontrol *kcontrol,
558320b8b0dSShuming Fan 		struct snd_ctl_elem_value *ucontrol)
559320b8b0dSShuming Fan {
560320b8b0dSShuming Fan 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
561320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
562320b8b0dSShuming Fan 	struct soc_mixer_control *mc =
563320b8b0dSShuming Fan 		(struct soc_mixer_control *)kcontrol->private_value;
564320b8b0dSShuming Fan 	unsigned int addr_h, addr_l, val_h;
565320b8b0dSShuming Fan 	unsigned int read_ll, read_rl;
566320b8b0dSShuming Fan 
567320b8b0dSShuming Fan 	/* switch to get command */
568320b8b0dSShuming Fan 	addr_h = mc->reg;
569320b8b0dSShuming Fan 	addr_l = mc->rreg;
570320b8b0dSShuming Fan 	if (mc->shift == RT711_DIR_OUT_SFT) /* output */
571320b8b0dSShuming Fan 		val_h = 0x80;
572320b8b0dSShuming Fan 	else /* input */
573320b8b0dSShuming Fan 		val_h = 0x0;
574320b8b0dSShuming Fan 
575320b8b0dSShuming Fan 	rt711_get_gain(rt711, addr_h, addr_l, val_h, &read_rl, &read_ll);
576320b8b0dSShuming Fan 
577320b8b0dSShuming Fan 	if (mc->invert) {
578320b8b0dSShuming Fan 		/* mute/unmute for switch controls */
579320b8b0dSShuming Fan 		read_ll = !((read_ll & 0x80) >> RT711_MUTE_SFT);
580320b8b0dSShuming Fan 		read_rl = !((read_rl & 0x80) >> RT711_MUTE_SFT);
581320b8b0dSShuming Fan 	} else {
582320b8b0dSShuming Fan 		/* for gain volume controls */
583320b8b0dSShuming Fan 		read_ll = read_ll & 0x7f;
584320b8b0dSShuming Fan 		read_rl = read_rl & 0x7f;
585320b8b0dSShuming Fan 	}
586320b8b0dSShuming Fan 	ucontrol->value.integer.value[0] = read_ll;
587320b8b0dSShuming Fan 	ucontrol->value.integer.value[1] = read_rl;
588320b8b0dSShuming Fan 
589320b8b0dSShuming Fan 	return 0;
590320b8b0dSShuming Fan }
591320b8b0dSShuming Fan 
592320b8b0dSShuming Fan static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6525, 75, 0);
593320b8b0dSShuming Fan static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0);
594320b8b0dSShuming Fan static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
595320b8b0dSShuming Fan 
596320b8b0dSShuming Fan static const struct snd_kcontrol_new rt711_snd_controls[] = {
597320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT_TLV("DAC Surr Playback Volume",
598320b8b0dSShuming Fan 		RT711_SET_GAIN_DAC2_H, RT711_SET_GAIN_DAC2_L,
599320b8b0dSShuming Fan 		RT711_DIR_OUT_SFT, 0x57, 0,
600320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put, out_vol_tlv),
601320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT("ADC 08 Capture Switch",
602320b8b0dSShuming Fan 		RT711_SET_GAIN_ADC2_H, RT711_SET_GAIN_ADC2_L,
603320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 1, 1,
604320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put),
605320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT("ADC 09 Capture Switch",
606320b8b0dSShuming Fan 		RT711_SET_GAIN_ADC1_H, RT711_SET_GAIN_ADC1_L,
607320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 1, 1,
608320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put),
609320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT_TLV("ADC 08 Capture Volume",
610320b8b0dSShuming Fan 		RT711_SET_GAIN_ADC2_H, RT711_SET_GAIN_ADC2_L,
611320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 0x3f, 0,
612320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put, in_vol_tlv),
613320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT_TLV("ADC 09 Capture Volume",
614320b8b0dSShuming Fan 		RT711_SET_GAIN_ADC1_H, RT711_SET_GAIN_ADC1_L,
615320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 0x3f, 0,
616320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put, in_vol_tlv),
617320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT_TLV("AMIC Volume",
618320b8b0dSShuming Fan 		RT711_SET_GAIN_AMIC_H, RT711_SET_GAIN_AMIC_L,
619320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 3, 0,
620320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put, mic_vol_tlv),
621320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT_TLV("DMIC1 Volume",
622320b8b0dSShuming Fan 		RT711_SET_GAIN_DMIC1_H, RT711_SET_GAIN_DMIC1_L,
623320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 3, 0,
624320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put, mic_vol_tlv),
625320b8b0dSShuming Fan 	SOC_DOUBLE_R_EXT_TLV("DMIC2 Volume",
626320b8b0dSShuming Fan 		RT711_SET_GAIN_DMIC2_H, RT711_SET_GAIN_DMIC2_L,
627320b8b0dSShuming Fan 		RT711_DIR_IN_SFT, 3, 0,
628320b8b0dSShuming Fan 		rt711_set_amp_gain_get, rt711_set_amp_gain_put, mic_vol_tlv),
629320b8b0dSShuming Fan };
630320b8b0dSShuming Fan 
631320b8b0dSShuming Fan static int rt711_mux_get(struct snd_kcontrol *kcontrol,
632320b8b0dSShuming Fan 			struct snd_ctl_elem_value *ucontrol)
633320b8b0dSShuming Fan {
634320b8b0dSShuming Fan 	struct snd_soc_component *component =
635320b8b0dSShuming Fan 		snd_soc_dapm_kcontrol_component(kcontrol);
636320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
637320b8b0dSShuming Fan 	unsigned int reg, val = 0, nid;
638320b8b0dSShuming Fan 	int ret;
639320b8b0dSShuming Fan 
640320b8b0dSShuming Fan 	if (strstr(ucontrol->id.name, "ADC 22 Mux"))
641320b8b0dSShuming Fan 		nid = RT711_MIXER_IN1;
642320b8b0dSShuming Fan 	else if (strstr(ucontrol->id.name, "ADC 23 Mux"))
643320b8b0dSShuming Fan 		nid = RT711_MIXER_IN2;
644320b8b0dSShuming Fan 	else
645320b8b0dSShuming Fan 		return -EINVAL;
646320b8b0dSShuming Fan 
647320b8b0dSShuming Fan 	/* vid = 0xf01 */
648320b8b0dSShuming Fan 	reg = RT711_VERB_SET_CONNECT_SEL | nid;
649320b8b0dSShuming Fan 	ret = regmap_read(rt711->regmap, reg, &val);
650320b8b0dSShuming Fan 	if (ret < 0) {
651320b8b0dSShuming Fan 		dev_err(component->dev, "%s: sdw read failed: %d\n",
652320b8b0dSShuming Fan 			__func__, ret);
653320b8b0dSShuming Fan 		return ret;
654320b8b0dSShuming Fan 	}
655320b8b0dSShuming Fan 
656320b8b0dSShuming Fan 	ucontrol->value.enumerated.item[0] = val;
657320b8b0dSShuming Fan 
658320b8b0dSShuming Fan 	return 0;
659320b8b0dSShuming Fan }
660320b8b0dSShuming Fan 
661320b8b0dSShuming Fan static int rt711_mux_put(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 snd_soc_dapm_context *dapm =
667320b8b0dSShuming Fan 		snd_soc_dapm_kcontrol_dapm(kcontrol);
668320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
669320b8b0dSShuming Fan 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
670320b8b0dSShuming Fan 	unsigned int *item = ucontrol->value.enumerated.item;
671320b8b0dSShuming Fan 	unsigned int val, val2 = 0, change, reg, nid;
672320b8b0dSShuming Fan 	int ret;
673320b8b0dSShuming Fan 
674320b8b0dSShuming Fan 	if (item[0] >= e->items)
675320b8b0dSShuming Fan 		return -EINVAL;
676320b8b0dSShuming Fan 
677320b8b0dSShuming Fan 	if (strstr(ucontrol->id.name, "ADC 22 Mux"))
678320b8b0dSShuming Fan 		nid = RT711_MIXER_IN1;
679320b8b0dSShuming Fan 	else if (strstr(ucontrol->id.name, "ADC 23 Mux"))
680320b8b0dSShuming Fan 		nid = RT711_MIXER_IN2;
681320b8b0dSShuming Fan 	else
682320b8b0dSShuming Fan 		return -EINVAL;
683320b8b0dSShuming Fan 
684320b8b0dSShuming Fan 	/* Verb ID = 0x701h */
685320b8b0dSShuming Fan 	val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
686320b8b0dSShuming Fan 
687320b8b0dSShuming Fan 	reg = RT711_VERB_SET_CONNECT_SEL | nid;
688320b8b0dSShuming Fan 	ret = regmap_read(rt711->regmap, reg, &val2);
689320b8b0dSShuming Fan 	if (ret < 0) {
690320b8b0dSShuming Fan 		dev_err(component->dev, "%s: sdw read failed: %d\n",
691320b8b0dSShuming Fan 			__func__, ret);
692320b8b0dSShuming Fan 		return ret;
693320b8b0dSShuming Fan 	}
694320b8b0dSShuming Fan 
695320b8b0dSShuming Fan 	if (val == val2)
696320b8b0dSShuming Fan 		change = 0;
697320b8b0dSShuming Fan 	else
698320b8b0dSShuming Fan 		change = 1;
699320b8b0dSShuming Fan 
700320b8b0dSShuming Fan 	if (change) {
701320b8b0dSShuming Fan 		reg = RT711_VERB_SET_CONNECT_SEL | nid;
702320b8b0dSShuming Fan 		regmap_write(rt711->regmap, reg, val);
703320b8b0dSShuming Fan 	}
704320b8b0dSShuming Fan 
705320b8b0dSShuming Fan 	snd_soc_dapm_mux_update_power(dapm, kcontrol,
706320b8b0dSShuming Fan 						item[0], e, NULL);
707320b8b0dSShuming Fan 
708320b8b0dSShuming Fan 	return change;
709320b8b0dSShuming Fan }
710320b8b0dSShuming Fan 
711320b8b0dSShuming Fan static const char * const adc_mux_text[] = {
712320b8b0dSShuming Fan 	"MIC2",
713320b8b0dSShuming Fan 	"LINE1",
714320b8b0dSShuming Fan 	"LINE2",
715320b8b0dSShuming Fan 	"DMIC",
716320b8b0dSShuming Fan };
717320b8b0dSShuming Fan 
718320b8b0dSShuming Fan static SOC_ENUM_SINGLE_DECL(
719320b8b0dSShuming Fan 	rt711_adc22_enum, SND_SOC_NOPM, 0, adc_mux_text);
720320b8b0dSShuming Fan 
721320b8b0dSShuming Fan static SOC_ENUM_SINGLE_DECL(
722320b8b0dSShuming Fan 	rt711_adc23_enum, SND_SOC_NOPM, 0, adc_mux_text);
723320b8b0dSShuming Fan 
724320b8b0dSShuming Fan static const struct snd_kcontrol_new rt711_adc22_mux =
725320b8b0dSShuming Fan 	SOC_DAPM_ENUM_EXT("ADC 22 Mux", rt711_adc22_enum,
726320b8b0dSShuming Fan 			rt711_mux_get, rt711_mux_put);
727320b8b0dSShuming Fan 
728320b8b0dSShuming Fan static const struct snd_kcontrol_new rt711_adc23_mux =
729320b8b0dSShuming Fan 	SOC_DAPM_ENUM_EXT("ADC 23 Mux", rt711_adc23_enum,
730320b8b0dSShuming Fan 			rt711_mux_get, rt711_mux_put);
731320b8b0dSShuming Fan 
732320b8b0dSShuming Fan static int rt711_dac_surround_event(struct snd_soc_dapm_widget *w,
733320b8b0dSShuming Fan 	struct snd_kcontrol *kcontrol, int event)
734320b8b0dSShuming Fan {
735320b8b0dSShuming Fan 	struct snd_soc_component *component =
736320b8b0dSShuming Fan 		snd_soc_dapm_to_component(w->dapm);
737320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
738320b8b0dSShuming Fan 	unsigned int val_h = (1 << RT711_DIR_OUT_SFT) | (0x3 << 4);
739320b8b0dSShuming Fan 	unsigned int val_l;
740320b8b0dSShuming Fan 
741320b8b0dSShuming Fan 	switch (event) {
742320b8b0dSShuming Fan 	case SND_SOC_DAPM_POST_PMU:
743320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
744320b8b0dSShuming Fan 			RT711_SET_STREAMID_DAC2, 0x10);
745320b8b0dSShuming Fan 
746320b8b0dSShuming Fan 		val_l = 0x00;
747320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
748320b8b0dSShuming Fan 			RT711_SET_GAIN_HP_H, (val_h << 8 | val_l));
749320b8b0dSShuming Fan 		break;
750320b8b0dSShuming Fan 	case SND_SOC_DAPM_PRE_PMD:
751320b8b0dSShuming Fan 		val_l = (1 << RT711_MUTE_SFT);
752320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
753320b8b0dSShuming Fan 			RT711_SET_GAIN_HP_H, (val_h << 8 | val_l));
754320b8b0dSShuming Fan 		usleep_range(50000, 55000);
755320b8b0dSShuming Fan 
756320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
757320b8b0dSShuming Fan 			RT711_SET_STREAMID_DAC2, 0x00);
758320b8b0dSShuming Fan 		break;
759320b8b0dSShuming Fan 	}
760320b8b0dSShuming Fan 	return 0;
761320b8b0dSShuming Fan }
762320b8b0dSShuming Fan 
763320b8b0dSShuming Fan static int rt711_adc_09_event(struct snd_soc_dapm_widget *w,
764320b8b0dSShuming Fan 	struct snd_kcontrol *kcontrol, int event)
765320b8b0dSShuming Fan {
766320b8b0dSShuming Fan 	struct snd_soc_component *component =
767320b8b0dSShuming Fan 		snd_soc_dapm_to_component(w->dapm);
768320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
769320b8b0dSShuming Fan 
770320b8b0dSShuming Fan 	switch (event) {
771320b8b0dSShuming Fan 	case SND_SOC_DAPM_POST_PMU:
772320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
773320b8b0dSShuming Fan 			RT711_SET_STREAMID_ADC1, 0x10);
774320b8b0dSShuming Fan 		break;
775320b8b0dSShuming Fan 	case SND_SOC_DAPM_PRE_PMD:
776320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
777320b8b0dSShuming Fan 			RT711_SET_STREAMID_ADC1, 0x00);
778320b8b0dSShuming Fan 		break;
779320b8b0dSShuming Fan 	}
780320b8b0dSShuming Fan 	return 0;
781320b8b0dSShuming Fan }
782320b8b0dSShuming Fan 
783320b8b0dSShuming Fan static int rt711_adc_08_event(struct snd_soc_dapm_widget *w,
784320b8b0dSShuming Fan 	struct snd_kcontrol *kcontrol, int event)
785320b8b0dSShuming Fan {
786320b8b0dSShuming Fan 	struct snd_soc_component *component =
787320b8b0dSShuming Fan 		snd_soc_dapm_to_component(w->dapm);
788320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
789320b8b0dSShuming Fan 
790320b8b0dSShuming Fan 	switch (event) {
791320b8b0dSShuming Fan 	case SND_SOC_DAPM_POST_PMU:
792320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
793320b8b0dSShuming Fan 			RT711_SET_STREAMID_ADC2, 0x10);
794320b8b0dSShuming Fan 		break;
795320b8b0dSShuming Fan 	case SND_SOC_DAPM_PRE_PMD:
796320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
797320b8b0dSShuming Fan 			RT711_SET_STREAMID_ADC2, 0x00);
798320b8b0dSShuming Fan 		break;
799320b8b0dSShuming Fan 	}
800320b8b0dSShuming Fan 	return 0;
801320b8b0dSShuming Fan }
802320b8b0dSShuming Fan 
803320b8b0dSShuming Fan static const struct snd_soc_dapm_widget rt711_dapm_widgets[] = {
804320b8b0dSShuming Fan 	SND_SOC_DAPM_OUTPUT("HP"),
805320b8b0dSShuming Fan 	SND_SOC_DAPM_INPUT("MIC2"),
806320b8b0dSShuming Fan 	SND_SOC_DAPM_INPUT("DMIC1"),
807320b8b0dSShuming Fan 	SND_SOC_DAPM_INPUT("DMIC2"),
808320b8b0dSShuming Fan 	SND_SOC_DAPM_INPUT("LINE1"),
809320b8b0dSShuming Fan 	SND_SOC_DAPM_INPUT("LINE2"),
810320b8b0dSShuming Fan 
811320b8b0dSShuming Fan 	SND_SOC_DAPM_DAC_E("DAC Surround", NULL, SND_SOC_NOPM, 0, 0,
812320b8b0dSShuming Fan 		rt711_dac_surround_event,
813320b8b0dSShuming Fan 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
814320b8b0dSShuming Fan 	SND_SOC_DAPM_ADC_E("ADC 09", NULL, SND_SOC_NOPM, 0, 0,
815320b8b0dSShuming Fan 		rt711_adc_09_event,
816320b8b0dSShuming Fan 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
817320b8b0dSShuming Fan 	SND_SOC_DAPM_ADC_E("ADC 08", NULL, SND_SOC_NOPM, 0, 0,
818320b8b0dSShuming Fan 		rt711_adc_08_event,
819320b8b0dSShuming Fan 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
820320b8b0dSShuming Fan 	SND_SOC_DAPM_MUX("ADC 22 Mux", SND_SOC_NOPM, 0, 0,
821320b8b0dSShuming Fan 		&rt711_adc22_mux),
822320b8b0dSShuming Fan 	SND_SOC_DAPM_MUX("ADC 23 Mux", SND_SOC_NOPM, 0, 0,
823320b8b0dSShuming Fan 		&rt711_adc23_mux),
824320b8b0dSShuming Fan 
825320b8b0dSShuming Fan 	SND_SOC_DAPM_AIF_IN("DP3RX", "DP3 Playback", 0, SND_SOC_NOPM, 0, 0),
826320b8b0dSShuming Fan 	SND_SOC_DAPM_AIF_OUT("DP2TX", "DP2 Capture", 0, SND_SOC_NOPM, 0, 0),
827320b8b0dSShuming Fan 	SND_SOC_DAPM_AIF_OUT("DP4TX", "DP4 Capture", 0, SND_SOC_NOPM, 0, 0),
828320b8b0dSShuming Fan };
829320b8b0dSShuming Fan 
830320b8b0dSShuming Fan static const struct snd_soc_dapm_route rt711_audio_map[] = {
831320b8b0dSShuming Fan 	{"DAC Surround", NULL, "DP3RX"},
832320b8b0dSShuming Fan 	{"DP2TX", NULL, "ADC 09"},
833320b8b0dSShuming Fan 	{"DP4TX", NULL, "ADC 08"},
834320b8b0dSShuming Fan 
835320b8b0dSShuming Fan 	{"ADC 09", NULL, "ADC 22 Mux"},
836320b8b0dSShuming Fan 	{"ADC 08", NULL, "ADC 23 Mux"},
837320b8b0dSShuming Fan 	{"ADC 22 Mux", "DMIC", "DMIC1"},
838320b8b0dSShuming Fan 	{"ADC 22 Mux", "LINE1", "LINE1"},
839320b8b0dSShuming Fan 	{"ADC 22 Mux", "LINE2", "LINE2"},
840320b8b0dSShuming Fan 	{"ADC 22 Mux", "MIC2", "MIC2"},
841320b8b0dSShuming Fan 	{"ADC 23 Mux", "DMIC", "DMIC2"},
842320b8b0dSShuming Fan 	{"ADC 23 Mux", "LINE1", "LINE1"},
843320b8b0dSShuming Fan 	{"ADC 23 Mux", "LINE2", "LINE2"},
844320b8b0dSShuming Fan 	{"ADC 23 Mux", "MIC2", "MIC2"},
845320b8b0dSShuming Fan 
846320b8b0dSShuming Fan 	{"HP", NULL, "DAC Surround"},
847320b8b0dSShuming Fan };
848320b8b0dSShuming Fan 
849320b8b0dSShuming Fan static int rt711_set_bias_level(struct snd_soc_component *component,
850320b8b0dSShuming Fan 				enum snd_soc_bias_level level)
851320b8b0dSShuming Fan {
852320b8b0dSShuming Fan 	struct snd_soc_dapm_context *dapm =
853320b8b0dSShuming Fan 		snd_soc_component_get_dapm(component);
854320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
855320b8b0dSShuming Fan 
856320b8b0dSShuming Fan 	switch (level) {
857320b8b0dSShuming Fan 	case SND_SOC_BIAS_PREPARE:
858320b8b0dSShuming Fan 		if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
859320b8b0dSShuming Fan 			regmap_write(rt711->regmap,
860320b8b0dSShuming Fan 				RT711_SET_AUDIO_POWER_STATE,
861320b8b0dSShuming Fan 				AC_PWRST_D0);
862320b8b0dSShuming Fan 		}
863320b8b0dSShuming Fan 		break;
864320b8b0dSShuming Fan 
865320b8b0dSShuming Fan 	case SND_SOC_BIAS_STANDBY:
8666108f990SShuming Fan 		mutex_lock(&rt711->calibrate_mutex);
867320b8b0dSShuming Fan 		regmap_write(rt711->regmap,
868320b8b0dSShuming Fan 			RT711_SET_AUDIO_POWER_STATE,
869320b8b0dSShuming Fan 			AC_PWRST_D3);
8706108f990SShuming Fan 		mutex_unlock(&rt711->calibrate_mutex);
871320b8b0dSShuming Fan 		break;
872320b8b0dSShuming Fan 
873320b8b0dSShuming Fan 	default:
874320b8b0dSShuming Fan 		break;
875320b8b0dSShuming Fan 	}
876320b8b0dSShuming Fan 
877320b8b0dSShuming Fan 	return 0;
878320b8b0dSShuming Fan }
879320b8b0dSShuming Fan 
880320b8b0dSShuming Fan static int rt711_parse_dt(struct rt711_priv *rt711, struct device *dev)
881320b8b0dSShuming Fan {
882320b8b0dSShuming Fan 	device_property_read_u32(dev, "realtek,jd-src",
883320b8b0dSShuming Fan 		&rt711->jd_src);
884320b8b0dSShuming Fan 
885320b8b0dSShuming Fan 	return 0;
886320b8b0dSShuming Fan }
887320b8b0dSShuming Fan 
888320b8b0dSShuming Fan static int rt711_probe(struct snd_soc_component *component)
889320b8b0dSShuming Fan {
890320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
891320b8b0dSShuming Fan 
892320b8b0dSShuming Fan 	rt711_parse_dt(rt711, &rt711->slave->dev);
893320b8b0dSShuming Fan 	rt711->component = component;
894320b8b0dSShuming Fan 
895320b8b0dSShuming Fan 	return 0;
896320b8b0dSShuming Fan }
897320b8b0dSShuming Fan 
898*899b1254SBard Liao static void rt711_remove(struct snd_soc_component *component)
899*899b1254SBard Liao {
900*899b1254SBard Liao 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
901*899b1254SBard Liao 
902*899b1254SBard Liao 	regcache_cache_only(rt711->regmap, true);
903*899b1254SBard Liao }
904*899b1254SBard Liao 
905320b8b0dSShuming Fan static const struct snd_soc_component_driver soc_codec_dev_rt711 = {
906320b8b0dSShuming Fan 	.probe = rt711_probe,
907320b8b0dSShuming Fan 	.set_bias_level = rt711_set_bias_level,
908320b8b0dSShuming Fan 	.controls = rt711_snd_controls,
909320b8b0dSShuming Fan 	.num_controls = ARRAY_SIZE(rt711_snd_controls),
910320b8b0dSShuming Fan 	.dapm_widgets = rt711_dapm_widgets,
911320b8b0dSShuming Fan 	.num_dapm_widgets = ARRAY_SIZE(rt711_dapm_widgets),
912320b8b0dSShuming Fan 	.dapm_routes = rt711_audio_map,
913320b8b0dSShuming Fan 	.num_dapm_routes = ARRAY_SIZE(rt711_audio_map),
914320b8b0dSShuming Fan 	.set_jack = rt711_set_jack_detect,
915*899b1254SBard Liao 	.remove = rt711_remove,
916320b8b0dSShuming Fan };
917320b8b0dSShuming Fan 
918320b8b0dSShuming Fan static int rt711_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
919320b8b0dSShuming Fan 				int direction)
920320b8b0dSShuming Fan {
921320b8b0dSShuming Fan 	struct sdw_stream_data *stream;
922320b8b0dSShuming Fan 
92307b542feSPierre-Louis Bossart 	if (!sdw_stream)
92407b542feSPierre-Louis Bossart 		return 0;
92507b542feSPierre-Louis Bossart 
926320b8b0dSShuming Fan 	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
927320b8b0dSShuming Fan 	if (!stream)
928320b8b0dSShuming Fan 		return -ENOMEM;
929320b8b0dSShuming Fan 
9304a550007SPierre-Louis Bossart 	stream->sdw_stream = sdw_stream;
931320b8b0dSShuming Fan 
932320b8b0dSShuming Fan 	/* Use tx_mask or rx_mask to configure stream tag and set dma_data */
933320b8b0dSShuming Fan 	if (direction == SNDRV_PCM_STREAM_PLAYBACK)
934320b8b0dSShuming Fan 		dai->playback_dma_data = stream;
935320b8b0dSShuming Fan 	else
936320b8b0dSShuming Fan 		dai->capture_dma_data = stream;
937320b8b0dSShuming Fan 
938320b8b0dSShuming Fan 	return 0;
939320b8b0dSShuming Fan }
940320b8b0dSShuming Fan 
941320b8b0dSShuming Fan static void rt711_shutdown(struct snd_pcm_substream *substream,
942320b8b0dSShuming Fan 				struct snd_soc_dai *dai)
943320b8b0dSShuming Fan {
944320b8b0dSShuming Fan 	struct sdw_stream_data *stream;
945320b8b0dSShuming Fan 
946320b8b0dSShuming Fan 	stream = snd_soc_dai_get_dma_data(dai, substream);
947320b8b0dSShuming Fan 	snd_soc_dai_set_dma_data(dai, substream, NULL);
948320b8b0dSShuming Fan 	kfree(stream);
949320b8b0dSShuming Fan }
950320b8b0dSShuming Fan 
951320b8b0dSShuming Fan static int rt711_pcm_hw_params(struct snd_pcm_substream *substream,
952320b8b0dSShuming Fan 				struct snd_pcm_hw_params *params,
953320b8b0dSShuming Fan 				struct snd_soc_dai *dai)
954320b8b0dSShuming Fan {
955320b8b0dSShuming Fan 	struct snd_soc_component *component = dai->component;
956320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
957320b8b0dSShuming Fan 	struct sdw_stream_config stream_config;
958320b8b0dSShuming Fan 	struct sdw_port_config port_config;
959320b8b0dSShuming Fan 	enum sdw_data_direction direction;
960320b8b0dSShuming Fan 	struct sdw_stream_data *stream;
961320b8b0dSShuming Fan 	int retval, port, num_channels;
962320b8b0dSShuming Fan 	unsigned int val = 0;
963320b8b0dSShuming Fan 
964320b8b0dSShuming Fan 	dev_dbg(dai->dev, "%s %s", __func__, dai->name);
965320b8b0dSShuming Fan 	stream = snd_soc_dai_get_dma_data(dai, substream);
966320b8b0dSShuming Fan 
967320b8b0dSShuming Fan 	if (!stream)
968320b8b0dSShuming Fan 		return -EINVAL;
969320b8b0dSShuming Fan 
970320b8b0dSShuming Fan 	if (!rt711->slave)
971320b8b0dSShuming Fan 		return -EINVAL;
972320b8b0dSShuming Fan 
973320b8b0dSShuming Fan 	/* SoundWire specific configuration */
974320b8b0dSShuming Fan 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
975320b8b0dSShuming Fan 		direction = SDW_DATA_DIR_RX;
976320b8b0dSShuming Fan 		port = 3;
977320b8b0dSShuming Fan 	} else {
978320b8b0dSShuming Fan 		direction = SDW_DATA_DIR_TX;
979320b8b0dSShuming Fan 		if (dai->id == RT711_AIF1)
980320b8b0dSShuming Fan 			port = 4;
981320b8b0dSShuming Fan 		else if (dai->id == RT711_AIF2)
982320b8b0dSShuming Fan 			port = 2;
983320b8b0dSShuming Fan 		else
984320b8b0dSShuming Fan 			return -EINVAL;
985320b8b0dSShuming Fan 	}
986320b8b0dSShuming Fan 
987320b8b0dSShuming Fan 	stream_config.frame_rate = params_rate(params);
988320b8b0dSShuming Fan 	stream_config.ch_count = params_channels(params);
989320b8b0dSShuming Fan 	stream_config.bps = snd_pcm_format_width(params_format(params));
990320b8b0dSShuming Fan 	stream_config.direction = direction;
991320b8b0dSShuming Fan 
992320b8b0dSShuming Fan 	num_channels = params_channels(params);
993320b8b0dSShuming Fan 	port_config.ch_mask = (1 << (num_channels)) - 1;
994320b8b0dSShuming Fan 	port_config.num = port;
995320b8b0dSShuming Fan 
996320b8b0dSShuming Fan 	retval = sdw_stream_add_slave(rt711->slave, &stream_config,
997320b8b0dSShuming Fan 					&port_config, 1, stream->sdw_stream);
998320b8b0dSShuming Fan 	if (retval) {
999320b8b0dSShuming Fan 		dev_err(dai->dev, "Unable to configure port\n");
1000320b8b0dSShuming Fan 		return retval;
1001320b8b0dSShuming Fan 	}
1002320b8b0dSShuming Fan 
1003320b8b0dSShuming Fan 	if (params_channels(params) <= 16) {
1004320b8b0dSShuming Fan 		/* bit 3:0 Number of Channel */
1005320b8b0dSShuming Fan 		val |= (params_channels(params) - 1);
1006320b8b0dSShuming Fan 	} else {
1007320b8b0dSShuming Fan 		dev_err(component->dev, "Unsupported channels %d\n",
1008320b8b0dSShuming Fan 			params_channels(params));
1009320b8b0dSShuming Fan 		return -EINVAL;
1010320b8b0dSShuming Fan 	}
1011320b8b0dSShuming Fan 
1012320b8b0dSShuming Fan 	switch (params_width(params)) {
1013320b8b0dSShuming Fan 	/* bit 6:4 Bits per Sample */
1014320b8b0dSShuming Fan 	case 8:
1015320b8b0dSShuming Fan 		break;
1016320b8b0dSShuming Fan 	case 16:
1017320b8b0dSShuming Fan 		val |= (0x1 << 4);
1018320b8b0dSShuming Fan 		break;
1019320b8b0dSShuming Fan 	case 20:
1020320b8b0dSShuming Fan 		val |= (0x2 << 4);
1021320b8b0dSShuming Fan 		break;
1022320b8b0dSShuming Fan 	case 24:
1023320b8b0dSShuming Fan 		val |= (0x3 << 4);
1024320b8b0dSShuming Fan 		break;
1025320b8b0dSShuming Fan 	case 32:
1026320b8b0dSShuming Fan 		val |= (0x4 << 4);
1027320b8b0dSShuming Fan 		break;
1028320b8b0dSShuming Fan 	default:
1029320b8b0dSShuming Fan 		return -EINVAL;
1030320b8b0dSShuming Fan 	}
1031320b8b0dSShuming Fan 
1032320b8b0dSShuming Fan 	/* 48Khz */
1033320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_DAC_FORMAT_H, val);
1034320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_ADC1_FORMAT_H, val);
1035320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_ADC2_FORMAT_H, val);
1036320b8b0dSShuming Fan 
1037320b8b0dSShuming Fan 	return retval;
1038320b8b0dSShuming Fan }
1039320b8b0dSShuming Fan 
1040320b8b0dSShuming Fan static int rt711_pcm_hw_free(struct snd_pcm_substream *substream,
1041320b8b0dSShuming Fan 				struct snd_soc_dai *dai)
1042320b8b0dSShuming Fan {
1043320b8b0dSShuming Fan 	struct snd_soc_component *component = dai->component;
1044320b8b0dSShuming Fan 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
1045320b8b0dSShuming Fan 	struct sdw_stream_data *stream =
1046320b8b0dSShuming Fan 		snd_soc_dai_get_dma_data(dai, substream);
1047320b8b0dSShuming Fan 
1048320b8b0dSShuming Fan 	if (!rt711->slave)
1049320b8b0dSShuming Fan 		return -EINVAL;
1050320b8b0dSShuming Fan 
1051320b8b0dSShuming Fan 	sdw_stream_remove_slave(rt711->slave, stream->sdw_stream);
1052320b8b0dSShuming Fan 	return 0;
1053320b8b0dSShuming Fan }
1054320b8b0dSShuming Fan 
1055320b8b0dSShuming Fan #define RT711_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
1056320b8b0dSShuming Fan #define RT711_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1057320b8b0dSShuming Fan 			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
1058320b8b0dSShuming Fan 
1059320b8b0dSShuming Fan static struct snd_soc_dai_ops rt711_ops = {
1060320b8b0dSShuming Fan 	.hw_params	= rt711_pcm_hw_params,
1061320b8b0dSShuming Fan 	.hw_free	= rt711_pcm_hw_free,
1062320b8b0dSShuming Fan 	.set_sdw_stream	= rt711_set_sdw_stream,
1063320b8b0dSShuming Fan 	.shutdown	= rt711_shutdown,
1064320b8b0dSShuming Fan };
1065320b8b0dSShuming Fan 
1066320b8b0dSShuming Fan static struct snd_soc_dai_driver rt711_dai[] = {
1067320b8b0dSShuming Fan 	{
1068320b8b0dSShuming Fan 		.name = "rt711-aif1",
1069320b8b0dSShuming Fan 		.id = RT711_AIF1,
1070320b8b0dSShuming Fan 		.playback = {
1071320b8b0dSShuming Fan 			.stream_name = "DP3 Playback",
1072320b8b0dSShuming Fan 			.channels_min = 1,
1073320b8b0dSShuming Fan 			.channels_max = 2,
1074320b8b0dSShuming Fan 			.rates = RT711_STEREO_RATES,
1075320b8b0dSShuming Fan 			.formats = RT711_FORMATS,
1076320b8b0dSShuming Fan 		},
1077320b8b0dSShuming Fan 		.capture = {
1078320b8b0dSShuming Fan 			.stream_name = "DP4 Capture",
1079320b8b0dSShuming Fan 			.channels_min = 1,
1080320b8b0dSShuming Fan 			.channels_max = 2,
1081320b8b0dSShuming Fan 			.rates = RT711_STEREO_RATES,
1082320b8b0dSShuming Fan 			.formats = RT711_FORMATS,
1083320b8b0dSShuming Fan 		},
1084320b8b0dSShuming Fan 		.ops = &rt711_ops,
1085320b8b0dSShuming Fan 	},
1086320b8b0dSShuming Fan 	{
1087320b8b0dSShuming Fan 		.name = "rt711-aif2",
1088320b8b0dSShuming Fan 		.id = RT711_AIF2,
1089320b8b0dSShuming Fan 		.capture = {
1090320b8b0dSShuming Fan 			.stream_name = "DP2 Capture",
1091320b8b0dSShuming Fan 			.channels_min = 1,
1092320b8b0dSShuming Fan 			.channels_max = 2,
1093320b8b0dSShuming Fan 			.rates = RT711_STEREO_RATES,
1094320b8b0dSShuming Fan 			.formats = RT711_FORMATS,
1095320b8b0dSShuming Fan 		},
1096320b8b0dSShuming Fan 		.ops = &rt711_ops,
1097320b8b0dSShuming Fan 	}
1098320b8b0dSShuming Fan };
1099320b8b0dSShuming Fan 
1100320b8b0dSShuming Fan /* Bus clock frequency */
1101320b8b0dSShuming Fan #define RT711_CLK_FREQ_9600000HZ 9600000
1102320b8b0dSShuming Fan #define RT711_CLK_FREQ_12000000HZ 12000000
1103320b8b0dSShuming Fan #define RT711_CLK_FREQ_6000000HZ 6000000
1104320b8b0dSShuming Fan #define RT711_CLK_FREQ_4800000HZ 4800000
1105320b8b0dSShuming Fan #define RT711_CLK_FREQ_2400000HZ 2400000
1106320b8b0dSShuming Fan #define RT711_CLK_FREQ_12288000HZ 12288000
1107320b8b0dSShuming Fan 
1108320b8b0dSShuming Fan int rt711_clock_config(struct device *dev)
1109320b8b0dSShuming Fan {
1110320b8b0dSShuming Fan 	struct rt711_priv *rt711 = dev_get_drvdata(dev);
1111320b8b0dSShuming Fan 	unsigned int clk_freq, value;
1112320b8b0dSShuming Fan 
1113320b8b0dSShuming Fan 	clk_freq = (rt711->params.curr_dr_freq >> 1);
1114320b8b0dSShuming Fan 
1115320b8b0dSShuming Fan 	switch (clk_freq) {
1116320b8b0dSShuming Fan 	case RT711_CLK_FREQ_12000000HZ:
1117320b8b0dSShuming Fan 		value = 0x0;
1118320b8b0dSShuming Fan 		break;
1119320b8b0dSShuming Fan 	case RT711_CLK_FREQ_6000000HZ:
1120320b8b0dSShuming Fan 		value = 0x1;
1121320b8b0dSShuming Fan 		break;
1122320b8b0dSShuming Fan 	case RT711_CLK_FREQ_9600000HZ:
1123320b8b0dSShuming Fan 		value = 0x2;
1124320b8b0dSShuming Fan 		break;
1125320b8b0dSShuming Fan 	case RT711_CLK_FREQ_4800000HZ:
1126320b8b0dSShuming Fan 		value = 0x3;
1127320b8b0dSShuming Fan 		break;
1128320b8b0dSShuming Fan 	case RT711_CLK_FREQ_2400000HZ:
1129320b8b0dSShuming Fan 		value = 0x4;
1130320b8b0dSShuming Fan 		break;
1131320b8b0dSShuming Fan 	case RT711_CLK_FREQ_12288000HZ:
1132320b8b0dSShuming Fan 		value = 0x5;
1133320b8b0dSShuming Fan 		break;
1134320b8b0dSShuming Fan 	default:
1135320b8b0dSShuming Fan 		return -EINVAL;
1136320b8b0dSShuming Fan 	}
1137320b8b0dSShuming Fan 
1138320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0xe0, value);
1139320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0xf0, value);
1140320b8b0dSShuming Fan 
1141320b8b0dSShuming Fan 	dev_dbg(dev, "%s complete, clk_freq=%d\n", __func__, clk_freq);
1142320b8b0dSShuming Fan 
1143320b8b0dSShuming Fan 	return 0;
1144320b8b0dSShuming Fan }
1145320b8b0dSShuming Fan 
1146320b8b0dSShuming Fan static void rt711_calibration_work(struct work_struct *work)
1147320b8b0dSShuming Fan {
1148320b8b0dSShuming Fan 	struct rt711_priv *rt711 =
1149320b8b0dSShuming Fan 		container_of(work, struct rt711_priv, calibration_work);
1150320b8b0dSShuming Fan 
1151320b8b0dSShuming Fan 	rt711_calibration(rt711);
1152320b8b0dSShuming Fan }
1153320b8b0dSShuming Fan 
1154320b8b0dSShuming Fan int rt711_init(struct device *dev, struct regmap *sdw_regmap,
1155320b8b0dSShuming Fan 			struct regmap *regmap, struct sdw_slave *slave)
1156320b8b0dSShuming Fan {
1157320b8b0dSShuming Fan 	struct rt711_priv *rt711;
1158320b8b0dSShuming Fan 	int ret;
1159320b8b0dSShuming Fan 
1160320b8b0dSShuming Fan 	rt711 = devm_kzalloc(dev, sizeof(*rt711), GFP_KERNEL);
1161320b8b0dSShuming Fan 	if (!rt711)
1162320b8b0dSShuming Fan 		return -ENOMEM;
1163320b8b0dSShuming Fan 
1164320b8b0dSShuming Fan 	dev_set_drvdata(dev, rt711);
1165320b8b0dSShuming Fan 	rt711->slave = slave;
1166320b8b0dSShuming Fan 	rt711->sdw_regmap = sdw_regmap;
1167320b8b0dSShuming Fan 	rt711->regmap = regmap;
1168320b8b0dSShuming Fan 
1169320b8b0dSShuming Fan 	/*
1170320b8b0dSShuming Fan 	 * Mark hw_init to false
1171320b8b0dSShuming Fan 	 * HW init will be performed when device reports present
1172320b8b0dSShuming Fan 	 */
1173320b8b0dSShuming Fan 	rt711->hw_init = false;
1174320b8b0dSShuming Fan 	rt711->first_hw_init = false;
1175320b8b0dSShuming Fan 
1176320b8b0dSShuming Fan 	/* JD source uses JD2 in default */
1177320b8b0dSShuming Fan 	rt711->jd_src = RT711_JD2;
1178320b8b0dSShuming Fan 
1179320b8b0dSShuming Fan 	ret =  devm_snd_soc_register_component(dev,
1180320b8b0dSShuming Fan 				&soc_codec_dev_rt711,
1181320b8b0dSShuming Fan 				rt711_dai,
1182320b8b0dSShuming Fan 				ARRAY_SIZE(rt711_dai));
1183320b8b0dSShuming Fan 
1184320b8b0dSShuming Fan 	dev_dbg(&slave->dev, "%s\n", __func__);
1185320b8b0dSShuming Fan 
1186320b8b0dSShuming Fan 	return ret;
1187320b8b0dSShuming Fan }
1188320b8b0dSShuming Fan 
1189320b8b0dSShuming Fan int rt711_io_init(struct device *dev, struct sdw_slave *slave)
1190320b8b0dSShuming Fan {
1191320b8b0dSShuming Fan 	struct rt711_priv *rt711 = dev_get_drvdata(dev);
1192320b8b0dSShuming Fan 
1193320b8b0dSShuming Fan 	if (rt711->hw_init)
1194320b8b0dSShuming Fan 		return 0;
1195320b8b0dSShuming Fan 
1196320b8b0dSShuming Fan 	if (rt711->first_hw_init) {
1197320b8b0dSShuming Fan 		regcache_cache_only(rt711->regmap, false);
1198320b8b0dSShuming Fan 		regcache_cache_bypass(rt711->regmap, true);
1199320b8b0dSShuming Fan 	}
1200320b8b0dSShuming Fan 
1201320b8b0dSShuming Fan 	/*
1202320b8b0dSShuming Fan 	 * PM runtime is only enabled when a Slave reports as Attached
1203320b8b0dSShuming Fan 	 */
1204320b8b0dSShuming Fan 	if (!rt711->first_hw_init) {
1205320b8b0dSShuming Fan 		/* set autosuspend parameters */
1206320b8b0dSShuming Fan 		pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
1207320b8b0dSShuming Fan 		pm_runtime_use_autosuspend(&slave->dev);
1208320b8b0dSShuming Fan 
1209320b8b0dSShuming Fan 		/* update count of parent 'active' children */
1210320b8b0dSShuming Fan 		pm_runtime_set_active(&slave->dev);
1211320b8b0dSShuming Fan 
1212320b8b0dSShuming Fan 		/* make sure the device does not suspend immediately */
1213320b8b0dSShuming Fan 		pm_runtime_mark_last_busy(&slave->dev);
1214320b8b0dSShuming Fan 
1215320b8b0dSShuming Fan 		pm_runtime_enable(&slave->dev);
1216320b8b0dSShuming Fan 	}
1217320b8b0dSShuming Fan 
1218320b8b0dSShuming Fan 	pm_runtime_get_noresume(&slave->dev);
1219320b8b0dSShuming Fan 
1220320b8b0dSShuming Fan 	rt711_reset(rt711->regmap);
1221320b8b0dSShuming Fan 
1222320b8b0dSShuming Fan 	/* power on */
1223320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D0);
1224320b8b0dSShuming Fan 
1225320b8b0dSShuming Fan 	/* Set Pin Widget */
1226320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_PIN_MIC2, 0x25);
1227320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_PIN_HP, 0xc0);
1228320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_PIN_DMIC1, 0x20);
1229320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_PIN_DMIC2, 0x20);
1230320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_PIN_LINE1, 0x20);
1231320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_PIN_LINE2, 0x20);
1232320b8b0dSShuming Fan 
1233320b8b0dSShuming Fan 	/* Mute HP/ADC1/ADC2 */
1234320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_GAIN_HP_H, 0xa080);
1235320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_GAIN_HP_H, 0x9080);
1236320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_GAIN_ADC2_H, 0x6080);
1237320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_GAIN_ADC2_H, 0x5080);
1238320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_GAIN_ADC1_H, 0x6080);
1239320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_GAIN_ADC1_H, 0x5080);
1240320b8b0dSShuming Fan 
1241320b8b0dSShuming Fan 	/* Set Configuration Default */
1242320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4f12, 0x91);
1243320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4e12, 0xd6);
1244320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4d12, 0x11);
1245320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4c12, 0x20);
1246320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4f13, 0x91);
1247320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4e13, 0xd6);
1248320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4d13, 0x11);
1249320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4c13, 0x21);
1250320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4c21, 0xf0);
1251320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4d21, 0x11);
1252320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4e21, 0x11);
1253320b8b0dSShuming Fan 	regmap_write(rt711->regmap, 0x4f21, 0x01);
1254320b8b0dSShuming Fan 
1255320b8b0dSShuming Fan 	/* Data port arrangement */
1256320b8b0dSShuming Fan 	rt711_index_write(rt711->regmap, RT711_VENDOR_REG,
1257320b8b0dSShuming Fan 		RT711_TX_RX_MUX_CTL, 0x0154);
1258320b8b0dSShuming Fan 
1259320b8b0dSShuming Fan 	/* Set index */
1260320b8b0dSShuming Fan 	rt711_index_write(rt711->regmap, RT711_VENDOR_REG,
1261320b8b0dSShuming Fan 		RT711_DIGITAL_MISC_CTRL4, 0x201b);
1262320b8b0dSShuming Fan 	rt711_index_write(rt711->regmap, RT711_VENDOR_REG,
1263320b8b0dSShuming Fan 		RT711_COMBO_JACK_AUTO_CTL1, 0x5089);
1264320b8b0dSShuming Fan 	rt711_index_write(rt711->regmap, RT711_VENDOR_REG,
1265320b8b0dSShuming Fan 		RT711_VREFOUT_CTL, 0x5064);
1266320b8b0dSShuming Fan 	rt711_index_write(rt711->regmap, RT711_VENDOR_REG,
1267320b8b0dSShuming Fan 		RT711_INLINE_CMD_CTL, 0xd249);
1268320b8b0dSShuming Fan 
1269320b8b0dSShuming Fan 	/* Finish Initial Settings, set power to D3 */
1270320b8b0dSShuming Fan 	regmap_write(rt711->regmap, RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D3);
1271320b8b0dSShuming Fan 
1272320b8b0dSShuming Fan 	if (rt711->first_hw_init)
1273320b8b0dSShuming Fan 		rt711_calibration(rt711);
1274320b8b0dSShuming Fan 	else {
1275320b8b0dSShuming Fan 		INIT_DELAYED_WORK(&rt711->jack_detect_work,
1276320b8b0dSShuming Fan 			rt711_jack_detect_handler);
1277320b8b0dSShuming Fan 		INIT_DELAYED_WORK(&rt711->jack_btn_check_work,
1278320b8b0dSShuming Fan 			rt711_btn_check_handler);
1279320b8b0dSShuming Fan 		mutex_init(&rt711->calibrate_mutex);
1280320b8b0dSShuming Fan 		INIT_WORK(&rt711->calibration_work, rt711_calibration_work);
1281320b8b0dSShuming Fan 		schedule_work(&rt711->calibration_work);
1282320b8b0dSShuming Fan 	}
1283320b8b0dSShuming Fan 
1284320b8b0dSShuming Fan 	/*
1285320b8b0dSShuming Fan 	 * if set_jack callback occurred early than io_init,
1286320b8b0dSShuming Fan 	 * we set up the jack detection function now
1287320b8b0dSShuming Fan 	 */
1288320b8b0dSShuming Fan 	if (rt711->hs_jack)
1289320b8b0dSShuming Fan 		rt711_jack_init(rt711);
1290320b8b0dSShuming Fan 
1291320b8b0dSShuming Fan 	if (rt711->first_hw_init) {
1292320b8b0dSShuming Fan 		regcache_cache_bypass(rt711->regmap, false);
1293320b8b0dSShuming Fan 		regcache_mark_dirty(rt711->regmap);
1294320b8b0dSShuming Fan 	} else
1295320b8b0dSShuming Fan 		rt711->first_hw_init = true;
1296320b8b0dSShuming Fan 
1297320b8b0dSShuming Fan 	/* Mark Slave initialization complete */
1298320b8b0dSShuming Fan 	rt711->hw_init = true;
1299320b8b0dSShuming Fan 
1300320b8b0dSShuming Fan 	pm_runtime_mark_last_busy(&slave->dev);
1301320b8b0dSShuming Fan 	pm_runtime_put_autosuspend(&slave->dev);
1302320b8b0dSShuming Fan 
1303320b8b0dSShuming Fan 	dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);
1304320b8b0dSShuming Fan 	return 0;
1305320b8b0dSShuming Fan }
1306320b8b0dSShuming Fan 
1307320b8b0dSShuming Fan MODULE_DESCRIPTION("ASoC RT711 SDW driver");
1308320b8b0dSShuming Fan MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");
1309320b8b0dSShuming Fan MODULE_LICENSE("GPL");
1310