diff options
author | Bard Liao <bardliao@realtek.com> | 2014-10-31 03:37:55 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-11-07 06:46:57 -0500 |
commit | 9e2683530d6f78b30bcf4cabb97d1b7d6b925b85 (patch) | |
tree | bda7240ce7f74f535de2121d920f58411563d3d2 /sound/soc/codecs/rt5645.c | |
parent | bb656add19764c7a3cf28b2b330ec0a189fe4f48 (diff) |
ASoC: rt5645: Add ASRC support
This patch add ASRC support for rt5645 codec.
Signed-off-by: Bard Liao <bardliao@realtek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/rt5645.c')
-rw-r--r-- | sound/soc/codecs/rt5645.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 286438d6916b..1dbbebc83d41 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c | |||
@@ -441,6 +441,65 @@ static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_sel_enum, | |||
441 | RT5645_TDM_CTRL_1, 8, | 441 | RT5645_TDM_CTRL_1, 8, |
442 | rt5645_tdm_adc_data_select); | 442 | rt5645_tdm_adc_data_select); |
443 | 443 | ||
444 | static int rt5645_clk_sel_put(struct snd_kcontrol *kcontrol, | ||
445 | struct snd_ctl_elem_value *ucontrol) | ||
446 | { | ||
447 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
448 | unsigned int u_bit = 0, p_bit = 0; | ||
449 | struct soc_enum *em = | ||
450 | (struct soc_enum *)kcontrol->private_value; | ||
451 | |||
452 | switch (em->reg) { | ||
453 | case RT5645_ASRC_2: | ||
454 | switch (em->shift_l) { | ||
455 | case 0: | ||
456 | u_bit = 0x8; | ||
457 | p_bit = RT5645_PWR_ADC_S1F; | ||
458 | break; | ||
459 | case 4: | ||
460 | u_bit = 0x100; | ||
461 | p_bit = RT5645_PWR_DAC_MF_R; | ||
462 | break; | ||
463 | case 8: | ||
464 | u_bit = 0x200; | ||
465 | p_bit = RT5645_PWR_DAC_MF_L; | ||
466 | break; | ||
467 | case 12: | ||
468 | u_bit = 0x400; | ||
469 | p_bit = RT5645_PWR_DAC_S1F; | ||
470 | break; | ||
471 | } | ||
472 | break; | ||
473 | case RT5645_ASRC_3: | ||
474 | switch (em->shift_l) { | ||
475 | case 0: | ||
476 | u_bit = 0x1; | ||
477 | p_bit = RT5645_PWR_ADC_MF_R; | ||
478 | break; | ||
479 | case 4: | ||
480 | u_bit = 0x2; | ||
481 | p_bit = RT5645_PWR_ADC_MF_L; | ||
482 | break; | ||
483 | } | ||
484 | break; | ||
485 | } | ||
486 | |||
487 | if (u_bit || p_bit) { | ||
488 | switch (ucontrol->value.integer.value[0]) { | ||
489 | case 1 ... 4: /*enable*/ | ||
490 | if (snd_soc_read(codec, RT5645_PWR_DIG2) & p_bit) | ||
491 | snd_soc_update_bits(codec, | ||
492 | RT5645_ASRC_1, u_bit, u_bit); | ||
493 | break; | ||
494 | default: /*disable*/ | ||
495 | snd_soc_update_bits(codec, RT5645_ASRC_1, u_bit, 0); | ||
496 | break; | ||
497 | } | ||
498 | } | ||
499 | |||
500 | return snd_soc_put_enum_double(kcontrol, ucontrol); | ||
501 | } | ||
502 | |||
444 | static const struct snd_kcontrol_new rt5645_snd_controls[] = { | 503 | static const struct snd_kcontrol_new rt5645_snd_controls[] = { |
445 | /* Speaker Output Volume */ | 504 | /* Speaker Output Volume */ |
446 | SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, | 505 | SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, |
@@ -552,6 +611,53 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | |||
552 | return 0; | 611 | return 0; |
553 | } | 612 | } |
554 | 613 | ||
614 | static int is_using_asrc(struct snd_soc_dapm_widget *source, | ||
615 | struct snd_soc_dapm_widget *sink) | ||
616 | { | ||
617 | unsigned int reg, shift, val; | ||
618 | |||
619 | switch (source->shift) { | ||
620 | case 0: | ||
621 | reg = RT5645_ASRC_3; | ||
622 | shift = 0; | ||
623 | break; | ||
624 | case 1: | ||
625 | reg = RT5645_ASRC_3; | ||
626 | shift = 4; | ||
627 | break; | ||
628 | case 3: | ||
629 | reg = RT5645_ASRC_2; | ||
630 | shift = 0; | ||
631 | break; | ||
632 | case 8: | ||
633 | reg = RT5645_ASRC_2; | ||
634 | shift = 4; | ||
635 | break; | ||
636 | case 9: | ||
637 | reg = RT5645_ASRC_2; | ||
638 | shift = 8; | ||
639 | break; | ||
640 | case 10: | ||
641 | reg = RT5645_ASRC_2; | ||
642 | shift = 12; | ||
643 | break; | ||
644 | default: | ||
645 | return 0; | ||
646 | } | ||
647 | |||
648 | val = (snd_soc_read(source->codec, reg) >> shift) & 0xf; | ||
649 | switch (val) { | ||
650 | case 1: | ||
651 | case 2: | ||
652 | case 3: | ||
653 | case 4: | ||
654 | return 1; | ||
655 | default: | ||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | } | ||
660 | |||
555 | /* Digital Mixer */ | 661 | /* Digital Mixer */ |
556 | static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { | 662 | static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { |
557 | SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, | 663 | SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, |
@@ -1244,6 +1350,30 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | |||
1244 | SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5645_PWR_VOL, | 1350 | SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5645_PWR_VOL, |
1245 | RT5645_PWR_MIC_DET_BIT, 0, NULL, 0), | 1351 | RT5645_PWR_MIC_DET_BIT, 0, NULL, 0), |
1246 | 1352 | ||
1353 | /* ASRC */ | ||
1354 | SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5645_ASRC_1, | ||
1355 | 11, 0, NULL, 0), | ||
1356 | SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5645_ASRC_1, | ||
1357 | 12, 0, NULL, 0), | ||
1358 | SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5645_ASRC_1, | ||
1359 | 10, 0, NULL, 0), | ||
1360 | SND_SOC_DAPM_SUPPLY_S("DAC MONO L ASRC", 1, RT5645_ASRC_1, | ||
1361 | 9, 0, NULL, 0), | ||
1362 | SND_SOC_DAPM_SUPPLY_S("DAC MONO R ASRC", 1, RT5645_ASRC_1, | ||
1363 | 8, 0, NULL, 0), | ||
1364 | SND_SOC_DAPM_SUPPLY_S("DMIC STO1 ASRC", 1, RT5645_ASRC_1, | ||
1365 | 7, 0, NULL, 0), | ||
1366 | SND_SOC_DAPM_SUPPLY_S("DMIC MONO L ASRC", 1, RT5645_ASRC_1, | ||
1367 | 5, 0, NULL, 0), | ||
1368 | SND_SOC_DAPM_SUPPLY_S("DMIC MONO R ASRC", 1, RT5645_ASRC_1, | ||
1369 | 4, 0, NULL, 0), | ||
1370 | SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5645_ASRC_1, | ||
1371 | 3, 0, NULL, 0), | ||
1372 | SND_SOC_DAPM_SUPPLY_S("ADC MONO L ASRC", 1, RT5645_ASRC_1, | ||
1373 | 1, 0, NULL, 0), | ||
1374 | SND_SOC_DAPM_SUPPLY_S("ADC MONO R ASRC", 1, RT5645_ASRC_1, | ||
1375 | 0, 0, NULL, 0), | ||
1376 | |||
1247 | /* Input Side */ | 1377 | /* Input Side */ |
1248 | /* micbias */ | 1378 | /* micbias */ |
1249 | SND_SOC_DAPM_MICBIAS("micbias1", RT5645_PWR_ANLG2, | 1379 | SND_SOC_DAPM_MICBIAS("micbias1", RT5645_PWR_ANLG2, |
@@ -1502,6 +1632,17 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | |||
1502 | }; | 1632 | }; |
1503 | 1633 | ||
1504 | static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { | 1634 | static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { |
1635 | { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc }, | ||
1636 | { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc }, | ||
1637 | { "adc mono left filter", NULL, "ADC MONO L ASRC", is_using_asrc }, | ||
1638 | { "adc mono right filter", NULL, "ADC MONO R ASRC", is_using_asrc }, | ||
1639 | { "dac mono left filter", NULL, "DAC MONO L ASRC", is_using_asrc }, | ||
1640 | { "dac mono right filter", NULL, "DAC MONO R ASRC", is_using_asrc }, | ||
1641 | { "dac stereo1 filter", NULL, "DAC STO ASRC", is_using_asrc }, | ||
1642 | |||
1643 | { "I2S1", NULL, "I2S1 ASRC" }, | ||
1644 | { "I2S2", NULL, "I2S2 ASRC" }, | ||
1645 | |||
1505 | { "IN1P", NULL, "LDO2" }, | 1646 | { "IN1P", NULL, "LDO2" }, |
1506 | { "IN2P", NULL, "LDO2" }, | 1647 | { "IN2P", NULL, "LDO2" }, |
1507 | 1648 | ||
@@ -1548,12 +1689,15 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { | |||
1548 | 1689 | ||
1549 | { "Stereo1 DMIC Mux", "DMIC1", "DMIC1" }, | 1690 | { "Stereo1 DMIC Mux", "DMIC1", "DMIC1" }, |
1550 | { "Stereo1 DMIC Mux", "DMIC2", "DMIC2" }, | 1691 | { "Stereo1 DMIC Mux", "DMIC2", "DMIC2" }, |
1692 | { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC" }, | ||
1551 | 1693 | ||
1552 | { "Mono DMIC L Mux", "DMIC1", "DMIC L1" }, | 1694 | { "Mono DMIC L Mux", "DMIC1", "DMIC L1" }, |
1553 | { "Mono DMIC L Mux", "DMIC2", "DMIC L2" }, | 1695 | { "Mono DMIC L Mux", "DMIC2", "DMIC L2" }, |
1696 | { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC" }, | ||
1554 | 1697 | ||
1555 | { "Mono DMIC R Mux", "DMIC1", "DMIC R1" }, | 1698 | { "Mono DMIC R Mux", "DMIC1", "DMIC R1" }, |
1556 | { "Mono DMIC R Mux", "DMIC2", "DMIC R2" }, | 1699 | { "Mono DMIC R Mux", "DMIC2", "DMIC R2" }, |
1700 | { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC" }, | ||
1557 | 1701 | ||
1558 | { "Stereo1 ADC L2 Mux", "DMIC", "Stereo1 DMIC Mux" }, | 1702 | { "Stereo1 ADC L2 Mux", "DMIC", "Stereo1 DMIC Mux" }, |
1559 | { "Stereo1 ADC L2 Mux", "DAC MIX", "DAC MIXL" }, | 1703 | { "Stereo1 ADC L2 Mux", "DAC MIX", "DAC MIXL" }, |