aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/rt5670.c83
-rw-r--r--sound/soc/codecs/rt5670.h15
2 files changed, 98 insertions, 0 deletions
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index 0a027bc94399..0632b7458a53 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -590,6 +590,89 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
590 return 0; 590 return 0;
591} 591}
592 592
593
594/**
595 * rt5670_sel_asrc_clk_src - select ASRC clock source for a set of filters
596 * @codec: SoC audio codec device.
597 * @filter_mask: mask of filters.
598 * @clk_src: clock source
599 *
600 * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5670 can
601 * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
602 * support special i2s clock format such as Intel's 100fs(100 * sampling rate).
603 * ASRC function will track i2s clock and generate a corresponding system clock
604 * for codec. This function provides an API to select the clock source for a
605 * set of filters specified by the mask. And the codec driver will turn on ASRC
606 * for these filters if ASRC is selected as their clock source.
607 */
608int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
609 unsigned int filter_mask, unsigned int clk_src)
610{
611 unsigned int asrc2_mask = 0, asrc2_value = 0;
612 unsigned int asrc3_mask = 0, asrc3_value = 0;
613
614 if (clk_src > RT5670_CLK_SEL_SYS3)
615 return -EINVAL;
616
617 if (filter_mask & RT5670_DA_STEREO_FILTER) {
618 asrc2_mask |= RT5670_DA_STO_CLK_SEL_MASK;
619 asrc2_value = (asrc2_value & ~RT5670_DA_STO_CLK_SEL_MASK)
620 | (clk_src << RT5670_DA_STO_CLK_SEL_SFT);
621 }
622
623 if (filter_mask & RT5670_DA_MONO_L_FILTER) {
624 asrc2_mask |= RT5670_DA_MONOL_CLK_SEL_MASK;
625 asrc2_value = (asrc2_value & ~RT5670_DA_MONOL_CLK_SEL_MASK)
626 | (clk_src << RT5670_DA_MONOL_CLK_SEL_SFT);
627 }
628
629 if (filter_mask & RT5670_DA_MONO_R_FILTER) {
630 asrc2_mask |= RT5670_DA_MONOR_CLK_SEL_MASK;
631 asrc2_value = (asrc2_value & ~RT5670_DA_MONOR_CLK_SEL_MASK)
632 | (clk_src << RT5670_DA_MONOR_CLK_SEL_SFT);
633 }
634
635 if (filter_mask & RT5670_AD_STEREO_FILTER) {
636 asrc2_mask |= RT5670_AD_STO1_CLK_SEL_MASK;
637 asrc2_value = (asrc2_value & ~RT5670_AD_STO1_CLK_SEL_MASK)
638 | (clk_src << RT5670_AD_STO1_CLK_SEL_SFT);
639 }
640
641 if (filter_mask & RT5670_AD_MONO_L_FILTER) {
642 asrc3_mask |= RT5670_AD_MONOL_CLK_SEL_MASK;
643 asrc3_value = (asrc3_value & ~RT5670_AD_MONOL_CLK_SEL_MASK)
644 | (clk_src << RT5670_AD_MONOL_CLK_SEL_SFT);
645 }
646
647 if (filter_mask & RT5670_AD_MONO_R_FILTER) {
648 asrc3_mask |= RT5670_AD_MONOR_CLK_SEL_MASK;
649 asrc3_value = (asrc3_value & ~RT5670_AD_MONOR_CLK_SEL_MASK)
650 | (clk_src << RT5670_AD_MONOR_CLK_SEL_SFT);
651 }
652
653 if (filter_mask & RT5670_UP_RATE_FILTER) {
654 asrc3_mask |= RT5670_UP_CLK_SEL_MASK;
655 asrc3_value = (asrc3_value & ~RT5670_UP_CLK_SEL_MASK)
656 | (clk_src << RT5670_UP_CLK_SEL_SFT);
657 }
658
659 if (filter_mask & RT5670_DOWN_RATE_FILTER) {
660 asrc3_mask |= RT5670_DOWN_CLK_SEL_MASK;
661 asrc3_value = (asrc3_value & ~RT5670_DOWN_CLK_SEL_MASK)
662 | (clk_src << RT5670_DOWN_CLK_SEL_SFT);
663 }
664
665 if (asrc2_mask)
666 snd_soc_update_bits(codec, RT5670_ASRC_2,
667 asrc2_mask, asrc2_value);
668
669 if (asrc3_mask)
670 snd_soc_update_bits(codec, RT5670_ASRC_3,
671 asrc3_mask, asrc3_value);
672 return 0;
673}
674EXPORT_SYMBOL_GPL(rt5670_sel_asrc_clk_src);
675
593/* Digital Mixer */ 676/* Digital Mixer */
594static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = { 677static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = {
595 SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER, 678 SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER,
diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h
index 82553b1726cd..0a67adbcfbc3 100644
--- a/sound/soc/codecs/rt5670.h
+++ b/sound/soc/codecs/rt5670.h
@@ -1969,6 +1969,21 @@ enum {
1969 RT5670_DMIC_DATA_GPIO5, 1969 RT5670_DMIC_DATA_GPIO5,
1970}; 1970};
1971 1971
1972/* filter mask */
1973enum {
1974 RT5670_DA_STEREO_FILTER = 0x1,
1975 RT5670_DA_MONO_L_FILTER = (0x1 << 1),
1976 RT5670_DA_MONO_R_FILTER = (0x1 << 2),
1977 RT5670_AD_STEREO_FILTER = (0x1 << 3),
1978 RT5670_AD_MONO_L_FILTER = (0x1 << 4),
1979 RT5670_AD_MONO_R_FILTER = (0x1 << 5),
1980 RT5670_UP_RATE_FILTER = (0x1 << 6),
1981 RT5670_DOWN_RATE_FILTER = (0x1 << 7),
1982};
1983
1984int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
1985 unsigned int filter_mask, unsigned int clk_src);
1986
1972struct rt5670_priv { 1987struct rt5670_priv {
1973 struct snd_soc_codec *codec; 1988 struct snd_soc_codec *codec;
1974 struct rt5670_platform_data pdata; 1989 struct rt5670_platform_data pdata;