aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorBard Liao <bardliao@realtek.com>2014-06-20 02:41:13 -0400
committerMark Brown <broonie@linaro.org>2014-07-04 13:50:51 -0400
commit07cf7cbadb4d97a78be61119a406de8fe446467e (patch)
treef237a61b13b5fc250909720a30b3e5eb2ba62b72 /sound/soc/codecs
parent7171511eaec5bf23fb06078f59784a3a0626b38f (diff)
ASoC: add RT286 CODEC driver
This patch adds Realtek ALC286 codec driver. ALC286 is a dual mode codec, which can run as HD-A or I2S mode. It is controlled by HD-A verb commands via I2C protocol. The following is the I/O difference between ALC286 and general I2S codecs. 1. A HD-A verb command contains three parts, NID, VID, and PID. And an I2S command contains only two parts: address and data. 2. Not only the register address is written, but the read command also includes the entire write command. 3. rt286 uses different registers for read and write the same bits. We map verb command to regmap structure. However, we read most registers from cache to prevent the asymmetry read/write issue in rt286. Signed-off-by: Bard Liao <bardliao@realtek.com> Signed-off-by: Gustaw Lewandowski <gustaw.lewandowski@intel.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/rt286.c1208
-rw-r--r--sound/soc/codecs/rt286.h193
4 files changed, 1407 insertions, 0 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index cbfa1e18f651..115e5de7b7eb 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -74,6 +74,7 @@ config SND_SOC_ALL_CODECS
74 select SND_SOC_PCM3008 74 select SND_SOC_PCM3008
75 select SND_SOC_PCM512x_I2C if I2C 75 select SND_SOC_PCM512x_I2C if I2C
76 select SND_SOC_PCM512x_SPI if SPI_MASTER 76 select SND_SOC_PCM512x_SPI if SPI_MASTER
77 select SND_SOC_RT286 if I2C
77 select SND_SOC_RT5631 if I2C 78 select SND_SOC_RT5631 if I2C
78 select SND_SOC_RT5640 if I2C 79 select SND_SOC_RT5640 if I2C
79 select SND_SOC_RT5645 if I2C 80 select SND_SOC_RT5645 if I2C
@@ -449,6 +450,9 @@ config SND_SOC_RL6231
449 default m if SND_SOC_RT5645=m 450 default m if SND_SOC_RT5645=m
450 default m if SND_SOC_RT5651=m 451 default m if SND_SOC_RT5651=m
451 452
453config SND_SOC_RT286
454 tristate
455
452config SND_SOC_RT5631 456config SND_SOC_RT5631
453 tristate 457 tristate
454 458
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index be3377b8d73f..c39449a862b3 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -68,6 +68,7 @@ snd-soc-pcm512x-objs := pcm512x.o
68snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o 68snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
69snd-soc-pcm512x-spi-objs := pcm512x-spi.o 69snd-soc-pcm512x-spi-objs := pcm512x-spi.o
70snd-soc-rl6231-objs := rl6231.o 70snd-soc-rl6231-objs := rl6231.o
71snd-soc-rt286-objs := rt286.o
71snd-soc-rt5631-objs := rt5631.o 72snd-soc-rt5631-objs := rt5631.o
72snd-soc-rt5640-objs := rt5640.o 73snd-soc-rt5640-objs := rt5640.o
73snd-soc-rt5645-objs := rt5645.o 74snd-soc-rt5645-objs := rt5645.o
@@ -233,6 +234,7 @@ obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o
233obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o 234obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
234obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o 235obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
235obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o 236obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
237obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
236obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 238obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
237obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o 239obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
238obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o 240obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
new file mode 100644
index 000000000000..acfba9c74c52
--- /dev/null
+++ b/sound/soc/codecs/rt286.c
@@ -0,0 +1,1208 @@
1/*
2 * rt286.c -- RT286 ALSA SoC audio codec driver
3 *
4 * Copyright 2013 Realtek Semiconductor Corp.
5 * Author: Bard Liao <bardliao@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/init.h>
15#include <linux/delay.h>
16#include <linux/pm.h>
17#include <linux/i2c.h>
18#include <linux/platform_device.h>
19#include <linux/spi/spi.h>
20#include <linux/acpi.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28#include <sound/jack.h>
29#include <linux/workqueue.h>
30#include <sound/rt286.h>
31#include <sound/hda_verbs.h>
32
33#include "rt286.h"
34
35#define RT286_VENDOR_ID 0x10ec0286
36
37struct rt286_priv {
38 struct regmap *regmap;
39 struct snd_soc_codec *codec;
40 struct rt286_platform_data pdata;
41 struct i2c_client *i2c;
42 struct snd_soc_jack *jack;
43 struct delayed_work jack_detect_work;
44 int sys_clk;
45 struct reg_default *index_cache;
46};
47
48static struct reg_default rt286_index_def[] = {
49 { 0x01, 0xaaaa },
50 { 0x02, 0x8aaa },
51 { 0x03, 0x0002 },
52 { 0x04, 0xaf01 },
53 { 0x08, 0x000d },
54 { 0x09, 0xd810 },
55 { 0x0a, 0x0060 },
56 { 0x0b, 0x0000 },
57 { 0x0f, 0x0000 },
58 { 0x19, 0x0a17 },
59 { 0x20, 0x0020 },
60 { 0x33, 0x0208 },
61 { 0x49, 0x0004 },
62 { 0x4f, 0x50e9 },
63 { 0x50, 0x2c00 },
64 { 0x63, 0x2902 },
65};
66#define INDEX_CACHE_SIZE ARRAY_SIZE(rt286_index_def)
67
68static const struct reg_default rt286_reg[] = {
69 { 0x00170500, 0x00000400 },
70 { 0x00220000, 0x00000031 },
71 { 0x00239000, 0x0000007f },
72 { 0x0023a000, 0x0000007f },
73 { 0x00270500, 0x00000400 },
74 { 0x00370500, 0x00000400 },
75 { 0x00870500, 0x00000400 },
76 { 0x00920000, 0x00000031 },
77 { 0x00935000, 0x000000c3 },
78 { 0x00936000, 0x000000c3 },
79 { 0x00970500, 0x00000400 },
80 { 0x00b37000, 0x00000097 },
81 { 0x00b37200, 0x00000097 },
82 { 0x00b37300, 0x00000097 },
83 { 0x00c37000, 0x00000000 },
84 { 0x00c37100, 0x00000080 },
85 { 0x01270500, 0x00000400 },
86 { 0x01370500, 0x00000400 },
87 { 0x01371f00, 0x411111f0 },
88 { 0x01439000, 0x00000080 },
89 { 0x0143a000, 0x00000080 },
90 { 0x01470700, 0x00000000 },
91 { 0x01470500, 0x00000400 },
92 { 0x01470c00, 0x00000000 },
93 { 0x01470100, 0x00000000 },
94 { 0x01837000, 0x00000000 },
95 { 0x01870500, 0x00000400 },
96 { 0x02050000, 0x00000000 },
97 { 0x02139000, 0x00000080 },
98 { 0x0213a000, 0x00000080 },
99 { 0x02170100, 0x00000000 },
100 { 0x02170500, 0x00000400 },
101 { 0x02170700, 0x00000000 },
102 { 0x02270100, 0x00000000 },
103 { 0x02370100, 0x00000000 },
104 { 0x02040000, 0x00004002 },
105 { 0x01870700, 0x00000020 },
106 { 0x00830000, 0x000000c3 },
107 { 0x00930000, 0x000000c3 },
108 { 0x01270700, 0x00000000 },
109};
110
111static bool rt286_volatile_register(struct device *dev, unsigned int reg)
112{
113 switch (reg) {
114 case 0 ... 0xff:
115 case RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID):
116 case RT286_GET_HP_SENSE:
117 case RT286_GET_MIC1_SENSE:
118 case RT286_PROC_COEF:
119 return true;
120 default:
121 return false;
122 }
123
124
125}
126
127static bool rt286_readable_register(struct device *dev, unsigned int reg)
128{
129 switch (reg) {
130 case 0 ... 0xff:
131 case RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID):
132 case RT286_GET_HP_SENSE:
133 case RT286_GET_MIC1_SENSE:
134 case RT286_SET_AUDIO_POWER:
135 case RT286_SET_HPO_POWER:
136 case RT286_SET_SPK_POWER:
137 case RT286_SET_DMIC1_POWER:
138 case RT286_SPK_MUX:
139 case RT286_HPO_MUX:
140 case RT286_ADC0_MUX:
141 case RT286_ADC1_MUX:
142 case RT286_SET_MIC1:
143 case RT286_SET_PIN_HPO:
144 case RT286_SET_PIN_SPK:
145 case RT286_SET_PIN_DMIC1:
146 case RT286_SPK_EAPD:
147 case RT286_SET_AMP_GAIN_HPO:
148 case RT286_SET_DMIC2_DEFAULT:
149 case RT286_DACL_GAIN:
150 case RT286_DACR_GAIN:
151 case RT286_ADCL_GAIN:
152 case RT286_ADCR_GAIN:
153 case RT286_MIC_GAIN:
154 case RT286_SPOL_GAIN:
155 case RT286_SPOR_GAIN:
156 case RT286_HPOL_GAIN:
157 case RT286_HPOR_GAIN:
158 case RT286_F_DAC_SWITCH:
159 case RT286_F_RECMIX_SWITCH:
160 case RT286_REC_MIC_SWITCH:
161 case RT286_REC_I2S_SWITCH:
162 case RT286_REC_LINE_SWITCH:
163 case RT286_REC_BEEP_SWITCH:
164 case RT286_DAC_FORMAT:
165 case RT286_ADC_FORMAT:
166 case RT286_COEF_INDEX:
167 case RT286_PROC_COEF:
168 case RT286_SET_AMP_GAIN_ADC_IN1:
169 case RT286_SET_AMP_GAIN_ADC_IN2:
170 case RT286_SET_POWER(RT286_DAC_OUT1):
171 case RT286_SET_POWER(RT286_DAC_OUT2):
172 case RT286_SET_POWER(RT286_ADC_IN1):
173 case RT286_SET_POWER(RT286_ADC_IN2):
174 case RT286_SET_POWER(RT286_DMIC2):
175 case RT286_SET_POWER(RT286_MIC1):
176 return true;
177 default:
178 return false;
179 }
180}
181
182static int rt286_hw_write(void *context, unsigned int reg, unsigned int value)
183{
184 struct i2c_client *client = context;
185 struct rt286_priv *rt286 = i2c_get_clientdata(client);
186 u8 data[4];
187 int ret, i;
188
189 /*handle index registers*/
190 if (reg <= 0xff) {
191 rt286_hw_write(client, RT286_COEF_INDEX, reg);
192 reg = RT286_PROC_COEF;
193 for (i = 0; i < INDEX_CACHE_SIZE; i++) {
194 if (reg == rt286->index_cache[i].reg) {
195 rt286->index_cache[i].def = value;
196 break;
197 }
198
199 }
200 }
201
202 data[0] = (reg >> 24) & 0xff;
203 data[1] = (reg >> 16) & 0xff;
204 /*
205 * 4 bit VID: reg should be 0
206 * 12 bit VID: value should be 0
207 * So we use an OR operator to handle it rather than use if condition.
208 */
209 data[2] = ((reg >> 8) & 0xff) | ((value >> 8) & 0xff);
210 data[3] = value & 0xff;
211
212 ret = i2c_master_send(client, data, 4);
213
214 if (ret == 4)
215 return 0;
216 else
217 pr_err("ret=%d\n", ret);
218 if (ret < 0)
219 return ret;
220 else
221 return -EIO;
222}
223
224static int rt286_hw_read(void *context, unsigned int reg, unsigned int *value)
225{
226 struct i2c_client *client = context;
227 struct i2c_msg xfer[2];
228 int ret;
229 __be32 be_reg;
230 unsigned int index, vid, buf = 0x0;
231
232 /*handle index registers*/
233 if (reg <= 0xff) {
234 rt286_hw_write(client, RT286_COEF_INDEX, reg);
235 reg = RT286_PROC_COEF;
236 }
237
238 reg = reg | 0x80000;
239 vid = (reg >> 8) & 0xfff;
240
241 if (AC_VERB_GET_AMP_GAIN_MUTE == (vid & 0xf00)) {
242 index = (reg >> 8) & 0xf;
243 reg = (reg & ~0xf0f) | index;
244 }
245 be_reg = cpu_to_be32(reg);
246
247 /* Write register */
248 xfer[0].addr = client->addr;
249 xfer[0].flags = 0;
250 xfer[0].len = 4;
251 xfer[0].buf = (u8 *)&be_reg;
252
253 /* Read data */
254 xfer[1].addr = client->addr;
255 xfer[1].flags = I2C_M_RD;
256 xfer[1].len = 4;
257 xfer[1].buf = (u8 *)&buf;
258
259 ret = i2c_transfer(client->adapter, xfer, 2);
260 if (ret < 0)
261 return ret;
262 else if (ret != 2)
263 return -EIO;
264
265 *value = be32_to_cpu(buf);
266
267 return 0;
268}
269
270static void rt286_index_sync(struct snd_soc_codec *codec)
271{
272 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
273 int i;
274
275 for (i = 0; i < INDEX_CACHE_SIZE; i++) {
276 snd_soc_write(codec, rt286->index_cache[i].reg,
277 rt286->index_cache[i].def);
278 }
279}
280
281static int rt286_support_power_controls[] = {
282 RT286_DAC_OUT1,
283 RT286_DAC_OUT2,
284 RT286_ADC_IN1,
285 RT286_ADC_IN2,
286 RT286_MIC1,
287 RT286_DMIC1,
288 RT286_DMIC2,
289 RT286_SPK_OUT,
290 RT286_HP_OUT,
291};
292#define RT286_POWER_REG_LEN ARRAY_SIZE(rt286_support_power_controls)
293
294static int rt286_jack_detect(struct snd_soc_codec *codec, bool *hp, bool *mic)
295{
296 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
297 unsigned int val, buf;
298 int i;
299
300 *hp = false;
301 *mic = false;
302
303 if (rt286->pdata.cbj_en) {
304 buf = snd_soc_read(codec, RT286_GET_HP_SENSE);
305 *hp = buf & 0x80000000;
306 if (*hp) {
307 /* power on HV,VERF */
308 snd_soc_update_bits(codec,
309 RT286_POWER_CTRL1, 0x1001, 0x0);
310 /* power LDO1 */
311 snd_soc_update_bits(codec,
312 RT286_POWER_CTRL2, 0x4, 0x4);
313 snd_soc_write(codec, RT286_SET_MIC1, 0x24);
314 val = snd_soc_read(codec, RT286_CBJ_CTRL2);
315
316 msleep(200);
317 i = 40;
318 while (((val & 0x0800) == 0) && (i > 0)) {
319 val = snd_soc_read(codec,
320 RT286_CBJ_CTRL2);
321 i--;
322 msleep(20);
323 }
324
325 if (0x0400 == (val & 0x0700)) {
326 *mic = false;
327
328 snd_soc_write(codec,
329 RT286_SET_MIC1, 0x20);
330 /* power off HV,VERF */
331 snd_soc_update_bits(codec,
332 RT286_POWER_CTRL1, 0x1001, 0x1001);
333 snd_soc_update_bits(codec,
334 RT286_A_BIAS_CTRL3, 0xc000, 0x0000);
335 snd_soc_update_bits(codec,
336 RT286_CBJ_CTRL1, 0x0030, 0x0000);
337 snd_soc_update_bits(codec,
338 RT286_A_BIAS_CTRL2, 0xc000, 0x0000);
339 } else if ((0x0200 == (val & 0x0700)) ||
340 (0x0100 == (val & 0x0700))) {
341 *mic = true;
342 snd_soc_update_bits(codec,
343 RT286_A_BIAS_CTRL3, 0xc000, 0x8000);
344 snd_soc_update_bits(codec,
345 RT286_CBJ_CTRL1, 0x0030, 0x0020);
346 snd_soc_update_bits(codec,
347 RT286_A_BIAS_CTRL2, 0xc000, 0x8000);
348 } else {
349 *mic = false;
350 }
351
352 snd_soc_update_bits(codec,
353 RT286_MISC_CTRL1,
354 0x0060, 0x0000);
355 } else {
356 snd_soc_update_bits(codec,
357 RT286_MISC_CTRL1,
358 0x0060, 0x0020);
359 snd_soc_update_bits(codec,
360 RT286_A_BIAS_CTRL3,
361 0xc000, 0x8000);
362 snd_soc_update_bits(codec,
363 RT286_CBJ_CTRL1,
364 0x0030, 0x0020);
365 snd_soc_update_bits(codec,
366 RT286_A_BIAS_CTRL2,
367 0xc000, 0x8000);
368
369 *mic = false;
370 }
371 } else {
372 buf = snd_soc_read(codec, RT286_GET_HP_SENSE);
373 *hp = buf & 0x80000000;
374 buf = snd_soc_read(codec, RT286_GET_MIC1_SENSE);
375 *mic = buf & 0x80000000;
376 }
377
378 return 0;
379}
380
381static void rt286_jack_detect_work(struct work_struct *work)
382{
383 struct rt286_priv *rt286 =
384 container_of(work, struct rt286_priv, jack_detect_work.work);
385 int status = 0;
386 bool hp = false;
387 bool mic = false;
388
389 rt286_jack_detect(rt286->codec, &hp, &mic);
390
391 if (hp == true)
392 status |= SND_JACK_HEADPHONE;
393
394 if (mic == true)
395 status |= SND_JACK_MICROPHONE;
396
397 snd_soc_jack_report(rt286->jack, status,
398 SND_JACK_MICROPHONE | SND_JACK_HEADPHONE);
399}
400
401int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
402{
403 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
404
405 rt286->jack = jack;
406
407 /* Send an initial empty report */
408 snd_soc_jack_report(rt286->jack, 0,
409 SND_JACK_MICROPHONE | SND_JACK_HEADPHONE);
410
411 return 0;
412}
413EXPORT_SYMBOL_GPL(rt286_mic_detect);
414
415static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0);
416static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
417
418static const struct snd_kcontrol_new rt286_snd_controls[] = {
419 SOC_DOUBLE_R_TLV("DAC0 Playback Volume", RT286_DACL_GAIN,
420 RT286_DACR_GAIN, 0, 0x7f, 0, out_vol_tlv),
421 SOC_DOUBLE_R_TLV("ADC0 Capture Volume", RT286_ADCL_GAIN,
422 RT286_ADCR_GAIN, 0, 0x7f, 0, out_vol_tlv),
423 SOC_SINGLE_TLV("AMIC Volume", RT286_MIC_GAIN,
424 0, 0x3, 0, mic_vol_tlv),
425 SOC_DOUBLE_R("Speaker Playback Switch", RT286_SPOL_GAIN,
426 RT286_SPOR_GAIN, RT286_MUTE_SFT, 1, 1),
427};
428
429/* Digital Mixer */
430static const struct snd_kcontrol_new rt286_front_mix[] = {
431 SOC_DAPM_SINGLE("DAC Switch", RT286_F_DAC_SWITCH,
432 RT286_MUTE_SFT, 1, 1),
433 SOC_DAPM_SINGLE("RECMIX Switch", RT286_F_RECMIX_SWITCH,
434 RT286_MUTE_SFT, 1, 1),
435};
436
437/* Analog Input Mixer */
438static const struct snd_kcontrol_new rt286_rec_mix[] = {
439 SOC_DAPM_SINGLE("Mic1 Switch", RT286_REC_MIC_SWITCH,
440 RT286_MUTE_SFT, 1, 1),
441 SOC_DAPM_SINGLE("I2S Switch", RT286_REC_I2S_SWITCH,
442 RT286_MUTE_SFT, 1, 1),
443 SOC_DAPM_SINGLE("Line1 Switch", RT286_REC_LINE_SWITCH,
444 RT286_MUTE_SFT, 1, 1),
445 SOC_DAPM_SINGLE("Beep Switch", RT286_REC_BEEP_SWITCH,
446 RT286_MUTE_SFT, 1, 1),
447};
448
449static const struct snd_kcontrol_new spo_enable_control =
450 SOC_DAPM_SINGLE("Switch", RT286_SET_PIN_SPK,
451 RT286_SET_PIN_SFT, 1, 0);
452
453static const struct snd_kcontrol_new hpol_enable_control =
454 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT286_HPOL_GAIN,
455 RT286_MUTE_SFT, 1, 1);
456
457static const struct snd_kcontrol_new hpor_enable_control =
458 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT286_HPOR_GAIN,
459 RT286_MUTE_SFT, 1, 1);
460
461/* ADC0 source */
462static const char * const rt286_adc_src[] = {
463 "Mic", "RECMIX", "Dmic"
464};
465
466static const int rt286_adc_values[] = {
467 0, 4, 5,
468};
469
470static SOC_VALUE_ENUM_SINGLE_DECL(
471 rt286_adc0_enum, RT286_ADC0_MUX, RT286_ADC_SEL_SFT,
472 RT286_ADC_SEL_MASK, rt286_adc_src, rt286_adc_values);
473
474static const struct snd_kcontrol_new rt286_adc0_mux =
475 SOC_DAPM_ENUM("ADC 0 source", rt286_adc0_enum);
476
477static SOC_VALUE_ENUM_SINGLE_DECL(
478 rt286_adc1_enum, RT286_ADC1_MUX, RT286_ADC_SEL_SFT,
479 RT286_ADC_SEL_MASK, rt286_adc_src, rt286_adc_values);
480
481static const struct snd_kcontrol_new rt286_adc1_mux =
482 SOC_DAPM_ENUM("ADC 1 source", rt286_adc1_enum);
483
484static const char * const rt286_dac_src[] = {
485 "Front", "Surround"
486};
487/* HP-OUT source */
488static SOC_ENUM_SINGLE_DECL(rt286_hpo_enum, RT286_HPO_MUX,
489 0, rt286_dac_src);
490
491static const struct snd_kcontrol_new rt286_hpo_mux =
492SOC_DAPM_ENUM("HPO source", rt286_hpo_enum);
493
494/* SPK-OUT source */
495static SOC_ENUM_SINGLE_DECL(rt286_spo_enum, RT286_SPK_MUX,
496 0, rt286_dac_src);
497
498static const struct snd_kcontrol_new rt286_spo_mux =
499SOC_DAPM_ENUM("SPO source", rt286_spo_enum);
500
501static int rt286_spk_event(struct snd_soc_dapm_widget *w,
502 struct snd_kcontrol *kcontrol, int event)
503{
504 struct snd_soc_codec *codec = w->codec;
505
506 switch (event) {
507 case SND_SOC_DAPM_POST_PMU:
508 snd_soc_write(codec,
509 RT286_SPK_EAPD, RT286_SET_EAPD_HIGH);
510 break;
511 case SND_SOC_DAPM_PRE_PMD:
512 snd_soc_write(codec,
513 RT286_SPK_EAPD, RT286_SET_EAPD_LOW);
514 break;
515
516 default:
517 return 0;
518 }
519
520 return 0;
521}
522
523static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
524 struct snd_kcontrol *kcontrol, int event)
525{
526 struct snd_soc_codec *codec = w->codec;
527
528 switch (event) {
529 case SND_SOC_DAPM_POST_PMU:
530 snd_soc_write(codec, RT286_SET_PIN_DMIC1, 0x20);
531 break;
532 case SND_SOC_DAPM_PRE_PMD:
533 snd_soc_write(codec, RT286_SET_PIN_DMIC1, 0);
534 break;
535 default:
536 return 0;
537 }
538
539 return 0;
540}
541
542static int rt286_adc_event(struct snd_soc_dapm_widget *w,
543 struct snd_kcontrol *kcontrol, int event)
544{
545 struct snd_soc_codec *codec = w->codec;
546 unsigned int nid;
547
548 nid = (w->reg >> 20) & 0xff;
549
550 switch (event) {
551 case SND_SOC_DAPM_POST_PMU:
552 snd_soc_update_bits(codec,
553 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
554 0x7080, 0x7000);
555 break;
556 case SND_SOC_DAPM_PRE_PMD:
557 snd_soc_update_bits(codec,
558 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
559 0x7080, 0x7080);
560 break;
561 default:
562 return 0;
563 }
564
565 return 0;
566}
567
568static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = {
569 /* Input Lines */
570 SND_SOC_DAPM_INPUT("DMIC1 Pin"),
571 SND_SOC_DAPM_INPUT("DMIC2 Pin"),
572 SND_SOC_DAPM_INPUT("MIC1"),
573 SND_SOC_DAPM_INPUT("LINE1"),
574 SND_SOC_DAPM_INPUT("Beep"),
575
576 /* DMIC */
577 SND_SOC_DAPM_PGA_E("DMIC1", RT286_SET_POWER(RT286_DMIC1), 0, 1,
578 NULL, 0, rt286_set_dmic1_event,
579 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
580 SND_SOC_DAPM_PGA("DMIC2", RT286_SET_POWER(RT286_DMIC2), 0, 1,
581 NULL, 0),
582 SND_SOC_DAPM_SUPPLY("DMIC Receiver", SND_SOC_NOPM,
583 0, 0, NULL, 0),
584
585 /* REC Mixer */
586 SND_SOC_DAPM_MIXER("RECMIX", SND_SOC_NOPM, 0, 0,
587 rt286_rec_mix, ARRAY_SIZE(rt286_rec_mix)),
588
589 /* ADCs */
590 SND_SOC_DAPM_ADC("ADC 0", NULL, SND_SOC_NOPM, 0, 0),
591 SND_SOC_DAPM_ADC("ADC 1", NULL, SND_SOC_NOPM, 0, 0),
592
593 /* ADC Mux */
594 SND_SOC_DAPM_MUX_E("ADC 0 Mux", RT286_SET_POWER(RT286_ADC_IN1), 0, 1,
595 &rt286_adc0_mux, rt286_adc_event, SND_SOC_DAPM_PRE_PMD |
596 SND_SOC_DAPM_POST_PMU),
597 SND_SOC_DAPM_MUX_E("ADC 1 Mux", RT286_SET_POWER(RT286_ADC_IN2), 0, 1,
598 &rt286_adc1_mux, rt286_adc_event, SND_SOC_DAPM_PRE_PMD |
599 SND_SOC_DAPM_POST_PMU),
600
601 /* Audio Interface */
602 SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
603 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
604 SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
605 SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
606
607 /* Output Side */
608 /* DACs */
609 SND_SOC_DAPM_DAC("DAC 0", NULL, SND_SOC_NOPM, 0, 0),
610 SND_SOC_DAPM_DAC("DAC 1", NULL, SND_SOC_NOPM, 0, 0),
611
612 /* Output Mux */
613 SND_SOC_DAPM_MUX("SPK Mux", SND_SOC_NOPM, 0, 0, &rt286_spo_mux),
614 SND_SOC_DAPM_MUX("HPO Mux", SND_SOC_NOPM, 0, 0, &rt286_hpo_mux),
615
616 SND_SOC_DAPM_SUPPLY("HP Power", RT286_SET_PIN_HPO,
617 RT286_SET_PIN_SFT, 0, NULL, 0),
618
619 /* Output Mixer */
620 SND_SOC_DAPM_MIXER("Front", RT286_SET_POWER(RT286_DAC_OUT1), 0, 1,
621 rt286_front_mix, ARRAY_SIZE(rt286_front_mix)),
622 SND_SOC_DAPM_PGA("Surround", RT286_SET_POWER(RT286_DAC_OUT2), 0, 1,
623 NULL, 0),
624
625 /* Output Pga */
626 SND_SOC_DAPM_SWITCH_E("SPO", SND_SOC_NOPM, 0, 0,
627 &spo_enable_control, rt286_spk_event,
628 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
629 SND_SOC_DAPM_SWITCH("HPO L", SND_SOC_NOPM, 0, 0,
630 &hpol_enable_control),
631 SND_SOC_DAPM_SWITCH("HPO R", SND_SOC_NOPM, 0, 0,
632 &hpor_enable_control),
633
634 /* Output Lines */
635 SND_SOC_DAPM_OUTPUT("SPOL"),
636 SND_SOC_DAPM_OUTPUT("SPOR"),
637 SND_SOC_DAPM_OUTPUT("HPO Pin"),
638 SND_SOC_DAPM_OUTPUT("SPDIF"),
639};
640
641static const struct snd_soc_dapm_route rt286_dapm_routes[] = {
642 {"DMIC1", NULL, "DMIC1 Pin"},
643 {"DMIC2", NULL, "DMIC2 Pin"},
644 {"DMIC1", NULL, "DMIC Receiver"},
645 {"DMIC2", NULL, "DMIC Receiver"},
646
647 {"RECMIX", "Beep Switch", "Beep"},
648 {"RECMIX", "Line1 Switch", "LINE1"},
649 {"RECMIX", "Mic1 Switch", "MIC1"},
650
651 {"ADC 0 Mux", "Dmic", "DMIC1"},
652 {"ADC 0 Mux", "RECMIX", "RECMIX"},
653 {"ADC 0 Mux", "Mic", "MIC1"},
654 {"ADC 1 Mux", "Dmic", "DMIC2"},
655 {"ADC 1 Mux", "RECMIX", "RECMIX"},
656 {"ADC 1 Mux", "Mic", "MIC1"},
657
658 {"ADC 0", NULL, "ADC 0 Mux"},
659 {"ADC 1", NULL, "ADC 1 Mux"},
660
661 {"AIF1TX", NULL, "ADC 0"},
662 {"AIF2TX", NULL, "ADC 1"},
663
664 {"DAC 0", NULL, "AIF1RX"},
665 {"DAC 1", NULL, "AIF2RX"},
666
667 {"Front", "DAC Switch", "DAC 0"},
668 {"Front", "RECMIX Switch", "RECMIX"},
669
670 {"Surround", NULL, "DAC 1"},
671
672 {"SPK Mux", "Front", "Front"},
673 {"SPK Mux", "Surround", "Surround"},
674
675 {"HPO Mux", "Front", "Front"},
676 {"HPO Mux", "Surround", "Surround"},
677
678 {"SPO", "Switch", "SPK Mux"},
679 {"HPO L", "Switch", "HPO Mux"},
680 {"HPO R", "Switch", "HPO Mux"},
681 {"HPO L", NULL, "HP Power"},
682 {"HPO R", NULL, "HP Power"},
683
684 {"SPOL", NULL, "SPO"},
685 {"SPOR", NULL, "SPO"},
686 {"HPO Pin", NULL, "HPO L"},
687 {"HPO Pin", NULL, "HPO R"},
688};
689
690static int rt286_hw_params(struct snd_pcm_substream *substream,
691 struct snd_pcm_hw_params *params,
692 struct snd_soc_dai *dai)
693{
694 struct snd_soc_codec *codec = dai->codec;
695 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
696 unsigned int val = 0;
697 int d_len_code;
698
699 switch (params_rate(params)) {
700 /* bit 14 0:48K 1:44.1K */
701 case 44100:
702 val |= 0x4000;
703 break;
704 case 48000:
705 break;
706 default:
707 dev_err(codec->dev, "Unsupported sample rate %d\n",
708 params_rate(params));
709 return -EINVAL;
710 }
711 switch (rt286->sys_clk) {
712 case 12288000:
713 case 24576000:
714 if (params_rate(params) != 48000) {
715 dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
716 params_rate(params), rt286->sys_clk);
717 return -EINVAL;
718 }
719 break;
720 case 11289600:
721 case 22579200:
722 if (params_rate(params) != 44100) {
723 dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
724 params_rate(params), rt286->sys_clk);
725 return -EINVAL;
726 }
727 break;
728 }
729
730 if (params_channels(params) <= 16) {
731 /* bit 3:0 Number of Channel */
732 val |= (params_channels(params) - 1);
733 } else {
734 dev_err(codec->dev, "Unsupported channels %d\n",
735 params_channels(params));
736 return -EINVAL;
737 }
738
739 d_len_code = 0;
740 switch (params_width(params)) {
741 /* bit 6:4 Bits per Sample */
742 case 16:
743 d_len_code = 0;
744 val |= (0x1 << 4);
745 break;
746 case 32:
747 d_len_code = 2;
748 val |= (0x4 << 4);
749 break;
750 case 20:
751 d_len_code = 1;
752 val |= (0x2 << 4);
753 break;
754 case 24:
755 d_len_code = 2;
756 val |= (0x3 << 4);
757 break;
758 case 8:
759 d_len_code = 3;
760 break;
761 default:
762 return -EINVAL;
763 }
764
765 snd_soc_update_bits(codec,
766 RT286_I2S_CTRL1, 0x0018, d_len_code << 3);
767 dev_dbg(codec->dev, "format val = 0x%x\n", val);
768
769 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
770 snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x407f, val);
771 else
772 snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x407f, val);
773
774 return 0;
775}
776
777static int rt286_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
778{
779 struct snd_soc_codec *codec = dai->codec;
780
781 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
782 case SND_SOC_DAIFMT_CBM_CFM:
783 snd_soc_update_bits(codec,
784 RT286_I2S_CTRL1, 0x800, 0x800);
785 break;
786 case SND_SOC_DAIFMT_CBS_CFS:
787 snd_soc_update_bits(codec,
788 RT286_I2S_CTRL1, 0x800, 0x0);
789 break;
790 default:
791 return -EINVAL;
792 }
793
794 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
795 case SND_SOC_DAIFMT_I2S:
796 snd_soc_update_bits(codec,
797 RT286_I2S_CTRL1, 0x300, 0x0);
798 break;
799 case SND_SOC_DAIFMT_LEFT_J:
800 snd_soc_update_bits(codec,
801 RT286_I2S_CTRL1, 0x300, 0x1 << 8);
802 break;
803 case SND_SOC_DAIFMT_DSP_A:
804 snd_soc_update_bits(codec,
805 RT286_I2S_CTRL1, 0x300, 0x2 << 8);
806 break;
807 case SND_SOC_DAIFMT_DSP_B:
808 snd_soc_update_bits(codec,
809 RT286_I2S_CTRL1, 0x300, 0x3 << 8);
810 break;
811 default:
812 return -EINVAL;
813 }
814 /* bit 15 Stream Type 0:PCM 1:Non-PCM */
815 snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x8000, 0);
816 snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x8000, 0);
817
818 return 0;
819}
820
821static int rt286_set_dai_sysclk(struct snd_soc_dai *dai,
822 int clk_id, unsigned int freq, int dir)
823{
824 struct snd_soc_codec *codec = dai->codec;
825 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
826
827 dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq);
828
829 if (RT286_SCLK_S_MCLK == clk_id) {
830 snd_soc_update_bits(codec,
831 RT286_I2S_CTRL2, 0x0100, 0x0);
832 snd_soc_update_bits(codec,
833 RT286_PLL_CTRL1, 0x20, 0x20);
834 } else {
835 snd_soc_update_bits(codec,
836 RT286_I2S_CTRL2, 0x0100, 0x0100);
837 snd_soc_update_bits(codec,
838 RT286_PLL_CTRL, 0x4, 0x4);
839 snd_soc_update_bits(codec,
840 RT286_PLL_CTRL1, 0x20, 0x0);
841 }
842
843 switch (freq) {
844 case 19200000:
845 if (RT286_SCLK_S_MCLK == clk_id) {
846 dev_err(codec->dev, "Should not use MCLK\n");
847 return -EINVAL;
848 }
849 snd_soc_update_bits(codec,
850 RT286_I2S_CTRL2, 0x40, 0x40);
851 break;
852 case 24000000:
853 if (RT286_SCLK_S_MCLK == clk_id) {
854 dev_err(codec->dev, "Should not use MCLK\n");
855 return -EINVAL;
856 }
857 snd_soc_update_bits(codec,
858 RT286_I2S_CTRL2, 0x40, 0x0);
859 break;
860 case 12288000:
861 case 11289600:
862 snd_soc_update_bits(codec,
863 RT286_I2S_CTRL2, 0x8, 0x0);
864 snd_soc_update_bits(codec,
865 RT286_CLK_DIV, 0xfc1e, 0x0004);
866 break;
867 case 24576000:
868 case 22579200:
869 snd_soc_update_bits(codec,
870 RT286_I2S_CTRL2, 0x8, 0x8);
871 snd_soc_update_bits(codec,
872 RT286_CLK_DIV, 0xfc1e, 0x5406);
873 break;
874 default:
875 dev_err(codec->dev, "Unsupported system clock\n");
876 return -EINVAL;
877 }
878
879 rt286->sys_clk = freq;
880
881 return 0;
882}
883
884static int rt286_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
885{
886 struct snd_soc_codec *codec = dai->codec;
887
888 dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
889 if (50 == ratio)
890 snd_soc_update_bits(codec,
891 RT286_I2S_CTRL1, 0x1000, 0x1000);
892 else
893 snd_soc_update_bits(codec,
894 RT286_I2S_CTRL1, 0x1000, 0x0);
895
896
897 return 0;
898}
899
900static int rt286_set_bias_level(struct snd_soc_codec *codec,
901 enum snd_soc_bias_level level)
902{
903 switch (level) {
904 case SND_SOC_BIAS_PREPARE:
905 if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level)
906 snd_soc_write(codec,
907 RT286_SET_AUDIO_POWER, AC_PWRST_D0);
908 break;
909
910 case SND_SOC_BIAS_STANDBY:
911 snd_soc_write(codec,
912 RT286_SET_AUDIO_POWER, AC_PWRST_D3);
913 break;
914
915 default:
916 break;
917 }
918 codec->dapm.bias_level = level;
919
920 return 0;
921}
922
923static irqreturn_t rt286_irq(int irq, void *data)
924{
925 struct rt286_priv *rt286 = data;
926 bool hp = false;
927 bool mic = false;
928 int status = 0;
929
930 rt286_jack_detect(rt286->codec, &hp, &mic);
931
932 /* Clear IRQ */
933 snd_soc_update_bits(rt286->codec,
934 RT286_IRQ_CTRL, 0x1, 0x1);
935
936 if (hp == true)
937 status |= SND_JACK_HEADPHONE;
938
939 if (mic == true)
940 status |= SND_JACK_MICROPHONE;
941
942 snd_soc_jack_report(rt286->jack, status,
943 SND_JACK_MICROPHONE | SND_JACK_HEADPHONE);
944
945 pm_wakeup_event(&rt286->i2c->dev, 300);
946
947 return IRQ_HANDLED;
948}
949
950static int rt286_probe(struct snd_soc_codec *codec)
951{
952 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
953 int i, ret;
954
955 ret = snd_soc_read(codec,
956 RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID));
957 if (ret != RT286_VENDOR_ID) {
958 dev_err(codec->dev,
959 "Device with ID register %x is not rt286\n", ret);
960 return -ENODEV;
961 }
962
963 snd_soc_write(codec, RT286_SET_AUDIO_POWER, AC_PWRST_D3);
964
965 for (i = 0; i < RT286_POWER_REG_LEN; i++)
966 snd_soc_write(codec,
967 RT286_SET_POWER(rt286_support_power_controls[i]),
968 AC_PWRST_D1);
969
970 if (!rt286->pdata.cbj_en) {
971 snd_soc_write(codec, RT286_CBJ_CTRL2, 0x0000);
972 snd_soc_write(codec, RT286_MIC1_DET_CTRL, 0x0816);
973 snd_soc_write(codec, RT286_MISC_CTRL1, 0x0000);
974 snd_soc_update_bits(codec,
975 RT286_CBJ_CTRL1, 0xf000, 0xb000);
976 } else {
977 snd_soc_update_bits(codec,
978 RT286_CBJ_CTRL1, 0xf000, 0x5000);
979 }
980
981 mdelay(10);
982
983 if (!rt286->pdata.gpio2_en)
984 snd_soc_write(codec, RT286_SET_DMIC2_DEFAULT, 0x4000);
985 else
986 snd_soc_write(codec, RT286_SET_DMIC2_DEFAULT, 0);
987
988 mdelay(10);
989
990 /*Power down LDO2*/
991 snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x8, 0x0);
992
993 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
994 rt286->codec = codec;
995
996 rt286->i2c->irq = 0;
997 if (rt286->i2c->irq) {
998 snd_soc_update_bits(codec,
999 RT286_IRQ_CTRL, 0x2, 0x2);
1000
1001 INIT_DELAYED_WORK(&rt286->jack_detect_work,
1002 rt286_jack_detect_work);
1003 schedule_delayed_work(&rt286->jack_detect_work,
1004 msecs_to_jiffies(1250));
1005
1006 ret = request_threaded_irq(rt286->i2c->irq, NULL, rt286_irq,
1007 IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt286", rt286);
1008 if (ret != 0) {
1009 dev_err(codec->dev,
1010 "Failed to reguest IRQ: %d\n", ret);
1011 return ret;
1012 }
1013 }
1014
1015 return 0;
1016}
1017
1018static int rt286_remove(struct snd_soc_codec *codec)
1019{
1020 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
1021
1022 cancel_delayed_work_sync(&rt286->jack_detect_work);
1023
1024 return 0;
1025}
1026
1027#ifdef CONFIG_PM
1028static int rt286_suspend(struct snd_soc_codec *codec)
1029{
1030 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
1031
1032 regcache_cache_only(rt286->regmap, true);
1033 regcache_mark_dirty(rt286->regmap);
1034
1035 return 0;
1036}
1037
1038static int rt286_resume(struct snd_soc_codec *codec)
1039{
1040 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
1041
1042 regcache_cache_only(rt286->regmap, false);
1043 rt286_index_sync(codec);
1044 regcache_sync(rt286->regmap);
1045
1046 return 0;
1047}
1048#else
1049#define rt286_suspend NULL
1050#define rt286_resume NULL
1051#endif
1052
1053#define RT286_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
1054#define RT286_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1055 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
1056
1057static const struct snd_soc_dai_ops rt286_aif_dai_ops = {
1058 .hw_params = rt286_hw_params,
1059 .set_fmt = rt286_set_dai_fmt,
1060 .set_sysclk = rt286_set_dai_sysclk,
1061 .set_bclk_ratio = rt286_set_bclk_ratio,
1062};
1063
1064static struct snd_soc_dai_driver rt286_dai[] = {
1065 {
1066 .name = "rt286-aif1",
1067 .id = RT286_AIF1,
1068 .playback = {
1069 .stream_name = "AIF1 Playback",
1070 .channels_min = 1,
1071 .channels_max = 2,
1072 .rates = RT286_STEREO_RATES,
1073 .formats = RT286_FORMATS,
1074 },
1075 .capture = {
1076 .stream_name = "AIF1 Capture",
1077 .channels_min = 1,
1078 .channels_max = 2,
1079 .rates = RT286_STEREO_RATES,
1080 .formats = RT286_FORMATS,
1081 },
1082 .ops = &rt286_aif_dai_ops,
1083 .symmetric_rates = 1,
1084 },
1085 {
1086 .name = "rt286-aif2",
1087 .id = RT286_AIF2,
1088 .playback = {
1089 .stream_name = "AIF2 Playback",
1090 .channels_min = 1,
1091 .channels_max = 2,
1092 .rates = RT286_STEREO_RATES,
1093 .formats = RT286_FORMATS,
1094 },
1095 .capture = {
1096 .stream_name = "AIF2 Capture",
1097 .channels_min = 1,
1098 .channels_max = 2,
1099 .rates = RT286_STEREO_RATES,
1100 .formats = RT286_FORMATS,
1101 },
1102 .ops = &rt286_aif_dai_ops,
1103 .symmetric_rates = 1,
1104 },
1105
1106};
1107
1108static struct snd_soc_codec_driver soc_codec_dev_rt286 = {
1109 .probe = rt286_probe,
1110 .remove = rt286_remove,
1111 .suspend = rt286_suspend,
1112 .resume = rt286_resume,
1113 .set_bias_level = rt286_set_bias_level,
1114 .idle_bias_off = true,
1115 .controls = rt286_snd_controls,
1116 .num_controls = ARRAY_SIZE(rt286_snd_controls),
1117 .dapm_widgets = rt286_dapm_widgets,
1118 .num_dapm_widgets = ARRAY_SIZE(rt286_dapm_widgets),
1119 .dapm_routes = rt286_dapm_routes,
1120 .num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes),
1121};
1122
1123static const struct regmap_config rt286_regmap = {
1124 .reg_bits = 32,
1125 .val_bits = 32,
1126 .max_register = 0x02370100,
1127 .volatile_reg = rt286_volatile_register,
1128 .readable_reg = rt286_readable_register,
1129 .reg_write = rt286_hw_write,
1130 .reg_read = rt286_hw_read,
1131 .cache_type = REGCACHE_RBTREE,
1132 .reg_defaults = rt286_reg,
1133 .num_reg_defaults = ARRAY_SIZE(rt286_reg),
1134};
1135
1136static const struct i2c_device_id rt286_i2c_id[] = {
1137 {"rt286", 0},
1138 {}
1139};
1140MODULE_DEVICE_TABLE(i2c, rt286_i2c_id);
1141
1142static const struct acpi_device_id rt286_acpi_match[] = {
1143 { "INT343A", 0 },
1144 {},
1145};
1146MODULE_DEVICE_TABLE(acpi, rt286_acpi_match);
1147
1148static int rt286_i2c_probe(struct i2c_client *i2c,
1149 const struct i2c_device_id *id)
1150{
1151 struct rt286_platform_data *pdata = dev_get_platdata(&i2c->dev);
1152 struct rt286_priv *rt286;
1153 int ret;
1154
1155 rt286 = devm_kzalloc(&i2c->dev, sizeof(*rt286),
1156 GFP_KERNEL);
1157 if (NULL == rt286)
1158 return -ENOMEM;
1159
1160 rt286->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt286_regmap);
1161 if (IS_ERR(rt286->regmap)) {
1162 ret = PTR_ERR(rt286->regmap);
1163 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1164 ret);
1165 return ret;
1166 }
1167
1168 rt286->index_cache = rt286_index_def;
1169 rt286->i2c = i2c;
1170 i2c_set_clientdata(i2c, rt286);
1171
1172 if (pdata)
1173 rt286->pdata = *pdata;
1174
1175 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt286,
1176 rt286_dai, ARRAY_SIZE(rt286_dai));
1177
1178 return ret;
1179}
1180
1181static int rt286_i2c_remove(struct i2c_client *i2c)
1182{
1183 struct rt286_priv *rt286 = i2c_get_clientdata(i2c);
1184
1185 if (i2c->irq)
1186 free_irq(i2c->irq, rt286);
1187 snd_soc_unregister_codec(&i2c->dev);
1188
1189 return 0;
1190}
1191
1192
1193struct i2c_driver rt286_i2c_driver = {
1194 .driver = {
1195 .name = "rt286",
1196 .owner = THIS_MODULE,
1197 .acpi_match_table = ACPI_PTR(rt286_acpi_match),
1198 },
1199 .probe = rt286_i2c_probe,
1200 .remove = rt286_i2c_remove,
1201 .id_table = rt286_i2c_id,
1202};
1203
1204module_i2c_driver(rt286_i2c_driver);
1205
1206MODULE_DESCRIPTION("ASoC RT286 driver");
1207MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
1208MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/rt286.h b/sound/soc/codecs/rt286.h
new file mode 100644
index 000000000000..21c570f88e9b
--- /dev/null
+++ b/sound/soc/codecs/rt286.h
@@ -0,0 +1,193 @@
1/*
2 * rt286.h -- RT286 ALSA SoC audio driver
3 *
4 * Copyright 2011 Realtek Microelectronics
5 * Author: Johnny Hsu <johnnyhsu@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __RT286_H__
13#define __RT286_H__
14
15#define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D)
16
17#define RT286_AUDIO_FUNCTION_GROUP 0x01
18#define RT286_DAC_OUT1 0x02
19#define RT286_DAC_OUT2 0x03
20#define RT286_ADC_IN1 0x09
21#define RT286_ADC_IN2 0x08
22#define RT286_MIXER_IN 0x0b
23#define RT286_MIXER_OUT1 0x0c
24#define RT286_MIXER_OUT2 0x0d
25#define RT286_DMIC1 0x12
26#define RT286_DMIC2 0x13
27#define RT286_SPK_OUT 0x14
28#define RT286_MIC1 0x18
29#define RT286_LINE1 0x1a
30#define RT286_BEEP 0x1d
31#define RT286_SPDIF 0x1e
32#define RT286_VENDOR_REGISTERS 0x20
33#define RT286_HP_OUT 0x21
34#define RT286_MIXER_IN1 0x22
35#define RT286_MIXER_IN2 0x23
36
37#define RT286_SET_PIN_SFT 6
38#define RT286_SET_PIN_ENABLE 0x40
39#define RT286_SET_PIN_DISABLE 0
40#define RT286_SET_EAPD_HIGH 0x2
41#define RT286_SET_EAPD_LOW 0
42
43#define RT286_MUTE_SFT 7
44
45/* Verb commands */
46#define RT286_GET_PARAM(NID, PARAM) VERB_CMD(AC_VERB_PARAMETERS, NID, PARAM)
47#define RT286_SET_POWER(NID) VERB_CMD(AC_VERB_SET_POWER_STATE, NID, 0)
48#define RT286_SET_AUDIO_POWER RT286_SET_POWER(RT286_AUDIO_FUNCTION_GROUP)
49#define RT286_SET_HPO_POWER RT286_SET_POWER(RT286_HP_OUT)
50#define RT286_SET_SPK_POWER RT286_SET_POWER(RT286_SPK_OUT)
51#define RT286_SET_DMIC1_POWER RT286_SET_POWER(RT286_DMIC1)
52#define RT286_SPK_MUX\
53 VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT286_SPK_OUT, 0)
54#define RT286_HPO_MUX\
55 VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT286_HP_OUT, 0)
56#define RT286_ADC0_MUX\
57 VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT286_MIXER_IN1, 0)
58#define RT286_ADC1_MUX\
59 VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT286_MIXER_IN2, 0)
60#define RT286_SET_MIC1\
61 VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT286_MIC1, 0)
62#define RT286_SET_PIN_HPO\
63 VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT286_HP_OUT, 0)
64#define RT286_SET_PIN_SPK\
65 VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT286_SPK_OUT, 0)
66#define RT286_SET_PIN_DMIC1\
67 VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT286_DMIC1, 0)
68#define RT286_SPK_EAPD\
69 VERB_CMD(AC_VERB_SET_EAPD_BTLENABLE, RT286_SPK_OUT, 0)
70#define RT286_SET_AMP_GAIN_HPO\
71 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_HP_OUT, 0)
72#define RT286_SET_AMP_GAIN_ADC_IN1\
73 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_ADC_IN1, 0)
74#define RT286_SET_AMP_GAIN_ADC_IN2\
75 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_ADC_IN2, 0)
76#define RT286_GET_HP_SENSE\
77 VERB_CMD(AC_VERB_GET_PIN_SENSE, RT286_HP_OUT, 0)
78#define RT286_GET_MIC1_SENSE\
79 VERB_CMD(AC_VERB_GET_PIN_SENSE, RT286_MIC1, 0)
80#define RT286_SET_DMIC2_DEFAULT\
81 VERB_CMD(AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, RT286_DMIC2, 0)
82#define RT286_DACL_GAIN\
83 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_DAC_OUT1, 0xa000)
84#define RT286_DACR_GAIN\
85 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_DAC_OUT1, 0x9000)
86#define RT286_ADCL_GAIN\
87 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_ADC_IN1, 0x6000)
88#define RT286_ADCR_GAIN\
89 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_ADC_IN1, 0x5000)
90#define RT286_MIC_GAIN\
91 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIC1, 0x7000)
92#define RT286_SPOL_GAIN\
93 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_SPK_OUT, 0xa000)
94#define RT286_SPOR_GAIN\
95 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_SPK_OUT, 0x9000)
96#define RT286_HPOL_GAIN\
97 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_HP_OUT, 0xa000)
98#define RT286_HPOR_GAIN\
99 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_HP_OUT, 0x9000)
100#define RT286_F_DAC_SWITCH\
101 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIXER_OUT1, 0x7000)
102#define RT286_F_RECMIX_SWITCH\
103 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIXER_OUT1, 0x7100)
104#define RT286_REC_MIC_SWITCH\
105 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIXER_IN, 0x7000)
106#define RT286_REC_I2S_SWITCH\
107 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIXER_IN, 0x7100)
108#define RT286_REC_LINE_SWITCH\
109 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIXER_IN, 0x7200)
110#define RT286_REC_BEEP_SWITCH\
111 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIXER_IN, 0x7300)
112#define RT286_DAC_FORMAT\
113 VERB_CMD(AC_VERB_SET_STREAM_FORMAT, RT286_DAC_OUT1, 0)
114#define RT286_ADC_FORMAT\
115 VERB_CMD(AC_VERB_SET_STREAM_FORMAT, RT286_ADC_IN1, 0)
116#define RT286_COEF_INDEX\
117 VERB_CMD(AC_VERB_SET_COEF_INDEX, RT286_VENDOR_REGISTERS, 0)
118#define RT286_PROC_COEF\
119 VERB_CMD(AC_VERB_SET_PROC_COEF, RT286_VENDOR_REGISTERS, 0)
120
121/* Index registers */
122#define RT286_A_BIAS_CTRL1 0x01
123#define RT286_A_BIAS_CTRL2 0x02
124#define RT286_POWER_CTRL1 0x03
125#define RT286_A_BIAS_CTRL3 0x04
126#define RT286_POWER_CTRL2 0x08
127#define RT286_I2S_CTRL1 0x09
128#define RT286_I2S_CTRL2 0x0a
129#define RT286_CLK_DIV 0x0b
130#define RT286_POWER_CTRL3 0x0f
131#define RT286_MIC1_DET_CTRL 0x19
132#define RT286_MISC_CTRL1 0x20
133#define RT286_IRQ_CTRL 0x33
134#define RT286_PLL_CTRL1 0x49
135#define RT286_CBJ_CTRL1 0x4f
136#define RT286_CBJ_CTRL2 0x50
137#define RT286_PLL_CTRL 0x63
138
139/* SPDIF (0x06) */
140#define RT286_SPDIF_SEL_SFT 0
141#define RT286_SPDIF_SEL_PCM0 0
142#define RT286_SPDIF_SEL_PCM1 1
143#define RT286_SPDIF_SEL_SPOUT 2
144#define RT286_SPDIF_SEL_PP 3
145
146/* RECMIX (0x0b) */
147#define RT286_M_REC_BEEP_SFT 0
148#define RT286_M_REC_LINE1_SFT 1
149#define RT286_M_REC_MIC1_SFT 2
150#define RT286_M_REC_I2S_SFT 3
151
152/* Front (0x0c) */
153#define RT286_M_FRONT_DAC_SFT 0
154#define RT286_M_FRONT_REC_SFT 1
155
156/* SPK-OUT (0x14) */
157#define RT286_M_SPK_MUX_SFT 14
158#define RT286_SPK_SEL_MASK 0x1
159#define RT286_SPK_SEL_SFT 0
160#define RT286_SPK_SEL_F 0
161#define RT286_SPK_SEL_S 1
162
163/* HP-OUT (0x21) */
164#define RT286_M_HP_MUX_SFT 14
165#define RT286_HP_SEL_MASK 0x1
166#define RT286_HP_SEL_SFT 0
167#define RT286_HP_SEL_F 0
168#define RT286_HP_SEL_S 1
169
170/* ADC (0x22) (0x23) */
171#define RT286_ADC_SEL_MASK 0x7
172#define RT286_ADC_SEL_SFT 0
173#define RT286_ADC_SEL_SURR 0
174#define RT286_ADC_SEL_FRONT 1
175#define RT286_ADC_SEL_DMIC 2
176#define RT286_ADC_SEL_BEEP 4
177#define RT286_ADC_SEL_LINE1 5
178#define RT286_ADC_SEL_I2S 6
179#define RT286_ADC_SEL_MIC1 7
180
181#define RT286_SCLK_S_MCLK 0
182#define RT286_SCLK_S_PLL 1
183
184enum {
185 RT286_AIF1,
186 RT286_AIF2,
187 RT286_AIFS,
188};
189
190int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
191
192#endif /* __RT286_H__ */
193