diff options
author | Mark Brown <broonie@kernel.org> | 2015-02-05 13:10:32 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-02-05 13:10:32 -0500 |
commit | b4964bb356ef9651478e555105586b6f5111fc14 (patch) | |
tree | 4ae969755339304f7403bbf645e58f94afd8d490 /sound | |
parent | cd311dd123f5ae5c6da71bdfa9a379a694eb9917 (diff) | |
parent | 79080a8b42a08fb68a1ea2e036e54a4749edbd43 (diff) |
Merge branch 'topic/rt5645' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-intel
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/rt5645.c | 239 | ||||
-rw-r--r-- | sound/soc/codecs/rt5645.h | 87 |
2 files changed, 268 insertions, 58 deletions
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 27141e2df878..debf16c5b549 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "rt5645.h" | 31 | #include "rt5645.h" |
32 | 32 | ||
33 | #define RT5645_DEVICE_ID 0x6308 | 33 | #define RT5645_DEVICE_ID 0x6308 |
34 | #define RT5650_DEVICE_ID 0x6419 | ||
34 | 35 | ||
35 | #define RT5645_PR_RANGE_BASE (0xff + 1) | 36 | #define RT5645_PR_RANGE_BASE (0xff + 1) |
36 | #define RT5645_PR_SPACING 0x100 | 37 | #define RT5645_PR_SPACING 0x100 |
@@ -59,6 +60,10 @@ static const struct reg_default init_list[] = { | |||
59 | }; | 60 | }; |
60 | #define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list) | 61 | #define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list) |
61 | 62 | ||
63 | static const struct reg_default rt5650_init_list[] = { | ||
64 | {0xf6, 0x0100}, | ||
65 | }; | ||
66 | |||
62 | static const struct reg_default rt5645_reg[] = { | 67 | static const struct reg_default rt5645_reg[] = { |
63 | { 0x00, 0x0000 }, | 68 | { 0x00, 0x0000 }, |
64 | { 0x01, 0xc8c8 }, | 69 | { 0x01, 0xc8c8 }, |
@@ -86,6 +91,7 @@ static const struct reg_default rt5645_reg[] = { | |||
86 | { 0x2a, 0x5656 }, | 91 | { 0x2a, 0x5656 }, |
87 | { 0x2b, 0x5454 }, | 92 | { 0x2b, 0x5454 }, |
88 | { 0x2c, 0xaaa0 }, | 93 | { 0x2c, 0xaaa0 }, |
94 | { 0x2d, 0x0000 }, | ||
89 | { 0x2f, 0x1002 }, | 95 | { 0x2f, 0x1002 }, |
90 | { 0x31, 0x5000 }, | 96 | { 0x31, 0x5000 }, |
91 | { 0x32, 0x0000 }, | 97 | { 0x32, 0x0000 }, |
@@ -193,6 +199,8 @@ static const struct reg_default rt5645_reg[] = { | |||
193 | { 0xdb, 0x0003 }, | 199 | { 0xdb, 0x0003 }, |
194 | { 0xdc, 0x0049 }, | 200 | { 0xdc, 0x0049 }, |
195 | { 0xdd, 0x001b }, | 201 | { 0xdd, 0x001b }, |
202 | { 0xdf, 0x0008 }, | ||
203 | { 0xe0, 0x4000 }, | ||
196 | { 0xe6, 0x8000 }, | 204 | { 0xe6, 0x8000 }, |
197 | { 0xe7, 0x0200 }, | 205 | { 0xe7, 0x0200 }, |
198 | { 0xec, 0xb300 }, | 206 | { 0xec, 0xb300 }, |
@@ -242,6 +250,7 @@ static bool rt5645_volatile_register(struct device *dev, unsigned int reg) | |||
242 | case RT5645_IRQ_CTRL3: | 250 | case RT5645_IRQ_CTRL3: |
243 | case RT5645_INT_IRQ_ST: | 251 | case RT5645_INT_IRQ_ST: |
244 | case RT5645_IL_CMD: | 252 | case RT5645_IL_CMD: |
253 | case RT5650_4BTN_IL_CMD1: | ||
245 | case RT5645_VENDOR_ID: | 254 | case RT5645_VENDOR_ID: |
246 | case RT5645_VENDOR_ID1: | 255 | case RT5645_VENDOR_ID1: |
247 | case RT5645_VENDOR_ID2: | 256 | case RT5645_VENDOR_ID2: |
@@ -287,6 +296,7 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg) | |||
287 | case RT5645_STO_DAC_MIXER: | 296 | case RT5645_STO_DAC_MIXER: |
288 | case RT5645_MONO_DAC_MIXER: | 297 | case RT5645_MONO_DAC_MIXER: |
289 | case RT5645_DIG_MIXER: | 298 | case RT5645_DIG_MIXER: |
299 | case RT5650_A_DAC_SOUR: | ||
290 | case RT5645_DIG_INF1_DATA: | 300 | case RT5645_DIG_INF1_DATA: |
291 | case RT5645_PDM_OUT_CTRL: | 301 | case RT5645_PDM_OUT_CTRL: |
292 | case RT5645_REC_L1_MIXER: | 302 | case RT5645_REC_L1_MIXER: |
@@ -378,6 +388,8 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg) | |||
378 | case RT5645_IL_CMD: | 388 | case RT5645_IL_CMD: |
379 | case RT5645_IL_CMD2: | 389 | case RT5645_IL_CMD2: |
380 | case RT5645_IL_CMD3: | 390 | case RT5645_IL_CMD3: |
391 | case RT5650_4BTN_IL_CMD1: | ||
392 | case RT5650_4BTN_IL_CMD2: | ||
381 | case RT5645_DRC1_HL_CTRL1: | 393 | case RT5645_DRC1_HL_CTRL1: |
382 | case RT5645_DRC2_HL_CTRL1: | 394 | case RT5645_DRC2_HL_CTRL1: |
383 | case RT5645_ADC_MONO_HP_CTRL1: | 395 | case RT5645_ADC_MONO_HP_CTRL1: |
@@ -601,6 +613,87 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source, | |||
601 | 613 | ||
602 | } | 614 | } |
603 | 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 | */ | ||
630 | int 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 | } | ||
695 | EXPORT_SYMBOL_GPL(rt5645_sel_asrc_clk_src); | ||
696 | |||
604 | /* Digital Mixer */ | 697 | /* Digital Mixer */ |
605 | static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { | 698 | static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { |
606 | SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, | 699 | SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, |
@@ -1007,6 +1100,44 @@ static SOC_ENUM_SINGLE_DECL( | |||
1007 | static const struct snd_kcontrol_new rt5645_if1_adc_in_mux = | 1100 | static const struct snd_kcontrol_new rt5645_if1_adc_in_mux = |
1008 | SOC_DAPM_ENUM("IF1 ADC IN source", rt5645_if1_adc_in_enum); | 1101 | SOC_DAPM_ENUM("IF1 ADC IN source", rt5645_if1_adc_in_enum); |
1009 | 1102 | ||
1103 | /* MX-2d [3] [2] */ | ||
1104 | static const char * const rt5650_a_dac1_src[] = { | ||
1105 | "DAC1", "Stereo DAC Mixer" | ||
1106 | }; | ||
1107 | |||
1108 | static SOC_ENUM_SINGLE_DECL( | ||
1109 | rt5650_a_dac1_l_enum, RT5650_A_DAC_SOUR, | ||
1110 | RT5650_A_DAC1_L_IN_SFT, rt5650_a_dac1_src); | ||
1111 | |||
1112 | static const struct snd_kcontrol_new rt5650_a_dac1_l_mux = | ||
1113 | SOC_DAPM_ENUM("A DAC1 L source", rt5650_a_dac1_l_enum); | ||
1114 | |||
1115 | static SOC_ENUM_SINGLE_DECL( | ||
1116 | rt5650_a_dac1_r_enum, RT5650_A_DAC_SOUR, | ||
1117 | RT5650_A_DAC1_R_IN_SFT, rt5650_a_dac1_src); | ||
1118 | |||
1119 | static const struct snd_kcontrol_new rt5650_a_dac1_r_mux = | ||
1120 | SOC_DAPM_ENUM("A DAC1 R source", rt5650_a_dac1_r_enum); | ||
1121 | |||
1122 | /* MX-2d [1] [0] */ | ||
1123 | static const char * const rt5650_a_dac2_src[] = { | ||
1124 | "Stereo DAC Mixer", "Mono DAC Mixer" | ||
1125 | }; | ||
1126 | |||
1127 | static SOC_ENUM_SINGLE_DECL( | ||
1128 | rt5650_a_dac2_l_enum, RT5650_A_DAC_SOUR, | ||
1129 | RT5650_A_DAC2_L_IN_SFT, rt5650_a_dac2_src); | ||
1130 | |||
1131 | static const struct snd_kcontrol_new rt5650_a_dac2_l_mux = | ||
1132 | SOC_DAPM_ENUM("A DAC2 L source", rt5650_a_dac2_l_enum); | ||
1133 | |||
1134 | static SOC_ENUM_SINGLE_DECL( | ||
1135 | rt5650_a_dac2_r_enum, RT5650_A_DAC_SOUR, | ||
1136 | RT5650_A_DAC2_R_IN_SFT, rt5650_a_dac2_src); | ||
1137 | |||
1138 | static const struct snd_kcontrol_new rt5650_a_dac2_r_mux = | ||
1139 | SOC_DAPM_ENUM("A DAC2 R source", rt5650_a_dac2_r_enum); | ||
1140 | |||
1010 | /* MX-2F [13:12] */ | 1141 | /* MX-2F [13:12] */ |
1011 | static const char * const rt5645_if2_adc_in_src[] = { | 1142 | static const char * const rt5645_if2_adc_in_src[] = { |
1012 | "IF_ADC1", "IF_ADC2", "VAD_ADC" | 1143 | "IF_ADC1", "IF_ADC2", "VAD_ADC" |
@@ -1151,11 +1282,16 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w, | |||
1151 | case SND_SOC_DAPM_POST_PMU: | 1282 | case SND_SOC_DAPM_POST_PMU: |
1152 | hp_amp_power(codec, 1); | 1283 | hp_amp_power(codec, 1); |
1153 | /* headphone unmute sequence */ | 1284 | /* headphone unmute sequence */ |
1154 | snd_soc_update_bits(codec, RT5645_DEPOP_M3, RT5645_CP_FQ1_MASK | | 1285 | if (rt5645->codec_type == CODEC_TYPE_RT5650) { |
1155 | RT5645_CP_FQ2_MASK | RT5645_CP_FQ3_MASK, | 1286 | snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737); |
1156 | (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) | | 1287 | } else { |
1157 | (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | | 1288 | snd_soc_update_bits(codec, RT5645_DEPOP_M3, |
1158 | (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT)); | 1289 | RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK | |
1290 | RT5645_CP_FQ3_MASK, | ||
1291 | (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) | | ||
1292 | (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | | ||
1293 | (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT)); | ||
1294 | } | ||
1159 | regmap_write(rt5645->regmap, | 1295 | regmap_write(rt5645->regmap, |
1160 | RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); | 1296 | RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); |
1161 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | 1297 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, |
@@ -1175,12 +1311,16 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w, | |||
1175 | 1311 | ||
1176 | case SND_SOC_DAPM_PRE_PMD: | 1312 | case SND_SOC_DAPM_PRE_PMD: |
1177 | /* headphone mute sequence */ | 1313 | /* headphone mute sequence */ |
1178 | snd_soc_update_bits(codec, RT5645_DEPOP_M3, | 1314 | if (rt5645->codec_type == CODEC_TYPE_RT5650) { |
1179 | RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK | | 1315 | snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737); |
1180 | RT5645_CP_FQ3_MASK, | 1316 | } else { |
1181 | (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) | | 1317 | snd_soc_update_bits(codec, RT5645_DEPOP_M3, |
1182 | (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | | 1318 | RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK | |
1183 | (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT)); | 1319 | RT5645_CP_FQ3_MASK, |
1320 | (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) | | ||
1321 | (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | | ||
1322 | (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT)); | ||
1323 | } | ||
1184 | regmap_write(rt5645->regmap, | 1324 | regmap_write(rt5645->regmap, |
1185 | RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); | 1325 | RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); |
1186 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | 1326 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, |
@@ -1574,6 +1714,17 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | |||
1574 | SND_SOC_DAPM_OUTPUT("SPOR"), | 1714 | SND_SOC_DAPM_OUTPUT("SPOR"), |
1575 | }; | 1715 | }; |
1576 | 1716 | ||
1717 | static const struct snd_soc_dapm_widget rt5650_specific_dapm_widgets[] = { | ||
1718 | SND_SOC_DAPM_MUX("A DAC1 L Mux", SND_SOC_NOPM, | ||
1719 | 0, 0, &rt5650_a_dac1_l_mux), | ||
1720 | SND_SOC_DAPM_MUX("A DAC1 R Mux", SND_SOC_NOPM, | ||
1721 | 0, 0, &rt5650_a_dac1_r_mux), | ||
1722 | SND_SOC_DAPM_MUX("A DAC2 L Mux", SND_SOC_NOPM, | ||
1723 | 0, 0, &rt5650_a_dac2_l_mux), | ||
1724 | SND_SOC_DAPM_MUX("A DAC2 R Mux", SND_SOC_NOPM, | ||
1725 | 0, 0, &rt5650_a_dac2_r_mux), | ||
1726 | }; | ||
1727 | |||
1577 | static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { | 1728 | static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { |
1578 | { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc }, | 1729 | { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc }, |
1579 | { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc }, | 1730 | { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc }, |
@@ -1779,13 +1930,9 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { | |||
1779 | { "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" }, | 1930 | { "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" }, |
1780 | { "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" }, | 1931 | { "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" }, |
1781 | 1932 | ||
1782 | { "DAC L1", NULL, "Stereo DAC MIXL" }, | ||
1783 | { "DAC L1", NULL, "PLL1", is_sys_clk_from_pll }, | 1933 | { "DAC L1", NULL, "PLL1", is_sys_clk_from_pll }, |
1784 | { "DAC R1", NULL, "Stereo DAC MIXR" }, | ||
1785 | { "DAC R1", NULL, "PLL1", is_sys_clk_from_pll }, | 1934 | { "DAC R1", NULL, "PLL1", is_sys_clk_from_pll }, |
1786 | { "DAC L2", NULL, "Mono DAC MIXL" }, | ||
1787 | { "DAC L2", NULL, "PLL1", is_sys_clk_from_pll }, | 1935 | { "DAC L2", NULL, "PLL1", is_sys_clk_from_pll }, |
1788 | { "DAC R2", NULL, "Mono DAC MIXR" }, | ||
1789 | { "DAC R2", NULL, "PLL1", is_sys_clk_from_pll }, | 1936 | { "DAC R2", NULL, "PLL1", is_sys_clk_from_pll }, |
1790 | 1937 | ||
1791 | { "SPK MIXL", "BST1 Switch", "BST1" }, | 1938 | { "SPK MIXL", "BST1 Switch", "BST1" }, |
@@ -1874,6 +2021,30 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { | |||
1874 | { "SPOR", NULL, "SPK amp" }, | 2021 | { "SPOR", NULL, "SPK amp" }, |
1875 | }; | 2022 | }; |
1876 | 2023 | ||
2024 | static const struct snd_soc_dapm_route rt5650_specific_dapm_routes[] = { | ||
2025 | { "A DAC1 L Mux", "DAC1", "DAC1 MIXL"}, | ||
2026 | { "A DAC1 L Mux", "Stereo DAC Mixer", "Stereo DAC MIXL"}, | ||
2027 | { "A DAC1 R Mux", "DAC1", "DAC1 MIXR"}, | ||
2028 | { "A DAC1 R Mux", "Stereo DAC Mixer", "Stereo DAC MIXR"}, | ||
2029 | |||
2030 | { "A DAC2 L Mux", "Stereo DAC Mixer", "Stereo DAC MIXL"}, | ||
2031 | { "A DAC2 L Mux", "Mono DAC Mixer", "Mono DAC MIXL"}, | ||
2032 | { "A DAC2 R Mux", "Stereo DAC Mixer", "Stereo DAC MIXR"}, | ||
2033 | { "A DAC2 R Mux", "Mono DAC Mixer", "Mono DAC MIXR"}, | ||
2034 | |||
2035 | { "DAC L1", NULL, "A DAC1 L Mux" }, | ||
2036 | { "DAC R1", NULL, "A DAC1 R Mux" }, | ||
2037 | { "DAC L2", NULL, "A DAC2 L Mux" }, | ||
2038 | { "DAC R2", NULL, "A DAC2 R Mux" }, | ||
2039 | }; | ||
2040 | |||
2041 | static const struct snd_soc_dapm_route rt5645_specific_dapm_routes[] = { | ||
2042 | { "DAC L1", NULL, "Stereo DAC MIXL" }, | ||
2043 | { "DAC R1", NULL, "Stereo DAC MIXR" }, | ||
2044 | { "DAC L2", NULL, "Mono DAC MIXL" }, | ||
2045 | { "DAC R2", NULL, "Mono DAC MIXR" }, | ||
2046 | }; | ||
2047 | |||
1877 | static int rt5645_hw_params(struct snd_pcm_substream *substream, | 2048 | static int rt5645_hw_params(struct snd_pcm_substream *substream, |
1878 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 2049 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
1879 | { | 2050 | { |
@@ -2293,6 +2464,22 @@ static int rt5645_probe(struct snd_soc_codec *codec) | |||
2293 | 2464 | ||
2294 | rt5645->codec = codec; | 2465 | rt5645->codec = codec; |
2295 | 2466 | ||
2467 | switch (rt5645->codec_type) { | ||
2468 | case CODEC_TYPE_RT5645: | ||
2469 | snd_soc_dapm_add_routes(&codec->dapm, | ||
2470 | rt5645_specific_dapm_routes, | ||
2471 | ARRAY_SIZE(rt5645_specific_dapm_routes)); | ||
2472 | break; | ||
2473 | case CODEC_TYPE_RT5650: | ||
2474 | snd_soc_dapm_new_controls(&codec->dapm, | ||
2475 | rt5650_specific_dapm_widgets, | ||
2476 | ARRAY_SIZE(rt5650_specific_dapm_widgets)); | ||
2477 | snd_soc_dapm_add_routes(&codec->dapm, | ||
2478 | rt5650_specific_dapm_routes, | ||
2479 | ARRAY_SIZE(rt5650_specific_dapm_routes)); | ||
2480 | break; | ||
2481 | } | ||
2482 | |||
2296 | rt5645_set_bias_level(codec, SND_SOC_BIAS_OFF); | 2483 | rt5645_set_bias_level(codec, SND_SOC_BIAS_OFF); |
2297 | 2484 | ||
2298 | snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200); | 2485 | snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200); |
@@ -2424,6 +2611,7 @@ static const struct regmap_config rt5645_regmap = { | |||
2424 | 2611 | ||
2425 | static const struct i2c_device_id rt5645_i2c_id[] = { | 2612 | static const struct i2c_device_id rt5645_i2c_id[] = { |
2426 | { "rt5645", 0 }, | 2613 | { "rt5645", 0 }, |
2614 | { "rt5650", 0 }, | ||
2427 | { } | 2615 | { } |
2428 | }; | 2616 | }; |
2429 | MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id); | 2617 | MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id); |
@@ -2456,9 +2644,18 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
2456 | } | 2644 | } |
2457 | 2645 | ||
2458 | regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val); | 2646 | regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val); |
2459 | if (val != RT5645_DEVICE_ID) { | 2647 | |
2648 | switch (val) { | ||
2649 | case RT5645_DEVICE_ID: | ||
2650 | rt5645->codec_type = CODEC_TYPE_RT5645; | ||
2651 | break; | ||
2652 | case RT5650_DEVICE_ID: | ||
2653 | rt5645->codec_type = CODEC_TYPE_RT5650; | ||
2654 | break; | ||
2655 | default: | ||
2460 | dev_err(&i2c->dev, | 2656 | dev_err(&i2c->dev, |
2461 | "Device with ID register %x is not rt5645\n", val); | 2657 | "Device with ID register %x is not rt5645 or rt5650\n", |
2658 | val); | ||
2462 | return -ENODEV; | 2659 | return -ENODEV; |
2463 | } | 2660 | } |
2464 | 2661 | ||
@@ -2469,6 +2666,14 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
2469 | if (ret != 0) | 2666 | if (ret != 0) |
2470 | dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); | 2667 | dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); |
2471 | 2668 | ||
2669 | if (rt5645->codec_type == CODEC_TYPE_RT5650) { | ||
2670 | ret = regmap_register_patch(rt5645->regmap, rt5650_init_list, | ||
2671 | ARRAY_SIZE(rt5650_init_list)); | ||
2672 | if (ret != 0) | ||
2673 | dev_warn(&i2c->dev, "Apply rt5650 patch failed: %d\n", | ||
2674 | ret); | ||
2675 | } | ||
2676 | |||
2472 | if (rt5645->pdata.in2_diff) | 2677 | if (rt5645->pdata.in2_diff) |
2473 | regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL, | 2678 | regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL, |
2474 | RT5645_IN_DF2, RT5645_IN_DF2); | 2679 | RT5645_IN_DF2, RT5645_IN_DF2); |
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index a815e36a2bdb..dbfd98c22f4d 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h | |||
@@ -47,6 +47,7 @@ | |||
47 | #define RT5645_STO_DAC_MIXER 0x2a | 47 | #define RT5645_STO_DAC_MIXER 0x2a |
48 | #define RT5645_MONO_DAC_MIXER 0x2b | 48 | #define RT5645_MONO_DAC_MIXER 0x2b |
49 | #define RT5645_DIG_MIXER 0x2c | 49 | #define RT5645_DIG_MIXER 0x2c |
50 | #define RT5650_A_DAC_SOUR 0x2d | ||
50 | #define RT5645_DIG_INF1_DATA 0x2f | 51 | #define RT5645_DIG_INF1_DATA 0x2f |
51 | /* Mixer - PDM */ | 52 | /* Mixer - PDM */ |
52 | #define RT5645_PDM_OUT_CTRL 0x31 | 53 | #define RT5645_PDM_OUT_CTRL 0x31 |
@@ -150,6 +151,8 @@ | |||
150 | #define RT5645_IL_CMD 0xdb | 151 | #define RT5645_IL_CMD 0xdb |
151 | #define RT5645_IL_CMD2 0xdc | 152 | #define RT5645_IL_CMD2 0xdc |
152 | #define RT5645_IL_CMD3 0xdd | 153 | #define RT5645_IL_CMD3 0xdd |
154 | #define RT5650_4BTN_IL_CMD1 0xdf | ||
155 | #define RT5650_4BTN_IL_CMD2 0xe0 | ||
153 | #define RT5645_DRC1_HL_CTRL1 0xe7 | 156 | #define RT5645_DRC1_HL_CTRL1 0xe7 |
154 | #define RT5645_DRC2_HL_CTRL1 0xe9 | 157 | #define RT5645_DRC2_HL_CTRL1 0xe9 |
155 | #define RT5645_MUTI_DRC_CTRL1 0xea | 158 | #define RT5645_MUTI_DRC_CTRL1 0xea |
@@ -472,6 +475,12 @@ | |||
472 | #define RT5645_DAC_L2_DAC_R_VOL_MASK (0x1 << 4) | 475 | #define RT5645_DAC_L2_DAC_R_VOL_MASK (0x1 << 4) |
473 | #define RT5645_DAC_L2_DAC_R_VOL_SFT 4 | 476 | #define RT5645_DAC_L2_DAC_R_VOL_SFT 4 |
474 | 477 | ||
478 | /* Analog DAC1/2 Input Source Control (0x2d) */ | ||
479 | #define RT5650_A_DAC1_L_IN_SFT 3 | ||
480 | #define RT5650_A_DAC1_R_IN_SFT 2 | ||
481 | #define RT5650_A_DAC2_L_IN_SFT 1 | ||
482 | #define RT5650_A_DAC2_R_IN_SFT 0 | ||
483 | |||
475 | /* Digital Interface Data Control (0x2f) */ | 484 | /* Digital Interface Data Control (0x2f) */ |
476 | #define RT5645_IF1_ADC2_IN_SEL (0x1 << 15) | 485 | #define RT5645_IF1_ADC2_IN_SEL (0x1 << 15) |
477 | #define RT5645_IF1_ADC2_IN_SFT 15 | 486 | #define RT5645_IF1_ADC2_IN_SFT 15 |
@@ -1111,50 +1120,27 @@ | |||
1111 | #define RT5645_DMIC_2_M_NOR (0x0 << 8) | 1120 | #define RT5645_DMIC_2_M_NOR (0x0 << 8) |
1112 | #define RT5645_DMIC_2_M_ASYN (0x1 << 8) | 1121 | #define RT5645_DMIC_2_M_ASYN (0x1 << 8) |
1113 | 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 | |||
1114 | /* ASRC Control 2 (0x84) */ | 1129 | /* ASRC Control 2 (0x84) */ |
1115 | #define RT5645_MDA_L_M_MASK (0x1 << 15) | 1130 | #define RT5645_DA_STO_CLK_SEL_MASK (0xf << 12) |
1116 | #define RT5645_MDA_L_M_SFT 15 | 1131 | #define RT5645_DA_STO_CLK_SEL_SFT 12 |
1117 | #define RT5645_MDA_L_M_NOR (0x0 << 15) | 1132 | #define RT5645_DA_MONOL_CLK_SEL_MASK (0xf << 8) |
1118 | #define RT5645_MDA_L_M_ASYN (0x1 << 15) | 1133 | #define RT5645_DA_MONOL_CLK_SEL_SFT 8 |
1119 | #define RT5645_MDA_R_M_MASK (0x1 << 14) | 1134 | #define RT5645_DA_MONOR_CLK_SEL_MASK (0xf << 4) |
1120 | #define RT5645_MDA_R_M_SFT 14 | 1135 | #define RT5645_DA_MONOR_CLK_SEL_SFT 4 |
1121 | #define RT5645_MDA_R_M_NOR (0x0 << 14) | 1136 | #define RT5645_AD_STO1_CLK_SEL_MASK (0xf << 0) |
1122 | #define RT5645_MDA_R_M_ASYN (0x1 << 14) | 1137 | #define RT5645_AD_STO1_CLK_SEL_SFT 0 |
1123 | #define RT5645_MAD_L_M_MASK (0x1 << 13) | ||
1124 | #define RT5645_MAD_L_M_SFT 13 | ||
1125 | #define RT5645_MAD_L_M_NOR (0x0 << 13) | ||
1126 | #define RT5645_MAD_L_M_ASYN (0x1 << 13) | ||
1127 | #define RT5645_MAD_R_M_MASK (0x1 << 12) | ||
1128 | #define RT5645_MAD_R_M_SFT 12 | ||
1129 | #define RT5645_MAD_R_M_NOR (0x0 << 12) | ||
1130 | #define RT5645_MAD_R_M_ASYN (0x1 << 12) | ||
1131 | #define RT5645_ADC_M_MASK (0x1 << 11) | ||
1132 | #define RT5645_ADC_M_SFT 11 | ||
1133 | #define RT5645_ADC_M_NOR (0x0 << 11) | ||
1134 | #define RT5645_ADC_M_ASYN (0x1 << 11) | ||
1135 | #define RT5645_STO_DAC_M_MASK (0x1 << 5) | ||
1136 | #define RT5645_STO_DAC_M_SFT 5 | ||
1137 | #define RT5645_STO_DAC_M_NOR (0x0 << 5) | ||
1138 | #define RT5645_STO_DAC_M_ASYN (0x1 << 5) | ||
1139 | #define RT5645_I2S1_R_D_MASK (0x1 << 4) | ||
1140 | #define RT5645_I2S1_R_D_SFT 4 | ||
1141 | #define RT5645_I2S1_R_D_DIS (0x0 << 4) | ||
1142 | #define RT5645_I2S1_R_D_EN (0x1 << 4) | ||
1143 | #define RT5645_I2S2_R_D_MASK (0x1 << 3) | ||
1144 | #define RT5645_I2S2_R_D_SFT 3 | ||
1145 | #define RT5645_I2S2_R_D_DIS (0x0 << 3) | ||
1146 | #define RT5645_I2S2_R_D_EN (0x1 << 3) | ||
1147 | #define RT5645_PRE_SCLK_MASK (0x3) | ||
1148 | #define RT5645_PRE_SCLK_SFT 0 | ||
1149 | #define RT5645_PRE_SCLK_512 (0x0) | ||
1150 | #define RT5645_PRE_SCLK_1024 (0x1) | ||
1151 | #define RT5645_PRE_SCLK_2048 (0x2) | ||
1152 | 1138 | ||
1153 | /* ASRC Control 3 (0x85) */ | 1139 | /* ASRC Control 3 (0x85) */ |
1154 | #define RT5645_I2S1_RATE_MASK (0xf << 12) | 1140 | #define RT5645_AD_MONOL_CLK_SEL_MASK (0xf << 4) |
1155 | #define RT5645_I2S1_RATE_SFT 12 | 1141 | #define RT5645_AD_MONOL_CLK_SEL_SFT 4 |
1156 | #define RT5645_I2S2_RATE_MASK (0xf << 8) | 1142 | #define RT5645_AD_MONOR_CLK_SEL_MASK (0xf << 0) |
1157 | #define RT5645_I2S2_RATE_SFT 8 | 1143 | #define RT5645_AD_MONOR_CLK_SEL_SFT 0 |
1158 | 1144 | ||
1159 | /* ASRC Control 4 (0x89) */ | 1145 | /* ASRC Control 4 (0x89) */ |
1160 | #define RT5645_I2S1_PD_MASK (0x7 << 12) | 1146 | #define RT5645_I2S1_PD_MASK (0x7 << 12) |
@@ -2175,6 +2161,24 @@ enum { | |||
2175 | RT5645_DMIC_DATA_GPIO11, | 2161 | RT5645_DMIC_DATA_GPIO11, |
2176 | }; | 2162 | }; |
2177 | 2163 | ||
2164 | enum { | ||
2165 | CODEC_TYPE_RT5645, | ||
2166 | CODEC_TYPE_RT5650, | ||
2167 | }; | ||
2168 | |||
2169 | /* filter mask */ | ||
2170 | enum { | ||
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 | |||
2179 | int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec, | ||
2180 | unsigned int filter_mask, unsigned int clk_src); | ||
2181 | |||
2178 | struct rt5645_priv { | 2182 | struct rt5645_priv { |
2179 | struct snd_soc_codec *codec; | 2183 | struct snd_soc_codec *codec; |
2180 | struct rt5645_platform_data pdata; | 2184 | struct rt5645_platform_data pdata; |
@@ -2184,6 +2188,7 @@ struct rt5645_priv { | |||
2184 | struct snd_soc_jack *mic_jack; | 2188 | struct snd_soc_jack *mic_jack; |
2185 | struct delayed_work jack_detect_work; | 2189 | struct delayed_work jack_detect_work; |
2186 | 2190 | ||
2191 | int codec_type; | ||
2187 | int sysclk; | 2192 | int sysclk; |
2188 | int sysclk_src; | 2193 | int sysclk_src; |
2189 | int lrck[RT5645_AIFS]; | 2194 | int lrck[RT5645_AIFS]; |