aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5514.txt15
-rw-r--r--Documentation/devicetree/bindings/sound/mt8173-rt5650.txt15
-rw-r--r--sound/soc/codecs/max98926.c4
-rw-r--r--sound/soc/codecs/nau8825.c169
-rw-r--r--sound/soc/codecs/nau8825.h16
-rw-r--r--sound/soc/mediatek/Kconfig22
-rw-r--r--sound/soc/mediatek/Makefile2
-rw-r--r--sound/soc/mediatek/mt8173-rt5650-rt5514.c258
-rw-r--r--sound/soc/mediatek/mt8173-rt5650-rt5676.c18
-rw-r--r--sound/soc/mediatek/mt8173-rt5650.c236
-rw-r--r--sound/soc/mediatek/mtk-afe-common.h1
-rw-r--r--sound/soc/mediatek/mtk-afe-pcm.c47
-rw-r--r--sound/soc/mxs/mxs-saif.c2
-rw-r--r--sound/soc/omap/omap-hdmi-audio.c1
14 files changed, 744 insertions, 62 deletions
diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5514.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5514.txt
new file mode 100644
index 000000000000..e8b3c80c6fff
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5514.txt
@@ -0,0 +1,15 @@
1MT8173 with RT5650 RT5514 CODECS
2
3Required properties:
4- compatible : "mediatek,mt8173-rt5650-rt5514"
5- mediatek,audio-codec: the phandles of rt5650 and rt5514 codecs
6- mediatek,platform: the phandle of MT8173 ASoC platform
7
8Example:
9
10 sound {
11 compatible = "mediatek,mt8173-rt5650-rt5514";
12 mediatek,audio-codec = <&rt5650 &rt5514>;
13 mediatek,platform = <&afe>;
14 };
15
diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650.txt
new file mode 100644
index 000000000000..fe5a5ef1714d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650.txt
@@ -0,0 +1,15 @@
1MT8173 with RT5650 CODECS
2
3Required properties:
4- compatible : "mediatek,mt8173-rt5650"
5- mediatek,audio-codec: the phandles of rt5650 codecs
6- mediatek,platform: the phandle of MT8173 ASoC platform
7
8Example:
9
10 sound {
11 compatible = "mediatek,mt8173-rt5650";
12 mediatek,audio-codec = <&rt5650>;
13 mediatek,platform = <&afe>;
14 };
15
diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c
index 5245e107de30..8d14adae5cc5 100644
--- a/sound/soc/codecs/max98926.c
+++ b/sound/soc/codecs/max98926.c
@@ -40,7 +40,7 @@ static const char *const max98926_hpf_cutoff_txt[] = {
40 "200Hz", "400Hz", "800Hz", 40 "200Hz", "400Hz", "800Hz",
41}; 41};
42 42
43static struct reg_default max98926_reg[] = { 43static const struct reg_default max98926_reg[] = {
44 { 0x0B, 0x00 }, /* IRQ Enable0 */ 44 { 0x0B, 0x00 }, /* IRQ Enable0 */
45 { 0x0C, 0x00 }, /* IRQ Enable1 */ 45 { 0x0C, 0x00 }, /* IRQ Enable1 */
46 { 0x0D, 0x00 }, /* IRQ Enable2 */ 46 { 0x0D, 0x00 }, /* IRQ Enable2 */
@@ -506,7 +506,7 @@ static struct snd_soc_codec_driver soc_codec_dev_max98926 = {
506 .num_dapm_widgets = ARRAY_SIZE(max98926_dapm_widgets), 506 .num_dapm_widgets = ARRAY_SIZE(max98926_dapm_widgets),
507}; 507};
508 508
509static struct regmap_config max98926_regmap = { 509static const struct regmap_config max98926_regmap = {
510 .reg_bits = 8, 510 .reg_bits = 8,
511 .val_bits = 8, 511 .val_bits = 8,
512 .max_register = MAX98926_VERSION, 512 .max_register = MAX98926_VERSION,
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index c1b87c5800b1..1c8729984c2b 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -84,6 +84,7 @@ static const struct nau8825_fll_attr fll_pre_scalar[] = {
84 84
85static const struct reg_default nau8825_reg_defaults[] = { 85static const struct reg_default nau8825_reg_defaults[] = {
86 { NAU8825_REG_ENA_CTRL, 0x00ff }, 86 { NAU8825_REG_ENA_CTRL, 0x00ff },
87 { NAU8825_REG_IIC_ADDR_SET, 0x0 },
87 { NAU8825_REG_CLK_DIVIDER, 0x0050 }, 88 { NAU8825_REG_CLK_DIVIDER, 0x0050 },
88 { NAU8825_REG_FLL1, 0x0 }, 89 { NAU8825_REG_FLL1, 0x0 },
89 { NAU8825_REG_FLL2, 0x3126 }, 90 { NAU8825_REG_FLL2, 0x3126 },
@@ -158,8 +159,7 @@ static const struct reg_default nau8825_reg_defaults[] = {
158static bool nau8825_readable_reg(struct device *dev, unsigned int reg) 159static bool nau8825_readable_reg(struct device *dev, unsigned int reg)
159{ 160{
160 switch (reg) { 161 switch (reg) {
161 case NAU8825_REG_ENA_CTRL: 162 case NAU8825_REG_ENA_CTRL ... NAU8825_REG_FLL_VCO_RSV:
162 case NAU8825_REG_CLK_DIVIDER ... NAU8825_REG_FLL_VCO_RSV:
163 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL: 163 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL:
164 case NAU8825_REG_INTERRUPT_MASK ... NAU8825_REG_KEYDET_CTRL: 164 case NAU8825_REG_INTERRUPT_MASK ... NAU8825_REG_KEYDET_CTRL:
165 case NAU8825_REG_VDET_THRESHOLD_1 ... NAU8825_REG_DACR_CTRL: 165 case NAU8825_REG_VDET_THRESHOLD_1 ... NAU8825_REG_DACR_CTRL:
@@ -184,8 +184,7 @@ static bool nau8825_readable_reg(struct device *dev, unsigned int reg)
184static bool nau8825_writeable_reg(struct device *dev, unsigned int reg) 184static bool nau8825_writeable_reg(struct device *dev, unsigned int reg)
185{ 185{
186 switch (reg) { 186 switch (reg) {
187 case NAU8825_REG_RESET ... NAU8825_REG_ENA_CTRL: 187 case NAU8825_REG_RESET ... NAU8825_REG_FLL_VCO_RSV:
188 case NAU8825_REG_CLK_DIVIDER ... NAU8825_REG_FLL_VCO_RSV:
189 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL: 188 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL:
190 case NAU8825_REG_INTERRUPT_MASK: 189 case NAU8825_REG_INTERRUPT_MASK:
191 case NAU8825_REG_INT_CLR_KEY_STATUS ... NAU8825_REG_KEYDET_CTRL: 190 case NAU8825_REG_INT_CLR_KEY_STATUS ... NAU8825_REG_KEYDET_CTRL:
@@ -227,10 +226,42 @@ static bool nau8825_volatile_reg(struct device *dev, unsigned int reg)
227static int nau8825_pump_event(struct snd_soc_dapm_widget *w, 226static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
228 struct snd_kcontrol *kcontrol, int event) 227 struct snd_kcontrol *kcontrol, int event)
229{ 228{
229 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
230 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
231
230 switch (event) { 232 switch (event) {
231 case SND_SOC_DAPM_POST_PMU: 233 case SND_SOC_DAPM_POST_PMU:
232 /* Prevent startup click by letting charge pump to ramp up */ 234 /* Prevent startup click by letting charge pump to ramp up */
233 msleep(10); 235 msleep(10);
236 regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
237 NAU8825_JAMNODCLOW, NAU8825_JAMNODCLOW);
238 break;
239 case SND_SOC_DAPM_PRE_PMD:
240 regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
241 NAU8825_JAMNODCLOW, 0);
242 break;
243 default:
244 return -EINVAL;
245 }
246
247 return 0;
248}
249
250static int nau8825_output_dac_event(struct snd_soc_dapm_widget *w,
251 struct snd_kcontrol *kcontrol, int event)
252{
253 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
254 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
255
256 switch (event) {
257 case SND_SOC_DAPM_PRE_PMU:
258 /* Disables the TESTDAC to let DAC signal pass through. */
259 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
260 NAU8825_BIAS_TESTDAC_EN, 0);
261 break;
262 case SND_SOC_DAPM_POST_PMD:
263 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
264 NAU8825_BIAS_TESTDAC_EN, NAU8825_BIAS_TESTDAC_EN);
234 break; 265 break;
235 default: 266 default:
236 return -EINVAL; 267 return -EINVAL;
@@ -316,10 +347,10 @@ static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = {
316 SND_SOC_DAPM_ADC("SAR", NULL, NAU8825_REG_SAR_CTRL, 347 SND_SOC_DAPM_ADC("SAR", NULL, NAU8825_REG_SAR_CTRL,
317 NAU8825_SAR_ADC_EN_SFT, 0), 348 NAU8825_SAR_ADC_EN_SFT, 0),
318 349
319 SND_SOC_DAPM_DAC("ADACL", NULL, NAU8825_REG_RDAC, 12, 0), 350 SND_SOC_DAPM_PGA_S("ADACL", 2, NAU8825_REG_RDAC, 12, 0, NULL, 0),
320 SND_SOC_DAPM_DAC("ADACR", NULL, NAU8825_REG_RDAC, 13, 0), 351 SND_SOC_DAPM_PGA_S("ADACR", 2, NAU8825_REG_RDAC, 13, 0, NULL, 0),
321 SND_SOC_DAPM_SUPPLY("ADACL Clock", NAU8825_REG_RDAC, 8, 0, NULL, 0), 352 SND_SOC_DAPM_PGA_S("ADACL Clock", 3, NAU8825_REG_RDAC, 8, 0, NULL, 0),
322 SND_SOC_DAPM_SUPPLY("ADACR Clock", NAU8825_REG_RDAC, 9, 0, NULL, 0), 353 SND_SOC_DAPM_PGA_S("ADACR Clock", 3, NAU8825_REG_RDAC, 9, 0, NULL, 0),
323 354
324 SND_SOC_DAPM_DAC("DDACR", NULL, NAU8825_REG_ENA_CTRL, 355 SND_SOC_DAPM_DAC("DDACR", NULL, NAU8825_REG_ENA_CTRL,
325 NAU8825_ENABLE_DACR_SFT, 0), 356 NAU8825_ENABLE_DACR_SFT, 0),
@@ -330,29 +361,48 @@ static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = {
330 SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacl_mux), 361 SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacl_mux),
331 SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacr_mux), 362 SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacr_mux),
332 363
333 SND_SOC_DAPM_PGA("HP amp L", NAU8825_REG_CLASSG_CTRL, 1, 0, NULL, 0), 364 SND_SOC_DAPM_PGA_S("HP amp L", 0,
334 SND_SOC_DAPM_PGA("HP amp R", NAU8825_REG_CLASSG_CTRL, 2, 0, NULL, 0), 365 NAU8825_REG_CLASSG_CTRL, 1, 0, NULL, 0),
335 SND_SOC_DAPM_SUPPLY("HP amp power", NAU8825_REG_CLASSG_CTRL, 0, 0, NULL, 366 SND_SOC_DAPM_PGA_S("HP amp R", 0,
336 0), 367 NAU8825_REG_CLASSG_CTRL, 2, 0, NULL, 0),
337 368
338 SND_SOC_DAPM_SUPPLY("Charge Pump", NAU8825_REG_CHARGE_PUMP, 5, 0, 369 SND_SOC_DAPM_PGA_S("Charge Pump", 1, NAU8825_REG_CHARGE_PUMP, 5, 0,
339 nau8825_pump_event, SND_SOC_DAPM_POST_PMU), 370 nau8825_pump_event, SND_SOC_DAPM_POST_PMU |
371 SND_SOC_DAPM_PRE_PMD),
340 372
341 SND_SOC_DAPM_PGA("Output Driver R Stage 1", 373 SND_SOC_DAPM_PGA_S("Output Driver R Stage 1", 4,
342 NAU8825_REG_POWER_UP_CONTROL, 5, 0, NULL, 0), 374 NAU8825_REG_POWER_UP_CONTROL, 5, 0, NULL, 0),
343 SND_SOC_DAPM_PGA("Output Driver L Stage 1", 375 SND_SOC_DAPM_PGA_S("Output Driver L Stage 1", 4,
344 NAU8825_REG_POWER_UP_CONTROL, 4, 0, NULL, 0), 376 NAU8825_REG_POWER_UP_CONTROL, 4, 0, NULL, 0),
345 SND_SOC_DAPM_PGA("Output Driver R Stage 2", 377 SND_SOC_DAPM_PGA_S("Output Driver R Stage 2", 5,
346 NAU8825_REG_POWER_UP_CONTROL, 3, 0, NULL, 0), 378 NAU8825_REG_POWER_UP_CONTROL, 3, 0, NULL, 0),
347 SND_SOC_DAPM_PGA("Output Driver L Stage 2", 379 SND_SOC_DAPM_PGA_S("Output Driver L Stage 2", 5,
348 NAU8825_REG_POWER_UP_CONTROL, 2, 0, NULL, 0), 380 NAU8825_REG_POWER_UP_CONTROL, 2, 0, NULL, 0),
349 SND_SOC_DAPM_PGA_S("Output Driver R Stage 3", 1, 381 SND_SOC_DAPM_PGA_S("Output Driver R Stage 3", 6,
350 NAU8825_REG_POWER_UP_CONTROL, 1, 0, NULL, 0), 382 NAU8825_REG_POWER_UP_CONTROL, 1, 0, NULL, 0),
351 SND_SOC_DAPM_PGA_S("Output Driver L Stage 3", 1, 383 SND_SOC_DAPM_PGA_S("Output Driver L Stage 3", 6,
352 NAU8825_REG_POWER_UP_CONTROL, 0, 0, NULL, 0), 384 NAU8825_REG_POWER_UP_CONTROL, 0, 0, NULL, 0),
353 385
354 SND_SOC_DAPM_PGA_S("Output DACL", 2, NAU8825_REG_CHARGE_PUMP, 8, 1, NULL, 0), 386 SND_SOC_DAPM_PGA_S("Output DACL", 7,
355 SND_SOC_DAPM_PGA_S("Output DACR", 2, NAU8825_REG_CHARGE_PUMP, 9, 1, NULL, 0), 387 NAU8825_REG_CHARGE_PUMP, 8, 1, nau8825_output_dac_event,
388 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
389 SND_SOC_DAPM_PGA_S("Output DACR", 7,
390 NAU8825_REG_CHARGE_PUMP, 9, 1, nau8825_output_dac_event,
391 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
392
393 /* HPOL/R are ungrounded by disabling 16 Ohm pull-downs on playback */
394 SND_SOC_DAPM_PGA_S("HPOL Pulldown", 8,
395 NAU8825_REG_HSD_CTRL, 0, 1, NULL, 0),
396 SND_SOC_DAPM_PGA_S("HPOR Pulldown", 8,
397 NAU8825_REG_HSD_CTRL, 1, 1, NULL, 0),
398
399 /* High current HPOL/R boost driver */
400 SND_SOC_DAPM_PGA_S("HP Boost Driver", 9,
401 NAU8825_REG_BOOST, 9, 1, NULL, 0),
402
403 /* Class G operation control*/
404 SND_SOC_DAPM_PGA_S("Class G", 10,
405 NAU8825_REG_CLASSG_CTRL, 0, 0, NULL, 0),
356 406
357 SND_SOC_DAPM_OUTPUT("HPOL"), 407 SND_SOC_DAPM_OUTPUT("HPOL"),
358 SND_SOC_DAPM_OUTPUT("HPOR"), 408 SND_SOC_DAPM_OUTPUT("HPOR"),
@@ -375,24 +425,27 @@ static const struct snd_soc_dapm_route nau8825_dapm_routes[] = {
375 {"DACR Mux", "DACR", "DDACR"}, 425 {"DACR Mux", "DACR", "DDACR"},
376 {"HP amp L", NULL, "DACL Mux"}, 426 {"HP amp L", NULL, "DACL Mux"},
377 {"HP amp R", NULL, "DACR Mux"}, 427 {"HP amp R", NULL, "DACR Mux"},
378 {"HP amp L", NULL, "HP amp power"}, 428 {"Charge Pump", NULL, "HP amp L"},
379 {"HP amp R", NULL, "HP amp power"}, 429 {"Charge Pump", NULL, "HP amp R"},
380 {"ADACL", NULL, "HP amp L"}, 430 {"ADACL", NULL, "Charge Pump"},
381 {"ADACR", NULL, "HP amp R"}, 431 {"ADACR", NULL, "Charge Pump"},
382 {"ADACL", NULL, "ADACL Clock"}, 432 {"ADACL Clock", NULL, "ADACL"},
383 {"ADACR", NULL, "ADACR Clock"}, 433 {"ADACR Clock", NULL, "ADACR"},
384 {"Output Driver L Stage 1", NULL, "ADACL"}, 434 {"Output Driver L Stage 1", NULL, "ADACL Clock"},
385 {"Output Driver R Stage 1", NULL, "ADACR"}, 435 {"Output Driver R Stage 1", NULL, "ADACR Clock"},
386 {"Output Driver L Stage 2", NULL, "Output Driver L Stage 1"}, 436 {"Output Driver L Stage 2", NULL, "Output Driver L Stage 1"},
387 {"Output Driver R Stage 2", NULL, "Output Driver R Stage 1"}, 437 {"Output Driver R Stage 2", NULL, "Output Driver R Stage 1"},
388 {"Output Driver L Stage 3", NULL, "Output Driver L Stage 2"}, 438 {"Output Driver L Stage 3", NULL, "Output Driver L Stage 2"},
389 {"Output Driver R Stage 3", NULL, "Output Driver R Stage 2"}, 439 {"Output Driver R Stage 3", NULL, "Output Driver R Stage 2"},
390 {"Output DACL", NULL, "Output Driver L Stage 3"}, 440 {"Output DACL", NULL, "Output Driver L Stage 3"},
391 {"Output DACR", NULL, "Output Driver R Stage 3"}, 441 {"Output DACR", NULL, "Output Driver R Stage 3"},
392 {"HPOL", NULL, "Output DACL"}, 442 {"HPOL Pulldown", NULL, "Output DACL"},
393 {"HPOR", NULL, "Output DACR"}, 443 {"HPOR Pulldown", NULL, "Output DACR"},
394 {"HPOL", NULL, "Charge Pump"}, 444 {"HP Boost Driver", NULL, "HPOL Pulldown"},
395 {"HPOR", NULL, "Charge Pump"}, 445 {"HP Boost Driver", NULL, "HPOR Pulldown"},
446 {"Class G", NULL, "HP Boost Driver"},
447 {"HPOL", NULL, "Class G"},
448 {"HPOR", NULL, "Class G"},
396}; 449};
397 450
398static int nau8825_hw_params(struct snd_pcm_substream *substream, 451static int nau8825_hw_params(struct snd_pcm_substream *substream,
@@ -659,11 +712,10 @@ static int nau8825_jack_insert(struct nau8825 *nau8825)
659 break; 712 break;
660 } 713 }
661 714
662 if (type & SND_JACK_HEADPHONE) { 715 /* Leaving HPOL/R grounded after jack insert by default. They will be
663 /* Unground HPL/R */ 716 * ungrounded as part of the widget power up sequence at the beginning
664 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 0x3, 0); 717 * of playback to reduce pop.
665 } 718 */
666
667 return type; 719 return type;
668} 720}
669 721
@@ -768,6 +820,8 @@ static void nau8825_init_regs(struct nau8825 *nau8825)
768{ 820{
769 struct regmap *regmap = nau8825->regmap; 821 struct regmap *regmap = nau8825->regmap;
770 822
823 /* Latch IIC LSB value */
824 regmap_write(regmap, NAU8825_REG_IIC_ADDR_SET, 0x0001);
771 /* Enable Bias/Vmid */ 825 /* Enable Bias/Vmid */
772 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ, 826 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
773 NAU8825_BIAS_VMID, NAU8825_BIAS_VMID); 827 NAU8825_BIAS_VMID, NAU8825_BIAS_VMID);
@@ -780,10 +834,10 @@ static void nau8825_init_regs(struct nau8825 *nau8825)
780 nau8825->vref_impedance << NAU8825_BIAS_VMID_SEL_SFT); 834 nau8825->vref_impedance << NAU8825_BIAS_VMID_SEL_SFT);
781 /* Disable Boost Driver, Automatic Short circuit protection enable */ 835 /* Disable Boost Driver, Automatic Short circuit protection enable */
782 regmap_update_bits(regmap, NAU8825_REG_BOOST, 836 regmap_update_bits(regmap, NAU8825_REG_BOOST,
783 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_G_DIS | 837 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_DIS |
784 NAU8825_SHORT_SHUTDOWN_EN, 838 NAU8825_HP_BOOST_G_DIS | NAU8825_SHORT_SHUTDOWN_EN,
785 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_G_DIS | 839 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_DIS |
786 NAU8825_SHORT_SHUTDOWN_EN); 840 NAU8825_HP_BOOST_G_DIS | NAU8825_SHORT_SHUTDOWN_EN);
787 841
788 regmap_update_bits(regmap, NAU8825_REG_GPIO12_CTRL, 842 regmap_update_bits(regmap, NAU8825_REG_GPIO12_CTRL,
789 NAU8825_JKDET_OUTPUT_EN, 843 NAU8825_JKDET_OUTPUT_EN,
@@ -822,6 +876,35 @@ static void nau8825_init_regs(struct nau8825 *nau8825)
822 NAU8825_ADC_SYNC_DOWN_MASK, NAU8825_ADC_SYNC_DOWN_128); 876 NAU8825_ADC_SYNC_DOWN_MASK, NAU8825_ADC_SYNC_DOWN_128);
823 regmap_update_bits(regmap, NAU8825_REG_DAC_CTRL1, 877 regmap_update_bits(regmap, NAU8825_REG_DAC_CTRL1,
824 NAU8825_DAC_OVERSAMPLE_MASK, NAU8825_DAC_OVERSAMPLE_128); 878 NAU8825_DAC_OVERSAMPLE_MASK, NAU8825_DAC_OVERSAMPLE_128);
879 /* Disable DACR/L power */
880 regmap_update_bits(regmap, NAU8825_REG_CHARGE_PUMP,
881 NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL,
882 NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL);
883 /* Enable TESTDAC. This sets the analog DAC inputs to a '0' input
884 * signal to avoid any glitches due to power up transients in both
885 * the analog and digital DAC circuit.
886 */
887 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
888 NAU8825_BIAS_TESTDAC_EN, NAU8825_BIAS_TESTDAC_EN);
889 /* CICCLP off */
890 regmap_update_bits(regmap, NAU8825_REG_DAC_CTRL1,
891 NAU8825_DAC_CLIP_OFF, NAU8825_DAC_CLIP_OFF);
892
893 /* Class AB bias current to 2x, DAC Capacitor enable MSB/LSB */
894 regmap_update_bits(regmap, NAU8825_REG_ANALOG_CONTROL_2,
895 NAU8825_HP_NON_CLASSG_CURRENT_2xADJ |
896 NAU8825_DAC_CAPACITOR_MSB | NAU8825_DAC_CAPACITOR_LSB,
897 NAU8825_HP_NON_CLASSG_CURRENT_2xADJ |
898 NAU8825_DAC_CAPACITOR_MSB | NAU8825_DAC_CAPACITOR_LSB);
899 /* Class G timer 64ms */
900 regmap_update_bits(regmap, NAU8825_REG_CLASSG_CTRL,
901 NAU8825_CLASSG_TIMER_MASK,
902 0x20 << NAU8825_CLASSG_TIMER_SFT);
903 /* DAC clock delay 2ns, VREF */
904 regmap_update_bits(regmap, NAU8825_REG_RDAC,
905 NAU8825_RDAC_CLK_DELAY_MASK | NAU8825_RDAC_VREF_MASK,
906 (0x2 << NAU8825_RDAC_CLK_DELAY_SFT) |
907 (0x3 << NAU8825_RDAC_VREF_SFT));
825} 908}
826 909
827static const struct regmap_config nau8825_regmap_config = { 910static const struct regmap_config nau8825_regmap_config = {
diff --git a/sound/soc/codecs/nau8825.h b/sound/soc/codecs/nau8825.h
index dff8edb83bfd..8ceb5f385478 100644
--- a/sound/soc/codecs/nau8825.h
+++ b/sound/soc/codecs/nau8825.h
@@ -14,6 +14,7 @@
14 14
15#define NAU8825_REG_RESET 0x00 15#define NAU8825_REG_RESET 0x00
16#define NAU8825_REG_ENA_CTRL 0x01 16#define NAU8825_REG_ENA_CTRL 0x01
17#define NAU8825_REG_IIC_ADDR_SET 0x02
17#define NAU8825_REG_CLK_DIVIDER 0x03 18#define NAU8825_REG_CLK_DIVIDER 0x03
18#define NAU8825_REG_FLL1 0x04 19#define NAU8825_REG_FLL1 0x04
19#define NAU8825_REG_FLL2 0x05 20#define NAU8825_REG_FLL2 0x05
@@ -129,7 +130,7 @@
129 130
130/* HSD_CTRL (0xc) */ 131/* HSD_CTRL (0xc) */
131#define NAU8825_HSD_AUTO_MODE (1 << 6) 132#define NAU8825_HSD_AUTO_MODE (1 << 6)
132/* 0 - short to GND, 1 - open */ 133/* 0 - open, 1 - short to GND */
133#define NAU8825_SPKR_DWN1R (1 << 1) 134#define NAU8825_SPKR_DWN1R (1 << 1)
134#define NAU8825_SPKR_DWN1L (1 << 0) 135#define NAU8825_SPKR_DWN1L (1 << 0)
135 136
@@ -251,12 +252,18 @@
251/* DACR_CTRL (0x34) */ 252/* DACR_CTRL (0x34) */
252#define NAU8825_DACR_CH_SEL_SFT 9 253#define NAU8825_DACR_CH_SEL_SFT 9
253 254
255/* CLASSG_CTRL (0x50) */
256#define NAU8825_CLASSG_TIMER_SFT 8
257#define NAU8825_CLASSG_TIMER_MASK (0x3f << NAU8825_CLASSG_TIMER_SFT)
258#define NAU8825_CLASSG_EN (1 << 0)
259
254/* I2C_DEVICE_ID (0x58) */ 260/* I2C_DEVICE_ID (0x58) */
255#define NAU8825_GPIO2JD1 (1 << 7) 261#define NAU8825_GPIO2JD1 (1 << 7)
256#define NAU8825_SOFTWARE_ID_MASK 0x3 262#define NAU8825_SOFTWARE_ID_MASK 0x3
257#define NAU8825_SOFTWARE_ID_NAU8825 0x0 263#define NAU8825_SOFTWARE_ID_NAU8825 0x0
258 264
259/* BIAS_ADJ (0x66) */ 265/* BIAS_ADJ (0x66) */
266#define NAU8825_BIAS_TESTDAC_EN (0x3 << 8)
260#define NAU8825_BIAS_VMID (1 << 6) 267#define NAU8825_BIAS_VMID (1 << 6)
261#define NAU8825_BIAS_VMID_SEL_SFT 4 268#define NAU8825_BIAS_VMID_SEL_SFT 4
262#define NAU8825_BIAS_VMID_SEL_MASK (3 << NAU8825_BIAS_VMID_SEL_SFT) 269#define NAU8825_BIAS_VMID_SEL_MASK (3 << NAU8825_BIAS_VMID_SEL_SFT)
@@ -274,6 +281,12 @@
274#define NAU8825_ADC_VREFSEL_VMID_PLUS_1DB (3 << 8) 281#define NAU8825_ADC_VREFSEL_VMID_PLUS_1DB (3 << 8)
275#define NAU8825_POWERUP_ADCL (1 << 6) 282#define NAU8825_POWERUP_ADCL (1 << 6)
276 283
284/* RDAC (0x73) */
285#define NAU8825_RDAC_CLK_DELAY_SFT 4
286#define NAU8825_RDAC_CLK_DELAY_MASK (0x7 << NAU8825_RDAC_CLK_DELAY_SFT)
287#define NAU8825_RDAC_VREF_SFT 2
288#define NAU8825_RDAC_VREF_MASK (0x3 << NAU8825_RDAC_VREF_SFT)
289
277/* MIC_BIAS (0x74) */ 290/* MIC_BIAS (0x74) */
278#define NAU8825_MICBIAS_JKSLV (1 << 14) 291#define NAU8825_MICBIAS_JKSLV (1 << 14)
279#define NAU8825_MICBIAS_JKR2 (1 << 12) 292#define NAU8825_MICBIAS_JKR2 (1 << 12)
@@ -284,6 +297,7 @@
284/* BOOST (0x76) */ 297/* BOOST (0x76) */
285#define NAU8825_PRECHARGE_DIS (1 << 13) 298#define NAU8825_PRECHARGE_DIS (1 << 13)
286#define NAU8825_GLOBAL_BIAS_EN (1 << 12) 299#define NAU8825_GLOBAL_BIAS_EN (1 << 12)
300#define NAU8825_HP_BOOST_DIS (1 << 9)
287#define NAU8825_HP_BOOST_G_DIS (1 << 8) 301#define NAU8825_HP_BOOST_G_DIS (1 << 8)
288#define NAU8825_SHORT_SHUTDOWN_EN (1 << 6) 302#define NAU8825_SHORT_SHUTDOWN_EN (1 << 6)
289 303
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 976967675387..f7e789e97fbc 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -17,6 +17,27 @@ config SND_SOC_MT8173_MAX98090
17 Select Y if you have such device. 17 Select Y if you have such device.
18 If unsure select "N". 18 If unsure select "N".
19 19
20config SND_SOC_MT8173_RT5650
21 tristate "ASoC Audio driver for MT8173 with RT5650 codec"
22 depends on SND_SOC_MEDIATEK && I2C
23 select SND_SOC_RT5645
24 help
25 This adds ASoC driver for Mediatek MT8173 boards
26 with the RT5650 audio codec.
27 Select Y if you have such device.
28 If unsure select "N".
29
30config SND_SOC_MT8173_RT5650_RT5514
31 tristate "ASoC Audio driver for MT8173 with RT5650 RT5514 codecs"
32 depends on SND_SOC_MEDIATEK && I2C
33 select SND_SOC_RT5645
34 select SND_SOC_RT5514
35 help
36 This adds ASoC driver for Mediatek MT8173 boards
37 with the RT5650 and RT5514 codecs.
38 Select Y if you have such device.
39 If unsure select "N".
40
20config SND_SOC_MT8173_RT5650_RT5676 41config SND_SOC_MT8173_RT5650_RT5676
21 tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs" 42 tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs"
22 depends on SND_SOC_MEDIATEK && I2C 43 depends on SND_SOC_MEDIATEK && I2C
@@ -27,4 +48,3 @@ config SND_SOC_MT8173_RT5650_RT5676
27 with the RT5650 and RT5676 codecs. 48 with the RT5650 and RT5676 codecs.
28 Select Y if you have such device. 49 Select Y if you have such device.
29 If unsure select "N". 50 If unsure select "N".
30
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
index 75effbec438d..d486860c0a88 100644
--- a/sound/soc/mediatek/Makefile
+++ b/sound/soc/mediatek/Makefile
@@ -2,4 +2,6 @@
2obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o 2obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o
3# Machine support 3# Machine support
4obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o 4obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o
5obj-$(CONFIG_SND_SOC_MT8173_RT5650) += mt8173-rt5650.o
6obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5514) += mt8173-rt5650-rt5514.o
5obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o 7obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o
diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173-rt5650-rt5514.c
new file mode 100644
index 000000000000..58e083642dea
--- /dev/null
+++ b/sound/soc/mediatek/mt8173-rt5650-rt5514.c
@@ -0,0 +1,258 @@
1/*
2 * mt8173-rt5650-rt5514.c -- MT8173 machine driver with RT5650/5514 codecs
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <linux/gpio.h>
19#include <linux/of_gpio.h>
20#include <sound/soc.h>
21#include <sound/jack.h>
22#include "../codecs/rt5645.h"
23
24#define MCLK_FOR_CODECS 12288000
25
26static const struct snd_soc_dapm_widget mt8173_rt5650_rt5514_widgets[] = {
27 SND_SOC_DAPM_SPK("Speaker", NULL),
28 SND_SOC_DAPM_MIC("Int Mic", NULL),
29 SND_SOC_DAPM_HP("Headphone", NULL),
30 SND_SOC_DAPM_MIC("Headset Mic", NULL),
31};
32
33static const struct snd_soc_dapm_route mt8173_rt5650_rt5514_routes[] = {
34 {"Speaker", NULL, "SPOL"},
35 {"Speaker", NULL, "SPOR"},
36 {"Sub DMIC1L", NULL, "Int Mic"},
37 {"Sub DMIC1R", NULL, "Int Mic"},
38 {"Headphone", NULL, "HPOL"},
39 {"Headphone", NULL, "HPOR"},
40 {"Headset Mic", NULL, "micbias1"},
41 {"Headset Mic", NULL, "micbias2"},
42 {"IN1P", NULL, "Headset Mic"},
43 {"IN1N", NULL, "Headset Mic"},
44};
45
46static const struct snd_kcontrol_new mt8173_rt5650_rt5514_controls[] = {
47 SOC_DAPM_PIN_SWITCH("Speaker"),
48 SOC_DAPM_PIN_SWITCH("Int Mic"),
49 SOC_DAPM_PIN_SWITCH("Headphone"),
50 SOC_DAPM_PIN_SWITCH("Headset Mic"),
51};
52
53static int mt8173_rt5650_rt5514_hw_params(struct snd_pcm_substream *substream,
54 struct snd_pcm_hw_params *params)
55{
56 struct snd_soc_pcm_runtime *rtd = substream->private_data;
57 int i, ret;
58
59 for (i = 0; i < rtd->num_codecs; i++) {
60 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
61
62 /* pll from mclk 12.288M */
63 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, MCLK_FOR_CODECS,
64 params_rate(params) * 512);
65 if (ret)
66 return ret;
67
68 /* sysclk from pll */
69 ret = snd_soc_dai_set_sysclk(codec_dai, 1,
70 params_rate(params) * 512,
71 SND_SOC_CLOCK_IN);
72 if (ret)
73 return ret;
74 }
75 return 0;
76}
77
78static struct snd_soc_ops mt8173_rt5650_rt5514_ops = {
79 .hw_params = mt8173_rt5650_rt5514_hw_params,
80};
81
82static struct snd_soc_jack mt8173_rt5650_rt5514_jack;
83
84static int mt8173_rt5650_rt5514_init(struct snd_soc_pcm_runtime *runtime)
85{
86 struct snd_soc_card *card = runtime->card;
87 struct snd_soc_codec *codec = runtime->codec_dais[0]->codec;
88 int ret;
89
90 rt5645_sel_asrc_clk_src(codec,
91 RT5645_DA_STEREO_FILTER |
92 RT5645_AD_STEREO_FILTER,
93 RT5645_CLK_SEL_I2S1_ASRC);
94
95 /* enable jack detection */
96 ret = snd_soc_card_jack_new(card, "Headset Jack",
97 SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
98 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
99 SND_JACK_BTN_2 | SND_JACK_BTN_3,
100 &mt8173_rt5650_rt5514_jack, NULL, 0);
101 if (ret) {
102 dev_err(card->dev, "Can't new Headset Jack %d\n", ret);
103 return ret;
104 }
105
106 return rt5645_set_jack_detect(codec,
107 &mt8173_rt5650_rt5514_jack,
108 &mt8173_rt5650_rt5514_jack,
109 &mt8173_rt5650_rt5514_jack);
110}
111
112static struct snd_soc_dai_link_component mt8173_rt5650_rt5514_codecs[] = {
113 {
114 .dai_name = "rt5645-aif1",
115 },
116 {
117 .dai_name = "rt5514-aif1",
118 },
119};
120
121enum {
122 DAI_LINK_PLAYBACK,
123 DAI_LINK_CAPTURE,
124 DAI_LINK_CODEC_I2S,
125};
126
127/* Digital audio interface glue - connects codec <---> CPU */
128static struct snd_soc_dai_link mt8173_rt5650_rt5514_dais[] = {
129 /* Front End DAI links */
130 [DAI_LINK_PLAYBACK] = {
131 .name = "rt5650_rt5514 Playback",
132 .stream_name = "rt5650_rt5514 Playback",
133 .cpu_dai_name = "DL1",
134 .codec_name = "snd-soc-dummy",
135 .codec_dai_name = "snd-soc-dummy-dai",
136 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
137 .dynamic = 1,
138 .dpcm_playback = 1,
139 },
140 [DAI_LINK_CAPTURE] = {
141 .name = "rt5650_rt5514 Capture",
142 .stream_name = "rt5650_rt5514 Capture",
143 .cpu_dai_name = "VUL",
144 .codec_name = "snd-soc-dummy",
145 .codec_dai_name = "snd-soc-dummy-dai",
146 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
147 .dynamic = 1,
148 .dpcm_capture = 1,
149 },
150 /* Back End DAI links */
151 [DAI_LINK_CODEC_I2S] = {
152 .name = "Codec",
153 .cpu_dai_name = "I2S",
154 .no_pcm = 1,
155 .codecs = mt8173_rt5650_rt5514_codecs,
156 .num_codecs = 2,
157 .init = mt8173_rt5650_rt5514_init,
158 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
159 SND_SOC_DAIFMT_CBS_CFS,
160 .ops = &mt8173_rt5650_rt5514_ops,
161 .ignore_pmdown_time = 1,
162 .dpcm_playback = 1,
163 .dpcm_capture = 1,
164 },
165};
166
167static struct snd_soc_codec_conf mt8173_rt5650_rt5514_codec_conf[] = {
168 {
169 .name_prefix = "Sub",
170 },
171};
172
173static struct snd_soc_card mt8173_rt5650_rt5514_card = {
174 .name = "mtk-rt5650-rt5514",
175 .owner = THIS_MODULE,
176 .dai_link = mt8173_rt5650_rt5514_dais,
177 .num_links = ARRAY_SIZE(mt8173_rt5650_rt5514_dais),
178 .codec_conf = mt8173_rt5650_rt5514_codec_conf,
179 .num_configs = ARRAY_SIZE(mt8173_rt5650_rt5514_codec_conf),
180 .controls = mt8173_rt5650_rt5514_controls,
181 .num_controls = ARRAY_SIZE(mt8173_rt5650_rt5514_controls),
182 .dapm_widgets = mt8173_rt5650_rt5514_widgets,
183 .num_dapm_widgets = ARRAY_SIZE(mt8173_rt5650_rt5514_widgets),
184 .dapm_routes = mt8173_rt5650_rt5514_routes,
185 .num_dapm_routes = ARRAY_SIZE(mt8173_rt5650_rt5514_routes),
186};
187
188static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
189{
190 struct snd_soc_card *card = &mt8173_rt5650_rt5514_card;
191 struct device_node *platform_node;
192 int i, ret;
193
194 platform_node = of_parse_phandle(pdev->dev.of_node,
195 "mediatek,platform", 0);
196 if (!platform_node) {
197 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
198 return -EINVAL;
199 }
200
201 for (i = 0; i < card->num_links; i++) {
202 if (mt8173_rt5650_rt5514_dais[i].platform_name)
203 continue;
204 mt8173_rt5650_rt5514_dais[i].platform_of_node = platform_node;
205 }
206
207 mt8173_rt5650_rt5514_codecs[0].of_node =
208 of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 0);
209 if (!mt8173_rt5650_rt5514_codecs[0].of_node) {
210 dev_err(&pdev->dev,
211 "Property 'audio-codec' missing or invalid\n");
212 return -EINVAL;
213 }
214 mt8173_rt5650_rt5514_codecs[1].of_node =
215 of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1);
216 if (!mt8173_rt5650_rt5514_codecs[1].of_node) {
217 dev_err(&pdev->dev,
218 "Property 'audio-codec' missing or invalid\n");
219 return -EINVAL;
220 }
221 mt8173_rt5650_rt5514_codec_conf[0].of_node =
222 mt8173_rt5650_rt5514_codecs[1].of_node;
223
224 card->dev = &pdev->dev;
225 platform_set_drvdata(pdev, card);
226
227 ret = devm_snd_soc_register_card(&pdev->dev, card);
228 if (ret)
229 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
230 __func__, ret);
231 return ret;
232}
233
234static const struct of_device_id mt8173_rt5650_rt5514_dt_match[] = {
235 { .compatible = "mediatek,mt8173-rt5650-rt5514", },
236 { }
237};
238MODULE_DEVICE_TABLE(of, mt8173_rt5650_rt5514_dt_match);
239
240static struct platform_driver mt8173_rt5650_rt5514_driver = {
241 .driver = {
242 .name = "mtk-rt5650-rt5514",
243 .of_match_table = mt8173_rt5650_rt5514_dt_match,
244#ifdef CONFIG_PM
245 .pm = &snd_soc_pm_ops,
246#endif
247 },
248 .probe = mt8173_rt5650_rt5514_dev_probe,
249};
250
251module_platform_driver(mt8173_rt5650_rt5514_driver);
252
253/* Module information */
254MODULE_DESCRIPTION("MT8173 RT5650 and RT5514 SoC machine driver");
255MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>");
256MODULE_LICENSE("GPL v2");
257MODULE_ALIAS("platform:mtk-rt5650-rt5514");
258
diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
index 50ba538eccb3..5c4c58c69c51 100644
--- a/sound/soc/mediatek/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
@@ -131,10 +131,17 @@ static struct snd_soc_dai_link_component mt8173_rt5650_rt5676_codecs[] = {
131 }, 131 },
132}; 132};
133 133
134enum {
135 DAI_LINK_PLAYBACK,
136 DAI_LINK_CAPTURE,
137 DAI_LINK_CODEC_I2S,
138 DAI_LINK_INTERCODEC
139};
140
134/* Digital audio interface glue - connects codec <---> CPU */ 141/* Digital audio interface glue - connects codec <---> CPU */
135static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = { 142static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
136 /* Front End DAI links */ 143 /* Front End DAI links */
137 { 144 [DAI_LINK_PLAYBACK] = {
138 .name = "rt5650_rt5676 Playback", 145 .name = "rt5650_rt5676 Playback",
139 .stream_name = "rt5650_rt5676 Playback", 146 .stream_name = "rt5650_rt5676 Playback",
140 .cpu_dai_name = "DL1", 147 .cpu_dai_name = "DL1",
@@ -144,7 +151,7 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
144 .dynamic = 1, 151 .dynamic = 1,
145 .dpcm_playback = 1, 152 .dpcm_playback = 1,
146 }, 153 },
147 { 154 [DAI_LINK_CAPTURE] = {
148 .name = "rt5650_rt5676 Capture", 155 .name = "rt5650_rt5676 Capture",
149 .stream_name = "rt5650_rt5676 Capture", 156 .stream_name = "rt5650_rt5676 Capture",
150 .cpu_dai_name = "VUL", 157 .cpu_dai_name = "VUL",
@@ -156,7 +163,7 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
156 }, 163 },
157 164
158 /* Back End DAI links */ 165 /* Back End DAI links */
159 { 166 [DAI_LINK_CODEC_I2S] = {
160 .name = "Codec", 167 .name = "Codec",
161 .cpu_dai_name = "I2S", 168 .cpu_dai_name = "I2S",
162 .no_pcm = 1, 169 .no_pcm = 1,
@@ -170,7 +177,8 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
170 .dpcm_playback = 1, 177 .dpcm_playback = 1,
171 .dpcm_capture = 1, 178 .dpcm_capture = 1,
172 }, 179 },
173 { /* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */ 180 /* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */
181 [DAI_LINK_INTERCODEC] = {
174 .name = "rt5650_rt5676 intercodec", 182 .name = "rt5650_rt5676 intercodec",
175 .stream_name = "rt5650_rt5676 intercodec", 183 .stream_name = "rt5650_rt5676 intercodec",
176 .cpu_dai_name = "snd-soc-dummy-dai", 184 .cpu_dai_name = "snd-soc-dummy-dai",
@@ -240,7 +248,7 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
240 mt8173_rt5650_rt5676_codec_conf[0].of_node = 248 mt8173_rt5650_rt5676_codec_conf[0].of_node =
241 mt8173_rt5650_rt5676_codecs[1].of_node; 249 mt8173_rt5650_rt5676_codecs[1].of_node;
242 250
243 mt8173_rt5650_rt5676_dais[3].codec_of_node = 251 mt8173_rt5650_rt5676_dais[DAI_LINK_INTERCODEC].codec_of_node =
244 mt8173_rt5650_rt5676_codecs[1].of_node; 252 mt8173_rt5650_rt5676_codecs[1].of_node;
245 253
246 card->dev = &pdev->dev; 254 card->dev = &pdev->dev;
diff --git a/sound/soc/mediatek/mt8173-rt5650.c b/sound/soc/mediatek/mt8173-rt5650.c
new file mode 100644
index 000000000000..bb09bb1b7f1c
--- /dev/null
+++ b/sound/soc/mediatek/mt8173-rt5650.c
@@ -0,0 +1,236 @@
1/*
2 * mt8173-rt5650.c -- MT8173 machine driver with RT5650 codecs
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <linux/gpio.h>
19#include <linux/of_gpio.h>
20#include <sound/soc.h>
21#include <sound/jack.h>
22#include "../codecs/rt5645.h"
23
24#define MCLK_FOR_CODECS 12288000
25
26static const struct snd_soc_dapm_widget mt8173_rt5650_widgets[] = {
27 SND_SOC_DAPM_SPK("Speaker", NULL),
28 SND_SOC_DAPM_MIC("Int Mic", NULL),
29 SND_SOC_DAPM_HP("Headphone", NULL),
30 SND_SOC_DAPM_MIC("Headset Mic", NULL),
31};
32
33static const struct snd_soc_dapm_route mt8173_rt5650_routes[] = {
34 {"Speaker", NULL, "SPOL"},
35 {"Speaker", NULL, "SPOR"},
36 {"DMIC L1", NULL, "Int Mic"},
37 {"DMIC R1", NULL, "Int Mic"},
38 {"Headphone", NULL, "HPOL"},
39 {"Headphone", NULL, "HPOR"},
40 {"Headset Mic", NULL, "micbias1"},
41 {"Headset Mic", NULL, "micbias2"},
42 {"IN1P", NULL, "Headset Mic"},
43 {"IN1N", NULL, "Headset Mic"},
44};
45
46static const struct snd_kcontrol_new mt8173_rt5650_controls[] = {
47 SOC_DAPM_PIN_SWITCH("Speaker"),
48 SOC_DAPM_PIN_SWITCH("Int Mic"),
49 SOC_DAPM_PIN_SWITCH("Headphone"),
50 SOC_DAPM_PIN_SWITCH("Headset Mic"),
51};
52
53static int mt8173_rt5650_hw_params(struct snd_pcm_substream *substream,
54 struct snd_pcm_hw_params *params)
55{
56 struct snd_soc_pcm_runtime *rtd = substream->private_data;
57 int i, ret;
58
59 for (i = 0; i < rtd->num_codecs; i++) {
60 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
61
62 /* pll from mclk 12.288M */
63 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, MCLK_FOR_CODECS,
64 params_rate(params) * 512);
65 if (ret)
66 return ret;
67
68 /* sysclk from pll */
69 ret = snd_soc_dai_set_sysclk(codec_dai, 1,
70 params_rate(params) * 512,
71 SND_SOC_CLOCK_IN);
72 if (ret)
73 return ret;
74 }
75 return 0;
76}
77
78static struct snd_soc_ops mt8173_rt5650_ops = {
79 .hw_params = mt8173_rt5650_hw_params,
80};
81
82static struct snd_soc_jack mt8173_rt5650_jack;
83
84static int mt8173_rt5650_init(struct snd_soc_pcm_runtime *runtime)
85{
86 struct snd_soc_card *card = runtime->card;
87 struct snd_soc_codec *codec = runtime->codec_dais[0]->codec;
88 int ret;
89
90 rt5645_sel_asrc_clk_src(codec,
91 RT5645_DA_STEREO_FILTER |
92 RT5645_AD_STEREO_FILTER,
93 RT5645_CLK_SEL_I2S1_ASRC);
94 /* enable jack detection */
95 ret = snd_soc_card_jack_new(card, "Headset Jack",
96 SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
97 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
98 SND_JACK_BTN_2 | SND_JACK_BTN_3,
99 &mt8173_rt5650_jack, NULL, 0);
100 if (ret) {
101 dev_err(card->dev, "Can't new Headset Jack %d\n", ret);
102 return ret;
103 }
104
105 return rt5645_set_jack_detect(codec,
106 &mt8173_rt5650_jack,
107 &mt8173_rt5650_jack,
108 &mt8173_rt5650_jack);
109}
110
111static struct snd_soc_dai_link_component mt8173_rt5650_codecs[] = {
112 {
113 .dai_name = "rt5645-aif1",
114 },
115};
116
117enum {
118 DAI_LINK_PLAYBACK,
119 DAI_LINK_CAPTURE,
120 DAI_LINK_CODEC_I2S,
121};
122
123/* Digital audio interface glue - connects codec <---> CPU */
124static struct snd_soc_dai_link mt8173_rt5650_dais[] = {
125 /* Front End DAI links */
126 [DAI_LINK_PLAYBACK] = {
127 .name = "rt5650 Playback",
128 .stream_name = "rt5650 Playback",
129 .cpu_dai_name = "DL1",
130 .codec_name = "snd-soc-dummy",
131 .codec_dai_name = "snd-soc-dummy-dai",
132 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
133 .dynamic = 1,
134 .dpcm_playback = 1,
135 },
136 [DAI_LINK_CAPTURE] = {
137 .name = "rt5650 Capture",
138 .stream_name = "rt5650 Capture",
139 .cpu_dai_name = "VUL",
140 .codec_name = "snd-soc-dummy",
141 .codec_dai_name = "snd-soc-dummy-dai",
142 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
143 .dynamic = 1,
144 .dpcm_capture = 1,
145 },
146 /* Back End DAI links */
147 [DAI_LINK_CODEC_I2S] = {
148 .name = "Codec",
149 .cpu_dai_name = "I2S",
150 .no_pcm = 1,
151 .codecs = mt8173_rt5650_codecs,
152 .num_codecs = 1,
153 .init = mt8173_rt5650_init,
154 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
155 SND_SOC_DAIFMT_CBS_CFS,
156 .ops = &mt8173_rt5650_ops,
157 .ignore_pmdown_time = 1,
158 .dpcm_playback = 1,
159 .dpcm_capture = 1,
160 },
161};
162
163static struct snd_soc_card mt8173_rt5650_card = {
164 .name = "mtk-rt5650",
165 .owner = THIS_MODULE,
166 .dai_link = mt8173_rt5650_dais,
167 .num_links = ARRAY_SIZE(mt8173_rt5650_dais),
168 .controls = mt8173_rt5650_controls,
169 .num_controls = ARRAY_SIZE(mt8173_rt5650_controls),
170 .dapm_widgets = mt8173_rt5650_widgets,
171 .num_dapm_widgets = ARRAY_SIZE(mt8173_rt5650_widgets),
172 .dapm_routes = mt8173_rt5650_routes,
173 .num_dapm_routes = ARRAY_SIZE(mt8173_rt5650_routes),
174};
175
176static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
177{
178 struct snd_soc_card *card = &mt8173_rt5650_card;
179 struct device_node *platform_node;
180 int i, ret;
181
182 platform_node = of_parse_phandle(pdev->dev.of_node,
183 "mediatek,platform", 0);
184 if (!platform_node) {
185 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
186 return -EINVAL;
187 }
188
189 for (i = 0; i < card->num_links; i++) {
190 if (mt8173_rt5650_dais[i].platform_name)
191 continue;
192 mt8173_rt5650_dais[i].platform_of_node = platform_node;
193 }
194
195 mt8173_rt5650_codecs[0].of_node =
196 of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 0);
197 if (!mt8173_rt5650_codecs[0].of_node) {
198 dev_err(&pdev->dev,
199 "Property 'audio-codec' missing or invalid\n");
200 return -EINVAL;
201 }
202 card->dev = &pdev->dev;
203 platform_set_drvdata(pdev, card);
204
205 ret = devm_snd_soc_register_card(&pdev->dev, card);
206 if (ret)
207 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
208 __func__, ret);
209 return ret;
210}
211
212static const struct of_device_id mt8173_rt5650_dt_match[] = {
213 { .compatible = "mediatek,mt8173-rt5650", },
214 { }
215};
216MODULE_DEVICE_TABLE(of, mt8173_rt5650_dt_match);
217
218static struct platform_driver mt8173_rt5650_driver = {
219 .driver = {
220 .name = "mtk-rt5650",
221 .of_match_table = mt8173_rt5650_dt_match,
222#ifdef CONFIG_PM
223 .pm = &snd_soc_pm_ops,
224#endif
225 },
226 .probe = mt8173_rt5650_dev_probe,
227};
228
229module_platform_driver(mt8173_rt5650_driver);
230
231/* Module information */
232MODULE_DESCRIPTION("MT8173 RT5650 SoC machine driver");
233MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>");
234MODULE_LICENSE("GPL v2");
235MODULE_ALIAS("platform:mtk-rt5650");
236
diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h
index 9b1af1a70874..f341f623e887 100644
--- a/sound/soc/mediatek/mtk-afe-common.h
+++ b/sound/soc/mediatek/mtk-afe-common.h
@@ -87,6 +87,7 @@ struct mtk_afe_memif_data {
87 int irq_en_shift; 87 int irq_en_shift;
88 int irq_fs_shift; 88 int irq_fs_shift;
89 int irq_clr_shift; 89 int irq_clr_shift;
90 int msb_shift;
90}; 91};
91 92
92struct mtk_afe_memif { 93struct mtk_afe_memif {
diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c
index 08af9f5dc4ab..f1c58a2c12fb 100644
--- a/sound/soc/mediatek/mtk-afe-pcm.c
+++ b/sound/soc/mediatek/mtk-afe-pcm.c
@@ -21,6 +21,7 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/of.h> 22#include <linux/of.h>
23#include <linux/of_address.h> 23#include <linux/of_address.h>
24#include <linux/dma-mapping.h>
24#include <linux/pm_runtime.h> 25#include <linux/pm_runtime.h>
25#include <sound/soc.h> 26#include <sound/soc.h>
26#include "mtk-afe-common.h" 27#include "mtk-afe-common.h"
@@ -35,9 +36,11 @@
35#define AFE_I2S_CON1 0x0034 36#define AFE_I2S_CON1 0x0034
36#define AFE_I2S_CON2 0x0038 37#define AFE_I2S_CON2 0x0038
37#define AFE_CONN_24BIT 0x006c 38#define AFE_CONN_24BIT 0x006c
39#define AFE_MEMIF_MSB 0x00cc
38 40
39#define AFE_CONN1 0x0024 41#define AFE_CONN1 0x0024
40#define AFE_CONN2 0x0028 42#define AFE_CONN2 0x0028
43#define AFE_CONN3 0x002c
41#define AFE_CONN7 0x0460 44#define AFE_CONN7 0x0460
42#define AFE_CONN8 0x0464 45#define AFE_CONN8 0x0464
43#define AFE_HDMI_CONN0 0x0390 46#define AFE_HDMI_CONN0 0x0390
@@ -61,6 +64,7 @@
61#define AFE_HDMI_OUT_CUR 0x0378 64#define AFE_HDMI_OUT_CUR 0x0378
62#define AFE_HDMI_OUT_END 0x037c 65#define AFE_HDMI_OUT_END 0x037c
63 66
67#define AFE_ADDA_TOP_CON0 0x0120
64#define AFE_ADDA2_TOP_CON0 0x0600 68#define AFE_ADDA2_TOP_CON0 0x0600
65 69
66#define AFE_HDMI_OUT_CON0 0x0370 70#define AFE_HDMI_OUT_CON0 0x0370
@@ -257,6 +261,7 @@ static int mtk_afe_set_i2s(struct mtk_afe *afe, unsigned int rate)
257 return -EINVAL; 261 return -EINVAL;
258 262
259 /* from external ADC */ 263 /* from external ADC */
264 regmap_update_bits(afe->regmap, AFE_ADDA_TOP_CON0, 0x1, 0x1);
260 regmap_update_bits(afe->regmap, AFE_ADDA2_TOP_CON0, 0x1, 0x1); 265 regmap_update_bits(afe->regmap, AFE_ADDA2_TOP_CON0, 0x1, 0x1);
261 266
262 /* set input */ 267 /* set input */
@@ -281,20 +286,13 @@ static void mtk_afe_set_i2s_enable(struct mtk_afe *afe, bool enable)
281 286
282 regmap_read(afe->regmap, AFE_I2S_CON2, &val); 287 regmap_read(afe->regmap, AFE_I2S_CON2, &val);
283 if (!!(val & AFE_I2S_CON2_EN) == enable) 288 if (!!(val & AFE_I2S_CON2_EN) == enable)
284 return; /* must skip soft reset */ 289 return;
285
286 /* I2S soft reset begin */
287 regmap_update_bits(afe->regmap, AUDIO_TOP_CON1, 0x4, 0x4);
288 290
289 /* input */ 291 /* input */
290 regmap_update_bits(afe->regmap, AFE_I2S_CON2, 0x1, enable); 292 regmap_update_bits(afe->regmap, AFE_I2S_CON2, 0x1, enable);
291 293
292 /* output */ 294 /* output */
293 regmap_update_bits(afe->regmap, AFE_I2S_CON1, 0x1, enable); 295 regmap_update_bits(afe->regmap, AFE_I2S_CON1, 0x1, enable);
294
295 /* I2S soft reset end */
296 udelay(1);
297 regmap_update_bits(afe->regmap, AUDIO_TOP_CON1, 0x4, 0);
298} 296}
299 297
300static int mtk_afe_dais_enable_clks(struct mtk_afe *afe, 298static int mtk_afe_dais_enable_clks(struct mtk_afe *afe,
@@ -363,6 +361,7 @@ static int mtk_afe_i2s_startup(struct snd_pcm_substream *substream,
363 return 0; 361 return 0;
364 362
365 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); 363 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
364 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S2_M], NULL);
366 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 365 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
367 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0); 366 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0);
368 return 0; 367 return 0;
@@ -382,6 +381,7 @@ static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream,
382 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 381 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M,
383 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M); 382 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M);
384 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); 383 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
384 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S2_M], NULL);
385} 385}
386 386
387static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream, 387static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream,
@@ -395,6 +395,9 @@ static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream,
395 mtk_afe_dais_set_clks(afe, 395 mtk_afe_dais_set_clks(afe,
396 afe->clocks[MTK_CLK_I2S1_M], runtime->rate * 256, 396 afe->clocks[MTK_CLK_I2S1_M], runtime->rate * 256,
397 NULL, 0); 397 NULL, 0);
398 mtk_afe_dais_set_clks(afe,
399 afe->clocks[MTK_CLK_I2S2_M], runtime->rate * 256,
400 NULL, 0);
398 /* config I2S */ 401 /* config I2S */
399 ret = mtk_afe_set_i2s(afe, substream->runtime->rate); 402 ret = mtk_afe_set_i2s(afe, substream->runtime->rate);
400 if (ret) 403 if (ret)
@@ -592,6 +595,7 @@ static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream,
592 struct snd_soc_pcm_runtime *rtd = substream->private_data; 595 struct snd_soc_pcm_runtime *rtd = substream->private_data;
593 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 596 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
594 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; 597 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
598 int msb_at_bit33 = 0;
595 int ret; 599 int ret;
596 600
597 dev_dbg(afe->dev, 601 dev_dbg(afe->dev,
@@ -603,7 +607,8 @@ static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream,
603 if (ret < 0) 607 if (ret < 0)
604 return ret; 608 return ret;
605 609
606 memif->phys_buf_addr = substream->runtime->dma_addr; 610 msb_at_bit33 = upper_32_bits(substream->runtime->dma_addr) ? 1 : 0;
611 memif->phys_buf_addr = lower_32_bits(substream->runtime->dma_addr);
607 memif->buffer_size = substream->runtime->dma_bytes; 612 memif->buffer_size = substream->runtime->dma_bytes;
608 613
609 /* start */ 614 /* start */
@@ -614,6 +619,11 @@ static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream,
614 memif->data->reg_ofs_base + AFE_BASE_END_OFFSET, 619 memif->data->reg_ofs_base + AFE_BASE_END_OFFSET,
615 memif->phys_buf_addr + memif->buffer_size - 1); 620 memif->phys_buf_addr + memif->buffer_size - 1);
616 621
622 /* set MSB to 33-bit */
623 regmap_update_bits(afe->regmap, AFE_MEMIF_MSB,
624 1 << memif->data->msb_shift,
625 msb_at_bit33 << memif->data->msb_shift);
626
617 /* set channel */ 627 /* set channel */
618 if (memif->data->mono_shift >= 0) { 628 if (memif->data->mono_shift >= 0) {
619 unsigned int mono = (params_channels(params) == 1) ? 1 : 0; 629 unsigned int mono = (params_channels(params) == 1) ? 1 : 0;
@@ -894,15 +904,19 @@ static const struct snd_kcontrol_new mtk_afe_o04_mix[] = {
894}; 904};
895 905
896static const struct snd_kcontrol_new mtk_afe_o09_mix[] = { 906static const struct snd_kcontrol_new mtk_afe_o09_mix[] = {
907 SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN3, 0, 1, 0),
897 SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN7, 30, 1, 0), 908 SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN7, 30, 1, 0),
898}; 909};
899 910
900static const struct snd_kcontrol_new mtk_afe_o10_mix[] = { 911static const struct snd_kcontrol_new mtk_afe_o10_mix[] = {
912 SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN3, 3, 1, 0),
901 SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN8, 0, 1, 0), 913 SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN8, 0, 1, 0),
902}; 914};
903 915
904static const struct snd_soc_dapm_widget mtk_afe_pcm_widgets[] = { 916static const struct snd_soc_dapm_widget mtk_afe_pcm_widgets[] = {
905 /* inter-connections */ 917 /* inter-connections */
918 SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0),
919 SND_SOC_DAPM_MIXER("I04", SND_SOC_NOPM, 0, 0, NULL, 0),
906 SND_SOC_DAPM_MIXER("I05", SND_SOC_NOPM, 0, 0, NULL, 0), 920 SND_SOC_DAPM_MIXER("I05", SND_SOC_NOPM, 0, 0, NULL, 0),
907 SND_SOC_DAPM_MIXER("I06", SND_SOC_NOPM, 0, 0, NULL, 0), 921 SND_SOC_DAPM_MIXER("I06", SND_SOC_NOPM, 0, 0, NULL, 0),
908 SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0), 922 SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -925,12 +939,16 @@ static const struct snd_soc_dapm_route mtk_afe_pcm_routes[] = {
925 {"I2S Playback", NULL, "O04"}, 939 {"I2S Playback", NULL, "O04"},
926 {"VUL", NULL, "O09"}, 940 {"VUL", NULL, "O09"},
927 {"VUL", NULL, "O10"}, 941 {"VUL", NULL, "O10"},
942 {"I03", NULL, "I2S Capture"},
943 {"I04", NULL, "I2S Capture"},
928 {"I17", NULL, "I2S Capture"}, 944 {"I17", NULL, "I2S Capture"},
929 {"I18", NULL, "I2S Capture"}, 945 {"I18", NULL, "I2S Capture"},
930 { "O03", "I05 Switch", "I05" }, 946 { "O03", "I05 Switch", "I05" },
931 { "O04", "I06 Switch", "I06" }, 947 { "O04", "I06 Switch", "I06" },
932 { "O09", "I17 Switch", "I17" }, 948 { "O09", "I17 Switch", "I17" },
949 { "O09", "I03 Switch", "I03" },
933 { "O10", "I18 Switch", "I18" }, 950 { "O10", "I18 Switch", "I18" },
951 { "O10", "I04 Switch", "I04" },
934}; 952};
935 953
936static const struct snd_soc_dapm_route mtk_afe_hdmi_routes[] = { 954static const struct snd_soc_dapm_route mtk_afe_hdmi_routes[] = {
@@ -978,6 +996,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = {
978 .irq_en_shift = 0, 996 .irq_en_shift = 0,
979 .irq_fs_shift = 4, 997 .irq_fs_shift = 4,
980 .irq_clr_shift = 0, 998 .irq_clr_shift = 0,
999 .msb_shift = 0,
981 }, { 1000 }, {
982 .name = "DL2", 1001 .name = "DL2",
983 .id = MTK_AFE_MEMIF_DL2, 1002 .id = MTK_AFE_MEMIF_DL2,
@@ -991,6 +1010,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = {
991 .irq_en_shift = 2, 1010 .irq_en_shift = 2,
992 .irq_fs_shift = 16, 1011 .irq_fs_shift = 16,
993 .irq_clr_shift = 2, 1012 .irq_clr_shift = 2,
1013 .msb_shift = 1,
994 }, { 1014 }, {
995 .name = "VUL", 1015 .name = "VUL",
996 .id = MTK_AFE_MEMIF_VUL, 1016 .id = MTK_AFE_MEMIF_VUL,
@@ -1004,6 +1024,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = {
1004 .irq_en_shift = 1, 1024 .irq_en_shift = 1,
1005 .irq_fs_shift = 8, 1025 .irq_fs_shift = 8,
1006 .irq_clr_shift = 1, 1026 .irq_clr_shift = 1,
1027 .msb_shift = 6,
1007 }, { 1028 }, {
1008 .name = "DAI", 1029 .name = "DAI",
1009 .id = MTK_AFE_MEMIF_DAI, 1030 .id = MTK_AFE_MEMIF_DAI,
@@ -1017,6 +1038,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = {
1017 .irq_en_shift = 3, 1038 .irq_en_shift = 3,
1018 .irq_fs_shift = 20, 1039 .irq_fs_shift = 20,
1019 .irq_clr_shift = 3, 1040 .irq_clr_shift = 3,
1041 .msb_shift = 5,
1020 }, { 1042 }, {
1021 .name = "AWB", 1043 .name = "AWB",
1022 .id = MTK_AFE_MEMIF_AWB, 1044 .id = MTK_AFE_MEMIF_AWB,
@@ -1030,6 +1052,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = {
1030 .irq_en_shift = 14, 1052 .irq_en_shift = 14,
1031 .irq_fs_shift = 24, 1053 .irq_fs_shift = 24,
1032 .irq_clr_shift = 6, 1054 .irq_clr_shift = 6,
1055 .msb_shift = 3,
1033 }, { 1056 }, {
1034 .name = "MOD_DAI", 1057 .name = "MOD_DAI",
1035 .id = MTK_AFE_MEMIF_MOD_DAI, 1058 .id = MTK_AFE_MEMIF_MOD_DAI,
@@ -1043,6 +1066,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = {
1043 .irq_en_shift = 3, 1066 .irq_en_shift = 3,
1044 .irq_fs_shift = 20, 1067 .irq_fs_shift = 20,
1045 .irq_clr_shift = 3, 1068 .irq_clr_shift = 3,
1069 .msb_shift = 4,
1046 }, { 1070 }, {
1047 .name = "HDMI", 1071 .name = "HDMI",
1048 .id = MTK_AFE_MEMIF_HDMI, 1072 .id = MTK_AFE_MEMIF_HDMI,
@@ -1056,6 +1080,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = {
1056 .irq_en_shift = 12, 1080 .irq_en_shift = 12,
1057 .irq_fs_shift = -1, 1081 .irq_fs_shift = -1,
1058 .irq_clr_shift = 4, 1082 .irq_clr_shift = 4,
1083 .msb_shift = 8,
1059 }, 1084 },
1060}; 1085};
1061 1086
@@ -1189,6 +1214,10 @@ static int mtk_afe_pcm_dev_probe(struct platform_device *pdev)
1189 struct mtk_afe *afe; 1214 struct mtk_afe *afe;
1190 struct resource *res; 1215 struct resource *res;
1191 1216
1217 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
1218 if (ret)
1219 return ret;
1220
1192 afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); 1221 afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
1193 if (!afe) 1222 if (!afe)
1194 return -ENOMEM; 1223 return -ENOMEM;
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index a6c7b8d87cd2..13631003cb7c 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -418,7 +418,7 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream,
418 } 418 }
419 419
420 stat = __raw_readl(saif->base + SAIF_STAT); 420 stat = __raw_readl(saif->base + SAIF_STAT);
421 if (stat & BM_SAIF_STAT_BUSY) { 421 if (!saif->mclk_in_use && (stat & BM_SAIF_STAT_BUSY)) {
422 dev_err(cpu_dai->dev, "error: busy\n"); 422 dev_err(cpu_dai->dev, "error: busy\n");
423 return -EBUSY; 423 return -EBUSY;
424 } 424 }
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
index f83cc2bc0fc4..64425d352962 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/omap/omap-hdmi-audio.c
@@ -345,6 +345,7 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev)
345 dai_drv = &omap4_hdmi_dai; 345 dai_drv = &omap4_hdmi_dai;
346 break; 346 break;
347 case OMAPDSS_VER_OMAP5: 347 case OMAPDSS_VER_OMAP5:
348 case OMAPDSS_VER_DRA7xx:
348 dai_drv = &omap5_hdmi_dai; 349 dai_drv = &omap5_hdmi_dai;
349 break; 350 break;
350 default: 351 default: