aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorFang, Yang A <yang.a.fang@intel.com>2015-02-04 21:19:31 -0500
committerMark Brown <broonie@kernel.org>2015-02-05 13:09:27 -0500
commit79080a8b42a08fb68a1ea2e036e54a4749edbd43 (patch)
treef5f7026285d94958bf3442f548e89c403ad9be85 /sound
parent5c4ca99df718f6569849ab5fabdf18c14755b144 (diff)
ASoC: rt5645: add API to select ASRC clock source
This patch defines an API to select the clock source for specified filters. Signed-off-by: Fang, Yang A <yang.a.fang@intel.com> Acked-by: Kevin Strasser <kevin.strasser@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/rt5645.c81
-rw-r--r--sound/soc/codecs/rt5645.h72
2 files changed, 112 insertions, 41 deletions
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 21b2d72b4ea8..debf16c5b549 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -613,6 +613,87 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
613 613
614} 614}
615 615
616/**
617 * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters
618 * @codec: SoC audio codec device.
619 * @filter_mask: mask of filters.
620 * @clk_src: clock source
621 *
622 * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5645 can
623 * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
624 * support special i2s clock format such as Intel's 100fs(100 * sampling rate).
625 * ASRC function will track i2s clock and generate a corresponding system clock
626 * for codec. This function provides an API to select the clock source for a
627 * set of filters specified by the mask. And the codec driver will turn on ASRC
628 * for these filters if ASRC is selected as their clock source.
629 */
630int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec,
631 unsigned int filter_mask, unsigned int clk_src)
632{
633 unsigned int asrc2_mask = 0;
634 unsigned int asrc2_value = 0;
635 unsigned int asrc3_mask = 0;
636 unsigned int asrc3_value = 0;
637
638 switch (clk_src) {
639 case RT5645_CLK_SEL_SYS:
640 case RT5645_CLK_SEL_I2S1_ASRC:
641 case RT5645_CLK_SEL_I2S2_ASRC:
642 case RT5645_CLK_SEL_SYS2:
643 break;
644
645 default:
646 return -EINVAL;
647 }
648
649 if (filter_mask & RT5645_DA_STEREO_FILTER) {
650 asrc2_mask |= RT5645_DA_STO_CLK_SEL_MASK;
651 asrc2_value = (asrc2_value & ~RT5645_DA_STO_CLK_SEL_MASK)
652 | (clk_src << RT5645_DA_STO_CLK_SEL_SFT);
653 }
654
655 if (filter_mask & RT5645_DA_MONO_L_FILTER) {
656 asrc2_mask |= RT5645_DA_MONOL_CLK_SEL_MASK;
657 asrc2_value = (asrc2_value & ~RT5645_DA_MONOL_CLK_SEL_MASK)
658 | (clk_src << RT5645_DA_MONOL_CLK_SEL_SFT);
659 }
660
661 if (filter_mask & RT5645_DA_MONO_R_FILTER) {
662 asrc2_mask |= RT5645_DA_MONOR_CLK_SEL_MASK;
663 asrc2_value = (asrc2_value & ~RT5645_DA_MONOR_CLK_SEL_MASK)
664 | (clk_src << RT5645_DA_MONOR_CLK_SEL_SFT);
665 }
666
667 if (filter_mask & RT5645_AD_STEREO_FILTER) {
668 asrc2_mask |= RT5645_AD_STO1_CLK_SEL_MASK;
669 asrc2_value = (asrc2_value & ~RT5645_AD_STO1_CLK_SEL_MASK)
670 | (clk_src << RT5645_AD_STO1_CLK_SEL_SFT);
671 }
672
673 if (filter_mask & RT5645_AD_MONO_L_FILTER) {
674 asrc3_mask |= RT5645_AD_MONOL_CLK_SEL_MASK;
675 asrc3_value = (asrc3_value & ~RT5645_AD_MONOL_CLK_SEL_MASK)
676 | (clk_src << RT5645_AD_MONOL_CLK_SEL_SFT);
677 }
678
679 if (filter_mask & RT5645_AD_MONO_R_FILTER) {
680 asrc3_mask |= RT5645_AD_MONOR_CLK_SEL_MASK;
681 asrc3_value = (asrc3_value & ~RT5645_AD_MONOR_CLK_SEL_MASK)
682 | (clk_src << RT5645_AD_MONOR_CLK_SEL_SFT);
683 }
684
685 if (asrc2_mask)
686 snd_soc_update_bits(codec, RT5645_ASRC_2,
687 asrc2_mask, asrc2_value);
688
689 if (asrc3_mask)
690 snd_soc_update_bits(codec, RT5645_ASRC_3,
691 asrc3_mask, asrc3_value);
692
693 return 0;
694}
695EXPORT_SYMBOL_GPL(rt5645_sel_asrc_clk_src);
696
616/* Digital Mixer */ 697/* Digital Mixer */
617static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { 698static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = {
618 SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, 699 SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER,
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h
index 74542310d3f0..dbfd98c22f4d 100644
--- a/sound/soc/codecs/rt5645.h
+++ b/sound/soc/codecs/rt5645.h
@@ -1120,50 +1120,27 @@
1120#define RT5645_DMIC_2_M_NOR (0x0 << 8) 1120#define RT5645_DMIC_2_M_NOR (0x0 << 8)
1121#define RT5645_DMIC_2_M_ASYN (0x1 << 8) 1121#define RT5645_DMIC_2_M_ASYN (0x1 << 8)
1122 1122
1123/* ASRC clock source selection (0x84, 0x85) */
1124#define RT5645_CLK_SEL_SYS (0x0)
1125#define RT5645_CLK_SEL_I2S1_ASRC (0x1)
1126#define RT5645_CLK_SEL_I2S2_ASRC (0x2)
1127#define RT5645_CLK_SEL_SYS2 (0x5)
1128
1123/* ASRC Control 2 (0x84) */ 1129/* ASRC Control 2 (0x84) */
1124#define RT5645_MDA_L_M_MASK (0x1 << 15) 1130#define RT5645_DA_STO_CLK_SEL_MASK (0xf << 12)
1125#define RT5645_MDA_L_M_SFT 15 1131#define RT5645_DA_STO_CLK_SEL_SFT 12
1126#define RT5645_MDA_L_M_NOR (0x0 << 15) 1132#define RT5645_DA_MONOL_CLK_SEL_MASK (0xf << 8)
1127#define RT5645_MDA_L_M_ASYN (0x1 << 15) 1133#define RT5645_DA_MONOL_CLK_SEL_SFT 8
1128#define RT5645_MDA_R_M_MASK (0x1 << 14) 1134#define RT5645_DA_MONOR_CLK_SEL_MASK (0xf << 4)
1129#define RT5645_MDA_R_M_SFT 14 1135#define RT5645_DA_MONOR_CLK_SEL_SFT 4
1130#define RT5645_MDA_R_M_NOR (0x0 << 14) 1136#define RT5645_AD_STO1_CLK_SEL_MASK (0xf << 0)
1131#define RT5645_MDA_R_M_ASYN (0x1 << 14) 1137#define RT5645_AD_STO1_CLK_SEL_SFT 0
1132#define RT5645_MAD_L_M_MASK (0x1 << 13)
1133#define RT5645_MAD_L_M_SFT 13
1134#define RT5645_MAD_L_M_NOR (0x0 << 13)
1135#define RT5645_MAD_L_M_ASYN (0x1 << 13)
1136#define RT5645_MAD_R_M_MASK (0x1 << 12)
1137#define RT5645_MAD_R_M_SFT 12
1138#define RT5645_MAD_R_M_NOR (0x0 << 12)
1139#define RT5645_MAD_R_M_ASYN (0x1 << 12)
1140#define RT5645_ADC_M_MASK (0x1 << 11)
1141#define RT5645_ADC_M_SFT 11
1142#define RT5645_ADC_M_NOR (0x0 << 11)
1143#define RT5645_ADC_M_ASYN (0x1 << 11)
1144#define RT5645_STO_DAC_M_MASK (0x1 << 5)
1145#define RT5645_STO_DAC_M_SFT 5
1146#define RT5645_STO_DAC_M_NOR (0x0 << 5)
1147#define RT5645_STO_DAC_M_ASYN (0x1 << 5)
1148#define RT5645_I2S1_R_D_MASK (0x1 << 4)
1149#define RT5645_I2S1_R_D_SFT 4
1150#define RT5645_I2S1_R_D_DIS (0x0 << 4)
1151#define RT5645_I2S1_R_D_EN (0x1 << 4)
1152#define RT5645_I2S2_R_D_MASK (0x1 << 3)
1153#define RT5645_I2S2_R_D_SFT 3
1154#define RT5645_I2S2_R_D_DIS (0x0 << 3)
1155#define RT5645_I2S2_R_D_EN (0x1 << 3)
1156#define RT5645_PRE_SCLK_MASK (0x3)
1157#define RT5645_PRE_SCLK_SFT 0
1158#define RT5645_PRE_SCLK_512 (0x0)
1159#define RT5645_PRE_SCLK_1024 (0x1)
1160#define RT5645_PRE_SCLK_2048 (0x2)
1161 1138
1162/* ASRC Control 3 (0x85) */ 1139/* ASRC Control 3 (0x85) */
1163#define RT5645_I2S1_RATE_MASK (0xf << 12) 1140#define RT5645_AD_MONOL_CLK_SEL_MASK (0xf << 4)
1164#define RT5645_I2S1_RATE_SFT 12 1141#define RT5645_AD_MONOL_CLK_SEL_SFT 4
1165#define RT5645_I2S2_RATE_MASK (0xf << 8) 1142#define RT5645_AD_MONOR_CLK_SEL_MASK (0xf << 0)
1166#define RT5645_I2S2_RATE_SFT 8 1143#define RT5645_AD_MONOR_CLK_SEL_SFT 0
1167 1144
1168/* ASRC Control 4 (0x89) */ 1145/* ASRC Control 4 (0x89) */
1169#define RT5645_I2S1_PD_MASK (0x7 << 12) 1146#define RT5645_I2S1_PD_MASK (0x7 << 12)
@@ -2189,6 +2166,19 @@ enum {
2189 CODEC_TYPE_RT5650, 2166 CODEC_TYPE_RT5650,
2190}; 2167};
2191 2168
2169/* filter mask */
2170enum {
2171 RT5645_DA_STEREO_FILTER = 0x1,
2172 RT5645_DA_MONO_L_FILTER = (0x1 << 1),
2173 RT5645_DA_MONO_R_FILTER = (0x1 << 2),
2174 RT5645_AD_STEREO_FILTER = (0x1 << 3),
2175 RT5645_AD_MONO_L_FILTER = (0x1 << 4),
2176 RT5645_AD_MONO_R_FILTER = (0x1 << 5),
2177};
2178
2179int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec,
2180 unsigned int filter_mask, unsigned int clk_src);
2181
2192struct rt5645_priv { 2182struct rt5645_priv {
2193 struct snd_soc_codec *codec; 2183 struct snd_soc_codec *codec;
2194 struct rt5645_platform_data pdata; 2184 struct rt5645_platform_data pdata;