aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/rt286.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/rt286.c')
-rw-r--r--sound/soc/codecs/rt286.c231
1 files changed, 172 insertions, 59 deletions
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index 4aa555cbcca8..2cd4fe463102 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -17,6 +17,7 @@
17#include <linux/i2c.h> 17#include <linux/i2c.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/spi/spi.h> 19#include <linux/spi/spi.h>
20#include <linux/dmi.h>
20#include <linux/acpi.h> 21#include <linux/acpi.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
@@ -36,11 +37,13 @@
36 37
37struct rt286_priv { 38struct rt286_priv {
38 struct regmap *regmap; 39 struct regmap *regmap;
40 struct snd_soc_codec *codec;
39 struct rt286_platform_data pdata; 41 struct rt286_platform_data pdata;
40 struct i2c_client *i2c; 42 struct i2c_client *i2c;
41 struct snd_soc_jack *jack; 43 struct snd_soc_jack *jack;
42 struct delayed_work jack_detect_work; 44 struct delayed_work jack_detect_work;
43 int sys_clk; 45 int sys_clk;
46 int clk_id;
44 struct reg_default *index_cache; 47 struct reg_default *index_cache;
45}; 48};
46 49
@@ -188,7 +191,7 @@ static int rt286_hw_write(void *context, unsigned int reg, unsigned int value)
188 u8 data[4]; 191 u8 data[4];
189 int ret, i; 192 int ret, i;
190 193
191 /*handle index registers*/ 194 /* handle index registers */
192 if (reg <= 0xff) { 195 if (reg <= 0xff) {
193 rt286_hw_write(client, RT286_COEF_INDEX, reg); 196 rt286_hw_write(client, RT286_COEF_INDEX, reg);
194 for (i = 0; i < INDEX_CACHE_SIZE; i++) { 197 for (i = 0; i < INDEX_CACHE_SIZE; i++) {
@@ -231,7 +234,7 @@ static int rt286_hw_read(void *context, unsigned int reg, unsigned int *value)
231 __be32 be_reg; 234 __be32 be_reg;
232 unsigned int index, vid, buf = 0x0; 235 unsigned int index, vid, buf = 0x0;
233 236
234 /*handle index registers*/ 237 /* handle index registers */
235 if (reg <= 0xff) { 238 if (reg <= 0xff) {
236 rt286_hw_write(client, RT286_COEF_INDEX, reg); 239 rt286_hw_write(client, RT286_COEF_INDEX, reg);
237 reg = RT286_PROC_COEF; 240 reg = RT286_PROC_COEF;
@@ -298,7 +301,6 @@ static int rt286_support_power_controls[] = {
298static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) 301static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
299{ 302{
300 unsigned int val, buf; 303 unsigned int val, buf;
301 int i;
302 304
303 *hp = false; 305 *hp = false;
304 *mic = false; 306 *mic = false;
@@ -309,67 +311,44 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
309 if (*hp) { 311 if (*hp) {
310 /* power on HV,VERF */ 312 /* power on HV,VERF */
311 regmap_update_bits(rt286->regmap, 313 regmap_update_bits(rt286->regmap,
312 RT286_POWER_CTRL1, 0x1001, 0x0); 314 RT286_DC_GAIN, 0x200, 0x200);
315
316 snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
317 "HV");
318 snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
319 "VREF");
313 /* power LDO1 */ 320 /* power LDO1 */
314 regmap_update_bits(rt286->regmap, 321 snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
315 RT286_POWER_CTRL2, 0x4, 0x4); 322 "LDO1");
316 regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24); 323 snd_soc_dapm_sync(&rt286->codec->dapm);
317 regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val);
318 324
319 msleep(200); 325 regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24);
320 i = 40; 326 msleep(50);
321 while (((val & 0x0800) == 0) && (i > 0)) {
322 regmap_read(rt286->regmap,
323 RT286_CBJ_CTRL2, &val);
324 i--;
325 msleep(20);
326 }
327 327
328 if (0x0400 == (val & 0x0700)) { 328 regmap_update_bits(rt286->regmap,
329 *mic = false; 329 RT286_CBJ_CTRL1, 0xfcc0, 0xd400);
330 msleep(300);
331 regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val);
330 332
331 regmap_write(rt286->regmap, 333 if (0x0070 == (val & 0x0070)) {
332 RT286_SET_MIC1, 0x20);
333 /* power off HV,VERF */
334 regmap_update_bits(rt286->regmap,
335 RT286_POWER_CTRL1, 0x1001, 0x1001);
336 regmap_update_bits(rt286->regmap,
337 RT286_A_BIAS_CTRL3, 0xc000, 0x0000);
338 regmap_update_bits(rt286->regmap,
339 RT286_CBJ_CTRL1, 0x0030, 0x0000);
340 regmap_update_bits(rt286->regmap,
341 RT286_A_BIAS_CTRL2, 0xc000, 0x0000);
342 } else if ((0x0200 == (val & 0x0700)) ||
343 (0x0100 == (val & 0x0700))) {
344 *mic = true; 334 *mic = true;
345 regmap_update_bits(rt286->regmap,
346 RT286_A_BIAS_CTRL3, 0xc000, 0x8000);
347 regmap_update_bits(rt286->regmap,
348 RT286_CBJ_CTRL1, 0x0030, 0x0020);
349 regmap_update_bits(rt286->regmap,
350 RT286_A_BIAS_CTRL2, 0xc000, 0x8000);
351 } else { 335 } else {
352 *mic = false; 336 regmap_update_bits(rt286->regmap,
337 RT286_CBJ_CTRL1, 0xfcc0, 0xe400);
338 msleep(300);
339 regmap_read(rt286->regmap,
340 RT286_CBJ_CTRL2, &val);
341 if (0x0070 == (val & 0x0070))
342 *mic = true;
343 else
344 *mic = false;
353 } 345 }
354
355 regmap_update_bits(rt286->regmap,
356 RT286_MISC_CTRL1,
357 0x0060, 0x0000);
358 } else {
359 regmap_update_bits(rt286->regmap,
360 RT286_MISC_CTRL1,
361 0x0060, 0x0020);
362 regmap_update_bits(rt286->regmap, 346 regmap_update_bits(rt286->regmap,
363 RT286_A_BIAS_CTRL3, 347 RT286_DC_GAIN, 0x200, 0x0);
364 0xc000, 0x8000);
365 regmap_update_bits(rt286->regmap,
366 RT286_CBJ_CTRL1,
367 0x0030, 0x0020);
368 regmap_update_bits(rt286->regmap,
369 RT286_A_BIAS_CTRL2,
370 0xc000, 0x8000);
371 348
349 } else {
372 *mic = false; 350 *mic = false;
351 regmap_write(rt286->regmap, RT286_SET_MIC1, 0x20);
373 } 352 }
374 } else { 353 } else {
375 regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); 354 regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
@@ -378,6 +357,12 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
378 *mic = buf & 0x80000000; 357 *mic = buf & 0x80000000;
379 } 358 }
380 359
360 snd_soc_dapm_disable_pin(&rt286->codec->dapm, "HV");
361 snd_soc_dapm_disable_pin(&rt286->codec->dapm, "VREF");
362 if (!*hp)
363 snd_soc_dapm_disable_pin(&rt286->codec->dapm, "LDO1");
364 snd_soc_dapm_sync(&rt286->codec->dapm);
365
381 return 0; 366 return 0;
382} 367}
383 368
@@ -415,6 +400,17 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
415} 400}
416EXPORT_SYMBOL_GPL(rt286_mic_detect); 401EXPORT_SYMBOL_GPL(rt286_mic_detect);
417 402
403static int is_mclk_mode(struct snd_soc_dapm_widget *source,
404 struct snd_soc_dapm_widget *sink)
405{
406 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(source->codec);
407
408 if (rt286->clk_id == RT286_SCLK_S_MCLK)
409 return 1;
410 else
411 return 0;
412}
413
418static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0); 414static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0);
419static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); 415static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
420 416
@@ -568,7 +564,84 @@ static int rt286_adc_event(struct snd_soc_dapm_widget *w,
568 return 0; 564 return 0;
569} 565}
570 566
567static int rt286_vref_event(struct snd_soc_dapm_widget *w,
568 struct snd_kcontrol *kcontrol, int event)
569{
570 struct snd_soc_codec *codec = w->codec;
571
572 switch (event) {
573 case SND_SOC_DAPM_PRE_PMU:
574 snd_soc_update_bits(codec,
575 RT286_CBJ_CTRL1, 0x0400, 0x0000);
576 mdelay(50);
577 break;
578 default:
579 return 0;
580 }
581
582 return 0;
583}
584
585static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
586 struct snd_kcontrol *kcontrol, int event)
587{
588 struct snd_soc_codec *codec = w->codec;
589
590 switch (event) {
591 case SND_SOC_DAPM_POST_PMU:
592 snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x08);
593 break;
594 case SND_SOC_DAPM_PRE_PMD:
595 snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x30);
596 break;
597 default:
598 return 0;
599 }
600
601 return 0;
602}
603
604static int rt286_mic1_event(struct snd_soc_dapm_widget *w,
605 struct snd_kcontrol *kcontrol, int event)
606{
607 struct snd_soc_codec *codec = w->codec;
608
609 switch (event) {
610 case SND_SOC_DAPM_PRE_PMU:
611 snd_soc_update_bits(codec,
612 RT286_A_BIAS_CTRL3, 0xc000, 0x8000);
613 snd_soc_update_bits(codec,
614 RT286_A_BIAS_CTRL2, 0xc000, 0x8000);
615 break;
616 case SND_SOC_DAPM_POST_PMD:
617 snd_soc_update_bits(codec,
618 RT286_A_BIAS_CTRL3, 0xc000, 0x0000);
619 snd_soc_update_bits(codec,
620 RT286_A_BIAS_CTRL2, 0xc000, 0x0000);
621 break;
622 default:
623 return 0;
624 }
625
626 return 0;
627}
628
571static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = { 629static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = {
630 SND_SOC_DAPM_SUPPLY_S("HV", 1, RT286_POWER_CTRL1,
631 12, 1, NULL, 0),
632 SND_SOC_DAPM_SUPPLY("VREF", RT286_POWER_CTRL1,
633 0, 1, rt286_vref_event, SND_SOC_DAPM_PRE_PMU),
634 SND_SOC_DAPM_SUPPLY_S("LDO1", 1, RT286_POWER_CTRL2,
635 2, 0, NULL, 0),
636 SND_SOC_DAPM_SUPPLY_S("LDO2", 2, RT286_POWER_CTRL1,
637 13, 1, rt286_ldo2_event, SND_SOC_DAPM_PRE_PMD |
638 SND_SOC_DAPM_POST_PMU),
639 SND_SOC_DAPM_SUPPLY("MCLK MODE", RT286_PLL_CTRL1,
640 5, 0, NULL, 0),
641 SND_SOC_DAPM_SUPPLY("MIC1 Input Buffer", SND_SOC_NOPM,
642 0, 0, rt286_mic1_event, SND_SOC_DAPM_PRE_PMU |
643 SND_SOC_DAPM_POST_PMD),
644
572 /* Input Lines */ 645 /* Input Lines */
573 SND_SOC_DAPM_INPUT("DMIC1 Pin"), 646 SND_SOC_DAPM_INPUT("DMIC1 Pin"),
574 SND_SOC_DAPM_INPUT("DMIC2 Pin"), 647 SND_SOC_DAPM_INPUT("DMIC2 Pin"),
@@ -642,6 +715,25 @@ static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = {
642}; 715};
643 716
644static const struct snd_soc_dapm_route rt286_dapm_routes[] = { 717static const struct snd_soc_dapm_route rt286_dapm_routes[] = {
718 {"ADC 0", NULL, "MCLK MODE", is_mclk_mode},
719 {"ADC 1", NULL, "MCLK MODE", is_mclk_mode},
720 {"Front", NULL, "MCLK MODE", is_mclk_mode},
721 {"Surround", NULL, "MCLK MODE", is_mclk_mode},
722
723 {"HP Power", NULL, "LDO1"},
724 {"HP Power", NULL, "LDO2"},
725
726 {"MIC1", NULL, "LDO1"},
727 {"MIC1", NULL, "LDO2"},
728 {"MIC1", NULL, "HV"},
729 {"MIC1", NULL, "VREF"},
730 {"MIC1", NULL, "MIC1 Input Buffer"},
731
732 {"SPO", NULL, "LDO1"},
733 {"SPO", NULL, "LDO2"},
734 {"SPO", NULL, "HV"},
735 {"SPO", NULL, "VREF"},
736
645 {"DMIC1", NULL, "DMIC1 Pin"}, 737 {"DMIC1", NULL, "DMIC1 Pin"},
646 {"DMIC2", NULL, "DMIC2 Pin"}, 738 {"DMIC2", NULL, "DMIC2 Pin"},
647 {"DMIC1", NULL, "DMIC Receiver"}, 739 {"DMIC1", NULL, "DMIC Receiver"},
@@ -880,6 +972,7 @@ static int rt286_set_dai_sysclk(struct snd_soc_dai *dai,
880 } 972 }
881 973
882 rt286->sys_clk = freq; 974 rt286->sys_clk = freq;
975 rt286->clk_id = clk_id;
883 976
884 return 0; 977 return 0;
885} 978}
@@ -915,13 +1008,18 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec,
915 1008
916 case SND_SOC_BIAS_ON: 1009 case SND_SOC_BIAS_ON:
917 mdelay(10); 1010 mdelay(10);
1011 snd_soc_update_bits(codec,
1012 RT286_CBJ_CTRL1, 0x0400, 0x0400);
1013 snd_soc_update_bits(codec,
1014 RT286_DC_GAIN, 0x200, 0x0);
1015
918 break; 1016 break;
919 1017
920 case SND_SOC_BIAS_STANDBY: 1018 case SND_SOC_BIAS_STANDBY:
921 snd_soc_write(codec, 1019 snd_soc_write(codec,
922 RT286_SET_AUDIO_POWER, AC_PWRST_D3); 1020 RT286_SET_AUDIO_POWER, AC_PWRST_D3);
923 snd_soc_update_bits(codec, 1021 snd_soc_update_bits(codec,
924 RT286_DC_GAIN, 0x200, 0x0); 1022 RT286_CBJ_CTRL1, 0x0400, 0x0000);
925 break; 1023 break;
926 1024
927 default: 1025 default:
@@ -962,6 +1060,7 @@ static int rt286_probe(struct snd_soc_codec *codec)
962{ 1060{
963 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); 1061 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
964 1062
1063 rt286->codec = codec;
965 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 1064 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
966 1065
967 if (rt286->i2c->irq) { 1066 if (rt286->i2c->irq) {
@@ -1107,6 +1206,16 @@ static const struct acpi_device_id rt286_acpi_match[] = {
1107}; 1206};
1108MODULE_DEVICE_TABLE(acpi, rt286_acpi_match); 1207MODULE_DEVICE_TABLE(acpi, rt286_acpi_match);
1109 1208
1209static struct dmi_system_id force_combo_jack_table[] = {
1210 {
1211 .ident = "Intel Wilson Beach",
1212 .matches = {
1213 DMI_MATCH(DMI_BOARD_NAME, "Wilson Beach SDS")
1214 }
1215 },
1216 { }
1217};
1218
1110static int rt286_i2c_probe(struct i2c_client *i2c, 1219static int rt286_i2c_probe(struct i2c_client *i2c,
1111 const struct i2c_device_id *id) 1220 const struct i2c_device_id *id)
1112{ 1221{
@@ -1142,6 +1251,9 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1142 if (pdata) 1251 if (pdata)
1143 rt286->pdata = *pdata; 1252 rt286->pdata = *pdata;
1144 1253
1254 if (dmi_check_system(force_combo_jack_table))
1255 rt286->pdata.cbj_en = true;
1256
1145 regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3); 1257 regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3);
1146 1258
1147 for (i = 0; i < RT286_POWER_REG_LEN; i++) 1259 for (i = 0; i < RT286_POWER_REG_LEN; i++)
@@ -1152,7 +1264,6 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1152 if (!rt286->pdata.cbj_en) { 1264 if (!rt286->pdata.cbj_en) {
1153 regmap_write(rt286->regmap, RT286_CBJ_CTRL2, 0x0000); 1265 regmap_write(rt286->regmap, RT286_CBJ_CTRL2, 0x0000);
1154 regmap_write(rt286->regmap, RT286_MIC1_DET_CTRL, 0x0816); 1266 regmap_write(rt286->regmap, RT286_MIC1_DET_CTRL, 0x0816);
1155 regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000);
1156 regmap_update_bits(rt286->regmap, 1267 regmap_update_bits(rt286->regmap,
1157 RT286_CBJ_CTRL1, 0xf000, 0xb000); 1268 RT286_CBJ_CTRL1, 0xf000, 0xb000);
1158 } else { 1269 } else {
@@ -1169,10 +1280,12 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1169 1280
1170 mdelay(10); 1281 mdelay(10);
1171 1282
1172 /*Power down LDO2*/ 1283 regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000);
1173 regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0x8, 0x0); 1284 /* Power down LDO, VREF */
1285 regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0xc, 0x0);
1286 regmap_update_bits(rt286->regmap, RT286_POWER_CTRL1, 0x1001, 0x1001);
1174 1287
1175 /*Set depop parameter*/ 1288 /* Set depop parameter */
1176 regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL2, 0x403a, 0x401a); 1289 regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL2, 0x403a, 0x401a);
1177 regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL3, 0xf777, 0x4737); 1290 regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL3, 0xf777, 0x4737);
1178 regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL4, 0x00ff, 0x003f); 1291 regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL4, 0x00ff, 0x003f);