rt5645.c (a3ae255e3729c1bb4507412ea29be804f703d44c) rt5645.c (79080a8b42a08fb68a1ea2e036e54a4749edbd43)
1/*
2 * rt5645.c -- RT5645 ALSA SoC audio codec driver
3 *
4 * Copyright 2013 Realtek Semiconductor Corp.
5 * Author: Bard Liao <bardliao@realtek.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 as

--- 525 unchanged lines hidden (view full) ---

534 * @w: DAPM widget.
535 * @kcontrol: The kcontrol of this widget.
536 * @event: Event id.
537 *
538 */
539static int set_dmic_clk(struct snd_soc_dapm_widget *w,
540 struct snd_kcontrol *kcontrol, int event)
541{
1/*
2 * rt5645.c -- RT5645 ALSA SoC audio codec driver
3 *
4 * Copyright 2013 Realtek Semiconductor Corp.
5 * Author: Bard Liao <bardliao@realtek.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 as

--- 525 unchanged lines hidden (view full) ---

534 * @w: DAPM widget.
535 * @kcontrol: The kcontrol of this widget.
536 * @event: Event id.
537 *
538 */
539static int set_dmic_clk(struct snd_soc_dapm_widget *w,
540 struct snd_kcontrol *kcontrol, int event)
541{
542 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
542 struct snd_soc_codec *codec = w->codec;
543 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
544 int idx = -EINVAL;
545
546 idx = rl6231_calc_dmic_clk(rt5645->sysclk);
547
548 if (idx < 0)
549 dev_err(codec->dev, "Failed to set DMIC clock\n");
550 else
551 snd_soc_update_bits(codec, RT5645_DMIC_CTRL1,
552 RT5645_DMIC_CLK_MASK, idx << RT5645_DMIC_CLK_SFT);
553 return idx;
554}
555
556static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
557 struct snd_soc_dapm_widget *sink)
558{
543 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
544 int idx = -EINVAL;
545
546 idx = rl6231_calc_dmic_clk(rt5645->sysclk);
547
548 if (idx < 0)
549 dev_err(codec->dev, "Failed to set DMIC clock\n");
550 else
551 snd_soc_update_bits(codec, RT5645_DMIC_CTRL1,
552 RT5645_DMIC_CLK_MASK, idx << RT5645_DMIC_CLK_SFT);
553 return idx;
554}
555
556static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
557 struct snd_soc_dapm_widget *sink)
558{
559 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
560 unsigned int val;
561
559 unsigned int val;
560
562 val = snd_soc_read(codec, RT5645_GLB_CLK);
561 val = snd_soc_read(source->codec, RT5645_GLB_CLK);
563 val &= RT5645_SCLK_SRC_MASK;
564 if (val == RT5645_SCLK_SRC_PLL1)
565 return 1;
566 else
567 return 0;
568}
569
570static int is_using_asrc(struct snd_soc_dapm_widget *source,
571 struct snd_soc_dapm_widget *sink)
572{
562 val &= RT5645_SCLK_SRC_MASK;
563 if (val == RT5645_SCLK_SRC_PLL1)
564 return 1;
565 else
566 return 0;
567}
568
569static int is_using_asrc(struct snd_soc_dapm_widget *source,
570 struct snd_soc_dapm_widget *sink)
571{
573 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
574 unsigned int reg, shift, val;
575
576 switch (source->shift) {
577 case 0:
578 reg = RT5645_ASRC_3;
579 shift = 0;
580 break;
581 case 1:

--- 15 unchanged lines hidden (view full) ---

597 case 10:
598 reg = RT5645_ASRC_2;
599 shift = 12;
600 break;
601 default:
602 return 0;
603 }
604
572 unsigned int reg, shift, val;
573
574 switch (source->shift) {
575 case 0:
576 reg = RT5645_ASRC_3;
577 shift = 0;
578 break;
579 case 1:

--- 15 unchanged lines hidden (view full) ---

595 case 10:
596 reg = RT5645_ASRC_2;
597 shift = 12;
598 break;
599 default:
600 return 0;
601 }
602
605 val = (snd_soc_read(codec, reg) >> shift) & 0xf;
603 val = (snd_soc_read(source->codec, reg) >> shift) & 0xf;
606 switch (val) {
607 case 1:
608 case 2:
609 case 3:
610 case 4:
611 return 1;
612 default:
613 return 0;
614 }
615
616}
617
604 switch (val) {
605 case 1:
606 case 2:
607 case 3:
608 case 4:
609 return 1;
610 default:
611 return 0;
612 }
613
614}
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
618/* Digital Mixer */
619static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = {
620 SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER,
621 RT5645_M_ADC_L1_SFT, 1, 1),
622 SOC_DAPM_SINGLE("ADC2 Switch", RT5645_STO1_ADC_MIXER,
623 RT5645_M_ADC_L2_SFT, 1, 1),
624};
625

--- 565 unchanged lines hidden (view full) ---

1191 RT5645_PWR_HA, 0);
1192 }
1193 }
1194}
1195
1196static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
1197 struct snd_kcontrol *kcontrol, int event)
1198{
697/* Digital Mixer */
698static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = {
699 SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER,
700 RT5645_M_ADC_L1_SFT, 1, 1),
701 SOC_DAPM_SINGLE("ADC2 Switch", RT5645_STO1_ADC_MIXER,
702 RT5645_M_ADC_L2_SFT, 1, 1),
703};
704

--- 565 unchanged lines hidden (view full) ---

1270 RT5645_PWR_HA, 0);
1271 }
1272 }
1273}
1274
1275static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
1276 struct snd_kcontrol *kcontrol, int event)
1277{
1199 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1278 struct snd_soc_codec *codec = w->codec;
1200 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
1201
1202 switch (event) {
1203 case SND_SOC_DAPM_POST_PMU:
1204 hp_amp_power(codec, 1);
1205 /* headphone unmute sequence */
1206 if (rt5645->codec_type == CODEC_TYPE_RT5650) {
1207 snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737);

--- 53 unchanged lines hidden (view full) ---

1261 }
1262
1263 return 0;
1264}
1265
1266static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
1267 struct snd_kcontrol *kcontrol, int event)
1268{
1279 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
1280
1281 switch (event) {
1282 case SND_SOC_DAPM_POST_PMU:
1283 hp_amp_power(codec, 1);
1284 /* headphone unmute sequence */
1285 if (rt5645->codec_type == CODEC_TYPE_RT5650) {
1286 snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737);

--- 53 unchanged lines hidden (view full) ---

1340 }
1341
1342 return 0;
1343}
1344
1345static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
1346 struct snd_kcontrol *kcontrol, int event)
1347{
1269 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1348 struct snd_soc_codec *codec = w->codec;
1270
1271 switch (event) {
1272 case SND_SOC_DAPM_POST_PMU:
1273 snd_soc_update_bits(codec, RT5645_PWR_DIG1,
1274 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
1275 RT5645_PWR_CLS_D_L,
1276 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
1277 RT5645_PWR_CLS_D_L);

--- 10 unchanged lines hidden (view full) ---

1288 }
1289
1290 return 0;
1291}
1292
1293static int rt5645_lout_event(struct snd_soc_dapm_widget *w,
1294 struct snd_kcontrol *kcontrol, int event)
1295{
1349
1350 switch (event) {
1351 case SND_SOC_DAPM_POST_PMU:
1352 snd_soc_update_bits(codec, RT5645_PWR_DIG1,
1353 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
1354 RT5645_PWR_CLS_D_L,
1355 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
1356 RT5645_PWR_CLS_D_L);

--- 10 unchanged lines hidden (view full) ---

1367 }
1368
1369 return 0;
1370}
1371
1372static int rt5645_lout_event(struct snd_soc_dapm_widget *w,
1373 struct snd_kcontrol *kcontrol, int event)
1374{
1296 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1375 struct snd_soc_codec *codec = w->codec;
1297
1298 switch (event) {
1299 case SND_SOC_DAPM_POST_PMU:
1300 hp_amp_power(codec, 1);
1301 snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
1302 RT5645_PWR_LM, RT5645_PWR_LM);
1303 snd_soc_update_bits(codec, RT5645_LOUT1,
1304 RT5645_L_MUTE | RT5645_R_MUTE, 0);

--- 13 unchanged lines hidden (view full) ---

1318 }
1319
1320 return 0;
1321}
1322
1323static int rt5645_bst2_event(struct snd_soc_dapm_widget *w,
1324 struct snd_kcontrol *kcontrol, int event)
1325{
1376
1377 switch (event) {
1378 case SND_SOC_DAPM_POST_PMU:
1379 hp_amp_power(codec, 1);
1380 snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
1381 RT5645_PWR_LM, RT5645_PWR_LM);
1382 snd_soc_update_bits(codec, RT5645_LOUT1,
1383 RT5645_L_MUTE | RT5645_R_MUTE, 0);

--- 13 unchanged lines hidden (view full) ---

1397 }
1398
1399 return 0;
1400}
1401
1402static int rt5645_bst2_event(struct snd_soc_dapm_widget *w,
1403 struct snd_kcontrol *kcontrol, int event)
1404{
1326 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1405 struct snd_soc_codec *codec = w->codec;
1327
1328 switch (event) {
1329 case SND_SOC_DAPM_POST_PMU:
1330 snd_soc_update_bits(codec, RT5645_PWR_ANLG2,
1331 RT5645_PWR_BST2_P, RT5645_PWR_BST2_P);
1332 break;
1333
1334 case SND_SOC_DAPM_PRE_PMD:

--- 1431 unchanged lines hidden ---
1406
1407 switch (event) {
1408 case SND_SOC_DAPM_POST_PMU:
1409 snd_soc_update_bits(codec, RT5645_PWR_ANLG2,
1410 RT5645_PWR_BST2_P, RT5645_PWR_BST2_P);
1411 break;
1412
1413 case SND_SOC_DAPM_PRE_PMD:

--- 1431 unchanged lines hidden ---