aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/rt286.c211
1 files changed, 155 insertions, 56 deletions
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index 4aa555cbcca8..97daa80e9104 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -36,11 +36,13 @@
36 36
37struct rt286_priv { 37struct rt286_priv {
38 struct regmap *regmap; 38 struct regmap *regmap;
39 struct snd_soc_codec *codec;
39 struct rt286_platform_data pdata; 40 struct rt286_platform_data pdata;
40 struct i2c_client *i2c; 41 struct i2c_client *i2c;
41 struct snd_soc_jack *jack; 42 struct snd_soc_jack *jack;
42 struct delayed_work jack_detect_work; 43 struct delayed_work jack_detect_work;
43 int sys_clk; 44 int sys_clk;
45 int clk_id;
44 struct reg_default *index_cache; 46 struct reg_default *index_cache;
45}; 47};
46 48
@@ -298,7 +300,6 @@ static int rt286_support_power_controls[] = {
298static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) 300static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
299{ 301{
300 unsigned int val, buf; 302 unsigned int val, buf;
301 int i;
302 303
303 *hp = false; 304 *hp = false;
304 *mic = false; 305 *mic = false;
@@ -309,67 +310,44 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
309 if (*hp) { 310 if (*hp) {
310 /* power on HV,VERF */ 311 /* power on HV,VERF */
311 regmap_update_bits(rt286->regmap, 312 regmap_update_bits(rt286->regmap,
312 RT286_POWER_CTRL1, 0x1001, 0x0); 313 RT286_DC_GAIN, 0x200, 0x200);
314
315 snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
316 "HV");
317 snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
318 "VREF");
313 /* power LDO1 */ 319 /* power LDO1 */
314 regmap_update_bits(rt286->regmap, 320 snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
315 RT286_POWER_CTRL2, 0x4, 0x4); 321 "LDO1");
316 regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24); 322 snd_soc_dapm_sync(&rt286->codec->dapm);
317 regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val);
318 323
319 msleep(200); 324 regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24);
320 i = 40; 325 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 326
328 if (0x0400 == (val & 0x0700)) { 327 regmap_update_bits(rt286->regmap,
329 *mic = false; 328 RT286_CBJ_CTRL1, 0xfcc0, 0xd400);
329 msleep(300);
330 regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val);
330 331
331 regmap_write(rt286->regmap, 332 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; 333 *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 { 334 } else {
352 *mic = false; 335 regmap_update_bits(rt286->regmap,
336 RT286_CBJ_CTRL1, 0xfcc0, 0xe400);
337 msleep(300);
338 regmap_read(rt286->regmap,
339 RT286_CBJ_CTRL2, &val);
340 if (0x0070 == (val & 0x0070))
341 *mic = true;
342 else
343 *mic = false;
353 } 344 }
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,
363 RT286_A_BIAS_CTRL3,
364 0xc000, 0x8000);
365 regmap_update_bits(rt286->regmap, 345 regmap_update_bits(rt286->regmap,
366 RT286_CBJ_CTRL1, 346 RT286_DC_GAIN, 0x200, 0x0);
367 0x0030, 0x0020);
368 regmap_update_bits(rt286->regmap,
369 RT286_A_BIAS_CTRL2,
370 0xc000, 0x8000);
371 347
348 } else {
372 *mic = false; 349 *mic = false;
350 regmap_write(rt286->regmap, RT286_SET_MIC1, 0x20);
373 } 351 }
374 } else { 352 } else {
375 regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); 353 regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
@@ -378,6 +356,12 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
378 *mic = buf & 0x80000000; 356 *mic = buf & 0x80000000;
379 } 357 }
380 358
359 snd_soc_dapm_disable_pin(&rt286->codec->dapm, "HV");
360 snd_soc_dapm_disable_pin(&rt286->codec->dapm, "VREF");
361 if (!*hp)
362 snd_soc_dapm_disable_pin(&rt286->codec->dapm, "LDO1");
363 snd_soc_dapm_sync(&rt286->codec->dapm);
364
381 return 0; 365 return 0;
382} 366}
383 367
@@ -415,6 +399,17 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
415} 399}
416EXPORT_SYMBOL_GPL(rt286_mic_detect); 400EXPORT_SYMBOL_GPL(rt286_mic_detect);
417 401
402static int is_mclk_mode(struct snd_soc_dapm_widget *source,
403 struct snd_soc_dapm_widget *sink)
404{
405 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(source->codec);
406
407 if (rt286->clk_id == RT286_SCLK_S_MCLK)
408 return 1;
409 else
410 return 0;
411}
412
418static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0); 413static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0);
419static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); 414static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
420 415
@@ -568,7 +563,84 @@ static int rt286_adc_event(struct snd_soc_dapm_widget *w,
568 return 0; 563 return 0;
569} 564}
570 565
566static int rt286_vref_event(struct snd_soc_dapm_widget *w,
567 struct snd_kcontrol *kcontrol, int event)
568{
569 struct snd_soc_codec *codec = w->codec;
570
571 switch (event) {
572 case SND_SOC_DAPM_PRE_PMU:
573 snd_soc_update_bits(codec,
574 RT286_CBJ_CTRL1, 0x0400, 0x0000);
575 mdelay(50);
576 break;
577 default:
578 return 0;
579 }
580
581 return 0;
582}
583
584static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
585 struct snd_kcontrol *kcontrol, int event)
586{
587 struct snd_soc_codec *codec = w->codec;
588
589 switch (event) {
590 case SND_SOC_DAPM_POST_PMU:
591 snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x08);
592 break;
593 case SND_SOC_DAPM_PRE_PMD:
594 snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x30);
595 break;
596 default:
597 return 0;
598 }
599
600 return 0;
601}
602
603static int rt286_mic1_event(struct snd_soc_dapm_widget *w,
604 struct snd_kcontrol *kcontrol, int event)
605{
606 struct snd_soc_codec *codec = w->codec;
607
608 switch (event) {
609 case SND_SOC_DAPM_PRE_PMU:
610 snd_soc_update_bits(codec,
611 RT286_A_BIAS_CTRL3, 0xc000, 0x8000);
612 snd_soc_update_bits(codec,
613 RT286_A_BIAS_CTRL2, 0xc000, 0x8000);
614 break;
615 case SND_SOC_DAPM_POST_PMD:
616 snd_soc_update_bits(codec,
617 RT286_A_BIAS_CTRL3, 0xc000, 0x0000);
618 snd_soc_update_bits(codec,
619 RT286_A_BIAS_CTRL2, 0xc000, 0x0000);
620 break;
621 default:
622 return 0;
623 }
624
625 return 0;
626}
627
571static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = { 628static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = {
629 SND_SOC_DAPM_SUPPLY_S("HV", 1, RT286_POWER_CTRL1,
630 12, 1, NULL, 0),
631 SND_SOC_DAPM_SUPPLY("VREF", RT286_POWER_CTRL1,
632 0, 1, rt286_vref_event, SND_SOC_DAPM_PRE_PMU),
633 SND_SOC_DAPM_SUPPLY_S("LDO1", 1, RT286_POWER_CTRL2,
634 2, 0, NULL, 0),
635 SND_SOC_DAPM_SUPPLY_S("LDO2", 2, RT286_POWER_CTRL1,
636 13, 1, rt286_ldo2_event, SND_SOC_DAPM_PRE_PMD |
637 SND_SOC_DAPM_POST_PMU),
638 SND_SOC_DAPM_SUPPLY("MCLK MODE", RT286_PLL_CTRL1,
639 5, 0, NULL, 0),
640 SND_SOC_DAPM_SUPPLY("MIC1 Input Buffer", SND_SOC_NOPM,
641 0, 0, rt286_mic1_event, SND_SOC_DAPM_PRE_PMU |
642 SND_SOC_DAPM_POST_PMD),
643
572 /* Input Lines */ 644 /* Input Lines */
573 SND_SOC_DAPM_INPUT("DMIC1 Pin"), 645 SND_SOC_DAPM_INPUT("DMIC1 Pin"),
574 SND_SOC_DAPM_INPUT("DMIC2 Pin"), 646 SND_SOC_DAPM_INPUT("DMIC2 Pin"),
@@ -642,6 +714,25 @@ static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = {
642}; 714};
643 715
644static const struct snd_soc_dapm_route rt286_dapm_routes[] = { 716static const struct snd_soc_dapm_route rt286_dapm_routes[] = {
717 {"ADC 0", NULL, "MCLK MODE", is_mclk_mode},
718 {"ADC 1", NULL, "MCLK MODE", is_mclk_mode},
719 {"Front", NULL, "MCLK MODE", is_mclk_mode},
720 {"Surround", NULL, "MCLK MODE", is_mclk_mode},
721
722 {"HP Power", NULL, "LDO1"},
723 {"HP Power", NULL, "LDO2"},
724
725 {"MIC1", NULL, "LDO1"},
726 {"MIC1", NULL, "LDO2"},
727 {"MIC1", NULL, "HV"},
728 {"MIC1", NULL, "VREF"},
729 {"MIC1", NULL, "MIC1 Input Buffer"},
730
731 {"SPO", NULL, "LDO1"},
732 {"SPO", NULL, "LDO2"},
733 {"SPO", NULL, "HV"},
734 {"SPO", NULL, "VREF"},
735
645 {"DMIC1", NULL, "DMIC1 Pin"}, 736 {"DMIC1", NULL, "DMIC1 Pin"},
646 {"DMIC2", NULL, "DMIC2 Pin"}, 737 {"DMIC2", NULL, "DMIC2 Pin"},
647 {"DMIC1", NULL, "DMIC Receiver"}, 738 {"DMIC1", NULL, "DMIC Receiver"},
@@ -880,6 +971,7 @@ static int rt286_set_dai_sysclk(struct snd_soc_dai *dai,
880 } 971 }
881 972
882 rt286->sys_clk = freq; 973 rt286->sys_clk = freq;
974 rt286->clk_id = clk_id;
883 975
884 return 0; 976 return 0;
885} 977}
@@ -915,13 +1007,18 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec,
915 1007
916 case SND_SOC_BIAS_ON: 1008 case SND_SOC_BIAS_ON:
917 mdelay(10); 1009 mdelay(10);
1010 snd_soc_update_bits(codec,
1011 RT286_CBJ_CTRL1, 0x0400, 0x0400);
1012 snd_soc_update_bits(codec,
1013 RT286_DC_GAIN, 0x200, 0x0);
1014
918 break; 1015 break;
919 1016
920 case SND_SOC_BIAS_STANDBY: 1017 case SND_SOC_BIAS_STANDBY:
921 snd_soc_write(codec, 1018 snd_soc_write(codec,
922 RT286_SET_AUDIO_POWER, AC_PWRST_D3); 1019 RT286_SET_AUDIO_POWER, AC_PWRST_D3);
923 snd_soc_update_bits(codec, 1020 snd_soc_update_bits(codec,
924 RT286_DC_GAIN, 0x200, 0x0); 1021 RT286_CBJ_CTRL1, 0x0400, 0x0000);
925 break; 1022 break;
926 1023
927 default: 1024 default:
@@ -962,6 +1059,7 @@ static int rt286_probe(struct snd_soc_codec *codec)
962{ 1059{
963 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); 1060 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
964 1061
1062 rt286->codec = codec;
965 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 1063 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
966 1064
967 if (rt286->i2c->irq) { 1065 if (rt286->i2c->irq) {
@@ -1152,7 +1250,6 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1152 if (!rt286->pdata.cbj_en) { 1250 if (!rt286->pdata.cbj_en) {
1153 regmap_write(rt286->regmap, RT286_CBJ_CTRL2, 0x0000); 1251 regmap_write(rt286->regmap, RT286_CBJ_CTRL2, 0x0000);
1154 regmap_write(rt286->regmap, RT286_MIC1_DET_CTRL, 0x0816); 1252 regmap_write(rt286->regmap, RT286_MIC1_DET_CTRL, 0x0816);
1155 regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000);
1156 regmap_update_bits(rt286->regmap, 1253 regmap_update_bits(rt286->regmap,
1157 RT286_CBJ_CTRL1, 0xf000, 0xb000); 1254 RT286_CBJ_CTRL1, 0xf000, 0xb000);
1158 } else { 1255 } else {
@@ -1169,8 +1266,10 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1169 1266
1170 mdelay(10); 1267 mdelay(10);
1171 1268
1172 /*Power down LDO2*/ 1269 regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000);
1173 regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0x8, 0x0); 1270 /*Power down LDO, VREF*/
1271 regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0xc, 0x0);
1272 regmap_update_bits(rt286->regmap, RT286_POWER_CTRL1, 0x1001, 0x1001);
1174 1273
1175 /*Set depop parameter*/ 1274 /*Set depop parameter*/
1176 regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL2, 0x403a, 0x401a); 1275 regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL2, 0x403a, 0x401a);