xref: /openbmc/linux/sound/soc/codecs/rt5668.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2d59fb285SBard Liao /*
3d59fb285SBard Liao  * rt5668.c  --  RT5668B ALSA SoC audio component driver
4d59fb285SBard Liao  *
5d59fb285SBard Liao  * Copyright 2018 Realtek Semiconductor Corp.
6d59fb285SBard Liao  * Author: Bard Liao <bardliao@realtek.com>
7d59fb285SBard Liao  */
8d59fb285SBard Liao 
9d59fb285SBard Liao #include <linux/module.h>
10d59fb285SBard Liao #include <linux/moduleparam.h>
11d59fb285SBard Liao #include <linux/init.h>
12d59fb285SBard Liao #include <linux/delay.h>
13d59fb285SBard Liao #include <linux/pm.h>
14d59fb285SBard Liao #include <linux/i2c.h>
15d59fb285SBard Liao #include <linux/platform_device.h>
16d59fb285SBard Liao #include <linux/spi/spi.h>
17d59fb285SBard Liao #include <linux/acpi.h>
18*ab2a5d17SLinus Walleij #include <linux/gpio/consumer.h>
19d59fb285SBard Liao #include <linux/regulator/consumer.h>
20d59fb285SBard Liao #include <linux/mutex.h>
21d59fb285SBard Liao #include <sound/core.h>
22d59fb285SBard Liao #include <sound/pcm.h>
23d59fb285SBard Liao #include <sound/pcm_params.h>
24d59fb285SBard Liao #include <sound/jack.h>
25d59fb285SBard Liao #include <sound/soc.h>
26d59fb285SBard Liao #include <sound/soc-dapm.h>
27d59fb285SBard Liao #include <sound/initval.h>
28d59fb285SBard Liao #include <sound/tlv.h>
29d59fb285SBard Liao #include <sound/rt5668.h>
30d59fb285SBard Liao 
31d59fb285SBard Liao #include "rl6231.h"
32d59fb285SBard Liao #include "rt5668.h"
33d59fb285SBard Liao 
34d59fb285SBard Liao #define RT5668_NUM_SUPPLIES 3
35d59fb285SBard Liao 
36d59fb285SBard Liao static const char *rt5668_supply_names[RT5668_NUM_SUPPLIES] = {
37d59fb285SBard Liao 	"AVDD",
38d59fb285SBard Liao 	"MICVDD",
39d59fb285SBard Liao 	"VBAT",
40d59fb285SBard Liao };
41d59fb285SBard Liao 
42d59fb285SBard Liao struct rt5668_priv {
43d59fb285SBard Liao 	struct snd_soc_component *component;
44d59fb285SBard Liao 	struct rt5668_platform_data pdata;
45*ab2a5d17SLinus Walleij 	struct gpio_desc *ldo1_en;
46d59fb285SBard Liao 	struct regmap *regmap;
47d59fb285SBard Liao 	struct snd_soc_jack *hs_jack;
48d59fb285SBard Liao 	struct regulator_bulk_data supplies[RT5668_NUM_SUPPLIES];
49d59fb285SBard Liao 	struct delayed_work jack_detect_work;
50d59fb285SBard Liao 	struct delayed_work jd_check_work;
51d59fb285SBard Liao 	struct mutex calibrate_mutex;
52d59fb285SBard Liao 
53d59fb285SBard Liao 	int sysclk;
54d59fb285SBard Liao 	int sysclk_src;
55d59fb285SBard Liao 	int lrck[RT5668_AIFS];
56d59fb285SBard Liao 	int bclk[RT5668_AIFS];
57d59fb285SBard Liao 	int master[RT5668_AIFS];
58d59fb285SBard Liao 
59d59fb285SBard Liao 	int pll_src;
60d59fb285SBard Liao 	int pll_in;
61d59fb285SBard Liao 	int pll_out;
62d59fb285SBard Liao 
63d59fb285SBard Liao 	int jack_type;
64d59fb285SBard Liao };
65d59fb285SBard Liao 
66d59fb285SBard Liao static const struct reg_default rt5668_reg[] = {
67d59fb285SBard Liao 	{0x0002, 0x8080},
68d59fb285SBard Liao 	{0x0003, 0x8000},
69d59fb285SBard Liao 	{0x0005, 0x0000},
70d59fb285SBard Liao 	{0x0006, 0x0000},
71d59fb285SBard Liao 	{0x0008, 0x800f},
72d59fb285SBard Liao 	{0x000b, 0x0000},
73d59fb285SBard Liao 	{0x0010, 0x4040},
74d59fb285SBard Liao 	{0x0011, 0x0000},
75d59fb285SBard Liao 	{0x0012, 0x1404},
76d59fb285SBard Liao 	{0x0013, 0x1000},
77d59fb285SBard Liao 	{0x0014, 0xa00a},
78d59fb285SBard Liao 	{0x0015, 0x0404},
79d59fb285SBard Liao 	{0x0016, 0x0404},
80d59fb285SBard Liao 	{0x0019, 0xafaf},
81d59fb285SBard Liao 	{0x001c, 0x2f2f},
82d59fb285SBard Liao 	{0x001f, 0x0000},
83d59fb285SBard Liao 	{0x0022, 0x5757},
84d59fb285SBard Liao 	{0x0023, 0x0039},
85d59fb285SBard Liao 	{0x0024, 0x000b},
86d59fb285SBard Liao 	{0x0026, 0xc0c4},
87d59fb285SBard Liao 	{0x0029, 0x8080},
88d59fb285SBard Liao 	{0x002a, 0xa0a0},
89d59fb285SBard Liao 	{0x002b, 0x0300},
90d59fb285SBard Liao 	{0x0030, 0x0000},
91d59fb285SBard Liao 	{0x003c, 0x0080},
92d59fb285SBard Liao 	{0x0044, 0x0c0c},
93d59fb285SBard Liao 	{0x0049, 0x0000},
94d59fb285SBard Liao 	{0x0061, 0x0000},
95d59fb285SBard Liao 	{0x0062, 0x0000},
96d59fb285SBard Liao 	{0x0063, 0x003f},
97d59fb285SBard Liao 	{0x0064, 0x0000},
98d59fb285SBard Liao 	{0x0065, 0x0000},
99d59fb285SBard Liao 	{0x0066, 0x0030},
100d59fb285SBard Liao 	{0x0067, 0x0000},
101d59fb285SBard Liao 	{0x006b, 0x0000},
102d59fb285SBard Liao 	{0x006c, 0x0000},
103d59fb285SBard Liao 	{0x006d, 0x2200},
104d59fb285SBard Liao 	{0x006e, 0x0a10},
105d59fb285SBard Liao 	{0x0070, 0x8000},
106d59fb285SBard Liao 	{0x0071, 0x8000},
107d59fb285SBard Liao 	{0x0073, 0x0000},
108d59fb285SBard Liao 	{0x0074, 0x0000},
109d59fb285SBard Liao 	{0x0075, 0x0002},
110d59fb285SBard Liao 	{0x0076, 0x0001},
111d59fb285SBard Liao 	{0x0079, 0x0000},
112d59fb285SBard Liao 	{0x007a, 0x0000},
113d59fb285SBard Liao 	{0x007b, 0x0000},
114d59fb285SBard Liao 	{0x007c, 0x0100},
115d59fb285SBard Liao 	{0x007e, 0x0000},
116d59fb285SBard Liao 	{0x0080, 0x0000},
117d59fb285SBard Liao 	{0x0081, 0x0000},
118d59fb285SBard Liao 	{0x0082, 0x0000},
119d59fb285SBard Liao 	{0x0083, 0x0000},
120d59fb285SBard Liao 	{0x0084, 0x0000},
121d59fb285SBard Liao 	{0x0085, 0x0000},
122d59fb285SBard Liao 	{0x0086, 0x0005},
123d59fb285SBard Liao 	{0x0087, 0x0000},
124d59fb285SBard Liao 	{0x0088, 0x0000},
125d59fb285SBard Liao 	{0x008c, 0x0003},
126d59fb285SBard Liao 	{0x008d, 0x0000},
127d59fb285SBard Liao 	{0x008e, 0x0060},
128d59fb285SBard Liao 	{0x008f, 0x1000},
129d59fb285SBard Liao 	{0x0091, 0x0c26},
130d59fb285SBard Liao 	{0x0092, 0x0073},
131d59fb285SBard Liao 	{0x0093, 0x0000},
132d59fb285SBard Liao 	{0x0094, 0x0080},
133d59fb285SBard Liao 	{0x0098, 0x0000},
134d59fb285SBard Liao 	{0x009a, 0x0000},
135d59fb285SBard Liao 	{0x009b, 0x0000},
136d59fb285SBard Liao 	{0x009c, 0x0000},
137d59fb285SBard Liao 	{0x009d, 0x0000},
138d59fb285SBard Liao 	{0x009e, 0x100c},
139d59fb285SBard Liao 	{0x009f, 0x0000},
140d59fb285SBard Liao 	{0x00a0, 0x0000},
141d59fb285SBard Liao 	{0x00a3, 0x0002},
142d59fb285SBard Liao 	{0x00a4, 0x0001},
143d59fb285SBard Liao 	{0x00ae, 0x2040},
144d59fb285SBard Liao 	{0x00af, 0x0000},
145d59fb285SBard Liao 	{0x00b6, 0x0000},
146d59fb285SBard Liao 	{0x00b7, 0x0000},
147d59fb285SBard Liao 	{0x00b8, 0x0000},
148d59fb285SBard Liao 	{0x00b9, 0x0002},
149d59fb285SBard Liao 	{0x00be, 0x0000},
150d59fb285SBard Liao 	{0x00c0, 0x0160},
151d59fb285SBard Liao 	{0x00c1, 0x82a0},
152d59fb285SBard Liao 	{0x00c2, 0x0000},
153d59fb285SBard Liao 	{0x00d0, 0x0000},
154d59fb285SBard Liao 	{0x00d1, 0x2244},
155d59fb285SBard Liao 	{0x00d2, 0x3300},
156d59fb285SBard Liao 	{0x00d3, 0x2200},
157d59fb285SBard Liao 	{0x00d4, 0x0000},
158d59fb285SBard Liao 	{0x00d9, 0x0009},
159d59fb285SBard Liao 	{0x00da, 0x0000},
160d59fb285SBard Liao 	{0x00db, 0x0000},
161d59fb285SBard Liao 	{0x00dc, 0x00c0},
162d59fb285SBard Liao 	{0x00dd, 0x2220},
163d59fb285SBard Liao 	{0x00de, 0x3131},
164d59fb285SBard Liao 	{0x00df, 0x3131},
165d59fb285SBard Liao 	{0x00e0, 0x3131},
166d59fb285SBard Liao 	{0x00e2, 0x0000},
167d59fb285SBard Liao 	{0x00e3, 0x4000},
168d59fb285SBard Liao 	{0x00e4, 0x0aa0},
169d59fb285SBard Liao 	{0x00e5, 0x3131},
170d59fb285SBard Liao 	{0x00e6, 0x3131},
171d59fb285SBard Liao 	{0x00e7, 0x3131},
172d59fb285SBard Liao 	{0x00e8, 0x3131},
173d59fb285SBard Liao 	{0x00ea, 0xb320},
174d59fb285SBard Liao 	{0x00eb, 0x0000},
175d59fb285SBard Liao 	{0x00f0, 0x0000},
176d59fb285SBard Liao 	{0x00f1, 0x00d0},
177d59fb285SBard Liao 	{0x00f2, 0x00d0},
178d59fb285SBard Liao 	{0x00f6, 0x0000},
179d59fb285SBard Liao 	{0x00fa, 0x0000},
180d59fb285SBard Liao 	{0x00fb, 0x0000},
181d59fb285SBard Liao 	{0x00fc, 0x0000},
182d59fb285SBard Liao 	{0x00fd, 0x0000},
183d59fb285SBard Liao 	{0x00fe, 0x10ec},
184d59fb285SBard Liao 	{0x00ff, 0x6530},
185d59fb285SBard Liao 	{0x0100, 0xa0a0},
186d59fb285SBard Liao 	{0x010b, 0x0000},
187d59fb285SBard Liao 	{0x010c, 0xae00},
188d59fb285SBard Liao 	{0x010d, 0xaaa0},
189d59fb285SBard Liao 	{0x010e, 0x8aa2},
190d59fb285SBard Liao 	{0x010f, 0x02a2},
191d59fb285SBard Liao 	{0x0110, 0xc000},
192d59fb285SBard Liao 	{0x0111, 0x04a2},
193d59fb285SBard Liao 	{0x0112, 0x2800},
194d59fb285SBard Liao 	{0x0113, 0x0000},
195d59fb285SBard Liao 	{0x0117, 0x0100},
196d59fb285SBard Liao 	{0x0125, 0x0410},
197d59fb285SBard Liao 	{0x0132, 0x6026},
198d59fb285SBard Liao 	{0x0136, 0x5555},
199d59fb285SBard Liao 	{0x0138, 0x3700},
200d59fb285SBard Liao 	{0x013a, 0x2000},
201d59fb285SBard Liao 	{0x013b, 0x2000},
202d59fb285SBard Liao 	{0x013c, 0x2005},
203d59fb285SBard Liao 	{0x013f, 0x0000},
204d59fb285SBard Liao 	{0x0142, 0x0000},
205d59fb285SBard Liao 	{0x0145, 0x0002},
206d59fb285SBard Liao 	{0x0146, 0x0000},
207d59fb285SBard Liao 	{0x0147, 0x0000},
208d59fb285SBard Liao 	{0x0148, 0x0000},
209d59fb285SBard Liao 	{0x0149, 0x0000},
210d59fb285SBard Liao 	{0x0150, 0x79a1},
211d59fb285SBard Liao 	{0x0151, 0x0000},
212d59fb285SBard Liao 	{0x0160, 0x4ec0},
213d59fb285SBard Liao 	{0x0161, 0x0080},
214d59fb285SBard Liao 	{0x0162, 0x0200},
215d59fb285SBard Liao 	{0x0163, 0x0800},
216d59fb285SBard Liao 	{0x0164, 0x0000},
217d59fb285SBard Liao 	{0x0165, 0x0000},
218d59fb285SBard Liao 	{0x0166, 0x0000},
219d59fb285SBard Liao 	{0x0167, 0x000f},
220d59fb285SBard Liao 	{0x0168, 0x000f},
221d59fb285SBard Liao 	{0x0169, 0x0021},
222d59fb285SBard Liao 	{0x0190, 0x413d},
223d59fb285SBard Liao 	{0x0194, 0x0000},
224d59fb285SBard Liao 	{0x0195, 0x0000},
225d59fb285SBard Liao 	{0x0197, 0x0022},
226d59fb285SBard Liao 	{0x0198, 0x0000},
227d59fb285SBard Liao 	{0x0199, 0x0000},
228d59fb285SBard Liao 	{0x01af, 0x0000},
229d59fb285SBard Liao 	{0x01b0, 0x0400},
230d59fb285SBard Liao 	{0x01b1, 0x0000},
231d59fb285SBard Liao 	{0x01b2, 0x0000},
232d59fb285SBard Liao 	{0x01b3, 0x0000},
233d59fb285SBard Liao 	{0x01b4, 0x0000},
234d59fb285SBard Liao 	{0x01b5, 0x0000},
235d59fb285SBard Liao 	{0x01b6, 0x01c3},
236d59fb285SBard Liao 	{0x01b7, 0x02a0},
237d59fb285SBard Liao 	{0x01b8, 0x03e9},
238d59fb285SBard Liao 	{0x01b9, 0x1389},
239d59fb285SBard Liao 	{0x01ba, 0xc351},
240d59fb285SBard Liao 	{0x01bb, 0x0009},
241d59fb285SBard Liao 	{0x01bc, 0x0018},
242d59fb285SBard Liao 	{0x01bd, 0x002a},
243d59fb285SBard Liao 	{0x01be, 0x004c},
244d59fb285SBard Liao 	{0x01bf, 0x0097},
245d59fb285SBard Liao 	{0x01c0, 0x433d},
246d59fb285SBard Liao 	{0x01c1, 0x2800},
247d59fb285SBard Liao 	{0x01c2, 0x0000},
248d59fb285SBard Liao 	{0x01c3, 0x0000},
249d59fb285SBard Liao 	{0x01c4, 0x0000},
250d59fb285SBard Liao 	{0x01c5, 0x0000},
251d59fb285SBard Liao 	{0x01c6, 0x0000},
252d59fb285SBard Liao 	{0x01c7, 0x0000},
253d59fb285SBard Liao 	{0x01c8, 0x40af},
254d59fb285SBard Liao 	{0x01c9, 0x0702},
255d59fb285SBard Liao 	{0x01ca, 0x0000},
256d59fb285SBard Liao 	{0x01cb, 0x0000},
257d59fb285SBard Liao 	{0x01cc, 0x5757},
258d59fb285SBard Liao 	{0x01cd, 0x5757},
259d59fb285SBard Liao 	{0x01ce, 0x5757},
260d59fb285SBard Liao 	{0x01cf, 0x5757},
261d59fb285SBard Liao 	{0x01d0, 0x5757},
262d59fb285SBard Liao 	{0x01d1, 0x5757},
263d59fb285SBard Liao 	{0x01d2, 0x5757},
264d59fb285SBard Liao 	{0x01d3, 0x5757},
265d59fb285SBard Liao 	{0x01d4, 0x5757},
266d59fb285SBard Liao 	{0x01d5, 0x5757},
267d59fb285SBard Liao 	{0x01d6, 0x0000},
268d59fb285SBard Liao 	{0x01d7, 0x0008},
269d59fb285SBard Liao 	{0x01d8, 0x0029},
270d59fb285SBard Liao 	{0x01d9, 0x3333},
271d59fb285SBard Liao 	{0x01da, 0x0000},
272d59fb285SBard Liao 	{0x01db, 0x0004},
273d59fb285SBard Liao 	{0x01dc, 0x0000},
274d59fb285SBard Liao 	{0x01de, 0x7c00},
275d59fb285SBard Liao 	{0x01df, 0x0320},
276d59fb285SBard Liao 	{0x01e0, 0x06a1},
277d59fb285SBard Liao 	{0x01e1, 0x0000},
278d59fb285SBard Liao 	{0x01e2, 0x0000},
279d59fb285SBard Liao 	{0x01e3, 0x0000},
280d59fb285SBard Liao 	{0x01e4, 0x0000},
281d59fb285SBard Liao 	{0x01e6, 0x0001},
282d59fb285SBard Liao 	{0x01e7, 0x0000},
283d59fb285SBard Liao 	{0x01e8, 0x0000},
284d59fb285SBard Liao 	{0x01ea, 0x0000},
285d59fb285SBard Liao 	{0x01eb, 0x0000},
286d59fb285SBard Liao 	{0x01ec, 0x0000},
287d59fb285SBard Liao 	{0x01ed, 0x0000},
288d59fb285SBard Liao 	{0x01ee, 0x0000},
289d59fb285SBard Liao 	{0x01ef, 0x0000},
290d59fb285SBard Liao 	{0x01f0, 0x0000},
291d59fb285SBard Liao 	{0x01f1, 0x0000},
292d59fb285SBard Liao 	{0x01f2, 0x0000},
293d59fb285SBard Liao 	{0x01f3, 0x0000},
294d59fb285SBard Liao 	{0x01f4, 0x0000},
295d59fb285SBard Liao 	{0x0210, 0x6297},
296d59fb285SBard Liao 	{0x0211, 0xa005},
297d59fb285SBard Liao 	{0x0212, 0x824c},
298d59fb285SBard Liao 	{0x0213, 0xf7ff},
299d59fb285SBard Liao 	{0x0214, 0xf24c},
300d59fb285SBard Liao 	{0x0215, 0x0102},
301d59fb285SBard Liao 	{0x0216, 0x00a3},
302d59fb285SBard Liao 	{0x0217, 0x0048},
303d59fb285SBard Liao 	{0x0218, 0xa2c0},
304d59fb285SBard Liao 	{0x0219, 0x0400},
305d59fb285SBard Liao 	{0x021a, 0x00c8},
306d59fb285SBard Liao 	{0x021b, 0x00c0},
307d59fb285SBard Liao 	{0x021c, 0x0000},
308d59fb285SBard Liao 	{0x0250, 0x4500},
309d59fb285SBard Liao 	{0x0251, 0x40b3},
310d59fb285SBard Liao 	{0x0252, 0x0000},
311d59fb285SBard Liao 	{0x0253, 0x0000},
312d59fb285SBard Liao 	{0x0254, 0x0000},
313d59fb285SBard Liao 	{0x0255, 0x0000},
314d59fb285SBard Liao 	{0x0256, 0x0000},
315d59fb285SBard Liao 	{0x0257, 0x0000},
316d59fb285SBard Liao 	{0x0258, 0x0000},
317d59fb285SBard Liao 	{0x0259, 0x0000},
318d59fb285SBard Liao 	{0x025a, 0x0005},
319d59fb285SBard Liao 	{0x0270, 0x0000},
320d59fb285SBard Liao 	{0x02ff, 0x0110},
321d59fb285SBard Liao 	{0x0300, 0x001f},
322d59fb285SBard Liao 	{0x0301, 0x032c},
323d59fb285SBard Liao 	{0x0302, 0x5f21},
324d59fb285SBard Liao 	{0x0303, 0x4000},
325d59fb285SBard Liao 	{0x0304, 0x4000},
326d59fb285SBard Liao 	{0x0305, 0x06d5},
327d59fb285SBard Liao 	{0x0306, 0x8000},
328d59fb285SBard Liao 	{0x0307, 0x0700},
329d59fb285SBard Liao 	{0x0310, 0x4560},
330d59fb285SBard Liao 	{0x0311, 0xa4a8},
331d59fb285SBard Liao 	{0x0312, 0x7418},
332d59fb285SBard Liao 	{0x0313, 0x0000},
333d59fb285SBard Liao 	{0x0314, 0x0006},
334d59fb285SBard Liao 	{0x0315, 0xffff},
335d59fb285SBard Liao 	{0x0316, 0xc400},
336d59fb285SBard Liao 	{0x0317, 0x0000},
337d59fb285SBard Liao 	{0x03c0, 0x7e00},
338d59fb285SBard Liao 	{0x03c1, 0x8000},
339d59fb285SBard Liao 	{0x03c2, 0x8000},
340d59fb285SBard Liao 	{0x03c3, 0x8000},
341d59fb285SBard Liao 	{0x03c4, 0x8000},
342d59fb285SBard Liao 	{0x03c5, 0x8000},
343d59fb285SBard Liao 	{0x03c6, 0x8000},
344d59fb285SBard Liao 	{0x03c7, 0x8000},
345d59fb285SBard Liao 	{0x03c8, 0x8000},
346d59fb285SBard Liao 	{0x03c9, 0x8000},
347d59fb285SBard Liao 	{0x03ca, 0x8000},
348d59fb285SBard Liao 	{0x03cb, 0x8000},
349d59fb285SBard Liao 	{0x03cc, 0x8000},
350d59fb285SBard Liao 	{0x03d0, 0x0000},
351d59fb285SBard Liao 	{0x03d1, 0x0000},
352d59fb285SBard Liao 	{0x03d2, 0x0000},
353d59fb285SBard Liao 	{0x03d3, 0x0000},
354d59fb285SBard Liao 	{0x03d4, 0x2000},
355d59fb285SBard Liao 	{0x03d5, 0x2000},
356d59fb285SBard Liao 	{0x03d6, 0x0000},
357d59fb285SBard Liao 	{0x03d7, 0x0000},
358d59fb285SBard Liao 	{0x03d8, 0x2000},
359d59fb285SBard Liao 	{0x03d9, 0x2000},
360d59fb285SBard Liao 	{0x03da, 0x2000},
361d59fb285SBard Liao 	{0x03db, 0x2000},
362d59fb285SBard Liao 	{0x03dc, 0x0000},
363d59fb285SBard Liao 	{0x03dd, 0x0000},
364d59fb285SBard Liao 	{0x03de, 0x0000},
365d59fb285SBard Liao 	{0x03df, 0x2000},
366d59fb285SBard Liao 	{0x03e0, 0x0000},
367d59fb285SBard Liao 	{0x03e1, 0x0000},
368d59fb285SBard Liao 	{0x03e2, 0x0000},
369d59fb285SBard Liao 	{0x03e3, 0x0000},
370d59fb285SBard Liao 	{0x03e4, 0x0000},
371d59fb285SBard Liao 	{0x03e5, 0x0000},
372d59fb285SBard Liao 	{0x03e6, 0x0000},
373d59fb285SBard Liao 	{0x03e7, 0x0000},
374d59fb285SBard Liao 	{0x03e8, 0x0000},
375d59fb285SBard Liao 	{0x03e9, 0x0000},
376d59fb285SBard Liao 	{0x03ea, 0x0000},
377d59fb285SBard Liao 	{0x03eb, 0x0000},
378d59fb285SBard Liao 	{0x03ec, 0x0000},
379d59fb285SBard Liao 	{0x03ed, 0x0000},
380d59fb285SBard Liao 	{0x03ee, 0x0000},
381d59fb285SBard Liao 	{0x03ef, 0x0000},
382d59fb285SBard Liao 	{0x03f0, 0x0800},
383d59fb285SBard Liao 	{0x03f1, 0x0800},
384d59fb285SBard Liao 	{0x03f2, 0x0800},
385d59fb285SBard Liao 	{0x03f3, 0x0800},
386d59fb285SBard Liao };
387d59fb285SBard Liao 
rt5668_volatile_register(struct device * dev,unsigned int reg)388d59fb285SBard Liao static bool rt5668_volatile_register(struct device *dev, unsigned int reg)
389d59fb285SBard Liao {
390d59fb285SBard Liao 	switch (reg) {
391d59fb285SBard Liao 	case RT5668_RESET:
392d59fb285SBard Liao 	case RT5668_CBJ_CTRL_2:
393d59fb285SBard Liao 	case RT5668_INT_ST_1:
394d59fb285SBard Liao 	case RT5668_4BTN_IL_CMD_1:
395d59fb285SBard Liao 	case RT5668_AJD1_CTRL:
396d59fb285SBard Liao 	case RT5668_HP_CALIB_CTRL_1:
397d59fb285SBard Liao 	case RT5668_DEVICE_ID:
398d59fb285SBard Liao 	case RT5668_I2C_MODE:
399d59fb285SBard Liao 	case RT5668_HP_CALIB_CTRL_10:
400d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_2:
401d59fb285SBard Liao 	case RT5668_JD_TOP_VC_VTRL:
402d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_19:
403d59fb285SBard Liao 	case RT5668_IL_CMD_1:
404d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_2:
405d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_4:
406d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_10:
407d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_11:
408d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_6...RT5668_EFUSE_CTRL_11:
409d59fb285SBard Liao 	case RT5668_HP_CALIB_STA_1...RT5668_HP_CALIB_STA_11:
410d59fb285SBard Liao 		return true;
411d59fb285SBard Liao 	default:
412d59fb285SBard Liao 		return false;
413d59fb285SBard Liao 	}
414d59fb285SBard Liao }
415d59fb285SBard Liao 
rt5668_readable_register(struct device * dev,unsigned int reg)416d59fb285SBard Liao static bool rt5668_readable_register(struct device *dev, unsigned int reg)
417d59fb285SBard Liao {
418d59fb285SBard Liao 	switch (reg) {
419d59fb285SBard Liao 	case RT5668_RESET:
420d59fb285SBard Liao 	case RT5668_VERSION_ID:
421d59fb285SBard Liao 	case RT5668_VENDOR_ID:
422d59fb285SBard Liao 	case RT5668_DEVICE_ID:
423d59fb285SBard Liao 	case RT5668_HP_CTRL_1:
424d59fb285SBard Liao 	case RT5668_HP_CTRL_2:
425d59fb285SBard Liao 	case RT5668_HPL_GAIN:
426d59fb285SBard Liao 	case RT5668_HPR_GAIN:
427d59fb285SBard Liao 	case RT5668_I2C_CTRL:
428d59fb285SBard Liao 	case RT5668_CBJ_BST_CTRL:
429d59fb285SBard Liao 	case RT5668_CBJ_CTRL_1:
430d59fb285SBard Liao 	case RT5668_CBJ_CTRL_2:
431d59fb285SBard Liao 	case RT5668_CBJ_CTRL_3:
432d59fb285SBard Liao 	case RT5668_CBJ_CTRL_4:
433d59fb285SBard Liao 	case RT5668_CBJ_CTRL_5:
434d59fb285SBard Liao 	case RT5668_CBJ_CTRL_6:
435d59fb285SBard Liao 	case RT5668_CBJ_CTRL_7:
436d59fb285SBard Liao 	case RT5668_DAC1_DIG_VOL:
437d59fb285SBard Liao 	case RT5668_STO1_ADC_DIG_VOL:
438d59fb285SBard Liao 	case RT5668_STO1_ADC_BOOST:
439d59fb285SBard Liao 	case RT5668_HP_IMP_GAIN_1:
440d59fb285SBard Liao 	case RT5668_HP_IMP_GAIN_2:
441d59fb285SBard Liao 	case RT5668_SIDETONE_CTRL:
442d59fb285SBard Liao 	case RT5668_STO1_ADC_MIXER:
443d59fb285SBard Liao 	case RT5668_AD_DA_MIXER:
444d59fb285SBard Liao 	case RT5668_STO1_DAC_MIXER:
445d59fb285SBard Liao 	case RT5668_A_DAC1_MUX:
446d59fb285SBard Liao 	case RT5668_DIG_INF2_DATA:
447d59fb285SBard Liao 	case RT5668_REC_MIXER:
448d59fb285SBard Liao 	case RT5668_CAL_REC:
449d59fb285SBard Liao 	case RT5668_ALC_BACK_GAIN:
450d59fb285SBard Liao 	case RT5668_PWR_DIG_1:
451d59fb285SBard Liao 	case RT5668_PWR_DIG_2:
452d59fb285SBard Liao 	case RT5668_PWR_ANLG_1:
453d59fb285SBard Liao 	case RT5668_PWR_ANLG_2:
454d59fb285SBard Liao 	case RT5668_PWR_ANLG_3:
455d59fb285SBard Liao 	case RT5668_PWR_MIXER:
456d59fb285SBard Liao 	case RT5668_PWR_VOL:
457d59fb285SBard Liao 	case RT5668_CLK_DET:
458d59fb285SBard Liao 	case RT5668_RESET_LPF_CTRL:
459d59fb285SBard Liao 	case RT5668_RESET_HPF_CTRL:
460d59fb285SBard Liao 	case RT5668_DMIC_CTRL_1:
461d59fb285SBard Liao 	case RT5668_I2S1_SDP:
462d59fb285SBard Liao 	case RT5668_I2S2_SDP:
463d59fb285SBard Liao 	case RT5668_ADDA_CLK_1:
464d59fb285SBard Liao 	case RT5668_ADDA_CLK_2:
465d59fb285SBard Liao 	case RT5668_I2S1_F_DIV_CTRL_1:
466d59fb285SBard Liao 	case RT5668_I2S1_F_DIV_CTRL_2:
467d59fb285SBard Liao 	case RT5668_TDM_CTRL:
468d59fb285SBard Liao 	case RT5668_TDM_ADDA_CTRL_1:
469d59fb285SBard Liao 	case RT5668_TDM_ADDA_CTRL_2:
470d59fb285SBard Liao 	case RT5668_DATA_SEL_CTRL_1:
471d59fb285SBard Liao 	case RT5668_TDM_TCON_CTRL:
472d59fb285SBard Liao 	case RT5668_GLB_CLK:
473d59fb285SBard Liao 	case RT5668_PLL_CTRL_1:
474d59fb285SBard Liao 	case RT5668_PLL_CTRL_2:
475d59fb285SBard Liao 	case RT5668_PLL_TRACK_1:
476d59fb285SBard Liao 	case RT5668_PLL_TRACK_2:
477d59fb285SBard Liao 	case RT5668_PLL_TRACK_3:
478d59fb285SBard Liao 	case RT5668_PLL_TRACK_4:
479d59fb285SBard Liao 	case RT5668_PLL_TRACK_5:
480d59fb285SBard Liao 	case RT5668_PLL_TRACK_6:
481d59fb285SBard Liao 	case RT5668_PLL_TRACK_11:
482d59fb285SBard Liao 	case RT5668_SDW_REF_CLK:
483d59fb285SBard Liao 	case RT5668_DEPOP_1:
484d59fb285SBard Liao 	case RT5668_DEPOP_2:
485d59fb285SBard Liao 	case RT5668_HP_CHARGE_PUMP_1:
486d59fb285SBard Liao 	case RT5668_HP_CHARGE_PUMP_2:
487d59fb285SBard Liao 	case RT5668_MICBIAS_1:
488d59fb285SBard Liao 	case RT5668_MICBIAS_2:
489d59fb285SBard Liao 	case RT5668_PLL_TRACK_12:
490d59fb285SBard Liao 	case RT5668_PLL_TRACK_14:
491d59fb285SBard Liao 	case RT5668_PLL2_CTRL_1:
492d59fb285SBard Liao 	case RT5668_PLL2_CTRL_2:
493d59fb285SBard Liao 	case RT5668_PLL2_CTRL_3:
494d59fb285SBard Liao 	case RT5668_PLL2_CTRL_4:
495d59fb285SBard Liao 	case RT5668_RC_CLK_CTRL:
496d59fb285SBard Liao 	case RT5668_I2S_M_CLK_CTRL_1:
497d59fb285SBard Liao 	case RT5668_I2S2_F_DIV_CTRL_1:
498d59fb285SBard Liao 	case RT5668_I2S2_F_DIV_CTRL_2:
499d59fb285SBard Liao 	case RT5668_EQ_CTRL_1:
500d59fb285SBard Liao 	case RT5668_EQ_CTRL_2:
501d59fb285SBard Liao 	case RT5668_IRQ_CTRL_1:
502d59fb285SBard Liao 	case RT5668_IRQ_CTRL_2:
503d59fb285SBard Liao 	case RT5668_IRQ_CTRL_3:
504d59fb285SBard Liao 	case RT5668_IRQ_CTRL_4:
505d59fb285SBard Liao 	case RT5668_INT_ST_1:
506d59fb285SBard Liao 	case RT5668_GPIO_CTRL_1:
507d59fb285SBard Liao 	case RT5668_GPIO_CTRL_2:
508d59fb285SBard Liao 	case RT5668_GPIO_CTRL_3:
509d59fb285SBard Liao 	case RT5668_HP_AMP_DET_CTRL_1:
510d59fb285SBard Liao 	case RT5668_HP_AMP_DET_CTRL_2:
511d59fb285SBard Liao 	case RT5668_MID_HP_AMP_DET:
512d59fb285SBard Liao 	case RT5668_LOW_HP_AMP_DET:
513d59fb285SBard Liao 	case RT5668_DELAY_BUF_CTRL:
514d59fb285SBard Liao 	case RT5668_SV_ZCD_1:
515d59fb285SBard Liao 	case RT5668_SV_ZCD_2:
516d59fb285SBard Liao 	case RT5668_IL_CMD_1:
517d59fb285SBard Liao 	case RT5668_IL_CMD_2:
518d59fb285SBard Liao 	case RT5668_IL_CMD_3:
519d59fb285SBard Liao 	case RT5668_IL_CMD_4:
520d59fb285SBard Liao 	case RT5668_IL_CMD_5:
521d59fb285SBard Liao 	case RT5668_IL_CMD_6:
522d59fb285SBard Liao 	case RT5668_4BTN_IL_CMD_1:
523d59fb285SBard Liao 	case RT5668_4BTN_IL_CMD_2:
524d59fb285SBard Liao 	case RT5668_4BTN_IL_CMD_3:
525d59fb285SBard Liao 	case RT5668_4BTN_IL_CMD_4:
526d59fb285SBard Liao 	case RT5668_4BTN_IL_CMD_5:
527d59fb285SBard Liao 	case RT5668_4BTN_IL_CMD_6:
528d59fb285SBard Liao 	case RT5668_4BTN_IL_CMD_7:
529d59fb285SBard Liao 	case RT5668_ADC_STO1_HP_CTRL_1:
530d59fb285SBard Liao 	case RT5668_ADC_STO1_HP_CTRL_2:
531d59fb285SBard Liao 	case RT5668_AJD1_CTRL:
532d59fb285SBard Liao 	case RT5668_JD1_THD:
533d59fb285SBard Liao 	case RT5668_JD2_THD:
534d59fb285SBard Liao 	case RT5668_JD_CTRL_1:
535d59fb285SBard Liao 	case RT5668_DUMMY_1:
536d59fb285SBard Liao 	case RT5668_DUMMY_2:
537d59fb285SBard Liao 	case RT5668_DUMMY_3:
538d59fb285SBard Liao 	case RT5668_DAC_ADC_DIG_VOL1:
539d59fb285SBard Liao 	case RT5668_BIAS_CUR_CTRL_2:
540d59fb285SBard Liao 	case RT5668_BIAS_CUR_CTRL_3:
541d59fb285SBard Liao 	case RT5668_BIAS_CUR_CTRL_4:
542d59fb285SBard Liao 	case RT5668_BIAS_CUR_CTRL_5:
543d59fb285SBard Liao 	case RT5668_BIAS_CUR_CTRL_6:
544d59fb285SBard Liao 	case RT5668_BIAS_CUR_CTRL_7:
545d59fb285SBard Liao 	case RT5668_BIAS_CUR_CTRL_8:
546d59fb285SBard Liao 	case RT5668_BIAS_CUR_CTRL_9:
547d59fb285SBard Liao 	case RT5668_BIAS_CUR_CTRL_10:
548d59fb285SBard Liao 	case RT5668_VREF_REC_OP_FB_CAP_CTRL:
549d59fb285SBard Liao 	case RT5668_CHARGE_PUMP_1:
550d59fb285SBard Liao 	case RT5668_DIG_IN_CTRL_1:
551d59fb285SBard Liao 	case RT5668_PAD_DRIVING_CTRL:
552d59fb285SBard Liao 	case RT5668_SOFT_RAMP_DEPOP:
553d59fb285SBard Liao 	case RT5668_CHOP_DAC:
554d59fb285SBard Liao 	case RT5668_CHOP_ADC:
555d59fb285SBard Liao 	case RT5668_CALIB_ADC_CTRL:
556d59fb285SBard Liao 	case RT5668_VOL_TEST:
557d59fb285SBard Liao 	case RT5668_SPKVDD_DET_STA:
558d59fb285SBard Liao 	case RT5668_TEST_MODE_CTRL_1:
559d59fb285SBard Liao 	case RT5668_TEST_MODE_CTRL_2:
560d59fb285SBard Liao 	case RT5668_TEST_MODE_CTRL_3:
561d59fb285SBard Liao 	case RT5668_TEST_MODE_CTRL_4:
562d59fb285SBard Liao 	case RT5668_TEST_MODE_CTRL_5:
563d59fb285SBard Liao 	case RT5668_PLL1_INTERNAL:
564d59fb285SBard Liao 	case RT5668_PLL2_INTERNAL:
565d59fb285SBard Liao 	case RT5668_STO_NG2_CTRL_1:
566d59fb285SBard Liao 	case RT5668_STO_NG2_CTRL_2:
567d59fb285SBard Liao 	case RT5668_STO_NG2_CTRL_3:
568d59fb285SBard Liao 	case RT5668_STO_NG2_CTRL_4:
569d59fb285SBard Liao 	case RT5668_STO_NG2_CTRL_5:
570d59fb285SBard Liao 	case RT5668_STO_NG2_CTRL_6:
571d59fb285SBard Liao 	case RT5668_STO_NG2_CTRL_7:
572d59fb285SBard Liao 	case RT5668_STO_NG2_CTRL_8:
573d59fb285SBard Liao 	case RT5668_STO_NG2_CTRL_9:
574d59fb285SBard Liao 	case RT5668_STO_NG2_CTRL_10:
575d59fb285SBard Liao 	case RT5668_STO1_DAC_SIL_DET:
576d59fb285SBard Liao 	case RT5668_SIL_PSV_CTRL1:
577d59fb285SBard Liao 	case RT5668_SIL_PSV_CTRL2:
578d59fb285SBard Liao 	case RT5668_SIL_PSV_CTRL3:
579d59fb285SBard Liao 	case RT5668_SIL_PSV_CTRL4:
580d59fb285SBard Liao 	case RT5668_SIL_PSV_CTRL5:
581d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_01:
582d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_02:
583d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_03:
584d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_04:
585d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_05:
586d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_06:
587d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_07:
588d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_08:
589d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_09:
590d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_10:
591d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_11:
592d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_12:
593d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_13:
594d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_14:
595d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_15:
596d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_16:
597d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_17:
598d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_18:
599d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_19:
600d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_20:
601d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_21:
602d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_22:
603d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_23:
604d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_24:
605d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_25:
606d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_26:
607d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_27:
608d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_28:
609d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_29:
610d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_30:
611d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_31:
612d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_32:
613d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_33:
614d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_34:
615d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_35:
616d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_36:
617d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_37:
618d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_38:
619d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_39:
620d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_40:
621d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_41:
622d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_42:
623d59fb285SBard Liao 	case RT5668_HP_IMP_SENS_CTRL_43:
624d59fb285SBard Liao 	case RT5668_HP_LOGIC_CTRL_1:
625d59fb285SBard Liao 	case RT5668_HP_LOGIC_CTRL_2:
626d59fb285SBard Liao 	case RT5668_HP_LOGIC_CTRL_3:
627d59fb285SBard Liao 	case RT5668_HP_CALIB_CTRL_1:
628d59fb285SBard Liao 	case RT5668_HP_CALIB_CTRL_2:
629d59fb285SBard Liao 	case RT5668_HP_CALIB_CTRL_3:
630d59fb285SBard Liao 	case RT5668_HP_CALIB_CTRL_4:
631d59fb285SBard Liao 	case RT5668_HP_CALIB_CTRL_5:
632d59fb285SBard Liao 	case RT5668_HP_CALIB_CTRL_6:
633d59fb285SBard Liao 	case RT5668_HP_CALIB_CTRL_7:
634d59fb285SBard Liao 	case RT5668_HP_CALIB_CTRL_9:
635d59fb285SBard Liao 	case RT5668_HP_CALIB_CTRL_10:
636d59fb285SBard Liao 	case RT5668_HP_CALIB_CTRL_11:
637d59fb285SBard Liao 	case RT5668_HP_CALIB_STA_1:
638d59fb285SBard Liao 	case RT5668_HP_CALIB_STA_2:
639d59fb285SBard Liao 	case RT5668_HP_CALIB_STA_3:
640d59fb285SBard Liao 	case RT5668_HP_CALIB_STA_4:
641d59fb285SBard Liao 	case RT5668_HP_CALIB_STA_5:
642d59fb285SBard Liao 	case RT5668_HP_CALIB_STA_6:
643d59fb285SBard Liao 	case RT5668_HP_CALIB_STA_7:
644d59fb285SBard Liao 	case RT5668_HP_CALIB_STA_8:
645d59fb285SBard Liao 	case RT5668_HP_CALIB_STA_9:
646d59fb285SBard Liao 	case RT5668_HP_CALIB_STA_10:
647d59fb285SBard Liao 	case RT5668_HP_CALIB_STA_11:
648d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_1:
649d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_2:
650d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_3:
651d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_4:
652d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_5:
653d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_6:
654d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_7:
655d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_8:
656d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_9:
657d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_10:
658d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_11:
659d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_12:
660d59fb285SBard Liao 	case RT5668_SAR_IL_CMD_13:
661d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_1:
662d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_2:
663d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_3:
664d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_4:
665d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_5:
666d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_6:
667d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_7:
668d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_8:
669d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_9:
670d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_10:
671d59fb285SBard Liao 	case RT5668_EFUSE_CTRL_11:
672d59fb285SBard Liao 	case RT5668_JD_TOP_VC_VTRL:
673d59fb285SBard Liao 	case RT5668_DRC1_CTRL_0:
674d59fb285SBard Liao 	case RT5668_DRC1_CTRL_1:
675d59fb285SBard Liao 	case RT5668_DRC1_CTRL_2:
676d59fb285SBard Liao 	case RT5668_DRC1_CTRL_3:
677d59fb285SBard Liao 	case RT5668_DRC1_CTRL_4:
678d59fb285SBard Liao 	case RT5668_DRC1_CTRL_5:
679d59fb285SBard Liao 	case RT5668_DRC1_CTRL_6:
680d59fb285SBard Liao 	case RT5668_DRC1_HARD_LMT_CTRL_1:
681d59fb285SBard Liao 	case RT5668_DRC1_HARD_LMT_CTRL_2:
682d59fb285SBard Liao 	case RT5668_DRC1_PRIV_1:
683d59fb285SBard Liao 	case RT5668_DRC1_PRIV_2:
684d59fb285SBard Liao 	case RT5668_DRC1_PRIV_3:
685d59fb285SBard Liao 	case RT5668_DRC1_PRIV_4:
686d59fb285SBard Liao 	case RT5668_DRC1_PRIV_5:
687d59fb285SBard Liao 	case RT5668_DRC1_PRIV_6:
688d59fb285SBard Liao 	case RT5668_DRC1_PRIV_7:
689d59fb285SBard Liao 	case RT5668_DRC1_PRIV_8:
690d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL1:
691d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL2:
692d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL3:
693d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL4:
694d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL5:
695d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL6:
696d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL7:
697d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL8:
698d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL9:
699d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL10:
700d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL11:
701d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL12:
702d59fb285SBard Liao 	case RT5668_EQ_AUTO_RCV_CTRL13:
703d59fb285SBard Liao 	case RT5668_ADC_L_EQ_LPF1_A1:
704d59fb285SBard Liao 	case RT5668_R_EQ_LPF1_A1:
705d59fb285SBard Liao 	case RT5668_L_EQ_LPF1_H0:
706d59fb285SBard Liao 	case RT5668_R_EQ_LPF1_H0:
707d59fb285SBard Liao 	case RT5668_L_EQ_BPF1_A1:
708d59fb285SBard Liao 	case RT5668_R_EQ_BPF1_A1:
709d59fb285SBard Liao 	case RT5668_L_EQ_BPF1_A2:
710d59fb285SBard Liao 	case RT5668_R_EQ_BPF1_A2:
711d59fb285SBard Liao 	case RT5668_L_EQ_BPF1_H0:
712d59fb285SBard Liao 	case RT5668_R_EQ_BPF1_H0:
713d59fb285SBard Liao 	case RT5668_L_EQ_BPF2_A1:
714d59fb285SBard Liao 	case RT5668_R_EQ_BPF2_A1:
715d59fb285SBard Liao 	case RT5668_L_EQ_BPF2_A2:
716d59fb285SBard Liao 	case RT5668_R_EQ_BPF2_A2:
717d59fb285SBard Liao 	case RT5668_L_EQ_BPF2_H0:
718d59fb285SBard Liao 	case RT5668_R_EQ_BPF2_H0:
719d59fb285SBard Liao 	case RT5668_L_EQ_BPF3_A1:
720d59fb285SBard Liao 	case RT5668_R_EQ_BPF3_A1:
721d59fb285SBard Liao 	case RT5668_L_EQ_BPF3_A2:
722d59fb285SBard Liao 	case RT5668_R_EQ_BPF3_A2:
723d59fb285SBard Liao 	case RT5668_L_EQ_BPF3_H0:
724d59fb285SBard Liao 	case RT5668_R_EQ_BPF3_H0:
725d59fb285SBard Liao 	case RT5668_L_EQ_BPF4_A1:
726d59fb285SBard Liao 	case RT5668_R_EQ_BPF4_A1:
727d59fb285SBard Liao 	case RT5668_L_EQ_BPF4_A2:
728d59fb285SBard Liao 	case RT5668_R_EQ_BPF4_A2:
729d59fb285SBard Liao 	case RT5668_L_EQ_BPF4_H0:
730d59fb285SBard Liao 	case RT5668_R_EQ_BPF4_H0:
731d59fb285SBard Liao 	case RT5668_L_EQ_HPF1_A1:
732d59fb285SBard Liao 	case RT5668_R_EQ_HPF1_A1:
733d59fb285SBard Liao 	case RT5668_L_EQ_HPF1_H0:
734d59fb285SBard Liao 	case RT5668_R_EQ_HPF1_H0:
735d59fb285SBard Liao 	case RT5668_L_EQ_PRE_VOL:
736d59fb285SBard Liao 	case RT5668_R_EQ_PRE_VOL:
737d59fb285SBard Liao 	case RT5668_L_EQ_POST_VOL:
738d59fb285SBard Liao 	case RT5668_R_EQ_POST_VOL:
739d59fb285SBard Liao 	case RT5668_I2C_MODE:
740d59fb285SBard Liao 		return true;
741d59fb285SBard Liao 	default:
742d59fb285SBard Liao 		return false;
743d59fb285SBard Liao 	}
744d59fb285SBard Liao }
745d59fb285SBard Liao 
746d59fb285SBard Liao static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -2250, 150, 0);
747d59fb285SBard Liao static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
748d59fb285SBard Liao static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
749d59fb285SBard Liao static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
750d59fb285SBard Liao 
751d59fb285SBard Liao /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
752d59fb285SBard Liao static const DECLARE_TLV_DB_RANGE(bst_tlv,
753d59fb285SBard Liao 	0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
754d59fb285SBard Liao 	1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
755d59fb285SBard Liao 	2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
756d59fb285SBard Liao 	3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
757d59fb285SBard Liao 	6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
758d59fb285SBard Liao 	7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
759d59fb285SBard Liao 	8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0)
760d59fb285SBard Liao );
761d59fb285SBard Liao 
762d59fb285SBard Liao /* Interface data select */
763d59fb285SBard Liao static const char * const rt5668_data_select[] = {
764d59fb285SBard Liao 	"L/R", "R/L", "L/L", "R/R"
765d59fb285SBard Liao };
766d59fb285SBard Liao 
767d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(rt5668_if2_adc_enum,
768d59fb285SBard Liao 	RT5668_DIG_INF2_DATA, RT5668_IF2_ADC_SEL_SFT, rt5668_data_select);
769d59fb285SBard Liao 
770d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(rt5668_if1_01_adc_enum,
771d59fb285SBard Liao 	RT5668_TDM_ADDA_CTRL_1, RT5668_IF1_ADC1_SEL_SFT, rt5668_data_select);
772d59fb285SBard Liao 
773d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(rt5668_if1_23_adc_enum,
774d59fb285SBard Liao 	RT5668_TDM_ADDA_CTRL_1, RT5668_IF1_ADC2_SEL_SFT, rt5668_data_select);
775d59fb285SBard Liao 
776d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(rt5668_if1_45_adc_enum,
777d59fb285SBard Liao 	RT5668_TDM_ADDA_CTRL_1, RT5668_IF1_ADC3_SEL_SFT, rt5668_data_select);
778d59fb285SBard Liao 
779d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(rt5668_if1_67_adc_enum,
780d59fb285SBard Liao 	RT5668_TDM_ADDA_CTRL_1, RT5668_IF1_ADC4_SEL_SFT, rt5668_data_select);
781d59fb285SBard Liao 
782d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_if2_adc_swap_mux =
783d59fb285SBard Liao 	SOC_DAPM_ENUM("IF2 ADC Swap Mux", rt5668_if2_adc_enum);
784d59fb285SBard Liao 
785d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_if1_01_adc_swap_mux =
786d59fb285SBard Liao 	SOC_DAPM_ENUM("IF1 01 ADC Swap Mux", rt5668_if1_01_adc_enum);
787d59fb285SBard Liao 
788d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_if1_23_adc_swap_mux =
789d59fb285SBard Liao 	SOC_DAPM_ENUM("IF1 23 ADC Swap Mux", rt5668_if1_23_adc_enum);
790d59fb285SBard Liao 
791d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_if1_45_adc_swap_mux =
792d59fb285SBard Liao 	SOC_DAPM_ENUM("IF1 45 ADC Swap Mux", rt5668_if1_45_adc_enum);
793d59fb285SBard Liao 
794d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_if1_67_adc_swap_mux =
795d59fb285SBard Liao 	SOC_DAPM_ENUM("IF1 67 ADC Swap Mux", rt5668_if1_67_adc_enum);
796d59fb285SBard Liao 
rt5668_reset(struct regmap * regmap)797d59fb285SBard Liao static void rt5668_reset(struct regmap *regmap)
798d59fb285SBard Liao {
799d59fb285SBard Liao 	regmap_write(regmap, RT5668_RESET, 0);
800d59fb285SBard Liao 	regmap_write(regmap, RT5668_I2C_MODE, 1);
801d59fb285SBard Liao }
802d59fb285SBard Liao /**
803d59fb285SBard Liao  * rt5668_sel_asrc_clk_src - select ASRC clock source for a set of filters
804d59fb285SBard Liao  * @component: SoC audio component device.
805d59fb285SBard Liao  * @filter_mask: mask of filters.
806d59fb285SBard Liao  * @clk_src: clock source
807d59fb285SBard Liao  *
808d59fb285SBard Liao  * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5668 can
809d59fb285SBard Liao  * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
810d59fb285SBard Liao  * support special i2s clock format such as Intel's 100fs(100 * sampling rate).
811d59fb285SBard Liao  * ASRC function will track i2s clock and generate a corresponding system clock
812d59fb285SBard Liao  * for codec. This function provides an API to select the clock source for a
813d59fb285SBard Liao  * set of filters specified by the mask. And the component driver will turn on
814d59fb285SBard Liao  * ASRC for these filters if ASRC is selected as their clock source.
815d59fb285SBard Liao  */
rt5668_sel_asrc_clk_src(struct snd_soc_component * component,unsigned int filter_mask,unsigned int clk_src)816d59fb285SBard Liao int rt5668_sel_asrc_clk_src(struct snd_soc_component *component,
817d59fb285SBard Liao 		unsigned int filter_mask, unsigned int clk_src)
818d59fb285SBard Liao {
819d59fb285SBard Liao 
820d59fb285SBard Liao 	switch (clk_src) {
821d59fb285SBard Liao 	case RT5668_CLK_SEL_SYS:
822d59fb285SBard Liao 	case RT5668_CLK_SEL_I2S1_ASRC:
823d59fb285SBard Liao 	case RT5668_CLK_SEL_I2S2_ASRC:
824d59fb285SBard Liao 		break;
825d59fb285SBard Liao 
826d59fb285SBard Liao 	default:
827d59fb285SBard Liao 		return -EINVAL;
828d59fb285SBard Liao 	}
829d59fb285SBard Liao 
830d59fb285SBard Liao 	if (filter_mask & RT5668_DA_STEREO1_FILTER) {
831d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_PLL_TRACK_2,
832d59fb285SBard Liao 			RT5668_FILTER_CLK_SEL_MASK,
833d59fb285SBard Liao 			clk_src << RT5668_FILTER_CLK_SEL_SFT);
834d59fb285SBard Liao 	}
835d59fb285SBard Liao 
836d59fb285SBard Liao 	if (filter_mask & RT5668_AD_STEREO1_FILTER) {
837d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_PLL_TRACK_3,
838d59fb285SBard Liao 			RT5668_FILTER_CLK_SEL_MASK,
839d59fb285SBard Liao 			clk_src << RT5668_FILTER_CLK_SEL_SFT);
840d59fb285SBard Liao 	}
841d59fb285SBard Liao 
842d59fb285SBard Liao 	return 0;
843d59fb285SBard Liao }
844d59fb285SBard Liao EXPORT_SYMBOL_GPL(rt5668_sel_asrc_clk_src);
845d59fb285SBard Liao 
rt5668_button_detect(struct snd_soc_component * component)846d59fb285SBard Liao static int rt5668_button_detect(struct snd_soc_component *component)
847d59fb285SBard Liao {
848d59fb285SBard Liao 	int btn_type, val;
849d59fb285SBard Liao 
850467a2553SKuninori Morimoto 	val = snd_soc_component_read(component, RT5668_4BTN_IL_CMD_1);
851d59fb285SBard Liao 	btn_type = val & 0xfff0;
852d59fb285SBard Liao 	snd_soc_component_write(component, RT5668_4BTN_IL_CMD_1, val);
853d59fb285SBard Liao 	pr_debug("%s btn_type=%x\n", __func__, btn_type);
854d59fb285SBard Liao 
855d59fb285SBard Liao 	return btn_type;
856d59fb285SBard Liao }
857d59fb285SBard Liao 
rt5668_enable_push_button_irq(struct snd_soc_component * component,bool enable)858d59fb285SBard Liao static void rt5668_enable_push_button_irq(struct snd_soc_component *component,
859d59fb285SBard Liao 		bool enable)
860d59fb285SBard Liao {
861d59fb285SBard Liao 	if (enable) {
862d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_SAR_IL_CMD_1,
863d59fb285SBard Liao 			RT5668_SAR_BUTT_DET_MASK, RT5668_SAR_BUTT_DET_EN);
864d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_SAR_IL_CMD_13,
865d59fb285SBard Liao 			RT5668_SAR_SOUR_MASK, RT5668_SAR_SOUR_BTN);
866d59fb285SBard Liao 		snd_soc_component_write(component, RT5668_IL_CMD_1, 0x0040);
867d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_4BTN_IL_CMD_2,
868d59fb285SBard Liao 			RT5668_4BTN_IL_MASK | RT5668_4BTN_IL_RST_MASK,
869d59fb285SBard Liao 			RT5668_4BTN_IL_EN | RT5668_4BTN_IL_NOR);
870d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_IRQ_CTRL_3,
871d59fb285SBard Liao 			RT5668_IL_IRQ_MASK, RT5668_IL_IRQ_EN);
872d59fb285SBard Liao 	} else {
873d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_IRQ_CTRL_3,
874d59fb285SBard Liao 			RT5668_IL_IRQ_MASK, RT5668_IL_IRQ_DIS);
875d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_SAR_IL_CMD_1,
876d59fb285SBard Liao 			RT5668_SAR_BUTT_DET_MASK, RT5668_SAR_BUTT_DET_DIS);
877d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_4BTN_IL_CMD_2,
878d59fb285SBard Liao 			RT5668_4BTN_IL_MASK, RT5668_4BTN_IL_DIS);
879d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_4BTN_IL_CMD_2,
880d59fb285SBard Liao 			RT5668_4BTN_IL_RST_MASK, RT5668_4BTN_IL_RST);
881d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_SAR_IL_CMD_13,
882d59fb285SBard Liao 			RT5668_SAR_SOUR_MASK, RT5668_SAR_SOUR_TYPE);
883d59fb285SBard Liao 	}
884d59fb285SBard Liao }
885d59fb285SBard Liao 
886d59fb285SBard Liao /**
887d59fb285SBard Liao  * rt5668_headset_detect - Detect headset.
888d59fb285SBard Liao  * @component: SoC audio component device.
889d59fb285SBard Liao  * @jack_insert: Jack insert or not.
890d59fb285SBard Liao  *
891d59fb285SBard Liao  * Detect whether is headset or not when jack inserted.
892d59fb285SBard Liao  *
893d59fb285SBard Liao  * Returns detect status.
894d59fb285SBard Liao  */
rt5668_headset_detect(struct snd_soc_component * component,int jack_insert)895d59fb285SBard Liao static int rt5668_headset_detect(struct snd_soc_component *component,
896d59fb285SBard Liao 		int jack_insert)
897d59fb285SBard Liao {
898d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
899d59fb285SBard Liao 	struct snd_soc_dapm_context *dapm =
900d59fb285SBard Liao 		snd_soc_component_get_dapm(component);
901d59fb285SBard Liao 	unsigned int val, count;
902d59fb285SBard Liao 
903d59fb285SBard Liao 	if (jack_insert) {
904d59fb285SBard Liao 		snd_soc_dapm_force_enable_pin(dapm, "CBJ Power");
905d59fb285SBard Liao 		snd_soc_dapm_sync(dapm);
906d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_CBJ_CTRL_1,
907d59fb285SBard Liao 			RT5668_TRIG_JD_MASK, RT5668_TRIG_JD_HIGH);
908d59fb285SBard Liao 
909d59fb285SBard Liao 		count = 0;
910467a2553SKuninori Morimoto 		val = snd_soc_component_read(component, RT5668_CBJ_CTRL_2)
911d59fb285SBard Liao 			& RT5668_JACK_TYPE_MASK;
912d59fb285SBard Liao 		while (val == 0 && count < 50) {
913d59fb285SBard Liao 			usleep_range(10000, 15000);
914467a2553SKuninori Morimoto 			val = snd_soc_component_read(component,
915d59fb285SBard Liao 				RT5668_CBJ_CTRL_2) & RT5668_JACK_TYPE_MASK;
916d59fb285SBard Liao 			count++;
917d59fb285SBard Liao 		}
918d59fb285SBard Liao 
919d59fb285SBard Liao 		switch (val) {
920d59fb285SBard Liao 		case 0x1:
921d59fb285SBard Liao 		case 0x2:
922d59fb285SBard Liao 			rt5668->jack_type = SND_JACK_HEADSET;
923d59fb285SBard Liao 			rt5668_enable_push_button_irq(component, true);
924d59fb285SBard Liao 			break;
925d59fb285SBard Liao 		default:
926d59fb285SBard Liao 			rt5668->jack_type = SND_JACK_HEADPHONE;
927d59fb285SBard Liao 		}
928d59fb285SBard Liao 
929d59fb285SBard Liao 	} else {
930d59fb285SBard Liao 		rt5668_enable_push_button_irq(component, false);
931d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_CBJ_CTRL_1,
932d59fb285SBard Liao 			RT5668_TRIG_JD_MASK, RT5668_TRIG_JD_LOW);
933d59fb285SBard Liao 		snd_soc_dapm_disable_pin(dapm, "CBJ Power");
934d59fb285SBard Liao 		snd_soc_dapm_sync(dapm);
935d59fb285SBard Liao 
936d59fb285SBard Liao 		rt5668->jack_type = 0;
937d59fb285SBard Liao 	}
938d59fb285SBard Liao 
939d59fb285SBard Liao 	dev_dbg(component->dev, "jack_type = %d\n", rt5668->jack_type);
940d59fb285SBard Liao 	return rt5668->jack_type;
941d59fb285SBard Liao }
942d59fb285SBard Liao 
rt5668_irq(int irq,void * data)943d59fb285SBard Liao static irqreturn_t rt5668_irq(int irq, void *data)
944d59fb285SBard Liao {
945d59fb285SBard Liao 	struct rt5668_priv *rt5668 = data;
946d59fb285SBard Liao 
947d59fb285SBard Liao 	mod_delayed_work(system_power_efficient_wq,
948d59fb285SBard Liao 			&rt5668->jack_detect_work, msecs_to_jiffies(250));
949d59fb285SBard Liao 
950d59fb285SBard Liao 	return IRQ_HANDLED;
951d59fb285SBard Liao }
952d59fb285SBard Liao 
rt5668_jd_check_handler(struct work_struct * work)953d59fb285SBard Liao static void rt5668_jd_check_handler(struct work_struct *work)
954d59fb285SBard Liao {
955d59fb285SBard Liao 	struct rt5668_priv *rt5668 = container_of(work, struct rt5668_priv,
956d59fb285SBard Liao 		jd_check_work.work);
957d59fb285SBard Liao 
958467a2553SKuninori Morimoto 	if (snd_soc_component_read(rt5668->component, RT5668_AJD1_CTRL)
959d59fb285SBard Liao 		& RT5668_JDH_RS_MASK) {
960d59fb285SBard Liao 		/* jack out */
961d59fb285SBard Liao 		rt5668->jack_type = rt5668_headset_detect(rt5668->component, 0);
962d59fb285SBard Liao 
963d59fb285SBard Liao 		snd_soc_jack_report(rt5668->hs_jack, rt5668->jack_type,
964d59fb285SBard Liao 				SND_JACK_HEADSET |
965d59fb285SBard Liao 				SND_JACK_BTN_0 | SND_JACK_BTN_1 |
966d59fb285SBard Liao 				SND_JACK_BTN_2 | SND_JACK_BTN_3);
967d59fb285SBard Liao 	} else {
968d59fb285SBard Liao 		schedule_delayed_work(&rt5668->jd_check_work, 500);
969d59fb285SBard Liao 	}
970d59fb285SBard Liao }
971d59fb285SBard Liao 
rt5668_set_jack_detect(struct snd_soc_component * component,struct snd_soc_jack * hs_jack,void * data)972d59fb285SBard Liao static int rt5668_set_jack_detect(struct snd_soc_component *component,
973d59fb285SBard Liao 	struct snd_soc_jack *hs_jack, void *data)
974d59fb285SBard Liao {
975d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
976d59fb285SBard Liao 
977d59fb285SBard Liao 	switch (rt5668->pdata.jd_src) {
978d59fb285SBard Liao 	case RT5668_JD1:
979d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_CBJ_CTRL_2,
980d59fb285SBard Liao 			RT5668_EXT_JD_SRC, RT5668_EXT_JD_SRC_MANUAL);
981d59fb285SBard Liao 		snd_soc_component_write(component, RT5668_CBJ_CTRL_1, 0xd002);
982d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_CBJ_CTRL_3,
983d59fb285SBard Liao 			RT5668_CBJ_IN_BUF_EN, RT5668_CBJ_IN_BUF_EN);
984d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_SAR_IL_CMD_1,
985d59fb285SBard Liao 			RT5668_SAR_POW_MASK, RT5668_SAR_POW_EN);
986d59fb285SBard Liao 		regmap_update_bits(rt5668->regmap, RT5668_GPIO_CTRL_1,
987d59fb285SBard Liao 			RT5668_GP1_PIN_MASK, RT5668_GP1_PIN_IRQ);
988d59fb285SBard Liao 		regmap_update_bits(rt5668->regmap, RT5668_RC_CLK_CTRL,
989d59fb285SBard Liao 				RT5668_POW_IRQ | RT5668_POW_JDH |
990d59fb285SBard Liao 				RT5668_POW_ANA, RT5668_POW_IRQ |
991d59fb285SBard Liao 				RT5668_POW_JDH | RT5668_POW_ANA);
992d59fb285SBard Liao 		regmap_update_bits(rt5668->regmap, RT5668_PWR_ANLG_2,
993d59fb285SBard Liao 			RT5668_PWR_JDH | RT5668_PWR_JDL,
994d59fb285SBard Liao 			RT5668_PWR_JDH | RT5668_PWR_JDL);
995d59fb285SBard Liao 		regmap_update_bits(rt5668->regmap, RT5668_IRQ_CTRL_2,
996d59fb285SBard Liao 			RT5668_JD1_EN_MASK | RT5668_JD1_POL_MASK,
997d59fb285SBard Liao 			RT5668_JD1_EN | RT5668_JD1_POL_NOR);
998d59fb285SBard Liao 		mod_delayed_work(system_power_efficient_wq,
999d59fb285SBard Liao 			   &rt5668->jack_detect_work, msecs_to_jiffies(250));
1000d59fb285SBard Liao 		break;
1001d59fb285SBard Liao 
1002d59fb285SBard Liao 	case RT5668_JD_NULL:
1003d59fb285SBard Liao 		regmap_update_bits(rt5668->regmap, RT5668_IRQ_CTRL_2,
1004d59fb285SBard Liao 			RT5668_JD1_EN_MASK, RT5668_JD1_DIS);
1005d59fb285SBard Liao 		regmap_update_bits(rt5668->regmap, RT5668_RC_CLK_CTRL,
1006d59fb285SBard Liao 				RT5668_POW_JDH | RT5668_POW_JDL, 0);
1007d59fb285SBard Liao 		break;
1008d59fb285SBard Liao 
1009d59fb285SBard Liao 	default:
1010d59fb285SBard Liao 		dev_warn(component->dev, "Wrong JD source\n");
1011d59fb285SBard Liao 		break;
1012d59fb285SBard Liao 	}
1013d59fb285SBard Liao 
1014d59fb285SBard Liao 	rt5668->hs_jack = hs_jack;
1015d59fb285SBard Liao 
1016d59fb285SBard Liao 	return 0;
1017d59fb285SBard Liao }
1018d59fb285SBard Liao 
rt5668_jack_detect_handler(struct work_struct * work)1019d59fb285SBard Liao static void rt5668_jack_detect_handler(struct work_struct *work)
1020d59fb285SBard Liao {
1021d59fb285SBard Liao 	struct rt5668_priv *rt5668 =
1022d59fb285SBard Liao 		container_of(work, struct rt5668_priv, jack_detect_work.work);
1023d59fb285SBard Liao 	int val, btn_type;
1024d59fb285SBard Liao 
10258ec35236SKuninori Morimoto 	if (!rt5668->component ||
10268ec35236SKuninori Morimoto 	    !snd_soc_card_is_instantiated(rt5668->component->card)) {
1027a6d78661SKai Vehmanen 		/* card not yet ready, try later */
1028a6d78661SKai Vehmanen 		mod_delayed_work(system_power_efficient_wq,
1029a6d78661SKai Vehmanen 				 &rt5668->jack_detect_work, msecs_to_jiffies(15));
1030a6d78661SKai Vehmanen 		return;
1031a6d78661SKai Vehmanen 	}
1032d59fb285SBard Liao 
1033d59fb285SBard Liao 	mutex_lock(&rt5668->calibrate_mutex);
1034d59fb285SBard Liao 
1035467a2553SKuninori Morimoto 	val = snd_soc_component_read(rt5668->component, RT5668_AJD1_CTRL)
1036d59fb285SBard Liao 		& RT5668_JDH_RS_MASK;
1037d59fb285SBard Liao 	if (!val) {
1038d59fb285SBard Liao 		/* jack in */
1039d59fb285SBard Liao 		if (rt5668->jack_type == 0) {
1040d59fb285SBard Liao 			/* jack was out, report jack type */
1041d59fb285SBard Liao 			rt5668->jack_type =
1042d59fb285SBard Liao 				rt5668_headset_detect(rt5668->component, 1);
1043d59fb285SBard Liao 		} else {
1044d59fb285SBard Liao 			/* jack is already in, report button event */
1045d59fb285SBard Liao 			rt5668->jack_type = SND_JACK_HEADSET;
1046d59fb285SBard Liao 			btn_type = rt5668_button_detect(rt5668->component);
1047d59fb285SBard Liao 			/**
1048d59fb285SBard Liao 			 * rt5668 can report three kinds of button behavior,
1049d59fb285SBard Liao 			 * one click, double click and hold. However,
1050d59fb285SBard Liao 			 * currently we will report button pressed/released
1051d59fb285SBard Liao 			 * event. So all the three button behaviors are
1052d59fb285SBard Liao 			 * treated as button pressed.
1053d59fb285SBard Liao 			 */
1054d59fb285SBard Liao 			switch (btn_type) {
1055d59fb285SBard Liao 			case 0x8000:
1056d59fb285SBard Liao 			case 0x4000:
1057d59fb285SBard Liao 			case 0x2000:
1058d59fb285SBard Liao 				rt5668->jack_type |= SND_JACK_BTN_0;
1059d59fb285SBard Liao 				break;
1060d59fb285SBard Liao 			case 0x1000:
1061d59fb285SBard Liao 			case 0x0800:
1062d59fb285SBard Liao 			case 0x0400:
1063d59fb285SBard Liao 				rt5668->jack_type |= SND_JACK_BTN_1;
1064d59fb285SBard Liao 				break;
1065d59fb285SBard Liao 			case 0x0200:
1066d59fb285SBard Liao 			case 0x0100:
1067d59fb285SBard Liao 			case 0x0080:
1068d59fb285SBard Liao 				rt5668->jack_type |= SND_JACK_BTN_2;
1069d59fb285SBard Liao 				break;
1070d59fb285SBard Liao 			case 0x0040:
1071d59fb285SBard Liao 			case 0x0020:
1072d59fb285SBard Liao 			case 0x0010:
1073d59fb285SBard Liao 				rt5668->jack_type |= SND_JACK_BTN_3;
1074d59fb285SBard Liao 				break;
1075d59fb285SBard Liao 			case 0x0000: /* unpressed */
1076d59fb285SBard Liao 				break;
1077d59fb285SBard Liao 			default:
1078d59fb285SBard Liao 				btn_type = 0;
1079d59fb285SBard Liao 				dev_err(rt5668->component->dev,
1080d59fb285SBard Liao 					"Unexpected button code 0x%04x\n",
1081d59fb285SBard Liao 					btn_type);
1082d59fb285SBard Liao 				break;
1083d59fb285SBard Liao 			}
1084d59fb285SBard Liao 		}
1085d59fb285SBard Liao 	} else {
1086d59fb285SBard Liao 		/* jack out */
1087d59fb285SBard Liao 		rt5668->jack_type = rt5668_headset_detect(rt5668->component, 0);
1088d59fb285SBard Liao 	}
1089d59fb285SBard Liao 
1090d59fb285SBard Liao 	snd_soc_jack_report(rt5668->hs_jack, rt5668->jack_type,
1091d59fb285SBard Liao 			SND_JACK_HEADSET |
1092d59fb285SBard Liao 			    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1093d59fb285SBard Liao 			    SND_JACK_BTN_2 | SND_JACK_BTN_3);
1094d59fb285SBard Liao 
1095d59fb285SBard Liao 	if (rt5668->jack_type & (SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1096d59fb285SBard Liao 		SND_JACK_BTN_2 | SND_JACK_BTN_3))
1097d59fb285SBard Liao 		schedule_delayed_work(&rt5668->jd_check_work, 0);
1098d59fb285SBard Liao 	else
1099d59fb285SBard Liao 		cancel_delayed_work_sync(&rt5668->jd_check_work);
1100d59fb285SBard Liao 
1101d59fb285SBard Liao 	mutex_unlock(&rt5668->calibrate_mutex);
1102d59fb285SBard Liao }
1103d59fb285SBard Liao 
1104d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_snd_controls[] = {
1105d59fb285SBard Liao 	/* Headphone Output Volume */
1106d59fb285SBard Liao 	SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5668_HPL_GAIN,
1107d59fb285SBard Liao 		RT5668_HPR_GAIN, RT5668_G_HP_SFT, 15, 1, hp_vol_tlv),
1108d59fb285SBard Liao 
1109d59fb285SBard Liao 	/* DAC Digital Volume */
1110d59fb285SBard Liao 	SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5668_DAC1_DIG_VOL,
1111d59fb285SBard Liao 		RT5668_L_VOL_SFT, RT5668_R_VOL_SFT, 175, 0, dac_vol_tlv),
1112d59fb285SBard Liao 
1113d59fb285SBard Liao 	/* IN Boost Volume */
1114d59fb285SBard Liao 	SOC_SINGLE_TLV("CBJ Boost Volume", RT5668_CBJ_BST_CTRL,
1115d59fb285SBard Liao 		RT5668_BST_CBJ_SFT, 8, 0, bst_tlv),
1116d59fb285SBard Liao 
1117d59fb285SBard Liao 	/* ADC Digital Volume Control */
1118d59fb285SBard Liao 	SOC_DOUBLE("STO1 ADC Capture Switch", RT5668_STO1_ADC_DIG_VOL,
1119d59fb285SBard Liao 		RT5668_L_MUTE_SFT, RT5668_R_MUTE_SFT, 1, 1),
1120d59fb285SBard Liao 	SOC_DOUBLE_TLV("STO1 ADC Capture Volume", RT5668_STO1_ADC_DIG_VOL,
1121d59fb285SBard Liao 		RT5668_L_VOL_SFT, RT5668_R_VOL_SFT, 127, 0, adc_vol_tlv),
1122d59fb285SBard Liao 
1123d59fb285SBard Liao 	/* ADC Boost Volume Control */
1124d59fb285SBard Liao 	SOC_DOUBLE_TLV("STO1 ADC Boost Gain Volume", RT5668_STO1_ADC_BOOST,
1125d59fb285SBard Liao 		RT5668_STO1_ADC_L_BST_SFT, RT5668_STO1_ADC_R_BST_SFT,
1126d59fb285SBard Liao 		3, 0, adc_bst_tlv),
1127d59fb285SBard Liao };
1128d59fb285SBard Liao 
1129d59fb285SBard Liao 
rt5668_div_sel(struct rt5668_priv * rt5668,int target,const int div[],int size)1130d59fb285SBard Liao static int rt5668_div_sel(struct rt5668_priv *rt5668,
1131d59fb285SBard Liao 			  int target, const int div[], int size)
1132d59fb285SBard Liao {
1133d59fb285SBard Liao 	int i;
1134d59fb285SBard Liao 
1135d59fb285SBard Liao 	if (rt5668->sysclk < target) {
1136d59fb285SBard Liao 		pr_err("sysclk rate %d is too low\n",
1137d59fb285SBard Liao 			rt5668->sysclk);
1138d59fb285SBard Liao 		return 0;
1139d59fb285SBard Liao 	}
1140d59fb285SBard Liao 
1141d59fb285SBard Liao 	for (i = 0; i < size - 1; i++) {
1142d59fb285SBard Liao 		pr_info("div[%d]=%d\n", i, div[i]);
1143d59fb285SBard Liao 		if (target * div[i] == rt5668->sysclk)
1144d59fb285SBard Liao 			return i;
1145d59fb285SBard Liao 		if (target * div[i + 1] > rt5668->sysclk) {
1146d59fb285SBard Liao 			pr_err("can't find div for sysclk %d\n",
1147d59fb285SBard Liao 				rt5668->sysclk);
1148d59fb285SBard Liao 			return i;
1149d59fb285SBard Liao 		}
1150d59fb285SBard Liao 	}
1151d59fb285SBard Liao 
1152d59fb285SBard Liao 	if (target * div[i] < rt5668->sysclk)
1153d59fb285SBard Liao 		pr_err("sysclk rate %d is too high\n",
1154d59fb285SBard Liao 			rt5668->sysclk);
1155d59fb285SBard Liao 
1156d59fb285SBard Liao 	return size - 1;
1157d59fb285SBard Liao 
1158d59fb285SBard Liao }
1159d59fb285SBard Liao 
1160d59fb285SBard Liao /**
1161d59fb285SBard Liao  * set_dmic_clk - Set parameter of dmic.
1162d59fb285SBard Liao  *
1163d59fb285SBard Liao  * @w: DAPM widget.
1164d59fb285SBard Liao  * @kcontrol: The kcontrol of this widget.
1165d59fb285SBard Liao  * @event: Event id.
1166d59fb285SBard Liao  *
1167d59fb285SBard Liao  * Choose dmic clock between 1MHz and 3MHz.
1168d59fb285SBard Liao  * It is better for clock to approximate 3MHz.
1169d59fb285SBard Liao  */
set_dmic_clk(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1170d59fb285SBard Liao static int set_dmic_clk(struct snd_soc_dapm_widget *w,
1171d59fb285SBard Liao 	struct snd_kcontrol *kcontrol, int event)
1172d59fb285SBard Liao {
1173d59fb285SBard Liao 	struct snd_soc_component *component =
1174d59fb285SBard Liao 		snd_soc_dapm_to_component(w->dapm);
1175d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
11766fa54456SPierre-Louis Bossart 	int idx;
1177d59fb285SBard Liao 	static const int div[] = {2, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128};
1178d59fb285SBard Liao 
1179d59fb285SBard Liao 	idx = rt5668_div_sel(rt5668, 1500000, div, ARRAY_SIZE(div));
1180d59fb285SBard Liao 
1181d59fb285SBard Liao 	snd_soc_component_update_bits(component, RT5668_DMIC_CTRL_1,
1182d59fb285SBard Liao 		RT5668_DMIC_CLK_MASK, idx << RT5668_DMIC_CLK_SFT);
1183d59fb285SBard Liao 
1184d59fb285SBard Liao 	return 0;
1185d59fb285SBard Liao }
1186d59fb285SBard Liao 
set_filter_clk(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1187d59fb285SBard Liao static int set_filter_clk(struct snd_soc_dapm_widget *w,
1188d59fb285SBard Liao 	struct snd_kcontrol *kcontrol, int event)
1189d59fb285SBard Liao {
1190d59fb285SBard Liao 	struct snd_soc_component *component =
1191d59fb285SBard Liao 		snd_soc_dapm_to_component(w->dapm);
1192d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
11936fa54456SPierre-Louis Bossart 	int ref, val, reg, idx;
1194d59fb285SBard Liao 	static const int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48};
1195d59fb285SBard Liao 
1196467a2553SKuninori Morimoto 	val = snd_soc_component_read(component, RT5668_GPIO_CTRL_1) &
1197d59fb285SBard Liao 		RT5668_GP4_PIN_MASK;
1198d59fb285SBard Liao 	if (w->shift == RT5668_PWR_ADC_S1F_BIT &&
1199d59fb285SBard Liao 		val == RT5668_GP4_PIN_ADCDAT2)
1200d59fb285SBard Liao 		ref = 256 * rt5668->lrck[RT5668_AIF2];
1201d59fb285SBard Liao 	else
1202d59fb285SBard Liao 		ref = 256 * rt5668->lrck[RT5668_AIF1];
1203d59fb285SBard Liao 
1204d59fb285SBard Liao 	idx = rt5668_div_sel(rt5668, ref, div, ARRAY_SIZE(div));
1205d59fb285SBard Liao 
1206d59fb285SBard Liao 	if (w->shift == RT5668_PWR_ADC_S1F_BIT)
1207d59fb285SBard Liao 		reg = RT5668_PLL_TRACK_3;
1208d59fb285SBard Liao 	else
1209d59fb285SBard Liao 		reg = RT5668_PLL_TRACK_2;
1210d59fb285SBard Liao 
1211d59fb285SBard Liao 	snd_soc_component_update_bits(component, reg,
1212d59fb285SBard Liao 		RT5668_FILTER_CLK_SEL_MASK, idx << RT5668_FILTER_CLK_SEL_SFT);
1213d59fb285SBard Liao 
1214d59fb285SBard Liao 	return 0;
1215d59fb285SBard Liao }
1216d59fb285SBard Liao 
is_sys_clk_from_pll1(struct snd_soc_dapm_widget * w,struct snd_soc_dapm_widget * sink)1217d59fb285SBard Liao static int is_sys_clk_from_pll1(struct snd_soc_dapm_widget *w,
1218d59fb285SBard Liao 			 struct snd_soc_dapm_widget *sink)
1219d59fb285SBard Liao {
1220d59fb285SBard Liao 	unsigned int val;
1221d59fb285SBard Liao 	struct snd_soc_component *component =
1222d59fb285SBard Liao 		snd_soc_dapm_to_component(w->dapm);
1223d59fb285SBard Liao 
1224467a2553SKuninori Morimoto 	val = snd_soc_component_read(component, RT5668_GLB_CLK);
1225d59fb285SBard Liao 	val &= RT5668_SCLK_SRC_MASK;
1226d59fb285SBard Liao 	if (val == RT5668_SCLK_SRC_PLL1)
1227d59fb285SBard Liao 		return 1;
1228d59fb285SBard Liao 	else
1229d59fb285SBard Liao 		return 0;
1230d59fb285SBard Liao }
1231d59fb285SBard Liao 
is_using_asrc(struct snd_soc_dapm_widget * w,struct snd_soc_dapm_widget * sink)1232d59fb285SBard Liao static int is_using_asrc(struct snd_soc_dapm_widget *w,
1233d59fb285SBard Liao 			 struct snd_soc_dapm_widget *sink)
1234d59fb285SBard Liao {
1235d59fb285SBard Liao 	unsigned int reg, shift, val;
1236d59fb285SBard Liao 	struct snd_soc_component *component =
1237d59fb285SBard Liao 		snd_soc_dapm_to_component(w->dapm);
1238d59fb285SBard Liao 
1239d59fb285SBard Liao 	switch (w->shift) {
1240d59fb285SBard Liao 	case RT5668_ADC_STO1_ASRC_SFT:
1241d59fb285SBard Liao 		reg = RT5668_PLL_TRACK_3;
1242d59fb285SBard Liao 		shift = RT5668_FILTER_CLK_SEL_SFT;
1243d59fb285SBard Liao 		break;
1244d59fb285SBard Liao 	case RT5668_DAC_STO1_ASRC_SFT:
1245d59fb285SBard Liao 		reg = RT5668_PLL_TRACK_2;
1246d59fb285SBard Liao 		shift = RT5668_FILTER_CLK_SEL_SFT;
1247d59fb285SBard Liao 		break;
1248d59fb285SBard Liao 	default:
1249d59fb285SBard Liao 		return 0;
1250d59fb285SBard Liao 	}
1251d59fb285SBard Liao 
1252467a2553SKuninori Morimoto 	val = (snd_soc_component_read(component, reg) >> shift) & 0xf;
1253d59fb285SBard Liao 	switch (val) {
1254d59fb285SBard Liao 	case RT5668_CLK_SEL_I2S1_ASRC:
1255d59fb285SBard Liao 	case RT5668_CLK_SEL_I2S2_ASRC:
1256d59fb285SBard Liao 		return 1;
1257d59fb285SBard Liao 	default:
1258d59fb285SBard Liao 		return 0;
1259d59fb285SBard Liao 	}
1260d59fb285SBard Liao 
1261d59fb285SBard Liao }
1262d59fb285SBard Liao 
1263d59fb285SBard Liao /* Digital Mixer */
1264d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_sto1_adc_l_mix[] = {
1265d59fb285SBard Liao 	SOC_DAPM_SINGLE("ADC1 Switch", RT5668_STO1_ADC_MIXER,
1266d59fb285SBard Liao 			RT5668_M_STO1_ADC_L1_SFT, 1, 1),
1267d59fb285SBard Liao 	SOC_DAPM_SINGLE("ADC2 Switch", RT5668_STO1_ADC_MIXER,
1268d59fb285SBard Liao 			RT5668_M_STO1_ADC_L2_SFT, 1, 1),
1269d59fb285SBard Liao };
1270d59fb285SBard Liao 
1271d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_sto1_adc_r_mix[] = {
1272d59fb285SBard Liao 	SOC_DAPM_SINGLE("ADC1 Switch", RT5668_STO1_ADC_MIXER,
1273d59fb285SBard Liao 			RT5668_M_STO1_ADC_R1_SFT, 1, 1),
1274d59fb285SBard Liao 	SOC_DAPM_SINGLE("ADC2 Switch", RT5668_STO1_ADC_MIXER,
1275d59fb285SBard Liao 			RT5668_M_STO1_ADC_R2_SFT, 1, 1),
1276d59fb285SBard Liao };
1277d59fb285SBard Liao 
1278d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_dac_l_mix[] = {
1279d59fb285SBard Liao 	SOC_DAPM_SINGLE("Stereo ADC Switch", RT5668_AD_DA_MIXER,
1280d59fb285SBard Liao 			RT5668_M_ADCMIX_L_SFT, 1, 1),
1281d59fb285SBard Liao 	SOC_DAPM_SINGLE("DAC1 Switch", RT5668_AD_DA_MIXER,
1282d59fb285SBard Liao 			RT5668_M_DAC1_L_SFT, 1, 1),
1283d59fb285SBard Liao };
1284d59fb285SBard Liao 
1285d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_dac_r_mix[] = {
1286d59fb285SBard Liao 	SOC_DAPM_SINGLE("Stereo ADC Switch", RT5668_AD_DA_MIXER,
1287d59fb285SBard Liao 			RT5668_M_ADCMIX_R_SFT, 1, 1),
1288d59fb285SBard Liao 	SOC_DAPM_SINGLE("DAC1 Switch", RT5668_AD_DA_MIXER,
1289d59fb285SBard Liao 			RT5668_M_DAC1_R_SFT, 1, 1),
1290d59fb285SBard Liao };
1291d59fb285SBard Liao 
1292d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_sto1_dac_l_mix[] = {
1293d59fb285SBard Liao 	SOC_DAPM_SINGLE("DAC L1 Switch", RT5668_STO1_DAC_MIXER,
1294d59fb285SBard Liao 			RT5668_M_DAC_L1_STO_L_SFT, 1, 1),
1295d59fb285SBard Liao 	SOC_DAPM_SINGLE("DAC R1 Switch", RT5668_STO1_DAC_MIXER,
1296d59fb285SBard Liao 			RT5668_M_DAC_R1_STO_L_SFT, 1, 1),
1297d59fb285SBard Liao };
1298d59fb285SBard Liao 
1299d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_sto1_dac_r_mix[] = {
1300d59fb285SBard Liao 	SOC_DAPM_SINGLE("DAC L1 Switch", RT5668_STO1_DAC_MIXER,
1301d59fb285SBard Liao 			RT5668_M_DAC_L1_STO_R_SFT, 1, 1),
1302d59fb285SBard Liao 	SOC_DAPM_SINGLE("DAC R1 Switch", RT5668_STO1_DAC_MIXER,
1303d59fb285SBard Liao 			RT5668_M_DAC_R1_STO_R_SFT, 1, 1),
1304d59fb285SBard Liao };
1305d59fb285SBard Liao 
1306d59fb285SBard Liao /* Analog Input Mixer */
1307d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_rec1_l_mix[] = {
1308d59fb285SBard Liao 	SOC_DAPM_SINGLE("CBJ Switch", RT5668_REC_MIXER,
1309d59fb285SBard Liao 			RT5668_M_CBJ_RM1_L_SFT, 1, 1),
1310d59fb285SBard Liao };
1311d59fb285SBard Liao 
1312d59fb285SBard Liao /* STO1 ADC1 Source */
1313d59fb285SBard Liao /* MX-26 [13] [5] */
1314d59fb285SBard Liao static const char * const rt5668_sto1_adc1_src[] = {
1315d59fb285SBard Liao 	"DAC MIX", "ADC"
1316d59fb285SBard Liao };
1317d59fb285SBard Liao 
1318d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(
1319d59fb285SBard Liao 	rt5668_sto1_adc1l_enum, RT5668_STO1_ADC_MIXER,
1320d59fb285SBard Liao 	RT5668_STO1_ADC1L_SRC_SFT, rt5668_sto1_adc1_src);
1321d59fb285SBard Liao 
1322d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_sto1_adc1l_mux =
1323d59fb285SBard Liao 	SOC_DAPM_ENUM("Stereo1 ADC1L Source", rt5668_sto1_adc1l_enum);
1324d59fb285SBard Liao 
1325d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(
1326d59fb285SBard Liao 	rt5668_sto1_adc1r_enum, RT5668_STO1_ADC_MIXER,
1327d59fb285SBard Liao 	RT5668_STO1_ADC1R_SRC_SFT, rt5668_sto1_adc1_src);
1328d59fb285SBard Liao 
1329d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_sto1_adc1r_mux =
1330d59fb285SBard Liao 	SOC_DAPM_ENUM("Stereo1 ADC1L Source", rt5668_sto1_adc1r_enum);
1331d59fb285SBard Liao 
1332d59fb285SBard Liao /* STO1 ADC Source */
1333d59fb285SBard Liao /* MX-26 [11:10] [3:2] */
1334d59fb285SBard Liao static const char * const rt5668_sto1_adc_src[] = {
1335d59fb285SBard Liao 	"ADC1 L", "ADC1 R"
1336d59fb285SBard Liao };
1337d59fb285SBard Liao 
1338d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(
1339d59fb285SBard Liao 	rt5668_sto1_adcl_enum, RT5668_STO1_ADC_MIXER,
1340d59fb285SBard Liao 	RT5668_STO1_ADCL_SRC_SFT, rt5668_sto1_adc_src);
1341d59fb285SBard Liao 
1342d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_sto1_adcl_mux =
1343d59fb285SBard Liao 	SOC_DAPM_ENUM("Stereo1 ADCL Source", rt5668_sto1_adcl_enum);
1344d59fb285SBard Liao 
1345d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(
1346d59fb285SBard Liao 	rt5668_sto1_adcr_enum, RT5668_STO1_ADC_MIXER,
1347d59fb285SBard Liao 	RT5668_STO1_ADCR_SRC_SFT, rt5668_sto1_adc_src);
1348d59fb285SBard Liao 
1349d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_sto1_adcr_mux =
1350d59fb285SBard Liao 	SOC_DAPM_ENUM("Stereo1 ADCR Source", rt5668_sto1_adcr_enum);
1351d59fb285SBard Liao 
1352d59fb285SBard Liao /* STO1 ADC2 Source */
1353d59fb285SBard Liao /* MX-26 [12] [4] */
1354d59fb285SBard Liao static const char * const rt5668_sto1_adc2_src[] = {
1355d59fb285SBard Liao 	"DAC MIX", "DMIC"
1356d59fb285SBard Liao };
1357d59fb285SBard Liao 
1358d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(
1359d59fb285SBard Liao 	rt5668_sto1_adc2l_enum, RT5668_STO1_ADC_MIXER,
1360d59fb285SBard Liao 	RT5668_STO1_ADC2L_SRC_SFT, rt5668_sto1_adc2_src);
1361d59fb285SBard Liao 
1362d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_sto1_adc2l_mux =
1363d59fb285SBard Liao 	SOC_DAPM_ENUM("Stereo1 ADC2L Source", rt5668_sto1_adc2l_enum);
1364d59fb285SBard Liao 
1365d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(
1366d59fb285SBard Liao 	rt5668_sto1_adc2r_enum, RT5668_STO1_ADC_MIXER,
1367d59fb285SBard Liao 	RT5668_STO1_ADC2R_SRC_SFT, rt5668_sto1_adc2_src);
1368d59fb285SBard Liao 
1369d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_sto1_adc2r_mux =
1370d59fb285SBard Liao 	SOC_DAPM_ENUM("Stereo1 ADC2R Source", rt5668_sto1_adc2r_enum);
1371d59fb285SBard Liao 
1372d59fb285SBard Liao /* MX-79 [6:4] I2S1 ADC data location */
1373d59fb285SBard Liao static const unsigned int rt5668_if1_adc_slot_values[] = {
1374d59fb285SBard Liao 	0,
1375d59fb285SBard Liao 	2,
1376d59fb285SBard Liao 	4,
1377d59fb285SBard Liao 	6,
1378d59fb285SBard Liao };
1379d59fb285SBard Liao 
1380d59fb285SBard Liao static const char * const rt5668_if1_adc_slot_src[] = {
1381d59fb285SBard Liao 	"Slot 0", "Slot 2", "Slot 4", "Slot 6"
1382d59fb285SBard Liao };
1383d59fb285SBard Liao 
1384d59fb285SBard Liao static SOC_VALUE_ENUM_SINGLE_DECL(rt5668_if1_adc_slot_enum,
1385d59fb285SBard Liao 	RT5668_TDM_CTRL, RT5668_TDM_ADC_LCA_SFT, RT5668_TDM_ADC_LCA_MASK,
1386d59fb285SBard Liao 	rt5668_if1_adc_slot_src, rt5668_if1_adc_slot_values);
1387d59fb285SBard Liao 
1388d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_if1_adc_slot_mux =
1389d59fb285SBard Liao 	SOC_DAPM_ENUM("IF1 ADC Slot location", rt5668_if1_adc_slot_enum);
1390d59fb285SBard Liao 
1391d59fb285SBard Liao /* Analog DAC L1 Source, Analog DAC R1 Source*/
1392d59fb285SBard Liao /* MX-2B [4], MX-2B [0]*/
1393d59fb285SBard Liao static const char * const rt5668_alg_dac1_src[] = {
1394d59fb285SBard Liao 	"Stereo1 DAC Mixer", "DAC1"
1395d59fb285SBard Liao };
1396d59fb285SBard Liao 
1397d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(
1398d59fb285SBard Liao 	rt5668_alg_dac_l1_enum, RT5668_A_DAC1_MUX,
1399d59fb285SBard Liao 	RT5668_A_DACL1_SFT, rt5668_alg_dac1_src);
1400d59fb285SBard Liao 
1401d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_alg_dac_l1_mux =
1402d59fb285SBard Liao 	SOC_DAPM_ENUM("Analog DAC L1 Source", rt5668_alg_dac_l1_enum);
1403d59fb285SBard Liao 
1404d59fb285SBard Liao static SOC_ENUM_SINGLE_DECL(
1405d59fb285SBard Liao 	rt5668_alg_dac_r1_enum, RT5668_A_DAC1_MUX,
1406d59fb285SBard Liao 	RT5668_A_DACR1_SFT, rt5668_alg_dac1_src);
1407d59fb285SBard Liao 
1408d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_alg_dac_r1_mux =
1409d59fb285SBard Liao 	SOC_DAPM_ENUM("Analog DAC R1 Source", rt5668_alg_dac_r1_enum);
1410d59fb285SBard Liao 
1411d59fb285SBard Liao /* Out Switch */
1412d59fb285SBard Liao static const struct snd_kcontrol_new hpol_switch =
1413d59fb285SBard Liao 	SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5668_HP_CTRL_1,
1414d59fb285SBard Liao 					RT5668_L_MUTE_SFT, 1, 1);
1415d59fb285SBard Liao static const struct snd_kcontrol_new hpor_switch =
1416d59fb285SBard Liao 	SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5668_HP_CTRL_1,
1417d59fb285SBard Liao 					RT5668_R_MUTE_SFT, 1, 1);
1418d59fb285SBard Liao 
rt5668_hp_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1419d59fb285SBard Liao static int rt5668_hp_event(struct snd_soc_dapm_widget *w,
1420d59fb285SBard Liao 	struct snd_kcontrol *kcontrol, int event)
1421d59fb285SBard Liao {
1422d59fb285SBard Liao 	struct snd_soc_component *component =
1423d59fb285SBard Liao 		snd_soc_dapm_to_component(w->dapm);
1424d59fb285SBard Liao 
1425d59fb285SBard Liao 	switch (event) {
1426d59fb285SBard Liao 	case SND_SOC_DAPM_PRE_PMU:
1427d59fb285SBard Liao 		snd_soc_component_write(component,
1428d59fb285SBard Liao 			RT5668_HP_LOGIC_CTRL_2, 0x0012);
1429d59fb285SBard Liao 		snd_soc_component_write(component,
1430d59fb285SBard Liao 			RT5668_HP_CTRL_2, 0x6000);
1431d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_STO_NG2_CTRL_1,
1432d59fb285SBard Liao 			RT5668_NG2_EN_MASK, RT5668_NG2_EN);
1433d59fb285SBard Liao 		snd_soc_component_update_bits(component,
1434d59fb285SBard Liao 			RT5668_DEPOP_1, 0x60, 0x60);
1435d59fb285SBard Liao 		break;
1436d59fb285SBard Liao 
1437d59fb285SBard Liao 	case SND_SOC_DAPM_POST_PMD:
1438d59fb285SBard Liao 		snd_soc_component_update_bits(component,
1439d59fb285SBard Liao 			RT5668_DEPOP_1, 0x60, 0x0);
1440d59fb285SBard Liao 		snd_soc_component_write(component,
1441d59fb285SBard Liao 			RT5668_HP_CTRL_2, 0x0000);
1442d59fb285SBard Liao 		break;
1443d59fb285SBard Liao 
1444d59fb285SBard Liao 	default:
1445d59fb285SBard Liao 		return 0;
1446d59fb285SBard Liao 	}
1447d59fb285SBard Liao 
1448d59fb285SBard Liao 	return 0;
1449d59fb285SBard Liao 
1450d59fb285SBard Liao }
1451d59fb285SBard Liao 
set_dmic_power(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1452d59fb285SBard Liao static int set_dmic_power(struct snd_soc_dapm_widget *w,
1453d59fb285SBard Liao 	struct snd_kcontrol *kcontrol, int event)
1454d59fb285SBard Liao {
1455d59fb285SBard Liao 	switch (event) {
1456d59fb285SBard Liao 	case SND_SOC_DAPM_POST_PMU:
1457d59fb285SBard Liao 		/*Add delay to avoid pop noise*/
1458d59fb285SBard Liao 		msleep(150);
1459d59fb285SBard Liao 		break;
1460d59fb285SBard Liao 
1461d59fb285SBard Liao 	default:
1462d59fb285SBard Liao 		return 0;
1463d59fb285SBard Liao 	}
1464d59fb285SBard Liao 
1465d59fb285SBard Liao 	return 0;
1466d59fb285SBard Liao }
1467d59fb285SBard Liao 
rt5655_set_verf(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1468d59fb285SBard Liao static int rt5655_set_verf(struct snd_soc_dapm_widget *w,
1469d59fb285SBard Liao 	struct snd_kcontrol *kcontrol, int event)
1470d59fb285SBard Liao {
1471d59fb285SBard Liao 	struct snd_soc_component *component =
1472d59fb285SBard Liao 		snd_soc_dapm_to_component(w->dapm);
1473d59fb285SBard Liao 
1474d59fb285SBard Liao 	switch (event) {
1475d59fb285SBard Liao 	case SND_SOC_DAPM_PRE_PMU:
1476d59fb285SBard Liao 		switch (w->shift) {
1477d59fb285SBard Liao 		case RT5668_PWR_VREF1_BIT:
1478d59fb285SBard Liao 			snd_soc_component_update_bits(component,
1479d59fb285SBard Liao 				RT5668_PWR_ANLG_1, RT5668_PWR_FV1, 0);
1480d59fb285SBard Liao 			break;
1481d59fb285SBard Liao 
1482d59fb285SBard Liao 		case RT5668_PWR_VREF2_BIT:
1483d59fb285SBard Liao 			snd_soc_component_update_bits(component,
1484d59fb285SBard Liao 				RT5668_PWR_ANLG_1, RT5668_PWR_FV2, 0);
1485d59fb285SBard Liao 			break;
1486d59fb285SBard Liao 
1487d59fb285SBard Liao 		default:
1488d59fb285SBard Liao 			break;
1489d59fb285SBard Liao 		}
1490d59fb285SBard Liao 		break;
1491d59fb285SBard Liao 
1492d59fb285SBard Liao 	case SND_SOC_DAPM_POST_PMU:
1493d59fb285SBard Liao 		usleep_range(15000, 20000);
1494d59fb285SBard Liao 		switch (w->shift) {
1495d59fb285SBard Liao 		case RT5668_PWR_VREF1_BIT:
1496d59fb285SBard Liao 			snd_soc_component_update_bits(component,
1497d59fb285SBard Liao 				RT5668_PWR_ANLG_1, RT5668_PWR_FV1,
1498d59fb285SBard Liao 				RT5668_PWR_FV1);
1499d59fb285SBard Liao 			break;
1500d59fb285SBard Liao 
1501d59fb285SBard Liao 		case RT5668_PWR_VREF2_BIT:
1502d59fb285SBard Liao 			snd_soc_component_update_bits(component,
1503d59fb285SBard Liao 				RT5668_PWR_ANLG_1, RT5668_PWR_FV2,
1504d59fb285SBard Liao 				RT5668_PWR_FV2);
1505d59fb285SBard Liao 			break;
1506d59fb285SBard Liao 
1507d59fb285SBard Liao 		default:
1508d59fb285SBard Liao 			break;
1509d59fb285SBard Liao 		}
1510d59fb285SBard Liao 		break;
1511d59fb285SBard Liao 
1512d59fb285SBard Liao 	default:
1513d59fb285SBard Liao 		return 0;
1514d59fb285SBard Liao 	}
1515d59fb285SBard Liao 
1516d59fb285SBard Liao 	return 0;
1517d59fb285SBard Liao }
1518d59fb285SBard Liao 
1519d59fb285SBard Liao static const unsigned int rt5668_adcdat_pin_values[] = {
1520d59fb285SBard Liao 	1,
1521d59fb285SBard Liao 	3,
1522d59fb285SBard Liao };
1523d59fb285SBard Liao 
1524d59fb285SBard Liao static const char * const rt5668_adcdat_pin_select[] = {
1525d59fb285SBard Liao 	"ADCDAT1",
1526d59fb285SBard Liao 	"ADCDAT2",
1527d59fb285SBard Liao };
1528d59fb285SBard Liao 
1529d59fb285SBard Liao static SOC_VALUE_ENUM_SINGLE_DECL(rt5668_adcdat_pin_enum,
1530d59fb285SBard Liao 	RT5668_GPIO_CTRL_1, RT5668_GP4_PIN_SFT, RT5668_GP4_PIN_MASK,
1531d59fb285SBard Liao 	rt5668_adcdat_pin_select, rt5668_adcdat_pin_values);
1532d59fb285SBard Liao 
1533d59fb285SBard Liao static const struct snd_kcontrol_new rt5668_adcdat_pin_ctrl =
1534d59fb285SBard Liao 	SOC_DAPM_ENUM("ADCDAT", rt5668_adcdat_pin_enum);
1535d59fb285SBard Liao 
1536d59fb285SBard Liao static const struct snd_soc_dapm_widget rt5668_dapm_widgets[] = {
1537d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("LDO2", RT5668_PWR_ANLG_3, RT5668_PWR_LDO2_BIT,
1538d59fb285SBard Liao 		0, NULL, 0),
1539d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("PLL1", RT5668_PWR_ANLG_3, RT5668_PWR_PLL_BIT,
1540d59fb285SBard Liao 		0, NULL, 0),
1541d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("PLL2B", RT5668_PWR_ANLG_3, RT5668_PWR_PLL2B_BIT,
1542d59fb285SBard Liao 		0, NULL, 0),
1543d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("PLL2F", RT5668_PWR_ANLG_3, RT5668_PWR_PLL2F_BIT,
1544d59fb285SBard Liao 		0, NULL, 0),
1545d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("Vref1", RT5668_PWR_ANLG_1, RT5668_PWR_VREF1_BIT, 0,
1546d59fb285SBard Liao 		rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1547d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("Vref2", RT5668_PWR_ANLG_1, RT5668_PWR_VREF2_BIT, 0,
1548d59fb285SBard Liao 		rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1549d59fb285SBard Liao 
1550d59fb285SBard Liao 	/* ASRC */
1551d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY_S("DAC STO1 ASRC", 1, RT5668_PLL_TRACK_1,
1552d59fb285SBard Liao 		RT5668_DAC_STO1_ASRC_SFT, 0, NULL, 0),
1553d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5668_PLL_TRACK_1,
1554d59fb285SBard Liao 		RT5668_ADC_STO1_ASRC_SFT, 0, NULL, 0),
1555d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY_S("AD ASRC", 1, RT5668_PLL_TRACK_1,
1556d59fb285SBard Liao 		RT5668_AD_ASRC_SFT, 0, NULL, 0),
1557d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY_S("DA ASRC", 1, RT5668_PLL_TRACK_1,
1558d59fb285SBard Liao 		RT5668_DA_ASRC_SFT, 0, NULL, 0),
1559d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY_S("DMIC ASRC", 1, RT5668_PLL_TRACK_1,
1560d59fb285SBard Liao 		RT5668_DMIC_ASRC_SFT, 0, NULL, 0),
1561d59fb285SBard Liao 
1562d59fb285SBard Liao 	/* Input Side */
1563d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5668_PWR_ANLG_2, RT5668_PWR_MB1_BIT,
1564d59fb285SBard Liao 		0, NULL, 0),
1565d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("MICBIAS2", RT5668_PWR_ANLG_2, RT5668_PWR_MB2_BIT,
1566d59fb285SBard Liao 		0, NULL, 0),
1567d59fb285SBard Liao 
1568d59fb285SBard Liao 	/* Input Lines */
1569d59fb285SBard Liao 	SND_SOC_DAPM_INPUT("DMIC L1"),
1570d59fb285SBard Liao 	SND_SOC_DAPM_INPUT("DMIC R1"),
1571d59fb285SBard Liao 
1572d59fb285SBard Liao 	SND_SOC_DAPM_INPUT("IN1P"),
1573d59fb285SBard Liao 
1574d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
1575d59fb285SBard Liao 		set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
1576d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5668_DMIC_CTRL_1,
1577d59fb285SBard Liao 		RT5668_DMIC_1_EN_SFT, 0, set_dmic_power, SND_SOC_DAPM_POST_PMU),
1578d59fb285SBard Liao 
1579d59fb285SBard Liao 	/* Boost */
1580d59fb285SBard Liao 	SND_SOC_DAPM_PGA("BST1 CBJ", SND_SOC_NOPM,
1581d59fb285SBard Liao 		0, 0, NULL, 0),
1582d59fb285SBard Liao 
1583d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("CBJ Power", RT5668_PWR_ANLG_3,
1584d59fb285SBard Liao 		RT5668_PWR_CBJ_BIT, 0, NULL, 0),
1585d59fb285SBard Liao 
1586d59fb285SBard Liao 	/* REC Mixer */
1587d59fb285SBard Liao 	SND_SOC_DAPM_MIXER("RECMIX1L", SND_SOC_NOPM, 0, 0, rt5668_rec1_l_mix,
1588d59fb285SBard Liao 		ARRAY_SIZE(rt5668_rec1_l_mix)),
1589d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("RECMIX1L Power", RT5668_PWR_ANLG_2,
1590d59fb285SBard Liao 		RT5668_PWR_RM1_L_BIT, 0, NULL, 0),
1591d59fb285SBard Liao 
1592d59fb285SBard Liao 	/* ADCs */
1593d59fb285SBard Liao 	SND_SOC_DAPM_ADC("ADC1 L", NULL, SND_SOC_NOPM, 0, 0),
1594d59fb285SBard Liao 	SND_SOC_DAPM_ADC("ADC1 R", NULL, SND_SOC_NOPM, 0, 0),
1595d59fb285SBard Liao 
1596d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("ADC1 L Power", RT5668_PWR_DIG_1,
1597d59fb285SBard Liao 		RT5668_PWR_ADC_L1_BIT, 0, NULL, 0),
1598d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("ADC1 R Power", RT5668_PWR_DIG_1,
1599d59fb285SBard Liao 		RT5668_PWR_ADC_R1_BIT, 0, NULL, 0),
1600d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("ADC1 clock", RT5668_CHOP_ADC,
1601d59fb285SBard Liao 		RT5668_CKGEN_ADC1_SFT, 0, NULL, 0),
1602d59fb285SBard Liao 
1603d59fb285SBard Liao 	/* ADC Mux */
1604d59fb285SBard Liao 	SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0,
1605d59fb285SBard Liao 		&rt5668_sto1_adc1l_mux),
1606d59fb285SBard Liao 	SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0,
1607d59fb285SBard Liao 		&rt5668_sto1_adc1r_mux),
1608d59fb285SBard Liao 	SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0,
1609d59fb285SBard Liao 		&rt5668_sto1_adc2l_mux),
1610d59fb285SBard Liao 	SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0,
1611d59fb285SBard Liao 		&rt5668_sto1_adc2r_mux),
1612d59fb285SBard Liao 	SND_SOC_DAPM_MUX("Stereo1 ADC L Mux", SND_SOC_NOPM, 0, 0,
1613d59fb285SBard Liao 		&rt5668_sto1_adcl_mux),
1614d59fb285SBard Liao 	SND_SOC_DAPM_MUX("Stereo1 ADC R Mux", SND_SOC_NOPM, 0, 0,
1615d59fb285SBard Liao 		&rt5668_sto1_adcr_mux),
1616d59fb285SBard Liao 	SND_SOC_DAPM_MUX("IF1_ADC Mux", SND_SOC_NOPM, 0, 0,
1617d59fb285SBard Liao 		&rt5668_if1_adc_slot_mux),
1618d59fb285SBard Liao 
1619d59fb285SBard Liao 	/* ADC Mixer */
1620d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("ADC Stereo1 Filter", RT5668_PWR_DIG_2,
1621d59fb285SBard Liao 		RT5668_PWR_ADC_S1F_BIT, 0, set_filter_clk,
1622d59fb285SBard Liao 		SND_SOC_DAPM_PRE_PMU),
1623d59fb285SBard Liao 	SND_SOC_DAPM_MIXER("Stereo1 ADC MIXL", RT5668_STO1_ADC_DIG_VOL,
1624d59fb285SBard Liao 		RT5668_L_MUTE_SFT, 1, rt5668_sto1_adc_l_mix,
1625d59fb285SBard Liao 		ARRAY_SIZE(rt5668_sto1_adc_l_mix)),
1626d59fb285SBard Liao 	SND_SOC_DAPM_MIXER("Stereo1 ADC MIXR", RT5668_STO1_ADC_DIG_VOL,
1627d59fb285SBard Liao 		RT5668_R_MUTE_SFT, 1, rt5668_sto1_adc_r_mix,
1628d59fb285SBard Liao 		ARRAY_SIZE(rt5668_sto1_adc_r_mix)),
1629d59fb285SBard Liao 
1630d59fb285SBard Liao 	/* ADC PGA */
1631d59fb285SBard Liao 	SND_SOC_DAPM_PGA("Stereo1 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
1632d59fb285SBard Liao 
1633d59fb285SBard Liao 	/* Digital Interface */
1634d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("I2S1", RT5668_PWR_DIG_1, RT5668_PWR_I2S1_BIT,
1635d59fb285SBard Liao 		0, NULL, 0),
1636d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("I2S2", RT5668_PWR_DIG_1, RT5668_PWR_I2S2_BIT,
1637d59fb285SBard Liao 		0, NULL, 0),
1638d59fb285SBard Liao 	SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0),
1639d59fb285SBard Liao 	SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
1640d59fb285SBard Liao 	SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
1641d59fb285SBard Liao 
1642d59fb285SBard Liao 	/* Digital Interface Select */
1643d59fb285SBard Liao 	SND_SOC_DAPM_MUX("IF1 01 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
1644d59fb285SBard Liao 			&rt5668_if1_01_adc_swap_mux),
1645d59fb285SBard Liao 	SND_SOC_DAPM_MUX("IF1 23 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
1646d59fb285SBard Liao 			&rt5668_if1_23_adc_swap_mux),
1647d59fb285SBard Liao 	SND_SOC_DAPM_MUX("IF1 45 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
1648d59fb285SBard Liao 			&rt5668_if1_45_adc_swap_mux),
1649d59fb285SBard Liao 	SND_SOC_DAPM_MUX("IF1 67 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
1650d59fb285SBard Liao 			&rt5668_if1_67_adc_swap_mux),
1651d59fb285SBard Liao 	SND_SOC_DAPM_MUX("IF2 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
1652d59fb285SBard Liao 			&rt5668_if2_adc_swap_mux),
1653d59fb285SBard Liao 
1654d59fb285SBard Liao 	SND_SOC_DAPM_MUX("ADCDAT Mux", SND_SOC_NOPM, 0, 0,
1655d59fb285SBard Liao 			&rt5668_adcdat_pin_ctrl),
1656d59fb285SBard Liao 
1657d59fb285SBard Liao 	/* Audio Interface */
1658d59fb285SBard Liao 	SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0,
1659d59fb285SBard Liao 		RT5668_I2S1_SDP, RT5668_SEL_ADCDAT_SFT, 1),
1660d59fb285SBard Liao 	SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0,
1661d59fb285SBard Liao 		RT5668_I2S2_SDP, RT5668_I2S2_PIN_CFG_SFT, 1),
1662d59fb285SBard Liao 	SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
1663d59fb285SBard Liao 
1664d59fb285SBard Liao 	/* Output Side */
1665d59fb285SBard Liao 	/* DAC mixer before sound effect  */
1666d59fb285SBard Liao 	SND_SOC_DAPM_MIXER("DAC1 MIXL", SND_SOC_NOPM, 0, 0,
1667d59fb285SBard Liao 		rt5668_dac_l_mix, ARRAY_SIZE(rt5668_dac_l_mix)),
1668d59fb285SBard Liao 	SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0,
1669d59fb285SBard Liao 		rt5668_dac_r_mix, ARRAY_SIZE(rt5668_dac_r_mix)),
1670d59fb285SBard Liao 
1671d59fb285SBard Liao 	/* DAC channel Mux */
1672d59fb285SBard Liao 	SND_SOC_DAPM_MUX("DAC L1 Source", SND_SOC_NOPM, 0, 0,
1673d59fb285SBard Liao 		&rt5668_alg_dac_l1_mux),
1674d59fb285SBard Liao 	SND_SOC_DAPM_MUX("DAC R1 Source", SND_SOC_NOPM, 0, 0,
1675d59fb285SBard Liao 		&rt5668_alg_dac_r1_mux),
1676d59fb285SBard Liao 
1677d59fb285SBard Liao 	/* DAC Mixer */
1678d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("DAC Stereo1 Filter", RT5668_PWR_DIG_2,
1679d59fb285SBard Liao 		RT5668_PWR_DAC_S1F_BIT, 0, set_filter_clk,
1680d59fb285SBard Liao 		SND_SOC_DAPM_PRE_PMU),
1681d59fb285SBard Liao 	SND_SOC_DAPM_MIXER("Stereo1 DAC MIXL", SND_SOC_NOPM, 0, 0,
1682d59fb285SBard Liao 		rt5668_sto1_dac_l_mix, ARRAY_SIZE(rt5668_sto1_dac_l_mix)),
1683d59fb285SBard Liao 	SND_SOC_DAPM_MIXER("Stereo1 DAC MIXR", SND_SOC_NOPM, 0, 0,
1684d59fb285SBard Liao 		rt5668_sto1_dac_r_mix, ARRAY_SIZE(rt5668_sto1_dac_r_mix)),
1685d59fb285SBard Liao 
1686d59fb285SBard Liao 	/* DACs */
1687d59fb285SBard Liao 	SND_SOC_DAPM_DAC("DAC L1", NULL, RT5668_PWR_DIG_1,
1688d59fb285SBard Liao 		RT5668_PWR_DAC_L1_BIT, 0),
1689d59fb285SBard Liao 	SND_SOC_DAPM_DAC("DAC R1", NULL, RT5668_PWR_DIG_1,
1690d59fb285SBard Liao 		RT5668_PWR_DAC_R1_BIT, 0),
1691d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY_S("DAC 1 Clock", 3, RT5668_CHOP_DAC,
1692d59fb285SBard Liao 		RT5668_CKGEN_DAC1_SFT, 0, NULL, 0),
1693d59fb285SBard Liao 
1694d59fb285SBard Liao 	/* HPO */
1695d59fb285SBard Liao 	SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5668_hp_event,
1696d59fb285SBard Liao 		SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU),
1697d59fb285SBard Liao 
1698d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("HP Amp L", RT5668_PWR_ANLG_1,
1699d59fb285SBard Liao 		RT5668_PWR_HA_L_BIT, 0, NULL, 0),
1700d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("HP Amp R", RT5668_PWR_ANLG_1,
1701d59fb285SBard Liao 		RT5668_PWR_HA_R_BIT, 0, NULL, 0),
1702d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, RT5668_DEPOP_1,
1703d59fb285SBard Liao 		RT5668_PUMP_EN_SFT, 0, NULL, 0),
1704d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY_S("Capless", 2, RT5668_DEPOP_1,
1705d59fb285SBard Liao 		RT5668_CAPLESS_EN_SFT, 0, NULL, 0),
1706d59fb285SBard Liao 
1707d59fb285SBard Liao 	SND_SOC_DAPM_SWITCH("HPOL Playback", SND_SOC_NOPM, 0, 0,
1708d59fb285SBard Liao 		&hpol_switch),
1709d59fb285SBard Liao 	SND_SOC_DAPM_SWITCH("HPOR Playback", SND_SOC_NOPM, 0, 0,
1710d59fb285SBard Liao 		&hpor_switch),
1711d59fb285SBard Liao 
1712d59fb285SBard Liao 	/* CLK DET */
1713d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("CLKDET SYS", RT5668_CLK_DET,
1714d59fb285SBard Liao 		RT5668_SYS_CLK_DET_SFT,	0, NULL, 0),
1715d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("CLKDET PLL1", RT5668_CLK_DET,
1716d59fb285SBard Liao 		RT5668_PLL1_CLK_DET_SFT, 0, NULL, 0),
1717d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("CLKDET PLL2", RT5668_CLK_DET,
1718d59fb285SBard Liao 		RT5668_PLL2_CLK_DET_SFT, 0, NULL, 0),
1719d59fb285SBard Liao 	SND_SOC_DAPM_SUPPLY("CLKDET", RT5668_CLK_DET,
1720d59fb285SBard Liao 		RT5668_POW_CLK_DET_SFT, 0, NULL, 0),
1721d59fb285SBard Liao 
1722d59fb285SBard Liao 	/* Output Lines */
1723d59fb285SBard Liao 	SND_SOC_DAPM_OUTPUT("HPOL"),
1724d59fb285SBard Liao 	SND_SOC_DAPM_OUTPUT("HPOR"),
1725d59fb285SBard Liao 
1726d59fb285SBard Liao };
1727d59fb285SBard Liao 
1728d59fb285SBard Liao static const struct snd_soc_dapm_route rt5668_dapm_routes[] = {
1729d59fb285SBard Liao 	/*PLL*/
1730d59fb285SBard Liao 	{"ADC Stereo1 Filter", NULL, "PLL1", is_sys_clk_from_pll1},
1731d59fb285SBard Liao 	{"DAC Stereo1 Filter", NULL, "PLL1", is_sys_clk_from_pll1},
1732d59fb285SBard Liao 
1733d59fb285SBard Liao 	/*ASRC*/
1734d59fb285SBard Liao 	{"ADC Stereo1 Filter", NULL, "ADC STO1 ASRC", is_using_asrc},
1735d59fb285SBard Liao 	{"DAC Stereo1 Filter", NULL, "DAC STO1 ASRC", is_using_asrc},
1736d59fb285SBard Liao 	{"ADC STO1 ASRC", NULL, "AD ASRC"},
1737d59fb285SBard Liao 	{"DAC STO1 ASRC", NULL, "DA ASRC"},
1738d59fb285SBard Liao 
1739d59fb285SBard Liao 	/*Vref*/
1740d59fb285SBard Liao 	{"MICBIAS1", NULL, "Vref1"},
1741d59fb285SBard Liao 	{"MICBIAS1", NULL, "Vref2"},
1742d59fb285SBard Liao 	{"MICBIAS2", NULL, "Vref1"},
1743d59fb285SBard Liao 	{"MICBIAS2", NULL, "Vref2"},
1744d59fb285SBard Liao 
1745d59fb285SBard Liao 	{"CLKDET SYS", NULL, "CLKDET"},
1746d59fb285SBard Liao 
1747d59fb285SBard Liao 	{"IN1P", NULL, "LDO2"},
1748d59fb285SBard Liao 
1749d59fb285SBard Liao 	{"BST1 CBJ", NULL, "IN1P"},
1750d59fb285SBard Liao 	{"BST1 CBJ", NULL, "CBJ Power"},
1751d59fb285SBard Liao 	{"CBJ Power", NULL, "Vref2"},
1752d59fb285SBard Liao 
1753d59fb285SBard Liao 	{"RECMIX1L", "CBJ Switch", "BST1 CBJ"},
1754d59fb285SBard Liao 	{"RECMIX1L", NULL, "RECMIX1L Power"},
1755d59fb285SBard Liao 
1756d59fb285SBard Liao 	{"ADC1 L", NULL, "RECMIX1L"},
1757d59fb285SBard Liao 	{"ADC1 L", NULL, "ADC1 L Power"},
1758d59fb285SBard Liao 	{"ADC1 L", NULL, "ADC1 clock"},
1759d59fb285SBard Liao 
1760d59fb285SBard Liao 	{"DMIC L1", NULL, "DMIC CLK"},
1761d59fb285SBard Liao 	{"DMIC L1", NULL, "DMIC1 Power"},
1762d59fb285SBard Liao 	{"DMIC R1", NULL, "DMIC CLK"},
1763d59fb285SBard Liao 	{"DMIC R1", NULL, "DMIC1 Power"},
1764d59fb285SBard Liao 	{"DMIC CLK", NULL, "DMIC ASRC"},
1765d59fb285SBard Liao 
1766d59fb285SBard Liao 	{"Stereo1 ADC L Mux", "ADC1 L", "ADC1 L"},
1767d59fb285SBard Liao 	{"Stereo1 ADC L Mux", "ADC1 R", "ADC1 R"},
1768d59fb285SBard Liao 	{"Stereo1 ADC R Mux", "ADC1 L", "ADC1 L"},
1769d59fb285SBard Liao 	{"Stereo1 ADC R Mux", "ADC1 R", "ADC1 R"},
1770d59fb285SBard Liao 
1771d59fb285SBard Liao 	{"Stereo1 ADC L1 Mux", "ADC", "Stereo1 ADC L Mux"},
1772d59fb285SBard Liao 	{"Stereo1 ADC L1 Mux", "DAC MIX", "Stereo1 DAC MIXL"},
1773d59fb285SBard Liao 	{"Stereo1 ADC L2 Mux", "DMIC", "DMIC L1"},
1774d59fb285SBard Liao 	{"Stereo1 ADC L2 Mux", "DAC MIX", "Stereo1 DAC MIXL"},
1775d59fb285SBard Liao 
1776d59fb285SBard Liao 	{"Stereo1 ADC R1 Mux", "ADC", "Stereo1 ADC R Mux"},
1777d59fb285SBard Liao 	{"Stereo1 ADC R1 Mux", "DAC MIX", "Stereo1 DAC MIXR"},
1778d59fb285SBard Liao 	{"Stereo1 ADC R2 Mux", "DMIC", "DMIC R1"},
1779d59fb285SBard Liao 	{"Stereo1 ADC R2 Mux", "DAC MIX", "Stereo1 DAC MIXR"},
1780d59fb285SBard Liao 
1781d59fb285SBard Liao 	{"Stereo1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux"},
1782d59fb285SBard Liao 	{"Stereo1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux"},
1783d59fb285SBard Liao 	{"Stereo1 ADC MIXL", NULL, "ADC Stereo1 Filter"},
1784d59fb285SBard Liao 
1785d59fb285SBard Liao 	{"Stereo1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux"},
1786d59fb285SBard Liao 	{"Stereo1 ADC MIXR", "ADC2 Switch", "Stereo1 ADC R2 Mux"},
1787d59fb285SBard Liao 	{"Stereo1 ADC MIXR", NULL, "ADC Stereo1 Filter"},
1788d59fb285SBard Liao 
1789d59fb285SBard Liao 	{"Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXL"},
1790d59fb285SBard Liao 	{"Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXR"},
1791d59fb285SBard Liao 
1792d59fb285SBard Liao 	{"IF1 01 ADC Swap Mux", "L/R", "Stereo1 ADC MIX"},
1793d59fb285SBard Liao 	{"IF1 01 ADC Swap Mux", "L/L", "Stereo1 ADC MIX"},
1794d59fb285SBard Liao 	{"IF1 01 ADC Swap Mux", "R/L", "Stereo1 ADC MIX"},
1795d59fb285SBard Liao 	{"IF1 01 ADC Swap Mux", "R/R", "Stereo1 ADC MIX"},
1796d59fb285SBard Liao 	{"IF1 23 ADC Swap Mux", "L/R", "Stereo1 ADC MIX"},
1797d59fb285SBard Liao 	{"IF1 23 ADC Swap Mux", "R/L", "Stereo1 ADC MIX"},
1798d59fb285SBard Liao 	{"IF1 23 ADC Swap Mux", "L/L", "Stereo1 ADC MIX"},
1799d59fb285SBard Liao 	{"IF1 23 ADC Swap Mux", "R/R", "Stereo1 ADC MIX"},
1800d59fb285SBard Liao 	{"IF1 45 ADC Swap Mux", "L/R", "Stereo1 ADC MIX"},
1801d59fb285SBard Liao 	{"IF1 45 ADC Swap Mux", "R/L", "Stereo1 ADC MIX"},
1802d59fb285SBard Liao 	{"IF1 45 ADC Swap Mux", "L/L", "Stereo1 ADC MIX"},
1803d59fb285SBard Liao 	{"IF1 45 ADC Swap Mux", "R/R", "Stereo1 ADC MIX"},
1804d59fb285SBard Liao 	{"IF1 67 ADC Swap Mux", "L/R", "Stereo1 ADC MIX"},
1805d59fb285SBard Liao 	{"IF1 67 ADC Swap Mux", "R/L", "Stereo1 ADC MIX"},
1806d59fb285SBard Liao 	{"IF1 67 ADC Swap Mux", "L/L", "Stereo1 ADC MIX"},
1807d59fb285SBard Liao 	{"IF1 67 ADC Swap Mux", "R/R", "Stereo1 ADC MIX"},
1808d59fb285SBard Liao 
1809d59fb285SBard Liao 	{"IF1_ADC Mux", "Slot 0", "IF1 01 ADC Swap Mux"},
1810d59fb285SBard Liao 	{"IF1_ADC Mux", "Slot 2", "IF1 23 ADC Swap Mux"},
1811d59fb285SBard Liao 	{"IF1_ADC Mux", "Slot 4", "IF1 45 ADC Swap Mux"},
1812d59fb285SBard Liao 	{"IF1_ADC Mux", "Slot 6", "IF1 67 ADC Swap Mux"},
1813d59fb285SBard Liao 	{"IF1_ADC Mux", NULL, "I2S1"},
1814d59fb285SBard Liao 	{"ADCDAT Mux", "ADCDAT1", "IF1_ADC Mux"},
1815d59fb285SBard Liao 	{"AIF1TX", NULL, "ADCDAT Mux"},
1816d59fb285SBard Liao 	{"IF2 ADC Swap Mux", "L/R", "Stereo1 ADC MIX"},
1817d59fb285SBard Liao 	{"IF2 ADC Swap Mux", "R/L", "Stereo1 ADC MIX"},
1818d59fb285SBard Liao 	{"IF2 ADC Swap Mux", "L/L", "Stereo1 ADC MIX"},
1819d59fb285SBard Liao 	{"IF2 ADC Swap Mux", "R/R", "Stereo1 ADC MIX"},
1820d59fb285SBard Liao 	{"ADCDAT Mux", "ADCDAT2", "IF2 ADC Swap Mux"},
1821d59fb285SBard Liao 	{"AIF2TX", NULL, "ADCDAT Mux"},
1822d59fb285SBard Liao 
1823d59fb285SBard Liao 	{"IF1 DAC1 L", NULL, "AIF1RX"},
1824d59fb285SBard Liao 	{"IF1 DAC1 L", NULL, "I2S1"},
1825d59fb285SBard Liao 	{"IF1 DAC1 L", NULL, "DAC Stereo1 Filter"},
1826d59fb285SBard Liao 	{"IF1 DAC1 R", NULL, "AIF1RX"},
1827d59fb285SBard Liao 	{"IF1 DAC1 R", NULL, "I2S1"},
1828d59fb285SBard Liao 	{"IF1 DAC1 R", NULL, "DAC Stereo1 Filter"},
1829d59fb285SBard Liao 
1830d59fb285SBard Liao 	{"DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL"},
1831d59fb285SBard Liao 	{"DAC1 MIXL", "DAC1 Switch", "IF1 DAC1 L"},
1832d59fb285SBard Liao 	{"DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR"},
1833d59fb285SBard Liao 	{"DAC1 MIXR", "DAC1 Switch", "IF1 DAC1 R"},
1834d59fb285SBard Liao 
1835d59fb285SBard Liao 	{"Stereo1 DAC MIXL", "DAC L1 Switch", "DAC1 MIXL"},
1836d59fb285SBard Liao 	{"Stereo1 DAC MIXL", "DAC R1 Switch", "DAC1 MIXR"},
1837d59fb285SBard Liao 
1838d59fb285SBard Liao 	{"Stereo1 DAC MIXR", "DAC R1 Switch", "DAC1 MIXR"},
1839d59fb285SBard Liao 	{"Stereo1 DAC MIXR", "DAC L1 Switch", "DAC1 MIXL"},
1840d59fb285SBard Liao 
1841d59fb285SBard Liao 	{"DAC L1 Source", "DAC1", "DAC1 MIXL"},
1842d59fb285SBard Liao 	{"DAC L1 Source", "Stereo1 DAC Mixer", "Stereo1 DAC MIXL"},
1843d59fb285SBard Liao 	{"DAC R1 Source", "DAC1", "DAC1 MIXR"},
1844d59fb285SBard Liao 	{"DAC R1 Source", "Stereo1 DAC Mixer", "Stereo1 DAC MIXR"},
1845d59fb285SBard Liao 
1846d59fb285SBard Liao 	{"DAC L1", NULL, "DAC L1 Source"},
1847d59fb285SBard Liao 	{"DAC R1", NULL, "DAC R1 Source"},
1848d59fb285SBard Liao 
1849d59fb285SBard Liao 	{"DAC L1", NULL, "DAC 1 Clock"},
1850d59fb285SBard Liao 	{"DAC R1", NULL, "DAC 1 Clock"},
1851d59fb285SBard Liao 
1852d59fb285SBard Liao 	{"HP Amp", NULL, "DAC L1"},
1853d59fb285SBard Liao 	{"HP Amp", NULL, "DAC R1"},
1854d59fb285SBard Liao 	{"HP Amp", NULL, "HP Amp L"},
1855d59fb285SBard Liao 	{"HP Amp", NULL, "HP Amp R"},
1856d59fb285SBard Liao 	{"HP Amp", NULL, "Capless"},
1857d59fb285SBard Liao 	{"HP Amp", NULL, "Charge Pump"},
1858d59fb285SBard Liao 	{"HP Amp", NULL, "CLKDET SYS"},
1859d59fb285SBard Liao 	{"HP Amp", NULL, "CBJ Power"},
1860d59fb285SBard Liao 	{"HP Amp", NULL, "Vref2"},
1861d59fb285SBard Liao 	{"HPOL Playback", "Switch", "HP Amp"},
1862d59fb285SBard Liao 	{"HPOR Playback", "Switch", "HP Amp"},
1863d59fb285SBard Liao 	{"HPOL", NULL, "HPOL Playback"},
1864d59fb285SBard Liao 	{"HPOR", NULL, "HPOR Playback"},
1865d59fb285SBard Liao };
1866d59fb285SBard Liao 
rt5668_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)1867d59fb285SBard Liao static int rt5668_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1868d59fb285SBard Liao 			unsigned int rx_mask, int slots, int slot_width)
1869d59fb285SBard Liao {
1870d59fb285SBard Liao 	struct snd_soc_component *component = dai->component;
1871d59fb285SBard Liao 	unsigned int val = 0;
1872d59fb285SBard Liao 
1873d59fb285SBard Liao 	switch (slots) {
1874d59fb285SBard Liao 	case 4:
1875d59fb285SBard Liao 		val |= RT5668_TDM_TX_CH_4;
1876d59fb285SBard Liao 		val |= RT5668_TDM_RX_CH_4;
1877d59fb285SBard Liao 		break;
1878d59fb285SBard Liao 	case 6:
1879d59fb285SBard Liao 		val |= RT5668_TDM_TX_CH_6;
1880d59fb285SBard Liao 		val |= RT5668_TDM_RX_CH_6;
1881d59fb285SBard Liao 		break;
1882d59fb285SBard Liao 	case 8:
1883d59fb285SBard Liao 		val |= RT5668_TDM_TX_CH_8;
1884d59fb285SBard Liao 		val |= RT5668_TDM_RX_CH_8;
1885d59fb285SBard Liao 		break;
1886d59fb285SBard Liao 	case 2:
1887d59fb285SBard Liao 		break;
1888d59fb285SBard Liao 	default:
1889d59fb285SBard Liao 		return -EINVAL;
1890d59fb285SBard Liao 	}
1891d59fb285SBard Liao 
1892d59fb285SBard Liao 	snd_soc_component_update_bits(component, RT5668_TDM_CTRL,
1893d59fb285SBard Liao 		RT5668_TDM_TX_CH_MASK | RT5668_TDM_RX_CH_MASK, val);
1894d59fb285SBard Liao 
1895d59fb285SBard Liao 	switch (slot_width) {
1896d59fb285SBard Liao 	case 16:
1897d59fb285SBard Liao 		val = RT5668_TDM_CL_16;
1898d59fb285SBard Liao 		break;
1899d59fb285SBard Liao 	case 20:
1900d59fb285SBard Liao 		val = RT5668_TDM_CL_20;
1901d59fb285SBard Liao 		break;
1902d59fb285SBard Liao 	case 24:
1903d59fb285SBard Liao 		val = RT5668_TDM_CL_24;
1904d59fb285SBard Liao 		break;
1905d59fb285SBard Liao 	case 32:
1906d59fb285SBard Liao 		val = RT5668_TDM_CL_32;
1907d59fb285SBard Liao 		break;
1908d59fb285SBard Liao 	default:
1909d59fb285SBard Liao 		return -EINVAL;
1910d59fb285SBard Liao 	}
1911d59fb285SBard Liao 
1912d59fb285SBard Liao 	snd_soc_component_update_bits(component, RT5668_TDM_TCON_CTRL,
1913d59fb285SBard Liao 		RT5668_TDM_CL_MASK, val);
1914d59fb285SBard Liao 
1915d59fb285SBard Liao 	return 0;
1916d59fb285SBard Liao }
1917d59fb285SBard Liao 
1918d59fb285SBard Liao 
rt5668_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)1919d59fb285SBard Liao static int rt5668_hw_params(struct snd_pcm_substream *substream,
1920d59fb285SBard Liao 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1921d59fb285SBard Liao {
1922d59fb285SBard Liao 	struct snd_soc_component *component = dai->component;
1923d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
1924d59fb285SBard Liao 	unsigned int len_1 = 0, len_2 = 0;
1925d59fb285SBard Liao 	int pre_div, frame_size;
1926d59fb285SBard Liao 
1927d59fb285SBard Liao 	rt5668->lrck[dai->id] = params_rate(params);
1928d59fb285SBard Liao 	pre_div = rl6231_get_clk_info(rt5668->sysclk, rt5668->lrck[dai->id]);
1929d59fb285SBard Liao 
1930d59fb285SBard Liao 	frame_size = snd_soc_params_to_frame_size(params);
1931d59fb285SBard Liao 	if (frame_size < 0) {
1932d59fb285SBard Liao 		dev_err(component->dev, "Unsupported frame size: %d\n",
1933d59fb285SBard Liao 			frame_size);
1934d59fb285SBard Liao 		return -EINVAL;
1935d59fb285SBard Liao 	}
1936d59fb285SBard Liao 
1937d59fb285SBard Liao 	dev_dbg(dai->dev, "lrck is %dHz and pre_div is %d for iis %d\n",
1938d59fb285SBard Liao 				rt5668->lrck[dai->id], pre_div, dai->id);
1939d59fb285SBard Liao 
1940d59fb285SBard Liao 	switch (params_width(params)) {
1941d59fb285SBard Liao 	case 16:
1942d59fb285SBard Liao 		break;
1943d59fb285SBard Liao 	case 20:
1944d59fb285SBard Liao 		len_1 |= RT5668_I2S1_DL_20;
1945d59fb285SBard Liao 		len_2 |= RT5668_I2S2_DL_20;
1946d59fb285SBard Liao 		break;
1947d59fb285SBard Liao 	case 24:
1948d59fb285SBard Liao 		len_1 |= RT5668_I2S1_DL_24;
1949d59fb285SBard Liao 		len_2 |= RT5668_I2S2_DL_24;
1950d59fb285SBard Liao 		break;
1951d59fb285SBard Liao 	case 32:
1952d59fb285SBard Liao 		len_1 |= RT5668_I2S1_DL_32;
1953d59fb285SBard Liao 		len_2 |= RT5668_I2S2_DL_24;
1954d59fb285SBard Liao 		break;
1955d59fb285SBard Liao 	case 8:
1956d59fb285SBard Liao 		len_1 |= RT5668_I2S2_DL_8;
1957d59fb285SBard Liao 		len_2 |= RT5668_I2S2_DL_8;
1958d59fb285SBard Liao 		break;
1959d59fb285SBard Liao 	default:
1960d59fb285SBard Liao 		return -EINVAL;
1961d59fb285SBard Liao 	}
1962d59fb285SBard Liao 
1963d59fb285SBard Liao 	switch (dai->id) {
1964d59fb285SBard Liao 	case RT5668_AIF1:
1965d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_I2S1_SDP,
1966d59fb285SBard Liao 			RT5668_I2S1_DL_MASK, len_1);
1967d59fb285SBard Liao 		if (rt5668->master[RT5668_AIF1]) {
1968d59fb285SBard Liao 			snd_soc_component_update_bits(component,
1969d59fb285SBard Liao 				RT5668_ADDA_CLK_1, RT5668_I2S_M_DIV_MASK,
1970d59fb285SBard Liao 				pre_div << RT5668_I2S_M_DIV_SFT);
1971d59fb285SBard Liao 		}
1972d59fb285SBard Liao 		if (params_channels(params) == 1) /* mono mode */
1973d59fb285SBard Liao 			snd_soc_component_update_bits(component,
1974d59fb285SBard Liao 				RT5668_I2S1_SDP, RT5668_I2S1_MONO_MASK,
1975d59fb285SBard Liao 				RT5668_I2S1_MONO_EN);
1976d59fb285SBard Liao 		else
1977d59fb285SBard Liao 			snd_soc_component_update_bits(component,
1978d59fb285SBard Liao 				RT5668_I2S1_SDP, RT5668_I2S1_MONO_MASK,
1979d59fb285SBard Liao 				RT5668_I2S1_MONO_DIS);
1980d59fb285SBard Liao 		break;
1981d59fb285SBard Liao 	case RT5668_AIF2:
1982d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_I2S2_SDP,
1983d59fb285SBard Liao 			RT5668_I2S2_DL_MASK, len_2);
1984d59fb285SBard Liao 		if (rt5668->master[RT5668_AIF2]) {
1985d59fb285SBard Liao 			snd_soc_component_update_bits(component,
1986d59fb285SBard Liao 				RT5668_I2S_M_CLK_CTRL_1, RT5668_I2S2_M_PD_MASK,
1987d59fb285SBard Liao 				pre_div << RT5668_I2S2_M_PD_SFT);
1988d59fb285SBard Liao 		}
1989d59fb285SBard Liao 		if (params_channels(params) == 1) /* mono mode */
1990d59fb285SBard Liao 			snd_soc_component_update_bits(component,
1991d59fb285SBard Liao 				RT5668_I2S2_SDP, RT5668_I2S2_MONO_MASK,
1992d59fb285SBard Liao 				RT5668_I2S2_MONO_EN);
1993d59fb285SBard Liao 		else
1994d59fb285SBard Liao 			snd_soc_component_update_bits(component,
1995d59fb285SBard Liao 				RT5668_I2S2_SDP, RT5668_I2S2_MONO_MASK,
1996d59fb285SBard Liao 				RT5668_I2S2_MONO_DIS);
1997d59fb285SBard Liao 		break;
1998d59fb285SBard Liao 	default:
1999d59fb285SBard Liao 		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
2000d59fb285SBard Liao 		return -EINVAL;
2001d59fb285SBard Liao 	}
2002d59fb285SBard Liao 
2003d59fb285SBard Liao 	return 0;
2004d59fb285SBard Liao }
2005d59fb285SBard Liao 
rt5668_set_dai_fmt(struct snd_soc_dai * dai,unsigned int fmt)2006d59fb285SBard Liao static int rt5668_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2007d59fb285SBard Liao {
2008d59fb285SBard Liao 	struct snd_soc_component *component = dai->component;
2009d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2010d59fb285SBard Liao 	unsigned int reg_val = 0, tdm_ctrl = 0;
2011d59fb285SBard Liao 
2012d59fb285SBard Liao 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2013d59fb285SBard Liao 	case SND_SOC_DAIFMT_CBM_CFM:
2014d59fb285SBard Liao 		rt5668->master[dai->id] = 1;
2015d59fb285SBard Liao 		break;
2016d59fb285SBard Liao 	case SND_SOC_DAIFMT_CBS_CFS:
2017d59fb285SBard Liao 		rt5668->master[dai->id] = 0;
2018d59fb285SBard Liao 		break;
2019d59fb285SBard Liao 	default:
2020d59fb285SBard Liao 		return -EINVAL;
2021d59fb285SBard Liao 	}
2022d59fb285SBard Liao 
2023d59fb285SBard Liao 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2024d59fb285SBard Liao 	case SND_SOC_DAIFMT_NB_NF:
2025d59fb285SBard Liao 		break;
2026d59fb285SBard Liao 	case SND_SOC_DAIFMT_IB_NF:
2027d59fb285SBard Liao 		reg_val |= RT5668_I2S_BP_INV;
2028d59fb285SBard Liao 		tdm_ctrl |= RT5668_TDM_S_BP_INV;
2029d59fb285SBard Liao 		break;
2030d59fb285SBard Liao 	case SND_SOC_DAIFMT_NB_IF:
2031d59fb285SBard Liao 		if (dai->id == RT5668_AIF1)
2032d59fb285SBard Liao 			tdm_ctrl |= RT5668_TDM_S_LP_INV | RT5668_TDM_M_BP_INV;
2033d59fb285SBard Liao 		else
2034d59fb285SBard Liao 			return -EINVAL;
2035d59fb285SBard Liao 		break;
2036d59fb285SBard Liao 	case SND_SOC_DAIFMT_IB_IF:
2037d59fb285SBard Liao 		if (dai->id == RT5668_AIF1)
2038d59fb285SBard Liao 			tdm_ctrl |= RT5668_TDM_S_BP_INV | RT5668_TDM_S_LP_INV |
2039d59fb285SBard Liao 				    RT5668_TDM_M_BP_INV | RT5668_TDM_M_LP_INV;
2040d59fb285SBard Liao 		else
2041d59fb285SBard Liao 			return -EINVAL;
2042d59fb285SBard Liao 		break;
2043d59fb285SBard Liao 	default:
2044d59fb285SBard Liao 		return -EINVAL;
2045d59fb285SBard Liao 	}
2046d59fb285SBard Liao 
2047d59fb285SBard Liao 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2048d59fb285SBard Liao 	case SND_SOC_DAIFMT_I2S:
2049d59fb285SBard Liao 		break;
2050d59fb285SBard Liao 	case SND_SOC_DAIFMT_LEFT_J:
2051d59fb285SBard Liao 		reg_val |= RT5668_I2S_DF_LEFT;
2052d59fb285SBard Liao 		tdm_ctrl |= RT5668_TDM_DF_LEFT;
2053d59fb285SBard Liao 		break;
2054d59fb285SBard Liao 	case SND_SOC_DAIFMT_DSP_A:
2055d59fb285SBard Liao 		reg_val |= RT5668_I2S_DF_PCM_A;
2056d59fb285SBard Liao 		tdm_ctrl |= RT5668_TDM_DF_PCM_A;
2057d59fb285SBard Liao 		break;
2058d59fb285SBard Liao 	case SND_SOC_DAIFMT_DSP_B:
2059d59fb285SBard Liao 		reg_val |= RT5668_I2S_DF_PCM_B;
2060d59fb285SBard Liao 		tdm_ctrl |= RT5668_TDM_DF_PCM_B;
2061d59fb285SBard Liao 		break;
2062d59fb285SBard Liao 	default:
2063d59fb285SBard Liao 		return -EINVAL;
2064d59fb285SBard Liao 	}
2065d59fb285SBard Liao 
2066d59fb285SBard Liao 	switch (dai->id) {
2067d59fb285SBard Liao 	case RT5668_AIF1:
2068d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_I2S1_SDP,
2069d59fb285SBard Liao 			RT5668_I2S_DF_MASK, reg_val);
2070d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_TDM_TCON_CTRL,
2071d59fb285SBard Liao 			RT5668_TDM_MS_MASK | RT5668_TDM_S_BP_MASK |
2072d59fb285SBard Liao 			RT5668_TDM_DF_MASK | RT5668_TDM_M_BP_MASK |
2073d59fb285SBard Liao 			RT5668_TDM_M_LP_MASK | RT5668_TDM_S_LP_MASK,
2074d59fb285SBard Liao 			tdm_ctrl | rt5668->master[dai->id]);
2075d59fb285SBard Liao 		break;
2076d59fb285SBard Liao 	case RT5668_AIF2:
2077d59fb285SBard Liao 		if (rt5668->master[dai->id] == 0)
2078d59fb285SBard Liao 			reg_val |= RT5668_I2S2_MS_S;
2079d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_I2S2_SDP,
2080d59fb285SBard Liao 			RT5668_I2S2_MS_MASK | RT5668_I2S_BP_MASK |
2081d59fb285SBard Liao 			RT5668_I2S_DF_MASK, reg_val);
2082d59fb285SBard Liao 		break;
2083d59fb285SBard Liao 	default:
2084d59fb285SBard Liao 		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
2085d59fb285SBard Liao 		return -EINVAL;
2086d59fb285SBard Liao 	}
2087d59fb285SBard Liao 	return 0;
2088d59fb285SBard Liao }
2089d59fb285SBard Liao 
rt5668_set_component_sysclk(struct snd_soc_component * component,int clk_id,int source,unsigned int freq,int dir)2090d59fb285SBard Liao static int rt5668_set_component_sysclk(struct snd_soc_component *component,
2091d59fb285SBard Liao 		int clk_id, int source, unsigned int freq, int dir)
2092d59fb285SBard Liao {
2093d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2094d59fb285SBard Liao 	unsigned int reg_val = 0, src = 0;
2095d59fb285SBard Liao 
2096d59fb285SBard Liao 	if (freq == rt5668->sysclk && clk_id == rt5668->sysclk_src)
2097d59fb285SBard Liao 		return 0;
2098d59fb285SBard Liao 
2099d59fb285SBard Liao 	switch (clk_id) {
2100d59fb285SBard Liao 	case RT5668_SCLK_S_MCLK:
2101d59fb285SBard Liao 		reg_val |= RT5668_SCLK_SRC_MCLK;
2102d59fb285SBard Liao 		src = RT5668_CLK_SRC_MCLK;
2103d59fb285SBard Liao 		break;
2104d59fb285SBard Liao 	case RT5668_SCLK_S_PLL1:
2105d59fb285SBard Liao 		reg_val |= RT5668_SCLK_SRC_PLL1;
2106d59fb285SBard Liao 		src = RT5668_CLK_SRC_PLL1;
2107d59fb285SBard Liao 		break;
2108d59fb285SBard Liao 	case RT5668_SCLK_S_PLL2:
2109d59fb285SBard Liao 		reg_val |= RT5668_SCLK_SRC_PLL2;
2110d59fb285SBard Liao 		src = RT5668_CLK_SRC_PLL2;
2111d59fb285SBard Liao 		break;
2112d59fb285SBard Liao 	case RT5668_SCLK_S_RCCLK:
2113d59fb285SBard Liao 		reg_val |= RT5668_SCLK_SRC_RCCLK;
2114d59fb285SBard Liao 		src = RT5668_CLK_SRC_RCCLK;
2115d59fb285SBard Liao 		break;
2116d59fb285SBard Liao 	default:
2117d59fb285SBard Liao 		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
2118d59fb285SBard Liao 		return -EINVAL;
2119d59fb285SBard Liao 	}
2120d59fb285SBard Liao 	snd_soc_component_update_bits(component, RT5668_GLB_CLK,
2121d59fb285SBard Liao 		RT5668_SCLK_SRC_MASK, reg_val);
2122d59fb285SBard Liao 
2123d59fb285SBard Liao 	if (rt5668->master[RT5668_AIF2]) {
2124d59fb285SBard Liao 		snd_soc_component_update_bits(component,
2125d59fb285SBard Liao 			RT5668_I2S_M_CLK_CTRL_1, RT5668_I2S2_SRC_MASK,
2126d59fb285SBard Liao 			src << RT5668_I2S2_SRC_SFT);
2127d59fb285SBard Liao 	}
2128d59fb285SBard Liao 
2129d59fb285SBard Liao 	rt5668->sysclk = freq;
2130d59fb285SBard Liao 	rt5668->sysclk_src = clk_id;
2131d59fb285SBard Liao 
2132d59fb285SBard Liao 	dev_dbg(component->dev, "Sysclk is %dHz and clock id is %d\n",
2133d59fb285SBard Liao 		freq, clk_id);
2134d59fb285SBard Liao 
2135d59fb285SBard Liao 	return 0;
2136d59fb285SBard Liao }
2137d59fb285SBard Liao 
rt5668_set_component_pll(struct snd_soc_component * component,int pll_id,int source,unsigned int freq_in,unsigned int freq_out)2138d59fb285SBard Liao static int rt5668_set_component_pll(struct snd_soc_component *component,
2139d59fb285SBard Liao 		int pll_id, int source, unsigned int freq_in,
2140d59fb285SBard Liao 		unsigned int freq_out)
2141d59fb285SBard Liao {
2142d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2143d59fb285SBard Liao 	struct rl6231_pll_code pll_code;
2144d59fb285SBard Liao 	int ret;
2145d59fb285SBard Liao 
2146d59fb285SBard Liao 	if (source == rt5668->pll_src && freq_in == rt5668->pll_in &&
2147d59fb285SBard Liao 	    freq_out == rt5668->pll_out)
2148d59fb285SBard Liao 		return 0;
2149d59fb285SBard Liao 
2150d59fb285SBard Liao 	if (!freq_in || !freq_out) {
2151d59fb285SBard Liao 		dev_dbg(component->dev, "PLL disabled\n");
2152d59fb285SBard Liao 
2153d59fb285SBard Liao 		rt5668->pll_in = 0;
2154d59fb285SBard Liao 		rt5668->pll_out = 0;
2155d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_GLB_CLK,
2156d59fb285SBard Liao 			RT5668_SCLK_SRC_MASK, RT5668_SCLK_SRC_MCLK);
2157d59fb285SBard Liao 		return 0;
2158d59fb285SBard Liao 	}
2159d59fb285SBard Liao 
2160d59fb285SBard Liao 	switch (source) {
2161d59fb285SBard Liao 	case RT5668_PLL1_S_MCLK:
2162d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_GLB_CLK,
2163d59fb285SBard Liao 			RT5668_PLL1_SRC_MASK, RT5668_PLL1_SRC_MCLK);
2164d59fb285SBard Liao 		break;
2165d59fb285SBard Liao 	case RT5668_PLL1_S_BCLK1:
2166d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_GLB_CLK,
2167d59fb285SBard Liao 				RT5668_PLL1_SRC_MASK, RT5668_PLL1_SRC_BCLK1);
2168d59fb285SBard Liao 		break;
2169d59fb285SBard Liao 	default:
2170d59fb285SBard Liao 		dev_err(component->dev, "Unknown PLL Source %d\n", source);
2171d59fb285SBard Liao 		return -EINVAL;
2172d59fb285SBard Liao 	}
2173d59fb285SBard Liao 
2174d59fb285SBard Liao 	ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
2175d59fb285SBard Liao 	if (ret < 0) {
2176a4db95b2SColin Ian King 		dev_err(component->dev, "Unsupported input clock %d\n", freq_in);
2177d59fb285SBard Liao 		return ret;
2178d59fb285SBard Liao 	}
2179d59fb285SBard Liao 
2180d59fb285SBard Liao 	dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
2181d59fb285SBard Liao 		pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
2182d59fb285SBard Liao 		pll_code.n_code, pll_code.k_code);
2183d59fb285SBard Liao 
2184d59fb285SBard Liao 	snd_soc_component_write(component, RT5668_PLL_CTRL_1,
2185d59fb285SBard Liao 		pll_code.n_code << RT5668_PLL_N_SFT | pll_code.k_code);
2186d59fb285SBard Liao 	snd_soc_component_write(component, RT5668_PLL_CTRL_2,
218717de6094SPierre-Louis Bossart 		((pll_code.m_bp ? 0 : pll_code.m_code) << RT5668_PLL_M_SFT) |
218817de6094SPierre-Louis Bossart 		(pll_code.m_bp << RT5668_PLL_M_BP_SFT));
2189d59fb285SBard Liao 
2190d59fb285SBard Liao 	rt5668->pll_in = freq_in;
2191d59fb285SBard Liao 	rt5668->pll_out = freq_out;
2192d59fb285SBard Liao 	rt5668->pll_src = source;
2193d59fb285SBard Liao 
2194d59fb285SBard Liao 	return 0;
2195d59fb285SBard Liao }
2196d59fb285SBard Liao 
rt5668_set_bclk_ratio(struct snd_soc_dai * dai,unsigned int ratio)2197d59fb285SBard Liao static int rt5668_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
2198d59fb285SBard Liao {
2199d59fb285SBard Liao 	struct snd_soc_component *component = dai->component;
2200d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2201d59fb285SBard Liao 
2202d59fb285SBard Liao 	rt5668->bclk[dai->id] = ratio;
2203d59fb285SBard Liao 
2204d59fb285SBard Liao 	switch (ratio) {
2205d59fb285SBard Liao 	case 64:
2206d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_ADDA_CLK_2,
2207d59fb285SBard Liao 			RT5668_I2S2_BCLK_MS2_MASK,
2208d59fb285SBard Liao 			RT5668_I2S2_BCLK_MS2_64);
2209d59fb285SBard Liao 		break;
2210d59fb285SBard Liao 	case 32:
2211d59fb285SBard Liao 		snd_soc_component_update_bits(component, RT5668_ADDA_CLK_2,
2212d59fb285SBard Liao 			RT5668_I2S2_BCLK_MS2_MASK,
2213d59fb285SBard Liao 			RT5668_I2S2_BCLK_MS2_32);
2214d59fb285SBard Liao 		break;
2215d59fb285SBard Liao 	default:
2216d59fb285SBard Liao 		dev_err(dai->dev, "Invalid bclk ratio %d\n", ratio);
2217d59fb285SBard Liao 		return -EINVAL;
2218d59fb285SBard Liao 	}
2219d59fb285SBard Liao 
2220d59fb285SBard Liao 	return 0;
2221d59fb285SBard Liao }
2222d59fb285SBard Liao 
rt5668_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)2223d59fb285SBard Liao static int rt5668_set_bias_level(struct snd_soc_component *component,
2224d59fb285SBard Liao 			enum snd_soc_bias_level level)
2225d59fb285SBard Liao {
2226d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2227d59fb285SBard Liao 
2228d59fb285SBard Liao 	switch (level) {
2229d59fb285SBard Liao 	case SND_SOC_BIAS_PREPARE:
2230d59fb285SBard Liao 		regmap_update_bits(rt5668->regmap, RT5668_PWR_ANLG_1,
2231d59fb285SBard Liao 			RT5668_PWR_MB | RT5668_PWR_BG,
2232d59fb285SBard Liao 			RT5668_PWR_MB | RT5668_PWR_BG);
2233d59fb285SBard Liao 		regmap_update_bits(rt5668->regmap, RT5668_PWR_DIG_1,
2234d59fb285SBard Liao 			RT5668_DIG_GATE_CTRL | RT5668_PWR_LDO,
2235d59fb285SBard Liao 			RT5668_DIG_GATE_CTRL | RT5668_PWR_LDO);
2236d59fb285SBard Liao 		break;
2237d59fb285SBard Liao 
2238d59fb285SBard Liao 	case SND_SOC_BIAS_STANDBY:
2239d59fb285SBard Liao 		regmap_update_bits(rt5668->regmap, RT5668_PWR_ANLG_1,
2240d59fb285SBard Liao 			RT5668_PWR_MB, RT5668_PWR_MB);
2241d59fb285SBard Liao 		regmap_update_bits(rt5668->regmap, RT5668_PWR_DIG_1,
2242d59fb285SBard Liao 			RT5668_DIG_GATE_CTRL, RT5668_DIG_GATE_CTRL);
2243d59fb285SBard Liao 		break;
2244d59fb285SBard Liao 	case SND_SOC_BIAS_OFF:
2245d59fb285SBard Liao 		regmap_update_bits(rt5668->regmap, RT5668_PWR_DIG_1,
2246d59fb285SBard Liao 			RT5668_DIG_GATE_CTRL | RT5668_PWR_LDO, 0);
2247d59fb285SBard Liao 		regmap_update_bits(rt5668->regmap, RT5668_PWR_ANLG_1,
2248d59fb285SBard Liao 			RT5668_PWR_MB | RT5668_PWR_BG, 0);
2249d59fb285SBard Liao 		break;
2250d59fb285SBard Liao 
2251d59fb285SBard Liao 	default:
2252d59fb285SBard Liao 		break;
2253d59fb285SBard Liao 	}
2254d59fb285SBard Liao 
2255d59fb285SBard Liao 	return 0;
2256d59fb285SBard Liao }
2257d59fb285SBard Liao 
rt5668_probe(struct snd_soc_component * component)2258d59fb285SBard Liao static int rt5668_probe(struct snd_soc_component *component)
2259d59fb285SBard Liao {
2260d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2261d59fb285SBard Liao 
2262d59fb285SBard Liao 	rt5668->component = component;
2263d59fb285SBard Liao 
2264d59fb285SBard Liao 	return 0;
2265d59fb285SBard Liao }
2266d59fb285SBard Liao 
rt5668_remove(struct snd_soc_component * component)2267d59fb285SBard Liao static void rt5668_remove(struct snd_soc_component *component)
2268d59fb285SBard Liao {
2269d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2270d59fb285SBard Liao 
2271d59fb285SBard Liao 	rt5668_reset(rt5668->regmap);
2272d59fb285SBard Liao }
2273d59fb285SBard Liao 
2274d59fb285SBard Liao #ifdef CONFIG_PM
rt5668_suspend(struct snd_soc_component * component)2275d59fb285SBard Liao static int rt5668_suspend(struct snd_soc_component *component)
2276d59fb285SBard Liao {
2277d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2278d59fb285SBard Liao 
2279d59fb285SBard Liao 	regcache_cache_only(rt5668->regmap, true);
2280d59fb285SBard Liao 	regcache_mark_dirty(rt5668->regmap);
2281d59fb285SBard Liao 	return 0;
2282d59fb285SBard Liao }
2283d59fb285SBard Liao 
rt5668_resume(struct snd_soc_component * component)2284d59fb285SBard Liao static int rt5668_resume(struct snd_soc_component *component)
2285d59fb285SBard Liao {
2286d59fb285SBard Liao 	struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2287d59fb285SBard Liao 
2288d59fb285SBard Liao 	regcache_cache_only(rt5668->regmap, false);
2289d59fb285SBard Liao 	regcache_sync(rt5668->regmap);
2290d59fb285SBard Liao 
2291d59fb285SBard Liao 	return 0;
2292d59fb285SBard Liao }
2293d59fb285SBard Liao #else
2294d59fb285SBard Liao #define rt5668_suspend NULL
2295d59fb285SBard Liao #define rt5668_resume NULL
2296d59fb285SBard Liao #endif
2297d59fb285SBard Liao 
2298d59fb285SBard Liao #define RT5668_STEREO_RATES SNDRV_PCM_RATE_8000_192000
2299d59fb285SBard Liao #define RT5668_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
2300d59fb285SBard Liao 		SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
2301d59fb285SBard Liao 
2302d59fb285SBard Liao static const struct snd_soc_dai_ops rt5668_aif1_dai_ops = {
2303d59fb285SBard Liao 	.hw_params = rt5668_hw_params,
2304d59fb285SBard Liao 	.set_fmt = rt5668_set_dai_fmt,
2305d59fb285SBard Liao 	.set_tdm_slot = rt5668_set_tdm_slot,
2306d59fb285SBard Liao };
2307d59fb285SBard Liao 
2308d59fb285SBard Liao static const struct snd_soc_dai_ops rt5668_aif2_dai_ops = {
2309d59fb285SBard Liao 	.hw_params = rt5668_hw_params,
2310d59fb285SBard Liao 	.set_fmt = rt5668_set_dai_fmt,
2311d59fb285SBard Liao 	.set_bclk_ratio = rt5668_set_bclk_ratio,
2312d59fb285SBard Liao };
2313d59fb285SBard Liao 
2314d59fb285SBard Liao static struct snd_soc_dai_driver rt5668_dai[] = {
2315d59fb285SBard Liao 	{
2316d59fb285SBard Liao 		.name = "rt5668-aif1",
2317d59fb285SBard Liao 		.id = RT5668_AIF1,
2318d59fb285SBard Liao 		.playback = {
2319d59fb285SBard Liao 			.stream_name = "AIF1 Playback",
2320d59fb285SBard Liao 			.channels_min = 1,
2321d59fb285SBard Liao 			.channels_max = 2,
2322d59fb285SBard Liao 			.rates = RT5668_STEREO_RATES,
2323d59fb285SBard Liao 			.formats = RT5668_FORMATS,
2324d59fb285SBard Liao 		},
2325d59fb285SBard Liao 		.capture = {
2326d59fb285SBard Liao 			.stream_name = "AIF1 Capture",
2327d59fb285SBard Liao 			.channels_min = 1,
2328d59fb285SBard Liao 			.channels_max = 2,
2329d59fb285SBard Liao 			.rates = RT5668_STEREO_RATES,
2330d59fb285SBard Liao 			.formats = RT5668_FORMATS,
2331d59fb285SBard Liao 		},
2332d59fb285SBard Liao 		.ops = &rt5668_aif1_dai_ops,
2333d59fb285SBard Liao 	},
2334d59fb285SBard Liao 	{
2335d59fb285SBard Liao 		.name = "rt5668-aif2",
2336d59fb285SBard Liao 		.id = RT5668_AIF2,
2337d59fb285SBard Liao 		.capture = {
2338d59fb285SBard Liao 			.stream_name = "AIF2 Capture",
2339d59fb285SBard Liao 			.channels_min = 1,
2340d59fb285SBard Liao 			.channels_max = 2,
2341d59fb285SBard Liao 			.rates = RT5668_STEREO_RATES,
2342d59fb285SBard Liao 			.formats = RT5668_FORMATS,
2343d59fb285SBard Liao 		},
2344d59fb285SBard Liao 		.ops = &rt5668_aif2_dai_ops,
2345d59fb285SBard Liao 	},
2346d59fb285SBard Liao };
2347d59fb285SBard Liao 
2348d59fb285SBard Liao static const struct snd_soc_component_driver soc_component_dev_rt5668 = {
2349d59fb285SBard Liao 	.probe = rt5668_probe,
2350d59fb285SBard Liao 	.remove = rt5668_remove,
2351d59fb285SBard Liao 	.suspend = rt5668_suspend,
2352d59fb285SBard Liao 	.resume = rt5668_resume,
2353d59fb285SBard Liao 	.set_bias_level = rt5668_set_bias_level,
2354d59fb285SBard Liao 	.controls = rt5668_snd_controls,
2355d59fb285SBard Liao 	.num_controls = ARRAY_SIZE(rt5668_snd_controls),
2356d59fb285SBard Liao 	.dapm_widgets = rt5668_dapm_widgets,
2357d59fb285SBard Liao 	.num_dapm_widgets = ARRAY_SIZE(rt5668_dapm_widgets),
2358d59fb285SBard Liao 	.dapm_routes = rt5668_dapm_routes,
2359d59fb285SBard Liao 	.num_dapm_routes = ARRAY_SIZE(rt5668_dapm_routes),
2360d59fb285SBard Liao 	.set_sysclk = rt5668_set_component_sysclk,
2361d59fb285SBard Liao 	.set_pll = rt5668_set_component_pll,
2362d59fb285SBard Liao 	.set_jack = rt5668_set_jack_detect,
2363d59fb285SBard Liao 	.use_pmdown_time	= 1,
2364d59fb285SBard Liao 	.endianness		= 1,
2365d59fb285SBard Liao };
2366d59fb285SBard Liao 
2367d59fb285SBard Liao static const struct regmap_config rt5668_regmap = {
2368d59fb285SBard Liao 	.reg_bits = 16,
2369d59fb285SBard Liao 	.val_bits = 16,
2370d59fb285SBard Liao 	.max_register = RT5668_I2C_MODE,
2371d59fb285SBard Liao 	.volatile_reg = rt5668_volatile_register,
2372d59fb285SBard Liao 	.readable_reg = rt5668_readable_register,
2373470cb1d9SMark Brown 	.cache_type = REGCACHE_MAPLE,
2374d59fb285SBard Liao 	.reg_defaults = rt5668_reg,
2375d59fb285SBard Liao 	.num_reg_defaults = ARRAY_SIZE(rt5668_reg),
23761c96a2f6SDavid Frey 	.use_single_read = true,
23771c96a2f6SDavid Frey 	.use_single_write = true,
2378d59fb285SBard Liao };
2379d59fb285SBard Liao 
2380d59fb285SBard Liao static const struct i2c_device_id rt5668_i2c_id[] = {
2381d59fb285SBard Liao 	{"rt5668b", 0},
2382d59fb285SBard Liao 	{}
2383d59fb285SBard Liao };
2384d59fb285SBard Liao MODULE_DEVICE_TABLE(i2c, rt5668_i2c_id);
2385d59fb285SBard Liao 
rt5668_parse_dt(struct rt5668_priv * rt5668,struct device * dev)2386d59fb285SBard Liao static int rt5668_parse_dt(struct rt5668_priv *rt5668, struct device *dev)
2387d59fb285SBard Liao {
2388d59fb285SBard Liao 
2389d59fb285SBard Liao 	of_property_read_u32(dev->of_node, "realtek,dmic1-data-pin",
2390d59fb285SBard Liao 		&rt5668->pdata.dmic1_data_pin);
2391d59fb285SBard Liao 	of_property_read_u32(dev->of_node, "realtek,dmic1-clk-pin",
2392d59fb285SBard Liao 		&rt5668->pdata.dmic1_clk_pin);
2393d59fb285SBard Liao 	of_property_read_u32(dev->of_node, "realtek,jd-src",
2394d59fb285SBard Liao 		&rt5668->pdata.jd_src);
2395d59fb285SBard Liao 
2396d59fb285SBard Liao 	return 0;
2397d59fb285SBard Liao }
2398d59fb285SBard Liao 
rt5668_calibrate(struct rt5668_priv * rt5668)2399d59fb285SBard Liao static void rt5668_calibrate(struct rt5668_priv *rt5668)
2400d59fb285SBard Liao {
2401d59fb285SBard Liao 	int value, count;
2402d59fb285SBard Liao 
2403d59fb285SBard Liao 	mutex_lock(&rt5668->calibrate_mutex);
2404d59fb285SBard Liao 
2405d59fb285SBard Liao 	rt5668_reset(rt5668->regmap);
2406d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_PWR_ANLG_1, 0xa2bf);
2407d59fb285SBard Liao 	usleep_range(15000, 20000);
2408d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_PWR_ANLG_1, 0xf2bf);
2409d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_MICBIAS_2, 0x0380);
2410d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_PWR_DIG_1, 0x8001);
2411d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_TEST_MODE_CTRL_1, 0x0000);
2412d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_STO1_DAC_MIXER, 0x2080);
2413d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_STO1_ADC_MIXER, 0x4040);
2414d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_DEPOP_1, 0x0069);
2415d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_CHOP_DAC, 0x3000);
2416d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_HP_CTRL_2, 0x6000);
2417d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_HP_CHARGE_PUMP_1, 0x0f26);
2418d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_CALIB_ADC_CTRL, 0x7f05);
2419d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_STO1_ADC_MIXER, 0x686c);
2420d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_CAL_REC, 0x0d0d);
2421d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_HP_CALIB_CTRL_9, 0x000f);
2422d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_PWR_DIG_1, 0x8d01);
2423d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_HP_CALIB_CTRL_2, 0x0321);
2424d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_HP_LOGIC_CTRL_2, 0x0004);
2425d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_HP_CALIB_CTRL_1, 0x7c00);
2426d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_HP_CALIB_CTRL_3, 0x06a1);
2427d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_A_DAC1_MUX, 0x0311);
2428d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_RESET_HPF_CTRL, 0x0000);
2429d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_ADC_STO1_HP_CTRL_1, 0x3320);
2430d59fb285SBard Liao 
2431d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_HP_CALIB_CTRL_1, 0xfc00);
2432d59fb285SBard Liao 
2433d59fb285SBard Liao 	for (count = 0; count < 60; count++) {
2434d59fb285SBard Liao 		regmap_read(rt5668->regmap, RT5668_HP_CALIB_STA_1, &value);
2435d59fb285SBard Liao 		if (!(value & 0x8000))
2436d59fb285SBard Liao 			break;
2437d59fb285SBard Liao 
2438d59fb285SBard Liao 		usleep_range(10000, 10005);
2439d59fb285SBard Liao 	}
2440d59fb285SBard Liao 
2441d59fb285SBard Liao 	if (count >= 60)
2442d59fb285SBard Liao 		pr_err("HP Calibration Failure\n");
2443d59fb285SBard Liao 
2444d59fb285SBard Liao 	/* restore settings */
2445d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_STO1_ADC_MIXER, 0xc0c4);
2446d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_PWR_DIG_1, 0x0000);
2447d59fb285SBard Liao 
2448d59fb285SBard Liao 	mutex_unlock(&rt5668->calibrate_mutex);
2449d59fb285SBard Liao 
2450d59fb285SBard Liao }
2451d59fb285SBard Liao 
rt5668_i2c_probe(struct i2c_client * i2c)245235b88858SStephen Kitt static int rt5668_i2c_probe(struct i2c_client *i2c)
2453d59fb285SBard Liao {
2454d59fb285SBard Liao 	struct rt5668_platform_data *pdata = dev_get_platdata(&i2c->dev);
2455d59fb285SBard Liao 	struct rt5668_priv *rt5668;
2456d59fb285SBard Liao 	int i, ret;
2457d59fb285SBard Liao 	unsigned int val;
2458d59fb285SBard Liao 
2459d59fb285SBard Liao 	rt5668 = devm_kzalloc(&i2c->dev, sizeof(struct rt5668_priv),
2460d59fb285SBard Liao 		GFP_KERNEL);
2461d59fb285SBard Liao 
2462d59fb285SBard Liao 	if (rt5668 == NULL)
2463d59fb285SBard Liao 		return -ENOMEM;
2464d59fb285SBard Liao 
2465d59fb285SBard Liao 	i2c_set_clientdata(i2c, rt5668);
2466d59fb285SBard Liao 
2467d59fb285SBard Liao 	if (pdata)
2468d59fb285SBard Liao 		rt5668->pdata = *pdata;
2469d59fb285SBard Liao 	else
2470d59fb285SBard Liao 		rt5668_parse_dt(rt5668, &i2c->dev);
2471d59fb285SBard Liao 
2472d59fb285SBard Liao 	rt5668->regmap = devm_regmap_init_i2c(i2c, &rt5668_regmap);
2473d59fb285SBard Liao 	if (IS_ERR(rt5668->regmap)) {
2474d59fb285SBard Liao 		ret = PTR_ERR(rt5668->regmap);
2475d59fb285SBard Liao 		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2476d59fb285SBard Liao 			ret);
2477d59fb285SBard Liao 		return ret;
2478d59fb285SBard Liao 	}
2479d59fb285SBard Liao 
2480d59fb285SBard Liao 	for (i = 0; i < ARRAY_SIZE(rt5668->supplies); i++)
2481d59fb285SBard Liao 		rt5668->supplies[i].supply = rt5668_supply_names[i];
2482d59fb285SBard Liao 
2483d59fb285SBard Liao 	ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(rt5668->supplies),
2484d59fb285SBard Liao 				      rt5668->supplies);
2485d59fb285SBard Liao 	if (ret != 0) {
2486d59fb285SBard Liao 		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
2487d59fb285SBard Liao 		return ret;
2488d59fb285SBard Liao 	}
2489d59fb285SBard Liao 
2490d59fb285SBard Liao 	ret = regulator_bulk_enable(ARRAY_SIZE(rt5668->supplies),
2491d59fb285SBard Liao 				    rt5668->supplies);
2492d59fb285SBard Liao 	if (ret != 0) {
2493d59fb285SBard Liao 		dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
2494d59fb285SBard Liao 		return ret;
2495d59fb285SBard Liao 	}
2496d59fb285SBard Liao 
2497*ab2a5d17SLinus Walleij 	rt5668->ldo1_en = devm_gpiod_get_optional(&i2c->dev,
2498*ab2a5d17SLinus Walleij 						  "realtek,ldo1-en",
2499*ab2a5d17SLinus Walleij 						  GPIOD_OUT_HIGH);
2500*ab2a5d17SLinus Walleij 	if (IS_ERR(rt5668->ldo1_en)) {
2501*ab2a5d17SLinus Walleij 		dev_err(&i2c->dev, "Fail gpio request ldo1_en\n");
2502*ab2a5d17SLinus Walleij 		return PTR_ERR(rt5668->ldo1_en);
2503d59fb285SBard Liao 	}
2504d59fb285SBard Liao 
2505d59fb285SBard Liao 	/* Sleep for 300 ms miniumum */
2506d59fb285SBard Liao 	usleep_range(300000, 350000);
2507d59fb285SBard Liao 
2508d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_I2C_MODE, 0x1);
2509d59fb285SBard Liao 	usleep_range(10000, 15000);
2510d59fb285SBard Liao 
2511d59fb285SBard Liao 	regmap_read(rt5668->regmap, RT5668_DEVICE_ID, &val);
2512d59fb285SBard Liao 	if (val != DEVICE_ID) {
2513d59fb285SBard Liao 		pr_err("Device with ID register %x is not rt5668\n", val);
2514d59fb285SBard Liao 		return -ENODEV;
2515d59fb285SBard Liao 	}
2516d59fb285SBard Liao 
2517d59fb285SBard Liao 	rt5668_reset(rt5668->regmap);
2518d59fb285SBard Liao 
2519d59fb285SBard Liao 	rt5668_calibrate(rt5668);
2520d59fb285SBard Liao 
2521d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_DEPOP_1, 0x0000);
2522d59fb285SBard Liao 
2523d59fb285SBard Liao 	/* DMIC pin*/
2524d59fb285SBard Liao 	if (rt5668->pdata.dmic1_data_pin != RT5668_DMIC1_NULL) {
2525d59fb285SBard Liao 		switch (rt5668->pdata.dmic1_data_pin) {
2526d59fb285SBard Liao 		case RT5668_DMIC1_DATA_GPIO2: /* share with LRCK2 */
2527d59fb285SBard Liao 			regmap_update_bits(rt5668->regmap, RT5668_DMIC_CTRL_1,
2528d59fb285SBard Liao 				RT5668_DMIC_1_DP_MASK, RT5668_DMIC_1_DP_GPIO2);
2529d59fb285SBard Liao 			regmap_update_bits(rt5668->regmap, RT5668_GPIO_CTRL_1,
2530d59fb285SBard Liao 				RT5668_GP2_PIN_MASK, RT5668_GP2_PIN_DMIC_SDA);
2531d59fb285SBard Liao 			break;
2532d59fb285SBard Liao 
2533d59fb285SBard Liao 		case RT5668_DMIC1_DATA_GPIO5: /* share with DACDAT1 */
2534d59fb285SBard Liao 			regmap_update_bits(rt5668->regmap, RT5668_DMIC_CTRL_1,
2535d59fb285SBard Liao 				RT5668_DMIC_1_DP_MASK, RT5668_DMIC_1_DP_GPIO5);
2536d59fb285SBard Liao 			regmap_update_bits(rt5668->regmap, RT5668_GPIO_CTRL_1,
2537d59fb285SBard Liao 				RT5668_GP5_PIN_MASK, RT5668_GP5_PIN_DMIC_SDA);
2538d59fb285SBard Liao 			break;
2539d59fb285SBard Liao 
2540d59fb285SBard Liao 		default:
2541d59fb285SBard Liao 			dev_dbg(&i2c->dev, "invalid DMIC_DAT pin\n");
2542d59fb285SBard Liao 			break;
2543d59fb285SBard Liao 		}
2544d59fb285SBard Liao 
2545d59fb285SBard Liao 		switch (rt5668->pdata.dmic1_clk_pin) {
2546d59fb285SBard Liao 		case RT5668_DMIC1_CLK_GPIO1: /* share with IRQ */
2547d59fb285SBard Liao 			regmap_update_bits(rt5668->regmap, RT5668_GPIO_CTRL_1,
2548d59fb285SBard Liao 				RT5668_GP1_PIN_MASK, RT5668_GP1_PIN_DMIC_CLK);
2549d59fb285SBard Liao 			break;
2550d59fb285SBard Liao 
2551d59fb285SBard Liao 		case RT5668_DMIC1_CLK_GPIO3: /* share with BCLK2 */
2552d59fb285SBard Liao 			regmap_update_bits(rt5668->regmap, RT5668_GPIO_CTRL_1,
2553d59fb285SBard Liao 				RT5668_GP3_PIN_MASK, RT5668_GP3_PIN_DMIC_CLK);
2554d59fb285SBard Liao 			break;
2555d59fb285SBard Liao 
2556d59fb285SBard Liao 		default:
2557d59fb285SBard Liao 			dev_dbg(&i2c->dev, "invalid DMIC_CLK pin\n");
2558d59fb285SBard Liao 			break;
2559d59fb285SBard Liao 		}
2560d59fb285SBard Liao 	}
2561d59fb285SBard Liao 
2562d59fb285SBard Liao 	regmap_update_bits(rt5668->regmap, RT5668_PWR_ANLG_1,
2563d59fb285SBard Liao 			RT5668_LDO1_DVO_MASK | RT5668_HP_DRIVER_MASK,
2564d59fb285SBard Liao 			RT5668_LDO1_DVO_14 | RT5668_HP_DRIVER_5X);
2565d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_MICBIAS_2, 0x0380);
2566d59fb285SBard Liao 	regmap_update_bits(rt5668->regmap, RT5668_GPIO_CTRL_1,
2567d59fb285SBard Liao 			RT5668_GP4_PIN_MASK | RT5668_GP5_PIN_MASK,
2568d59fb285SBard Liao 			RT5668_GP4_PIN_ADCDAT1 | RT5668_GP5_PIN_DACDAT1);
2569d59fb285SBard Liao 	regmap_write(rt5668->regmap, RT5668_TEST_MODE_CTRL_1, 0x0000);
2570d59fb285SBard Liao 
2571d59fb285SBard Liao 	INIT_DELAYED_WORK(&rt5668->jack_detect_work,
2572d59fb285SBard Liao 				rt5668_jack_detect_handler);
2573d59fb285SBard Liao 	INIT_DELAYED_WORK(&rt5668->jd_check_work,
2574d59fb285SBard Liao 				rt5668_jd_check_handler);
2575d59fb285SBard Liao 
2576d59fb285SBard Liao 	mutex_init(&rt5668->calibrate_mutex);
2577d59fb285SBard Liao 
2578d59fb285SBard Liao 	if (i2c->irq) {
2579d59fb285SBard Liao 		ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
2580d59fb285SBard Liao 			rt5668_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
2581d59fb285SBard Liao 			| IRQF_ONESHOT, "rt5668", rt5668);
2582d59fb285SBard Liao 		if (ret)
2583d59fb285SBard Liao 			dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
2584d59fb285SBard Liao 
2585d59fb285SBard Liao 	}
2586d59fb285SBard Liao 
25874fe1984eSKuninori Morimoto 	return devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_rt5668,
2588d59fb285SBard Liao 			rt5668_dai, ARRAY_SIZE(rt5668_dai));
2589d59fb285SBard Liao }
2590d59fb285SBard Liao 
rt5668_i2c_shutdown(struct i2c_client * client)2591d59fb285SBard Liao static void rt5668_i2c_shutdown(struct i2c_client *client)
2592d59fb285SBard Liao {
2593d59fb285SBard Liao 	struct rt5668_priv *rt5668 = i2c_get_clientdata(client);
2594d59fb285SBard Liao 
2595d59fb285SBard Liao 	rt5668_reset(rt5668->regmap);
2596d59fb285SBard Liao }
2597d59fb285SBard Liao 
2598d59fb285SBard Liao #ifdef CONFIG_OF
2599d59fb285SBard Liao static const struct of_device_id rt5668_of_match[] = {
2600d59fb285SBard Liao 	{.compatible = "realtek,rt5668b"},
2601d59fb285SBard Liao 	{},
2602d59fb285SBard Liao };
2603d59fb285SBard Liao MODULE_DEVICE_TABLE(of, rt5668_of_match);
2604d59fb285SBard Liao #endif
2605d59fb285SBard Liao 
2606d59fb285SBard Liao #ifdef CONFIG_ACPI
2607d59fb285SBard Liao static const struct acpi_device_id rt5668_acpi_match[] = {
2608d59fb285SBard Liao 	{"10EC5668", 0,},
2609d59fb285SBard Liao 	{},
2610d59fb285SBard Liao };
2611d59fb285SBard Liao MODULE_DEVICE_TABLE(acpi, rt5668_acpi_match);
2612d59fb285SBard Liao #endif
2613d59fb285SBard Liao 
2614d59fb285SBard Liao static struct i2c_driver rt5668_i2c_driver = {
2615d59fb285SBard Liao 	.driver = {
2616d59fb285SBard Liao 		.name = "rt5668b",
2617d59fb285SBard Liao 		.of_match_table = of_match_ptr(rt5668_of_match),
2618d59fb285SBard Liao 		.acpi_match_table = ACPI_PTR(rt5668_acpi_match),
2619d59fb285SBard Liao 	},
26209abcd240SUwe Kleine-König 	.probe = rt5668_i2c_probe,
2621d59fb285SBard Liao 	.shutdown = rt5668_i2c_shutdown,
2622d59fb285SBard Liao 	.id_table = rt5668_i2c_id,
2623d59fb285SBard Liao };
2624d59fb285SBard Liao module_i2c_driver(rt5668_i2c_driver);
2625d59fb285SBard Liao 
2626d59fb285SBard Liao MODULE_DESCRIPTION("ASoC RT5668B driver");
2627d59fb285SBard Liao MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
2628d59fb285SBard Liao MODULE_LICENSE("GPL v2");
2629