diff options
| -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]; |
