aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2015-02-05 13:10:32 -0500
committerMark Brown <broonie@kernel.org>2015-02-05 13:10:32 -0500
commitb4964bb356ef9651478e555105586b6f5111fc14 (patch)
tree4ae969755339304f7403bbf645e58f94afd8d490 /sound
parentcd311dd123f5ae5c6da71bdfa9a379a694eb9917 (diff)
parent79080a8b42a08fb68a1ea2e036e54a4749edbd43 (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.c239
-rw-r--r--sound/soc/codecs/rt5645.h87
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
63static const struct reg_default rt5650_init_list[] = {
64 {0xf6, 0x0100},
65};
66
62static const struct reg_default rt5645_reg[] = { 67static 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 */
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
604/* Digital Mixer */ 697/* Digital Mixer */
605static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { 698static 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(
1007static const struct snd_kcontrol_new rt5645_if1_adc_in_mux = 1100static 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] */
1104static const char * const rt5650_a_dac1_src[] = {
1105 "DAC1", "Stereo DAC Mixer"
1106};
1107
1108static 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
1112static const struct snd_kcontrol_new rt5650_a_dac1_l_mux =
1113 SOC_DAPM_ENUM("A DAC1 L source", rt5650_a_dac1_l_enum);
1114
1115static 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
1119static 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] */
1123static const char * const rt5650_a_dac2_src[] = {
1124 "Stereo DAC Mixer", "Mono DAC Mixer"
1125};
1126
1127static 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
1131static const struct snd_kcontrol_new rt5650_a_dac2_l_mux =
1132 SOC_DAPM_ENUM("A DAC2 L source", rt5650_a_dac2_l_enum);
1133
1134static 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
1138static 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] */
1011static const char * const rt5645_if2_adc_in_src[] = { 1142static 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
1717static 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
1577static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { 1728static 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
2024static 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
2041static 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
1877static int rt5645_hw_params(struct snd_pcm_substream *substream, 2048static 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
2425static const struct i2c_device_id rt5645_i2c_id[] = { 2612static const struct i2c_device_id rt5645_i2c_id[] = {
2426 { "rt5645", 0 }, 2613 { "rt5645", 0 },
2614 { "rt5650", 0 },
2427 { } 2615 { }
2428}; 2616};
2429MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id); 2617MODULE_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
2164enum {
2165 CODEC_TYPE_RT5645,
2166 CODEC_TYPE_RT5650,
2167};
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
2178struct rt5645_priv { 2182struct 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];