diff options
Diffstat (limited to 'sound/soc/codecs')
135 files changed, 8215 insertions, 3071 deletions
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 75d0ad5d2dcb..b07e17160f94 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c | |||
@@ -448,38 +448,38 @@ static const char *pm860x_opamp_texts[] = {"-50%", "-25%", "0%", "75%"}; | |||
448 | 448 | ||
449 | static const char *pm860x_pa_texts[] = {"-33%", "0%", "33%", "66%"}; | 449 | static const char *pm860x_pa_texts[] = {"-33%", "0%", "33%", "66%"}; |
450 | 450 | ||
451 | static const struct soc_enum pm860x_hs1_opamp_enum = | 451 | static SOC_ENUM_SINGLE_DECL(pm860x_hs1_opamp_enum, |
452 | SOC_ENUM_SINGLE(PM860X_HS1_CTRL, 5, 4, pm860x_opamp_texts); | 452 | PM860X_HS1_CTRL, 5, pm860x_opamp_texts); |
453 | 453 | ||
454 | static const struct soc_enum pm860x_hs2_opamp_enum = | 454 | static SOC_ENUM_SINGLE_DECL(pm860x_hs2_opamp_enum, |
455 | SOC_ENUM_SINGLE(PM860X_HS2_CTRL, 5, 4, pm860x_opamp_texts); | 455 | PM860X_HS2_CTRL, 5, pm860x_opamp_texts); |
456 | 456 | ||
457 | static const struct soc_enum pm860x_hs1_pa_enum = | 457 | static SOC_ENUM_SINGLE_DECL(pm860x_hs1_pa_enum, |
458 | SOC_ENUM_SINGLE(PM860X_HS1_CTRL, 3, 4, pm860x_pa_texts); | 458 | PM860X_HS1_CTRL, 3, pm860x_pa_texts); |
459 | 459 | ||
460 | static const struct soc_enum pm860x_hs2_pa_enum = | 460 | static SOC_ENUM_SINGLE_DECL(pm860x_hs2_pa_enum, |
461 | SOC_ENUM_SINGLE(PM860X_HS2_CTRL, 3, 4, pm860x_pa_texts); | 461 | PM860X_HS2_CTRL, 3, pm860x_pa_texts); |
462 | 462 | ||
463 | static const struct soc_enum pm860x_lo1_opamp_enum = | 463 | static SOC_ENUM_SINGLE_DECL(pm860x_lo1_opamp_enum, |
464 | SOC_ENUM_SINGLE(PM860X_LO1_CTRL, 5, 4, pm860x_opamp_texts); | 464 | PM860X_LO1_CTRL, 5, pm860x_opamp_texts); |
465 | 465 | ||
466 | static const struct soc_enum pm860x_lo2_opamp_enum = | 466 | static SOC_ENUM_SINGLE_DECL(pm860x_lo2_opamp_enum, |
467 | SOC_ENUM_SINGLE(PM860X_LO2_CTRL, 5, 4, pm860x_opamp_texts); | 467 | PM860X_LO2_CTRL, 5, pm860x_opamp_texts); |
468 | 468 | ||
469 | static const struct soc_enum pm860x_lo1_pa_enum = | 469 | static SOC_ENUM_SINGLE_DECL(pm860x_lo1_pa_enum, |
470 | SOC_ENUM_SINGLE(PM860X_LO1_CTRL, 3, 4, pm860x_pa_texts); | 470 | PM860X_LO1_CTRL, 3, pm860x_pa_texts); |
471 | 471 | ||
472 | static const struct soc_enum pm860x_lo2_pa_enum = | 472 | static SOC_ENUM_SINGLE_DECL(pm860x_lo2_pa_enum, |
473 | SOC_ENUM_SINGLE(PM860X_LO2_CTRL, 3, 4, pm860x_pa_texts); | 473 | PM860X_LO2_CTRL, 3, pm860x_pa_texts); |
474 | 474 | ||
475 | static const struct soc_enum pm860x_spk_pa_enum = | 475 | static SOC_ENUM_SINGLE_DECL(pm860x_spk_pa_enum, |
476 | SOC_ENUM_SINGLE(PM860X_EAR_CTRL_1, 5, 4, pm860x_pa_texts); | 476 | PM860X_EAR_CTRL_1, 5, pm860x_pa_texts); |
477 | 477 | ||
478 | static const struct soc_enum pm860x_ear_pa_enum = | 478 | static SOC_ENUM_SINGLE_DECL(pm860x_ear_pa_enum, |
479 | SOC_ENUM_SINGLE(PM860X_EAR_CTRL_2, 0, 4, pm860x_pa_texts); | 479 | PM860X_EAR_CTRL_2, 0, pm860x_pa_texts); |
480 | 480 | ||
481 | static const struct soc_enum pm860x_spk_ear_opamp_enum = | 481 | static SOC_ENUM_SINGLE_DECL(pm860x_spk_ear_opamp_enum, |
482 | SOC_ENUM_SINGLE(PM860X_EAR_CTRL_1, 3, 4, pm860x_opamp_texts); | 482 | PM860X_EAR_CTRL_1, 3, pm860x_opamp_texts); |
483 | 483 | ||
484 | static const struct snd_kcontrol_new pm860x_snd_controls[] = { | 484 | static const struct snd_kcontrol_new pm860x_snd_controls[] = { |
485 | SOC_DOUBLE_R_TLV("ADC Capture Volume", PM860X_ADC_ANA_2, | 485 | SOC_DOUBLE_R_TLV("ADC Capture Volume", PM860X_ADC_ANA_2, |
@@ -561,8 +561,8 @@ static const char *aif1_text[] = { | |||
561 | "PCM L", "PCM R", | 561 | "PCM L", "PCM R", |
562 | }; | 562 | }; |
563 | 563 | ||
564 | static const struct soc_enum aif1_enum = | 564 | static SOC_ENUM_SINGLE_DECL(aif1_enum, |
565 | SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 6, 2, aif1_text); | 565 | PM860X_PCM_IFACE_3, 6, aif1_text); |
566 | 566 | ||
567 | static const struct snd_kcontrol_new aif1_mux = | 567 | static const struct snd_kcontrol_new aif1_mux = |
568 | SOC_DAPM_ENUM("PCM Mux", aif1_enum); | 568 | SOC_DAPM_ENUM("PCM Mux", aif1_enum); |
@@ -572,8 +572,8 @@ static const char *i2s_din_text[] = { | |||
572 | "DIN", "DIN1", | 572 | "DIN", "DIN1", |
573 | }; | 573 | }; |
574 | 574 | ||
575 | static const struct soc_enum i2s_din_enum = | 575 | static SOC_ENUM_SINGLE_DECL(i2s_din_enum, |
576 | SOC_ENUM_SINGLE(PM860X_I2S_IFACE_3, 1, 2, i2s_din_text); | 576 | PM860X_I2S_IFACE_3, 1, i2s_din_text); |
577 | 577 | ||
578 | static const struct snd_kcontrol_new i2s_din_mux = | 578 | static const struct snd_kcontrol_new i2s_din_mux = |
579 | SOC_DAPM_ENUM("I2S DIN Mux", i2s_din_enum); | 579 | SOC_DAPM_ENUM("I2S DIN Mux", i2s_din_enum); |
@@ -583,8 +583,8 @@ static const char *i2s_mic_text[] = { | |||
583 | "Ex PA", "ADC", | 583 | "Ex PA", "ADC", |
584 | }; | 584 | }; |
585 | 585 | ||
586 | static const struct soc_enum i2s_mic_enum = | 586 | static SOC_ENUM_SINGLE_DECL(i2s_mic_enum, |
587 | SOC_ENUM_SINGLE(PM860X_I2S_IFACE_3, 4, 2, i2s_mic_text); | 587 | PM860X_I2S_IFACE_3, 4, i2s_mic_text); |
588 | 588 | ||
589 | static const struct snd_kcontrol_new i2s_mic_mux = | 589 | static const struct snd_kcontrol_new i2s_mic_mux = |
590 | SOC_DAPM_ENUM("I2S Mic Mux", i2s_mic_enum); | 590 | SOC_DAPM_ENUM("I2S Mic Mux", i2s_mic_enum); |
@@ -594,8 +594,8 @@ static const char *adcl_text[] = { | |||
594 | "ADCR", "ADCL", | 594 | "ADCR", "ADCL", |
595 | }; | 595 | }; |
596 | 596 | ||
597 | static const struct soc_enum adcl_enum = | 597 | static SOC_ENUM_SINGLE_DECL(adcl_enum, |
598 | SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 4, 2, adcl_text); | 598 | PM860X_PCM_IFACE_3, 4, adcl_text); |
599 | 599 | ||
600 | static const struct snd_kcontrol_new adcl_mux = | 600 | static const struct snd_kcontrol_new adcl_mux = |
601 | SOC_DAPM_ENUM("ADC Left Mux", adcl_enum); | 601 | SOC_DAPM_ENUM("ADC Left Mux", adcl_enum); |
@@ -605,8 +605,8 @@ static const char *adcr_text[] = { | |||
605 | "ADCL", "ADCR", | 605 | "ADCL", "ADCR", |
606 | }; | 606 | }; |
607 | 607 | ||
608 | static const struct soc_enum adcr_enum = | 608 | static SOC_ENUM_SINGLE_DECL(adcr_enum, |
609 | SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 2, 2, adcr_text); | 609 | PM860X_PCM_IFACE_3, 2, adcr_text); |
610 | 610 | ||
611 | static const struct snd_kcontrol_new adcr_mux = | 611 | static const struct snd_kcontrol_new adcr_mux = |
612 | SOC_DAPM_ENUM("ADC Right Mux", adcr_enum); | 612 | SOC_DAPM_ENUM("ADC Right Mux", adcr_enum); |
@@ -616,8 +616,8 @@ static const char *adcr_ec_text[] = { | |||
616 | "ADCR", "EC", | 616 | "ADCR", "EC", |
617 | }; | 617 | }; |
618 | 618 | ||
619 | static const struct soc_enum adcr_ec_enum = | 619 | static SOC_ENUM_SINGLE_DECL(adcr_ec_enum, |
620 | SOC_ENUM_SINGLE(PM860X_ADC_EN_2, 3, 2, adcr_ec_text); | 620 | PM860X_ADC_EN_2, 3, adcr_ec_text); |
621 | 621 | ||
622 | static const struct snd_kcontrol_new adcr_ec_mux = | 622 | static const struct snd_kcontrol_new adcr_ec_mux = |
623 | SOC_DAPM_ENUM("ADCR EC Mux", adcr_ec_enum); | 623 | SOC_DAPM_ENUM("ADCR EC Mux", adcr_ec_enum); |
@@ -627,8 +627,8 @@ static const char *ec_text[] = { | |||
627 | "Left", "Right", "Left + Right", | 627 | "Left", "Right", "Left + Right", |
628 | }; | 628 | }; |
629 | 629 | ||
630 | static const struct soc_enum ec_enum = | 630 | static SOC_ENUM_SINGLE_DECL(ec_enum, |
631 | SOC_ENUM_SINGLE(PM860X_EC_PATH, 1, 3, ec_text); | 631 | PM860X_EC_PATH, 1, ec_text); |
632 | 632 | ||
633 | static const struct snd_kcontrol_new ec_mux = | 633 | static const struct snd_kcontrol_new ec_mux = |
634 | SOC_DAPM_ENUM("EC Mux", ec_enum); | 634 | SOC_DAPM_ENUM("EC Mux", ec_enum); |
@@ -638,36 +638,36 @@ static const char *dac_text[] = { | |||
638 | }; | 638 | }; |
639 | 639 | ||
640 | /* DAC Headset 1 Mux / Mux10 */ | 640 | /* DAC Headset 1 Mux / Mux10 */ |
641 | static const struct soc_enum dac_hs1_enum = | 641 | static SOC_ENUM_SINGLE_DECL(dac_hs1_enum, |
642 | SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 0, 4, dac_text); | 642 | PM860X_ANA_INPUT_SEL_1, 0, dac_text); |
643 | 643 | ||
644 | static const struct snd_kcontrol_new dac_hs1_mux = | 644 | static const struct snd_kcontrol_new dac_hs1_mux = |
645 | SOC_DAPM_ENUM("DAC HS1 Mux", dac_hs1_enum); | 645 | SOC_DAPM_ENUM("DAC HS1 Mux", dac_hs1_enum); |
646 | 646 | ||
647 | /* DAC Headset 2 Mux / Mux11 */ | 647 | /* DAC Headset 2 Mux / Mux11 */ |
648 | static const struct soc_enum dac_hs2_enum = | 648 | static SOC_ENUM_SINGLE_DECL(dac_hs2_enum, |
649 | SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 2, 4, dac_text); | 649 | PM860X_ANA_INPUT_SEL_1, 2, dac_text); |
650 | 650 | ||
651 | static const struct snd_kcontrol_new dac_hs2_mux = | 651 | static const struct snd_kcontrol_new dac_hs2_mux = |
652 | SOC_DAPM_ENUM("DAC HS2 Mux", dac_hs2_enum); | 652 | SOC_DAPM_ENUM("DAC HS2 Mux", dac_hs2_enum); |
653 | 653 | ||
654 | /* DAC Lineout 1 Mux / Mux12 */ | 654 | /* DAC Lineout 1 Mux / Mux12 */ |
655 | static const struct soc_enum dac_lo1_enum = | 655 | static SOC_ENUM_SINGLE_DECL(dac_lo1_enum, |
656 | SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 4, 4, dac_text); | 656 | PM860X_ANA_INPUT_SEL_1, 4, dac_text); |
657 | 657 | ||
658 | static const struct snd_kcontrol_new dac_lo1_mux = | 658 | static const struct snd_kcontrol_new dac_lo1_mux = |
659 | SOC_DAPM_ENUM("DAC LO1 Mux", dac_lo1_enum); | 659 | SOC_DAPM_ENUM("DAC LO1 Mux", dac_lo1_enum); |
660 | 660 | ||
661 | /* DAC Lineout 2 Mux / Mux13 */ | 661 | /* DAC Lineout 2 Mux / Mux13 */ |
662 | static const struct soc_enum dac_lo2_enum = | 662 | static SOC_ENUM_SINGLE_DECL(dac_lo2_enum, |
663 | SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 6, 4, dac_text); | 663 | PM860X_ANA_INPUT_SEL_1, 6, dac_text); |
664 | 664 | ||
665 | static const struct snd_kcontrol_new dac_lo2_mux = | 665 | static const struct snd_kcontrol_new dac_lo2_mux = |
666 | SOC_DAPM_ENUM("DAC LO2 Mux", dac_lo2_enum); | 666 | SOC_DAPM_ENUM("DAC LO2 Mux", dac_lo2_enum); |
667 | 667 | ||
668 | /* DAC Spearker Earphone Mux / Mux14 */ | 668 | /* DAC Spearker Earphone Mux / Mux14 */ |
669 | static const struct soc_enum dac_spk_ear_enum = | 669 | static SOC_ENUM_SINGLE_DECL(dac_spk_ear_enum, |
670 | SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_2, 0, 4, dac_text); | 670 | PM860X_ANA_INPUT_SEL_2, 0, dac_text); |
671 | 671 | ||
672 | static const struct snd_kcontrol_new dac_spk_ear_mux = | 672 | static const struct snd_kcontrol_new dac_spk_ear_mux = |
673 | SOC_DAPM_ENUM("DAC SP Mux", dac_spk_ear_enum); | 673 | SOC_DAPM_ENUM("DAC SP Mux", dac_spk_ear_enum); |
@@ -677,29 +677,29 @@ static const char *in_text[] = { | |||
677 | "Digital", "Analog", | 677 | "Digital", "Analog", |
678 | }; | 678 | }; |
679 | 679 | ||
680 | static const struct soc_enum hs1_enum = | 680 | static SOC_ENUM_SINGLE_DECL(hs1_enum, |
681 | SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 0, 2, in_text); | 681 | PM860X_ANA_TO_ANA, 0, in_text); |
682 | 682 | ||
683 | static const struct snd_kcontrol_new hs1_mux = | 683 | static const struct snd_kcontrol_new hs1_mux = |
684 | SOC_DAPM_ENUM("Headset1 Mux", hs1_enum); | 684 | SOC_DAPM_ENUM("Headset1 Mux", hs1_enum); |
685 | 685 | ||
686 | /* Headset 2 Mux / Mux16 */ | 686 | /* Headset 2 Mux / Mux16 */ |
687 | static const struct soc_enum hs2_enum = | 687 | static SOC_ENUM_SINGLE_DECL(hs2_enum, |
688 | SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 1, 2, in_text); | 688 | PM860X_ANA_TO_ANA, 1, in_text); |
689 | 689 | ||
690 | static const struct snd_kcontrol_new hs2_mux = | 690 | static const struct snd_kcontrol_new hs2_mux = |
691 | SOC_DAPM_ENUM("Headset2 Mux", hs2_enum); | 691 | SOC_DAPM_ENUM("Headset2 Mux", hs2_enum); |
692 | 692 | ||
693 | /* Lineout 1 Mux / Mux17 */ | 693 | /* Lineout 1 Mux / Mux17 */ |
694 | static const struct soc_enum lo1_enum = | 694 | static SOC_ENUM_SINGLE_DECL(lo1_enum, |
695 | SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 2, 2, in_text); | 695 | PM860X_ANA_TO_ANA, 2, in_text); |
696 | 696 | ||
697 | static const struct snd_kcontrol_new lo1_mux = | 697 | static const struct snd_kcontrol_new lo1_mux = |
698 | SOC_DAPM_ENUM("Lineout1 Mux", lo1_enum); | 698 | SOC_DAPM_ENUM("Lineout1 Mux", lo1_enum); |
699 | 699 | ||
700 | /* Lineout 2 Mux / Mux18 */ | 700 | /* Lineout 2 Mux / Mux18 */ |
701 | static const struct soc_enum lo2_enum = | 701 | static SOC_ENUM_SINGLE_DECL(lo2_enum, |
702 | SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 3, 2, in_text); | 702 | PM860X_ANA_TO_ANA, 3, in_text); |
703 | 703 | ||
704 | static const struct snd_kcontrol_new lo2_mux = | 704 | static const struct snd_kcontrol_new lo2_mux = |
705 | SOC_DAPM_ENUM("Lineout2 Mux", lo2_enum); | 705 | SOC_DAPM_ENUM("Lineout2 Mux", lo2_enum); |
@@ -709,8 +709,8 @@ static const char *spk_text[] = { | |||
709 | "Earpiece", "Speaker", | 709 | "Earpiece", "Speaker", |
710 | }; | 710 | }; |
711 | 711 | ||
712 | static const struct soc_enum spk_enum = | 712 | static SOC_ENUM_SINGLE_DECL(spk_enum, |
713 | SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 6, 2, spk_text); | 713 | PM860X_ANA_TO_ANA, 6, spk_text); |
714 | 714 | ||
715 | static const struct snd_kcontrol_new spk_demux = | 715 | static const struct snd_kcontrol_new spk_demux = |
716 | SOC_DAPM_ENUM("Speaker Earpiece Demux", spk_enum); | 716 | SOC_DAPM_ENUM("Speaker Earpiece Demux", spk_enum); |
@@ -720,8 +720,8 @@ static const char *mic_text[] = { | |||
720 | "Mic 1", "Mic 2", | 720 | "Mic 1", "Mic 2", |
721 | }; | 721 | }; |
722 | 722 | ||
723 | static const struct soc_enum mic_enum = | 723 | static SOC_ENUM_SINGLE_DECL(mic_enum, |
724 | SOC_ENUM_SINGLE(PM860X_ADC_ANA_4, 4, 2, mic_text); | 724 | PM860X_ADC_ANA_4, 4, mic_text); |
725 | 725 | ||
726 | static const struct snd_kcontrol_new mic_mux = | 726 | static const struct snd_kcontrol_new mic_mux = |
727 | SOC_DAPM_ENUM("MIC Mux", mic_enum); | 727 | SOC_DAPM_ENUM("MIC Mux", mic_enum); |
@@ -1327,7 +1327,9 @@ static int pm860x_probe(struct snd_soc_codec *codec) | |||
1327 | 1327 | ||
1328 | pm860x->codec = codec; | 1328 | pm860x->codec = codec; |
1329 | 1329 | ||
1330 | codec->control_data = pm860x->regmap; | 1330 | ret = snd_soc_codec_set_cache_io(codec, pm860x->regmap); |
1331 | if (ret) | ||
1332 | return ret; | ||
1331 | 1333 | ||
1332 | for (i = 0; i < 4; i++) { | 1334 | for (i = 0; i < 4; i++) { |
1333 | ret = request_threaded_irq(pm860x->irq[i], NULL, | 1335 | ret = request_threaded_irq(pm860x->irq[i], NULL, |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 983d087aa92a..f0e840137887 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -8,6 +8,8 @@ config SND_SOC_I2C_AND_SPI | |||
8 | default y if I2C=y | 8 | default y if I2C=y |
9 | default y if SPI_MASTER=y | 9 | default y if SPI_MASTER=y |
10 | 10 | ||
11 | menu "CODEC drivers" | ||
12 | |||
11 | config SND_SOC_ALL_CODECS | 13 | config SND_SOC_ALL_CODECS |
12 | tristate "Build all ASoC CODEC drivers" | 14 | tristate "Build all ASoC CODEC drivers" |
13 | depends on COMPILE_TEST | 15 | depends on COMPILE_TEST |
@@ -16,15 +18,20 @@ config SND_SOC_ALL_CODECS | |||
16 | select SND_SOC_AB8500_CODEC if ABX500_CORE | 18 | select SND_SOC_AB8500_CODEC if ABX500_CORE |
17 | select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS | 19 | select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS |
18 | select SND_SOC_AD1836 if SPI_MASTER | 20 | select SND_SOC_AD1836 if SPI_MASTER |
19 | select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI | 21 | select SND_SOC_AD193X_SPI if SPI_MASTER |
22 | select SND_SOC_AD193X_I2C if I2C | ||
20 | select SND_SOC_AD1980 if SND_SOC_AC97_BUS | 23 | select SND_SOC_AD1980 if SND_SOC_AC97_BUS |
21 | select SND_SOC_AD73311 | 24 | select SND_SOC_AD73311 |
22 | select SND_SOC_ADAU1373 if I2C | 25 | select SND_SOC_ADAU1373 if I2C |
23 | select SND_SOC_ADAV80X if SND_SOC_I2C_AND_SPI | 26 | select SND_SOC_ADAV801 if SPI_MASTER |
27 | select SND_SOC_ADAV803 if I2C | ||
28 | select SND_SOC_ADAU1977_SPI if SPI_MASTER | ||
29 | select SND_SOC_ADAU1977_I2C if I2C | ||
24 | select SND_SOC_ADAU1701 if I2C | 30 | select SND_SOC_ADAU1701 if I2C |
25 | select SND_SOC_ADS117X | 31 | select SND_SOC_ADS117X |
26 | select SND_SOC_AK4104 if SPI_MASTER | 32 | select SND_SOC_AK4104 if SPI_MASTER |
27 | select SND_SOC_AK4535 if I2C | 33 | select SND_SOC_AK4535 if I2C |
34 | select SND_SOC_AK4554 | ||
28 | select SND_SOC_AK4641 if I2C | 35 | select SND_SOC_AK4641 if I2C |
29 | select SND_SOC_AK4642 if I2C | 36 | select SND_SOC_AK4642 if I2C |
30 | select SND_SOC_AK4671 if I2C | 37 | select SND_SOC_AK4671 if I2C |
@@ -37,6 +44,7 @@ config SND_SOC_ALL_CODECS | |||
37 | select SND_SOC_CS42L73 if I2C | 44 | select SND_SOC_CS42L73 if I2C |
38 | select SND_SOC_CS4270 if I2C | 45 | select SND_SOC_CS4270 if I2C |
39 | select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI | 46 | select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI |
47 | select SND_SOC_CS42XX8_I2C if I2C | ||
40 | select SND_SOC_CX20442 if TTY | 48 | select SND_SOC_CX20442 if TTY |
41 | select SND_SOC_DA7210 if I2C | 49 | select SND_SOC_DA7210 if I2C |
42 | select SND_SOC_DA7213 if I2C | 50 | select SND_SOC_DA7213 if I2C |
@@ -59,20 +67,26 @@ config SND_SOC_ALL_CODECS | |||
59 | select SND_SOC_PCM1681 if I2C | 67 | select SND_SOC_PCM1681 if I2C |
60 | select SND_SOC_PCM1792A if SPI_MASTER | 68 | select SND_SOC_PCM1792A if SPI_MASTER |
61 | select SND_SOC_PCM3008 | 69 | select SND_SOC_PCM3008 |
70 | select SND_SOC_PCM512x_I2C if I2C | ||
71 | select SND_SOC_PCM512x_SPI if SPI_MASTER | ||
62 | select SND_SOC_RT5631 if I2C | 72 | select SND_SOC_RT5631 if I2C |
63 | select SND_SOC_RT5640 if I2C | 73 | select SND_SOC_RT5640 if I2C |
64 | select SND_SOC_SGTL5000 if I2C | 74 | select SND_SOC_SGTL5000 if I2C |
65 | select SND_SOC_SI476X if MFD_SI476X_CORE | 75 | select SND_SOC_SI476X if MFD_SI476X_CORE |
76 | select SND_SOC_SIRF_AUDIO_CODEC | ||
66 | select SND_SOC_SN95031 if INTEL_SCU_IPC | 77 | select SND_SOC_SN95031 if INTEL_SCU_IPC |
67 | select SND_SOC_SPDIF | 78 | select SND_SOC_SPDIF |
68 | select SND_SOC_SSM2518 if I2C | 79 | select SND_SOC_SSM2518 if I2C |
69 | select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI | 80 | select SND_SOC_SSM2602_SPI if SPI_MASTER |
81 | select SND_SOC_SSM2602_I2C if I2C | ||
70 | select SND_SOC_STA32X if I2C | 82 | select SND_SOC_STA32X if I2C |
71 | select SND_SOC_STA529 if I2C | 83 | select SND_SOC_STA529 if I2C |
72 | select SND_SOC_STAC9766 if SND_SOC_AC97_BUS | 84 | select SND_SOC_STAC9766 if SND_SOC_AC97_BUS |
73 | select SND_SOC_TAS5086 if I2C | 85 | select SND_SOC_TAS5086 if I2C |
74 | select SND_SOC_TLV320AIC23 if I2C | 86 | select SND_SOC_TLV320AIC23_I2C if I2C |
87 | select SND_SOC_TLV320AIC23_SPI if SPI_MASTER | ||
75 | select SND_SOC_TLV320AIC26 if SPI_MASTER | 88 | select SND_SOC_TLV320AIC26 if SPI_MASTER |
89 | select SND_SOC_TLV320AIC31XX if I2C | ||
76 | select SND_SOC_TLV320AIC32X4 if I2C | 90 | select SND_SOC_TLV320AIC32X4 if I2C |
77 | select SND_SOC_TLV320AIC3X if I2C | 91 | select SND_SOC_TLV320AIC3X if I2C |
78 | select SND_SOC_TPA6130A2 if I2C | 92 | select SND_SOC_TPA6130A2 if I2C |
@@ -182,6 +196,14 @@ config SND_SOC_AD1836 | |||
182 | config SND_SOC_AD193X | 196 | config SND_SOC_AD193X |
183 | tristate | 197 | tristate |
184 | 198 | ||
199 | config SND_SOC_AD193X_SPI | ||
200 | tristate | ||
201 | select SND_SOC_AD193X | ||
202 | |||
203 | config SND_SOC_AD193X_I2C | ||
204 | tristate | ||
205 | select SND_SOC_AD193X | ||
206 | |||
185 | config SND_SOC_AD1980 | 207 | config SND_SOC_AD1980 |
186 | tristate | 208 | tristate |
187 | 209 | ||
@@ -189,41 +211,66 @@ config SND_SOC_AD73311 | |||
189 | tristate | 211 | tristate |
190 | 212 | ||
191 | config SND_SOC_ADAU1701 | 213 | config SND_SOC_ADAU1701 |
214 | tristate "Analog Devices ADAU1701 CODEC" | ||
215 | depends on I2C | ||
192 | select SND_SOC_SIGMADSP | 216 | select SND_SOC_SIGMADSP |
193 | tristate | ||
194 | 217 | ||
195 | config SND_SOC_ADAU1373 | 218 | config SND_SOC_ADAU1373 |
196 | tristate | 219 | tristate |
197 | 220 | ||
221 | config SND_SOC_ADAU1977 | ||
222 | tristate | ||
223 | |||
224 | config SND_SOC_ADAU1977_SPI | ||
225 | tristate | ||
226 | select SND_SOC_ADAU1977 | ||
227 | select REGMAP_SPI | ||
228 | |||
229 | config SND_SOC_ADAU1977_I2C | ||
230 | tristate | ||
231 | select SND_SOC_ADAU1977 | ||
232 | select REGMAP_I2C | ||
233 | |||
198 | config SND_SOC_ADAV80X | 234 | config SND_SOC_ADAV80X |
199 | tristate | 235 | tristate |
200 | 236 | ||
237 | config SND_SOC_ADAV801 | ||
238 | tristate | ||
239 | select SND_SOC_ADAV80X | ||
240 | |||
241 | config SND_SOC_ADAV803 | ||
242 | tristate | ||
243 | select SND_SOC_ADAV80X | ||
244 | |||
201 | config SND_SOC_ADS117X | 245 | config SND_SOC_ADS117X |
202 | tristate | 246 | tristate |
203 | 247 | ||
204 | config SND_SOC_AK4104 | 248 | config SND_SOC_AK4104 |
205 | tristate | 249 | tristate "AKM AK4104 CODEC" |
250 | depends on SPI_MASTER | ||
206 | 251 | ||
207 | config SND_SOC_AK4535 | 252 | config SND_SOC_AK4535 |
208 | tristate | 253 | tristate |
209 | 254 | ||
210 | config SND_SOC_AK4554 | 255 | config SND_SOC_AK4554 |
211 | tristate | 256 | tristate "AKM AK4554 CODEC" |
212 | 257 | ||
213 | config SND_SOC_AK4641 | 258 | config SND_SOC_AK4641 |
214 | tristate | 259 | tristate |
215 | 260 | ||
216 | config SND_SOC_AK4642 | 261 | config SND_SOC_AK4642 |
217 | tristate | 262 | tristate "AKM AK4642 CODEC" |
263 | depends on I2C | ||
218 | 264 | ||
219 | config SND_SOC_AK4671 | 265 | config SND_SOC_AK4671 |
220 | tristate | 266 | tristate |
221 | 267 | ||
222 | config SND_SOC_AK5386 | 268 | config SND_SOC_AK5386 |
223 | tristate | 269 | tristate "AKM AK5638 CODEC" |
224 | 270 | ||
225 | config SND_SOC_ALC5623 | 271 | config SND_SOC_ALC5623 |
226 | tristate | 272 | tristate |
273 | |||
227 | config SND_SOC_ALC5632 | 274 | config SND_SOC_ALC5632 |
228 | tristate | 275 | tristate |
229 | 276 | ||
@@ -234,14 +281,17 @@ config SND_SOC_CS42L51 | |||
234 | tristate | 281 | tristate |
235 | 282 | ||
236 | config SND_SOC_CS42L52 | 283 | config SND_SOC_CS42L52 |
237 | tristate | 284 | tristate "Cirrus Logic CS42L52 CODEC" |
285 | depends on I2C | ||
238 | 286 | ||
239 | config SND_SOC_CS42L73 | 287 | config SND_SOC_CS42L73 |
240 | tristate | 288 | tristate "Cirrus Logic CS42L73 CODEC" |
289 | depends on I2C | ||
241 | 290 | ||
242 | # Cirrus Logic CS4270 Codec | 291 | # Cirrus Logic CS4270 Codec |
243 | config SND_SOC_CS4270 | 292 | config SND_SOC_CS4270 |
244 | tristate | 293 | tristate "Cirrus Logic CS4270 CODEC" |
294 | depends on I2C | ||
245 | 295 | ||
246 | # Cirrus Logic CS4270 Codec VD = 3.3V Errata | 296 | # Cirrus Logic CS4270 Codec VD = 3.3V Errata |
247 | # Select if you are affected by the errata where the part will not function | 297 | # Select if you are affected by the errata where the part will not function |
@@ -252,8 +302,18 @@ config SND_SOC_CS4270_VD33_ERRATA | |||
252 | depends on SND_SOC_CS4270 | 302 | depends on SND_SOC_CS4270 |
253 | 303 | ||
254 | config SND_SOC_CS4271 | 304 | config SND_SOC_CS4271 |
305 | tristate "Cirrus Logic CS4271 CODEC" | ||
306 | depends on SND_SOC_I2C_AND_SPI | ||
307 | |||
308 | config SND_SOC_CS42XX8 | ||
255 | tristate | 309 | tristate |
256 | 310 | ||
311 | config SND_SOC_CS42XX8_I2C | ||
312 | tristate "Cirrus Logic CS42448/CS42888 CODEC (I2C)" | ||
313 | depends on I2C | ||
314 | select SND_SOC_CS42XX8 | ||
315 | select REGMAP_I2C | ||
316 | |||
257 | config SND_SOC_CX20442 | 317 | config SND_SOC_CX20442 |
258 | tristate | 318 | tristate |
259 | depends on TTY | 319 | depends on TTY |
@@ -283,6 +343,9 @@ config SND_SOC_BT_SCO | |||
283 | config SND_SOC_DMIC | 343 | config SND_SOC_DMIC |
284 | tristate | 344 | tristate |
285 | 345 | ||
346 | config SND_SOC_HDMI_CODEC | ||
347 | tristate "HDMI stub CODEC" | ||
348 | |||
286 | config SND_SOC_ISABELLE | 349 | config SND_SOC_ISABELLE |
287 | tristate | 350 | tristate |
288 | 351 | ||
@@ -301,18 +364,32 @@ config SND_SOC_MAX98095 | |||
301 | config SND_SOC_MAX9850 | 364 | config SND_SOC_MAX9850 |
302 | tristate | 365 | tristate |
303 | 366 | ||
304 | config SND_SOC_HDMI_CODEC | ||
305 | tristate | ||
306 | |||
307 | config SND_SOC_PCM1681 | 367 | config SND_SOC_PCM1681 |
308 | tristate | 368 | tristate "Texas Instruments PCM1681 CODEC" |
369 | depends on I2C | ||
309 | 370 | ||
310 | config SND_SOC_PCM1792A | 371 | config SND_SOC_PCM1792A |
311 | tristate | 372 | tristate "Texas Instruments PCM1792A CODEC" |
373 | depends on SPI_MASTER | ||
312 | 374 | ||
313 | config SND_SOC_PCM3008 | 375 | config SND_SOC_PCM3008 |
314 | tristate | 376 | tristate |
315 | 377 | ||
378 | config SND_SOC_PCM512x | ||
379 | tristate | ||
380 | |||
381 | config SND_SOC_PCM512x_I2C | ||
382 | tristate "Texas Instruments PCM512x CODECs - I2C" | ||
383 | depends on I2C | ||
384 | select SND_SOC_PCM512x | ||
385 | select REGMAP_I2C | ||
386 | |||
387 | config SND_SOC_PCM512x_SPI | ||
388 | tristate "Texas Instruments PCM512x CODECs - SPI" | ||
389 | depends on SPI_MASTER | ||
390 | select SND_SOC_PCM512x | ||
391 | select REGMAP_SPI | ||
392 | |||
316 | config SND_SOC_RT5631 | 393 | config SND_SOC_RT5631 |
317 | tristate | 394 | tristate |
318 | 395 | ||
@@ -321,7 +398,8 @@ config SND_SOC_RT5640 | |||
321 | 398 | ||
322 | #Freescale sgtl5000 codec | 399 | #Freescale sgtl5000 codec |
323 | config SND_SOC_SGTL5000 | 400 | config SND_SOC_SGTL5000 |
324 | tristate | 401 | tristate "Freescale SGTL5000 CODEC" |
402 | depends on I2C | ||
325 | 403 | ||
326 | config SND_SOC_SI476X | 404 | config SND_SOC_SI476X |
327 | tristate | 405 | tristate |
@@ -330,11 +408,15 @@ config SND_SOC_SIGMADSP | |||
330 | tristate | 408 | tristate |
331 | select CRC32 | 409 | select CRC32 |
332 | 410 | ||
411 | config SND_SOC_SIRF_AUDIO_CODEC | ||
412 | tristate "SiRF SoC internal audio codec" | ||
413 | select REGMAP_MMIO | ||
414 | |||
333 | config SND_SOC_SN95031 | 415 | config SND_SOC_SN95031 |
334 | tristate | 416 | tristate |
335 | 417 | ||
336 | config SND_SOC_SPDIF | 418 | config SND_SOC_SPDIF |
337 | tristate | 419 | tristate "S/PDIF CODEC" |
338 | 420 | ||
339 | config SND_SOC_SSM2518 | 421 | config SND_SOC_SSM2518 |
340 | tristate | 422 | tristate |
@@ -342,6 +424,14 @@ config SND_SOC_SSM2518 | |||
342 | config SND_SOC_SSM2602 | 424 | config SND_SOC_SSM2602 |
343 | tristate | 425 | tristate |
344 | 426 | ||
427 | config SND_SOC_SSM2602_SPI | ||
428 | select SND_SOC_SSM2602 | ||
429 | tristate | ||
430 | |||
431 | config SND_SOC_SSM2602_I2C | ||
432 | select SND_SOC_SSM2602 | ||
433 | tristate | ||
434 | |||
345 | config SND_SOC_STA32X | 435 | config SND_SOC_STA32X |
346 | tristate | 436 | tristate |
347 | 437 | ||
@@ -352,20 +442,33 @@ config SND_SOC_STAC9766 | |||
352 | tristate | 442 | tristate |
353 | 443 | ||
354 | config SND_SOC_TAS5086 | 444 | config SND_SOC_TAS5086 |
355 | tristate | 445 | tristate "Texas Instruments TAS5086 speaker amplifier" |
446 | depends on I2C | ||
356 | 447 | ||
357 | config SND_SOC_TLV320AIC23 | 448 | config SND_SOC_TLV320AIC23 |
358 | tristate | 449 | tristate |
359 | 450 | ||
451 | config SND_SOC_TLV320AIC23_I2C | ||
452 | tristate | ||
453 | select SND_SOC_TLV320AIC23 | ||
454 | |||
455 | config SND_SOC_TLV320AIC23_SPI | ||
456 | tristate | ||
457 | select SND_SOC_TLV320AIC23 | ||
458 | |||
360 | config SND_SOC_TLV320AIC26 | 459 | config SND_SOC_TLV320AIC26 |
361 | tristate | 460 | tristate |
362 | depends on SPI | 461 | depends on SPI |
363 | 462 | ||
463 | config SND_SOC_TLV320AIC31XX | ||
464 | tristate | ||
465 | |||
364 | config SND_SOC_TLV320AIC32X4 | 466 | config SND_SOC_TLV320AIC32X4 |
365 | tristate | 467 | tristate |
366 | 468 | ||
367 | config SND_SOC_TLV320AIC3X | 469 | config SND_SOC_TLV320AIC3X |
368 | tristate | 470 | tristate "Texas Instruments TLV320AIC3x CODECs" |
471 | depends on I2C | ||
369 | 472 | ||
370 | config SND_SOC_TLV320DAC33 | 473 | config SND_SOC_TLV320DAC33 |
371 | tristate | 474 | tristate |
@@ -414,55 +517,69 @@ config SND_SOC_WM8400 | |||
414 | tristate | 517 | tristate |
415 | 518 | ||
416 | config SND_SOC_WM8510 | 519 | config SND_SOC_WM8510 |
417 | tristate | 520 | tristate "Wolfson Microelectronics WM8510 CODEC" |
521 | depends on SND_SOC_I2C_AND_SPI | ||
418 | 522 | ||
419 | config SND_SOC_WM8523 | 523 | config SND_SOC_WM8523 |
420 | tristate | 524 | tristate "Wolfson Microelectronics WM8523 DAC" |
525 | depends on I2C | ||
421 | 526 | ||
422 | config SND_SOC_WM8580 | 527 | config SND_SOC_WM8580 |
423 | tristate | 528 | tristate "Wolfson Microelectronics WM8523 CODEC" |
529 | depends on I2C | ||
424 | 530 | ||
425 | config SND_SOC_WM8711 | 531 | config SND_SOC_WM8711 |
426 | tristate | 532 | tristate "Wolfson Microelectronics WM8711 CODEC" |
533 | depends on SND_SOC_I2C_AND_SPI | ||
427 | 534 | ||
428 | config SND_SOC_WM8727 | 535 | config SND_SOC_WM8727 |
429 | tristate | 536 | tristate |
430 | 537 | ||
431 | config SND_SOC_WM8728 | 538 | config SND_SOC_WM8728 |
432 | tristate | 539 | tristate "Wolfson Microelectronics WM8728 DAC" |
540 | depends on SND_SOC_I2C_AND_SPI | ||
433 | 541 | ||
434 | config SND_SOC_WM8731 | 542 | config SND_SOC_WM8731 |
435 | tristate | 543 | tristate "Wolfson Microelectronics WM8731 CODEC" |
544 | depends on SND_SOC_I2C_AND_SPI | ||
436 | 545 | ||
437 | config SND_SOC_WM8737 | 546 | config SND_SOC_WM8737 |
438 | tristate | 547 | tristate "Wolfson Microelectronics WM8737 ADC" |
548 | depends on SND_SOC_I2C_AND_SPI | ||
439 | 549 | ||
440 | config SND_SOC_WM8741 | 550 | config SND_SOC_WM8741 |
441 | tristate | 551 | tristate "Wolfson Microelectronics WM8737 DAC" |
552 | depends on SND_SOC_I2C_AND_SPI | ||
442 | 553 | ||
443 | config SND_SOC_WM8750 | 554 | config SND_SOC_WM8750 |
444 | tristate | 555 | tristate "Wolfson Microelectronics WM8750 CODEC" |
556 | depends on SND_SOC_I2C_AND_SPI | ||
445 | 557 | ||
446 | config SND_SOC_WM8753 | 558 | config SND_SOC_WM8753 |
447 | tristate | 559 | tristate "Wolfson Microelectronics WM8753 CODEC" |
560 | depends on SND_SOC_I2C_AND_SPI | ||
448 | 561 | ||
449 | config SND_SOC_WM8770 | 562 | config SND_SOC_WM8770 |
450 | tristate | 563 | tristate "Wolfson Microelectronics WM8770 CODEC" |
564 | depends on SPI_MASTER | ||
451 | 565 | ||
452 | config SND_SOC_WM8776 | 566 | config SND_SOC_WM8776 |
453 | tristate | 567 | tristate "Wolfson Microelectronics WM8776 CODEC" |
568 | depends on SND_SOC_I2C_AND_SPI | ||
454 | 569 | ||
455 | config SND_SOC_WM8782 | 570 | config SND_SOC_WM8782 |
456 | tristate | 571 | tristate |
457 | 572 | ||
458 | config SND_SOC_WM8804 | 573 | config SND_SOC_WM8804 |
459 | tristate | 574 | tristate "Wolfson Microelectronics WM8804 S/PDIF transceiver" |
575 | depends on SND_SOC_I2C_AND_SPI | ||
460 | 576 | ||
461 | config SND_SOC_WM8900 | 577 | config SND_SOC_WM8900 |
462 | tristate | 578 | tristate |
463 | 579 | ||
464 | config SND_SOC_WM8903 | 580 | config SND_SOC_WM8903 |
465 | tristate | 581 | tristate "Wolfson Microelectronics WM8903 CODEC" |
582 | depends on I2C | ||
466 | 583 | ||
467 | config SND_SOC_WM8904 | 584 | config SND_SOC_WM8904 |
468 | tristate | 585 | tristate |
@@ -480,7 +597,8 @@ config SND_SOC_WM8961 | |||
480 | tristate | 597 | tristate |
481 | 598 | ||
482 | config SND_SOC_WM8962 | 599 | config SND_SOC_WM8962 |
483 | tristate | 600 | tristate "Wolfson Microelectronics WM8962 CODEC" |
601 | depends on I2C | ||
484 | 602 | ||
485 | config SND_SOC_WM8971 | 603 | config SND_SOC_WM8971 |
486 | tristate | 604 | tristate |
@@ -553,4 +671,7 @@ config SND_SOC_ML26124 | |||
553 | tristate | 671 | tristate |
554 | 672 | ||
555 | config SND_SOC_TPA6130A2 | 673 | config SND_SOC_TPA6130A2 |
556 | tristate | 674 | tristate "Texas Instruments TPA6130A2 headphone amplifier" |
675 | depends on I2C | ||
676 | |||
677 | endmenu | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index bc126764a44d..3c4d275d064b 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -3,11 +3,18 @@ snd-soc-ab8500-codec-objs := ab8500-codec.o | |||
3 | snd-soc-ac97-objs := ac97.o | 3 | snd-soc-ac97-objs := ac97.o |
4 | snd-soc-ad1836-objs := ad1836.o | 4 | snd-soc-ad1836-objs := ad1836.o |
5 | snd-soc-ad193x-objs := ad193x.o | 5 | snd-soc-ad193x-objs := ad193x.o |
6 | snd-soc-ad193x-spi-objs := ad193x-spi.o | ||
7 | snd-soc-ad193x-i2c-objs := ad193x-i2c.o | ||
6 | snd-soc-ad1980-objs := ad1980.o | 8 | snd-soc-ad1980-objs := ad1980.o |
7 | snd-soc-ad73311-objs := ad73311.o | 9 | snd-soc-ad73311-objs := ad73311.o |
8 | snd-soc-adau1701-objs := adau1701.o | 10 | snd-soc-adau1701-objs := adau1701.o |
9 | snd-soc-adau1373-objs := adau1373.o | 11 | snd-soc-adau1373-objs := adau1373.o |
12 | snd-soc-adau1977-objs := adau1977.o | ||
13 | snd-soc-adau1977-spi-objs := adau1977-spi.o | ||
14 | snd-soc-adau1977-i2c-objs := adau1977-i2c.o | ||
10 | snd-soc-adav80x-objs := adav80x.o | 15 | snd-soc-adav80x-objs := adav80x.o |
16 | snd-soc-adav801-objs := adav801.o | ||
17 | snd-soc-adav803-objs := adav803.o | ||
11 | snd-soc-ads117x-objs := ads117x.o | 18 | snd-soc-ads117x-objs := ads117x.o |
12 | snd-soc-ak4104-objs := ak4104.o | 19 | snd-soc-ak4104-objs := ak4104.o |
13 | snd-soc-ak4535-objs := ak4535.o | 20 | snd-soc-ak4535-objs := ak4535.o |
@@ -23,6 +30,8 @@ snd-soc-cs42l52-objs := cs42l52.o | |||
23 | snd-soc-cs42l73-objs := cs42l73.o | 30 | snd-soc-cs42l73-objs := cs42l73.o |
24 | snd-soc-cs4270-objs := cs4270.o | 31 | snd-soc-cs4270-objs := cs4270.o |
25 | snd-soc-cs4271-objs := cs4271.o | 32 | snd-soc-cs4271-objs := cs4271.o |
33 | snd-soc-cs42xx8-objs := cs42xx8.o | ||
34 | snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o | ||
26 | snd-soc-cx20442-objs := cx20442.o | 35 | snd-soc-cx20442-objs := cx20442.o |
27 | snd-soc-da7210-objs := da7210.o | 36 | snd-soc-da7210-objs := da7210.o |
28 | snd-soc-da7213-objs := da7213.o | 37 | snd-soc-da7213-objs := da7213.o |
@@ -46,6 +55,9 @@ snd-soc-hdmi-codec-objs := hdmi.o | |||
46 | snd-soc-pcm1681-objs := pcm1681.o | 55 | snd-soc-pcm1681-objs := pcm1681.o |
47 | snd-soc-pcm1792a-codec-objs := pcm1792a.o | 56 | snd-soc-pcm1792a-codec-objs := pcm1792a.o |
48 | snd-soc-pcm3008-objs := pcm3008.o | 57 | snd-soc-pcm3008-objs := pcm3008.o |
58 | snd-soc-pcm512x-objs := pcm512x.o | ||
59 | snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o | ||
60 | snd-soc-pcm512x-spi-objs := pcm512x-spi.o | ||
49 | snd-soc-rt5631-objs := rt5631.o | 61 | snd-soc-rt5631-objs := rt5631.o |
50 | snd-soc-rt5640-objs := rt5640.o | 62 | snd-soc-rt5640-objs := rt5640.o |
51 | snd-soc-sgtl5000-objs := sgtl5000.o | 63 | snd-soc-sgtl5000-objs := sgtl5000.o |
@@ -53,19 +65,25 @@ snd-soc-alc5623-objs := alc5623.o | |||
53 | snd-soc-alc5632-objs := alc5632.o | 65 | snd-soc-alc5632-objs := alc5632.o |
54 | snd-soc-sigmadsp-objs := sigmadsp.o | 66 | snd-soc-sigmadsp-objs := sigmadsp.o |
55 | snd-soc-si476x-objs := si476x.o | 67 | snd-soc-si476x-objs := si476x.o |
68 | snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o | ||
56 | snd-soc-sn95031-objs := sn95031.o | 69 | snd-soc-sn95031-objs := sn95031.o |
57 | snd-soc-spdif-tx-objs := spdif_transmitter.o | 70 | snd-soc-spdif-tx-objs := spdif_transmitter.o |
58 | snd-soc-spdif-rx-objs := spdif_receiver.o | 71 | snd-soc-spdif-rx-objs := spdif_receiver.o |
59 | snd-soc-ssm2518-objs := ssm2518.o | 72 | snd-soc-ssm2518-objs := ssm2518.o |
60 | snd-soc-ssm2602-objs := ssm2602.o | 73 | snd-soc-ssm2602-objs := ssm2602.o |
74 | snd-soc-ssm2602-spi-objs := ssm2602-spi.o | ||
75 | snd-soc-ssm2602-i2c-objs := ssm2602-i2c.o | ||
61 | snd-soc-sta32x-objs := sta32x.o | 76 | snd-soc-sta32x-objs := sta32x.o |
62 | snd-soc-sta529-objs := sta529.o | 77 | snd-soc-sta529-objs := sta529.o |
63 | snd-soc-stac9766-objs := stac9766.o | 78 | snd-soc-stac9766-objs := stac9766.o |
64 | snd-soc-tas5086-objs := tas5086.o | 79 | snd-soc-tas5086-objs := tas5086.o |
65 | snd-soc-tlv320aic23-objs := tlv320aic23.o | 80 | snd-soc-tlv320aic23-objs := tlv320aic23.o |
81 | snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o | ||
82 | snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o | ||
66 | snd-soc-tlv320aic26-objs := tlv320aic26.o | 83 | snd-soc-tlv320aic26-objs := tlv320aic26.o |
67 | snd-soc-tlv320aic3x-objs := tlv320aic3x.o | 84 | snd-soc-tlv320aic31xx-objs := tlv320aic31xx.o |
68 | snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o | 85 | snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o |
86 | snd-soc-tlv320aic3x-objs := tlv320aic3x.o | ||
69 | snd-soc-tlv320dac33-objs := tlv320dac33.o | 87 | snd-soc-tlv320dac33-objs := tlv320dac33.o |
70 | snd-soc-twl4030-objs := twl4030.o | 88 | snd-soc-twl4030-objs := twl4030.o |
71 | snd-soc-twl6040-objs := twl6040.o | 89 | snd-soc-twl6040-objs := twl6040.o |
@@ -134,11 +152,18 @@ obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o | |||
134 | obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o | 152 | obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o |
135 | obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o | 153 | obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o |
136 | obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o | 154 | obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o |
155 | obj-$(CONFIG_SND_SOC_AD193X_SPI) += snd-soc-ad193x-spi.o | ||
156 | obj-$(CONFIG_SND_SOC_AD193X_I2C) += snd-soc-ad193x-i2c.o | ||
137 | obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o | 157 | obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o |
138 | obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o | 158 | obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o |
139 | obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o | 159 | obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o |
160 | obj-$(CONFIG_SND_SOC_ADAU1977) += snd-soc-adau1977.o | ||
161 | obj-$(CONFIG_SND_SOC_ADAU1977_SPI) += snd-soc-adau1977-spi.o | ||
162 | obj-$(CONFIG_SND_SOC_ADAU1977_I2C) += snd-soc-adau1977-i2c.o | ||
140 | obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o | 163 | obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o |
141 | obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o | 164 | obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o |
165 | obj-$(CONFIG_SND_SOC_ADAV801) += snd-soc-adav801.o | ||
166 | obj-$(CONFIG_SND_SOC_ADAV803) += snd-soc-adav803.o | ||
142 | obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o | 167 | obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o |
143 | obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o | 168 | obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o |
144 | obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o | 169 | obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o |
@@ -156,6 +181,8 @@ obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o | |||
156 | obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o | 181 | obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o |
157 | obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o | 182 | obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o |
158 | obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o | 183 | obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o |
184 | obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o | ||
185 | obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o | ||
159 | obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o | 186 | obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o |
160 | obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o | 187 | obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o |
161 | obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o | 188 | obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o |
@@ -179,6 +206,9 @@ obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o | |||
179 | obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o | 206 | obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o |
180 | obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o | 207 | obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o |
181 | obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o | 208 | obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o |
209 | obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o | ||
210 | obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o | ||
211 | obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o | ||
182 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o | 212 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o |
183 | obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o | 213 | obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o |
184 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o | 214 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o |
@@ -188,14 +218,19 @@ obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o | |||
188 | obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o | 218 | obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o |
189 | obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o | 219 | obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o |
190 | obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o | 220 | obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o |
221 | obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o | ||
222 | obj-$(CONFIG_SND_SOC_SSM2602_I2C) += snd-soc-ssm2602-i2c.o | ||
191 | obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o | 223 | obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o |
192 | obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o | 224 | obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o |
193 | obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o | 225 | obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o |
194 | obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o | 226 | obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o |
195 | obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o | 227 | obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o |
228 | obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o | ||
229 | obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o | ||
196 | obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o | 230 | obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o |
197 | obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o | 231 | obj-$(CONFIG_SND_SOC_TLV320AIC31XX) += snd-soc-tlv320aic31xx.o |
198 | obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o | 232 | obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o |
233 | obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o | ||
199 | obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o | 234 | obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o |
200 | obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o | 235 | obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o |
201 | obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o | 236 | obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o |
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 77f459868579..685998dd086e 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c | |||
@@ -40,8 +40,8 @@ struct ad1836_priv { | |||
40 | */ | 40 | */ |
41 | static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"}; | 41 | static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"}; |
42 | 42 | ||
43 | static const struct soc_enum ad1836_deemp_enum = | 43 | static SOC_ENUM_SINGLE_DECL(ad1836_deemp_enum, |
44 | SOC_ENUM_SINGLE(AD1836_DAC_CTRL1, 8, 4, ad1836_deemp); | 44 | AD1836_DAC_CTRL1, 8, ad1836_deemp); |
45 | 45 | ||
46 | #define AD1836_DAC_VOLUME(x) \ | 46 | #define AD1836_DAC_VOLUME(x) \ |
47 | SOC_DOUBLE_R("DAC" #x " Playback Volume", AD1836_DAC_L_VOL(x), \ | 47 | SOC_DOUBLE_R("DAC" #x " Playback Volume", AD1836_DAC_L_VOL(x), \ |
diff --git a/sound/soc/codecs/ad193x-i2c.c b/sound/soc/codecs/ad193x-i2c.c new file mode 100644 index 000000000000..df3a1a415825 --- /dev/null +++ b/sound/soc/codecs/ad193x-i2c.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * AD1936/AD1937 audio driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/regmap.h> | ||
12 | |||
13 | #include <sound/soc.h> | ||
14 | |||
15 | #include "ad193x.h" | ||
16 | |||
17 | static const struct i2c_device_id ad193x_id[] = { | ||
18 | { "ad1936", 0 }, | ||
19 | { "ad1937", 0 }, | ||
20 | { } | ||
21 | }; | ||
22 | MODULE_DEVICE_TABLE(i2c, ad193x_id); | ||
23 | |||
24 | static int ad193x_i2c_probe(struct i2c_client *client, | ||
25 | const struct i2c_device_id *id) | ||
26 | { | ||
27 | struct regmap_config config; | ||
28 | |||
29 | config = ad193x_regmap_config; | ||
30 | config.val_bits = 8; | ||
31 | config.reg_bits = 8; | ||
32 | |||
33 | return ad193x_probe(&client->dev, devm_regmap_init_i2c(client, &config)); | ||
34 | } | ||
35 | |||
36 | static int ad193x_i2c_remove(struct i2c_client *client) | ||
37 | { | ||
38 | snd_soc_unregister_codec(&client->dev); | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static struct i2c_driver ad193x_i2c_driver = { | ||
43 | .driver = { | ||
44 | .name = "ad193x", | ||
45 | }, | ||
46 | .probe = ad193x_i2c_probe, | ||
47 | .remove = ad193x_i2c_remove, | ||
48 | .id_table = ad193x_id, | ||
49 | }; | ||
50 | module_i2c_driver(ad193x_i2c_driver); | ||
51 | |||
52 | MODULE_DESCRIPTION("ASoC AD1936/AD1937 audio CODEC driver"); | ||
53 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | ||
54 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/ad193x-spi.c b/sound/soc/codecs/ad193x-spi.c new file mode 100644 index 000000000000..390cef9b9dc2 --- /dev/null +++ b/sound/soc/codecs/ad193x-spi.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * AD1938/AD1939 audio driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/spi/spi.h> | ||
11 | #include <linux/regmap.h> | ||
12 | |||
13 | #include <sound/soc.h> | ||
14 | |||
15 | #include "ad193x.h" | ||
16 | |||
17 | static int ad193x_spi_probe(struct spi_device *spi) | ||
18 | { | ||
19 | struct regmap_config config; | ||
20 | |||
21 | config = ad193x_regmap_config; | ||
22 | config.val_bits = 8; | ||
23 | config.reg_bits = 16; | ||
24 | config.read_flag_mask = 0x09; | ||
25 | config.write_flag_mask = 0x08; | ||
26 | |||
27 | return ad193x_probe(&spi->dev, devm_regmap_init_spi(spi, &config)); | ||
28 | } | ||
29 | |||
30 | static int ad193x_spi_remove(struct spi_device *spi) | ||
31 | { | ||
32 | snd_soc_unregister_codec(&spi->dev); | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static struct spi_driver ad193x_spi_driver = { | ||
37 | .driver = { | ||
38 | .name = "ad193x", | ||
39 | .owner = THIS_MODULE, | ||
40 | }, | ||
41 | .probe = ad193x_spi_probe, | ||
42 | .remove = ad193x_spi_remove, | ||
43 | }; | ||
44 | module_spi_driver(ad193x_spi_driver); | ||
45 | |||
46 | MODULE_DESCRIPTION("ASoC AD1938/AD1939 audio CODEC driver"); | ||
47 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | ||
48 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 5a42dca535b7..6844d0b2af68 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c | |||
@@ -6,12 +6,10 @@ | |||
6 | * Licensed under the GPL-2 or later. | 6 | * Licensed under the GPL-2 or later. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/module.h> | 9 | #include <linux/module.h> |
11 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
12 | #include <linux/device.h> | 11 | #include <linux/device.h> |
13 | #include <linux/i2c.h> | 12 | #include <linux/regmap.h> |
14 | #include <linux/spi/spi.h> | ||
15 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
16 | #include <sound/core.h> | 14 | #include <sound/core.h> |
17 | #include <sound/pcm.h> | 15 | #include <sound/pcm.h> |
@@ -19,6 +17,7 @@ | |||
19 | #include <sound/initval.h> | 17 | #include <sound/initval.h> |
20 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
21 | #include <sound/tlv.h> | 19 | #include <sound/tlv.h> |
20 | |||
22 | #include "ad193x.h" | 21 | #include "ad193x.h" |
23 | 22 | ||
24 | /* codec private data */ | 23 | /* codec private data */ |
@@ -32,8 +31,8 @@ struct ad193x_priv { | |||
32 | */ | 31 | */ |
33 | static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"}; | 32 | static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"}; |
34 | 33 | ||
35 | static const struct soc_enum ad193x_deemp_enum = | 34 | static SOC_ENUM_SINGLE_DECL(ad193x_deemp_enum, AD193X_DAC_CTRL2, 1, |
36 | SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp); | 35 | ad193x_deemp); |
37 | 36 | ||
38 | static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0); | 37 | static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0); |
39 | 38 | ||
@@ -320,17 +319,9 @@ static struct snd_soc_dai_driver ad193x_dai = { | |||
320 | .ops = &ad193x_dai_ops, | 319 | .ops = &ad193x_dai_ops, |
321 | }; | 320 | }; |
322 | 321 | ||
323 | static int ad193x_probe(struct snd_soc_codec *codec) | 322 | static int ad193x_codec_probe(struct snd_soc_codec *codec) |
324 | { | 323 | { |
325 | struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); | 324 | struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); |
326 | int ret; | ||
327 | |||
328 | codec->control_data = ad193x->regmap; | ||
329 | ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); | ||
330 | if (ret < 0) { | ||
331 | dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); | ||
332 | return ret; | ||
333 | } | ||
334 | 325 | ||
335 | /* default setting for ad193x */ | 326 | /* default setting for ad193x */ |
336 | 327 | ||
@@ -348,11 +339,11 @@ static int ad193x_probe(struct snd_soc_codec *codec) | |||
348 | regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */ | 339 | regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */ |
349 | regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04); | 340 | regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04); |
350 | 341 | ||
351 | return ret; | 342 | return 0; |
352 | } | 343 | } |
353 | 344 | ||
354 | static struct snd_soc_codec_driver soc_codec_dev_ad193x = { | 345 | static struct snd_soc_codec_driver soc_codec_dev_ad193x = { |
355 | .probe = ad193x_probe, | 346 | .probe = ad193x_codec_probe, |
356 | .controls = ad193x_snd_controls, | 347 | .controls = ad193x_snd_controls, |
357 | .num_controls = ARRAY_SIZE(ad193x_snd_controls), | 348 | .num_controls = ARRAY_SIZE(ad193x_snd_controls), |
358 | .dapm_widgets = ad193x_dapm_widgets, | 349 | .dapm_widgets = ad193x_dapm_widgets, |
@@ -366,140 +357,31 @@ static bool adau193x_reg_volatile(struct device *dev, unsigned int reg) | |||
366 | return false; | 357 | return false; |
367 | } | 358 | } |
368 | 359 | ||
369 | #if defined(CONFIG_SPI_MASTER) | 360 | const struct regmap_config ad193x_regmap_config = { |
370 | |||
371 | static const struct regmap_config ad193x_spi_regmap_config = { | ||
372 | .val_bits = 8, | ||
373 | .reg_bits = 16, | ||
374 | .read_flag_mask = 0x09, | ||
375 | .write_flag_mask = 0x08, | ||
376 | |||
377 | .max_register = AD193X_NUM_REGS - 1, | 361 | .max_register = AD193X_NUM_REGS - 1, |
378 | .volatile_reg = adau193x_reg_volatile, | 362 | .volatile_reg = adau193x_reg_volatile, |
379 | }; | 363 | }; |
364 | EXPORT_SYMBOL_GPL(ad193x_regmap_config); | ||
380 | 365 | ||
381 | static int ad193x_spi_probe(struct spi_device *spi) | 366 | int ad193x_probe(struct device *dev, struct regmap *regmap) |
382 | { | 367 | { |
383 | struct ad193x_priv *ad193x; | 368 | struct ad193x_priv *ad193x; |
384 | 369 | ||
385 | ad193x = devm_kzalloc(&spi->dev, sizeof(struct ad193x_priv), | 370 | if (IS_ERR(regmap)) |
386 | GFP_KERNEL); | 371 | return PTR_ERR(regmap); |
387 | if (ad193x == NULL) | ||
388 | return -ENOMEM; | ||
389 | |||
390 | ad193x->regmap = devm_regmap_init_spi(spi, &ad193x_spi_regmap_config); | ||
391 | if (IS_ERR(ad193x->regmap)) | ||
392 | return PTR_ERR(ad193x->regmap); | ||
393 | |||
394 | spi_set_drvdata(spi, ad193x); | ||
395 | |||
396 | return snd_soc_register_codec(&spi->dev, &soc_codec_dev_ad193x, | ||
397 | &ad193x_dai, 1); | ||
398 | } | ||
399 | |||
400 | static int ad193x_spi_remove(struct spi_device *spi) | ||
401 | { | ||
402 | snd_soc_unregister_codec(&spi->dev); | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static struct spi_driver ad193x_spi_driver = { | ||
407 | .driver = { | ||
408 | .name = "ad193x", | ||
409 | .owner = THIS_MODULE, | ||
410 | }, | ||
411 | .probe = ad193x_spi_probe, | ||
412 | .remove = ad193x_spi_remove, | ||
413 | }; | ||
414 | #endif | ||
415 | |||
416 | #if IS_ENABLED(CONFIG_I2C) | ||
417 | |||
418 | static const struct regmap_config ad193x_i2c_regmap_config = { | ||
419 | .val_bits = 8, | ||
420 | .reg_bits = 8, | ||
421 | |||
422 | .max_register = AD193X_NUM_REGS - 1, | ||
423 | .volatile_reg = adau193x_reg_volatile, | ||
424 | }; | ||
425 | |||
426 | static const struct i2c_device_id ad193x_id[] = { | ||
427 | { "ad1936", 0 }, | ||
428 | { "ad1937", 0 }, | ||
429 | { } | ||
430 | }; | ||
431 | MODULE_DEVICE_TABLE(i2c, ad193x_id); | ||
432 | |||
433 | static int ad193x_i2c_probe(struct i2c_client *client, | ||
434 | const struct i2c_device_id *id) | ||
435 | { | ||
436 | struct ad193x_priv *ad193x; | ||
437 | 372 | ||
438 | ad193x = devm_kzalloc(&client->dev, sizeof(struct ad193x_priv), | 373 | ad193x = devm_kzalloc(dev, sizeof(*ad193x), GFP_KERNEL); |
439 | GFP_KERNEL); | ||
440 | if (ad193x == NULL) | 374 | if (ad193x == NULL) |
441 | return -ENOMEM; | 375 | return -ENOMEM; |
442 | 376 | ||
443 | ad193x->regmap = devm_regmap_init_i2c(client, &ad193x_i2c_regmap_config); | 377 | ad193x->regmap = regmap; |
444 | if (IS_ERR(ad193x->regmap)) | ||
445 | return PTR_ERR(ad193x->regmap); | ||
446 | |||
447 | i2c_set_clientdata(client, ad193x); | ||
448 | |||
449 | return snd_soc_register_codec(&client->dev, &soc_codec_dev_ad193x, | ||
450 | &ad193x_dai, 1); | ||
451 | } | ||
452 | |||
453 | static int ad193x_i2c_remove(struct i2c_client *client) | ||
454 | { | ||
455 | snd_soc_unregister_codec(&client->dev); | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static struct i2c_driver ad193x_i2c_driver = { | ||
460 | .driver = { | ||
461 | .name = "ad193x", | ||
462 | }, | ||
463 | .probe = ad193x_i2c_probe, | ||
464 | .remove = ad193x_i2c_remove, | ||
465 | .id_table = ad193x_id, | ||
466 | }; | ||
467 | #endif | ||
468 | |||
469 | static int __init ad193x_modinit(void) | ||
470 | { | ||
471 | int ret; | ||
472 | |||
473 | #if IS_ENABLED(CONFIG_I2C) | ||
474 | ret = i2c_add_driver(&ad193x_i2c_driver); | ||
475 | if (ret != 0) { | ||
476 | printk(KERN_ERR "Failed to register AD193X I2C driver: %d\n", | ||
477 | ret); | ||
478 | } | ||
479 | #endif | ||
480 | |||
481 | #if defined(CONFIG_SPI_MASTER) | ||
482 | ret = spi_register_driver(&ad193x_spi_driver); | ||
483 | if (ret != 0) { | ||
484 | printk(KERN_ERR "Failed to register AD193X SPI driver: %d\n", | ||
485 | ret); | ||
486 | } | ||
487 | #endif | ||
488 | return ret; | ||
489 | } | ||
490 | module_init(ad193x_modinit); | ||
491 | 378 | ||
492 | static void __exit ad193x_modexit(void) | 379 | dev_set_drvdata(dev, ad193x); |
493 | { | ||
494 | #if defined(CONFIG_SPI_MASTER) | ||
495 | spi_unregister_driver(&ad193x_spi_driver); | ||
496 | #endif | ||
497 | 380 | ||
498 | #if IS_ENABLED(CONFIG_I2C) | 381 | return snd_soc_register_codec(dev, &soc_codec_dev_ad193x, |
499 | i2c_del_driver(&ad193x_i2c_driver); | 382 | &ad193x_dai, 1); |
500 | #endif | ||
501 | } | 383 | } |
502 | module_exit(ad193x_modexit); | 384 | EXPORT_SYMBOL_GPL(ad193x_probe); |
503 | 385 | ||
504 | MODULE_DESCRIPTION("ASoC ad193x driver"); | 386 | MODULE_DESCRIPTION("ASoC ad193x driver"); |
505 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | 387 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); |
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h index 473388049992..ab9a998f15be 100644 --- a/sound/soc/codecs/ad193x.h +++ b/sound/soc/codecs/ad193x.h | |||
@@ -9,6 +9,13 @@ | |||
9 | #ifndef __AD193X_H__ | 9 | #ifndef __AD193X_H__ |
10 | #define __AD193X_H__ | 10 | #define __AD193X_H__ |
11 | 11 | ||
12 | #include <linux/regmap.h> | ||
13 | |||
14 | struct device; | ||
15 | |||
16 | extern const struct regmap_config ad193x_regmap_config; | ||
17 | int ad193x_probe(struct device *dev, struct regmap *regmap); | ||
18 | |||
12 | #define AD193X_PLL_CLK_CTRL0 0x00 | 19 | #define AD193X_PLL_CLK_CTRL0 0x00 |
13 | #define AD193X_PLL_POWERDOWN 0x01 | 20 | #define AD193X_PLL_POWERDOWN 0x01 |
14 | #define AD193X_PLL_INPUT_MASK 0x6 | 21 | #define AD193X_PLL_INPUT_MASK 0x6 |
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 7257a8885f42..34d965a4a040 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
@@ -57,8 +57,8 @@ static const u16 ad1980_reg[] = { | |||
57 | static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line", | 57 | static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line", |
58 | "Stereo Mix", "Mono Mix", "Phone"}; | 58 | "Stereo Mix", "Mono Mix", "Phone"}; |
59 | 59 | ||
60 | static const struct soc_enum ad1980_cap_src = | 60 | static SOC_ENUM_DOUBLE_DECL(ad1980_cap_src, |
61 | SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 7, ad1980_rec_sel); | 61 | AC97_REC_SEL, 8, 0, ad1980_rec_sel); |
62 | 62 | ||
63 | static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = { | 63 | static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = { |
64 | SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1), | 64 | SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1), |
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index eb836ed5271f..877f5737bb6b 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c | |||
@@ -345,15 +345,15 @@ static const char *adau1373_fdsp_sel_text[] = { | |||
345 | "Channel 5", | 345 | "Channel 5", |
346 | }; | 346 | }; |
347 | 347 | ||
348 | static const SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum, | 348 | static SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum, |
349 | ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text); | 349 | ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text); |
350 | static const SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum, | 350 | static SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum, |
351 | ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text); | 351 | ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text); |
352 | static const SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum, | 352 | static SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum, |
353 | ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text); | 353 | ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text); |
354 | static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum, | 354 | static SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum, |
355 | ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text); | 355 | ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text); |
356 | static const SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum, | 356 | static SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum, |
357 | ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text); | 357 | ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text); |
358 | 358 | ||
359 | static const char *adau1373_hpf_cutoff_text[] = { | 359 | static const char *adau1373_hpf_cutoff_text[] = { |
@@ -362,7 +362,7 @@ static const char *adau1373_hpf_cutoff_text[] = { | |||
362 | "800Hz", | 362 | "800Hz", |
363 | }; | 363 | }; |
364 | 364 | ||
365 | static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum, | 365 | static SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum, |
366 | ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text); | 366 | ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text); |
367 | 367 | ||
368 | static const char *adau1373_bass_lpf_cutoff_text[] = { | 368 | static const char *adau1373_bass_lpf_cutoff_text[] = { |
@@ -388,14 +388,14 @@ static const unsigned int adau1373_bass_tlv[] = { | |||
388 | 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0), | 388 | 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0), |
389 | }; | 389 | }; |
390 | 390 | ||
391 | static const SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum, | 391 | static SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum, |
392 | ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text); | 392 | ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text); |
393 | 393 | ||
394 | static const SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum, | 394 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum, |
395 | ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text, | 395 | ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text, |
396 | adau1373_bass_clip_level_values); | 396 | adau1373_bass_clip_level_values); |
397 | 397 | ||
398 | static const SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum, | 398 | static SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum, |
399 | ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text); | 399 | ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text); |
400 | 400 | ||
401 | static const char *adau1373_3d_level_text[] = { | 401 | static const char *adau1373_3d_level_text[] = { |
@@ -409,9 +409,9 @@ static const char *adau1373_3d_cutoff_text[] = { | |||
409 | "0.16875 fs", "0.27083 fs" | 409 | "0.16875 fs", "0.27083 fs" |
410 | }; | 410 | }; |
411 | 411 | ||
412 | static const SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum, | 412 | static SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum, |
413 | ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text); | 413 | ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text); |
414 | static const SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum, | 414 | static SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum, |
415 | ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text); | 415 | ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text); |
416 | 416 | ||
417 | static const unsigned int adau1373_3d_tlv[] = { | 417 | static const unsigned int adau1373_3d_tlv[] = { |
@@ -427,11 +427,11 @@ static const char *adau1373_lr_mux_text[] = { | |||
427 | "Stereo", | 427 | "Stereo", |
428 | }; | 428 | }; |
429 | 429 | ||
430 | static const SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum, | 430 | static SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum, |
431 | ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text); | 431 | ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text); |
432 | static const SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum, | 432 | static SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum, |
433 | ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text); | 433 | ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text); |
434 | static const SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum, | 434 | static SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum, |
435 | ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text); | 435 | ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text); |
436 | 436 | ||
437 | static const struct snd_kcontrol_new adau1373_controls[] = { | 437 | static const struct snd_kcontrol_new adau1373_controls[] = { |
@@ -576,8 +576,8 @@ static const char *adau1373_decimator_text[] = { | |||
576 | "DMIC1", | 576 | "DMIC1", |
577 | }; | 577 | }; |
578 | 578 | ||
579 | static const struct soc_enum adau1373_decimator_enum = | 579 | static SOC_ENUM_SINGLE_VIRT_DECL(adau1373_decimator_enum, |
580 | SOC_ENUM_SINGLE(0, 0, 2, adau1373_decimator_text); | 580 | adau1373_decimator_text); |
581 | 581 | ||
582 | static const struct snd_kcontrol_new adau1373_decimator_mux = | 582 | static const struct snd_kcontrol_new adau1373_decimator_mux = |
583 | SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum); | 583 | SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum); |
@@ -1376,15 +1376,8 @@ static int adau1373_probe(struct snd_soc_codec *codec) | |||
1376 | struct adau1373_platform_data *pdata = codec->dev->platform_data; | 1376 | struct adau1373_platform_data *pdata = codec->dev->platform_data; |
1377 | bool lineout_differential = false; | 1377 | bool lineout_differential = false; |
1378 | unsigned int val; | 1378 | unsigned int val; |
1379 | int ret; | ||
1380 | int i; | 1379 | int i; |
1381 | 1380 | ||
1382 | ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); | ||
1383 | if (ret) { | ||
1384 | dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); | ||
1385 | return ret; | ||
1386 | } | ||
1387 | |||
1388 | if (pdata) { | 1381 | if (pdata) { |
1389 | if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting)) | 1382 | if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting)) |
1390 | return -EINVAL; | 1383 | return -EINVAL; |
diff --git a/sound/soc/codecs/adau1977-i2c.c b/sound/soc/codecs/adau1977-i2c.c new file mode 100644 index 000000000000..9700e8c838c9 --- /dev/null +++ b/sound/soc/codecs/adau1977-i2c.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * ADAU1977/ADAU1978/ADAU1979 driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
6 | * | ||
7 | * Licensed under the GPL-2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/mod_devicetable.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/regmap.h> | ||
14 | #include <sound/soc.h> | ||
15 | |||
16 | #include "adau1977.h" | ||
17 | |||
18 | static int adau1977_i2c_probe(struct i2c_client *client, | ||
19 | const struct i2c_device_id *id) | ||
20 | { | ||
21 | struct regmap_config config; | ||
22 | |||
23 | config = adau1977_regmap_config; | ||
24 | config.val_bits = 8; | ||
25 | config.reg_bits = 8; | ||
26 | |||
27 | return adau1977_probe(&client->dev, | ||
28 | devm_regmap_init_i2c(client, &config), | ||
29 | id->driver_data, NULL); | ||
30 | } | ||
31 | |||
32 | static int adau1977_i2c_remove(struct i2c_client *client) | ||
33 | { | ||
34 | snd_soc_unregister_codec(&client->dev); | ||
35 | return 0; | ||
36 | } | ||
37 | |||
38 | static const struct i2c_device_id adau1977_i2c_ids[] = { | ||
39 | { "adau1977", ADAU1977 }, | ||
40 | { "adau1978", ADAU1978 }, | ||
41 | { "adau1979", ADAU1978 }, | ||
42 | { } | ||
43 | }; | ||
44 | MODULE_DEVICE_TABLE(i2c, adau1977_i2c_ids); | ||
45 | |||
46 | static struct i2c_driver adau1977_i2c_driver = { | ||
47 | .driver = { | ||
48 | .name = "adau1977", | ||
49 | .owner = THIS_MODULE, | ||
50 | }, | ||
51 | .probe = adau1977_i2c_probe, | ||
52 | .remove = adau1977_i2c_remove, | ||
53 | .id_table = adau1977_i2c_ids, | ||
54 | }; | ||
55 | module_i2c_driver(adau1977_i2c_driver); | ||
56 | |||
57 | MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver"); | ||
58 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
59 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/adau1977-spi.c b/sound/soc/codecs/adau1977-spi.c new file mode 100644 index 000000000000..b05cf5da3a94 --- /dev/null +++ b/sound/soc/codecs/adau1977-spi.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * ADAU1977/ADAU1978/ADAU1979 driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
6 | * | ||
7 | * Licensed under the GPL-2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/mod_devicetable.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/regmap.h> | ||
13 | #include <linux/spi/spi.h> | ||
14 | #include <sound/soc.h> | ||
15 | |||
16 | #include "adau1977.h" | ||
17 | |||
18 | static void adau1977_spi_switch_mode(struct device *dev) | ||
19 | { | ||
20 | struct spi_device *spi = to_spi_device(dev); | ||
21 | |||
22 | /* | ||
23 | * To get the device into SPI mode CLATCH has to be pulled low three | ||
24 | * times. Do this by issuing three dummy reads. | ||
25 | */ | ||
26 | spi_w8r8(spi, 0x00); | ||
27 | spi_w8r8(spi, 0x00); | ||
28 | spi_w8r8(spi, 0x00); | ||
29 | } | ||
30 | |||
31 | static int adau1977_spi_probe(struct spi_device *spi) | ||
32 | { | ||
33 | const struct spi_device_id *id = spi_get_device_id(spi); | ||
34 | struct regmap_config config; | ||
35 | |||
36 | if (!id) | ||
37 | return -EINVAL; | ||
38 | |||
39 | config = adau1977_regmap_config; | ||
40 | config.val_bits = 8; | ||
41 | config.reg_bits = 16; | ||
42 | config.read_flag_mask = 0x1; | ||
43 | |||
44 | return adau1977_probe(&spi->dev, | ||
45 | devm_regmap_init_spi(spi, &config), | ||
46 | id->driver_data, adau1977_spi_switch_mode); | ||
47 | } | ||
48 | |||
49 | static int adau1977_spi_remove(struct spi_device *spi) | ||
50 | { | ||
51 | snd_soc_unregister_codec(&spi->dev); | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static const struct spi_device_id adau1977_spi_ids[] = { | ||
56 | { "adau1977", ADAU1977 }, | ||
57 | { "adau1978", ADAU1978 }, | ||
58 | { "adau1979", ADAU1978 }, | ||
59 | { } | ||
60 | }; | ||
61 | MODULE_DEVICE_TABLE(spi, adau1977_spi_ids); | ||
62 | |||
63 | static struct spi_driver adau1977_spi_driver = { | ||
64 | .driver = { | ||
65 | .name = "adau1977", | ||
66 | .owner = THIS_MODULE, | ||
67 | }, | ||
68 | .probe = adau1977_spi_probe, | ||
69 | .remove = adau1977_spi_remove, | ||
70 | .id_table = adau1977_spi_ids, | ||
71 | }; | ||
72 | module_spi_driver(adau1977_spi_driver); | ||
73 | |||
74 | MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver"); | ||
75 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
76 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c new file mode 100644 index 000000000000..fd55da7cb9d4 --- /dev/null +++ b/sound/soc/codecs/adau1977.c | |||
@@ -0,0 +1,1018 @@ | |||
1 | /* | ||
2 | * ADAU1977/ADAU1978/ADAU1979 driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
6 | * | ||
7 | * Licensed under the GPL-2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/delay.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/gpio/consumer.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_data/adau1977.h> | ||
17 | #include <linux/regmap.h> | ||
18 | #include <linux/regulator/consumer.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #include <sound/core.h> | ||
22 | #include <sound/initval.h> | ||
23 | #include <sound/pcm.h> | ||
24 | #include <sound/pcm_params.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include <sound/tlv.h> | ||
27 | |||
28 | #include "adau1977.h" | ||
29 | |||
30 | #define ADAU1977_REG_POWER 0x00 | ||
31 | #define ADAU1977_REG_PLL 0x01 | ||
32 | #define ADAU1977_REG_BOOST 0x02 | ||
33 | #define ADAU1977_REG_MICBIAS 0x03 | ||
34 | #define ADAU1977_REG_BLOCK_POWER_SAI 0x04 | ||
35 | #define ADAU1977_REG_SAI_CTRL0 0x05 | ||
36 | #define ADAU1977_REG_SAI_CTRL1 0x06 | ||
37 | #define ADAU1977_REG_CMAP12 0x07 | ||
38 | #define ADAU1977_REG_CMAP34 0x08 | ||
39 | #define ADAU1977_REG_SAI_OVERTEMP 0x09 | ||
40 | #define ADAU1977_REG_POST_ADC_GAIN(x) (0x0a + (x)) | ||
41 | #define ADAU1977_REG_MISC_CONTROL 0x0e | ||
42 | #define ADAU1977_REG_DIAG_CONTROL 0x10 | ||
43 | #define ADAU1977_REG_STATUS(x) (0x11 + (x)) | ||
44 | #define ADAU1977_REG_DIAG_IRQ1 0x15 | ||
45 | #define ADAU1977_REG_DIAG_IRQ2 0x16 | ||
46 | #define ADAU1977_REG_ADJUST1 0x17 | ||
47 | #define ADAU1977_REG_ADJUST2 0x18 | ||
48 | #define ADAU1977_REG_ADC_CLIP 0x19 | ||
49 | #define ADAU1977_REG_DC_HPF_CAL 0x1a | ||
50 | |||
51 | #define ADAU1977_POWER_RESET BIT(7) | ||
52 | #define ADAU1977_POWER_PWUP BIT(0) | ||
53 | |||
54 | #define ADAU1977_PLL_CLK_S BIT(4) | ||
55 | #define ADAU1977_PLL_MCS_MASK 0x7 | ||
56 | |||
57 | #define ADAU1977_MICBIAS_MB_VOLTS_MASK 0xf0 | ||
58 | #define ADAU1977_MICBIAS_MB_VOLTS_OFFSET 4 | ||
59 | |||
60 | #define ADAU1977_BLOCK_POWER_SAI_LR_POL BIT(7) | ||
61 | #define ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE BIT(6) | ||
62 | #define ADAU1977_BLOCK_POWER_SAI_LDO_EN BIT(5) | ||
63 | |||
64 | #define ADAU1977_SAI_CTRL0_FMT_MASK (0x3 << 6) | ||
65 | #define ADAU1977_SAI_CTRL0_FMT_I2S (0x0 << 6) | ||
66 | #define ADAU1977_SAI_CTRL0_FMT_LJ (0x1 << 6) | ||
67 | #define ADAU1977_SAI_CTRL0_FMT_RJ_24BIT (0x2 << 6) | ||
68 | #define ADAU1977_SAI_CTRL0_FMT_RJ_16BIT (0x3 << 6) | ||
69 | |||
70 | #define ADAU1977_SAI_CTRL0_SAI_MASK (0x7 << 3) | ||
71 | #define ADAU1977_SAI_CTRL0_SAI_I2S (0x0 << 3) | ||
72 | #define ADAU1977_SAI_CTRL0_SAI_TDM_2 (0x1 << 3) | ||
73 | #define ADAU1977_SAI_CTRL0_SAI_TDM_4 (0x2 << 3) | ||
74 | #define ADAU1977_SAI_CTRL0_SAI_TDM_8 (0x3 << 3) | ||
75 | #define ADAU1977_SAI_CTRL0_SAI_TDM_16 (0x4 << 3) | ||
76 | |||
77 | #define ADAU1977_SAI_CTRL0_FS_MASK (0x7) | ||
78 | #define ADAU1977_SAI_CTRL0_FS_8000_12000 (0x0) | ||
79 | #define ADAU1977_SAI_CTRL0_FS_16000_24000 (0x1) | ||
80 | #define ADAU1977_SAI_CTRL0_FS_32000_48000 (0x2) | ||
81 | #define ADAU1977_SAI_CTRL0_FS_64000_96000 (0x3) | ||
82 | #define ADAU1977_SAI_CTRL0_FS_128000_192000 (0x4) | ||
83 | |||
84 | #define ADAU1977_SAI_CTRL1_SLOT_WIDTH_MASK (0x3 << 5) | ||
85 | #define ADAU1977_SAI_CTRL1_SLOT_WIDTH_32 (0x0 << 5) | ||
86 | #define ADAU1977_SAI_CTRL1_SLOT_WIDTH_24 (0x1 << 5) | ||
87 | #define ADAU1977_SAI_CTRL1_SLOT_WIDTH_16 (0x2 << 5) | ||
88 | #define ADAU1977_SAI_CTRL1_DATA_WIDTH_MASK (0x1 << 4) | ||
89 | #define ADAU1977_SAI_CTRL1_DATA_WIDTH_16BIT (0x1 << 4) | ||
90 | #define ADAU1977_SAI_CTRL1_DATA_WIDTH_24BIT (0x0 << 4) | ||
91 | #define ADAU1977_SAI_CTRL1_LRCLK_PULSE BIT(3) | ||
92 | #define ADAU1977_SAI_CTRL1_MSB BIT(2) | ||
93 | #define ADAU1977_SAI_CTRL1_BCLKRATE_16 (0x1 << 1) | ||
94 | #define ADAU1977_SAI_CTRL1_BCLKRATE_32 (0x0 << 1) | ||
95 | #define ADAU1977_SAI_CTRL1_BCLKRATE_MASK (0x1 << 1) | ||
96 | #define ADAU1977_SAI_CTRL1_MASTER BIT(0) | ||
97 | |||
98 | #define ADAU1977_SAI_OVERTEMP_DRV_C(x) BIT(4 + (x)) | ||
99 | #define ADAU1977_SAI_OVERTEMP_DRV_HIZ BIT(3) | ||
100 | |||
101 | #define ADAU1977_MISC_CONTROL_SUM_MODE_MASK (0x3 << 6) | ||
102 | #define ADAU1977_MISC_CONTROL_SUM_MODE_1CH (0x2 << 6) | ||
103 | #define ADAU1977_MISC_CONTROL_SUM_MODE_2CH (0x1 << 6) | ||
104 | #define ADAU1977_MISC_CONTROL_SUM_MODE_4CH (0x0 << 6) | ||
105 | #define ADAU1977_MISC_CONTROL_MMUTE BIT(4) | ||
106 | #define ADAU1977_MISC_CONTROL_DC_CAL BIT(0) | ||
107 | |||
108 | #define ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET 4 | ||
109 | #define ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET 0 | ||
110 | |||
111 | struct adau1977 { | ||
112 | struct regmap *regmap; | ||
113 | bool right_j; | ||
114 | unsigned int sysclk; | ||
115 | enum adau1977_sysclk_src sysclk_src; | ||
116 | struct gpio_desc *reset_gpio; | ||
117 | enum adau1977_type type; | ||
118 | |||
119 | struct regulator *avdd_reg; | ||
120 | struct regulator *dvdd_reg; | ||
121 | |||
122 | struct snd_pcm_hw_constraint_list constraints; | ||
123 | |||
124 | struct device *dev; | ||
125 | void (*switch_mode)(struct device *dev); | ||
126 | |||
127 | unsigned int max_master_fs; | ||
128 | unsigned int slot_width; | ||
129 | bool enabled; | ||
130 | bool master; | ||
131 | }; | ||
132 | |||
133 | static const struct reg_default adau1977_reg_defaults[] = { | ||
134 | { 0x00, 0x00 }, | ||
135 | { 0x01, 0x41 }, | ||
136 | { 0x02, 0x4a }, | ||
137 | { 0x03, 0x7d }, | ||
138 | { 0x04, 0x3d }, | ||
139 | { 0x05, 0x02 }, | ||
140 | { 0x06, 0x00 }, | ||
141 | { 0x07, 0x10 }, | ||
142 | { 0x08, 0x32 }, | ||
143 | { 0x09, 0xf0 }, | ||
144 | { 0x0a, 0xa0 }, | ||
145 | { 0x0b, 0xa0 }, | ||
146 | { 0x0c, 0xa0 }, | ||
147 | { 0x0d, 0xa0 }, | ||
148 | { 0x0e, 0x02 }, | ||
149 | { 0x10, 0x0f }, | ||
150 | { 0x15, 0x20 }, | ||
151 | { 0x16, 0x00 }, | ||
152 | { 0x17, 0x00 }, | ||
153 | { 0x18, 0x00 }, | ||
154 | { 0x1a, 0x00 }, | ||
155 | }; | ||
156 | |||
157 | static const DECLARE_TLV_DB_MINMAX_MUTE(adau1977_adc_gain, -3562, 6000); | ||
158 | |||
159 | static const struct snd_soc_dapm_widget adau1977_micbias_dapm_widgets[] = { | ||
160 | SND_SOC_DAPM_SUPPLY("MICBIAS", ADAU1977_REG_MICBIAS, | ||
161 | 3, 0, NULL, 0) | ||
162 | }; | ||
163 | |||
164 | static const struct snd_soc_dapm_widget adau1977_dapm_widgets[] = { | ||
165 | SND_SOC_DAPM_SUPPLY("Vref", ADAU1977_REG_BLOCK_POWER_SAI, | ||
166 | 4, 0, NULL, 0), | ||
167 | |||
168 | SND_SOC_DAPM_ADC("ADC1", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 0, 0), | ||
169 | SND_SOC_DAPM_ADC("ADC2", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 1, 0), | ||
170 | SND_SOC_DAPM_ADC("ADC3", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 2, 0), | ||
171 | SND_SOC_DAPM_ADC("ADC4", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 3, 0), | ||
172 | |||
173 | SND_SOC_DAPM_INPUT("AIN1"), | ||
174 | SND_SOC_DAPM_INPUT("AIN2"), | ||
175 | SND_SOC_DAPM_INPUT("AIN3"), | ||
176 | SND_SOC_DAPM_INPUT("AIN4"), | ||
177 | |||
178 | SND_SOC_DAPM_OUTPUT("VREF"), | ||
179 | }; | ||
180 | |||
181 | static const struct snd_soc_dapm_route adau1977_dapm_routes[] = { | ||
182 | { "ADC1", NULL, "AIN1" }, | ||
183 | { "ADC2", NULL, "AIN2" }, | ||
184 | { "ADC3", NULL, "AIN3" }, | ||
185 | { "ADC4", NULL, "AIN4" }, | ||
186 | |||
187 | { "ADC1", NULL, "Vref" }, | ||
188 | { "ADC2", NULL, "Vref" }, | ||
189 | { "ADC3", NULL, "Vref" }, | ||
190 | { "ADC4", NULL, "Vref" }, | ||
191 | |||
192 | { "VREF", NULL, "Vref" }, | ||
193 | }; | ||
194 | |||
195 | #define ADAU1977_VOLUME(x) \ | ||
196 | SOC_SINGLE_TLV("ADC" #x " Capture Volume", \ | ||
197 | ADAU1977_REG_POST_ADC_GAIN((x) - 1), \ | ||
198 | 0, 255, 1, adau1977_adc_gain) | ||
199 | |||
200 | #define ADAU1977_HPF_SWITCH(x) \ | ||
201 | SOC_SINGLE("ADC" #x " Highpass-Filter Capture Switch", \ | ||
202 | ADAU1977_REG_DC_HPF_CAL, (x) - 1, 1, 0) | ||
203 | |||
204 | #define ADAU1977_DC_SUB_SWITCH(x) \ | ||
205 | SOC_SINGLE("ADC" #x " DC Substraction Capture Switch", \ | ||
206 | ADAU1977_REG_DC_HPF_CAL, (x) + 3, 1, 0) | ||
207 | |||
208 | static const struct snd_kcontrol_new adau1977_snd_controls[] = { | ||
209 | ADAU1977_VOLUME(1), | ||
210 | ADAU1977_VOLUME(2), | ||
211 | ADAU1977_VOLUME(3), | ||
212 | ADAU1977_VOLUME(4), | ||
213 | |||
214 | ADAU1977_HPF_SWITCH(1), | ||
215 | ADAU1977_HPF_SWITCH(2), | ||
216 | ADAU1977_HPF_SWITCH(3), | ||
217 | ADAU1977_HPF_SWITCH(4), | ||
218 | |||
219 | ADAU1977_DC_SUB_SWITCH(1), | ||
220 | ADAU1977_DC_SUB_SWITCH(2), | ||
221 | ADAU1977_DC_SUB_SWITCH(3), | ||
222 | ADAU1977_DC_SUB_SWITCH(4), | ||
223 | }; | ||
224 | |||
225 | static int adau1977_reset(struct adau1977 *adau1977) | ||
226 | { | ||
227 | int ret; | ||
228 | |||
229 | /* | ||
230 | * The reset bit is obviously volatile, but we need to be able to cache | ||
231 | * the other bits in the register, so we can't just mark the whole | ||
232 | * register as volatile. Since this is the only place where we'll ever | ||
233 | * touch the reset bit just bypass the cache for this operation. | ||
234 | */ | ||
235 | regcache_cache_bypass(adau1977->regmap, true); | ||
236 | ret = regmap_write(adau1977->regmap, ADAU1977_REG_POWER, | ||
237 | ADAU1977_POWER_RESET); | ||
238 | regcache_cache_bypass(adau1977->regmap, false); | ||
239 | if (ret) | ||
240 | return ret; | ||
241 | |||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Returns the appropriate setting for ths FS field in the CTRL0 register | ||
247 | * depending on the rate. | ||
248 | */ | ||
249 | static int adau1977_lookup_fs(unsigned int rate) | ||
250 | { | ||
251 | if (rate >= 8000 && rate <= 12000) | ||
252 | return ADAU1977_SAI_CTRL0_FS_8000_12000; | ||
253 | else if (rate >= 16000 && rate <= 24000) | ||
254 | return ADAU1977_SAI_CTRL0_FS_16000_24000; | ||
255 | else if (rate >= 32000 && rate <= 48000) | ||
256 | return ADAU1977_SAI_CTRL0_FS_32000_48000; | ||
257 | else if (rate >= 64000 && rate <= 96000) | ||
258 | return ADAU1977_SAI_CTRL0_FS_64000_96000; | ||
259 | else if (rate >= 128000 && rate <= 192000) | ||
260 | return ADAU1977_SAI_CTRL0_FS_128000_192000; | ||
261 | else | ||
262 | return -EINVAL; | ||
263 | } | ||
264 | |||
265 | static int adau1977_lookup_mcs(struct adau1977 *adau1977, unsigned int rate, | ||
266 | unsigned int fs) | ||
267 | { | ||
268 | unsigned int mcs; | ||
269 | |||
270 | /* | ||
271 | * rate = sysclk / (512 * mcs_lut[mcs]) * 2**fs | ||
272 | * => mcs_lut[mcs] = sysclk / (512 * rate) * 2**fs | ||
273 | * => mcs_lut[mcs] = sysclk / ((512 / 2**fs) * rate) | ||
274 | */ | ||
275 | |||
276 | rate *= 512 >> fs; | ||
277 | |||
278 | if (adau1977->sysclk % rate != 0) | ||
279 | return -EINVAL; | ||
280 | |||
281 | mcs = adau1977->sysclk / rate; | ||
282 | |||
283 | /* The factors configured by MCS are 1, 2, 3, 4, 6 */ | ||
284 | if (mcs < 1 || mcs > 6 || mcs == 5) | ||
285 | return -EINVAL; | ||
286 | |||
287 | mcs = mcs - 1; | ||
288 | if (mcs == 5) | ||
289 | mcs = 4; | ||
290 | |||
291 | return mcs; | ||
292 | } | ||
293 | |||
294 | static int adau1977_hw_params(struct snd_pcm_substream *substream, | ||
295 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
296 | { | ||
297 | struct snd_soc_codec *codec = dai->codec; | ||
298 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec); | ||
299 | unsigned int rate = params_rate(params); | ||
300 | unsigned int slot_width; | ||
301 | unsigned int ctrl0, ctrl0_mask; | ||
302 | unsigned int ctrl1; | ||
303 | int mcs, fs; | ||
304 | int ret; | ||
305 | |||
306 | fs = adau1977_lookup_fs(rate); | ||
307 | if (fs < 0) | ||
308 | return fs; | ||
309 | |||
310 | if (adau1977->sysclk_src == ADAU1977_SYSCLK_SRC_MCLK) { | ||
311 | mcs = adau1977_lookup_mcs(adau1977, rate, fs); | ||
312 | if (mcs < 0) | ||
313 | return mcs; | ||
314 | } else { | ||
315 | mcs = 0; | ||
316 | } | ||
317 | |||
318 | ctrl0_mask = ADAU1977_SAI_CTRL0_FS_MASK; | ||
319 | ctrl0 = fs; | ||
320 | |||
321 | if (adau1977->right_j) { | ||
322 | switch (params_width(params)) { | ||
323 | case 16: | ||
324 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_16BIT; | ||
325 | break; | ||
326 | case 24: | ||
327 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT; | ||
328 | break; | ||
329 | default: | ||
330 | return -EINVAL; | ||
331 | } | ||
332 | ctrl0_mask |= ADAU1977_SAI_CTRL0_FMT_MASK; | ||
333 | } | ||
334 | |||
335 | if (adau1977->master) { | ||
336 | switch (params_width(params)) { | ||
337 | case 16: | ||
338 | ctrl1 = ADAU1977_SAI_CTRL1_DATA_WIDTH_16BIT; | ||
339 | slot_width = 16; | ||
340 | break; | ||
341 | case 24: | ||
342 | case 32: | ||
343 | ctrl1 = ADAU1977_SAI_CTRL1_DATA_WIDTH_24BIT; | ||
344 | slot_width = 32; | ||
345 | break; | ||
346 | default: | ||
347 | return -EINVAL; | ||
348 | } | ||
349 | |||
350 | /* In TDM mode there is a fixed slot width */ | ||
351 | if (adau1977->slot_width) | ||
352 | slot_width = adau1977->slot_width; | ||
353 | |||
354 | if (slot_width == 16) | ||
355 | ctrl1 |= ADAU1977_SAI_CTRL1_BCLKRATE_16; | ||
356 | else | ||
357 | ctrl1 |= ADAU1977_SAI_CTRL1_BCLKRATE_32; | ||
358 | |||
359 | ret = regmap_update_bits(adau1977->regmap, | ||
360 | ADAU1977_REG_SAI_CTRL1, | ||
361 | ADAU1977_SAI_CTRL1_DATA_WIDTH_MASK | | ||
362 | ADAU1977_SAI_CTRL1_BCLKRATE_MASK, | ||
363 | ctrl1); | ||
364 | if (ret < 0) | ||
365 | return ret; | ||
366 | } | ||
367 | |||
368 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0, | ||
369 | ctrl0_mask, ctrl0); | ||
370 | if (ret < 0) | ||
371 | return ret; | ||
372 | |||
373 | return regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL, | ||
374 | ADAU1977_PLL_MCS_MASK, mcs); | ||
375 | } | ||
376 | |||
377 | static int adau1977_power_disable(struct adau1977 *adau1977) | ||
378 | { | ||
379 | int ret = 0; | ||
380 | |||
381 | if (!adau1977->enabled) | ||
382 | return 0; | ||
383 | |||
384 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER, | ||
385 | ADAU1977_POWER_PWUP, 0); | ||
386 | if (ret) | ||
387 | return ret; | ||
388 | |||
389 | regcache_mark_dirty(adau1977->regmap); | ||
390 | |||
391 | if (adau1977->reset_gpio) | ||
392 | gpiod_set_value_cansleep(adau1977->reset_gpio, 0); | ||
393 | |||
394 | regcache_cache_only(adau1977->regmap, true); | ||
395 | |||
396 | regulator_disable(adau1977->avdd_reg); | ||
397 | if (adau1977->dvdd_reg) | ||
398 | regulator_disable(adau1977->dvdd_reg); | ||
399 | |||
400 | adau1977->enabled = false; | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static int adau1977_power_enable(struct adau1977 *adau1977) | ||
406 | { | ||
407 | unsigned int val; | ||
408 | int ret = 0; | ||
409 | |||
410 | if (adau1977->enabled) | ||
411 | return 0; | ||
412 | |||
413 | ret = regulator_enable(adau1977->avdd_reg); | ||
414 | if (ret) | ||
415 | return ret; | ||
416 | |||
417 | if (adau1977->dvdd_reg) { | ||
418 | ret = regulator_enable(adau1977->dvdd_reg); | ||
419 | if (ret) | ||
420 | goto err_disable_avdd; | ||
421 | } | ||
422 | |||
423 | if (adau1977->reset_gpio) | ||
424 | gpiod_set_value_cansleep(adau1977->reset_gpio, 1); | ||
425 | |||
426 | regcache_cache_only(adau1977->regmap, false); | ||
427 | |||
428 | if (adau1977->switch_mode) | ||
429 | adau1977->switch_mode(adau1977->dev); | ||
430 | |||
431 | ret = adau1977_reset(adau1977); | ||
432 | if (ret) | ||
433 | goto err_disable_dvdd; | ||
434 | |||
435 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER, | ||
436 | ADAU1977_POWER_PWUP, ADAU1977_POWER_PWUP); | ||
437 | if (ret) | ||
438 | goto err_disable_dvdd; | ||
439 | |||
440 | ret = regcache_sync(adau1977->regmap); | ||
441 | if (ret) | ||
442 | goto err_disable_dvdd; | ||
443 | |||
444 | /* | ||
445 | * The PLL register is not affected by the software reset. It is | ||
446 | * possible that the value of the register was changed to the | ||
447 | * default value while we were in cache only mode. In this case | ||
448 | * regcache_sync will skip over it and we have to manually sync | ||
449 | * it. | ||
450 | */ | ||
451 | ret = regmap_read(adau1977->regmap, ADAU1977_REG_PLL, &val); | ||
452 | if (ret) | ||
453 | goto err_disable_dvdd; | ||
454 | |||
455 | if (val == 0x41) { | ||
456 | regcache_cache_bypass(adau1977->regmap, true); | ||
457 | ret = regmap_write(adau1977->regmap, ADAU1977_REG_PLL, | ||
458 | 0x41); | ||
459 | if (ret) | ||
460 | goto err_disable_dvdd; | ||
461 | regcache_cache_bypass(adau1977->regmap, false); | ||
462 | } | ||
463 | |||
464 | adau1977->enabled = true; | ||
465 | |||
466 | return ret; | ||
467 | |||
468 | err_disable_dvdd: | ||
469 | if (adau1977->dvdd_reg) | ||
470 | regulator_disable(adau1977->dvdd_reg); | ||
471 | err_disable_avdd: | ||
472 | regulator_disable(adau1977->avdd_reg); | ||
473 | return ret; | ||
474 | } | ||
475 | |||
476 | static int adau1977_set_bias_level(struct snd_soc_codec *codec, | ||
477 | enum snd_soc_bias_level level) | ||
478 | { | ||
479 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec); | ||
480 | int ret = 0; | ||
481 | |||
482 | switch (level) { | ||
483 | case SND_SOC_BIAS_ON: | ||
484 | break; | ||
485 | case SND_SOC_BIAS_PREPARE: | ||
486 | break; | ||
487 | case SND_SOC_BIAS_STANDBY: | ||
488 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) | ||
489 | ret = adau1977_power_enable(adau1977); | ||
490 | break; | ||
491 | case SND_SOC_BIAS_OFF: | ||
492 | ret = adau1977_power_disable(adau1977); | ||
493 | break; | ||
494 | } | ||
495 | |||
496 | if (ret) | ||
497 | return ret; | ||
498 | |||
499 | codec->dapm.bias_level = level; | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | ||
505 | unsigned int rx_mask, int slots, int width) | ||
506 | { | ||
507 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec); | ||
508 | unsigned int ctrl0, ctrl1, drv; | ||
509 | unsigned int slot[4]; | ||
510 | unsigned int i; | ||
511 | int ret; | ||
512 | |||
513 | if (slots == 0) { | ||
514 | /* 0 = No fixed slot width */ | ||
515 | adau1977->slot_width = 0; | ||
516 | adau1977->max_master_fs = 192000; | ||
517 | return regmap_update_bits(adau1977->regmap, | ||
518 | ADAU1977_REG_SAI_CTRL0, ADAU1977_SAI_CTRL0_SAI_MASK, | ||
519 | ADAU1977_SAI_CTRL0_SAI_I2S); | ||
520 | } | ||
521 | |||
522 | if (rx_mask == 0 || tx_mask != 0) | ||
523 | return -EINVAL; | ||
524 | |||
525 | drv = 0; | ||
526 | for (i = 0; i < 4; i++) { | ||
527 | slot[i] = __ffs(rx_mask); | ||
528 | drv |= ADAU1977_SAI_OVERTEMP_DRV_C(i); | ||
529 | rx_mask &= ~(1 << slot[i]); | ||
530 | if (slot[i] >= slots) | ||
531 | return -EINVAL; | ||
532 | if (rx_mask == 0) | ||
533 | break; | ||
534 | } | ||
535 | |||
536 | if (rx_mask != 0) | ||
537 | return -EINVAL; | ||
538 | |||
539 | switch (width) { | ||
540 | case 16: | ||
541 | ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_16; | ||
542 | break; | ||
543 | case 24: | ||
544 | /* We can only generate 16 bit or 32 bit wide slots */ | ||
545 | if (adau1977->master) | ||
546 | return -EINVAL; | ||
547 | ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_24; | ||
548 | break; | ||
549 | case 32: | ||
550 | ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_32; | ||
551 | break; | ||
552 | default: | ||
553 | return -EINVAL; | ||
554 | } | ||
555 | |||
556 | switch (slots) { | ||
557 | case 2: | ||
558 | ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_2; | ||
559 | break; | ||
560 | case 4: | ||
561 | ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_4; | ||
562 | break; | ||
563 | case 8: | ||
564 | ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_8; | ||
565 | break; | ||
566 | case 16: | ||
567 | ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_16; | ||
568 | break; | ||
569 | default: | ||
570 | return -EINVAL; | ||
571 | } | ||
572 | |||
573 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP, | ||
574 | ADAU1977_SAI_OVERTEMP_DRV_C(0) | | ||
575 | ADAU1977_SAI_OVERTEMP_DRV_C(1) | | ||
576 | ADAU1977_SAI_OVERTEMP_DRV_C(2) | | ||
577 | ADAU1977_SAI_OVERTEMP_DRV_C(3), drv); | ||
578 | if (ret) | ||
579 | return ret; | ||
580 | |||
581 | ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP12, | ||
582 | (slot[1] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) | | ||
583 | (slot[0] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET)); | ||
584 | if (ret) | ||
585 | return ret; | ||
586 | |||
587 | ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP34, | ||
588 | (slot[3] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) | | ||
589 | (slot[2] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET)); | ||
590 | if (ret) | ||
591 | return ret; | ||
592 | |||
593 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0, | ||
594 | ADAU1977_SAI_CTRL0_SAI_MASK, ctrl0); | ||
595 | if (ret) | ||
596 | return ret; | ||
597 | |||
598 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1, | ||
599 | ADAU1977_SAI_CTRL1_SLOT_WIDTH_MASK, ctrl1); | ||
600 | if (ret) | ||
601 | return ret; | ||
602 | |||
603 | adau1977->slot_width = width; | ||
604 | |||
605 | /* In master mode the maximum bitclock is 24.576 MHz */ | ||
606 | adau1977->max_master_fs = min(192000, 24576000 / width / slots); | ||
607 | |||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | static int adau1977_mute(struct snd_soc_dai *dai, int mute, int stream) | ||
612 | { | ||
613 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec); | ||
614 | unsigned int val; | ||
615 | |||
616 | if (mute) | ||
617 | val = ADAU1977_MISC_CONTROL_MMUTE; | ||
618 | else | ||
619 | val = 0; | ||
620 | |||
621 | return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MISC_CONTROL, | ||
622 | ADAU1977_MISC_CONTROL_MMUTE, val); | ||
623 | } | ||
624 | |||
625 | static int adau1977_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
626 | { | ||
627 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec); | ||
628 | unsigned int ctrl0 = 0, ctrl1 = 0, block_power = 0; | ||
629 | bool invert_lrclk; | ||
630 | int ret; | ||
631 | |||
632 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
633 | case SND_SOC_DAIFMT_CBS_CFS: | ||
634 | adau1977->master = false; | ||
635 | break; | ||
636 | case SND_SOC_DAIFMT_CBM_CFM: | ||
637 | ctrl1 |= ADAU1977_SAI_CTRL1_MASTER; | ||
638 | adau1977->master = true; | ||
639 | break; | ||
640 | default: | ||
641 | return -EINVAL; | ||
642 | } | ||
643 | |||
644 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
645 | case SND_SOC_DAIFMT_NB_NF: | ||
646 | invert_lrclk = false; | ||
647 | break; | ||
648 | case SND_SOC_DAIFMT_IB_NF: | ||
649 | block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE; | ||
650 | invert_lrclk = false; | ||
651 | break; | ||
652 | case SND_SOC_DAIFMT_NB_IF: | ||
653 | invert_lrclk = true; | ||
654 | break; | ||
655 | case SND_SOC_DAIFMT_IB_IF: | ||
656 | block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE; | ||
657 | invert_lrclk = true; | ||
658 | break; | ||
659 | default: | ||
660 | return -EINVAL; | ||
661 | } | ||
662 | |||
663 | adau1977->right_j = false; | ||
664 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
665 | case SND_SOC_DAIFMT_I2S: | ||
666 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S; | ||
667 | break; | ||
668 | case SND_SOC_DAIFMT_LEFT_J: | ||
669 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ; | ||
670 | invert_lrclk = !invert_lrclk; | ||
671 | break; | ||
672 | case SND_SOC_DAIFMT_RIGHT_J: | ||
673 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT; | ||
674 | adau1977->right_j = true; | ||
675 | invert_lrclk = !invert_lrclk; | ||
676 | break; | ||
677 | case SND_SOC_DAIFMT_DSP_A: | ||
678 | ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE; | ||
679 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S; | ||
680 | invert_lrclk = false; | ||
681 | break; | ||
682 | case SND_SOC_DAIFMT_DSP_B: | ||
683 | ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE; | ||
684 | ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ; | ||
685 | invert_lrclk = false; | ||
686 | break; | ||
687 | default: | ||
688 | return -EINVAL; | ||
689 | } | ||
690 | |||
691 | if (invert_lrclk) | ||
692 | block_power |= ADAU1977_BLOCK_POWER_SAI_LR_POL; | ||
693 | |||
694 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI, | ||
695 | ADAU1977_BLOCK_POWER_SAI_LR_POL | | ||
696 | ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE, block_power); | ||
697 | if (ret) | ||
698 | return ret; | ||
699 | |||
700 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0, | ||
701 | ADAU1977_SAI_CTRL0_FMT_MASK, | ||
702 | ctrl0); | ||
703 | if (ret) | ||
704 | return ret; | ||
705 | |||
706 | return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1, | ||
707 | ADAU1977_SAI_CTRL1_MASTER | ADAU1977_SAI_CTRL1_LRCLK_PULSE, | ||
708 | ctrl1); | ||
709 | } | ||
710 | |||
711 | static int adau1977_startup(struct snd_pcm_substream *substream, | ||
712 | struct snd_soc_dai *dai) | ||
713 | { | ||
714 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec); | ||
715 | u64 formats = 0; | ||
716 | |||
717 | if (adau1977->slot_width == 16) | ||
718 | formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE; | ||
719 | else if (adau1977->right_j || adau1977->slot_width == 24) | ||
720 | formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | | ||
721 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE; | ||
722 | |||
723 | snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
724 | SNDRV_PCM_HW_PARAM_RATE, &adau1977->constraints); | ||
725 | |||
726 | if (adau1977->master) | ||
727 | snd_pcm_hw_constraint_minmax(substream->runtime, | ||
728 | SNDRV_PCM_HW_PARAM_RATE, 8000, adau1977->max_master_fs); | ||
729 | |||
730 | if (formats != 0) | ||
731 | snd_pcm_hw_constraint_mask64(substream->runtime, | ||
732 | SNDRV_PCM_HW_PARAM_FORMAT, formats); | ||
733 | |||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | static int adau1977_set_tristate(struct snd_soc_dai *dai, int tristate) | ||
738 | { | ||
739 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec); | ||
740 | unsigned int val; | ||
741 | |||
742 | if (tristate) | ||
743 | val = ADAU1977_SAI_OVERTEMP_DRV_HIZ; | ||
744 | else | ||
745 | val = 0; | ||
746 | |||
747 | return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP, | ||
748 | ADAU1977_SAI_OVERTEMP_DRV_HIZ, val); | ||
749 | } | ||
750 | |||
751 | static const struct snd_soc_dai_ops adau1977_dai_ops = { | ||
752 | .startup = adau1977_startup, | ||
753 | .hw_params = adau1977_hw_params, | ||
754 | .mute_stream = adau1977_mute, | ||
755 | .set_fmt = adau1977_set_dai_fmt, | ||
756 | .set_tdm_slot = adau1977_set_tdm_slot, | ||
757 | .set_tristate = adau1977_set_tristate, | ||
758 | }; | ||
759 | |||
760 | static struct snd_soc_dai_driver adau1977_dai = { | ||
761 | .name = "adau1977-hifi", | ||
762 | .capture = { | ||
763 | .stream_name = "Capture", | ||
764 | .channels_min = 1, | ||
765 | .channels_max = 4, | ||
766 | .rates = SNDRV_PCM_RATE_KNOT, | ||
767 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | | ||
768 | SNDRV_PCM_FMTBIT_S32_LE, | ||
769 | .sig_bits = 24, | ||
770 | }, | ||
771 | .ops = &adau1977_dai_ops, | ||
772 | }; | ||
773 | |||
774 | static const unsigned int adau1977_rates[] = { | ||
775 | 8000, 16000, 32000, 64000, 128000, | ||
776 | 11025, 22050, 44100, 88200, 172400, | ||
777 | 12000, 24000, 48000, 96000, 192000, | ||
778 | }; | ||
779 | |||
780 | #define ADAU1977_RATE_CONSTRAINT_MASK_32000 0x001f | ||
781 | #define ADAU1977_RATE_CONSTRAINT_MASK_44100 0x03e0 | ||
782 | #define ADAU1977_RATE_CONSTRAINT_MASK_48000 0x7c00 | ||
783 | /* All rates >= 32000 */ | ||
784 | #define ADAU1977_RATE_CONSTRAINT_MASK_LRCLK 0x739c | ||
785 | |||
786 | static bool adau1977_check_sysclk(unsigned int mclk, unsigned int base_freq) | ||
787 | { | ||
788 | unsigned int mcs; | ||
789 | |||
790 | if (mclk % (base_freq * 128) != 0) | ||
791 | return false; | ||
792 | |||
793 | mcs = mclk / (128 * base_freq); | ||
794 | if (mcs < 1 || mcs > 6 || mcs == 5) | ||
795 | return false; | ||
796 | |||
797 | return true; | ||
798 | } | ||
799 | |||
800 | static int adau1977_set_sysclk(struct snd_soc_codec *codec, | ||
801 | int clk_id, int source, unsigned int freq, int dir) | ||
802 | { | ||
803 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec); | ||
804 | unsigned int mask = 0; | ||
805 | unsigned int clk_src; | ||
806 | unsigned int ret; | ||
807 | |||
808 | if (dir != SND_SOC_CLOCK_IN) | ||
809 | return -EINVAL; | ||
810 | |||
811 | if (clk_id != ADAU1977_SYSCLK) | ||
812 | return -EINVAL; | ||
813 | |||
814 | switch (source) { | ||
815 | case ADAU1977_SYSCLK_SRC_MCLK: | ||
816 | clk_src = 0; | ||
817 | break; | ||
818 | case ADAU1977_SYSCLK_SRC_LRCLK: | ||
819 | clk_src = ADAU1977_PLL_CLK_S; | ||
820 | break; | ||
821 | default: | ||
822 | return -EINVAL; | ||
823 | } | ||
824 | |||
825 | if (freq != 0 && source == ADAU1977_SYSCLK_SRC_MCLK) { | ||
826 | if (freq < 4000000 || freq > 36864000) | ||
827 | return -EINVAL; | ||
828 | |||
829 | if (adau1977_check_sysclk(freq, 32000)) | ||
830 | mask |= ADAU1977_RATE_CONSTRAINT_MASK_32000; | ||
831 | if (adau1977_check_sysclk(freq, 44100)) | ||
832 | mask |= ADAU1977_RATE_CONSTRAINT_MASK_44100; | ||
833 | if (adau1977_check_sysclk(freq, 48000)) | ||
834 | mask |= ADAU1977_RATE_CONSTRAINT_MASK_48000; | ||
835 | |||
836 | if (mask == 0) | ||
837 | return -EINVAL; | ||
838 | } else if (source == ADAU1977_SYSCLK_SRC_LRCLK) { | ||
839 | mask = ADAU1977_RATE_CONSTRAINT_MASK_LRCLK; | ||
840 | } | ||
841 | |||
842 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL, | ||
843 | ADAU1977_PLL_CLK_S, clk_src); | ||
844 | if (ret) | ||
845 | return ret; | ||
846 | |||
847 | adau1977->constraints.mask = mask; | ||
848 | adau1977->sysclk_src = source; | ||
849 | adau1977->sysclk = freq; | ||
850 | |||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static int adau1977_codec_probe(struct snd_soc_codec *codec) | ||
855 | { | ||
856 | struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec); | ||
857 | int ret; | ||
858 | |||
859 | switch (adau1977->type) { | ||
860 | case ADAU1977: | ||
861 | ret = snd_soc_dapm_new_controls(&codec->dapm, | ||
862 | adau1977_micbias_dapm_widgets, | ||
863 | ARRAY_SIZE(adau1977_micbias_dapm_widgets)); | ||
864 | if (ret < 0) | ||
865 | return ret; | ||
866 | break; | ||
867 | default: | ||
868 | break; | ||
869 | } | ||
870 | |||
871 | return 0; | ||
872 | } | ||
873 | |||
874 | static struct snd_soc_codec_driver adau1977_codec_driver = { | ||
875 | .probe = adau1977_codec_probe, | ||
876 | .set_bias_level = adau1977_set_bias_level, | ||
877 | .set_sysclk = adau1977_set_sysclk, | ||
878 | .idle_bias_off = true, | ||
879 | |||
880 | .controls = adau1977_snd_controls, | ||
881 | .num_controls = ARRAY_SIZE(adau1977_snd_controls), | ||
882 | .dapm_widgets = adau1977_dapm_widgets, | ||
883 | .num_dapm_widgets = ARRAY_SIZE(adau1977_dapm_widgets), | ||
884 | .dapm_routes = adau1977_dapm_routes, | ||
885 | .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes), | ||
886 | }; | ||
887 | |||
888 | static int adau1977_setup_micbias(struct adau1977 *adau1977) | ||
889 | { | ||
890 | struct adau1977_platform_data *pdata = adau1977->dev->platform_data; | ||
891 | unsigned int micbias; | ||
892 | |||
893 | if (pdata) { | ||
894 | micbias = pdata->micbias; | ||
895 | if (micbias > ADAU1977_MICBIAS_9V0) | ||
896 | return -EINVAL; | ||
897 | |||
898 | } else { | ||
899 | micbias = ADAU1977_MICBIAS_8V5; | ||
900 | } | ||
901 | |||
902 | return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MICBIAS, | ||
903 | ADAU1977_MICBIAS_MB_VOLTS_MASK, | ||
904 | micbias << ADAU1977_MICBIAS_MB_VOLTS_OFFSET); | ||
905 | } | ||
906 | |||
907 | int adau1977_probe(struct device *dev, struct regmap *regmap, | ||
908 | enum adau1977_type type, void (*switch_mode)(struct device *dev)) | ||
909 | { | ||
910 | unsigned int power_off_mask; | ||
911 | struct adau1977 *adau1977; | ||
912 | int ret; | ||
913 | |||
914 | if (IS_ERR(regmap)) | ||
915 | return PTR_ERR(regmap); | ||
916 | |||
917 | adau1977 = devm_kzalloc(dev, sizeof(*adau1977), GFP_KERNEL); | ||
918 | if (adau1977 == NULL) | ||
919 | return -ENOMEM; | ||
920 | |||
921 | adau1977->dev = dev; | ||
922 | adau1977->type = type; | ||
923 | adau1977->regmap = regmap; | ||
924 | adau1977->switch_mode = switch_mode; | ||
925 | adau1977->max_master_fs = 192000; | ||
926 | |||
927 | adau1977->constraints.list = adau1977_rates; | ||
928 | adau1977->constraints.count = ARRAY_SIZE(adau1977_rates); | ||
929 | |||
930 | adau1977->avdd_reg = devm_regulator_get(dev, "AVDD"); | ||
931 | if (IS_ERR(adau1977->avdd_reg)) | ||
932 | return PTR_ERR(adau1977->avdd_reg); | ||
933 | |||
934 | adau1977->dvdd_reg = devm_regulator_get_optional(dev, "DVDD"); | ||
935 | if (IS_ERR(adau1977->dvdd_reg)) { | ||
936 | if (PTR_ERR(adau1977->dvdd_reg) != -ENODEV) | ||
937 | return PTR_ERR(adau1977->dvdd_reg); | ||
938 | adau1977->dvdd_reg = NULL; | ||
939 | } | ||
940 | |||
941 | adau1977->reset_gpio = devm_gpiod_get(dev, "reset"); | ||
942 | if (IS_ERR(adau1977->reset_gpio)) { | ||
943 | ret = PTR_ERR(adau1977->reset_gpio); | ||
944 | if (ret != -ENOENT && ret != -ENOSYS) | ||
945 | return PTR_ERR(adau1977->reset_gpio); | ||
946 | adau1977->reset_gpio = NULL; | ||
947 | } | ||
948 | |||
949 | dev_set_drvdata(dev, adau1977); | ||
950 | |||
951 | if (adau1977->reset_gpio) { | ||
952 | ret = gpiod_direction_output(adau1977->reset_gpio, 0); | ||
953 | if (ret) | ||
954 | return ret; | ||
955 | ndelay(100); | ||
956 | } | ||
957 | |||
958 | ret = adau1977_power_enable(adau1977); | ||
959 | if (ret) | ||
960 | return ret; | ||
961 | |||
962 | if (type == ADAU1977) { | ||
963 | ret = adau1977_setup_micbias(adau1977); | ||
964 | if (ret) | ||
965 | goto err_poweroff; | ||
966 | } | ||
967 | |||
968 | if (adau1977->dvdd_reg) | ||
969 | power_off_mask = ~0; | ||
970 | else | ||
971 | power_off_mask = ~ADAU1977_BLOCK_POWER_SAI_LDO_EN; | ||
972 | |||
973 | ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI, | ||
974 | power_off_mask, 0x00); | ||
975 | if (ret) | ||
976 | goto err_poweroff; | ||
977 | |||
978 | ret = adau1977_power_disable(adau1977); | ||
979 | if (ret) | ||
980 | return ret; | ||
981 | |||
982 | return snd_soc_register_codec(dev, &adau1977_codec_driver, | ||
983 | &adau1977_dai, 1); | ||
984 | |||
985 | err_poweroff: | ||
986 | adau1977_power_disable(adau1977); | ||
987 | return ret; | ||
988 | |||
989 | } | ||
990 | EXPORT_SYMBOL_GPL(adau1977_probe); | ||
991 | |||
992 | static bool adau1977_register_volatile(struct device *dev, unsigned int reg) | ||
993 | { | ||
994 | switch (reg) { | ||
995 | case ADAU1977_REG_STATUS(0): | ||
996 | case ADAU1977_REG_STATUS(1): | ||
997 | case ADAU1977_REG_STATUS(2): | ||
998 | case ADAU1977_REG_STATUS(3): | ||
999 | case ADAU1977_REG_ADC_CLIP: | ||
1000 | return true; | ||
1001 | } | ||
1002 | |||
1003 | return false; | ||
1004 | } | ||
1005 | |||
1006 | const struct regmap_config adau1977_regmap_config = { | ||
1007 | .max_register = ADAU1977_REG_DC_HPF_CAL, | ||
1008 | .volatile_reg = adau1977_register_volatile, | ||
1009 | |||
1010 | .cache_type = REGCACHE_RBTREE, | ||
1011 | .reg_defaults = adau1977_reg_defaults, | ||
1012 | .num_reg_defaults = ARRAY_SIZE(adau1977_reg_defaults), | ||
1013 | }; | ||
1014 | EXPORT_SYMBOL_GPL(adau1977_regmap_config); | ||
1015 | |||
1016 | MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver"); | ||
1017 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
1018 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/adau1977.h b/sound/soc/codecs/adau1977.h new file mode 100644 index 000000000000..95e714345a86 --- /dev/null +++ b/sound/soc/codecs/adau1977.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * ADAU1977/ADAU1978/ADAU1979 driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
6 | * | ||
7 | * Licensed under the GPL-2. | ||
8 | */ | ||
9 | |||
10 | #ifndef __SOUND_SOC_CODECS_ADAU1977_H__ | ||
11 | #define __SOUND_SOC_CODECS_ADAU1977_H__ | ||
12 | |||
13 | #include <linux/regmap.h> | ||
14 | |||
15 | struct device; | ||
16 | |||
17 | enum adau1977_type { | ||
18 | ADAU1977, | ||
19 | ADAU1978, | ||
20 | ADAU1979, | ||
21 | }; | ||
22 | |||
23 | int adau1977_probe(struct device *dev, struct regmap *regmap, | ||
24 | enum adau1977_type type, void (*switch_mode)(struct device *dev)); | ||
25 | |||
26 | extern const struct regmap_config adau1977_regmap_config; | ||
27 | |||
28 | enum adau1977_clk_id { | ||
29 | ADAU1977_SYSCLK, | ||
30 | }; | ||
31 | |||
32 | enum adau1977_sysclk_src { | ||
33 | ADAU1977_SYSCLK_SRC_MCLK, | ||
34 | ADAU1977_SYSCLK_SRC_LRCLK, | ||
35 | }; | ||
36 | |||
37 | #endif | ||
diff --git a/sound/soc/codecs/adav801.c b/sound/soc/codecs/adav801.c new file mode 100644 index 000000000000..790fce33ab10 --- /dev/null +++ b/sound/soc/codecs/adav801.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * ADAV801 audio driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/spi/spi.h> | ||
11 | #include <linux/regmap.h> | ||
12 | |||
13 | #include <sound/soc.h> | ||
14 | |||
15 | #include "adav80x.h" | ||
16 | |||
17 | static const struct spi_device_id adav80x_spi_id[] = { | ||
18 | { "adav801", 0 }, | ||
19 | { } | ||
20 | }; | ||
21 | MODULE_DEVICE_TABLE(spi, adav80x_spi_id); | ||
22 | |||
23 | static int adav80x_spi_probe(struct spi_device *spi) | ||
24 | { | ||
25 | struct regmap_config config; | ||
26 | |||
27 | config = adav80x_regmap_config; | ||
28 | config.read_flag_mask = 0x01; | ||
29 | |||
30 | return adav80x_bus_probe(&spi->dev, devm_regmap_init_spi(spi, &config)); | ||
31 | } | ||
32 | |||
33 | static int adav80x_spi_remove(struct spi_device *spi) | ||
34 | { | ||
35 | snd_soc_unregister_codec(&spi->dev); | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static struct spi_driver adav80x_spi_driver = { | ||
40 | .driver = { | ||
41 | .name = "adav801", | ||
42 | .owner = THIS_MODULE, | ||
43 | }, | ||
44 | .probe = adav80x_spi_probe, | ||
45 | .remove = adav80x_spi_remove, | ||
46 | .id_table = adav80x_spi_id, | ||
47 | }; | ||
48 | module_spi_driver(adav80x_spi_driver); | ||
49 | |||
50 | MODULE_DESCRIPTION("ASoC ADAV801 driver"); | ||
51 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
52 | MODULE_AUTHOR("Yi Li <yi.li@analog.com>>"); | ||
53 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/adav803.c b/sound/soc/codecs/adav803.c new file mode 100644 index 000000000000..66d9fce34e62 --- /dev/null +++ b/sound/soc/codecs/adav803.c | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * ADAV803 audio driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/regmap.h> | ||
12 | |||
13 | #include <sound/soc.h> | ||
14 | |||
15 | #include "adav80x.h" | ||
16 | |||
17 | static const struct i2c_device_id adav803_id[] = { | ||
18 | { "adav803", 0 }, | ||
19 | { } | ||
20 | }; | ||
21 | MODULE_DEVICE_TABLE(i2c, adav803_id); | ||
22 | |||
23 | static int adav803_probe(struct i2c_client *client, | ||
24 | const struct i2c_device_id *id) | ||
25 | { | ||
26 | return adav80x_bus_probe(&client->dev, | ||
27 | devm_regmap_init_i2c(client, &adav80x_regmap_config)); | ||
28 | } | ||
29 | |||
30 | static int adav803_remove(struct i2c_client *client) | ||
31 | { | ||
32 | snd_soc_unregister_codec(&client->dev); | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static struct i2c_driver adav803_driver = { | ||
37 | .driver = { | ||
38 | .name = "adav803", | ||
39 | .owner = THIS_MODULE, | ||
40 | }, | ||
41 | .probe = adav803_probe, | ||
42 | .remove = adav803_remove, | ||
43 | .id_table = adav803_id, | ||
44 | }; | ||
45 | module_i2c_driver(adav803_driver); | ||
46 | |||
47 | MODULE_DESCRIPTION("ASoC ADAV803 driver"); | ||
48 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
49 | MODULE_AUTHOR("Yi Li <yi.li@analog.com>>"); | ||
50 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index f78b27a7c461..5062e34ee8dc 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c | |||
@@ -8,17 +8,15 @@ | |||
8 | * Licensed under the GPL-2 or later. | 8 | * Licensed under the GPL-2 or later. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | 11 | #include <linux/module.h> |
13 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
14 | #include <linux/i2c.h> | 13 | #include <linux/regmap.h> |
15 | #include <linux/spi/spi.h> | ||
16 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
17 | #include <sound/core.h> | 15 | |
18 | #include <sound/pcm.h> | 16 | #include <sound/pcm.h> |
19 | #include <sound/pcm_params.h> | 17 | #include <sound/pcm_params.h> |
20 | #include <sound/tlv.h> | ||
21 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
19 | #include <sound/tlv.h> | ||
22 | 20 | ||
23 | #include "adav80x.h" | 21 | #include "adav80x.h" |
24 | 22 | ||
@@ -541,6 +539,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec, | |||
541 | unsigned int freq, int dir) | 539 | unsigned int freq, int dir) |
542 | { | 540 | { |
543 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); | 541 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
542 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
544 | 543 | ||
545 | if (dir == SND_SOC_CLOCK_IN) { | 544 | if (dir == SND_SOC_CLOCK_IN) { |
546 | switch (clk_id) { | 545 | switch (clk_id) { |
@@ -573,7 +572,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec, | |||
573 | regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2, | 572 | regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2, |
574 | iclk_ctrl2); | 573 | iclk_ctrl2); |
575 | 574 | ||
576 | snd_soc_dapm_sync(&codec->dapm); | 575 | snd_soc_dapm_sync(dapm); |
577 | } | 576 | } |
578 | } else { | 577 | } else { |
579 | unsigned int mask; | 578 | unsigned int mask; |
@@ -600,17 +599,21 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec, | |||
600 | adav80x->sysclk_pd[clk_id] = false; | 599 | adav80x->sysclk_pd[clk_id] = false; |
601 | } | 600 | } |
602 | 601 | ||
602 | snd_soc_dapm_mutex_lock(dapm); | ||
603 | |||
603 | if (adav80x->sysclk_pd[0]) | 604 | if (adav80x->sysclk_pd[0]) |
604 | snd_soc_dapm_disable_pin(&codec->dapm, "PLL1"); | 605 | snd_soc_dapm_disable_pin_unlocked(dapm, "PLL1"); |
605 | else | 606 | else |
606 | snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); | 607 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL1"); |
607 | 608 | ||
608 | if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2]) | 609 | if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2]) |
609 | snd_soc_dapm_disable_pin(&codec->dapm, "PLL2"); | 610 | snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2"); |
610 | else | 611 | else |
611 | snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2"); | 612 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2"); |
612 | 613 | ||
613 | snd_soc_dapm_sync(&codec->dapm); | 614 | snd_soc_dapm_sync_unlocked(dapm); |
615 | |||
616 | snd_soc_dapm_mutex_unlock(dapm); | ||
614 | } | 617 | } |
615 | 618 | ||
616 | return 0; | 619 | return 0; |
@@ -722,7 +725,7 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream, | |||
722 | struct snd_soc_codec *codec = dai->codec; | 725 | struct snd_soc_codec *codec = dai->codec; |
723 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); | 726 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
724 | 727 | ||
725 | if (!codec->active || !adav80x->rate) | 728 | if (!snd_soc_codec_is_active(codec) || !adav80x->rate) |
726 | return 0; | 729 | return 0; |
727 | 730 | ||
728 | return snd_pcm_hw_constraint_minmax(substream->runtime, | 731 | return snd_pcm_hw_constraint_minmax(substream->runtime, |
@@ -735,7 +738,7 @@ static void adav80x_dai_shutdown(struct snd_pcm_substream *substream, | |||
735 | struct snd_soc_codec *codec = dai->codec; | 738 | struct snd_soc_codec *codec = dai->codec; |
736 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); | 739 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
737 | 740 | ||
738 | if (!codec->active) | 741 | if (!snd_soc_codec_is_active(codec)) |
739 | adav80x->rate = 0; | 742 | adav80x->rate = 0; |
740 | } | 743 | } |
741 | 744 | ||
@@ -798,15 +801,8 @@ static struct snd_soc_dai_driver adav80x_dais[] = { | |||
798 | 801 | ||
799 | static int adav80x_probe(struct snd_soc_codec *codec) | 802 | static int adav80x_probe(struct snd_soc_codec *codec) |
800 | { | 803 | { |
801 | int ret; | ||
802 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); | 804 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
803 | 805 | ||
804 | ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); | ||
805 | if (ret) { | ||
806 | dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); | ||
807 | return ret; | ||
808 | } | ||
809 | |||
810 | /* Force PLLs on for SYSCLK output */ | 806 | /* Force PLLs on for SYSCLK output */ |
811 | snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); | 807 | snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); |
812 | snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2"); | 808 | snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2"); |
@@ -864,39 +860,26 @@ static struct snd_soc_codec_driver adav80x_codec_driver = { | |||
864 | .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), | 860 | .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), |
865 | }; | 861 | }; |
866 | 862 | ||
867 | static int adav80x_bus_probe(struct device *dev, struct regmap *regmap) | 863 | int adav80x_bus_probe(struct device *dev, struct regmap *regmap) |
868 | { | 864 | { |
869 | struct adav80x *adav80x; | 865 | struct adav80x *adav80x; |
870 | int ret; | ||
871 | 866 | ||
872 | if (IS_ERR(regmap)) | 867 | if (IS_ERR(regmap)) |
873 | return PTR_ERR(regmap); | 868 | return PTR_ERR(regmap); |
874 | 869 | ||
875 | adav80x = kzalloc(sizeof(*adav80x), GFP_KERNEL); | 870 | adav80x = devm_kzalloc(dev, sizeof(*adav80x), GFP_KERNEL); |
876 | if (!adav80x) | 871 | if (!adav80x) |
877 | return -ENOMEM; | 872 | return -ENOMEM; |
878 | 873 | ||
879 | |||
880 | dev_set_drvdata(dev, adav80x); | 874 | dev_set_drvdata(dev, adav80x); |
881 | adav80x->regmap = regmap; | 875 | adav80x->regmap = regmap; |
882 | 876 | ||
883 | ret = snd_soc_register_codec(dev, &adav80x_codec_driver, | 877 | return snd_soc_register_codec(dev, &adav80x_codec_driver, |
884 | adav80x_dais, ARRAY_SIZE(adav80x_dais)); | 878 | adav80x_dais, ARRAY_SIZE(adav80x_dais)); |
885 | if (ret) | ||
886 | kfree(adav80x); | ||
887 | |||
888 | return ret; | ||
889 | } | ||
890 | |||
891 | static int adav80x_bus_remove(struct device *dev) | ||
892 | { | ||
893 | snd_soc_unregister_codec(dev); | ||
894 | kfree(dev_get_drvdata(dev)); | ||
895 | return 0; | ||
896 | } | 879 | } |
880 | EXPORT_SYMBOL_GPL(adav80x_bus_probe); | ||
897 | 881 | ||
898 | #if defined(CONFIG_SPI_MASTER) | 882 | const struct regmap_config adav80x_regmap_config = { |
899 | static const struct regmap_config adav80x_spi_regmap_config = { | ||
900 | .val_bits = 8, | 883 | .val_bits = 8, |
901 | .pad_bits = 1, | 884 | .pad_bits = 1, |
902 | .reg_bits = 7, | 885 | .reg_bits = 7, |
@@ -908,105 +891,7 @@ static const struct regmap_config adav80x_spi_regmap_config = { | |||
908 | .reg_defaults = adav80x_reg_defaults, | 891 | .reg_defaults = adav80x_reg_defaults, |
909 | .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults), | 892 | .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults), |
910 | }; | 893 | }; |
911 | 894 | EXPORT_SYMBOL_GPL(adav80x_regmap_config); | |
912 | static const struct spi_device_id adav80x_spi_id[] = { | ||
913 | { "adav801", 0 }, | ||
914 | { } | ||
915 | }; | ||
916 | MODULE_DEVICE_TABLE(spi, adav80x_spi_id); | ||
917 | |||
918 | static int adav80x_spi_probe(struct spi_device *spi) | ||
919 | { | ||
920 | return adav80x_bus_probe(&spi->dev, | ||
921 | devm_regmap_init_spi(spi, &adav80x_spi_regmap_config)); | ||
922 | } | ||
923 | |||
924 | static int adav80x_spi_remove(struct spi_device *spi) | ||
925 | { | ||
926 | return adav80x_bus_remove(&spi->dev); | ||
927 | } | ||
928 | |||
929 | static struct spi_driver adav80x_spi_driver = { | ||
930 | .driver = { | ||
931 | .name = "adav801", | ||
932 | .owner = THIS_MODULE, | ||
933 | }, | ||
934 | .probe = adav80x_spi_probe, | ||
935 | .remove = adav80x_spi_remove, | ||
936 | .id_table = adav80x_spi_id, | ||
937 | }; | ||
938 | #endif | ||
939 | |||
940 | #if IS_ENABLED(CONFIG_I2C) | ||
941 | static const struct regmap_config adav80x_i2c_regmap_config = { | ||
942 | .val_bits = 8, | ||
943 | .pad_bits = 1, | ||
944 | .reg_bits = 7, | ||
945 | |||
946 | .max_register = ADAV80X_PLL_OUTE, | ||
947 | |||
948 | .cache_type = REGCACHE_RBTREE, | ||
949 | .reg_defaults = adav80x_reg_defaults, | ||
950 | .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults), | ||
951 | }; | ||
952 | |||
953 | static const struct i2c_device_id adav80x_i2c_id[] = { | ||
954 | { "adav803", 0 }, | ||
955 | { } | ||
956 | }; | ||
957 | MODULE_DEVICE_TABLE(i2c, adav80x_i2c_id); | ||
958 | |||
959 | static int adav80x_i2c_probe(struct i2c_client *client, | ||
960 | const struct i2c_device_id *id) | ||
961 | { | ||
962 | return adav80x_bus_probe(&client->dev, | ||
963 | devm_regmap_init_i2c(client, &adav80x_i2c_regmap_config)); | ||
964 | } | ||
965 | |||
966 | static int adav80x_i2c_remove(struct i2c_client *client) | ||
967 | { | ||
968 | return adav80x_bus_remove(&client->dev); | ||
969 | } | ||
970 | |||
971 | static struct i2c_driver adav80x_i2c_driver = { | ||
972 | .driver = { | ||
973 | .name = "adav803", | ||
974 | .owner = THIS_MODULE, | ||
975 | }, | ||
976 | .probe = adav80x_i2c_probe, | ||
977 | .remove = adav80x_i2c_remove, | ||
978 | .id_table = adav80x_i2c_id, | ||
979 | }; | ||
980 | #endif | ||
981 | |||
982 | static int __init adav80x_init(void) | ||
983 | { | ||
984 | int ret = 0; | ||
985 | |||
986 | #if IS_ENABLED(CONFIG_I2C) | ||
987 | ret = i2c_add_driver(&adav80x_i2c_driver); | ||
988 | if (ret) | ||
989 | return ret; | ||
990 | #endif | ||
991 | |||
992 | #if defined(CONFIG_SPI_MASTER) | ||
993 | ret = spi_register_driver(&adav80x_spi_driver); | ||
994 | #endif | ||
995 | |||
996 | return ret; | ||
997 | } | ||
998 | module_init(adav80x_init); | ||
999 | |||
1000 | static void __exit adav80x_exit(void) | ||
1001 | { | ||
1002 | #if IS_ENABLED(CONFIG_I2C) | ||
1003 | i2c_del_driver(&adav80x_i2c_driver); | ||
1004 | #endif | ||
1005 | #if defined(CONFIG_SPI_MASTER) | ||
1006 | spi_unregister_driver(&adav80x_spi_driver); | ||
1007 | #endif | ||
1008 | } | ||
1009 | module_exit(adav80x_exit); | ||
1010 | 895 | ||
1011 | MODULE_DESCRIPTION("ASoC ADAV80x driver"); | 896 | MODULE_DESCRIPTION("ASoC ADAV80x driver"); |
1012 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | 897 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); |
diff --git a/sound/soc/codecs/adav80x.h b/sound/soc/codecs/adav80x.h index adb0fc76d4e3..8a1d7c09dca5 100644 --- a/sound/soc/codecs/adav80x.h +++ b/sound/soc/codecs/adav80x.h | |||
@@ -9,6 +9,13 @@ | |||
9 | #ifndef _ADAV80X_H | 9 | #ifndef _ADAV80X_H |
10 | #define _ADAV80X_H | 10 | #define _ADAV80X_H |
11 | 11 | ||
12 | #include <linux/regmap.h> | ||
13 | |||
14 | struct device; | ||
15 | |||
16 | extern const struct regmap_config adav80x_regmap_config; | ||
17 | int adav80x_bus_probe(struct device *dev, struct regmap *regmap); | ||
18 | |||
12 | enum adav80x_pll_src { | 19 | enum adav80x_pll_src { |
13 | ADAV80X_PLL_SRC_XIN, | 20 | ADAV80X_PLL_SRC_XIN, |
14 | ADAV80X_PLL_SRC_XTAL, | 21 | ADAV80X_PLL_SRC_XTAL, |
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index b4819dcd4f4d..10adf25d4c14 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c | |||
@@ -174,8 +174,6 @@ static int ak4104_probe(struct snd_soc_codec *codec) | |||
174 | struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); | 174 | struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); |
175 | int ret; | 175 | int ret; |
176 | 176 | ||
177 | codec->control_data = ak4104->regmap; | ||
178 | |||
179 | /* set power-up and non-reset bits */ | 177 | /* set power-up and non-reset bits */ |
180 | ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, | 178 | ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, |
181 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, | 179 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, |
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 684fe910669f..30e297890fec 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c | |||
@@ -388,15 +388,6 @@ static int ak4535_resume(struct snd_soc_codec *codec) | |||
388 | 388 | ||
389 | static int ak4535_probe(struct snd_soc_codec *codec) | 389 | static int ak4535_probe(struct snd_soc_codec *codec) |
390 | { | 390 | { |
391 | struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); | ||
392 | int ret; | ||
393 | |||
394 | codec->control_data = ak4535->regmap; | ||
395 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
396 | if (ret < 0) { | ||
397 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
398 | return ret; | ||
399 | } | ||
400 | /* power on device */ | 391 | /* power on device */ |
401 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 392 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
402 | 393 | ||
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 94cbe508dd37..868c0e2da1ec 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c | |||
@@ -113,14 +113,14 @@ static const DECLARE_TLV_DB_SCALE(alc_tlv, -800, 50, 0); | |||
113 | static const DECLARE_TLV_DB_SCALE(aux_in_tlv, -2100, 300, 0); | 113 | static const DECLARE_TLV_DB_SCALE(aux_in_tlv, -2100, 300, 0); |
114 | 114 | ||
115 | 115 | ||
116 | static const struct soc_enum ak4641_mono_out_enum = | 116 | static SOC_ENUM_SINGLE_DECL(ak4641_mono_out_enum, |
117 | SOC_ENUM_SINGLE(AK4641_SIG1, 6, 2, ak4641_mono_out); | 117 | AK4641_SIG1, 6, ak4641_mono_out); |
118 | static const struct soc_enum ak4641_hp_out_enum = | 118 | static SOC_ENUM_SINGLE_DECL(ak4641_hp_out_enum, |
119 | SOC_ENUM_SINGLE(AK4641_MODE2, 2, 2, ak4641_hp_out); | 119 | AK4641_MODE2, 2, ak4641_hp_out); |
120 | static const struct soc_enum ak4641_mic_select_enum = | 120 | static SOC_ENUM_SINGLE_DECL(ak4641_mic_select_enum, |
121 | SOC_ENUM_SINGLE(AK4641_MIC, 1, 2, ak4641_mic_select); | 121 | AK4641_MIC, 1, ak4641_mic_select); |
122 | static const struct soc_enum ak4641_mic_or_dac_enum = | 122 | static SOC_ENUM_SINGLE_DECL(ak4641_mic_or_dac_enum, |
123 | SOC_ENUM_SINGLE(AK4641_BTIF, 4, 2, ak4641_mic_or_dac); | 123 | AK4641_BTIF, 4, ak4641_mic_or_dac); |
124 | 124 | ||
125 | static const struct snd_kcontrol_new ak4641_snd_controls[] = { | 125 | static const struct snd_kcontrol_new ak4641_snd_controls[] = { |
126 | SOC_ENUM("Mono 1 Output", ak4641_mono_out_enum), | 126 | SOC_ENUM("Mono 1 Output", ak4641_mono_out_enum), |
@@ -519,14 +519,6 @@ static int ak4641_resume(struct snd_soc_codec *codec) | |||
519 | 519 | ||
520 | static int ak4641_probe(struct snd_soc_codec *codec) | 520 | static int ak4641_probe(struct snd_soc_codec *codec) |
521 | { | 521 | { |
522 | int ret; | ||
523 | |||
524 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
525 | if (ret != 0) { | ||
526 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
527 | return ret; | ||
528 | } | ||
529 | |||
530 | /* power on device */ | 522 | /* power on device */ |
531 | ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 523 | ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
532 | 524 | ||
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 1f646c6e90c6..92655cc189ae 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
@@ -465,14 +465,6 @@ static int ak4642_resume(struct snd_soc_codec *codec) | |||
465 | 465 | ||
466 | static int ak4642_probe(struct snd_soc_codec *codec) | 466 | static int ak4642_probe(struct snd_soc_codec *codec) |
467 | { | 467 | { |
468 | int ret; | ||
469 | |||
470 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
471 | if (ret < 0) { | ||
472 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
473 | return ret; | ||
474 | } | ||
475 | |||
476 | ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 468 | ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
477 | 469 | ||
478 | return 0; | 470 | return 0; |
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 25bdf6ad4a54..998fa0c5a0b9 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/i2c.h> | 16 | #include <linux/i2c.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/regmap.h> | ||
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
19 | #include <sound/soc.h> | 20 | #include <sound/soc.h> |
20 | #include <sound/initval.h> | 21 | #include <sound/initval.h> |
@@ -23,104 +24,99 @@ | |||
23 | #include "ak4671.h" | 24 | #include "ak4671.h" |
24 | 25 | ||
25 | 26 | ||
26 | /* codec private data */ | ||
27 | struct ak4671_priv { | ||
28 | enum snd_soc_control_type control_type; | ||
29 | }; | ||
30 | |||
31 | /* ak4671 register cache & default register settings */ | 27 | /* ak4671 register cache & default register settings */ |
32 | static const u8 ak4671_reg[AK4671_CACHEREGNUM] = { | 28 | static const struct reg_default ak4671_reg_defaults[] = { |
33 | 0x00, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */ | 29 | { 0x00, 0x00 }, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */ |
34 | 0xf6, /* AK4671_PLL_MODE_SELECT0 (0x01) */ | 30 | { 0x01, 0xf6 }, /* AK4671_PLL_MODE_SELECT0 (0x01) */ |
35 | 0x00, /* AK4671_PLL_MODE_SELECT1 (0x02) */ | 31 | { 0x02, 0x00 }, /* AK4671_PLL_MODE_SELECT1 (0x02) */ |
36 | 0x02, /* AK4671_FORMAT_SELECT (0x03) */ | 32 | { 0x03, 0x02 }, /* AK4671_FORMAT_SELECT (0x03) */ |
37 | 0x00, /* AK4671_MIC_SIGNAL_SELECT (0x04) */ | 33 | { 0x04, 0x00 }, /* AK4671_MIC_SIGNAL_SELECT (0x04) */ |
38 | 0x55, /* AK4671_MIC_AMP_GAIN (0x05) */ | 34 | { 0x05, 0x55 }, /* AK4671_MIC_AMP_GAIN (0x05) */ |
39 | 0x00, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */ | 35 | { 0x06, 0x00 }, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */ |
40 | 0x00, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */ | 36 | { 0x07, 0x00 }, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */ |
41 | 0xb5, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */ | 37 | { 0x08, 0xb5 }, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */ |
42 | 0x00, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */ | 38 | { 0x09, 0x00 }, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */ |
43 | 0x00, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */ | 39 | { 0x0a, 0x00 }, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */ |
44 | 0x00, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */ | 40 | { 0x0b, 0x00 }, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */ |
45 | 0x00, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */ | 41 | { 0x0c, 0x00 }, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */ |
46 | 0x00, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */ | 42 | { 0x0d, 0x00 }, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */ |
47 | 0x00, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */ | 43 | { 0x0e, 0x00 }, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */ |
48 | 0x00, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */ | 44 | { 0x0f, 0x00 }, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */ |
49 | 0x00, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */ | 45 | { 0x10, 0x00 }, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */ |
50 | 0x80, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */ | 46 | { 0x11, 0x80 }, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */ |
51 | 0x91, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */ | 47 | { 0x12, 0x91 }, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */ |
52 | 0x91, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */ | 48 | { 0x13, 0x91 }, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */ |
53 | 0xe1, /* AK4671_ALC_REFERENCE_SELECT (0x14) */ | 49 | { 0x14, 0xe1 }, /* AK4671_ALC_REFERENCE_SELECT (0x14) */ |
54 | 0x00, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */ | 50 | { 0x15, 0x00 }, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */ |
55 | 0x00, /* AK4671_ALC_TIMER_SELECT (0x16) */ | 51 | { 0x16, 0x00 }, /* AK4671_ALC_TIMER_SELECT (0x16) */ |
56 | 0x00, /* AK4671_ALC_MODE_CONTROL (0x17) */ | 52 | { 0x17, 0x00 }, /* AK4671_ALC_MODE_CONTROL (0x17) */ |
57 | 0x02, /* AK4671_MODE_CONTROL1 (0x18) */ | 53 | { 0x18, 0x02 }, /* AK4671_MODE_CONTROL1 (0x18) */ |
58 | 0x01, /* AK4671_MODE_CONTROL2 (0x19) */ | 54 | { 0x19, 0x01 }, /* AK4671_MODE_CONTROL2 (0x19) */ |
59 | 0x18, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */ | 55 | { 0x1a, 0x18 }, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */ |
60 | 0x18, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */ | 56 | { 0x1b, 0x18 }, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */ |
61 | 0x00, /* AK4671_SIDETONE_A_CONTROL (0x1c) */ | 57 | { 0x1c, 0x00 }, /* AK4671_SIDETONE_A_CONTROL (0x1c) */ |
62 | 0x02, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */ | 58 | { 0x1d, 0x02 }, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */ |
63 | 0x00, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */ | 59 | { 0x1e, 0x00 }, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */ |
64 | 0x00, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */ | 60 | { 0x1f, 0x00 }, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */ |
65 | 0x00, /* AK4671_FIL3_COEFFICIENT2 (0x20) */ | 61 | { 0x20, 0x00 }, /* AK4671_FIL3_COEFFICIENT2 (0x20) */ |
66 | 0x00, /* AK4671_FIL3_COEFFICIENT3 (0x21) */ | 62 | { 0x21, 0x00 }, /* AK4671_FIL3_COEFFICIENT3 (0x21) */ |
67 | 0x00, /* AK4671_EQ_COEFFICIENT0 (0x22) */ | 63 | { 0x22, 0x00 }, /* AK4671_EQ_COEFFICIENT0 (0x22) */ |
68 | 0x00, /* AK4671_EQ_COEFFICIENT1 (0x23) */ | 64 | { 0x23, 0x00 }, /* AK4671_EQ_COEFFICIENT1 (0x23) */ |
69 | 0x00, /* AK4671_EQ_COEFFICIENT2 (0x24) */ | 65 | { 0x24, 0x00 }, /* AK4671_EQ_COEFFICIENT2 (0x24) */ |
70 | 0x00, /* AK4671_EQ_COEFFICIENT3 (0x25) */ | 66 | { 0x25, 0x00 }, /* AK4671_EQ_COEFFICIENT3 (0x25) */ |
71 | 0x00, /* AK4671_EQ_COEFFICIENT4 (0x26) */ | 67 | { 0x26, 0x00 }, /* AK4671_EQ_COEFFICIENT4 (0x26) */ |
72 | 0x00, /* AK4671_EQ_COEFFICIENT5 (0x27) */ | 68 | { 0x27, 0x00 }, /* AK4671_EQ_COEFFICIENT5 (0x27) */ |
73 | 0xa9, /* AK4671_FIL1_COEFFICIENT0 (0x28) */ | 69 | { 0x28, 0xa9 }, /* AK4671_FIL1_COEFFICIENT0 (0x28) */ |
74 | 0x1f, /* AK4671_FIL1_COEFFICIENT1 (0x29) */ | 70 | { 0x29, 0x1f }, /* AK4671_FIL1_COEFFICIENT1 (0x29) */ |
75 | 0xad, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */ | 71 | { 0x2a, 0xad }, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */ |
76 | 0x20, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */ | 72 | { 0x2b, 0x20 }, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */ |
77 | 0x00, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */ | 73 | { 0x2c, 0x00 }, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */ |
78 | 0x00, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */ | 74 | { 0x2d, 0x00 }, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */ |
79 | 0x00, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */ | 75 | { 0x2e, 0x00 }, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */ |
80 | 0x00, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */ | 76 | { 0x2f, 0x00 }, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */ |
81 | 0x00, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */ | 77 | { 0x30, 0x00 }, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */ |
82 | 0x00, /* this register not used */ | 78 | |
83 | 0x00, /* AK4671_E1_COEFFICIENT0 (0x32) */ | 79 | { 0x32, 0x00 }, /* AK4671_E1_COEFFICIENT0 (0x32) */ |
84 | 0x00, /* AK4671_E1_COEFFICIENT1 (0x33) */ | 80 | { 0x33, 0x00 }, /* AK4671_E1_COEFFICIENT1 (0x33) */ |
85 | 0x00, /* AK4671_E1_COEFFICIENT2 (0x34) */ | 81 | { 0x34, 0x00 }, /* AK4671_E1_COEFFICIENT2 (0x34) */ |
86 | 0x00, /* AK4671_E1_COEFFICIENT3 (0x35) */ | 82 | { 0x35, 0x00 }, /* AK4671_E1_COEFFICIENT3 (0x35) */ |
87 | 0x00, /* AK4671_E1_COEFFICIENT4 (0x36) */ | 83 | { 0x36, 0x00 }, /* AK4671_E1_COEFFICIENT4 (0x36) */ |
88 | 0x00, /* AK4671_E1_COEFFICIENT5 (0x37) */ | 84 | { 0x37, 0x00 }, /* AK4671_E1_COEFFICIENT5 (0x37) */ |
89 | 0x00, /* AK4671_E2_COEFFICIENT0 (0x38) */ | 85 | { 0x38, 0x00 }, /* AK4671_E2_COEFFICIENT0 (0x38) */ |
90 | 0x00, /* AK4671_E2_COEFFICIENT1 (0x39) */ | 86 | { 0x39, 0x00 }, /* AK4671_E2_COEFFICIENT1 (0x39) */ |
91 | 0x00, /* AK4671_E2_COEFFICIENT2 (0x3a) */ | 87 | { 0x3a, 0x00 }, /* AK4671_E2_COEFFICIENT2 (0x3a) */ |
92 | 0x00, /* AK4671_E2_COEFFICIENT3 (0x3b) */ | 88 | { 0x3b, 0x00 }, /* AK4671_E2_COEFFICIENT3 (0x3b) */ |
93 | 0x00, /* AK4671_E2_COEFFICIENT4 (0x3c) */ | 89 | { 0x3c, 0x00 }, /* AK4671_E2_COEFFICIENT4 (0x3c) */ |
94 | 0x00, /* AK4671_E2_COEFFICIENT5 (0x3d) */ | 90 | { 0x3d, 0x00 }, /* AK4671_E2_COEFFICIENT5 (0x3d) */ |
95 | 0x00, /* AK4671_E3_COEFFICIENT0 (0x3e) */ | 91 | { 0x3e, 0x00 }, /* AK4671_E3_COEFFICIENT0 (0x3e) */ |
96 | 0x00, /* AK4671_E3_COEFFICIENT1 (0x3f) */ | 92 | { 0x3f, 0x00 }, /* AK4671_E3_COEFFICIENT1 (0x3f) */ |
97 | 0x00, /* AK4671_E3_COEFFICIENT2 (0x40) */ | 93 | { 0x40, 0x00 }, /* AK4671_E3_COEFFICIENT2 (0x40) */ |
98 | 0x00, /* AK4671_E3_COEFFICIENT3 (0x41) */ | 94 | { 0x41, 0x00 }, /* AK4671_E3_COEFFICIENT3 (0x41) */ |
99 | 0x00, /* AK4671_E3_COEFFICIENT4 (0x42) */ | 95 | { 0x42, 0x00 }, /* AK4671_E3_COEFFICIENT4 (0x42) */ |
100 | 0x00, /* AK4671_E3_COEFFICIENT5 (0x43) */ | 96 | { 0x43, 0x00 }, /* AK4671_E3_COEFFICIENT5 (0x43) */ |
101 | 0x00, /* AK4671_E4_COEFFICIENT0 (0x44) */ | 97 | { 0x44, 0x00 }, /* AK4671_E4_COEFFICIENT0 (0x44) */ |
102 | 0x00, /* AK4671_E4_COEFFICIENT1 (0x45) */ | 98 | { 0x45, 0x00 }, /* AK4671_E4_COEFFICIENT1 (0x45) */ |
103 | 0x00, /* AK4671_E4_COEFFICIENT2 (0x46) */ | 99 | { 0x46, 0x00 }, /* AK4671_E4_COEFFICIENT2 (0x46) */ |
104 | 0x00, /* AK4671_E4_COEFFICIENT3 (0x47) */ | 100 | { 0x47, 0x00 }, /* AK4671_E4_COEFFICIENT3 (0x47) */ |
105 | 0x00, /* AK4671_E4_COEFFICIENT4 (0x48) */ | 101 | { 0x48, 0x00 }, /* AK4671_E4_COEFFICIENT4 (0x48) */ |
106 | 0x00, /* AK4671_E4_COEFFICIENT5 (0x49) */ | 102 | { 0x49, 0x00 }, /* AK4671_E4_COEFFICIENT5 (0x49) */ |
107 | 0x00, /* AK4671_E5_COEFFICIENT0 (0x4a) */ | 103 | { 0x4a, 0x00 }, /* AK4671_E5_COEFFICIENT0 (0x4a) */ |
108 | 0x00, /* AK4671_E5_COEFFICIENT1 (0x4b) */ | 104 | { 0x4b, 0x00 }, /* AK4671_E5_COEFFICIENT1 (0x4b) */ |
109 | 0x00, /* AK4671_E5_COEFFICIENT2 (0x4c) */ | 105 | { 0x4c, 0x00 }, /* AK4671_E5_COEFFICIENT2 (0x4c) */ |
110 | 0x00, /* AK4671_E5_COEFFICIENT3 (0x4d) */ | 106 | { 0x4d, 0x00 }, /* AK4671_E5_COEFFICIENT3 (0x4d) */ |
111 | 0x00, /* AK4671_E5_COEFFICIENT4 (0x4e) */ | 107 | { 0x4e, 0x00 }, /* AK4671_E5_COEFFICIENT4 (0x4e) */ |
112 | 0x00, /* AK4671_E5_COEFFICIENT5 (0x4f) */ | 108 | { 0x4f, 0x00 }, /* AK4671_E5_COEFFICIENT5 (0x4f) */ |
113 | 0x88, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */ | 109 | { 0x50, 0x88 }, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */ |
114 | 0x88, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */ | 110 | { 0x51, 0x88 }, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */ |
115 | 0x08, /* AK4671_EQ_CONTRO_10KHZ (0x52) */ | 111 | { 0x52, 0x08 }, /* AK4671_EQ_CONTRO_10KHZ (0x52) */ |
116 | 0x00, /* AK4671_PCM_IF_CONTROL0 (0x53) */ | 112 | { 0x53, 0x00 }, /* AK4671_PCM_IF_CONTROL0 (0x53) */ |
117 | 0x00, /* AK4671_PCM_IF_CONTROL1 (0x54) */ | 113 | { 0x54, 0x00 }, /* AK4671_PCM_IF_CONTROL1 (0x54) */ |
118 | 0x00, /* AK4671_PCM_IF_CONTROL2 (0x55) */ | 114 | { 0x55, 0x00 }, /* AK4671_PCM_IF_CONTROL2 (0x55) */ |
119 | 0x18, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */ | 115 | { 0x56, 0x18 }, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */ |
120 | 0x18, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */ | 116 | { 0x57, 0x18 }, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */ |
121 | 0x00, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */ | 117 | { 0x58, 0x00 }, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */ |
122 | 0x00, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */ | 118 | { 0x59, 0x00 }, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */ |
123 | 0x00, /* AK4671_SAR_ADC_CONTROL (0x5a) */ | 119 | { 0x5a, 0x00 }, /* AK4671_SAR_ADC_CONTROL (0x5a) */ |
124 | }; | 120 | }; |
125 | 121 | ||
126 | /* | 122 | /* |
@@ -241,19 +237,17 @@ static const struct snd_kcontrol_new ak4671_rout3_mixer_controls[] = { | |||
241 | /* Input MUXs */ | 237 | /* Input MUXs */ |
242 | static const char *ak4671_lin_mux_texts[] = | 238 | static const char *ak4671_lin_mux_texts[] = |
243 | {"LIN1", "LIN2", "LIN3", "LIN4"}; | 239 | {"LIN1", "LIN2", "LIN3", "LIN4"}; |
244 | static const struct soc_enum ak4671_lin_mux_enum = | 240 | static SOC_ENUM_SINGLE_DECL(ak4671_lin_mux_enum, |
245 | SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 0, | 241 | AK4671_MIC_SIGNAL_SELECT, 0, |
246 | ARRAY_SIZE(ak4671_lin_mux_texts), | 242 | ak4671_lin_mux_texts); |
247 | ak4671_lin_mux_texts); | ||
248 | static const struct snd_kcontrol_new ak4671_lin_mux_control = | 243 | static const struct snd_kcontrol_new ak4671_lin_mux_control = |
249 | SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum); | 244 | SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum); |
250 | 245 | ||
251 | static const char *ak4671_rin_mux_texts[] = | 246 | static const char *ak4671_rin_mux_texts[] = |
252 | {"RIN1", "RIN2", "RIN3", "RIN4"}; | 247 | {"RIN1", "RIN2", "RIN3", "RIN4"}; |
253 | static const struct soc_enum ak4671_rin_mux_enum = | 248 | static SOC_ENUM_SINGLE_DECL(ak4671_rin_mux_enum, |
254 | SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 2, | 249 | AK4671_MIC_SIGNAL_SELECT, 2, |
255 | ARRAY_SIZE(ak4671_rin_mux_texts), | 250 | ak4671_rin_mux_texts); |
256 | ak4671_rin_mux_texts); | ||
257 | static const struct snd_kcontrol_new ak4671_rin_mux_control = | 251 | static const struct snd_kcontrol_new ak4671_rin_mux_control = |
258 | SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum); | 252 | SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum); |
259 | 253 | ||
@@ -619,21 +613,7 @@ static struct snd_soc_dai_driver ak4671_dai = { | |||
619 | 613 | ||
620 | static int ak4671_probe(struct snd_soc_codec *codec) | 614 | static int ak4671_probe(struct snd_soc_codec *codec) |
621 | { | 615 | { |
622 | struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec); | 616 | return ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
623 | int ret; | ||
624 | |||
625 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type); | ||
626 | if (ret < 0) { | ||
627 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
628 | return ret; | ||
629 | } | ||
630 | |||
631 | snd_soc_add_codec_controls(codec, ak4671_snd_controls, | ||
632 | ARRAY_SIZE(ak4671_snd_controls)); | ||
633 | |||
634 | ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
635 | |||
636 | return ret; | ||
637 | } | 617 | } |
638 | 618 | ||
639 | static int ak4671_remove(struct snd_soc_codec *codec) | 619 | static int ak4671_remove(struct snd_soc_codec *codec) |
@@ -646,28 +626,36 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { | |||
646 | .probe = ak4671_probe, | 626 | .probe = ak4671_probe, |
647 | .remove = ak4671_remove, | 627 | .remove = ak4671_remove, |
648 | .set_bias_level = ak4671_set_bias_level, | 628 | .set_bias_level = ak4671_set_bias_level, |
649 | .reg_cache_size = AK4671_CACHEREGNUM, | 629 | .controls = ak4671_snd_controls, |
650 | .reg_word_size = sizeof(u8), | 630 | .num_controls = ARRAY_SIZE(ak4671_snd_controls), |
651 | .reg_cache_default = ak4671_reg, | ||
652 | .dapm_widgets = ak4671_dapm_widgets, | 631 | .dapm_widgets = ak4671_dapm_widgets, |
653 | .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets), | 632 | .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets), |
654 | .dapm_routes = ak4671_intercon, | 633 | .dapm_routes = ak4671_intercon, |
655 | .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), | 634 | .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), |
656 | }; | 635 | }; |
657 | 636 | ||
637 | static const struct regmap_config ak4671_regmap = { | ||
638 | .reg_bits = 8, | ||
639 | .val_bits = 8, | ||
640 | |||
641 | .max_register = AK4671_SAR_ADC_CONTROL, | ||
642 | .reg_defaults = ak4671_reg_defaults, | ||
643 | .num_reg_defaults = ARRAY_SIZE(ak4671_reg_defaults), | ||
644 | .cache_type = REGCACHE_RBTREE, | ||
645 | }; | ||
646 | |||
658 | static int ak4671_i2c_probe(struct i2c_client *client, | 647 | static int ak4671_i2c_probe(struct i2c_client *client, |
659 | const struct i2c_device_id *id) | 648 | const struct i2c_device_id *id) |
660 | { | 649 | { |
661 | struct ak4671_priv *ak4671; | 650 | struct regmap *regmap; |
662 | int ret; | 651 | int ret; |
663 | 652 | ||
664 | ak4671 = devm_kzalloc(&client->dev, sizeof(struct ak4671_priv), | 653 | regmap = devm_regmap_init_i2c(client, &ak4671_regmap); |
665 | GFP_KERNEL); | 654 | if (IS_ERR(regmap)) { |
666 | if (ak4671 == NULL) | 655 | ret = PTR_ERR(regmap); |
667 | return -ENOMEM; | 656 | dev_err(&client->dev, "Failed to create regmap: %d\n", ret); |
668 | 657 | return ret; | |
669 | i2c_set_clientdata(client, ak4671); | 658 | } |
670 | ak4671->control_type = SND_SOC_I2C; | ||
671 | 659 | ||
672 | ret = snd_soc_register_codec(&client->dev, | 660 | ret = snd_soc_register_codec(&client->dev, |
673 | &soc_codec_dev_ak4671, &ak4671_dai, 1); | 661 | &soc_codec_dev_ak4671, &ak4671_dai, 1); |
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h index 61cb7ab7552c..394a34d3f50a 100644 --- a/sound/soc/codecs/ak4671.h +++ b/sound/soc/codecs/ak4671.h | |||
@@ -105,8 +105,6 @@ | |||
105 | #define AK4671_DIGITAL_MIXING_CONTROL2 0x59 | 105 | #define AK4671_DIGITAL_MIXING_CONTROL2 0x59 |
106 | #define AK4671_SAR_ADC_CONTROL 0x5a | 106 | #define AK4671_SAR_ADC_CONTROL 0x5a |
107 | 107 | ||
108 | #define AK4671_CACHEREGNUM (AK4671_SAR_ADC_CONTROL + 1) | ||
109 | |||
110 | /* Bitfield Definitions */ | 108 | /* Bitfield Definitions */ |
111 | 109 | ||
112 | /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */ | 110 | /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */ |
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index d3036283482a..09f7e773bafb 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/pm.h> | 22 | #include <linux/pm.h> |
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include <linux/regmap.h> | ||
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
25 | #include <sound/core.h> | 26 | #include <sound/core.h> |
26 | #include <sound/pcm.h> | 27 | #include <sound/pcm.h> |
@@ -38,26 +39,13 @@ MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)"); | |||
38 | 39 | ||
39 | /* codec private data */ | 40 | /* codec private data */ |
40 | struct alc5623_priv { | 41 | struct alc5623_priv { |
41 | enum snd_soc_control_type control_type; | 42 | struct regmap *regmap; |
42 | u8 id; | 43 | u8 id; |
43 | unsigned int sysclk; | 44 | unsigned int sysclk; |
44 | u16 reg_cache[ALC5623_VENDOR_ID2+2]; | ||
45 | unsigned int add_ctrl; | 45 | unsigned int add_ctrl; |
46 | unsigned int jack_det_ctrl; | 46 | unsigned int jack_det_ctrl; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static void alc5623_fill_cache(struct snd_soc_codec *codec) | ||
50 | { | ||
51 | int i, step = codec->driver->reg_cache_step; | ||
52 | u16 *cache = codec->reg_cache; | ||
53 | |||
54 | /* not really efficient ... */ | ||
55 | codec->cache_bypass = 1; | ||
56 | for (i = 0 ; i < codec->driver->reg_cache_size ; i += step) | ||
57 | cache[i] = snd_soc_read(codec, i); | ||
58 | codec->cache_bypass = 0; | ||
59 | } | ||
60 | |||
61 | static inline int alc5623_reset(struct snd_soc_codec *codec) | 49 | static inline int alc5623_reset(struct snd_soc_codec *codec) |
62 | { | 50 | { |
63 | return snd_soc_write(codec, ALC5623_RESET, 0); | 51 | return snd_soc_write(codec, ALC5623_RESET, 0); |
@@ -228,32 +216,37 @@ static const char *alc5623_aux_out_input_sel[] = { | |||
228 | "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; | 216 | "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; |
229 | 217 | ||
230 | /* auxout output mux */ | 218 | /* auxout output mux */ |
231 | static const struct soc_enum alc5623_aux_out_input_enum = | 219 | static SOC_ENUM_SINGLE_DECL(alc5623_aux_out_input_enum, |
232 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 6, 4, alc5623_aux_out_input_sel); | 220 | ALC5623_OUTPUT_MIXER_CTRL, 6, |
221 | alc5623_aux_out_input_sel); | ||
233 | static const struct snd_kcontrol_new alc5623_auxout_mux_controls = | 222 | static const struct snd_kcontrol_new alc5623_auxout_mux_controls = |
234 | SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum); | 223 | SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum); |
235 | 224 | ||
236 | /* speaker output mux */ | 225 | /* speaker output mux */ |
237 | static const struct soc_enum alc5623_spkout_input_enum = | 226 | static SOC_ENUM_SINGLE_DECL(alc5623_spkout_input_enum, |
238 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel); | 227 | ALC5623_OUTPUT_MIXER_CTRL, 10, |
228 | alc5623_spkout_input_sel); | ||
239 | static const struct snd_kcontrol_new alc5623_spkout_mux_controls = | 229 | static const struct snd_kcontrol_new alc5623_spkout_mux_controls = |
240 | SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum); | 230 | SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum); |
241 | 231 | ||
242 | /* headphone left output mux */ | 232 | /* headphone left output mux */ |
243 | static const struct soc_enum alc5623_hpl_out_input_enum = | 233 | static SOC_ENUM_SINGLE_DECL(alc5623_hpl_out_input_enum, |
244 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 9, 2, alc5623_hpl_out_input_sel); | 234 | ALC5623_OUTPUT_MIXER_CTRL, 9, |
235 | alc5623_hpl_out_input_sel); | ||
245 | static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls = | 236 | static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls = |
246 | SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum); | 237 | SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum); |
247 | 238 | ||
248 | /* headphone right output mux */ | 239 | /* headphone right output mux */ |
249 | static const struct soc_enum alc5623_hpr_out_input_enum = | 240 | static SOC_ENUM_SINGLE_DECL(alc5623_hpr_out_input_enum, |
250 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 8, 2, alc5623_hpr_out_input_sel); | 241 | ALC5623_OUTPUT_MIXER_CTRL, 8, |
242 | alc5623_hpr_out_input_sel); | ||
251 | static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls = | 243 | static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls = |
252 | SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum); | 244 | SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum); |
253 | 245 | ||
254 | /* speaker output N select */ | 246 | /* speaker output N select */ |
255 | static const struct soc_enum alc5623_spk_n_sour_enum = | 247 | static SOC_ENUM_SINGLE_DECL(alc5623_spk_n_sour_enum, |
256 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 14, 4, alc5623_spk_n_sour_sel); | 248 | ALC5623_OUTPUT_MIXER_CTRL, 14, |
249 | alc5623_spk_n_sour_sel); | ||
257 | static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls = | 250 | static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls = |
258 | SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum); | 251 | SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum); |
259 | 252 | ||
@@ -338,8 +331,9 @@ SND_SOC_DAPM_VMID("Vmid"), | |||
338 | }; | 331 | }; |
339 | 332 | ||
340 | static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"}; | 333 | static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"}; |
341 | static const struct soc_enum alc5623_amp_enum = | 334 | static SOC_ENUM_SINGLE_DECL(alc5623_amp_enum, |
342 | SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 13, 2, alc5623_amp_names); | 335 | ALC5623_OUTPUT_MIXER_CTRL, 13, |
336 | alc5623_amp_names); | ||
343 | static const struct snd_kcontrol_new alc5623_amp_mux_controls = | 337 | static const struct snd_kcontrol_new alc5623_amp_mux_controls = |
344 | SOC_DAPM_ENUM("Route", alc5623_amp_enum); | 338 | SOC_DAPM_ENUM("Route", alc5623_amp_enum); |
345 | 339 | ||
@@ -869,18 +863,28 @@ static struct snd_soc_dai_driver alc5623_dai = { | |||
869 | 863 | ||
870 | static int alc5623_suspend(struct snd_soc_codec *codec) | 864 | static int alc5623_suspend(struct snd_soc_codec *codec) |
871 | { | 865 | { |
866 | struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); | ||
867 | |||
872 | alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); | 868 | alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); |
869 | regcache_cache_only(alc5623->regmap, true); | ||
870 | |||
873 | return 0; | 871 | return 0; |
874 | } | 872 | } |
875 | 873 | ||
876 | static int alc5623_resume(struct snd_soc_codec *codec) | 874 | static int alc5623_resume(struct snd_soc_codec *codec) |
877 | { | 875 | { |
878 | int i, step = codec->driver->reg_cache_step; | 876 | struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); |
879 | u16 *cache = codec->reg_cache; | 877 | int ret; |
880 | 878 | ||
881 | /* Sync reg_cache with the hardware */ | 879 | /* Sync reg_cache with the hardware */ |
882 | for (i = 2 ; i < codec->driver->reg_cache_size ; i += step) | 880 | regcache_cache_only(alc5623->regmap, false); |
883 | snd_soc_write(codec, i, cache[i]); | 881 | ret = regcache_sync(alc5623->regmap); |
882 | if (ret != 0) { | ||
883 | dev_err(codec->dev, "Failed to sync register cache: %d\n", | ||
884 | ret); | ||
885 | regcache_cache_only(alc5623->regmap, true); | ||
886 | return ret; | ||
887 | } | ||
884 | 888 | ||
885 | alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 889 | alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
886 | 890 | ||
@@ -900,14 +904,7 @@ static int alc5623_probe(struct snd_soc_codec *codec) | |||
900 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 904 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
901 | int ret; | 905 | int ret; |
902 | 906 | ||
903 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type); | ||
904 | if (ret < 0) { | ||
905 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
906 | return ret; | ||
907 | } | ||
908 | |||
909 | alc5623_reset(codec); | 907 | alc5623_reset(codec); |
910 | alc5623_fill_cache(codec); | ||
911 | 908 | ||
912 | /* power on device */ | 909 | /* power on device */ |
913 | alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 910 | alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
@@ -980,9 +977,15 @@ static struct snd_soc_codec_driver soc_codec_device_alc5623 = { | |||
980 | .suspend = alc5623_suspend, | 977 | .suspend = alc5623_suspend, |
981 | .resume = alc5623_resume, | 978 | .resume = alc5623_resume, |
982 | .set_bias_level = alc5623_set_bias_level, | 979 | .set_bias_level = alc5623_set_bias_level, |
983 | .reg_cache_size = ALC5623_VENDOR_ID2+2, | 980 | }; |
984 | .reg_word_size = sizeof(u16), | 981 | |
985 | .reg_cache_step = 2, | 982 | static const struct regmap_config alc5623_regmap = { |
983 | .reg_bits = 8, | ||
984 | .val_bits = 16, | ||
985 | .reg_stride = 2, | ||
986 | |||
987 | .max_register = ALC5623_VENDOR_ID2, | ||
988 | .cache_type = REGCACHE_RBTREE, | ||
986 | }; | 989 | }; |
987 | 990 | ||
988 | /* | 991 | /* |
@@ -996,19 +999,32 @@ static int alc5623_i2c_probe(struct i2c_client *client, | |||
996 | { | 999 | { |
997 | struct alc5623_platform_data *pdata; | 1000 | struct alc5623_platform_data *pdata; |
998 | struct alc5623_priv *alc5623; | 1001 | struct alc5623_priv *alc5623; |
999 | int ret, vid1, vid2; | 1002 | unsigned int vid1, vid2; |
1003 | int ret; | ||
1000 | 1004 | ||
1001 | vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1); | 1005 | alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv), |
1002 | if (vid1 < 0) { | 1006 | GFP_KERNEL); |
1003 | dev_err(&client->dev, "failed to read I2C\n"); | 1007 | if (alc5623 == NULL) |
1004 | return -EIO; | 1008 | return -ENOMEM; |
1009 | |||
1010 | alc5623->regmap = devm_regmap_init_i2c(client, &alc5623_regmap); | ||
1011 | if (IS_ERR(alc5623->regmap)) { | ||
1012 | ret = PTR_ERR(alc5623->regmap); | ||
1013 | dev_err(&client->dev, "Failed to initialise I/O: %d\n", ret); | ||
1014 | return ret; | ||
1015 | } | ||
1016 | |||
1017 | ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID1, &vid1); | ||
1018 | if (ret < 0) { | ||
1019 | dev_err(&client->dev, "failed to read vendor ID1: %d\n", ret); | ||
1020 | return ret; | ||
1005 | } | 1021 | } |
1006 | vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8); | 1022 | vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8); |
1007 | 1023 | ||
1008 | vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2); | 1024 | ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID2, &vid2); |
1009 | if (vid2 < 0) { | 1025 | if (ret < 0) { |
1010 | dev_err(&client->dev, "failed to read I2C\n"); | 1026 | dev_err(&client->dev, "failed to read vendor ID2: %d\n", ret); |
1011 | return -EIO; | 1027 | return ret; |
1012 | } | 1028 | } |
1013 | 1029 | ||
1014 | if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { | 1030 | if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { |
@@ -1021,11 +1037,6 @@ static int alc5623_i2c_probe(struct i2c_client *client, | |||
1021 | 1037 | ||
1022 | dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2); | 1038 | dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2); |
1023 | 1039 | ||
1024 | alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv), | ||
1025 | GFP_KERNEL); | ||
1026 | if (alc5623 == NULL) | ||
1027 | return -ENOMEM; | ||
1028 | |||
1029 | pdata = client->dev.platform_data; | 1040 | pdata = client->dev.platform_data; |
1030 | if (pdata) { | 1041 | if (pdata) { |
1031 | alc5623->add_ctrl = pdata->add_ctrl; | 1042 | alc5623->add_ctrl = pdata->add_ctrl; |
@@ -1048,7 +1059,6 @@ static int alc5623_i2c_probe(struct i2c_client *client, | |||
1048 | } | 1059 | } |
1049 | 1060 | ||
1050 | i2c_set_clientdata(client, alc5623); | 1061 | i2c_set_clientdata(client, alc5623); |
1051 | alc5623->control_type = SND_SOC_I2C; | ||
1052 | 1062 | ||
1053 | ret = snd_soc_register_codec(&client->dev, | 1063 | ret = snd_soc_register_codec(&client->dev, |
1054 | &soc_codec_device_alc5623, &alc5623_dai, 1); | 1064 | &soc_codec_device_alc5623, &alc5623_dai, 1); |
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index fb001c56cf8d..ec071a6306ef 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c | |||
@@ -293,51 +293,59 @@ static const char * const alc5632_i2s_out_sel[] = { | |||
293 | "ADC LR", "Voice Stereo Digital"}; | 293 | "ADC LR", "Voice Stereo Digital"}; |
294 | 294 | ||
295 | /* auxout output mux */ | 295 | /* auxout output mux */ |
296 | static const struct soc_enum alc5632_aux_out_input_enum = | 296 | static SOC_ENUM_SINGLE_DECL(alc5632_aux_out_input_enum, |
297 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 6, 4, alc5632_aux_out_input_sel); | 297 | ALC5632_OUTPUT_MIXER_CTRL, 6, |
298 | alc5632_aux_out_input_sel); | ||
298 | static const struct snd_kcontrol_new alc5632_auxout_mux_controls = | 299 | static const struct snd_kcontrol_new alc5632_auxout_mux_controls = |
299 | SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum); | 300 | SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum); |
300 | 301 | ||
301 | /* speaker output mux */ | 302 | /* speaker output mux */ |
302 | static const struct soc_enum alc5632_spkout_input_enum = | 303 | static SOC_ENUM_SINGLE_DECL(alc5632_spkout_input_enum, |
303 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 10, 4, alc5632_spkout_input_sel); | 304 | ALC5632_OUTPUT_MIXER_CTRL, 10, |
305 | alc5632_spkout_input_sel); | ||
304 | static const struct snd_kcontrol_new alc5632_spkout_mux_controls = | 306 | static const struct snd_kcontrol_new alc5632_spkout_mux_controls = |
305 | SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum); | 307 | SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum); |
306 | 308 | ||
307 | /* headphone left output mux */ | 309 | /* headphone left output mux */ |
308 | static const struct soc_enum alc5632_hpl_out_input_enum = | 310 | static SOC_ENUM_SINGLE_DECL(alc5632_hpl_out_input_enum, |
309 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 9, 2, alc5632_hpl_out_input_sel); | 311 | ALC5632_OUTPUT_MIXER_CTRL, 9, |
312 | alc5632_hpl_out_input_sel); | ||
310 | static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls = | 313 | static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls = |
311 | SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum); | 314 | SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum); |
312 | 315 | ||
313 | /* headphone right output mux */ | 316 | /* headphone right output mux */ |
314 | static const struct soc_enum alc5632_hpr_out_input_enum = | 317 | static SOC_ENUM_SINGLE_DECL(alc5632_hpr_out_input_enum, |
315 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 8, 2, alc5632_hpr_out_input_sel); | 318 | ALC5632_OUTPUT_MIXER_CTRL, 8, |
319 | alc5632_hpr_out_input_sel); | ||
316 | static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls = | 320 | static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls = |
317 | SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum); | 321 | SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum); |
318 | 322 | ||
319 | /* speaker output N select */ | 323 | /* speaker output N select */ |
320 | static const struct soc_enum alc5632_spk_n_sour_enum = | 324 | static SOC_ENUM_SINGLE_DECL(alc5632_spk_n_sour_enum, |
321 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 14, 4, alc5632_spk_n_sour_sel); | 325 | ALC5632_OUTPUT_MIXER_CTRL, 14, |
326 | alc5632_spk_n_sour_sel); | ||
322 | static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls = | 327 | static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls = |
323 | SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum); | 328 | SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum); |
324 | 329 | ||
325 | /* speaker amplifier */ | 330 | /* speaker amplifier */ |
326 | static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"}; | 331 | static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"}; |
327 | static const struct soc_enum alc5632_amp_enum = | 332 | static SOC_ENUM_SINGLE_DECL(alc5632_amp_enum, |
328 | SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 13, 2, alc5632_amp_names); | 333 | ALC5632_OUTPUT_MIXER_CTRL, 13, |
334 | alc5632_amp_names); | ||
329 | static const struct snd_kcontrol_new alc5632_amp_mux_controls = | 335 | static const struct snd_kcontrol_new alc5632_amp_mux_controls = |
330 | SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); | 336 | SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); |
331 | 337 | ||
332 | /* ADC output select */ | 338 | /* ADC output select */ |
333 | static const struct soc_enum alc5632_adcr_func_enum = | 339 | static SOC_ENUM_SINGLE_DECL(alc5632_adcr_func_enum, |
334 | SOC_ENUM_SINGLE(ALC5632_DAC_FUNC_SELECT, 5, 2, alc5632_adcr_func_sel); | 340 | ALC5632_DAC_FUNC_SELECT, 5, |
341 | alc5632_adcr_func_sel); | ||
335 | static const struct snd_kcontrol_new alc5632_adcr_func_controls = | 342 | static const struct snd_kcontrol_new alc5632_adcr_func_controls = |
336 | SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum); | 343 | SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum); |
337 | 344 | ||
338 | /* I2S out select */ | 345 | /* I2S out select */ |
339 | static const struct soc_enum alc5632_i2s_out_enum = | 346 | static SOC_ENUM_SINGLE_DECL(alc5632_i2s_out_enum, |
340 | SOC_ENUM_SINGLE(ALC5632_I2S_OUT_CTL, 5, 2, alc5632_i2s_out_sel); | 347 | ALC5632_I2S_OUT_CTL, 5, |
348 | alc5632_i2s_out_sel); | ||
341 | static const struct snd_kcontrol_new alc5632_i2s_out_controls = | 349 | static const struct snd_kcontrol_new alc5632_i2s_out_controls = |
342 | SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum); | 350 | SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum); |
343 | 351 | ||
@@ -1055,14 +1063,6 @@ static int alc5632_probe(struct snd_soc_codec *codec) | |||
1055 | struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); | 1063 | struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); |
1056 | int ret; | 1064 | int ret; |
1057 | 1065 | ||
1058 | codec->control_data = alc5632->regmap; | ||
1059 | |||
1060 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1061 | if (ret != 0) { | ||
1062 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1063 | return ret; | ||
1064 | } | ||
1065 | |||
1066 | /* power on device */ | 1066 | /* power on device */ |
1067 | alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1067 | alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1068 | 1068 | ||
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index e4295fee8f13..29e198f57d4c 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -53,6 +53,14 @@ | |||
53 | #define ARIZONA_AIF_RX_ENABLES 0x1A | 53 | #define ARIZONA_AIF_RX_ENABLES 0x1A |
54 | #define ARIZONA_AIF_FORCE_WRITE 0x1B | 54 | #define ARIZONA_AIF_FORCE_WRITE 0x1B |
55 | 55 | ||
56 | #define ARIZONA_FLL_VCO_CORNER 141900000 | ||
57 | #define ARIZONA_FLL_MAX_FREF 13500000 | ||
58 | #define ARIZONA_FLL_MIN_FVCO 90000000 | ||
59 | #define ARIZONA_FLL_MAX_FRATIO 16 | ||
60 | #define ARIZONA_FLL_MAX_REFDIV 8 | ||
61 | #define ARIZONA_FLL_MIN_OUTDIV 2 | ||
62 | #define ARIZONA_FLL_MAX_OUTDIV 7 | ||
63 | |||
56 | #define arizona_fll_err(_fll, fmt, ...) \ | 64 | #define arizona_fll_err(_fll, fmt, ...) \ |
57 | dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) | 65 | dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) |
58 | #define arizona_fll_warn(_fll, fmt, ...) \ | 66 | #define arizona_fll_warn(_fll, fmt, ...) \ |
@@ -542,67 +550,76 @@ static const char *arizona_vol_ramp_text[] = { | |||
542 | "15ms/6dB", "30ms/6dB", | 550 | "15ms/6dB", "30ms/6dB", |
543 | }; | 551 | }; |
544 | 552 | ||
545 | const struct soc_enum arizona_in_vd_ramp = | 553 | SOC_ENUM_SINGLE_DECL(arizona_in_vd_ramp, |
546 | SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, | 554 | ARIZONA_INPUT_VOLUME_RAMP, |
547 | ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); | 555 | ARIZONA_IN_VD_RAMP_SHIFT, |
556 | arizona_vol_ramp_text); | ||
548 | EXPORT_SYMBOL_GPL(arizona_in_vd_ramp); | 557 | EXPORT_SYMBOL_GPL(arizona_in_vd_ramp); |
549 | 558 | ||
550 | const struct soc_enum arizona_in_vi_ramp = | 559 | SOC_ENUM_SINGLE_DECL(arizona_in_vi_ramp, |
551 | SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, | 560 | ARIZONA_INPUT_VOLUME_RAMP, |
552 | ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); | 561 | ARIZONA_IN_VI_RAMP_SHIFT, |
562 | arizona_vol_ramp_text); | ||
553 | EXPORT_SYMBOL_GPL(arizona_in_vi_ramp); | 563 | EXPORT_SYMBOL_GPL(arizona_in_vi_ramp); |
554 | 564 | ||
555 | const struct soc_enum arizona_out_vd_ramp = | 565 | SOC_ENUM_SINGLE_DECL(arizona_out_vd_ramp, |
556 | SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, | 566 | ARIZONA_OUTPUT_VOLUME_RAMP, |
557 | ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); | 567 | ARIZONA_OUT_VD_RAMP_SHIFT, |
568 | arizona_vol_ramp_text); | ||
558 | EXPORT_SYMBOL_GPL(arizona_out_vd_ramp); | 569 | EXPORT_SYMBOL_GPL(arizona_out_vd_ramp); |
559 | 570 | ||
560 | const struct soc_enum arizona_out_vi_ramp = | 571 | SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp, |
561 | SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, | 572 | ARIZONA_OUTPUT_VOLUME_RAMP, |
562 | ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); | 573 | ARIZONA_OUT_VI_RAMP_SHIFT, |
574 | arizona_vol_ramp_text); | ||
563 | EXPORT_SYMBOL_GPL(arizona_out_vi_ramp); | 575 | EXPORT_SYMBOL_GPL(arizona_out_vi_ramp); |
564 | 576 | ||
565 | static const char *arizona_lhpf_mode_text[] = { | 577 | static const char *arizona_lhpf_mode_text[] = { |
566 | "Low-pass", "High-pass" | 578 | "Low-pass", "High-pass" |
567 | }; | 579 | }; |
568 | 580 | ||
569 | const struct soc_enum arizona_lhpf1_mode = | 581 | SOC_ENUM_SINGLE_DECL(arizona_lhpf1_mode, |
570 | SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2, | 582 | ARIZONA_HPLPF1_1, |
571 | arizona_lhpf_mode_text); | 583 | ARIZONA_LHPF1_MODE_SHIFT, |
584 | arizona_lhpf_mode_text); | ||
572 | EXPORT_SYMBOL_GPL(arizona_lhpf1_mode); | 585 | EXPORT_SYMBOL_GPL(arizona_lhpf1_mode); |
573 | 586 | ||
574 | const struct soc_enum arizona_lhpf2_mode = | 587 | SOC_ENUM_SINGLE_DECL(arizona_lhpf2_mode, |
575 | SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2, | 588 | ARIZONA_HPLPF2_1, |
576 | arizona_lhpf_mode_text); | 589 | ARIZONA_LHPF2_MODE_SHIFT, |
590 | arizona_lhpf_mode_text); | ||
577 | EXPORT_SYMBOL_GPL(arizona_lhpf2_mode); | 591 | EXPORT_SYMBOL_GPL(arizona_lhpf2_mode); |
578 | 592 | ||
579 | const struct soc_enum arizona_lhpf3_mode = | 593 | SOC_ENUM_SINGLE_DECL(arizona_lhpf3_mode, |
580 | SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2, | 594 | ARIZONA_HPLPF3_1, |
581 | arizona_lhpf_mode_text); | 595 | ARIZONA_LHPF3_MODE_SHIFT, |
596 | arizona_lhpf_mode_text); | ||
582 | EXPORT_SYMBOL_GPL(arizona_lhpf3_mode); | 597 | EXPORT_SYMBOL_GPL(arizona_lhpf3_mode); |
583 | 598 | ||
584 | const struct soc_enum arizona_lhpf4_mode = | 599 | SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode, |
585 | SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2, | 600 | ARIZONA_HPLPF4_1, |
586 | arizona_lhpf_mode_text); | 601 | ARIZONA_LHPF4_MODE_SHIFT, |
602 | arizona_lhpf_mode_text); | ||
587 | EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); | 603 | EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); |
588 | 604 | ||
589 | static const char *arizona_ng_hold_text[] = { | 605 | static const char *arizona_ng_hold_text[] = { |
590 | "30ms", "120ms", "250ms", "500ms", | 606 | "30ms", "120ms", "250ms", "500ms", |
591 | }; | 607 | }; |
592 | 608 | ||
593 | const struct soc_enum arizona_ng_hold = | 609 | SOC_ENUM_SINGLE_DECL(arizona_ng_hold, |
594 | SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT, | 610 | ARIZONA_NOISE_GATE_CONTROL, |
595 | 4, arizona_ng_hold_text); | 611 | ARIZONA_NGATE_HOLD_SHIFT, |
612 | arizona_ng_hold_text); | ||
596 | EXPORT_SYMBOL_GPL(arizona_ng_hold); | 613 | EXPORT_SYMBOL_GPL(arizona_ng_hold); |
597 | 614 | ||
598 | static const char * const arizona_in_hpf_cut_text[] = { | 615 | static const char * const arizona_in_hpf_cut_text[] = { |
599 | "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz" | 616 | "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz" |
600 | }; | 617 | }; |
601 | 618 | ||
602 | const struct soc_enum arizona_in_hpf_cut_enum = | 619 | SOC_ENUM_SINGLE_DECL(arizona_in_hpf_cut_enum, |
603 | SOC_ENUM_SINGLE(ARIZONA_HPF_CONTROL, ARIZONA_IN_HPF_CUT_SHIFT, | 620 | ARIZONA_HPF_CONTROL, |
604 | ARRAY_SIZE(arizona_in_hpf_cut_text), | 621 | ARIZONA_IN_HPF_CUT_SHIFT, |
605 | arizona_in_hpf_cut_text); | 622 | arizona_in_hpf_cut_text); |
606 | EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum); | 623 | EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum); |
607 | 624 | ||
608 | static const char * const arizona_in_dmic_osr_text[] = { | 625 | static const char * const arizona_in_dmic_osr_text[] = { |
@@ -1377,74 +1394,147 @@ struct arizona_fll_cfg { | |||
1377 | int gain; | 1394 | int gain; |
1378 | }; | 1395 | }; |
1379 | 1396 | ||
1380 | static int arizona_calc_fll(struct arizona_fll *fll, | 1397 | static int arizona_validate_fll(struct arizona_fll *fll, |
1381 | struct arizona_fll_cfg *cfg, | 1398 | unsigned int Fref, |
1382 | unsigned int Fref, | 1399 | unsigned int Fout) |
1383 | unsigned int Fout) | ||
1384 | { | 1400 | { |
1385 | unsigned int target, div, gcd_fll; | 1401 | unsigned int Fvco_min; |
1386 | int i, ratio; | 1402 | |
1403 | if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) { | ||
1404 | arizona_fll_err(fll, | ||
1405 | "Can't scale %dMHz in to <=13.5MHz\n", | ||
1406 | Fref); | ||
1407 | return -EINVAL; | ||
1408 | } | ||
1387 | 1409 | ||
1388 | arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout); | 1410 | Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult; |
1411 | if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) { | ||
1412 | arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n", | ||
1413 | Fout); | ||
1414 | return -EINVAL; | ||
1415 | } | ||
1416 | |||
1417 | return 0; | ||
1418 | } | ||
1419 | |||
1420 | static int arizona_find_fratio(unsigned int Fref, int *fratio) | ||
1421 | { | ||
1422 | int i; | ||
1423 | |||
1424 | /* Find an appropriate FLL_FRATIO */ | ||
1425 | for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { | ||
1426 | if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { | ||
1427 | if (fratio) | ||
1428 | *fratio = fll_fratios[i].fratio; | ||
1429 | return fll_fratios[i].ratio; | ||
1430 | } | ||
1431 | } | ||
1432 | |||
1433 | return -EINVAL; | ||
1434 | } | ||
1435 | |||
1436 | static int arizona_calc_fratio(struct arizona_fll *fll, | ||
1437 | struct arizona_fll_cfg *cfg, | ||
1438 | unsigned int target, | ||
1439 | unsigned int Fref, bool sync) | ||
1440 | { | ||
1441 | int init_ratio, ratio; | ||
1442 | int refdiv, div; | ||
1389 | 1443 | ||
1390 | /* Fref must be <=13.5MHz */ | 1444 | /* Fref must be <=13.5MHz, find initial refdiv */ |
1391 | div = 1; | 1445 | div = 1; |
1392 | cfg->refdiv = 0; | 1446 | cfg->refdiv = 0; |
1393 | while ((Fref / div) > 13500000) { | 1447 | while (Fref > ARIZONA_FLL_MAX_FREF) { |
1394 | div *= 2; | 1448 | div *= 2; |
1449 | Fref /= 2; | ||
1395 | cfg->refdiv++; | 1450 | cfg->refdiv++; |
1396 | 1451 | ||
1397 | if (div > 8) { | 1452 | if (div > ARIZONA_FLL_MAX_REFDIV) |
1398 | arizona_fll_err(fll, | ||
1399 | "Can't scale %dMHz in to <=13.5MHz\n", | ||
1400 | Fref); | ||
1401 | return -EINVAL; | 1453 | return -EINVAL; |
1454 | } | ||
1455 | |||
1456 | /* Find an appropriate FLL_FRATIO */ | ||
1457 | init_ratio = arizona_find_fratio(Fref, &cfg->fratio); | ||
1458 | if (init_ratio < 0) { | ||
1459 | arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n", | ||
1460 | Fref); | ||
1461 | return init_ratio; | ||
1462 | } | ||
1463 | |||
1464 | switch (fll->arizona->type) { | ||
1465 | case WM5110: | ||
1466 | if (fll->arizona->rev < 3 || sync) | ||
1467 | return init_ratio; | ||
1468 | break; | ||
1469 | default: | ||
1470 | return init_ratio; | ||
1471 | } | ||
1472 | |||
1473 | cfg->fratio = init_ratio - 1; | ||
1474 | |||
1475 | /* Adjust FRATIO/refdiv to avoid integer mode if possible */ | ||
1476 | refdiv = cfg->refdiv; | ||
1477 | |||
1478 | while (div <= ARIZONA_FLL_MAX_REFDIV) { | ||
1479 | for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO; | ||
1480 | ratio++) { | ||
1481 | if (target % (ratio * Fref)) { | ||
1482 | cfg->refdiv = refdiv; | ||
1483 | cfg->fratio = ratio - 1; | ||
1484 | return ratio; | ||
1485 | } | ||
1402 | } | 1486 | } |
1487 | |||
1488 | for (ratio = init_ratio - 1; ratio >= 0; ratio--) { | ||
1489 | if (ARIZONA_FLL_VCO_CORNER / (fll->vco_mult * ratio) < | ||
1490 | Fref) | ||
1491 | break; | ||
1492 | |||
1493 | if (target % (ratio * Fref)) { | ||
1494 | cfg->refdiv = refdiv; | ||
1495 | cfg->fratio = ratio - 1; | ||
1496 | return ratio; | ||
1497 | } | ||
1498 | } | ||
1499 | |||
1500 | div *= 2; | ||
1501 | Fref /= 2; | ||
1502 | refdiv++; | ||
1503 | init_ratio = arizona_find_fratio(Fref, NULL); | ||
1403 | } | 1504 | } |
1404 | 1505 | ||
1405 | /* Apply the division for our remaining calculations */ | 1506 | arizona_fll_warn(fll, "Falling back to integer mode operation\n"); |
1406 | Fref /= div; | 1507 | return cfg->fratio + 1; |
1508 | } | ||
1509 | |||
1510 | static int arizona_calc_fll(struct arizona_fll *fll, | ||
1511 | struct arizona_fll_cfg *cfg, | ||
1512 | unsigned int Fref, bool sync) | ||
1513 | { | ||
1514 | unsigned int target, div, gcd_fll; | ||
1515 | int i, ratio; | ||
1516 | |||
1517 | arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout); | ||
1407 | 1518 | ||
1408 | /* Fvco should be over the targt; don't check the upper bound */ | 1519 | /* Fvco should be over the targt; don't check the upper bound */ |
1409 | div = 1; | 1520 | div = ARIZONA_FLL_MIN_OUTDIV; |
1410 | while (Fout * div < 90000000 * fll->vco_mult) { | 1521 | while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) { |
1411 | div++; | 1522 | div++; |
1412 | if (div > 7) { | 1523 | if (div > ARIZONA_FLL_MAX_OUTDIV) |
1413 | arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n", | ||
1414 | Fout); | ||
1415 | return -EINVAL; | 1524 | return -EINVAL; |
1416 | } | ||
1417 | } | 1525 | } |
1418 | target = Fout * div / fll->vco_mult; | 1526 | target = fll->fout * div / fll->vco_mult; |
1419 | cfg->outdiv = div; | 1527 | cfg->outdiv = div; |
1420 | 1528 | ||
1421 | arizona_fll_dbg(fll, "Fvco=%dHz\n", target); | 1529 | arizona_fll_dbg(fll, "Fvco=%dHz\n", target); |
1422 | 1530 | ||
1423 | /* Find an appropraite FLL_FRATIO and factor it out of the target */ | 1531 | /* Find an appropriate FLL_FRATIO and refdiv */ |
1424 | for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { | 1532 | ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync); |
1425 | if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { | 1533 | if (ratio < 0) |
1426 | cfg->fratio = fll_fratios[i].fratio; | 1534 | return ratio; |
1427 | ratio = fll_fratios[i].ratio; | ||
1428 | break; | ||
1429 | } | ||
1430 | } | ||
1431 | if (i == ARRAY_SIZE(fll_fratios)) { | ||
1432 | arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n", | ||
1433 | Fref); | ||
1434 | return -EINVAL; | ||
1435 | } | ||
1436 | 1535 | ||
1437 | for (i = 0; i < ARRAY_SIZE(fll_gains); i++) { | 1536 | /* Apply the division for our remaining calculations */ |
1438 | if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) { | 1537 | Fref = Fref / (1 << cfg->refdiv); |
1439 | cfg->gain = fll_gains[i].gain; | ||
1440 | break; | ||
1441 | } | ||
1442 | } | ||
1443 | if (i == ARRAY_SIZE(fll_gains)) { | ||
1444 | arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n", | ||
1445 | Fref); | ||
1446 | return -EINVAL; | ||
1447 | } | ||
1448 | 1538 | ||
1449 | cfg->n = target / (ratio * Fref); | 1539 | cfg->n = target / (ratio * Fref); |
1450 | 1540 | ||
@@ -1469,6 +1559,18 @@ static int arizona_calc_fll(struct arizona_fll *fll, | |||
1469 | cfg->lambda >>= 1; | 1559 | cfg->lambda >>= 1; |
1470 | } | 1560 | } |
1471 | 1561 | ||
1562 | for (i = 0; i < ARRAY_SIZE(fll_gains); i++) { | ||
1563 | if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) { | ||
1564 | cfg->gain = fll_gains[i].gain; | ||
1565 | break; | ||
1566 | } | ||
1567 | } | ||
1568 | if (i == ARRAY_SIZE(fll_gains)) { | ||
1569 | arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n", | ||
1570 | Fref); | ||
1571 | return -EINVAL; | ||
1572 | } | ||
1573 | |||
1472 | arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n", | 1574 | arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n", |
1473 | cfg->n, cfg->theta, cfg->lambda); | 1575 | cfg->n, cfg->theta, cfg->lambda); |
1474 | arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", | 1576 | arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", |
@@ -1496,14 +1598,18 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base, | |||
1496 | cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | | 1598 | cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | |
1497 | source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); | 1599 | source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); |
1498 | 1600 | ||
1499 | if (sync) | 1601 | if (sync) { |
1500 | regmap_update_bits_async(arizona->regmap, base + 0x7, | 1602 | regmap_update_bits(arizona->regmap, base + 0x7, |
1501 | ARIZONA_FLL1_GAIN_MASK, | 1603 | ARIZONA_FLL1_GAIN_MASK, |
1502 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); | 1604 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); |
1503 | else | 1605 | } else { |
1504 | regmap_update_bits_async(arizona->regmap, base + 0x9, | 1606 | regmap_update_bits(arizona->regmap, base + 0x5, |
1505 | ARIZONA_FLL1_GAIN_MASK, | 1607 | ARIZONA_FLL1_OUTDIV_MASK, |
1506 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); | 1608 | cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); |
1609 | regmap_update_bits(arizona->regmap, base + 0x9, | ||
1610 | ARIZONA_FLL1_GAIN_MASK, | ||
1611 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); | ||
1612 | } | ||
1507 | 1613 | ||
1508 | regmap_update_bits_async(arizona->regmap, base + 2, | 1614 | regmap_update_bits_async(arizona->regmap, base + 2, |
1509 | ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, | 1615 | ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, |
@@ -1526,13 +1632,12 @@ static bool arizona_is_enabled_fll(struct arizona_fll *fll) | |||
1526 | return reg & ARIZONA_FLL1_ENA; | 1632 | return reg & ARIZONA_FLL1_ENA; |
1527 | } | 1633 | } |
1528 | 1634 | ||
1529 | static void arizona_enable_fll(struct arizona_fll *fll, | 1635 | static void arizona_enable_fll(struct arizona_fll *fll) |
1530 | struct arizona_fll_cfg *ref, | ||
1531 | struct arizona_fll_cfg *sync) | ||
1532 | { | 1636 | { |
1533 | struct arizona *arizona = fll->arizona; | 1637 | struct arizona *arizona = fll->arizona; |
1534 | int ret; | 1638 | int ret; |
1535 | bool use_sync = false; | 1639 | bool use_sync = false; |
1640 | struct arizona_fll_cfg cfg; | ||
1536 | 1641 | ||
1537 | /* | 1642 | /* |
1538 | * If we have both REFCLK and SYNCCLK then enable both, | 1643 | * If we have both REFCLK and SYNCCLK then enable both, |
@@ -1540,23 +1645,21 @@ static void arizona_enable_fll(struct arizona_fll *fll, | |||
1540 | */ | 1645 | */ |
1541 | if (fll->ref_src >= 0 && fll->ref_freq && | 1646 | if (fll->ref_src >= 0 && fll->ref_freq && |
1542 | fll->ref_src != fll->sync_src) { | 1647 | fll->ref_src != fll->sync_src) { |
1543 | regmap_update_bits_async(arizona->regmap, fll->base + 5, | 1648 | arizona_calc_fll(fll, &cfg, fll->ref_freq, false); |
1544 | ARIZONA_FLL1_OUTDIV_MASK, | ||
1545 | ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); | ||
1546 | 1649 | ||
1547 | arizona_apply_fll(arizona, fll->base, ref, fll->ref_src, | 1650 | arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src, |
1548 | false); | 1651 | false); |
1549 | if (fll->sync_src >= 0) { | 1652 | if (fll->sync_src >= 0) { |
1550 | arizona_apply_fll(arizona, fll->base + 0x10, sync, | 1653 | arizona_calc_fll(fll, &cfg, fll->sync_freq, true); |
1654 | |||
1655 | arizona_apply_fll(arizona, fll->base + 0x10, &cfg, | ||
1551 | fll->sync_src, true); | 1656 | fll->sync_src, true); |
1552 | use_sync = true; | 1657 | use_sync = true; |
1553 | } | 1658 | } |
1554 | } else if (fll->sync_src >= 0) { | 1659 | } else if (fll->sync_src >= 0) { |
1555 | regmap_update_bits_async(arizona->regmap, fll->base + 5, | 1660 | arizona_calc_fll(fll, &cfg, fll->sync_freq, false); |
1556 | ARIZONA_FLL1_OUTDIV_MASK, | ||
1557 | sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); | ||
1558 | 1661 | ||
1559 | arizona_apply_fll(arizona, fll->base, sync, | 1662 | arizona_apply_fll(arizona, fll->base, &cfg, |
1560 | fll->sync_src, false); | 1663 | fll->sync_src, false); |
1561 | 1664 | ||
1562 | regmap_update_bits_async(arizona->regmap, fll->base + 0x11, | 1665 | regmap_update_bits_async(arizona->regmap, fll->base + 0x11, |
@@ -1618,32 +1721,22 @@ static void arizona_disable_fll(struct arizona_fll *fll) | |||
1618 | int arizona_set_fll_refclk(struct arizona_fll *fll, int source, | 1721 | int arizona_set_fll_refclk(struct arizona_fll *fll, int source, |
1619 | unsigned int Fref, unsigned int Fout) | 1722 | unsigned int Fref, unsigned int Fout) |
1620 | { | 1723 | { |
1621 | struct arizona_fll_cfg ref, sync; | ||
1622 | int ret; | 1724 | int ret; |
1623 | 1725 | ||
1624 | if (fll->ref_src == source && fll->ref_freq == Fref) | 1726 | if (fll->ref_src == source && fll->ref_freq == Fref) |
1625 | return 0; | 1727 | return 0; |
1626 | 1728 | ||
1627 | if (fll->fout) { | 1729 | if (fll->fout && Fref > 0) { |
1628 | if (Fref > 0) { | 1730 | ret = arizona_validate_fll(fll, Fref, fll->fout); |
1629 | ret = arizona_calc_fll(fll, &ref, Fref, fll->fout); | 1731 | if (ret != 0) |
1630 | if (ret != 0) | 1732 | return ret; |
1631 | return ret; | ||
1632 | } | ||
1633 | |||
1634 | if (fll->sync_src >= 0) { | ||
1635 | ret = arizona_calc_fll(fll, &sync, fll->sync_freq, | ||
1636 | fll->fout); | ||
1637 | if (ret != 0) | ||
1638 | return ret; | ||
1639 | } | ||
1640 | } | 1733 | } |
1641 | 1734 | ||
1642 | fll->ref_src = source; | 1735 | fll->ref_src = source; |
1643 | fll->ref_freq = Fref; | 1736 | fll->ref_freq = Fref; |
1644 | 1737 | ||
1645 | if (fll->fout && Fref > 0) { | 1738 | if (fll->fout && Fref > 0) { |
1646 | arizona_enable_fll(fll, &ref, &sync); | 1739 | arizona_enable_fll(fll); |
1647 | } | 1740 | } |
1648 | 1741 | ||
1649 | return 0; | 1742 | return 0; |
@@ -1653,7 +1746,6 @@ EXPORT_SYMBOL_GPL(arizona_set_fll_refclk); | |||
1653 | int arizona_set_fll(struct arizona_fll *fll, int source, | 1746 | int arizona_set_fll(struct arizona_fll *fll, int source, |
1654 | unsigned int Fref, unsigned int Fout) | 1747 | unsigned int Fref, unsigned int Fout) |
1655 | { | 1748 | { |
1656 | struct arizona_fll_cfg ref, sync; | ||
1657 | int ret; | 1749 | int ret; |
1658 | 1750 | ||
1659 | if (fll->sync_src == source && | 1751 | if (fll->sync_src == source && |
@@ -1662,13 +1754,12 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
1662 | 1754 | ||
1663 | if (Fout) { | 1755 | if (Fout) { |
1664 | if (fll->ref_src >= 0) { | 1756 | if (fll->ref_src >= 0) { |
1665 | ret = arizona_calc_fll(fll, &ref, fll->ref_freq, | 1757 | ret = arizona_validate_fll(fll, fll->ref_freq, Fout); |
1666 | Fout); | ||
1667 | if (ret != 0) | 1758 | if (ret != 0) |
1668 | return ret; | 1759 | return ret; |
1669 | } | 1760 | } |
1670 | 1761 | ||
1671 | ret = arizona_calc_fll(fll, &sync, Fref, Fout); | 1762 | ret = arizona_validate_fll(fll, Fref, Fout); |
1672 | if (ret != 0) | 1763 | if (ret != 0) |
1673 | return ret; | 1764 | return ret; |
1674 | } | 1765 | } |
@@ -1678,7 +1769,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
1678 | fll->fout = Fout; | 1769 | fll->fout = Fout; |
1679 | 1770 | ||
1680 | if (Fout) { | 1771 | if (Fout) { |
1681 | arizona_enable_fll(fll, &ref, &sync); | 1772 | arizona_enable_fll(fll); |
1682 | } else { | 1773 | } else { |
1683 | arizona_disable_fll(fll); | 1774 | arizona_disable_fll(fll); |
1684 | } | 1775 | } |
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 43737a27d79c..1e25c7af853b 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c | |||
@@ -138,9 +138,8 @@ static int cq93vc_probe(struct snd_soc_codec *codec) | |||
138 | struct davinci_vc *davinci_vc = codec->dev->platform_data; | 138 | struct davinci_vc *davinci_vc = codec->dev->platform_data; |
139 | 139 | ||
140 | davinci_vc->cq93vc.codec = codec; | 140 | davinci_vc->cq93vc.codec = codec; |
141 | codec->control_data = davinci_vc->regmap; | ||
142 | 141 | ||
143 | snd_soc_codec_set_cache_io(codec, 32, 32, SND_SOC_REGMAP); | 142 | snd_soc_codec_set_cache_io(codec, davinci_vc->regmap); |
144 | 143 | ||
145 | /* Off, with power on */ | 144 | /* Off, with power on */ |
146 | cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 145 | cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 83c835d9fd88..3920e6264948 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
@@ -506,15 +506,6 @@ static int cs4270_probe(struct snd_soc_codec *codec) | |||
506 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 506 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
507 | int ret; | 507 | int ret; |
508 | 508 | ||
509 | /* Tell ASoC what kind of I/O to use to read the registers. ASoC will | ||
510 | * then do the I2C transactions itself. | ||
511 | */ | ||
512 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
513 | if (ret < 0) { | ||
514 | dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret); | ||
515 | return ret; | ||
516 | } | ||
517 | |||
518 | /* Disable auto-mute. This feature appears to be buggy. In some | 509 | /* Disable auto-mute. This feature appears to be buggy. In some |
519 | * situations, auto-mute will not deactivate when it should, so we want | 510 | * situations, auto-mute will not deactivate when it should, so we want |
520 | * this feature disabled by default. An application (e.g. alsactl) can | 511 | * this feature disabled by default. An application (e.g. alsactl) can |
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index ce05fd93dc74..aef4965750c7 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
@@ -159,7 +159,6 @@ static bool cs4271_volatile_reg(struct device *dev, unsigned int reg) | |||
159 | } | 159 | } |
160 | 160 | ||
161 | struct cs4271_private { | 161 | struct cs4271_private { |
162 | /* SND_SOC_I2C or SND_SOC_SPI */ | ||
163 | unsigned int mclk; | 162 | unsigned int mclk; |
164 | bool master; | 163 | bool master; |
165 | bool deemph; | 164 | bool deemph; |
@@ -540,14 +539,10 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
540 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); | 539 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); |
541 | struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; | 540 | struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; |
542 | int ret; | 541 | int ret; |
543 | int gpio_nreset = -EINVAL; | ||
544 | bool amutec_eq_bmutec = false; | 542 | bool amutec_eq_bmutec = false; |
545 | 543 | ||
546 | #ifdef CONFIG_OF | 544 | #ifdef CONFIG_OF |
547 | if (of_match_device(cs4271_dt_ids, codec->dev)) { | 545 | if (of_match_device(cs4271_dt_ids, codec->dev)) { |
548 | gpio_nreset = of_get_named_gpio(codec->dev->of_node, | ||
549 | "reset-gpio", 0); | ||
550 | |||
551 | if (of_get_property(codec->dev->of_node, | 546 | if (of_get_property(codec->dev->of_node, |
552 | "cirrus,amutec-eq-bmutec", NULL)) | 547 | "cirrus,amutec-eq-bmutec", NULL)) |
553 | amutec_eq_bmutec = true; | 548 | amutec_eq_bmutec = true; |
@@ -559,27 +554,19 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
559 | #endif | 554 | #endif |
560 | 555 | ||
561 | if (cs4271plat) { | 556 | if (cs4271plat) { |
562 | if (gpio_is_valid(cs4271plat->gpio_nreset)) | ||
563 | gpio_nreset = cs4271plat->gpio_nreset; | ||
564 | |||
565 | amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec; | 557 | amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec; |
566 | cs4271->enable_soft_reset = cs4271plat->enable_soft_reset; | 558 | cs4271->enable_soft_reset = cs4271plat->enable_soft_reset; |
567 | } | 559 | } |
568 | 560 | ||
569 | if (gpio_nreset >= 0) | 561 | if (gpio_is_valid(cs4271->gpio_nreset)) { |
570 | if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset")) | ||
571 | gpio_nreset = -EINVAL; | ||
572 | if (gpio_nreset >= 0) { | ||
573 | /* Reset codec */ | 562 | /* Reset codec */ |
574 | gpio_direction_output(gpio_nreset, 0); | 563 | gpio_direction_output(cs4271->gpio_nreset, 0); |
575 | udelay(1); | 564 | udelay(1); |
576 | gpio_set_value(gpio_nreset, 1); | 565 | gpio_set_value(cs4271->gpio_nreset, 1); |
577 | /* Give the codec time to wake up */ | 566 | /* Give the codec time to wake up */ |
578 | udelay(1); | 567 | udelay(1); |
579 | } | 568 | } |
580 | 569 | ||
581 | cs4271->gpio_nreset = gpio_nreset; | ||
582 | |||
583 | ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, | 570 | ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, |
584 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN, | 571 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN, |
585 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN); | 572 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN); |
@@ -625,6 +612,36 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = { | |||
625 | .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes), | 612 | .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes), |
626 | }; | 613 | }; |
627 | 614 | ||
615 | static int cs4271_common_probe(struct device *dev, | ||
616 | struct cs4271_private **c) | ||
617 | { | ||
618 | struct cs4271_platform_data *cs4271plat = dev->platform_data; | ||
619 | struct cs4271_private *cs4271; | ||
620 | |||
621 | cs4271 = devm_kzalloc(dev, sizeof(*cs4271), GFP_KERNEL); | ||
622 | if (!cs4271) | ||
623 | return -ENOMEM; | ||
624 | |||
625 | if (of_match_device(cs4271_dt_ids, dev)) | ||
626 | cs4271->gpio_nreset = | ||
627 | of_get_named_gpio(dev->of_node, "reset-gpio", 0); | ||
628 | |||
629 | if (cs4271plat) | ||
630 | cs4271->gpio_nreset = cs4271plat->gpio_nreset; | ||
631 | |||
632 | if (gpio_is_valid(cs4271->gpio_nreset)) { | ||
633 | int ret; | ||
634 | |||
635 | ret = devm_gpio_request(dev, cs4271->gpio_nreset, | ||
636 | "CS4271 Reset"); | ||
637 | if (ret < 0) | ||
638 | return ret; | ||
639 | } | ||
640 | |||
641 | *c = cs4271; | ||
642 | return 0; | ||
643 | } | ||
644 | |||
628 | #if defined(CONFIG_SPI_MASTER) | 645 | #if defined(CONFIG_SPI_MASTER) |
629 | 646 | ||
630 | static const struct regmap_config cs4271_spi_regmap = { | 647 | static const struct regmap_config cs4271_spi_regmap = { |
@@ -644,10 +661,11 @@ static const struct regmap_config cs4271_spi_regmap = { | |||
644 | static int cs4271_spi_probe(struct spi_device *spi) | 661 | static int cs4271_spi_probe(struct spi_device *spi) |
645 | { | 662 | { |
646 | struct cs4271_private *cs4271; | 663 | struct cs4271_private *cs4271; |
664 | int ret; | ||
647 | 665 | ||
648 | cs4271 = devm_kzalloc(&spi->dev, sizeof(*cs4271), GFP_KERNEL); | 666 | ret = cs4271_common_probe(&spi->dev, &cs4271); |
649 | if (!cs4271) | 667 | if (ret < 0) |
650 | return -ENOMEM; | 668 | return ret; |
651 | 669 | ||
652 | spi_set_drvdata(spi, cs4271); | 670 | spi_set_drvdata(spi, cs4271); |
653 | cs4271->regmap = devm_regmap_init_spi(spi, &cs4271_spi_regmap); | 671 | cs4271->regmap = devm_regmap_init_spi(spi, &cs4271_spi_regmap); |
@@ -698,10 +716,11 @@ static int cs4271_i2c_probe(struct i2c_client *client, | |||
698 | const struct i2c_device_id *id) | 716 | const struct i2c_device_id *id) |
699 | { | 717 | { |
700 | struct cs4271_private *cs4271; | 718 | struct cs4271_private *cs4271; |
719 | int ret; | ||
701 | 720 | ||
702 | cs4271 = devm_kzalloc(&client->dev, sizeof(*cs4271), GFP_KERNEL); | 721 | ret = cs4271_common_probe(&client->dev, &cs4271); |
703 | if (!cs4271) | 722 | if (ret < 0) |
704 | return -ENOMEM; | 723 | return ret; |
705 | 724 | ||
706 | i2c_set_clientdata(client, cs4271); | 725 | i2c_set_clientdata(client, cs4271); |
707 | cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap); | 726 | cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap); |
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 6e9ea8379a91..6c0da2baa154 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <sound/pcm_params.h> | 30 | #include <sound/pcm_params.h> |
31 | #include <sound/pcm.h> | 31 | #include <sound/pcm.h> |
32 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
33 | #include <linux/regmap.h> | ||
33 | 34 | ||
34 | #include "cs42l51.h" | 35 | #include "cs42l51.h" |
35 | 36 | ||
@@ -40,7 +41,6 @@ enum master_slave_mode { | |||
40 | }; | 41 | }; |
41 | 42 | ||
42 | struct cs42l51_private { | 43 | struct cs42l51_private { |
43 | enum snd_soc_control_type control_type; | ||
44 | unsigned int mclk; | 44 | unsigned int mclk; |
45 | unsigned int audio_mode; /* The mode (I2S or left-justified) */ | 45 | unsigned int audio_mode; /* The mode (I2S or left-justified) */ |
46 | enum master_slave_mode func; | 46 | enum master_slave_mode func; |
@@ -52,24 +52,6 @@ struct cs42l51_private { | |||
52 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ | 52 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ |
53 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) | 53 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) |
54 | 54 | ||
55 | static int cs42l51_fill_cache(struct snd_soc_codec *codec) | ||
56 | { | ||
57 | u8 *cache = codec->reg_cache + 1; | ||
58 | struct i2c_client *i2c_client = to_i2c_client(codec->dev); | ||
59 | s32 length; | ||
60 | |||
61 | length = i2c_smbus_read_i2c_block_data(i2c_client, | ||
62 | CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache); | ||
63 | if (length != CS42L51_NUMREGS) { | ||
64 | dev_err(&i2c_client->dev, | ||
65 | "I2C read failure, addr=0x%x (ret=%d vs %d)\n", | ||
66 | i2c_client->addr, length, CS42L51_NUMREGS); | ||
67 | return -EIO; | ||
68 | } | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, | 55 | static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, |
74 | struct snd_ctl_elem_value *ucontrol) | 56 | struct snd_ctl_elem_value *ucontrol) |
75 | { | 57 | { |
@@ -124,9 +106,8 @@ static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol, | |||
124 | 106 | ||
125 | static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0); | 107 | static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0); |
126 | static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0); | 108 | static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0); |
127 | /* This is a lie. after -102 db, it stays at -102 */ | 109 | |
128 | /* maybe a range would be better */ | 110 | static const DECLARE_TLV_DB_SCALE(aout_tlv, -10200, 50, 0); |
129 | static const DECLARE_TLV_DB_SCALE(aout_tlv, -11550, 50, 0); | ||
130 | 111 | ||
131 | static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0); | 112 | static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0); |
132 | static const char *chan_mix[] = { | 113 | static const char *chan_mix[] = { |
@@ -135,13 +116,12 @@ static const char *chan_mix[] = { | |||
135 | "R L", | 116 | "R L", |
136 | }; | 117 | }; |
137 | 118 | ||
138 | static const struct soc_enum cs42l51_chan_mix = | 119 | static SOC_ENUM_SINGLE_EXT_DECL(cs42l51_chan_mix, chan_mix); |
139 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(chan_mix), chan_mix); | ||
140 | 120 | ||
141 | static const struct snd_kcontrol_new cs42l51_snd_controls[] = { | 121 | static const struct snd_kcontrol_new cs42l51_snd_controls[] = { |
142 | SOC_DOUBLE_R_SX_TLV("PCM Playback Volume", | 122 | SOC_DOUBLE_R_SX_TLV("PCM Playback Volume", |
143 | CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, | 123 | CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, |
144 | 6, 0x19, 0x7F, adc_pcm_tlv), | 124 | 0, 0x19, 0x7F, adc_pcm_tlv), |
145 | SOC_DOUBLE_R("PCM Playback Switch", | 125 | SOC_DOUBLE_R("PCM Playback Switch", |
146 | CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1), | 126 | CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1), |
147 | SOC_DOUBLE_R_SX_TLV("Analog Playback Volume", | 127 | SOC_DOUBLE_R_SX_TLV("Analog Playback Volume", |
@@ -149,7 +129,7 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = { | |||
149 | 0, 0x34, 0xE4, aout_tlv), | 129 | 0, 0x34, 0xE4, aout_tlv), |
150 | SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", | 130 | SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", |
151 | CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, | 131 | CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, |
152 | 6, 0x19, 0x7F, adc_pcm_tlv), | 132 | 0, 0x19, 0x7F, adc_pcm_tlv), |
153 | SOC_DOUBLE_R("ADC Mixer Switch", | 133 | SOC_DOUBLE_R("ADC Mixer Switch", |
154 | CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1), | 134 | CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1), |
155 | SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0), | 135 | SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0), |
@@ -192,22 +172,22 @@ static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w, | |||
192 | 172 | ||
193 | static const char *cs42l51_dac_names[] = {"Direct PCM", | 173 | static const char *cs42l51_dac_names[] = {"Direct PCM", |
194 | "DSP PCM", "ADC"}; | 174 | "DSP PCM", "ADC"}; |
195 | static const struct soc_enum cs42l51_dac_mux_enum = | 175 | static SOC_ENUM_SINGLE_DECL(cs42l51_dac_mux_enum, |
196 | SOC_ENUM_SINGLE(CS42L51_DAC_CTL, 6, 3, cs42l51_dac_names); | 176 | CS42L51_DAC_CTL, 6, cs42l51_dac_names); |
197 | static const struct snd_kcontrol_new cs42l51_dac_mux_controls = | 177 | static const struct snd_kcontrol_new cs42l51_dac_mux_controls = |
198 | SOC_DAPM_ENUM("Route", cs42l51_dac_mux_enum); | 178 | SOC_DAPM_ENUM("Route", cs42l51_dac_mux_enum); |
199 | 179 | ||
200 | static const char *cs42l51_adcl_names[] = {"AIN1 Left", "AIN2 Left", | 180 | static const char *cs42l51_adcl_names[] = {"AIN1 Left", "AIN2 Left", |
201 | "MIC Left", "MIC+preamp Left"}; | 181 | "MIC Left", "MIC+preamp Left"}; |
202 | static const struct soc_enum cs42l51_adcl_mux_enum = | 182 | static SOC_ENUM_SINGLE_DECL(cs42l51_adcl_mux_enum, |
203 | SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 4, 4, cs42l51_adcl_names); | 183 | CS42L51_ADC_INPUT, 4, cs42l51_adcl_names); |
204 | static const struct snd_kcontrol_new cs42l51_adcl_mux_controls = | 184 | static const struct snd_kcontrol_new cs42l51_adcl_mux_controls = |
205 | SOC_DAPM_ENUM("Route", cs42l51_adcl_mux_enum); | 185 | SOC_DAPM_ENUM("Route", cs42l51_adcl_mux_enum); |
206 | 186 | ||
207 | static const char *cs42l51_adcr_names[] = {"AIN1 Right", "AIN2 Right", | 187 | static const char *cs42l51_adcr_names[] = {"AIN1 Right", "AIN2 Right", |
208 | "MIC Right", "MIC+preamp Right"}; | 188 | "MIC Right", "MIC+preamp Right"}; |
209 | static const struct soc_enum cs42l51_adcr_mux_enum = | 189 | static SOC_ENUM_SINGLE_DECL(cs42l51_adcr_mux_enum, |
210 | SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 6, 4, cs42l51_adcr_names); | 190 | CS42L51_ADC_INPUT, 6, cs42l51_adcr_names); |
211 | static const struct snd_kcontrol_new cs42l51_adcr_mux_controls = | 191 | static const struct snd_kcontrol_new cs42l51_adcr_mux_controls = |
212 | SOC_DAPM_ENUM("Route", cs42l51_adcr_mux_enum); | 192 | SOC_DAPM_ENUM("Route", cs42l51_adcr_mux_enum); |
213 | 193 | ||
@@ -505,21 +485,8 @@ static struct snd_soc_dai_driver cs42l51_dai = { | |||
505 | 485 | ||
506 | static int cs42l51_probe(struct snd_soc_codec *codec) | 486 | static int cs42l51_probe(struct snd_soc_codec *codec) |
507 | { | 487 | { |
508 | struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); | ||
509 | int ret, reg; | 488 | int ret, reg; |
510 | 489 | ||
511 | ret = cs42l51_fill_cache(codec); | ||
512 | if (ret < 0) { | ||
513 | dev_err(codec->dev, "failed to fill register cache\n"); | ||
514 | return ret; | ||
515 | } | ||
516 | |||
517 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type); | ||
518 | if (ret < 0) { | ||
519 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
520 | return ret; | ||
521 | } | ||
522 | |||
523 | /* | 490 | /* |
524 | * DAC configuration | 491 | * DAC configuration |
525 | * - Use signal processor | 492 | * - Use signal processor |
@@ -538,8 +505,6 @@ static int cs42l51_probe(struct snd_soc_codec *codec) | |||
538 | 505 | ||
539 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | 506 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { |
540 | .probe = cs42l51_probe, | 507 | .probe = cs42l51_probe, |
541 | .reg_cache_size = CS42L51_NUMREGS + 1, | ||
542 | .reg_word_size = sizeof(u8), | ||
543 | 508 | ||
544 | .controls = cs42l51_snd_controls, | 509 | .controls = cs42l51_snd_controls, |
545 | .num_controls = ARRAY_SIZE(cs42l51_snd_controls), | 510 | .num_controls = ARRAY_SIZE(cs42l51_snd_controls), |
@@ -549,38 +514,53 @@ static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | |||
549 | .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), | 514 | .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), |
550 | }; | 515 | }; |
551 | 516 | ||
517 | static const struct regmap_config cs42l51_regmap = { | ||
518 | .reg_bits = 8, | ||
519 | .val_bits = 8, | ||
520 | |||
521 | .max_register = CS42L51_CHARGE_FREQ, | ||
522 | .cache_type = REGCACHE_RBTREE, | ||
523 | }; | ||
524 | |||
552 | static int cs42l51_i2c_probe(struct i2c_client *i2c_client, | 525 | static int cs42l51_i2c_probe(struct i2c_client *i2c_client, |
553 | const struct i2c_device_id *id) | 526 | const struct i2c_device_id *id) |
554 | { | 527 | { |
555 | struct cs42l51_private *cs42l51; | 528 | struct cs42l51_private *cs42l51; |
529 | struct regmap *regmap; | ||
530 | unsigned int val; | ||
556 | int ret; | 531 | int ret; |
557 | 532 | ||
533 | regmap = devm_regmap_init_i2c(i2c_client, &cs42l51_regmap); | ||
534 | if (IS_ERR(regmap)) { | ||
535 | ret = PTR_ERR(regmap); | ||
536 | dev_err(&i2c_client->dev, "Failed to create regmap: %d\n", | ||
537 | ret); | ||
538 | return ret; | ||
539 | } | ||
540 | |||
558 | /* Verify that we have a CS42L51 */ | 541 | /* Verify that we have a CS42L51 */ |
559 | ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID); | 542 | ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val); |
560 | if (ret < 0) { | 543 | if (ret < 0) { |
561 | dev_err(&i2c_client->dev, "failed to read I2C\n"); | 544 | dev_err(&i2c_client->dev, "failed to read I2C\n"); |
562 | goto error; | 545 | goto error; |
563 | } | 546 | } |
564 | 547 | ||
565 | if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && | 548 | if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && |
566 | (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { | 549 | (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { |
567 | dev_err(&i2c_client->dev, "Invalid chip id\n"); | 550 | dev_err(&i2c_client->dev, "Invalid chip id: %x\n", val); |
568 | ret = -ENODEV; | 551 | ret = -ENODEV; |
569 | goto error; | 552 | goto error; |
570 | } | 553 | } |
571 | 554 | ||
572 | dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n", | 555 | dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n", |
573 | ret & 7); | 556 | val & 7); |
574 | 557 | ||
575 | cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private), | 558 | cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private), |
576 | GFP_KERNEL); | 559 | GFP_KERNEL); |
577 | if (!cs42l51) { | 560 | if (!cs42l51) |
578 | dev_err(&i2c_client->dev, "could not allocate codec\n"); | ||
579 | return -ENOMEM; | 561 | return -ENOMEM; |
580 | } | ||
581 | 562 | ||
582 | i2c_set_clientdata(i2c_client, cs42l51); | 563 | i2c_set_clientdata(i2c_client, cs42l51); |
583 | cs42l51->control_type = SND_SOC_I2C; | ||
584 | 564 | ||
585 | ret = snd_soc_register_codec(&i2c_client->dev, | 565 | ret = snd_soc_register_codec(&i2c_client->dev, |
586 | &soc_codec_device_cs42l51, &cs42l51_dai, 1); | 566 | &soc_codec_device_cs42l51, &cs42l51_dai, 1); |
@@ -600,10 +580,17 @@ static const struct i2c_device_id cs42l51_id[] = { | |||
600 | }; | 580 | }; |
601 | MODULE_DEVICE_TABLE(i2c, cs42l51_id); | 581 | MODULE_DEVICE_TABLE(i2c, cs42l51_id); |
602 | 582 | ||
583 | static const struct of_device_id cs42l51_of_match[] = { | ||
584 | { .compatible = "cirrus,cs42l51", }, | ||
585 | { } | ||
586 | }; | ||
587 | MODULE_DEVICE_TABLE(of, cs42l51_of_match); | ||
588 | |||
603 | static struct i2c_driver cs42l51_i2c_driver = { | 589 | static struct i2c_driver cs42l51_i2c_driver = { |
604 | .driver = { | 590 | .driver = { |
605 | .name = "cs42l51-codec", | 591 | .name = "cs42l51-codec", |
606 | .owner = THIS_MODULE, | 592 | .owner = THIS_MODULE, |
593 | .of_match_table = cs42l51_of_match, | ||
607 | }, | 594 | }, |
608 | .id_table = cs42l51_id, | 595 | .id_table = cs42l51_id, |
609 | .probe = cs42l51_i2c_probe, | 596 | .probe = cs42l51_i2c_probe, |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 0bac6d5a4ac8..f0ca6bee6771 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -210,13 +210,11 @@ static const char * const cs42l52_adca_text[] = { | |||
210 | static const char * const cs42l52_adcb_text[] = { | 210 | static const char * const cs42l52_adcb_text[] = { |
211 | "Input1B", "Input2B", "Input3B", "Input4B", "PGA Input Right"}; | 211 | "Input1B", "Input2B", "Input3B", "Input4B", "PGA Input Right"}; |
212 | 212 | ||
213 | static const struct soc_enum adca_enum = | 213 | static SOC_ENUM_SINGLE_DECL(adca_enum, |
214 | SOC_ENUM_SINGLE(CS42L52_ADC_PGA_A, 5, | 214 | CS42L52_ADC_PGA_A, 5, cs42l52_adca_text); |
215 | ARRAY_SIZE(cs42l52_adca_text), cs42l52_adca_text); | ||
216 | 215 | ||
217 | static const struct soc_enum adcb_enum = | 216 | static SOC_ENUM_SINGLE_DECL(adcb_enum, |
218 | SOC_ENUM_SINGLE(CS42L52_ADC_PGA_B, 5, | 217 | CS42L52_ADC_PGA_B, 5, cs42l52_adcb_text); |
219 | ARRAY_SIZE(cs42l52_adcb_text), cs42l52_adcb_text); | ||
220 | 218 | ||
221 | static const struct snd_kcontrol_new adca_mux = | 219 | static const struct snd_kcontrol_new adca_mux = |
222 | SOC_DAPM_ENUM("Left ADC Input Capture Mux", adca_enum); | 220 | SOC_DAPM_ENUM("Left ADC Input Capture Mux", adca_enum); |
@@ -229,26 +227,22 @@ static const char * const mic_bias_level_text[] = { | |||
229 | "0.8 +VA", "0.83 +VA", "0.91 +VA" | 227 | "0.8 +VA", "0.83 +VA", "0.91 +VA" |
230 | }; | 228 | }; |
231 | 229 | ||
232 | static const struct soc_enum mic_bias_level_enum = | 230 | static SOC_ENUM_SINGLE_DECL(mic_bias_level_enum, |
233 | SOC_ENUM_SINGLE(CS42L52_IFACE_CTL2, 0, | 231 | CS42L52_IFACE_CTL2, 0, mic_bias_level_text); |
234 | ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text); | ||
235 | 232 | ||
236 | static const char * const cs42l52_mic_text[] = { "MIC1", "MIC2" }; | 233 | static const char * const cs42l52_mic_text[] = { "MIC1", "MIC2" }; |
237 | 234 | ||
238 | static const struct soc_enum mica_enum = | 235 | static SOC_ENUM_SINGLE_DECL(mica_enum, |
239 | SOC_ENUM_SINGLE(CS42L52_MICA_CTL, 5, | 236 | CS42L52_MICA_CTL, 5, cs42l52_mic_text); |
240 | ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text); | ||
241 | 237 | ||
242 | static const struct soc_enum micb_enum = | 238 | static SOC_ENUM_SINGLE_DECL(micb_enum, |
243 | SOC_ENUM_SINGLE(CS42L52_MICB_CTL, 5, | 239 | CS42L52_MICB_CTL, 5, cs42l52_mic_text); |
244 | ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text); | ||
245 | 240 | ||
246 | static const char * const digital_output_mux_text[] = {"ADC", "DSP"}; | 241 | static const char * const digital_output_mux_text[] = {"ADC", "DSP"}; |
247 | 242 | ||
248 | static const struct soc_enum digital_output_mux_enum = | 243 | static SOC_ENUM_SINGLE_DECL(digital_output_mux_enum, |
249 | SOC_ENUM_SINGLE(CS42L52_ADC_MISC_CTL, 6, | 244 | CS42L52_ADC_MISC_CTL, 6, |
250 | ARRAY_SIZE(digital_output_mux_text), | 245 | digital_output_mux_text); |
251 | digital_output_mux_text); | ||
252 | 246 | ||
253 | static const struct snd_kcontrol_new digital_output_mux = | 247 | static const struct snd_kcontrol_new digital_output_mux = |
254 | SOC_DAPM_ENUM("Digital Output Mux", digital_output_mux_enum); | 248 | SOC_DAPM_ENUM("Digital Output Mux", digital_output_mux_enum); |
@@ -258,18 +252,18 @@ static const char * const hp_gain_num_text[] = { | |||
258 | "0.7099", "0.8399", "1.000", "1.1430" | 252 | "0.7099", "0.8399", "1.000", "1.1430" |
259 | }; | 253 | }; |
260 | 254 | ||
261 | static const struct soc_enum hp_gain_enum = | 255 | static SOC_ENUM_SINGLE_DECL(hp_gain_enum, |
262 | SOC_ENUM_SINGLE(CS42L52_PB_CTL1, 5, | 256 | CS42L52_PB_CTL1, 5, |
263 | ARRAY_SIZE(hp_gain_num_text), hp_gain_num_text); | 257 | hp_gain_num_text); |
264 | 258 | ||
265 | static const char * const beep_pitch_text[] = { | 259 | static const char * const beep_pitch_text[] = { |
266 | "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5", | 260 | "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5", |
267 | "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7" | 261 | "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7" |
268 | }; | 262 | }; |
269 | 263 | ||
270 | static const struct soc_enum beep_pitch_enum = | 264 | static SOC_ENUM_SINGLE_DECL(beep_pitch_enum, |
271 | SOC_ENUM_SINGLE(CS42L52_BEEP_FREQ, 4, | 265 | CS42L52_BEEP_FREQ, 4, |
272 | ARRAY_SIZE(beep_pitch_text), beep_pitch_text); | 266 | beep_pitch_text); |
273 | 267 | ||
274 | static const char * const beep_ontime_text[] = { | 268 | static const char * const beep_ontime_text[] = { |
275 | "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s", | 269 | "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s", |
@@ -277,66 +271,66 @@ static const char * const beep_ontime_text[] = { | |||
277 | "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s" | 271 | "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s" |
278 | }; | 272 | }; |
279 | 273 | ||
280 | static const struct soc_enum beep_ontime_enum = | 274 | static SOC_ENUM_SINGLE_DECL(beep_ontime_enum, |
281 | SOC_ENUM_SINGLE(CS42L52_BEEP_FREQ, 0, | 275 | CS42L52_BEEP_FREQ, 0, |
282 | ARRAY_SIZE(beep_ontime_text), beep_ontime_text); | 276 | beep_ontime_text); |
283 | 277 | ||
284 | static const char * const beep_offtime_text[] = { | 278 | static const char * const beep_offtime_text[] = { |
285 | "1.23 s", "2.58 s", "3.90 s", "5.20 s", | 279 | "1.23 s", "2.58 s", "3.90 s", "5.20 s", |
286 | "6.60 s", "8.05 s", "9.35 s", "10.80 s" | 280 | "6.60 s", "8.05 s", "9.35 s", "10.80 s" |
287 | }; | 281 | }; |
288 | 282 | ||
289 | static const struct soc_enum beep_offtime_enum = | 283 | static SOC_ENUM_SINGLE_DECL(beep_offtime_enum, |
290 | SOC_ENUM_SINGLE(CS42L52_BEEP_VOL, 5, | 284 | CS42L52_BEEP_VOL, 5, |
291 | ARRAY_SIZE(beep_offtime_text), beep_offtime_text); | 285 | beep_offtime_text); |
292 | 286 | ||
293 | static const char * const beep_config_text[] = { | 287 | static const char * const beep_config_text[] = { |
294 | "Off", "Single", "Multiple", "Continuous" | 288 | "Off", "Single", "Multiple", "Continuous" |
295 | }; | 289 | }; |
296 | 290 | ||
297 | static const struct soc_enum beep_config_enum = | 291 | static SOC_ENUM_SINGLE_DECL(beep_config_enum, |
298 | SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 6, | 292 | CS42L52_BEEP_TONE_CTL, 6, |
299 | ARRAY_SIZE(beep_config_text), beep_config_text); | 293 | beep_config_text); |
300 | 294 | ||
301 | static const char * const beep_bass_text[] = { | 295 | static const char * const beep_bass_text[] = { |
302 | "50 Hz", "100 Hz", "200 Hz", "250 Hz" | 296 | "50 Hz", "100 Hz", "200 Hz", "250 Hz" |
303 | }; | 297 | }; |
304 | 298 | ||
305 | static const struct soc_enum beep_bass_enum = | 299 | static SOC_ENUM_SINGLE_DECL(beep_bass_enum, |
306 | SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 1, | 300 | CS42L52_BEEP_TONE_CTL, 1, |
307 | ARRAY_SIZE(beep_bass_text), beep_bass_text); | 301 | beep_bass_text); |
308 | 302 | ||
309 | static const char * const beep_treble_text[] = { | 303 | static const char * const beep_treble_text[] = { |
310 | "5 kHz", "7 kHz", "10 kHz", " 15 kHz" | 304 | "5 kHz", "7 kHz", "10 kHz", " 15 kHz" |
311 | }; | 305 | }; |
312 | 306 | ||
313 | static const struct soc_enum beep_treble_enum = | 307 | static SOC_ENUM_SINGLE_DECL(beep_treble_enum, |
314 | SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 3, | 308 | CS42L52_BEEP_TONE_CTL, 3, |
315 | ARRAY_SIZE(beep_treble_text), beep_treble_text); | 309 | beep_treble_text); |
316 | 310 | ||
317 | static const char * const ng_threshold_text[] = { | 311 | static const char * const ng_threshold_text[] = { |
318 | "-34dB", "-37dB", "-40dB", "-43dB", | 312 | "-34dB", "-37dB", "-40dB", "-43dB", |
319 | "-46dB", "-52dB", "-58dB", "-64dB" | 313 | "-46dB", "-52dB", "-58dB", "-64dB" |
320 | }; | 314 | }; |
321 | 315 | ||
322 | static const struct soc_enum ng_threshold_enum = | 316 | static SOC_ENUM_SINGLE_DECL(ng_threshold_enum, |
323 | SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 2, | 317 | CS42L52_NOISE_GATE_CTL, 2, |
324 | ARRAY_SIZE(ng_threshold_text), ng_threshold_text); | 318 | ng_threshold_text); |
325 | 319 | ||
326 | static const char * const cs42l52_ng_delay_text[] = { | 320 | static const char * const cs42l52_ng_delay_text[] = { |
327 | "50ms", "100ms", "150ms", "200ms"}; | 321 | "50ms", "100ms", "150ms", "200ms"}; |
328 | 322 | ||
329 | static const struct soc_enum ng_delay_enum = | 323 | static SOC_ENUM_SINGLE_DECL(ng_delay_enum, |
330 | SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 0, | 324 | CS42L52_NOISE_GATE_CTL, 0, |
331 | ARRAY_SIZE(cs42l52_ng_delay_text), cs42l52_ng_delay_text); | 325 | cs42l52_ng_delay_text); |
332 | 326 | ||
333 | static const char * const cs42l52_ng_type_text[] = { | 327 | static const char * const cs42l52_ng_type_text[] = { |
334 | "Apply Specific", "Apply All" | 328 | "Apply Specific", "Apply All" |
335 | }; | 329 | }; |
336 | 330 | ||
337 | static const struct soc_enum ng_type_enum = | 331 | static SOC_ENUM_SINGLE_DECL(ng_type_enum, |
338 | SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 6, | 332 | CS42L52_NOISE_GATE_CTL, 6, |
339 | ARRAY_SIZE(cs42l52_ng_type_text), cs42l52_ng_type_text); | 333 | cs42l52_ng_type_text); |
340 | 334 | ||
341 | static const char * const left_swap_text[] = { | 335 | static const char * const left_swap_text[] = { |
342 | "Left", "LR 2", "Right"}; | 336 | "Left", "LR 2", "Right"}; |
@@ -347,7 +341,7 @@ static const char * const right_swap_text[] = { | |||
347 | static const unsigned int swap_values[] = { 0, 1, 3 }; | 341 | static const unsigned int swap_values[] = { 0, 1, 3 }; |
348 | 342 | ||
349 | static const struct soc_enum adca_swap_enum = | 343 | static const struct soc_enum adca_swap_enum = |
350 | SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 2, 1, | 344 | SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 2, 3, |
351 | ARRAY_SIZE(left_swap_text), | 345 | ARRAY_SIZE(left_swap_text), |
352 | left_swap_text, | 346 | left_swap_text, |
353 | swap_values); | 347 | swap_values); |
@@ -356,7 +350,7 @@ static const struct snd_kcontrol_new adca_mixer = | |||
356 | SOC_DAPM_ENUM("Route", adca_swap_enum); | 350 | SOC_DAPM_ENUM("Route", adca_swap_enum); |
357 | 351 | ||
358 | static const struct soc_enum pcma_swap_enum = | 352 | static const struct soc_enum pcma_swap_enum = |
359 | SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 6, 1, | 353 | SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 6, 3, |
360 | ARRAY_SIZE(left_swap_text), | 354 | ARRAY_SIZE(left_swap_text), |
361 | left_swap_text, | 355 | left_swap_text, |
362 | swap_values); | 356 | swap_values); |
@@ -365,7 +359,7 @@ static const struct snd_kcontrol_new pcma_mixer = | |||
365 | SOC_DAPM_ENUM("Route", pcma_swap_enum); | 359 | SOC_DAPM_ENUM("Route", pcma_swap_enum); |
366 | 360 | ||
367 | static const struct soc_enum adcb_swap_enum = | 361 | static const struct soc_enum adcb_swap_enum = |
368 | SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 0, 1, | 362 | SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 0, 3, |
369 | ARRAY_SIZE(right_swap_text), | 363 | ARRAY_SIZE(right_swap_text), |
370 | right_swap_text, | 364 | right_swap_text, |
371 | swap_values); | 365 | swap_values); |
@@ -374,7 +368,7 @@ static const struct snd_kcontrol_new adcb_mixer = | |||
374 | SOC_DAPM_ENUM("Route", adcb_swap_enum); | 368 | SOC_DAPM_ENUM("Route", adcb_swap_enum); |
375 | 369 | ||
376 | static const struct soc_enum pcmb_swap_enum = | 370 | static const struct soc_enum pcmb_swap_enum = |
377 | SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 4, 1, | 371 | SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 4, 3, |
378 | ARRAY_SIZE(right_swap_text), | 372 | ARRAY_SIZE(right_swap_text), |
379 | right_swap_text, | 373 | right_swap_text, |
380 | swap_values); | 374 | swap_values); |
@@ -1115,14 +1109,7 @@ static void cs42l52_free_beep(struct snd_soc_codec *codec) | |||
1115 | static int cs42l52_probe(struct snd_soc_codec *codec) | 1109 | static int cs42l52_probe(struct snd_soc_codec *codec) |
1116 | { | 1110 | { |
1117 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); | 1111 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); |
1118 | int ret; | ||
1119 | 1112 | ||
1120 | codec->control_data = cs42l52->regmap; | ||
1121 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1122 | if (ret < 0) { | ||
1123 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1124 | return ret; | ||
1125 | } | ||
1126 | regcache_cache_only(cs42l52->regmap, true); | 1113 | regcache_cache_only(cs42l52->regmap, true); |
1127 | 1114 | ||
1128 | cs42l52_add_mic_controls(codec); | 1115 | cs42l52_add_mic_controls(codec); |
@@ -1134,7 +1121,7 @@ static int cs42l52_probe(struct snd_soc_codec *codec) | |||
1134 | cs42l52->sysclk = CS42L52_DEFAULT_CLK; | 1121 | cs42l52->sysclk = CS42L52_DEFAULT_CLK; |
1135 | cs42l52->config.format = CS42L52_DEFAULT_FORMAT; | 1122 | cs42l52->config.format = CS42L52_DEFAULT_FORMAT; |
1136 | 1123 | ||
1137 | return ret; | 1124 | return 0; |
1138 | } | 1125 | } |
1139 | 1126 | ||
1140 | static int cs42l52_remove(struct snd_soc_codec *codec) | 1127 | static int cs42l52_remove(struct snd_soc_codec *codec) |
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 549d5d6a3fef..0ee60a19a263 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -278,13 +278,13 @@ static const DECLARE_TLV_DB_SCALE(attn_tlv, -6300, 100, 1); | |||
278 | static const char * const cs42l73_pgaa_text[] = { "Line A", "Mic 1" }; | 278 | static const char * const cs42l73_pgaa_text[] = { "Line A", "Mic 1" }; |
279 | static const char * const cs42l73_pgab_text[] = { "Line B", "Mic 2" }; | 279 | static const char * const cs42l73_pgab_text[] = { "Line B", "Mic 2" }; |
280 | 280 | ||
281 | static const struct soc_enum pgaa_enum = | 281 | static SOC_ENUM_SINGLE_DECL(pgaa_enum, |
282 | SOC_ENUM_SINGLE(CS42L73_ADCIPC, 3, | 282 | CS42L73_ADCIPC, 3, |
283 | ARRAY_SIZE(cs42l73_pgaa_text), cs42l73_pgaa_text); | 283 | cs42l73_pgaa_text); |
284 | 284 | ||
285 | static const struct soc_enum pgab_enum = | 285 | static SOC_ENUM_SINGLE_DECL(pgab_enum, |
286 | SOC_ENUM_SINGLE(CS42L73_ADCIPC, 7, | 286 | CS42L73_ADCIPC, 7, |
287 | ARRAY_SIZE(cs42l73_pgab_text), cs42l73_pgab_text); | 287 | cs42l73_pgab_text); |
288 | 288 | ||
289 | static const struct snd_kcontrol_new pgaa_mux = | 289 | static const struct snd_kcontrol_new pgaa_mux = |
290 | SOC_DAPM_ENUM("Left Analog Input Capture Mux", pgaa_enum); | 290 | SOC_DAPM_ENUM("Left Analog Input Capture Mux", pgaa_enum); |
@@ -309,9 +309,9 @@ static const struct snd_kcontrol_new input_right_mixer[] = { | |||
309 | static const char * const cs42l73_ng_delay_text[] = { | 309 | static const char * const cs42l73_ng_delay_text[] = { |
310 | "50ms", "100ms", "150ms", "200ms" }; | 310 | "50ms", "100ms", "150ms", "200ms" }; |
311 | 311 | ||
312 | static const struct soc_enum ng_delay_enum = | 312 | static SOC_ENUM_SINGLE_DECL(ng_delay_enum, |
313 | SOC_ENUM_SINGLE(CS42L73_NGCAB, 0, | 313 | CS42L73_NGCAB, 0, |
314 | ARRAY_SIZE(cs42l73_ng_delay_text), cs42l73_ng_delay_text); | 314 | cs42l73_ng_delay_text); |
315 | 315 | ||
316 | static const char * const cs42l73_mono_mix_texts[] = { | 316 | static const char * const cs42l73_mono_mix_texts[] = { |
317 | "Left", "Right", "Mono Mix"}; | 317 | "Left", "Right", "Mono Mix"}; |
@@ -319,7 +319,7 @@ static const char * const cs42l73_mono_mix_texts[] = { | |||
319 | static const unsigned int cs42l73_mono_mix_values[] = { 0, 1, 2 }; | 319 | static const unsigned int cs42l73_mono_mix_values[] = { 0, 1, 2 }; |
320 | 320 | ||
321 | static const struct soc_enum spk_asp_enum = | 321 | static const struct soc_enum spk_asp_enum = |
322 | SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 6, 1, | 322 | SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 6, 3, |
323 | ARRAY_SIZE(cs42l73_mono_mix_texts), | 323 | ARRAY_SIZE(cs42l73_mono_mix_texts), |
324 | cs42l73_mono_mix_texts, | 324 | cs42l73_mono_mix_texts, |
325 | cs42l73_mono_mix_values); | 325 | cs42l73_mono_mix_values); |
@@ -337,7 +337,7 @@ static const struct snd_kcontrol_new spk_xsp_mixer = | |||
337 | SOC_DAPM_ENUM("Route", spk_xsp_enum); | 337 | SOC_DAPM_ENUM("Route", spk_xsp_enum); |
338 | 338 | ||
339 | static const struct soc_enum esl_asp_enum = | 339 | static const struct soc_enum esl_asp_enum = |
340 | SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 2, 5, | 340 | SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 2, 3, |
341 | ARRAY_SIZE(cs42l73_mono_mix_texts), | 341 | ARRAY_SIZE(cs42l73_mono_mix_texts), |
342 | cs42l73_mono_mix_texts, | 342 | cs42l73_mono_mix_texts, |
343 | cs42l73_mono_mix_values); | 343 | cs42l73_mono_mix_values); |
@@ -346,7 +346,7 @@ static const struct snd_kcontrol_new esl_asp_mixer = | |||
346 | SOC_DAPM_ENUM("Route", esl_asp_enum); | 346 | SOC_DAPM_ENUM("Route", esl_asp_enum); |
347 | 347 | ||
348 | static const struct soc_enum esl_xsp_enum = | 348 | static const struct soc_enum esl_xsp_enum = |
349 | SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 0, 7, | 349 | SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 0, 3, |
350 | ARRAY_SIZE(cs42l73_mono_mix_texts), | 350 | ARRAY_SIZE(cs42l73_mono_mix_texts), |
351 | cs42l73_mono_mix_texts, | 351 | cs42l73_mono_mix_texts, |
352 | cs42l73_mono_mix_values); | 352 | cs42l73_mono_mix_values); |
@@ -357,19 +357,19 @@ static const struct snd_kcontrol_new esl_xsp_mixer = | |||
357 | static const char * const cs42l73_ip_swap_text[] = { | 357 | static const char * const cs42l73_ip_swap_text[] = { |
358 | "Stereo", "Mono A", "Mono B", "Swap A-B"}; | 358 | "Stereo", "Mono A", "Mono B", "Swap A-B"}; |
359 | 359 | ||
360 | static const struct soc_enum ip_swap_enum = | 360 | static SOC_ENUM_SINGLE_DECL(ip_swap_enum, |
361 | SOC_ENUM_SINGLE(CS42L73_MIOPC, 6, | 361 | CS42L73_MIOPC, 6, |
362 | ARRAY_SIZE(cs42l73_ip_swap_text), cs42l73_ip_swap_text); | 362 | cs42l73_ip_swap_text); |
363 | 363 | ||
364 | static const char * const cs42l73_spo_mixer_text[] = {"Mono", "Stereo"}; | 364 | static const char * const cs42l73_spo_mixer_text[] = {"Mono", "Stereo"}; |
365 | 365 | ||
366 | static const struct soc_enum vsp_output_mux_enum = | 366 | static SOC_ENUM_SINGLE_DECL(vsp_output_mux_enum, |
367 | SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 5, | 367 | CS42L73_MIXERCTL, 5, |
368 | ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text); | 368 | cs42l73_spo_mixer_text); |
369 | 369 | ||
370 | static const struct soc_enum xsp_output_mux_enum = | 370 | static SOC_ENUM_SINGLE_DECL(xsp_output_mux_enum, |
371 | SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 4, | 371 | CS42L73_MIXERCTL, 4, |
372 | ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text); | 372 | cs42l73_spo_mixer_text); |
373 | 373 | ||
374 | static const struct snd_kcontrol_new vsp_output_mux = | 374 | static const struct snd_kcontrol_new vsp_output_mux = |
375 | SOC_DAPM_ENUM("Route", vsp_output_mux_enum); | 375 | SOC_DAPM_ENUM("Route", vsp_output_mux_enum); |
@@ -1108,7 +1108,7 @@ static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |||
1108 | return 0; | 1108 | return 0; |
1109 | } | 1109 | } |
1110 | 1110 | ||
1111 | static u32 cs42l73_asrc_rates[] = { | 1111 | static const unsigned int cs42l73_asrc_rates[] = { |
1112 | 8000, 11025, 12000, 16000, 22050, | 1112 | 8000, 11025, 12000, 16000, 22050, |
1113 | 24000, 32000, 44100, 48000 | 1113 | 24000, 32000, 44100, 48000 |
1114 | }; | 1114 | }; |
@@ -1241,7 +1241,7 @@ static int cs42l73_set_tristate(struct snd_soc_dai *dai, int tristate) | |||
1241 | 0x7F, tristate << 7); | 1241 | 0x7F, tristate << 7); |
1242 | } | 1242 | } |
1243 | 1243 | ||
1244 | static struct snd_pcm_hw_constraint_list constraints_12_24 = { | 1244 | static const struct snd_pcm_hw_constraint_list constraints_12_24 = { |
1245 | .count = ARRAY_SIZE(cs42l73_asrc_rates), | 1245 | .count = ARRAY_SIZE(cs42l73_asrc_rates), |
1246 | .list = cs42l73_asrc_rates, | 1246 | .list = cs42l73_asrc_rates, |
1247 | }; | 1247 | }; |
@@ -1255,9 +1255,6 @@ static int cs42l73_pcm_startup(struct snd_pcm_substream *substream, | |||
1255 | return 0; | 1255 | return 0; |
1256 | } | 1256 | } |
1257 | 1257 | ||
1258 | /* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */ | ||
1259 | #define CS42L73_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT) | ||
1260 | |||
1261 | 1258 | ||
1262 | #define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | 1259 | #define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
1263 | SNDRV_PCM_FMTBIT_S24_LE) | 1260 | SNDRV_PCM_FMTBIT_S24_LE) |
@@ -1278,14 +1275,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { | |||
1278 | .stream_name = "XSP Playback", | 1275 | .stream_name = "XSP Playback", |
1279 | .channels_min = 1, | 1276 | .channels_min = 1, |
1280 | .channels_max = 2, | 1277 | .channels_max = 2, |
1281 | .rates = CS42L73_RATES, | 1278 | .rates = SNDRV_PCM_RATE_KNOT, |
1282 | .formats = CS42L73_FORMATS, | 1279 | .formats = CS42L73_FORMATS, |
1283 | }, | 1280 | }, |
1284 | .capture = { | 1281 | .capture = { |
1285 | .stream_name = "XSP Capture", | 1282 | .stream_name = "XSP Capture", |
1286 | .channels_min = 1, | 1283 | .channels_min = 1, |
1287 | .channels_max = 2, | 1284 | .channels_max = 2, |
1288 | .rates = CS42L73_RATES, | 1285 | .rates = SNDRV_PCM_RATE_KNOT, |
1289 | .formats = CS42L73_FORMATS, | 1286 | .formats = CS42L73_FORMATS, |
1290 | }, | 1287 | }, |
1291 | .ops = &cs42l73_ops, | 1288 | .ops = &cs42l73_ops, |
@@ -1298,14 +1295,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { | |||
1298 | .stream_name = "ASP Playback", | 1295 | .stream_name = "ASP Playback", |
1299 | .channels_min = 2, | 1296 | .channels_min = 2, |
1300 | .channels_max = 2, | 1297 | .channels_max = 2, |
1301 | .rates = CS42L73_RATES, | 1298 | .rates = SNDRV_PCM_RATE_KNOT, |
1302 | .formats = CS42L73_FORMATS, | 1299 | .formats = CS42L73_FORMATS, |
1303 | }, | 1300 | }, |
1304 | .capture = { | 1301 | .capture = { |
1305 | .stream_name = "ASP Capture", | 1302 | .stream_name = "ASP Capture", |
1306 | .channels_min = 2, | 1303 | .channels_min = 2, |
1307 | .channels_max = 2, | 1304 | .channels_max = 2, |
1308 | .rates = CS42L73_RATES, | 1305 | .rates = SNDRV_PCM_RATE_KNOT, |
1309 | .formats = CS42L73_FORMATS, | 1306 | .formats = CS42L73_FORMATS, |
1310 | }, | 1307 | }, |
1311 | .ops = &cs42l73_ops, | 1308 | .ops = &cs42l73_ops, |
@@ -1318,14 +1315,14 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { | |||
1318 | .stream_name = "VSP Playback", | 1315 | .stream_name = "VSP Playback", |
1319 | .channels_min = 1, | 1316 | .channels_min = 1, |
1320 | .channels_max = 2, | 1317 | .channels_max = 2, |
1321 | .rates = CS42L73_RATES, | 1318 | .rates = SNDRV_PCM_RATE_KNOT, |
1322 | .formats = CS42L73_FORMATS, | 1319 | .formats = CS42L73_FORMATS, |
1323 | }, | 1320 | }, |
1324 | .capture = { | 1321 | .capture = { |
1325 | .stream_name = "VSP Capture", | 1322 | .stream_name = "VSP Capture", |
1326 | .channels_min = 1, | 1323 | .channels_min = 1, |
1327 | .channels_max = 2, | 1324 | .channels_max = 2, |
1328 | .rates = CS42L73_RATES, | 1325 | .rates = SNDRV_PCM_RATE_KNOT, |
1329 | .formats = CS42L73_FORMATS, | 1326 | .formats = CS42L73_FORMATS, |
1330 | }, | 1327 | }, |
1331 | .ops = &cs42l73_ops, | 1328 | .ops = &cs42l73_ops, |
@@ -1348,17 +1345,8 @@ static int cs42l73_resume(struct snd_soc_codec *codec) | |||
1348 | 1345 | ||
1349 | static int cs42l73_probe(struct snd_soc_codec *codec) | 1346 | static int cs42l73_probe(struct snd_soc_codec *codec) |
1350 | { | 1347 | { |
1351 | int ret; | ||
1352 | struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec); | 1348 | struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec); |
1353 | 1349 | ||
1354 | codec->control_data = cs42l73->regmap; | ||
1355 | |||
1356 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1357 | if (ret < 0) { | ||
1358 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1359 | return ret; | ||
1360 | } | ||
1361 | |||
1362 | cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1350 | cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1363 | 1351 | ||
1364 | /* Set Charge Pump Frequency */ | 1352 | /* Set Charge Pump Frequency */ |
@@ -1371,7 +1359,7 @@ static int cs42l73_probe(struct snd_soc_codec *codec) | |||
1371 | cs42l73->mclksel = CS42L73_CLKID_MCLK1; | 1359 | cs42l73->mclksel = CS42L73_CLKID_MCLK1; |
1372 | cs42l73->mclk = 0; | 1360 | cs42l73->mclk = 0; |
1373 | 1361 | ||
1374 | return ret; | 1362 | return 0; |
1375 | } | 1363 | } |
1376 | 1364 | ||
1377 | static int cs42l73_remove(struct snd_soc_codec *codec) | 1365 | static int cs42l73_remove(struct snd_soc_codec *codec) |
diff --git a/sound/soc/codecs/cs42xx8-i2c.c b/sound/soc/codecs/cs42xx8-i2c.c new file mode 100644 index 000000000000..657dce27eade --- /dev/null +++ b/sound/soc/codecs/cs42xx8-i2c.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * Cirrus Logic CS42448/CS42888 Audio CODEC DAI I2C driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Freescale Semiconductor, Inc. | ||
5 | * | ||
6 | * Author: Nicolin Chen <Guangyu.Chen@freescale.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public License | ||
9 | * version 2. This program is licensed "as is" without any warranty of any | ||
10 | * kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/pm_runtime.h> | ||
16 | #include <sound/soc.h> | ||
17 | |||
18 | #include "cs42xx8.h" | ||
19 | |||
20 | static int cs42xx8_i2c_probe(struct i2c_client *i2c, | ||
21 | const struct i2c_device_id *id) | ||
22 | { | ||
23 | u32 ret = cs42xx8_probe(&i2c->dev, | ||
24 | devm_regmap_init_i2c(i2c, &cs42xx8_regmap_config)); | ||
25 | if (ret) | ||
26 | return ret; | ||
27 | |||
28 | pm_runtime_enable(&i2c->dev); | ||
29 | pm_request_idle(&i2c->dev); | ||
30 | |||
31 | return 0; | ||
32 | } | ||
33 | |||
34 | static int cs42xx8_i2c_remove(struct i2c_client *i2c) | ||
35 | { | ||
36 | snd_soc_unregister_codec(&i2c->dev); | ||
37 | pm_runtime_disable(&i2c->dev); | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static struct i2c_device_id cs42xx8_i2c_id[] = { | ||
43 | {"cs42448", (kernel_ulong_t)&cs42448_data}, | ||
44 | {"cs42888", (kernel_ulong_t)&cs42888_data}, | ||
45 | {} | ||
46 | }; | ||
47 | MODULE_DEVICE_TABLE(i2c, cs42xx8_i2c_id); | ||
48 | |||
49 | static struct i2c_driver cs42xx8_i2c_driver = { | ||
50 | .driver = { | ||
51 | .name = "cs42xx8", | ||
52 | .owner = THIS_MODULE, | ||
53 | .pm = &cs42xx8_pm, | ||
54 | }, | ||
55 | .probe = cs42xx8_i2c_probe, | ||
56 | .remove = cs42xx8_i2c_remove, | ||
57 | .id_table = cs42xx8_i2c_id, | ||
58 | }; | ||
59 | |||
60 | module_i2c_driver(cs42xx8_i2c_driver); | ||
61 | |||
62 | MODULE_DESCRIPTION("Cirrus Logic CS42448/CS42888 ALSA SoC Codec I2C Driver"); | ||
63 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
64 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c new file mode 100644 index 000000000000..082299a4e2fa --- /dev/null +++ b/sound/soc/codecs/cs42xx8.c | |||
@@ -0,0 +1,602 @@ | |||
1 | /* | ||
2 | * Cirrus Logic CS42448/CS42888 Audio CODEC Digital Audio Interface (DAI) driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Freescale Semiconductor, Inc. | ||
5 | * | ||
6 | * Author: Nicolin Chen <Guangyu.Chen@freescale.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public License | ||
9 | * version 2. This program is licensed "as is" without any warranty of any | ||
10 | * kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/clk.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of_device.h> | ||
17 | #include <linux/pm_runtime.h> | ||
18 | #include <linux/regulator/consumer.h> | ||
19 | #include <sound/pcm_params.h> | ||
20 | #include <sound/soc.h> | ||
21 | #include <sound/tlv.h> | ||
22 | |||
23 | #include "cs42xx8.h" | ||
24 | |||
25 | #define CS42XX8_NUM_SUPPLIES 4 | ||
26 | static const char *const cs42xx8_supply_names[CS42XX8_NUM_SUPPLIES] = { | ||
27 | "VA", | ||
28 | "VD", | ||
29 | "VLS", | ||
30 | "VLC", | ||
31 | }; | ||
32 | |||
33 | #define CS42XX8_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | ||
34 | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
35 | SNDRV_PCM_FMTBIT_S24_LE | \ | ||
36 | SNDRV_PCM_FMTBIT_S32_LE) | ||
37 | |||
38 | /* codec private data */ | ||
39 | struct cs42xx8_priv { | ||
40 | struct regulator_bulk_data supplies[CS42XX8_NUM_SUPPLIES]; | ||
41 | const struct cs42xx8_driver_data *drvdata; | ||
42 | struct regmap *regmap; | ||
43 | struct clk *clk; | ||
44 | |||
45 | bool slave_mode; | ||
46 | unsigned long sysclk; | ||
47 | }; | ||
48 | |||
49 | /* -127.5dB to 0dB with step of 0.5dB */ | ||
50 | static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); | ||
51 | /* -64dB to 24dB with step of 0.5dB */ | ||
52 | static const DECLARE_TLV_DB_SCALE(adc_tlv, -6400, 50, 0); | ||
53 | |||
54 | static const char *const cs42xx8_adc_single[] = { "Differential", "Single-Ended" }; | ||
55 | static const char *const cs42xx8_szc[] = { "Immediate Change", "Zero Cross", | ||
56 | "Soft Ramp", "Soft Ramp on Zero Cross" }; | ||
57 | |||
58 | static const struct soc_enum adc1_single_enum = | ||
59 | SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 4, 2, cs42xx8_adc_single); | ||
60 | static const struct soc_enum adc2_single_enum = | ||
61 | SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 3, 2, cs42xx8_adc_single); | ||
62 | static const struct soc_enum adc3_single_enum = | ||
63 | SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 2, 2, cs42xx8_adc_single); | ||
64 | static const struct soc_enum dac_szc_enum = | ||
65 | SOC_ENUM_SINGLE(CS42XX8_TXCTL, 5, 4, cs42xx8_szc); | ||
66 | static const struct soc_enum adc_szc_enum = | ||
67 | SOC_ENUM_SINGLE(CS42XX8_TXCTL, 0, 4, cs42xx8_szc); | ||
68 | |||
69 | static const struct snd_kcontrol_new cs42xx8_snd_controls[] = { | ||
70 | SOC_DOUBLE_R_TLV("DAC1 Playback Volume", CS42XX8_VOLAOUT1, | ||
71 | CS42XX8_VOLAOUT2, 0, 0xff, 1, dac_tlv), | ||
72 | SOC_DOUBLE_R_TLV("DAC2 Playback Volume", CS42XX8_VOLAOUT3, | ||
73 | CS42XX8_VOLAOUT4, 0, 0xff, 1, dac_tlv), | ||
74 | SOC_DOUBLE_R_TLV("DAC3 Playback Volume", CS42XX8_VOLAOUT5, | ||
75 | CS42XX8_VOLAOUT6, 0, 0xff, 1, dac_tlv), | ||
76 | SOC_DOUBLE_R_TLV("DAC4 Playback Volume", CS42XX8_VOLAOUT7, | ||
77 | CS42XX8_VOLAOUT8, 0, 0xff, 1, dac_tlv), | ||
78 | SOC_DOUBLE_R_S_TLV("ADC1 Capture Volume", CS42XX8_VOLAIN1, | ||
79 | CS42XX8_VOLAIN2, 0, -0x80, 0x30, 7, 0, adc_tlv), | ||
80 | SOC_DOUBLE_R_S_TLV("ADC2 Capture Volume", CS42XX8_VOLAIN3, | ||
81 | CS42XX8_VOLAIN4, 0, -0x80, 0x30, 7, 0, adc_tlv), | ||
82 | SOC_DOUBLE("DAC1 Invert Switch", CS42XX8_DACINV, 0, 1, 1, 0), | ||
83 | SOC_DOUBLE("DAC2 Invert Switch", CS42XX8_DACINV, 2, 3, 1, 0), | ||
84 | SOC_DOUBLE("DAC3 Invert Switch", CS42XX8_DACINV, 4, 5, 1, 0), | ||
85 | SOC_DOUBLE("DAC4 Invert Switch", CS42XX8_DACINV, 6, 7, 1, 0), | ||
86 | SOC_DOUBLE("ADC1 Invert Switch", CS42XX8_ADCINV, 0, 1, 1, 0), | ||
87 | SOC_DOUBLE("ADC2 Invert Switch", CS42XX8_ADCINV, 2, 3, 1, 0), | ||
88 | SOC_SINGLE("ADC High-Pass Filter Switch", CS42XX8_ADCCTL, 7, 1, 1), | ||
89 | SOC_SINGLE("DAC De-emphasis Switch", CS42XX8_ADCCTL, 5, 1, 0), | ||
90 | SOC_ENUM("ADC1 Single Ended Mode Switch", adc1_single_enum), | ||
91 | SOC_ENUM("ADC2 Single Ended Mode Switch", adc2_single_enum), | ||
92 | SOC_SINGLE("DAC Single Volume Control Switch", CS42XX8_TXCTL, 7, 1, 0), | ||
93 | SOC_ENUM("DAC Soft Ramp & Zero Cross Control Switch", dac_szc_enum), | ||
94 | SOC_SINGLE("DAC Auto Mute Switch", CS42XX8_TXCTL, 4, 1, 0), | ||
95 | SOC_SINGLE("Mute ADC Serial Port Switch", CS42XX8_TXCTL, 3, 1, 0), | ||
96 | SOC_SINGLE("ADC Single Volume Control Switch", CS42XX8_TXCTL, 2, 1, 0), | ||
97 | SOC_ENUM("ADC Soft Ramp & Zero Cross Control Switch", adc_szc_enum), | ||
98 | }; | ||
99 | |||
100 | static const struct snd_kcontrol_new cs42xx8_adc3_snd_controls[] = { | ||
101 | SOC_DOUBLE_R_S_TLV("ADC3 Capture Volume", CS42XX8_VOLAIN5, | ||
102 | CS42XX8_VOLAIN6, 0, -0x80, 0x30, 7, 0, adc_tlv), | ||
103 | SOC_DOUBLE("ADC3 Invert Switch", CS42XX8_ADCINV, 4, 5, 1, 0), | ||
104 | SOC_ENUM("ADC3 Single Ended Mode Switch", adc3_single_enum), | ||
105 | }; | ||
106 | |||
107 | static const struct snd_soc_dapm_widget cs42xx8_dapm_widgets[] = { | ||
108 | SND_SOC_DAPM_DAC("DAC1", "Playback", CS42XX8_PWRCTL, 1, 1), | ||
109 | SND_SOC_DAPM_DAC("DAC2", "Playback", CS42XX8_PWRCTL, 2, 1), | ||
110 | SND_SOC_DAPM_DAC("DAC3", "Playback", CS42XX8_PWRCTL, 3, 1), | ||
111 | SND_SOC_DAPM_DAC("DAC4", "Playback", CS42XX8_PWRCTL, 4, 1), | ||
112 | |||
113 | SND_SOC_DAPM_OUTPUT("AOUT1L"), | ||
114 | SND_SOC_DAPM_OUTPUT("AOUT1R"), | ||
115 | SND_SOC_DAPM_OUTPUT("AOUT2L"), | ||
116 | SND_SOC_DAPM_OUTPUT("AOUT2R"), | ||
117 | SND_SOC_DAPM_OUTPUT("AOUT3L"), | ||
118 | SND_SOC_DAPM_OUTPUT("AOUT3R"), | ||
119 | SND_SOC_DAPM_OUTPUT("AOUT4L"), | ||
120 | SND_SOC_DAPM_OUTPUT("AOUT4R"), | ||
121 | |||
122 | SND_SOC_DAPM_ADC("ADC1", "Capture", CS42XX8_PWRCTL, 5, 1), | ||
123 | SND_SOC_DAPM_ADC("ADC2", "Capture", CS42XX8_PWRCTL, 6, 1), | ||
124 | |||
125 | SND_SOC_DAPM_INPUT("AIN1L"), | ||
126 | SND_SOC_DAPM_INPUT("AIN1R"), | ||
127 | SND_SOC_DAPM_INPUT("AIN2L"), | ||
128 | SND_SOC_DAPM_INPUT("AIN2R"), | ||
129 | |||
130 | SND_SOC_DAPM_SUPPLY("PWR", CS42XX8_PWRCTL, 0, 1, NULL, 0), | ||
131 | }; | ||
132 | |||
133 | static const struct snd_soc_dapm_widget cs42xx8_adc3_dapm_widgets[] = { | ||
134 | SND_SOC_DAPM_ADC("ADC3", "Capture", CS42XX8_PWRCTL, 7, 1), | ||
135 | |||
136 | SND_SOC_DAPM_INPUT("AIN3L"), | ||
137 | SND_SOC_DAPM_INPUT("AIN3R"), | ||
138 | }; | ||
139 | |||
140 | static const struct snd_soc_dapm_route cs42xx8_dapm_routes[] = { | ||
141 | /* Playback */ | ||
142 | { "AOUT1L", NULL, "DAC1" }, | ||
143 | { "AOUT1R", NULL, "DAC1" }, | ||
144 | { "DAC1", NULL, "PWR" }, | ||
145 | |||
146 | { "AOUT2L", NULL, "DAC2" }, | ||
147 | { "AOUT2R", NULL, "DAC2" }, | ||
148 | { "DAC2", NULL, "PWR" }, | ||
149 | |||
150 | { "AOUT3L", NULL, "DAC3" }, | ||
151 | { "AOUT3R", NULL, "DAC3" }, | ||
152 | { "DAC3", NULL, "PWR" }, | ||
153 | |||
154 | { "AOUT4L", NULL, "DAC4" }, | ||
155 | { "AOUT4R", NULL, "DAC4" }, | ||
156 | { "DAC4", NULL, "PWR" }, | ||
157 | |||
158 | /* Capture */ | ||
159 | { "ADC1", NULL, "AIN1L" }, | ||
160 | { "ADC1", NULL, "AIN1R" }, | ||
161 | { "ADC1", NULL, "PWR" }, | ||
162 | |||
163 | { "ADC2", NULL, "AIN2L" }, | ||
164 | { "ADC2", NULL, "AIN2R" }, | ||
165 | { "ADC2", NULL, "PWR" }, | ||
166 | }; | ||
167 | |||
168 | static const struct snd_soc_dapm_route cs42xx8_adc3_dapm_routes[] = { | ||
169 | /* Capture */ | ||
170 | { "ADC3", NULL, "AIN3L" }, | ||
171 | { "ADC3", NULL, "AIN3R" }, | ||
172 | { "ADC3", NULL, "PWR" }, | ||
173 | }; | ||
174 | |||
175 | struct cs42xx8_ratios { | ||
176 | unsigned int ratio; | ||
177 | unsigned char speed; | ||
178 | unsigned char mclk; | ||
179 | }; | ||
180 | |||
181 | static const struct cs42xx8_ratios cs42xx8_ratios[] = { | ||
182 | { 64, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_256(4) }, | ||
183 | { 96, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_384(4) }, | ||
184 | { 128, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_512(4) }, | ||
185 | { 192, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_768(4) }, | ||
186 | { 256, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_256(1) }, | ||
187 | { 384, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_384(1) }, | ||
188 | { 512, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_512(1) }, | ||
189 | { 768, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_768(1) }, | ||
190 | { 1024, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_1024(1) } | ||
191 | }; | ||
192 | |||
193 | static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai, | ||
194 | int clk_id, unsigned int freq, int dir) | ||
195 | { | ||
196 | struct snd_soc_codec *codec = codec_dai->codec; | ||
197 | struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec); | ||
198 | |||
199 | cs42xx8->sysclk = freq; | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
205 | unsigned int format) | ||
206 | { | ||
207 | struct snd_soc_codec *codec = codec_dai->codec; | ||
208 | struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec); | ||
209 | u32 val; | ||
210 | |||
211 | /* Set DAI format */ | ||
212 | switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
213 | case SND_SOC_DAIFMT_LEFT_J: | ||
214 | val = CS42XX8_INTF_DAC_DIF_LEFTJ | CS42XX8_INTF_ADC_DIF_LEFTJ; | ||
215 | break; | ||
216 | case SND_SOC_DAIFMT_I2S: | ||
217 | val = CS42XX8_INTF_DAC_DIF_I2S | CS42XX8_INTF_ADC_DIF_I2S; | ||
218 | break; | ||
219 | case SND_SOC_DAIFMT_RIGHT_J: | ||
220 | val = CS42XX8_INTF_DAC_DIF_RIGHTJ | CS42XX8_INTF_ADC_DIF_RIGHTJ; | ||
221 | break; | ||
222 | default: | ||
223 | dev_err(codec->dev, "unsupported dai format\n"); | ||
224 | return -EINVAL; | ||
225 | } | ||
226 | |||
227 | regmap_update_bits(cs42xx8->regmap, CS42XX8_INTF, | ||
228 | CS42XX8_INTF_DAC_DIF_MASK | | ||
229 | CS42XX8_INTF_ADC_DIF_MASK, val); | ||
230 | |||
231 | /* Set master/slave audio interface */ | ||
232 | switch (format & SND_SOC_DAIFMT_MASTER_MASK) { | ||
233 | case SND_SOC_DAIFMT_CBS_CFS: | ||
234 | cs42xx8->slave_mode = true; | ||
235 | break; | ||
236 | case SND_SOC_DAIFMT_CBM_CFM: | ||
237 | cs42xx8->slave_mode = false; | ||
238 | break; | ||
239 | default: | ||
240 | dev_err(codec->dev, "unsupported master/slave mode\n"); | ||
241 | return -EINVAL; | ||
242 | } | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static int cs42xx8_hw_params(struct snd_pcm_substream *substream, | ||
248 | struct snd_pcm_hw_params *params, | ||
249 | struct snd_soc_dai *dai) | ||
250 | { | ||
251 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
252 | struct snd_soc_codec *codec = rtd->codec; | ||
253 | struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec); | ||
254 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | ||
255 | u32 ratio = cs42xx8->sysclk / params_rate(params); | ||
256 | u32 i, fm, val, mask; | ||
257 | |||
258 | for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) { | ||
259 | if (cs42xx8_ratios[i].ratio == ratio) | ||
260 | break; | ||
261 | } | ||
262 | |||
263 | if (i == ARRAY_SIZE(cs42xx8_ratios)) { | ||
264 | dev_err(codec->dev, "unsupported sysclk ratio\n"); | ||
265 | return -EINVAL; | ||
266 | } | ||
267 | |||
268 | mask = CS42XX8_FUNCMOD_MFREQ_MASK; | ||
269 | val = cs42xx8_ratios[i].mclk; | ||
270 | |||
271 | fm = cs42xx8->slave_mode ? CS42XX8_FM_AUTO : cs42xx8_ratios[i].speed; | ||
272 | |||
273 | regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD, | ||
274 | CS42XX8_FUNCMOD_xC_FM_MASK(tx) | mask, | ||
275 | CS42XX8_FUNCMOD_xC_FM(tx, fm) | val); | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | static int cs42xx8_digital_mute(struct snd_soc_dai *dai, int mute) | ||
281 | { | ||
282 | struct snd_soc_codec *codec = dai->codec; | ||
283 | struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec); | ||
284 | |||
285 | regmap_update_bits(cs42xx8->regmap, CS42XX8_DACMUTE, | ||
286 | CS42XX8_DACMUTE_ALL, mute ? CS42XX8_DACMUTE_ALL : 0); | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static const struct snd_soc_dai_ops cs42xx8_dai_ops = { | ||
292 | .set_fmt = cs42xx8_set_dai_fmt, | ||
293 | .set_sysclk = cs42xx8_set_dai_sysclk, | ||
294 | .hw_params = cs42xx8_hw_params, | ||
295 | .digital_mute = cs42xx8_digital_mute, | ||
296 | }; | ||
297 | |||
298 | static struct snd_soc_dai_driver cs42xx8_dai = { | ||
299 | .playback = { | ||
300 | .stream_name = "Playback", | ||
301 | .channels_min = 1, | ||
302 | .channels_max = 8, | ||
303 | .rates = SNDRV_PCM_RATE_8000_192000, | ||
304 | .formats = CS42XX8_FORMATS, | ||
305 | }, | ||
306 | .capture = { | ||
307 | .stream_name = "Capture", | ||
308 | .channels_min = 1, | ||
309 | .rates = SNDRV_PCM_RATE_8000_192000, | ||
310 | .formats = CS42XX8_FORMATS, | ||
311 | }, | ||
312 | .ops = &cs42xx8_dai_ops, | ||
313 | }; | ||
314 | |||
315 | static const struct reg_default cs42xx8_reg[] = { | ||
316 | { 0x01, 0x01 }, /* Chip I.D. and Revision Register */ | ||
317 | { 0x02, 0x00 }, /* Power Control */ | ||
318 | { 0x03, 0xF0 }, /* Functional Mode */ | ||
319 | { 0x04, 0x46 }, /* Interface Formats */ | ||
320 | { 0x05, 0x00 }, /* ADC Control & DAC De-Emphasis */ | ||
321 | { 0x06, 0x10 }, /* Transition Control */ | ||
322 | { 0x07, 0x00 }, /* DAC Channel Mute */ | ||
323 | { 0x08, 0x00 }, /* Volume Control AOUT1 */ | ||
324 | { 0x09, 0x00 }, /* Volume Control AOUT2 */ | ||
325 | { 0x0a, 0x00 }, /* Volume Control AOUT3 */ | ||
326 | { 0x0b, 0x00 }, /* Volume Control AOUT4 */ | ||
327 | { 0x0c, 0x00 }, /* Volume Control AOUT5 */ | ||
328 | { 0x0d, 0x00 }, /* Volume Control AOUT6 */ | ||
329 | { 0x0e, 0x00 }, /* Volume Control AOUT7 */ | ||
330 | { 0x0f, 0x00 }, /* Volume Control AOUT8 */ | ||
331 | { 0x10, 0x00 }, /* DAC Channel Invert */ | ||
332 | { 0x11, 0x00 }, /* Volume Control AIN1 */ | ||
333 | { 0x12, 0x00 }, /* Volume Control AIN2 */ | ||
334 | { 0x13, 0x00 }, /* Volume Control AIN3 */ | ||
335 | { 0x14, 0x00 }, /* Volume Control AIN4 */ | ||
336 | { 0x15, 0x00 }, /* Volume Control AIN5 */ | ||
337 | { 0x16, 0x00 }, /* Volume Control AIN6 */ | ||
338 | { 0x17, 0x00 }, /* ADC Channel Invert */ | ||
339 | { 0x18, 0x00 }, /* Status Control */ | ||
340 | { 0x1a, 0x00 }, /* Status Mask */ | ||
341 | { 0x1b, 0x00 }, /* MUTEC Pin Control */ | ||
342 | }; | ||
343 | |||
344 | static bool cs42xx8_volatile_register(struct device *dev, unsigned int reg) | ||
345 | { | ||
346 | switch (reg) { | ||
347 | case CS42XX8_STATUS: | ||
348 | return true; | ||
349 | default: | ||
350 | return false; | ||
351 | } | ||
352 | } | ||
353 | |||
354 | static bool cs42xx8_writeable_register(struct device *dev, unsigned int reg) | ||
355 | { | ||
356 | switch (reg) { | ||
357 | case CS42XX8_CHIPID: | ||
358 | case CS42XX8_STATUS: | ||
359 | return false; | ||
360 | default: | ||
361 | return true; | ||
362 | } | ||
363 | } | ||
364 | |||
365 | const struct regmap_config cs42xx8_regmap_config = { | ||
366 | .reg_bits = 8, | ||
367 | .val_bits = 8, | ||
368 | |||
369 | .max_register = CS42XX8_LASTREG, | ||
370 | .reg_defaults = cs42xx8_reg, | ||
371 | .num_reg_defaults = ARRAY_SIZE(cs42xx8_reg), | ||
372 | .volatile_reg = cs42xx8_volatile_register, | ||
373 | .writeable_reg = cs42xx8_writeable_register, | ||
374 | .cache_type = REGCACHE_RBTREE, | ||
375 | }; | ||
376 | EXPORT_SYMBOL_GPL(cs42xx8_regmap_config); | ||
377 | |||
378 | static int cs42xx8_codec_probe(struct snd_soc_codec *codec) | ||
379 | { | ||
380 | struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec); | ||
381 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
382 | |||
383 | switch (cs42xx8->drvdata->num_adcs) { | ||
384 | case 3: | ||
385 | snd_soc_add_codec_controls(codec, cs42xx8_adc3_snd_controls, | ||
386 | ARRAY_SIZE(cs42xx8_adc3_snd_controls)); | ||
387 | snd_soc_dapm_new_controls(dapm, cs42xx8_adc3_dapm_widgets, | ||
388 | ARRAY_SIZE(cs42xx8_adc3_dapm_widgets)); | ||
389 | snd_soc_dapm_add_routes(dapm, cs42xx8_adc3_dapm_routes, | ||
390 | ARRAY_SIZE(cs42xx8_adc3_dapm_routes)); | ||
391 | break; | ||
392 | default: | ||
393 | break; | ||
394 | } | ||
395 | |||
396 | /* Mute all DAC channels */ | ||
397 | regmap_write(cs42xx8->regmap, CS42XX8_DACMUTE, CS42XX8_DACMUTE_ALL); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static const struct snd_soc_codec_driver cs42xx8_driver = { | ||
403 | .probe = cs42xx8_codec_probe, | ||
404 | .idle_bias_off = true, | ||
405 | |||
406 | .controls = cs42xx8_snd_controls, | ||
407 | .num_controls = ARRAY_SIZE(cs42xx8_snd_controls), | ||
408 | .dapm_widgets = cs42xx8_dapm_widgets, | ||
409 | .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets), | ||
410 | .dapm_routes = cs42xx8_dapm_routes, | ||
411 | .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes), | ||
412 | }; | ||
413 | |||
414 | const struct cs42xx8_driver_data cs42448_data = { | ||
415 | .name = "cs42448", | ||
416 | .num_adcs = 3, | ||
417 | }; | ||
418 | EXPORT_SYMBOL_GPL(cs42448_data); | ||
419 | |||
420 | const struct cs42xx8_driver_data cs42888_data = { | ||
421 | .name = "cs42888", | ||
422 | .num_adcs = 2, | ||
423 | }; | ||
424 | EXPORT_SYMBOL_GPL(cs42888_data); | ||
425 | |||
426 | const struct of_device_id cs42xx8_of_match[] = { | ||
427 | { .compatible = "cirrus,cs42448", .data = &cs42448_data, }, | ||
428 | { .compatible = "cirrus,cs42888", .data = &cs42888_data, }, | ||
429 | { /* sentinel */ } | ||
430 | }; | ||
431 | MODULE_DEVICE_TABLE(of, cs42xx8_of_match); | ||
432 | EXPORT_SYMBOL_GPL(cs42xx8_of_match); | ||
433 | |||
434 | int cs42xx8_probe(struct device *dev, struct regmap *regmap) | ||
435 | { | ||
436 | const struct of_device_id *of_id = of_match_device(cs42xx8_of_match, dev); | ||
437 | struct cs42xx8_priv *cs42xx8; | ||
438 | int ret, val, i; | ||
439 | |||
440 | cs42xx8 = devm_kzalloc(dev, sizeof(*cs42xx8), GFP_KERNEL); | ||
441 | if (cs42xx8 == NULL) | ||
442 | return -ENOMEM; | ||
443 | |||
444 | dev_set_drvdata(dev, cs42xx8); | ||
445 | |||
446 | if (of_id) | ||
447 | cs42xx8->drvdata = of_id->data; | ||
448 | |||
449 | if (!cs42xx8->drvdata) { | ||
450 | dev_err(dev, "failed to find driver data\n"); | ||
451 | return -EINVAL; | ||
452 | } | ||
453 | |||
454 | cs42xx8->clk = devm_clk_get(dev, "mclk"); | ||
455 | if (IS_ERR(cs42xx8->clk)) { | ||
456 | dev_err(dev, "failed to get the clock: %ld\n", | ||
457 | PTR_ERR(cs42xx8->clk)); | ||
458 | return -EINVAL; | ||
459 | } | ||
460 | |||
461 | cs42xx8->sysclk = clk_get_rate(cs42xx8->clk); | ||
462 | |||
463 | for (i = 0; i < ARRAY_SIZE(cs42xx8->supplies); i++) | ||
464 | cs42xx8->supplies[i].supply = cs42xx8_supply_names[i]; | ||
465 | |||
466 | ret = devm_regulator_bulk_get(dev, | ||
467 | ARRAY_SIZE(cs42xx8->supplies), cs42xx8->supplies); | ||
468 | if (ret) { | ||
469 | dev_err(dev, "failed to request supplies: %d\n", ret); | ||
470 | return ret; | ||
471 | } | ||
472 | |||
473 | ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies), | ||
474 | cs42xx8->supplies); | ||
475 | if (ret) { | ||
476 | dev_err(dev, "failed to enable supplies: %d\n", ret); | ||
477 | return ret; | ||
478 | } | ||
479 | |||
480 | /* Make sure hardware reset done */ | ||
481 | msleep(5); | ||
482 | |||
483 | cs42xx8->regmap = regmap; | ||
484 | if (IS_ERR(cs42xx8->regmap)) { | ||
485 | ret = PTR_ERR(cs42xx8->regmap); | ||
486 | dev_err(dev, "failed to allocate regmap: %d\n", ret); | ||
487 | goto err_enable; | ||
488 | } | ||
489 | |||
490 | /* | ||
491 | * We haven't marked the chip revision as volatile due to | ||
492 | * sharing a register with the right input volume; explicitly | ||
493 | * bypass the cache to read it. | ||
494 | */ | ||
495 | regcache_cache_bypass(cs42xx8->regmap, true); | ||
496 | |||
497 | /* Validate the chip ID */ | ||
498 | regmap_read(cs42xx8->regmap, CS42XX8_CHIPID, &val); | ||
499 | if (val < 0) { | ||
500 | dev_err(dev, "failed to get device ID: %x", val); | ||
501 | ret = -EINVAL; | ||
502 | goto err_enable; | ||
503 | } | ||
504 | |||
505 | /* The top four bits of the chip ID should be 0000 */ | ||
506 | if ((val & CS42XX8_CHIPID_CHIP_ID_MASK) != 0x00) { | ||
507 | dev_err(dev, "unmatched chip ID: %d\n", | ||
508 | val & CS42XX8_CHIPID_CHIP_ID_MASK); | ||
509 | ret = -EINVAL; | ||
510 | goto err_enable; | ||
511 | } | ||
512 | |||
513 | dev_info(dev, "found device, revision %X\n", | ||
514 | val & CS42XX8_CHIPID_REV_ID_MASK); | ||
515 | |||
516 | regcache_cache_bypass(cs42xx8->regmap, false); | ||
517 | |||
518 | cs42xx8_dai.name = cs42xx8->drvdata->name; | ||
519 | |||
520 | /* Each adc supports stereo input */ | ||
521 | cs42xx8_dai.capture.channels_max = cs42xx8->drvdata->num_adcs * 2; | ||
522 | |||
523 | ret = snd_soc_register_codec(dev, &cs42xx8_driver, &cs42xx8_dai, 1); | ||
524 | if (ret) { | ||
525 | dev_err(dev, "failed to register codec:%d\n", ret); | ||
526 | goto err_enable; | ||
527 | } | ||
528 | |||
529 | regcache_cache_only(cs42xx8->regmap, true); | ||
530 | |||
531 | err_enable: | ||
532 | regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies), | ||
533 | cs42xx8->supplies); | ||
534 | |||
535 | return ret; | ||
536 | } | ||
537 | EXPORT_SYMBOL_GPL(cs42xx8_probe); | ||
538 | |||
539 | #ifdef CONFIG_PM_RUNTIME | ||
540 | static int cs42xx8_runtime_resume(struct device *dev) | ||
541 | { | ||
542 | struct cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev); | ||
543 | int ret; | ||
544 | |||
545 | ret = clk_prepare_enable(cs42xx8->clk); | ||
546 | if (ret) { | ||
547 | dev_err(dev, "failed to enable mclk: %d\n", ret); | ||
548 | return ret; | ||
549 | } | ||
550 | |||
551 | ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies), | ||
552 | cs42xx8->supplies); | ||
553 | if (ret) { | ||
554 | dev_err(dev, "failed to enable supplies: %d\n", ret); | ||
555 | goto err_clk; | ||
556 | } | ||
557 | |||
558 | /* Make sure hardware reset done */ | ||
559 | msleep(5); | ||
560 | |||
561 | regcache_cache_only(cs42xx8->regmap, false); | ||
562 | |||
563 | ret = regcache_sync(cs42xx8->regmap); | ||
564 | if (ret) { | ||
565 | dev_err(dev, "failed to sync regmap: %d\n", ret); | ||
566 | goto err_bulk; | ||
567 | } | ||
568 | |||
569 | return 0; | ||
570 | |||
571 | err_bulk: | ||
572 | regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies), | ||
573 | cs42xx8->supplies); | ||
574 | err_clk: | ||
575 | clk_disable_unprepare(cs42xx8->clk); | ||
576 | |||
577 | return ret; | ||
578 | } | ||
579 | |||
580 | static int cs42xx8_runtime_suspend(struct device *dev) | ||
581 | { | ||
582 | struct cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev); | ||
583 | |||
584 | regcache_cache_only(cs42xx8->regmap, true); | ||
585 | |||
586 | regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies), | ||
587 | cs42xx8->supplies); | ||
588 | |||
589 | clk_disable_unprepare(cs42xx8->clk); | ||
590 | |||
591 | return 0; | ||
592 | } | ||
593 | #endif | ||
594 | |||
595 | const struct dev_pm_ops cs42xx8_pm = { | ||
596 | SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL) | ||
597 | }; | ||
598 | EXPORT_SYMBOL_GPL(cs42xx8_pm); | ||
599 | |||
600 | MODULE_DESCRIPTION("Cirrus Logic CS42448/CS42888 ALSA SoC Codec Driver"); | ||
601 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
602 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/cs42xx8.h b/sound/soc/codecs/cs42xx8.h new file mode 100644 index 000000000000..da0b94aee419 --- /dev/null +++ b/sound/soc/codecs/cs42xx8.h | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | * cs42xx8.h - Cirrus Logic CS42448/CS42888 Audio CODEC driver header file | ||
3 | * | ||
4 | * Copyright (C) 2014 Freescale Semiconductor, Inc. | ||
5 | * | ||
6 | * Author: Nicolin Chen <Guangyu.Chen@freescale.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public License | ||
9 | * version 2. This program is licensed "as is" without any warranty of any | ||
10 | * kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #ifndef _CS42XX8_H | ||
14 | #define _CS42XX8_H | ||
15 | |||
16 | struct cs42xx8_driver_data { | ||
17 | char name[32]; | ||
18 | int num_adcs; | ||
19 | }; | ||
20 | |||
21 | extern const struct dev_pm_ops cs42xx8_pm; | ||
22 | extern const struct cs42xx8_driver_data cs42448_data; | ||
23 | extern const struct cs42xx8_driver_data cs42888_data; | ||
24 | extern const struct regmap_config cs42xx8_regmap_config; | ||
25 | int cs42xx8_probe(struct device *dev, struct regmap *regmap); | ||
26 | |||
27 | /* CS42888 register map */ | ||
28 | #define CS42XX8_CHIPID 0x01 /* Chip ID */ | ||
29 | #define CS42XX8_PWRCTL 0x02 /* Power Control */ | ||
30 | #define CS42XX8_FUNCMOD 0x03 /* Functional Mode */ | ||
31 | #define CS42XX8_INTF 0x04 /* Interface Formats */ | ||
32 | #define CS42XX8_ADCCTL 0x05 /* ADC Control */ | ||
33 | #define CS42XX8_TXCTL 0x06 /* Transition Control */ | ||
34 | #define CS42XX8_DACMUTE 0x07 /* DAC Mute Control */ | ||
35 | #define CS42XX8_VOLAOUT1 0x08 /* Volume Control AOUT1 */ | ||
36 | #define CS42XX8_VOLAOUT2 0x09 /* Volume Control AOUT2 */ | ||
37 | #define CS42XX8_VOLAOUT3 0x0A /* Volume Control AOUT3 */ | ||
38 | #define CS42XX8_VOLAOUT4 0x0B /* Volume Control AOUT4 */ | ||
39 | #define CS42XX8_VOLAOUT5 0x0C /* Volume Control AOUT5 */ | ||
40 | #define CS42XX8_VOLAOUT6 0x0D /* Volume Control AOUT6 */ | ||
41 | #define CS42XX8_VOLAOUT7 0x0E /* Volume Control AOUT7 */ | ||
42 | #define CS42XX8_VOLAOUT8 0x0F /* Volume Control AOUT8 */ | ||
43 | #define CS42XX8_DACINV 0x10 /* DAC Channel Invert */ | ||
44 | #define CS42XX8_VOLAIN1 0x11 /* Volume Control AIN1 */ | ||
45 | #define CS42XX8_VOLAIN2 0x12 /* Volume Control AIN2 */ | ||
46 | #define CS42XX8_VOLAIN3 0x13 /* Volume Control AIN3 */ | ||
47 | #define CS42XX8_VOLAIN4 0x14 /* Volume Control AIN4 */ | ||
48 | #define CS42XX8_VOLAIN5 0x15 /* Volume Control AIN5 */ | ||
49 | #define CS42XX8_VOLAIN6 0x16 /* Volume Control AIN6 */ | ||
50 | #define CS42XX8_ADCINV 0x17 /* ADC Channel Invert */ | ||
51 | #define CS42XX8_STATUSCTL 0x18 /* Status Control */ | ||
52 | #define CS42XX8_STATUS 0x19 /* Status */ | ||
53 | #define CS42XX8_STATUSM 0x1A /* Status Mask */ | ||
54 | #define CS42XX8_MUTEC 0x1B /* MUTEC Pin Control */ | ||
55 | |||
56 | #define CS42XX8_FIRSTREG CS42XX8_CHIPID | ||
57 | #define CS42XX8_LASTREG CS42XX8_MUTEC | ||
58 | #define CS42XX8_NUMREGS (CS42XX8_LASTREG - CS42XX8_FIRSTREG + 1) | ||
59 | #define CS42XX8_I2C_INCR 0x80 | ||
60 | |||
61 | /* Chip I.D. and Revision Register (Address 01h) */ | ||
62 | #define CS42XX8_CHIPID_CHIP_ID_MASK 0xF0 | ||
63 | #define CS42XX8_CHIPID_REV_ID_MASK 0x0F | ||
64 | |||
65 | /* Power Control (Address 02h) */ | ||
66 | #define CS42XX8_PWRCTL_PDN_ADC3_SHIFT 7 | ||
67 | #define CS42XX8_PWRCTL_PDN_ADC3_MASK (1 << CS42XX8_PWRCTL_PDN_ADC3_SHIFT) | ||
68 | #define CS42XX8_PWRCTL_PDN_ADC3 (1 << CS42XX8_PWRCTL_PDN_ADC3_SHIFT) | ||
69 | #define CS42XX8_PWRCTL_PDN_ADC2_SHIFT 6 | ||
70 | #define CS42XX8_PWRCTL_PDN_ADC2_MASK (1 << CS42XX8_PWRCTL_PDN_ADC2_SHIFT) | ||
71 | #define CS42XX8_PWRCTL_PDN_ADC2 (1 << CS42XX8_PWRCTL_PDN_ADC2_SHIFT) | ||
72 | #define CS42XX8_PWRCTL_PDN_ADC1_SHIFT 5 | ||
73 | #define CS42XX8_PWRCTL_PDN_ADC1_MASK (1 << CS42XX8_PWRCTL_PDN_ADC1_SHIFT) | ||
74 | #define CS42XX8_PWRCTL_PDN_ADC1 (1 << CS42XX8_PWRCTL_PDN_ADC1_SHIFT) | ||
75 | #define CS42XX8_PWRCTL_PDN_DAC4_SHIFT 4 | ||
76 | #define CS42XX8_PWRCTL_PDN_DAC4_MASK (1 << CS42XX8_PWRCTL_PDN_DAC4_SHIFT) | ||
77 | #define CS42XX8_PWRCTL_PDN_DAC4 (1 << CS42XX8_PWRCTL_PDN_DAC4_SHIFT) | ||
78 | #define CS42XX8_PWRCTL_PDN_DAC3_SHIFT 3 | ||
79 | #define CS42XX8_PWRCTL_PDN_DAC3_MASK (1 << CS42XX8_PWRCTL_PDN_DAC3_SHIFT) | ||
80 | #define CS42XX8_PWRCTL_PDN_DAC3 (1 << CS42XX8_PWRCTL_PDN_DAC3_SHIFT) | ||
81 | #define CS42XX8_PWRCTL_PDN_DAC2_SHIFT 2 | ||
82 | #define CS42XX8_PWRCTL_PDN_DAC2_MASK (1 << CS42XX8_PWRCTL_PDN_DAC2_SHIFT) | ||
83 | #define CS42XX8_PWRCTL_PDN_DAC2 (1 << CS42XX8_PWRCTL_PDN_DAC2_SHIFT) | ||
84 | #define CS42XX8_PWRCTL_PDN_DAC1_SHIFT 1 | ||
85 | #define CS42XX8_PWRCTL_PDN_DAC1_MASK (1 << CS42XX8_PWRCTL_PDN_DAC1_SHIFT) | ||
86 | #define CS42XX8_PWRCTL_PDN_DAC1 (1 << CS42XX8_PWRCTL_PDN_DAC1_SHIFT) | ||
87 | #define CS42XX8_PWRCTL_PDN_SHIFT 0 | ||
88 | #define CS42XX8_PWRCTL_PDN_MASK (1 << CS42XX8_PWRCTL_PDN_SHIFT) | ||
89 | #define CS42XX8_PWRCTL_PDN (1 << CS42XX8_PWRCTL_PDN_SHIFT) | ||
90 | |||
91 | /* Functional Mode (Address 03h) */ | ||
92 | #define CS42XX8_FUNCMOD_DAC_FM_SHIFT 6 | ||
93 | #define CS42XX8_FUNCMOD_DAC_FM_WIDTH 2 | ||
94 | #define CS42XX8_FUNCMOD_DAC_FM_MASK (((1 << CS42XX8_FUNCMOD_DAC_FM_WIDTH) - 1) << CS42XX8_FUNCMOD_DAC_FM_SHIFT) | ||
95 | #define CS42XX8_FUNCMOD_DAC_FM(v) ((v) << CS42XX8_FUNCMOD_DAC_FM_SHIFT) | ||
96 | #define CS42XX8_FUNCMOD_ADC_FM_SHIFT 4 | ||
97 | #define CS42XX8_FUNCMOD_ADC_FM_WIDTH 2 | ||
98 | #define CS42XX8_FUNCMOD_ADC_FM_MASK (((1 << CS42XX8_FUNCMOD_ADC_FM_WIDTH) - 1) << CS42XX8_FUNCMOD_ADC_FM_SHIFT) | ||
99 | #define CS42XX8_FUNCMOD_ADC_FM(v) ((v) << CS42XX8_FUNCMOD_ADC_FM_SHIFT) | ||
100 | #define CS42XX8_FUNCMOD_xC_FM_MASK(x) ((x) ? CS42XX8_FUNCMOD_DAC_FM_MASK : CS42XX8_FUNCMOD_ADC_FM_MASK) | ||
101 | #define CS42XX8_FUNCMOD_xC_FM(x, v) ((x) ? CS42XX8_FUNCMOD_DAC_FM(v) : CS42XX8_FUNCMOD_ADC_FM(v)) | ||
102 | #define CS42XX8_FUNCMOD_MFREQ_SHIFT 1 | ||
103 | #define CS42XX8_FUNCMOD_MFREQ_WIDTH 3 | ||
104 | #define CS42XX8_FUNCMOD_MFREQ_MASK (((1 << CS42XX8_FUNCMOD_MFREQ_WIDTH) - 1) << CS42XX8_FUNCMOD_MFREQ_SHIFT) | ||
105 | #define CS42XX8_FUNCMOD_MFREQ_256(s) ((0 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1)) | ||
106 | #define CS42XX8_FUNCMOD_MFREQ_384(s) ((1 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1)) | ||
107 | #define CS42XX8_FUNCMOD_MFREQ_512(s) ((2 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1)) | ||
108 | #define CS42XX8_FUNCMOD_MFREQ_768(s) ((3 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1)) | ||
109 | #define CS42XX8_FUNCMOD_MFREQ_1024(s) ((4 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1)) | ||
110 | |||
111 | #define CS42XX8_FM_SINGLE 0 | ||
112 | #define CS42XX8_FM_DOUBLE 1 | ||
113 | #define CS42XX8_FM_QUAD 2 | ||
114 | #define CS42XX8_FM_AUTO 3 | ||
115 | |||
116 | /* Interface Formats (Address 04h) */ | ||
117 | #define CS42XX8_INTF_FREEZE_SHIFT 7 | ||
118 | #define CS42XX8_INTF_FREEZE_MASK (1 << CS42XX8_INTF_FREEZE_SHIFT) | ||
119 | #define CS42XX8_INTF_FREEZE (1 << CS42XX8_INTF_FREEZE_SHIFT) | ||
120 | #define CS42XX8_INTF_AUX_DIF_SHIFT 6 | ||
121 | #define CS42XX8_INTF_AUX_DIF_MASK (1 << CS42XX8_INTF_AUX_DIF_SHIFT) | ||
122 | #define CS42XX8_INTF_AUX_DIF (1 << CS42XX8_INTF_AUX_DIF_SHIFT) | ||
123 | #define CS42XX8_INTF_DAC_DIF_SHIFT 3 | ||
124 | #define CS42XX8_INTF_DAC_DIF_WIDTH 3 | ||
125 | #define CS42XX8_INTF_DAC_DIF_MASK (((1 << CS42XX8_INTF_DAC_DIF_WIDTH) - 1) << CS42XX8_INTF_DAC_DIF_SHIFT) | ||
126 | #define CS42XX8_INTF_DAC_DIF_LEFTJ (0 << CS42XX8_INTF_DAC_DIF_SHIFT) | ||
127 | #define CS42XX8_INTF_DAC_DIF_I2S (1 << CS42XX8_INTF_DAC_DIF_SHIFT) | ||
128 | #define CS42XX8_INTF_DAC_DIF_RIGHTJ (2 << CS42XX8_INTF_DAC_DIF_SHIFT) | ||
129 | #define CS42XX8_INTF_DAC_DIF_RIGHTJ_16 (3 << CS42XX8_INTF_DAC_DIF_SHIFT) | ||
130 | #define CS42XX8_INTF_DAC_DIF_ONELINE_20 (4 << CS42XX8_INTF_DAC_DIF_SHIFT) | ||
131 | #define CS42XX8_INTF_DAC_DIF_ONELINE_24 (6 << CS42XX8_INTF_DAC_DIF_SHIFT) | ||
132 | #define CS42XX8_INTF_DAC_DIF_TDM (7 << CS42XX8_INTF_DAC_DIF_SHIFT) | ||
133 | #define CS42XX8_INTF_ADC_DIF_SHIFT 0 | ||
134 | #define CS42XX8_INTF_ADC_DIF_WIDTH 3 | ||
135 | #define CS42XX8_INTF_ADC_DIF_MASK (((1 << CS42XX8_INTF_ADC_DIF_WIDTH) - 1) << CS42XX8_INTF_ADC_DIF_SHIFT) | ||
136 | #define CS42XX8_INTF_ADC_DIF_LEFTJ (0 << CS42XX8_INTF_ADC_DIF_SHIFT) | ||
137 | #define CS42XX8_INTF_ADC_DIF_I2S (1 << CS42XX8_INTF_ADC_DIF_SHIFT) | ||
138 | #define CS42XX8_INTF_ADC_DIF_RIGHTJ (2 << CS42XX8_INTF_ADC_DIF_SHIFT) | ||
139 | #define CS42XX8_INTF_ADC_DIF_RIGHTJ_16 (3 << CS42XX8_INTF_ADC_DIF_SHIFT) | ||
140 | #define CS42XX8_INTF_ADC_DIF_ONELINE_20 (4 << CS42XX8_INTF_ADC_DIF_SHIFT) | ||
141 | #define CS42XX8_INTF_ADC_DIF_ONELINE_24 (6 << CS42XX8_INTF_ADC_DIF_SHIFT) | ||
142 | #define CS42XX8_INTF_ADC_DIF_TDM (7 << CS42XX8_INTF_ADC_DIF_SHIFT) | ||
143 | |||
144 | /* ADC Control & DAC De-Emphasis (Address 05h) */ | ||
145 | #define CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT 7 | ||
146 | #define CS42XX8_ADCCTL_ADC_HPF_FREEZE_MASK (1 << CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT) | ||
147 | #define CS42XX8_ADCCTL_ADC_HPF_FREEZE (1 << CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT) | ||
148 | #define CS42XX8_ADCCTL_DAC_DEM_SHIFT 5 | ||
149 | #define CS42XX8_ADCCTL_DAC_DEM_MASK (1 << CS42XX8_ADCCTL_DAC_DEM_SHIFT) | ||
150 | #define CS42XX8_ADCCTL_DAC_DEM (1 << CS42XX8_ADCCTL_DAC_DEM_SHIFT) | ||
151 | #define CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT 4 | ||
152 | #define CS42XX8_ADCCTL_ADC1_SINGLE_MASK (1 << CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT) | ||
153 | #define CS42XX8_ADCCTL_ADC1_SINGLE (1 << CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT) | ||
154 | #define CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT 3 | ||
155 | #define CS42XX8_ADCCTL_ADC2_SINGLE_MASK (1 << CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT) | ||
156 | #define CS42XX8_ADCCTL_ADC2_SINGLE (1 << CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT) | ||
157 | #define CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT 2 | ||
158 | #define CS42XX8_ADCCTL_ADC3_SINGLE_MASK (1 << CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT) | ||
159 | #define CS42XX8_ADCCTL_ADC3_SINGLE (1 << CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT) | ||
160 | #define CS42XX8_ADCCTL_AIN5_MUX_SHIFT 1 | ||
161 | #define CS42XX8_ADCCTL_AIN5_MUX_MASK (1 << CS42XX8_ADCCTL_AIN5_MUX_SHIFT) | ||
162 | #define CS42XX8_ADCCTL_AIN5_MUX (1 << CS42XX8_ADCCTL_AIN5_MUX_SHIFT) | ||
163 | #define CS42XX8_ADCCTL_AIN6_MUX_SHIFT 0 | ||
164 | #define CS42XX8_ADCCTL_AIN6_MUX_MASK (1 << CS42XX8_ADCCTL_AIN6_MUX_SHIFT) | ||
165 | #define CS42XX8_ADCCTL_AIN6_MUX (1 << CS42XX8_ADCCTL_AIN6_MUX_SHIFT) | ||
166 | |||
167 | /* Transition Control (Address 06h) */ | ||
168 | #define CS42XX8_TXCTL_DAC_SNGVOL_SHIFT 7 | ||
169 | #define CS42XX8_TXCTL_DAC_SNGVOL_MASK (1 << CS42XX8_TXCTL_DAC_SNGVOL_SHIFT) | ||
170 | #define CS42XX8_TXCTL_DAC_SNGVOL (1 << CS42XX8_TXCTL_DAC_SNGVOL_SHIFT) | ||
171 | #define CS42XX8_TXCTL_DAC_SZC_SHIFT 5 | ||
172 | #define CS42XX8_TXCTL_DAC_SZC_WIDTH 2 | ||
173 | #define CS42XX8_TXCTL_DAC_SZC_MASK (((1 << CS42XX8_TXCTL_DAC_SZC_WIDTH) - 1) << CS42XX8_TXCTL_DAC_SZC_SHIFT) | ||
174 | #define CS42XX8_TXCTL_DAC_SZC_IC (0 << CS42XX8_TXCTL_DAC_SZC_SHIFT) | ||
175 | #define CS42XX8_TXCTL_DAC_SZC_ZC (1 << CS42XX8_TXCTL_DAC_SZC_SHIFT) | ||
176 | #define CS42XX8_TXCTL_DAC_SZC_SR (2 << CS42XX8_TXCTL_DAC_SZC_SHIFT) | ||
177 | #define CS42XX8_TXCTL_DAC_SZC_SRZC (3 << CS42XX8_TXCTL_DAC_SZC_SHIFT) | ||
178 | #define CS42XX8_TXCTL_AMUTE_SHIFT 4 | ||
179 | #define CS42XX8_TXCTL_AMUTE_MASK (1 << CS42XX8_TXCTL_AMUTE_SHIFT) | ||
180 | #define CS42XX8_TXCTL_AMUTE (1 << CS42XX8_TXCTL_AMUTE_SHIFT) | ||
181 | #define CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT 3 | ||
182 | #define CS42XX8_TXCTL_MUTE_ADC_SP_MASK (1 << CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT) | ||
183 | #define CS42XX8_TXCTL_MUTE_ADC_SP (1 << CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT) | ||
184 | #define CS42XX8_TXCTL_ADC_SNGVOL_SHIFT 2 | ||
185 | #define CS42XX8_TXCTL_ADC_SNGVOL_MASK (1 << CS42XX8_TXCTL_ADC_SNGVOL_SHIFT) | ||
186 | #define CS42XX8_TXCTL_ADC_SNGVOL (1 << CS42XX8_TXCTL_ADC_SNGVOL_SHIFT) | ||
187 | #define CS42XX8_TXCTL_ADC_SZC_SHIFT 0 | ||
188 | #define CS42XX8_TXCTL_ADC_SZC_MASK (((1 << CS42XX8_TXCTL_ADC_SZC_WIDTH) - 1) << CS42XX8_TXCTL_ADC_SZC_SHIFT) | ||
189 | #define CS42XX8_TXCTL_ADC_SZC_IC (0 << CS42XX8_TXCTL_ADC_SZC_SHIFT) | ||
190 | #define CS42XX8_TXCTL_ADC_SZC_ZC (1 << CS42XX8_TXCTL_ADC_SZC_SHIFT) | ||
191 | #define CS42XX8_TXCTL_ADC_SZC_SR (2 << CS42XX8_TXCTL_ADC_SZC_SHIFT) | ||
192 | #define CS42XX8_TXCTL_ADC_SZC_SRZC (3 << CS42XX8_TXCTL_ADC_SZC_SHIFT) | ||
193 | |||
194 | /* DAC Channel Mute (Address 07h) */ | ||
195 | #define CS42XX8_DACMUTE_AOUT(n) (0x1 << n) | ||
196 | #define CS42XX8_DACMUTE_ALL 0xff | ||
197 | |||
198 | /* Status Control (Address 18h)*/ | ||
199 | #define CS42XX8_STATUSCTL_INI_SHIFT 2 | ||
200 | #define CS42XX8_STATUSCTL_INI_WIDTH 2 | ||
201 | #define CS42XX8_STATUSCTL_INI_MASK (((1 << CS42XX8_STATUSCTL_INI_WIDTH) - 1) << CS42XX8_STATUSCTL_INI_SHIFT) | ||
202 | #define CS42XX8_STATUSCTL_INT_ACTIVE_HIGH (0 << CS42XX8_STATUSCTL_INI_SHIFT) | ||
203 | #define CS42XX8_STATUSCTL_INT_ACTIVE_LOW (1 << CS42XX8_STATUSCTL_INI_SHIFT) | ||
204 | #define CS42XX8_STATUSCTL_INT_OPEN_DRAIN (2 << CS42XX8_STATUSCTL_INI_SHIFT) | ||
205 | |||
206 | /* Status (Address 19h)*/ | ||
207 | #define CS42XX8_STATUS_DAC_CLK_ERR_SHIFT 4 | ||
208 | #define CS42XX8_STATUS_DAC_CLK_ERR_MASK (1 << CS42XX8_STATUS_DAC_CLK_ERR_SHIFT) | ||
209 | #define CS42XX8_STATUS_ADC_CLK_ERR_SHIFT 3 | ||
210 | #define CS42XX8_STATUS_ADC_CLK_ERR_MASK (1 << CS42XX8_STATUS_ADC_CLK_ERR_SHIFT) | ||
211 | #define CS42XX8_STATUS_ADC3_OVFL_SHIFT 2 | ||
212 | #define CS42XX8_STATUS_ADC3_OVFL_MASK (1 << CS42XX8_STATUS_ADC3_OVFL_SHIFT) | ||
213 | #define CS42XX8_STATUS_ADC2_OVFL_SHIFT 1 | ||
214 | #define CS42XX8_STATUS_ADC2_OVFL_MASK (1 << CS42XX8_STATUS_ADC2_OVFL_SHIFT) | ||
215 | #define CS42XX8_STATUS_ADC1_OVFL_SHIFT 0 | ||
216 | #define CS42XX8_STATUS_ADC1_OVFL_MASK (1 << CS42XX8_STATUS_ADC1_OVFL_SHIFT) | ||
217 | |||
218 | /* Status Mask (Address 1Ah) */ | ||
219 | #define CS42XX8_STATUS_DAC_CLK_ERR_M_SHIFT 4 | ||
220 | #define CS42XX8_STATUS_DAC_CLK_ERR_M_MASK (1 << CS42XX8_STATUS_DAC_CLK_ERR_M_SHIFT) | ||
221 | #define CS42XX8_STATUS_ADC_CLK_ERR_M_SHIFT 3 | ||
222 | #define CS42XX8_STATUS_ADC_CLK_ERR_M_MASK (1 << CS42XX8_STATUS_ADC_CLK_ERR_M_SHIFT) | ||
223 | #define CS42XX8_STATUS_ADC3_OVFL_M_SHIFT 2 | ||
224 | #define CS42XX8_STATUS_ADC3_OVFL_M_MASK (1 << CS42XX8_STATUS_ADC3_OVFL_M_SHIFT) | ||
225 | #define CS42XX8_STATUS_ADC2_OVFL_M_SHIFT 1 | ||
226 | #define CS42XX8_STATUS_ADC2_OVFL_M_MASK (1 << CS42XX8_STATUS_ADC2_OVFL_M_SHIFT) | ||
227 | #define CS42XX8_STATUS_ADC1_OVFL_M_SHIFT 0 | ||
228 | #define CS42XX8_STATUS_ADC1_OVFL_M_MASK (1 << CS42XX8_STATUS_ADC1_OVFL_M_SHIFT) | ||
229 | |||
230 | /* MUTEC Pin Control (Address 1Bh) */ | ||
231 | #define CS42XX8_MUTEC_MCPOLARITY_SHIFT 1 | ||
232 | #define CS42XX8_MUTEC_MCPOLARITY_MASK (1 << CS42XX8_MUTEC_MCPOLARITY_SHIFT) | ||
233 | #define CS42XX8_MUTEC_MCPOLARITY_ACTIVE_LOW (0 << CS42XX8_MUTEC_MCPOLARITY_SHIFT) | ||
234 | #define CS42XX8_MUTEC_MCPOLARITY_ACTIVE_HIGH (1 << CS42XX8_MUTEC_MCPOLARITY_SHIFT) | ||
235 | #define CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT 0 | ||
236 | #define CS42XX8_MUTEC_MUTEC_ACTIVE_MASK (1 << CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT) | ||
237 | #define CS42XX8_MUTEC_MUTEC_ACTIVE (1 << CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT) | ||
238 | #endif /* _CS42XX8_H */ | ||
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index e62e294a8033..137e8ebc092c 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c | |||
@@ -307,29 +307,29 @@ static const char * const da7210_hpf_cutoff_txt[] = { | |||
307 | "Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi" | 307 | "Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi" |
308 | }; | 308 | }; |
309 | 309 | ||
310 | static const struct soc_enum da7210_dac_hpf_cutoff = | 310 | static SOC_ENUM_SINGLE_DECL(da7210_dac_hpf_cutoff, |
311 | SOC_ENUM_SINGLE(DA7210_DAC_HPF, 0, 4, da7210_hpf_cutoff_txt); | 311 | DA7210_DAC_HPF, 0, da7210_hpf_cutoff_txt); |
312 | 312 | ||
313 | static const struct soc_enum da7210_adc_hpf_cutoff = | 313 | static SOC_ENUM_SINGLE_DECL(da7210_adc_hpf_cutoff, |
314 | SOC_ENUM_SINGLE(DA7210_ADC_HPF, 0, 4, da7210_hpf_cutoff_txt); | 314 | DA7210_ADC_HPF, 0, da7210_hpf_cutoff_txt); |
315 | 315 | ||
316 | /* ADC and DAC voice (8kHz) high pass cutoff value */ | 316 | /* ADC and DAC voice (8kHz) high pass cutoff value */ |
317 | static const char * const da7210_vf_cutoff_txt[] = { | 317 | static const char * const da7210_vf_cutoff_txt[] = { |
318 | "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" | 318 | "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" |
319 | }; | 319 | }; |
320 | 320 | ||
321 | static const struct soc_enum da7210_dac_vf_cutoff = | 321 | static SOC_ENUM_SINGLE_DECL(da7210_dac_vf_cutoff, |
322 | SOC_ENUM_SINGLE(DA7210_DAC_HPF, 4, 8, da7210_vf_cutoff_txt); | 322 | DA7210_DAC_HPF, 4, da7210_vf_cutoff_txt); |
323 | 323 | ||
324 | static const struct soc_enum da7210_adc_vf_cutoff = | 324 | static SOC_ENUM_SINGLE_DECL(da7210_adc_vf_cutoff, |
325 | SOC_ENUM_SINGLE(DA7210_ADC_HPF, 4, 8, da7210_vf_cutoff_txt); | 325 | DA7210_ADC_HPF, 4, da7210_vf_cutoff_txt); |
326 | 326 | ||
327 | static const char *da7210_hp_mode_txt[] = { | 327 | static const char *da7210_hp_mode_txt[] = { |
328 | "Class H", "Class G" | 328 | "Class H", "Class G" |
329 | }; | 329 | }; |
330 | 330 | ||
331 | static const struct soc_enum da7210_hp_mode_sel = | 331 | static SOC_ENUM_SINGLE_DECL(da7210_hp_mode_sel, |
332 | SOC_ENUM_SINGLE(DA7210_HP_CFG, 0, 2, da7210_hp_mode_txt); | 332 | DA7210_HP_CFG, 0, da7210_hp_mode_txt); |
333 | 333 | ||
334 | /* ALC can be enabled only if noise suppression is disabled */ | 334 | /* ALC can be enabled only if noise suppression is disabled */ |
335 | static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, | 335 | static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, |
@@ -1071,17 +1071,9 @@ static struct snd_soc_dai_driver da7210_dai = { | |||
1071 | static int da7210_probe(struct snd_soc_codec *codec) | 1071 | static int da7210_probe(struct snd_soc_codec *codec) |
1072 | { | 1072 | { |
1073 | struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec); | 1073 | struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec); |
1074 | int ret; | ||
1075 | 1074 | ||
1076 | dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); | 1075 | dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); |
1077 | 1076 | ||
1078 | codec->control_data = da7210->regmap; | ||
1079 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1080 | if (ret < 0) { | ||
1081 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1082 | return ret; | ||
1083 | } | ||
1084 | |||
1085 | da7210->mclk_rate = 0; /* This will be set from set_sysclk() */ | 1077 | da7210->mclk_rate = 0; /* This will be set from set_sysclk() */ |
1086 | da7210->master = 0; /* This will be set from set_fmt() */ | 1078 | da7210->master = 0; /* This will be set from set_fmt() */ |
1087 | 1079 | ||
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 0c77e7ad7423..738fa18a50d2 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c | |||
@@ -63,30 +63,30 @@ static const char * const da7213_voice_hpf_corner_txt[] = { | |||
63 | "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" | 63 | "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" |
64 | }; | 64 | }; |
65 | 65 | ||
66 | static const struct soc_enum da7213_dac_voice_hpf_corner = | 66 | static SOC_ENUM_SINGLE_DECL(da7213_dac_voice_hpf_corner, |
67 | SOC_ENUM_SINGLE(DA7213_DAC_FILTERS1, DA7213_VOICE_HPF_CORNER_SHIFT, | 67 | DA7213_DAC_FILTERS1, |
68 | DA7213_VOICE_HPF_CORNER_MAX, | 68 | DA7213_VOICE_HPF_CORNER_SHIFT, |
69 | da7213_voice_hpf_corner_txt); | 69 | da7213_voice_hpf_corner_txt); |
70 | 70 | ||
71 | static const struct soc_enum da7213_adc_voice_hpf_corner = | 71 | static SOC_ENUM_SINGLE_DECL(da7213_adc_voice_hpf_corner, |
72 | SOC_ENUM_SINGLE(DA7213_ADC_FILTERS1, DA7213_VOICE_HPF_CORNER_SHIFT, | 72 | DA7213_ADC_FILTERS1, |
73 | DA7213_VOICE_HPF_CORNER_MAX, | 73 | DA7213_VOICE_HPF_CORNER_SHIFT, |
74 | da7213_voice_hpf_corner_txt); | 74 | da7213_voice_hpf_corner_txt); |
75 | 75 | ||
76 | /* ADC and DAC high pass filter cutoff value */ | 76 | /* ADC and DAC high pass filter cutoff value */ |
77 | static const char * const da7213_audio_hpf_corner_txt[] = { | 77 | static const char * const da7213_audio_hpf_corner_txt[] = { |
78 | "Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000" | 78 | "Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000" |
79 | }; | 79 | }; |
80 | 80 | ||
81 | static const struct soc_enum da7213_dac_audio_hpf_corner = | 81 | static SOC_ENUM_SINGLE_DECL(da7213_dac_audio_hpf_corner, |
82 | SOC_ENUM_SINGLE(DA7213_DAC_FILTERS1, DA7213_AUDIO_HPF_CORNER_SHIFT, | 82 | DA7213_DAC_FILTERS1 |
83 | DA7213_AUDIO_HPF_CORNER_MAX, | 83 | , DA7213_AUDIO_HPF_CORNER_SHIFT, |
84 | da7213_audio_hpf_corner_txt); | 84 | da7213_audio_hpf_corner_txt); |
85 | 85 | ||
86 | static const struct soc_enum da7213_adc_audio_hpf_corner = | 86 | static SOC_ENUM_SINGLE_DECL(da7213_adc_audio_hpf_corner, |
87 | SOC_ENUM_SINGLE(DA7213_ADC_FILTERS1, DA7213_AUDIO_HPF_CORNER_SHIFT, | 87 | DA7213_ADC_FILTERS1, |
88 | DA7213_AUDIO_HPF_CORNER_MAX, | 88 | DA7213_AUDIO_HPF_CORNER_SHIFT, |
89 | da7213_audio_hpf_corner_txt); | 89 | da7213_audio_hpf_corner_txt); |
90 | 90 | ||
91 | /* Gain ramping rate value */ | 91 | /* Gain ramping rate value */ |
92 | static const char * const da7213_gain_ramp_rate_txt[] = { | 92 | static const char * const da7213_gain_ramp_rate_txt[] = { |
@@ -94,52 +94,50 @@ static const char * const da7213_gain_ramp_rate_txt[] = { | |||
94 | "nominal rate / 32" | 94 | "nominal rate / 32" |
95 | }; | 95 | }; |
96 | 96 | ||
97 | static const struct soc_enum da7213_gain_ramp_rate = | 97 | static SOC_ENUM_SINGLE_DECL(da7213_gain_ramp_rate, |
98 | SOC_ENUM_SINGLE(DA7213_GAIN_RAMP_CTRL, DA7213_GAIN_RAMP_RATE_SHIFT, | 98 | DA7213_GAIN_RAMP_CTRL, |
99 | DA7213_GAIN_RAMP_RATE_MAX, da7213_gain_ramp_rate_txt); | 99 | DA7213_GAIN_RAMP_RATE_SHIFT, |
100 | da7213_gain_ramp_rate_txt); | ||
100 | 101 | ||
101 | /* DAC noise gate setup time value */ | 102 | /* DAC noise gate setup time value */ |
102 | static const char * const da7213_dac_ng_setup_time_txt[] = { | 103 | static const char * const da7213_dac_ng_setup_time_txt[] = { |
103 | "256 samples", "512 samples", "1024 samples", "2048 samples" | 104 | "256 samples", "512 samples", "1024 samples", "2048 samples" |
104 | }; | 105 | }; |
105 | 106 | ||
106 | static const struct soc_enum da7213_dac_ng_setup_time = | 107 | static SOC_ENUM_SINGLE_DECL(da7213_dac_ng_setup_time, |
107 | SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME, | 108 | DA7213_DAC_NG_SETUP_TIME, |
108 | DA7213_DAC_NG_SETUP_TIME_SHIFT, | 109 | DA7213_DAC_NG_SETUP_TIME_SHIFT, |
109 | DA7213_DAC_NG_SETUP_TIME_MAX, | 110 | da7213_dac_ng_setup_time_txt); |
110 | da7213_dac_ng_setup_time_txt); | ||
111 | 111 | ||
112 | /* DAC noise gate rampup rate value */ | 112 | /* DAC noise gate rampup rate value */ |
113 | static const char * const da7213_dac_ng_rampup_txt[] = { | 113 | static const char * const da7213_dac_ng_rampup_txt[] = { |
114 | "0.02 ms/dB", "0.16 ms/dB" | 114 | "0.02 ms/dB", "0.16 ms/dB" |
115 | }; | 115 | }; |
116 | 116 | ||
117 | static const struct soc_enum da7213_dac_ng_rampup_rate = | 117 | static SOC_ENUM_SINGLE_DECL(da7213_dac_ng_rampup_rate, |
118 | SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME, | 118 | DA7213_DAC_NG_SETUP_TIME, |
119 | DA7213_DAC_NG_RAMPUP_RATE_SHIFT, | 119 | DA7213_DAC_NG_RAMPUP_RATE_SHIFT, |
120 | DA7213_DAC_NG_RAMP_RATE_MAX, | 120 | da7213_dac_ng_rampup_txt); |
121 | da7213_dac_ng_rampup_txt); | ||
122 | 121 | ||
123 | /* DAC noise gate rampdown rate value */ | 122 | /* DAC noise gate rampdown rate value */ |
124 | static const char * const da7213_dac_ng_rampdown_txt[] = { | 123 | static const char * const da7213_dac_ng_rampdown_txt[] = { |
125 | "0.64 ms/dB", "20.48 ms/dB" | 124 | "0.64 ms/dB", "20.48 ms/dB" |
126 | }; | 125 | }; |
127 | 126 | ||
128 | static const struct soc_enum da7213_dac_ng_rampdown_rate = | 127 | static SOC_ENUM_SINGLE_DECL(da7213_dac_ng_rampdown_rate, |
129 | SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME, | 128 | DA7213_DAC_NG_SETUP_TIME, |
130 | DA7213_DAC_NG_RAMPDN_RATE_SHIFT, | 129 | DA7213_DAC_NG_RAMPDN_RATE_SHIFT, |
131 | DA7213_DAC_NG_RAMP_RATE_MAX, | 130 | da7213_dac_ng_rampdown_txt); |
132 | da7213_dac_ng_rampdown_txt); | ||
133 | 131 | ||
134 | /* DAC soft mute rate value */ | 132 | /* DAC soft mute rate value */ |
135 | static const char * const da7213_dac_soft_mute_rate_txt[] = { | 133 | static const char * const da7213_dac_soft_mute_rate_txt[] = { |
136 | "1", "2", "4", "8", "16", "32", "64" | 134 | "1", "2", "4", "8", "16", "32", "64" |
137 | }; | 135 | }; |
138 | 136 | ||
139 | static const struct soc_enum da7213_dac_soft_mute_rate = | 137 | static SOC_ENUM_SINGLE_DECL(da7213_dac_soft_mute_rate, |
140 | SOC_ENUM_SINGLE(DA7213_DAC_FILTERS5, DA7213_DAC_SOFTMUTE_RATE_SHIFT, | 138 | DA7213_DAC_FILTERS5, |
141 | DA7213_DAC_SOFTMUTE_RATE_MAX, | 139 | DA7213_DAC_SOFTMUTE_RATE_SHIFT, |
142 | da7213_dac_soft_mute_rate_txt); | 140 | da7213_dac_soft_mute_rate_txt); |
143 | 141 | ||
144 | /* ALC Attack Rate select */ | 142 | /* ALC Attack Rate select */ |
145 | static const char * const da7213_alc_attack_rate_txt[] = { | 143 | static const char * const da7213_alc_attack_rate_txt[] = { |
@@ -147,9 +145,10 @@ static const char * const da7213_alc_attack_rate_txt[] = { | |||
147 | "5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" | 145 | "5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" |
148 | }; | 146 | }; |
149 | 147 | ||
150 | static const struct soc_enum da7213_alc_attack_rate = | 148 | static SOC_ENUM_SINGLE_DECL(da7213_alc_attack_rate, |
151 | SOC_ENUM_SINGLE(DA7213_ALC_CTRL2, DA7213_ALC_ATTACK_SHIFT, | 149 | DA7213_ALC_CTRL2, |
152 | DA7213_ALC_ATTACK_MAX, da7213_alc_attack_rate_txt); | 150 | DA7213_ALC_ATTACK_SHIFT, |
151 | da7213_alc_attack_rate_txt); | ||
153 | 152 | ||
154 | /* ALC Release Rate select */ | 153 | /* ALC Release Rate select */ |
155 | static const char * const da7213_alc_release_rate_txt[] = { | 154 | static const char * const da7213_alc_release_rate_txt[] = { |
@@ -157,9 +156,10 @@ static const char * const da7213_alc_release_rate_txt[] = { | |||
157 | "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" | 156 | "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" |
158 | }; | 157 | }; |
159 | 158 | ||
160 | static const struct soc_enum da7213_alc_release_rate = | 159 | static SOC_ENUM_SINGLE_DECL(da7213_alc_release_rate, |
161 | SOC_ENUM_SINGLE(DA7213_ALC_CTRL2, DA7213_ALC_RELEASE_SHIFT, | 160 | DA7213_ALC_CTRL2, |
162 | DA7213_ALC_RELEASE_MAX, da7213_alc_release_rate_txt); | 161 | DA7213_ALC_RELEASE_SHIFT, |
162 | da7213_alc_release_rate_txt); | ||
163 | 163 | ||
164 | /* ALC Hold Time select */ | 164 | /* ALC Hold Time select */ |
165 | static const char * const da7213_alc_hold_time_txt[] = { | 165 | static const char * const da7213_alc_hold_time_txt[] = { |
@@ -168,22 +168,25 @@ static const char * const da7213_alc_hold_time_txt[] = { | |||
168 | "253952/fs", "507904/fs", "1015808/fs", "2031616/fs" | 168 | "253952/fs", "507904/fs", "1015808/fs", "2031616/fs" |
169 | }; | 169 | }; |
170 | 170 | ||
171 | static const struct soc_enum da7213_alc_hold_time = | 171 | static SOC_ENUM_SINGLE_DECL(da7213_alc_hold_time, |
172 | SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_HOLD_SHIFT, | 172 | DA7213_ALC_CTRL3, |
173 | DA7213_ALC_HOLD_MAX, da7213_alc_hold_time_txt); | 173 | DA7213_ALC_HOLD_SHIFT, |
174 | da7213_alc_hold_time_txt); | ||
174 | 175 | ||
175 | /* ALC Input Signal Tracking rate select */ | 176 | /* ALC Input Signal Tracking rate select */ |
176 | static const char * const da7213_alc_integ_rate_txt[] = { | 177 | static const char * const da7213_alc_integ_rate_txt[] = { |
177 | "1/4", "1/16", "1/256", "1/65536" | 178 | "1/4", "1/16", "1/256", "1/65536" |
178 | }; | 179 | }; |
179 | 180 | ||
180 | static const struct soc_enum da7213_alc_integ_attack_rate = | 181 | static SOC_ENUM_SINGLE_DECL(da7213_alc_integ_attack_rate, |
181 | SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_INTEG_ATTACK_SHIFT, | 182 | DA7213_ALC_CTRL3, |
182 | DA7213_ALC_INTEG_MAX, da7213_alc_integ_rate_txt); | 183 | DA7213_ALC_INTEG_ATTACK_SHIFT, |
184 | da7213_alc_integ_rate_txt); | ||
183 | 185 | ||
184 | static const struct soc_enum da7213_alc_integ_release_rate = | 186 | static SOC_ENUM_SINGLE_DECL(da7213_alc_integ_release_rate, |
185 | SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_INTEG_RELEASE_SHIFT, | 187 | DA7213_ALC_CTRL3, |
186 | DA7213_ALC_INTEG_MAX, da7213_alc_integ_rate_txt); | 188 | DA7213_ALC_INTEG_RELEASE_SHIFT, |
189 | da7213_alc_integ_rate_txt); | ||
187 | 190 | ||
188 | 191 | ||
189 | /* | 192 | /* |
@@ -584,15 +587,17 @@ static const char * const da7213_mic_amp_in_sel_txt[] = { | |||
584 | "Differential", "MIC_P", "MIC_N" | 587 | "Differential", "MIC_P", "MIC_N" |
585 | }; | 588 | }; |
586 | 589 | ||
587 | static const struct soc_enum da7213_mic_1_amp_in_sel = | 590 | static SOC_ENUM_SINGLE_DECL(da7213_mic_1_amp_in_sel, |
588 | SOC_ENUM_SINGLE(DA7213_MIC_1_CTRL, DA7213_MIC_AMP_IN_SEL_SHIFT, | 591 | DA7213_MIC_1_CTRL, |
589 | DA7213_MIC_AMP_IN_SEL_MAX, da7213_mic_amp_in_sel_txt); | 592 | DA7213_MIC_AMP_IN_SEL_SHIFT, |
593 | da7213_mic_amp_in_sel_txt); | ||
590 | static const struct snd_kcontrol_new da7213_mic_1_amp_in_sel_mux = | 594 | static const struct snd_kcontrol_new da7213_mic_1_amp_in_sel_mux = |
591 | SOC_DAPM_ENUM("Mic 1 Amp Source MUX", da7213_mic_1_amp_in_sel); | 595 | SOC_DAPM_ENUM("Mic 1 Amp Source MUX", da7213_mic_1_amp_in_sel); |
592 | 596 | ||
593 | static const struct soc_enum da7213_mic_2_amp_in_sel = | 597 | static SOC_ENUM_SINGLE_DECL(da7213_mic_2_amp_in_sel, |
594 | SOC_ENUM_SINGLE(DA7213_MIC_2_CTRL, DA7213_MIC_AMP_IN_SEL_SHIFT, | 598 | DA7213_MIC_2_CTRL, |
595 | DA7213_MIC_AMP_IN_SEL_MAX, da7213_mic_amp_in_sel_txt); | 599 | DA7213_MIC_AMP_IN_SEL_SHIFT, |
600 | da7213_mic_amp_in_sel_txt); | ||
596 | static const struct snd_kcontrol_new da7213_mic_2_amp_in_sel_mux = | 601 | static const struct snd_kcontrol_new da7213_mic_2_amp_in_sel_mux = |
597 | SOC_DAPM_ENUM("Mic 2 Amp Source MUX", da7213_mic_2_amp_in_sel); | 602 | SOC_DAPM_ENUM("Mic 2 Amp Source MUX", da7213_mic_2_amp_in_sel); |
598 | 603 | ||
@@ -601,15 +606,17 @@ static const char * const da7213_dai_src_txt[] = { | |||
601 | "ADC Left", "ADC Right", "DAI Input Left", "DAI Input Right" | 606 | "ADC Left", "ADC Right", "DAI Input Left", "DAI Input Right" |
602 | }; | 607 | }; |
603 | 608 | ||
604 | static const struct soc_enum da7213_dai_l_src = | 609 | static SOC_ENUM_SINGLE_DECL(da7213_dai_l_src, |
605 | SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAI, DA7213_DAI_L_SRC_SHIFT, | 610 | DA7213_DIG_ROUTING_DAI, |
606 | DA7213_DAI_SRC_MAX, da7213_dai_src_txt); | 611 | DA7213_DAI_L_SRC_SHIFT, |
612 | da7213_dai_src_txt); | ||
607 | static const struct snd_kcontrol_new da7213_dai_l_src_mux = | 613 | static const struct snd_kcontrol_new da7213_dai_l_src_mux = |
608 | SOC_DAPM_ENUM("DAI Left Source MUX", da7213_dai_l_src); | 614 | SOC_DAPM_ENUM("DAI Left Source MUX", da7213_dai_l_src); |
609 | 615 | ||
610 | static const struct soc_enum da7213_dai_r_src = | 616 | static SOC_ENUM_SINGLE_DECL(da7213_dai_r_src, |
611 | SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAI, DA7213_DAI_R_SRC_SHIFT, | 617 | DA7213_DIG_ROUTING_DAI, |
612 | DA7213_DAI_SRC_MAX, da7213_dai_src_txt); | 618 | DA7213_DAI_R_SRC_SHIFT, |
619 | da7213_dai_src_txt); | ||
613 | static const struct snd_kcontrol_new da7213_dai_r_src_mux = | 620 | static const struct snd_kcontrol_new da7213_dai_r_src_mux = |
614 | SOC_DAPM_ENUM("DAI Right Source MUX", da7213_dai_r_src); | 621 | SOC_DAPM_ENUM("DAI Right Source MUX", da7213_dai_r_src); |
615 | 622 | ||
@@ -619,15 +626,17 @@ static const char * const da7213_dac_src_txt[] = { | |||
619 | "DAI Input Right" | 626 | "DAI Input Right" |
620 | }; | 627 | }; |
621 | 628 | ||
622 | static const struct soc_enum da7213_dac_l_src = | 629 | static SOC_ENUM_SINGLE_DECL(da7213_dac_l_src, |
623 | SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAC, DA7213_DAC_L_SRC_SHIFT, | 630 | DA7213_DIG_ROUTING_DAC, |
624 | DA7213_DAC_SRC_MAX, da7213_dac_src_txt); | 631 | DA7213_DAC_L_SRC_SHIFT, |
632 | da7213_dac_src_txt); | ||
625 | static const struct snd_kcontrol_new da7213_dac_l_src_mux = | 633 | static const struct snd_kcontrol_new da7213_dac_l_src_mux = |
626 | SOC_DAPM_ENUM("DAC Left Source MUX", da7213_dac_l_src); | 634 | SOC_DAPM_ENUM("DAC Left Source MUX", da7213_dac_l_src); |
627 | 635 | ||
628 | static const struct soc_enum da7213_dac_r_src = | 636 | static SOC_ENUM_SINGLE_DECL(da7213_dac_r_src, |
629 | SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAC, DA7213_DAC_R_SRC_SHIFT, | 637 | DA7213_DIG_ROUTING_DAC, |
630 | DA7213_DAC_SRC_MAX, da7213_dac_src_txt); | 638 | DA7213_DAC_R_SRC_SHIFT, |
639 | da7213_dac_src_txt); | ||
631 | static const struct snd_kcontrol_new da7213_dac_r_src_mux = | 640 | static const struct snd_kcontrol_new da7213_dac_r_src_mux = |
632 | SOC_DAPM_ENUM("DAC Right Source MUX", da7213_dac_r_src); | 641 | SOC_DAPM_ENUM("DAC Right Source MUX", da7213_dac_r_src); |
633 | 642 | ||
@@ -1384,17 +1393,9 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec, | |||
1384 | 1393 | ||
1385 | static int da7213_probe(struct snd_soc_codec *codec) | 1394 | static int da7213_probe(struct snd_soc_codec *codec) |
1386 | { | 1395 | { |
1387 | int ret; | ||
1388 | struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); | 1396 | struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); |
1389 | struct da7213_platform_data *pdata = da7213->pdata; | 1397 | struct da7213_platform_data *pdata = da7213->pdata; |
1390 | 1398 | ||
1391 | codec->control_data = da7213->regmap; | ||
1392 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1393 | if (ret < 0) { | ||
1394 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1395 | return ret; | ||
1396 | } | ||
1397 | |||
1398 | /* Default to using ALC auto offset calibration mode. */ | 1399 | /* Default to using ALC auto offset calibration mode. */ |
1399 | snd_soc_update_bits(codec, DA7213_ALC_CTRL1, | 1400 | snd_soc_update_bits(codec, DA7213_ALC_CTRL1, |
1400 | DA7213_ALC_CALIB_MODE_MAN, 0); | 1401 | DA7213_ALC_CALIB_MODE_MAN, 0); |
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index f295b6569910..7d168ec71cd7 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c | |||
@@ -269,81 +269,65 @@ static const char *da732x_hpf_voice[] = { | |||
269 | "150Hz", "200Hz", "300Hz", "400Hz" | 269 | "150Hz", "200Hz", "300Hz", "400Hz" |
270 | }; | 270 | }; |
271 | 271 | ||
272 | static const struct soc_enum da732x_dac1_hpf_mode_enum[] = { | 272 | static SOC_ENUM_SINGLE_DECL(da732x_dac1_hpf_mode_enum, |
273 | SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT, | 273 | DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT, |
274 | DA732X_HPF_MODE_MAX, da732x_hpf_mode) | 274 | da732x_hpf_mode); |
275 | }; | ||
276 | 275 | ||
277 | static const struct soc_enum da732x_dac2_hpf_mode_enum[] = { | 276 | static SOC_ENUM_SINGLE_DECL(da732x_dac2_hpf_mode_enum, |
278 | SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT, | 277 | DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT, |
279 | DA732X_HPF_MODE_MAX, da732x_hpf_mode) | 278 | da732x_hpf_mode); |
280 | }; | ||
281 | 279 | ||
282 | static const struct soc_enum da732x_dac3_hpf_mode_enum[] = { | 280 | static SOC_ENUM_SINGLE_DECL(da732x_dac3_hpf_mode_enum, |
283 | SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT, | 281 | DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT, |
284 | DA732X_HPF_MODE_MAX, da732x_hpf_mode) | 282 | da732x_hpf_mode); |
285 | }; | ||
286 | 283 | ||
287 | static const struct soc_enum da732x_adc1_hpf_mode_enum[] = { | 284 | static SOC_ENUM_SINGLE_DECL(da732x_adc1_hpf_mode_enum, |
288 | SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT, | 285 | DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT, |
289 | DA732X_HPF_MODE_MAX, da732x_hpf_mode) | 286 | da732x_hpf_mode); |
290 | }; | ||
291 | 287 | ||
292 | static const struct soc_enum da732x_adc2_hpf_mode_enum[] = { | 288 | static SOC_ENUM_SINGLE_DECL(da732x_adc2_hpf_mode_enum, |
293 | SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT, | 289 | DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT, |
294 | DA732X_HPF_MODE_MAX, da732x_hpf_mode) | 290 | da732x_hpf_mode); |
295 | }; | ||
296 | 291 | ||
297 | static const struct soc_enum da732x_dac1_hp_filter_enum[] = { | 292 | static SOC_ENUM_SINGLE_DECL(da732x_dac1_hp_filter_enum, |
298 | SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT, | 293 | DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT, |
299 | DA732X_HPF_MUSIC_MAX, da732x_hpf_music) | 294 | da732x_hpf_music); |
300 | }; | ||
301 | 295 | ||
302 | static const struct soc_enum da732x_dac2_hp_filter_enum[] = { | 296 | static SOC_ENUM_SINGLE_DECL(da732x_dac2_hp_filter_enum, |
303 | SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT, | 297 | DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT, |
304 | DA732X_HPF_MUSIC_MAX, da732x_hpf_music) | 298 | da732x_hpf_music); |
305 | }; | ||
306 | 299 | ||
307 | static const struct soc_enum da732x_dac3_hp_filter_enum[] = { | 300 | static SOC_ENUM_SINGLE_DECL(da732x_dac3_hp_filter_enum, |
308 | SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT, | 301 | DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT, |
309 | DA732X_HPF_MUSIC_MAX, da732x_hpf_music) | 302 | da732x_hpf_music); |
310 | }; | ||
311 | 303 | ||
312 | static const struct soc_enum da732x_adc1_hp_filter_enum[] = { | 304 | static SOC_ENUM_SINGLE_DECL(da732x_adc1_hp_filter_enum, |
313 | SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT, | 305 | DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT, |
314 | DA732X_HPF_MUSIC_MAX, da732x_hpf_music) | 306 | da732x_hpf_music); |
315 | }; | ||
316 | 307 | ||
317 | static const struct soc_enum da732x_adc2_hp_filter_enum[] = { | 308 | static SOC_ENUM_SINGLE_DECL(da732x_adc2_hp_filter_enum, |
318 | SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT, | 309 | DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT, |
319 | DA732X_HPF_MUSIC_MAX, da732x_hpf_music) | 310 | da732x_hpf_music); |
320 | }; | ||
321 | 311 | ||
322 | static const struct soc_enum da732x_dac1_voice_filter_enum[] = { | 312 | static SOC_ENUM_SINGLE_DECL(da732x_dac1_voice_filter_enum, |
323 | SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT, | 313 | DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT, |
324 | DA732X_HPF_VOICE_MAX, da732x_hpf_voice) | 314 | da732x_hpf_voice); |
325 | }; | ||
326 | 315 | ||
327 | static const struct soc_enum da732x_dac2_voice_filter_enum[] = { | 316 | static SOC_ENUM_SINGLE_DECL(da732x_dac2_voice_filter_enum, |
328 | SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT, | 317 | DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT, |
329 | DA732X_HPF_VOICE_MAX, da732x_hpf_voice) | 318 | da732x_hpf_voice); |
330 | }; | ||
331 | 319 | ||
332 | static const struct soc_enum da732x_dac3_voice_filter_enum[] = { | 320 | static SOC_ENUM_SINGLE_DECL(da732x_dac3_voice_filter_enum, |
333 | SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT, | 321 | DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT, |
334 | DA732X_HPF_VOICE_MAX, da732x_hpf_voice) | 322 | da732x_hpf_voice); |
335 | }; | ||
336 | 323 | ||
337 | static const struct soc_enum da732x_adc1_voice_filter_enum[] = { | 324 | static SOC_ENUM_SINGLE_DECL(da732x_adc1_voice_filter_enum, |
338 | SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT, | 325 | DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT, |
339 | DA732X_HPF_VOICE_MAX, da732x_hpf_voice) | 326 | da732x_hpf_voice); |
340 | }; | ||
341 | |||
342 | static const struct soc_enum da732x_adc2_voice_filter_enum[] = { | ||
343 | SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT, | ||
344 | DA732X_HPF_VOICE_MAX, da732x_hpf_voice) | ||
345 | }; | ||
346 | 327 | ||
328 | static SOC_ENUM_SINGLE_DECL(da732x_adc2_voice_filter_enum, | ||
329 | DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT, | ||
330 | da732x_hpf_voice); | ||
347 | 331 | ||
348 | static int da732x_hpf_set(struct snd_kcontrol *kcontrol, | 332 | static int da732x_hpf_set(struct snd_kcontrol *kcontrol, |
349 | struct snd_ctl_elem_value *ucontrol) | 333 | struct snd_ctl_elem_value *ucontrol) |
@@ -714,65 +698,65 @@ static const char *enable_text[] = { | |||
714 | }; | 698 | }; |
715 | 699 | ||
716 | /* ADC1LMUX */ | 700 | /* ADC1LMUX */ |
717 | static const struct soc_enum adc1l_enum = | 701 | static SOC_ENUM_SINGLE_DECL(adc1l_enum, |
718 | SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT, | 702 | DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT, |
719 | DA732X_ADCL_MUX_MAX, adcl_text); | 703 | adcl_text); |
720 | static const struct snd_kcontrol_new adc1l_mux = | 704 | static const struct snd_kcontrol_new adc1l_mux = |
721 | SOC_DAPM_ENUM("ADC Route", adc1l_enum); | 705 | SOC_DAPM_ENUM("ADC Route", adc1l_enum); |
722 | 706 | ||
723 | /* ADC1RMUX */ | 707 | /* ADC1RMUX */ |
724 | static const struct soc_enum adc1r_enum = | 708 | static SOC_ENUM_SINGLE_DECL(adc1r_enum, |
725 | SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT, | 709 | DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT, |
726 | DA732X_ADCR_MUX_MAX, adcr_text); | 710 | adcr_text); |
727 | static const struct snd_kcontrol_new adc1r_mux = | 711 | static const struct snd_kcontrol_new adc1r_mux = |
728 | SOC_DAPM_ENUM("ADC Route", adc1r_enum); | 712 | SOC_DAPM_ENUM("ADC Route", adc1r_enum); |
729 | 713 | ||
730 | /* ADC2LMUX */ | 714 | /* ADC2LMUX */ |
731 | static const struct soc_enum adc2l_enum = | 715 | static SOC_ENUM_SINGLE_DECL(adc2l_enum, |
732 | SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT, | 716 | DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT, |
733 | DA732X_ADCL_MUX_MAX, adcl_text); | 717 | adcl_text); |
734 | static const struct snd_kcontrol_new adc2l_mux = | 718 | static const struct snd_kcontrol_new adc2l_mux = |
735 | SOC_DAPM_ENUM("ADC Route", adc2l_enum); | 719 | SOC_DAPM_ENUM("ADC Route", adc2l_enum); |
736 | 720 | ||
737 | /* ADC2RMUX */ | 721 | /* ADC2RMUX */ |
738 | static const struct soc_enum adc2r_enum = | 722 | static SOC_ENUM_SINGLE_DECL(adc2r_enum, |
739 | SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT, | 723 | DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT, |
740 | DA732X_ADCR_MUX_MAX, adcr_text); | 724 | adcr_text); |
741 | 725 | ||
742 | static const struct snd_kcontrol_new adc2r_mux = | 726 | static const struct snd_kcontrol_new adc2r_mux = |
743 | SOC_DAPM_ENUM("ADC Route", adc2r_enum); | 727 | SOC_DAPM_ENUM("ADC Route", adc2r_enum); |
744 | 728 | ||
745 | static const struct soc_enum da732x_hp_left_output = | 729 | static SOC_ENUM_SINGLE_DECL(da732x_hp_left_output, |
746 | SOC_ENUM_SINGLE(DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT, | 730 | DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT, |
747 | DA732X_DAC_EN_MAX, enable_text); | 731 | enable_text); |
748 | 732 | ||
749 | static const struct snd_kcontrol_new hpl_mux = | 733 | static const struct snd_kcontrol_new hpl_mux = |
750 | SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output); | 734 | SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output); |
751 | 735 | ||
752 | static const struct soc_enum da732x_hp_right_output = | 736 | static SOC_ENUM_SINGLE_DECL(da732x_hp_right_output, |
753 | SOC_ENUM_SINGLE(DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT, | 737 | DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT, |
754 | DA732X_DAC_EN_MAX, enable_text); | 738 | enable_text); |
755 | 739 | ||
756 | static const struct snd_kcontrol_new hpr_mux = | 740 | static const struct snd_kcontrol_new hpr_mux = |
757 | SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output); | 741 | SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output); |
758 | 742 | ||
759 | static const struct soc_enum da732x_speaker_output = | 743 | static SOC_ENUM_SINGLE_DECL(da732x_speaker_output, |
760 | SOC_ENUM_SINGLE(DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT, | 744 | DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT, |
761 | DA732X_DAC_EN_MAX, enable_text); | 745 | enable_text); |
762 | 746 | ||
763 | static const struct snd_kcontrol_new spk_mux = | 747 | static const struct snd_kcontrol_new spk_mux = |
764 | SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output); | 748 | SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output); |
765 | 749 | ||
766 | static const struct soc_enum da732x_lout4_output = | 750 | static SOC_ENUM_SINGLE_DECL(da732x_lout4_output, |
767 | SOC_ENUM_SINGLE(DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT, | 751 | DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT, |
768 | DA732X_DAC_EN_MAX, enable_text); | 752 | enable_text); |
769 | 753 | ||
770 | static const struct snd_kcontrol_new lout4_mux = | 754 | static const struct snd_kcontrol_new lout4_mux = |
771 | SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output); | 755 | SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output); |
772 | 756 | ||
773 | static const struct soc_enum da732x_lout2_output = | 757 | static SOC_ENUM_SINGLE_DECL(da732x_lout2_output, |
774 | SOC_ENUM_SINGLE(DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT, | 758 | DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT, |
775 | DA732X_DAC_EN_MAX, enable_text); | 759 | enable_text); |
776 | 760 | ||
777 | static const struct snd_kcontrol_new lout2_mux = | 761 | static const struct snd_kcontrol_new lout2_mux = |
778 | SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output); | 762 | SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output); |
@@ -1268,11 +1252,23 @@ static struct snd_soc_dai_driver da732x_dai[] = { | |||
1268 | }, | 1252 | }, |
1269 | }; | 1253 | }; |
1270 | 1254 | ||
1255 | static bool da732x_volatile(struct device *dev, unsigned int reg) | ||
1256 | { | ||
1257 | switch (reg) { | ||
1258 | case DA732X_REG_HPL_DAC_OFF_CNTL: | ||
1259 | case DA732X_REG_HPR_DAC_OFF_CNTL: | ||
1260 | return true; | ||
1261 | default: | ||
1262 | return false; | ||
1263 | } | ||
1264 | } | ||
1265 | |||
1271 | static const struct regmap_config da732x_regmap = { | 1266 | static const struct regmap_config da732x_regmap = { |
1272 | .reg_bits = 8, | 1267 | .reg_bits = 8, |
1273 | .val_bits = 8, | 1268 | .val_bits = 8, |
1274 | 1269 | ||
1275 | .max_register = DA732X_MAX_REG, | 1270 | .max_register = DA732X_MAX_REG, |
1271 | .volatile_reg = da732x_volatile, | ||
1276 | .reg_defaults = da732x_reg_cache, | 1272 | .reg_defaults = da732x_reg_cache, |
1277 | .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache), | 1273 | .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache), |
1278 | .cache_type = REGCACHE_RBTREE, | 1274 | .cache_type = REGCACHE_RBTREE, |
@@ -1301,9 +1297,9 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec) | |||
1301 | msleep(DA732X_WAIT_FOR_STABILIZATION); | 1297 | msleep(DA732X_WAIT_FOR_STABILIZATION); |
1302 | 1298 | ||
1303 | /* Check DAC offset sign */ | 1299 | /* Check DAC offset sign */ |
1304 | sign[DA732X_HPL_DAC] = (codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & | 1300 | sign[DA732X_HPL_DAC] = (snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & |
1305 | DA732X_HP_DAC_OFF_CNTL_COMPO); | 1301 | DA732X_HP_DAC_OFF_CNTL_COMPO); |
1306 | sign[DA732X_HPR_DAC] = (codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & | 1302 | sign[DA732X_HPR_DAC] = (snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & |
1307 | DA732X_HP_DAC_OFF_CNTL_COMPO); | 1303 | DA732X_HP_DAC_OFF_CNTL_COMPO); |
1308 | 1304 | ||
1309 | /* Binary search DAC offset values (both channels at once) */ | 1305 | /* Binary search DAC offset values (both channels at once) */ |
@@ -1320,10 +1316,10 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec) | |||
1320 | 1316 | ||
1321 | msleep(DA732X_WAIT_FOR_STABILIZATION); | 1317 | msleep(DA732X_WAIT_FOR_STABILIZATION); |
1322 | 1318 | ||
1323 | if ((codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & | 1319 | if ((snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & |
1324 | DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC]) | 1320 | DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC]) |
1325 | offset[DA732X_HPL_DAC] &= ~step; | 1321 | offset[DA732X_HPL_DAC] &= ~step; |
1326 | if ((codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & | 1322 | if ((snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & |
1327 | DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC]) | 1323 | DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC]) |
1328 | offset[DA732X_HPR_DAC] &= ~step; | 1324 | offset[DA732X_HPR_DAC] &= ~step; |
1329 | 1325 | ||
@@ -1364,9 +1360,9 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec) | |||
1364 | msleep(DA732X_WAIT_FOR_STABILIZATION); | 1360 | msleep(DA732X_WAIT_FOR_STABILIZATION); |
1365 | 1361 | ||
1366 | /* Check output offset sign */ | 1362 | /* Check output offset sign */ |
1367 | sign[DA732X_HPL_AMP] = codec->hw_read(codec, DA732X_REG_HPL) & | 1363 | sign[DA732X_HPL_AMP] = snd_soc_read(codec, DA732X_REG_HPL) & |
1368 | DA732X_HP_OUT_COMPO; | 1364 | DA732X_HP_OUT_COMPO; |
1369 | sign[DA732X_HPR_AMP] = codec->hw_read(codec, DA732X_REG_HPR) & | 1365 | sign[DA732X_HPR_AMP] = snd_soc_read(codec, DA732X_REG_HPR) & |
1370 | DA732X_HP_OUT_COMPO; | 1366 | DA732X_HP_OUT_COMPO; |
1371 | 1367 | ||
1372 | snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP | | 1368 | snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP | |
@@ -1387,10 +1383,10 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec) | |||
1387 | 1383 | ||
1388 | msleep(DA732X_WAIT_FOR_STABILIZATION); | 1384 | msleep(DA732X_WAIT_FOR_STABILIZATION); |
1389 | 1385 | ||
1390 | if ((codec->hw_read(codec, DA732X_REG_HPL) & | 1386 | if ((snd_soc_read(codec, DA732X_REG_HPL) & |
1391 | DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP]) | 1387 | DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP]) |
1392 | offset[DA732X_HPL_AMP] &= ~step; | 1388 | offset[DA732X_HPL_AMP] &= ~step; |
1393 | if ((codec->hw_read(codec, DA732X_REG_HPR) & | 1389 | if ((snd_soc_read(codec, DA732X_REG_HPR) & |
1394 | DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP]) | 1390 | DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP]) |
1395 | offset[DA732X_HPR_AMP] &= ~step; | 1391 | offset[DA732X_HPR_AMP] &= ~step; |
1396 | 1392 | ||
@@ -1487,8 +1483,8 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec, | |||
1487 | 1483 | ||
1488 | da732x_hp_dc_offset_cancellation(codec); | 1484 | da732x_hp_dc_offset_cancellation(codec); |
1489 | 1485 | ||
1490 | regcache_cache_only(codec->control_data, false); | 1486 | regcache_cache_only(da732x->regmap, false); |
1491 | regcache_sync(codec->control_data); | 1487 | regcache_sync(da732x->regmap); |
1492 | } else { | 1488 | } else { |
1493 | snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, | 1489 | snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, |
1494 | DA732X_BIAS_BOOST_MASK, | 1490 | DA732X_BIAS_BOOST_MASK, |
@@ -1499,7 +1495,7 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec, | |||
1499 | } | 1495 | } |
1500 | break; | 1496 | break; |
1501 | case SND_SOC_BIAS_OFF: | 1497 | case SND_SOC_BIAS_OFF: |
1502 | regcache_cache_only(codec->control_data, true); | 1498 | regcache_cache_only(da732x->regmap, true); |
1503 | da732x_set_charge_pump(codec, DA732X_DISABLE_CP); | 1499 | da732x_set_charge_pump(codec, DA732X_DISABLE_CP); |
1504 | snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN, | 1500 | snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN, |
1505 | DA732X_BIAS_DIS); | 1501 | DA732X_BIAS_DIS); |
@@ -1516,23 +1512,14 @@ static int da732x_probe(struct snd_soc_codec *codec) | |||
1516 | { | 1512 | { |
1517 | struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); | 1513 | struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); |
1518 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 1514 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
1519 | int ret = 0; | ||
1520 | 1515 | ||
1521 | da732x->codec = codec; | 1516 | da732x->codec = codec; |
1522 | 1517 | ||
1523 | dapm->idle_bias_off = false; | 1518 | dapm->idle_bias_off = false; |
1524 | 1519 | ||
1525 | codec->control_data = da732x->regmap; | ||
1526 | |||
1527 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1528 | if (ret != 0) { | ||
1529 | dev_err(codec->dev, "Failed to register codec.\n"); | ||
1530 | goto err; | ||
1531 | } | ||
1532 | |||
1533 | da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1520 | da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1534 | err: | 1521 | |
1535 | return ret; | 1522 | return 0; |
1536 | } | 1523 | } |
1537 | 1524 | ||
1538 | static int da732x_remove(struct snd_soc_codec *codec) | 1525 | static int da732x_remove(struct snd_soc_codec *codec) |
@@ -1554,7 +1541,6 @@ static struct snd_soc_codec_driver soc_codec_dev_da732x = { | |||
1554 | .dapm_routes = da732x_dapm_routes, | 1541 | .dapm_routes = da732x_dapm_routes, |
1555 | .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), | 1542 | .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), |
1556 | .set_pll = da732x_set_dai_pll, | 1543 | .set_pll = da732x_set_dai_pll, |
1557 | .reg_cache_size = ARRAY_SIZE(da732x_reg_cache), | ||
1558 | }; | 1544 | }; |
1559 | 1545 | ||
1560 | static int da732x_i2c_probe(struct i2c_client *i2c, | 1546 | static int da732x_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/da732x.h b/sound/soc/codecs/da732x.h index c8ce5475de22..1dceafeec415 100644 --- a/sound/soc/codecs/da732x.h +++ b/sound/soc/codecs/da732x.h | |||
@@ -113,9 +113,6 @@ | |||
113 | #define DA732X_EQ_OVERALL_VOL_DB_MIN -1800 | 113 | #define DA732X_EQ_OVERALL_VOL_DB_MIN -1800 |
114 | #define DA732X_EQ_OVERALL_VOL_DB_INC 600 | 114 | #define DA732X_EQ_OVERALL_VOL_DB_INC 600 |
115 | 115 | ||
116 | #define DA732X_SOC_ENUM_DOUBLE_R(xreg, xrreg, xmax, xtext) \ | ||
117 | {.reg = xreg, .reg2 = xrreg, .max = xmax, .texts = xtext} | ||
118 | |||
119 | enum da732x_sysctl { | 116 | enum da732x_sysctl { |
120 | DA732X_SR_8KHZ = 0x1, | 117 | DA732X_SR_8KHZ = 0x1, |
121 | DA732X_SR_11_025KHZ = 0x2, | 118 | DA732X_SR_11_025KHZ = 0x2, |
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index 52b79a487ac7..4ff06b50fbba 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/regmap.h> | 18 | #include <linux/regmap.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/of.h> | ||
22 | #include <linux/of_device.h> | ||
21 | #include <sound/pcm.h> | 23 | #include <sound/pcm.h> |
22 | #include <sound/pcm_params.h> | 24 | #include <sound/pcm_params.h> |
23 | #include <sound/soc.h> | 25 | #include <sound/soc.h> |
@@ -321,22 +323,22 @@ static const char * const da9055_hpf_cutoff_txt[] = { | |||
321 | "Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000" | 323 | "Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000" |
322 | }; | 324 | }; |
323 | 325 | ||
324 | static const struct soc_enum da9055_dac_hpf_cutoff = | 326 | static SOC_ENUM_SINGLE_DECL(da9055_dac_hpf_cutoff, |
325 | SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt); | 327 | DA9055_DAC_FILTERS1, 4, da9055_hpf_cutoff_txt); |
326 | 328 | ||
327 | static const struct soc_enum da9055_adc_hpf_cutoff = | 329 | static SOC_ENUM_SINGLE_DECL(da9055_adc_hpf_cutoff, |
328 | SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt); | 330 | DA9055_ADC_FILTERS1, 4, da9055_hpf_cutoff_txt); |
329 | 331 | ||
330 | /* ADC and DAC voice mode (8kHz) high pass cutoff value */ | 332 | /* ADC and DAC voice mode (8kHz) high pass cutoff value */ |
331 | static const char * const da9055_vf_cutoff_txt[] = { | 333 | static const char * const da9055_vf_cutoff_txt[] = { |
332 | "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" | 334 | "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" |
333 | }; | 335 | }; |
334 | 336 | ||
335 | static const struct soc_enum da9055_dac_vf_cutoff = | 337 | static SOC_ENUM_SINGLE_DECL(da9055_dac_vf_cutoff, |
336 | SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 0, 8, da9055_vf_cutoff_txt); | 338 | DA9055_DAC_FILTERS1, 0, da9055_vf_cutoff_txt); |
337 | 339 | ||
338 | static const struct soc_enum da9055_adc_vf_cutoff = | 340 | static SOC_ENUM_SINGLE_DECL(da9055_adc_vf_cutoff, |
339 | SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 0, 8, da9055_vf_cutoff_txt); | 341 | DA9055_ADC_FILTERS1, 0, da9055_vf_cutoff_txt); |
340 | 342 | ||
341 | /* Gain ramping rate value */ | 343 | /* Gain ramping rate value */ |
342 | static const char * const da9055_gain_ramping_txt[] = { | 344 | static const char * const da9055_gain_ramping_txt[] = { |
@@ -344,44 +346,44 @@ static const char * const da9055_gain_ramping_txt[] = { | |||
344 | "nominal rate / 8" | 346 | "nominal rate / 8" |
345 | }; | 347 | }; |
346 | 348 | ||
347 | static const struct soc_enum da9055_gain_ramping_rate = | 349 | static SOC_ENUM_SINGLE_DECL(da9055_gain_ramping_rate, |
348 | SOC_ENUM_SINGLE(DA9055_GAIN_RAMP_CTRL, 0, 4, da9055_gain_ramping_txt); | 350 | DA9055_GAIN_RAMP_CTRL, 0, da9055_gain_ramping_txt); |
349 | 351 | ||
350 | /* DAC noise gate setup time value */ | 352 | /* DAC noise gate setup time value */ |
351 | static const char * const da9055_dac_ng_setup_time_txt[] = { | 353 | static const char * const da9055_dac_ng_setup_time_txt[] = { |
352 | "256 samples", "512 samples", "1024 samples", "2048 samples" | 354 | "256 samples", "512 samples", "1024 samples", "2048 samples" |
353 | }; | 355 | }; |
354 | 356 | ||
355 | static const struct soc_enum da9055_dac_ng_setup_time = | 357 | static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_setup_time, |
356 | SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 0, 4, | 358 | DA9055_DAC_NG_SETUP_TIME, 0, |
357 | da9055_dac_ng_setup_time_txt); | 359 | da9055_dac_ng_setup_time_txt); |
358 | 360 | ||
359 | /* DAC noise gate rampup rate value */ | 361 | /* DAC noise gate rampup rate value */ |
360 | static const char * const da9055_dac_ng_rampup_txt[] = { | 362 | static const char * const da9055_dac_ng_rampup_txt[] = { |
361 | "0.02 ms/dB", "0.16 ms/dB" | 363 | "0.02 ms/dB", "0.16 ms/dB" |
362 | }; | 364 | }; |
363 | 365 | ||
364 | static const struct soc_enum da9055_dac_ng_rampup_rate = | 366 | static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_rampup_rate, |
365 | SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 2, 2, | 367 | DA9055_DAC_NG_SETUP_TIME, 2, |
366 | da9055_dac_ng_rampup_txt); | 368 | da9055_dac_ng_rampup_txt); |
367 | 369 | ||
368 | /* DAC noise gate rampdown rate value */ | 370 | /* DAC noise gate rampdown rate value */ |
369 | static const char * const da9055_dac_ng_rampdown_txt[] = { | 371 | static const char * const da9055_dac_ng_rampdown_txt[] = { |
370 | "0.64 ms/dB", "20.48 ms/dB" | 372 | "0.64 ms/dB", "20.48 ms/dB" |
371 | }; | 373 | }; |
372 | 374 | ||
373 | static const struct soc_enum da9055_dac_ng_rampdown_rate = | 375 | static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_rampdown_rate, |
374 | SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 3, 2, | 376 | DA9055_DAC_NG_SETUP_TIME, 3, |
375 | da9055_dac_ng_rampdown_txt); | 377 | da9055_dac_ng_rampdown_txt); |
376 | 378 | ||
377 | /* DAC soft mute rate value */ | 379 | /* DAC soft mute rate value */ |
378 | static const char * const da9055_dac_soft_mute_rate_txt[] = { | 380 | static const char * const da9055_dac_soft_mute_rate_txt[] = { |
379 | "1", "2", "4", "8", "16", "32", "64" | 381 | "1", "2", "4", "8", "16", "32", "64" |
380 | }; | 382 | }; |
381 | 383 | ||
382 | static const struct soc_enum da9055_dac_soft_mute_rate = | 384 | static SOC_ENUM_SINGLE_DECL(da9055_dac_soft_mute_rate, |
383 | SOC_ENUM_SINGLE(DA9055_DAC_FILTERS5, 4, 7, | 385 | DA9055_DAC_FILTERS5, 4, |
384 | da9055_dac_soft_mute_rate_txt); | 386 | da9055_dac_soft_mute_rate_txt); |
385 | 387 | ||
386 | /* DAC routing select */ | 388 | /* DAC routing select */ |
387 | static const char * const da9055_dac_src_txt[] = { | 389 | static const char * const da9055_dac_src_txt[] = { |
@@ -389,40 +391,40 @@ static const char * const da9055_dac_src_txt[] = { | |||
389 | "AIF input right" | 391 | "AIF input right" |
390 | }; | 392 | }; |
391 | 393 | ||
392 | static const struct soc_enum da9055_dac_l_src = | 394 | static SOC_ENUM_SINGLE_DECL(da9055_dac_l_src, |
393 | SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 0, 4, da9055_dac_src_txt); | 395 | DA9055_DIG_ROUTING_DAC, 0, da9055_dac_src_txt); |
394 | 396 | ||
395 | static const struct soc_enum da9055_dac_r_src = | 397 | static SOC_ENUM_SINGLE_DECL(da9055_dac_r_src, |
396 | SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 4, 4, da9055_dac_src_txt); | 398 | DA9055_DIG_ROUTING_DAC, 4, da9055_dac_src_txt); |
397 | 399 | ||
398 | /* MIC PGA Left source select */ | 400 | /* MIC PGA Left source select */ |
399 | static const char * const da9055_mic_l_src_txt[] = { | 401 | static const char * const da9055_mic_l_src_txt[] = { |
400 | "MIC1_P_N", "MIC1_P", "MIC1_N", "MIC2_L" | 402 | "MIC1_P_N", "MIC1_P", "MIC1_N", "MIC2_L" |
401 | }; | 403 | }; |
402 | 404 | ||
403 | static const struct soc_enum da9055_mic_l_src = | 405 | static SOC_ENUM_SINGLE_DECL(da9055_mic_l_src, |
404 | SOC_ENUM_SINGLE(DA9055_MIXIN_L_SELECT, 4, 4, da9055_mic_l_src_txt); | 406 | DA9055_MIXIN_L_SELECT, 4, da9055_mic_l_src_txt); |
405 | 407 | ||
406 | /* MIC PGA Right source select */ | 408 | /* MIC PGA Right source select */ |
407 | static const char * const da9055_mic_r_src_txt[] = { | 409 | static const char * const da9055_mic_r_src_txt[] = { |
408 | "MIC2_R_L", "MIC2_R", "MIC2_L" | 410 | "MIC2_R_L", "MIC2_R", "MIC2_L" |
409 | }; | 411 | }; |
410 | 412 | ||
411 | static const struct soc_enum da9055_mic_r_src = | 413 | static SOC_ENUM_SINGLE_DECL(da9055_mic_r_src, |
412 | SOC_ENUM_SINGLE(DA9055_MIXIN_R_SELECT, 4, 3, da9055_mic_r_src_txt); | 414 | DA9055_MIXIN_R_SELECT, 4, da9055_mic_r_src_txt); |
413 | 415 | ||
414 | /* ALC Input Signal Tracking rate select */ | 416 | /* ALC Input Signal Tracking rate select */ |
415 | static const char * const da9055_signal_tracking_rate_txt[] = { | 417 | static const char * const da9055_signal_tracking_rate_txt[] = { |
416 | "1/4", "1/16", "1/256", "1/65536" | 418 | "1/4", "1/16", "1/256", "1/65536" |
417 | }; | 419 | }; |
418 | 420 | ||
419 | static const struct soc_enum da9055_integ_attack_rate = | 421 | static SOC_ENUM_SINGLE_DECL(da9055_integ_attack_rate, |
420 | SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 4, 4, | 422 | DA9055_ALC_CTRL3, 4, |
421 | da9055_signal_tracking_rate_txt); | 423 | da9055_signal_tracking_rate_txt); |
422 | 424 | ||
423 | static const struct soc_enum da9055_integ_release_rate = | 425 | static SOC_ENUM_SINGLE_DECL(da9055_integ_release_rate, |
424 | SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 6, 4, | 426 | DA9055_ALC_CTRL3, 6, |
425 | da9055_signal_tracking_rate_txt); | 427 | da9055_signal_tracking_rate_txt); |
426 | 428 | ||
427 | /* ALC Attack Rate select */ | 429 | /* ALC Attack Rate select */ |
428 | static const char * const da9055_attack_rate_txt[] = { | 430 | static const char * const da9055_attack_rate_txt[] = { |
@@ -430,8 +432,8 @@ static const char * const da9055_attack_rate_txt[] = { | |||
430 | "5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" | 432 | "5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" |
431 | }; | 433 | }; |
432 | 434 | ||
433 | static const struct soc_enum da9055_attack_rate = | 435 | static SOC_ENUM_SINGLE_DECL(da9055_attack_rate, |
434 | SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 0, 13, da9055_attack_rate_txt); | 436 | DA9055_ALC_CTRL2, 0, da9055_attack_rate_txt); |
435 | 437 | ||
436 | /* ALC Release Rate select */ | 438 | /* ALC Release Rate select */ |
437 | static const char * const da9055_release_rate_txt[] = { | 439 | static const char * const da9055_release_rate_txt[] = { |
@@ -439,8 +441,8 @@ static const char * const da9055_release_rate_txt[] = { | |||
439 | "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" | 441 | "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" |
440 | }; | 442 | }; |
441 | 443 | ||
442 | static const struct soc_enum da9055_release_rate = | 444 | static SOC_ENUM_SINGLE_DECL(da9055_release_rate, |
443 | SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 4, 11, da9055_release_rate_txt); | 445 | DA9055_ALC_CTRL2, 4, da9055_release_rate_txt); |
444 | 446 | ||
445 | /* ALC Hold Time select */ | 447 | /* ALC Hold Time select */ |
446 | static const char * const da9055_hold_time_txt[] = { | 448 | static const char * const da9055_hold_time_txt[] = { |
@@ -449,8 +451,8 @@ static const char * const da9055_hold_time_txt[] = { | |||
449 | "253952/fs", "507904/fs", "1015808/fs", "2031616/fs" | 451 | "253952/fs", "507904/fs", "1015808/fs", "2031616/fs" |
450 | }; | 452 | }; |
451 | 453 | ||
452 | static const struct soc_enum da9055_hold_time = | 454 | static SOC_ENUM_SINGLE_DECL(da9055_hold_time, |
453 | SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 0, 16, da9055_hold_time_txt); | 455 | DA9055_ALC_CTRL3, 0, da9055_hold_time_txt); |
454 | 456 | ||
455 | static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val) | 457 | static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val) |
456 | { | 458 | { |
@@ -1381,16 +1383,8 @@ static int da9055_set_bias_level(struct snd_soc_codec *codec, | |||
1381 | 1383 | ||
1382 | static int da9055_probe(struct snd_soc_codec *codec) | 1384 | static int da9055_probe(struct snd_soc_codec *codec) |
1383 | { | 1385 | { |
1384 | int ret; | ||
1385 | struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec); | 1386 | struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec); |
1386 | 1387 | ||
1387 | codec->control_data = da9055->regmap; | ||
1388 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1389 | if (ret < 0) { | ||
1390 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1391 | return ret; | ||
1392 | } | ||
1393 | |||
1394 | /* Enable all Gain Ramps */ | 1388 | /* Enable all Gain Ramps */ |
1395 | snd_soc_update_bits(codec, DA9055_AUX_L_CTRL, | 1389 | snd_soc_update_bits(codec, DA9055_AUX_L_CTRL, |
1396 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | 1390 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); |
@@ -1523,17 +1517,30 @@ static int da9055_remove(struct i2c_client *client) | |||
1523 | return 0; | 1517 | return 0; |
1524 | } | 1518 | } |
1525 | 1519 | ||
1520 | /* | ||
1521 | * DO NOT change the device Ids. The naming is intentionally specific as both | ||
1522 | * the CODEC and PMIC parts of this chip are instantiated separately as I2C | ||
1523 | * devices (both have configurable I2C addresses, and are to all intents and | ||
1524 | * purposes separate). As a result there are specific DA9055 Ids for CODEC | ||
1525 | * and PMIC, which must be different to operate together. | ||
1526 | */ | ||
1526 | static const struct i2c_device_id da9055_i2c_id[] = { | 1527 | static const struct i2c_device_id da9055_i2c_id[] = { |
1527 | { "da9055", 0 }, | 1528 | { "da9055-codec", 0 }, |
1528 | { } | 1529 | { } |
1529 | }; | 1530 | }; |
1530 | MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); | 1531 | MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); |
1531 | 1532 | ||
1533 | static const struct of_device_id da9055_of_match[] = { | ||
1534 | { .compatible = "dlg,da9055-codec", }, | ||
1535 | { } | ||
1536 | }; | ||
1537 | |||
1532 | /* I2C codec control layer */ | 1538 | /* I2C codec control layer */ |
1533 | static struct i2c_driver da9055_i2c_driver = { | 1539 | static struct i2c_driver da9055_i2c_driver = { |
1534 | .driver = { | 1540 | .driver = { |
1535 | .name = "da9055", | 1541 | .name = "da9055-codec", |
1536 | .owner = THIS_MODULE, | 1542 | .owner = THIS_MODULE, |
1543 | .of_match_table = of_match_ptr(da9055_of_match), | ||
1537 | }, | 1544 | }, |
1538 | .probe = da9055_i2c_probe, | 1545 | .probe = da9055_i2c_probe, |
1539 | .remove = da9055_remove, | 1546 | .remove = da9055_remove, |
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index 5839048ec467..3a89ce66d51d 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c | |||
@@ -140,13 +140,17 @@ static const char *isabelle_rx1_texts[] = {"VRX1", "ARX1"}; | |||
140 | static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"}; | 140 | static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"}; |
141 | 141 | ||
142 | static const struct soc_enum isabelle_rx1_enum[] = { | 142 | static const struct soc_enum isabelle_rx1_enum[] = { |
143 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3, 1, isabelle_rx1_texts), | 143 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3, |
144 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5, 1, isabelle_rx1_texts), | 144 | ARRAY_SIZE(isabelle_rx1_texts), isabelle_rx1_texts), |
145 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5, | ||
146 | ARRAY_SIZE(isabelle_rx1_texts), isabelle_rx1_texts), | ||
145 | }; | 147 | }; |
146 | 148 | ||
147 | static const struct soc_enum isabelle_rx2_enum[] = { | 149 | static const struct soc_enum isabelle_rx2_enum[] = { |
148 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, 1, isabelle_rx2_texts), | 150 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, |
149 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, 1, isabelle_rx2_texts), | 151 | ARRAY_SIZE(isabelle_rx2_texts), isabelle_rx2_texts), |
152 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, | ||
153 | ARRAY_SIZE(isabelle_rx2_texts), isabelle_rx2_texts), | ||
150 | }; | 154 | }; |
151 | 155 | ||
152 | /* Headset DAC playback switches */ | 156 | /* Headset DAC playback switches */ |
@@ -161,13 +165,17 @@ static const char *isabelle_atx_texts[] = {"AMIC1", "DMIC"}; | |||
161 | static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"}; | 165 | static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"}; |
162 | 166 | ||
163 | static const struct soc_enum isabelle_atx_enum[] = { | 167 | static const struct soc_enum isabelle_atx_enum[] = { |
164 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, 1, isabelle_atx_texts), | 168 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, |
165 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_atx_texts), | 169 | ARRAY_SIZE(isabelle_atx_texts), isabelle_atx_texts), |
170 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, | ||
171 | ARRAY_SIZE(isabelle_atx_texts), isabelle_atx_texts), | ||
166 | }; | 172 | }; |
167 | 173 | ||
168 | static const struct soc_enum isabelle_vtx_enum[] = { | 174 | static const struct soc_enum isabelle_vtx_enum[] = { |
169 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, 1, isabelle_vtx_texts), | 175 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, |
170 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_vtx_texts), | 176 | ARRAY_SIZE(isabelle_vtx_texts), isabelle_vtx_texts), |
177 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, | ||
178 | ARRAY_SIZE(isabelle_vtx_texts), isabelle_vtx_texts), | ||
171 | }; | 179 | }; |
172 | 180 | ||
173 | static const struct snd_kcontrol_new atx_mux_controls = | 181 | static const struct snd_kcontrol_new atx_mux_controls = |
@@ -183,17 +191,13 @@ static const char *isabelle_amic1_texts[] = { | |||
183 | /* Left analog microphone selection */ | 191 | /* Left analog microphone selection */ |
184 | static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"}; | 192 | static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"}; |
185 | 193 | ||
186 | static const struct soc_enum isabelle_amic1_enum[] = { | 194 | static SOC_ENUM_SINGLE_DECL(isabelle_amic1_enum, |
187 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 5, | 195 | ISABELLE_AMIC_CFG_REG, 5, |
188 | ARRAY_SIZE(isabelle_amic1_texts), | 196 | isabelle_amic1_texts); |
189 | isabelle_amic1_texts), | ||
190 | }; | ||
191 | 197 | ||
192 | static const struct soc_enum isabelle_amic2_enum[] = { | 198 | static SOC_ENUM_SINGLE_DECL(isabelle_amic2_enum, |
193 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 4, | 199 | ISABELLE_AMIC_CFG_REG, 4, |
194 | ARRAY_SIZE(isabelle_amic2_texts), | 200 | isabelle_amic2_texts); |
195 | isabelle_amic2_texts), | ||
196 | }; | ||
197 | 201 | ||
198 | static const struct snd_kcontrol_new amic1_control = | 202 | static const struct snd_kcontrol_new amic1_control = |
199 | SOC_DAPM_ENUM("Route", isabelle_amic1_enum); | 203 | SOC_DAPM_ENUM("Route", isabelle_amic1_enum); |
@@ -206,16 +210,20 @@ static const char *isabelle_st_audio_texts[] = {"ATX1", "ATX2"}; | |||
206 | static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"}; | 210 | static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"}; |
207 | 211 | ||
208 | static const struct soc_enum isabelle_st_audio_enum[] = { | 212 | static const struct soc_enum isabelle_st_audio_enum[] = { |
209 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7, 1, | 213 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7, |
214 | ARRAY_SIZE(isabelle_st_audio_texts), | ||
210 | isabelle_st_audio_texts), | 215 | isabelle_st_audio_texts), |
211 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7, 1, | 216 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7, |
217 | ARRAY_SIZE(isabelle_st_audio_texts), | ||
212 | isabelle_st_audio_texts), | 218 | isabelle_st_audio_texts), |
213 | }; | 219 | }; |
214 | 220 | ||
215 | static const struct soc_enum isabelle_st_voice_enum[] = { | 221 | static const struct soc_enum isabelle_st_voice_enum[] = { |
216 | SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7, 1, | 222 | SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7, |
223 | ARRAY_SIZE(isabelle_st_voice_texts), | ||
217 | isabelle_st_voice_texts), | 224 | isabelle_st_voice_texts), |
218 | SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7, 1, | 225 | SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7, |
226 | ARRAY_SIZE(isabelle_st_voice_texts), | ||
219 | isabelle_st_voice_texts), | 227 | isabelle_st_voice_texts), |
220 | }; | 228 | }; |
221 | 229 | ||
@@ -910,8 +918,7 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream, | |||
910 | struct snd_pcm_hw_params *params, | 918 | struct snd_pcm_hw_params *params, |
911 | struct snd_soc_dai *dai) | 919 | struct snd_soc_dai *dai) |
912 | { | 920 | { |
913 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 921 | struct snd_soc_codec *codec = dai->codec; |
914 | struct snd_soc_codec *codec = rtd->codec; | ||
915 | u16 aif = 0; | 922 | u16 aif = 0; |
916 | unsigned int fs_val = 0; | 923 | unsigned int fs_val = 0; |
917 | 924 | ||
@@ -1082,23 +1089,7 @@ static struct snd_soc_dai_driver isabelle_dai[] = { | |||
1082 | }, | 1089 | }, |
1083 | }; | 1090 | }; |
1084 | 1091 | ||
1085 | static int isabelle_probe(struct snd_soc_codec *codec) | ||
1086 | { | ||
1087 | int ret = 0; | ||
1088 | |||
1089 | codec->control_data = dev_get_regmap(codec->dev, NULL); | ||
1090 | |||
1091 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1092 | if (ret < 0) { | ||
1093 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1094 | return ret; | ||
1095 | } | ||
1096 | |||
1097 | return 0; | ||
1098 | } | ||
1099 | |||
1100 | static struct snd_soc_codec_driver soc_codec_dev_isabelle = { | 1092 | static struct snd_soc_codec_driver soc_codec_dev_isabelle = { |
1101 | .probe = isabelle_probe, | ||
1102 | .set_bias_level = isabelle_set_bias_level, | 1093 | .set_bias_level = isabelle_set_bias_level, |
1103 | .controls = isabelle_snd_controls, | 1094 | .controls = isabelle_snd_controls, |
1104 | .num_controls = ARRAY_SIZE(isabelle_snd_controls), | 1095 | .num_controls = ARRAY_SIZE(isabelle_snd_controls), |
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index 0e5743ea79df..4f048db9f55f 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c | |||
@@ -101,8 +101,7 @@ static const char *lm4857_mode[] = { | |||
101 | "Headphone", | 101 | "Headphone", |
102 | }; | 102 | }; |
103 | 103 | ||
104 | static const struct soc_enum lm4857_mode_enum = | 104 | static SOC_ENUM_SINGLE_EXT_DECL(lm4857_mode_enum, lm4857_mode); |
105 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode); | ||
106 | 105 | ||
107 | static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = { | 106 | static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = { |
108 | SND_SOC_DAPM_INPUT("IN"), | 107 | SND_SOC_DAPM_INPUT("IN"), |
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index e19490cfb3a8..275b3f72f3f4 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c | |||
@@ -195,33 +195,31 @@ struct lm49453_priv { | |||
195 | 195 | ||
196 | static const char *lm49453_mic2mode_text[] = {"Single Ended", "Differential"}; | 196 | static const char *lm49453_mic2mode_text[] = {"Single Ended", "Differential"}; |
197 | 197 | ||
198 | static const SOC_ENUM_SINGLE_DECL(lm49453_mic2mode_enum, LM49453_P0_MICR_REG, 5, | 198 | static SOC_ENUM_SINGLE_DECL(lm49453_mic2mode_enum, LM49453_P0_MICR_REG, 5, |
199 | lm49453_mic2mode_text); | 199 | lm49453_mic2mode_text); |
200 | 200 | ||
201 | static const char *lm49453_dmic_cfg_text[] = {"DMICDAT1", "DMICDAT2"}; | 201 | static const char *lm49453_dmic_cfg_text[] = {"DMICDAT1", "DMICDAT2"}; |
202 | 202 | ||
203 | static const SOC_ENUM_SINGLE_DECL(lm49453_dmic12_cfg_enum, | 203 | static SOC_ENUM_SINGLE_DECL(lm49453_dmic12_cfg_enum, |
204 | LM49453_P0_DIGITAL_MIC1_CONFIG_REG, | 204 | LM49453_P0_DIGITAL_MIC1_CONFIG_REG, 7, |
205 | 7, lm49453_dmic_cfg_text); | 205 | lm49453_dmic_cfg_text); |
206 | 206 | ||
207 | static const SOC_ENUM_SINGLE_DECL(lm49453_dmic34_cfg_enum, | 207 | static SOC_ENUM_SINGLE_DECL(lm49453_dmic34_cfg_enum, |
208 | LM49453_P0_DIGITAL_MIC2_CONFIG_REG, | 208 | LM49453_P0_DIGITAL_MIC2_CONFIG_REG, 7, |
209 | 7, lm49453_dmic_cfg_text); | 209 | lm49453_dmic_cfg_text); |
210 | 210 | ||
211 | /* MUX Controls */ | 211 | /* MUX Controls */ |
212 | static const char *lm49453_adcl_mux_text[] = { "MIC1", "Aux_L" }; | 212 | static const char *lm49453_adcl_mux_text[] = { "MIC1", "Aux_L" }; |
213 | 213 | ||
214 | static const char *lm49453_adcr_mux_text[] = { "MIC2", "Aux_R" }; | 214 | static const char *lm49453_adcr_mux_text[] = { "MIC2", "Aux_R" }; |
215 | 215 | ||
216 | static const struct soc_enum lm49453_adcl_enum = | 216 | static SOC_ENUM_SINGLE_DECL(lm49453_adcl_enum, |
217 | SOC_ENUM_SINGLE(LM49453_P0_ANALOG_MIXER_ADC_REG, 0, | 217 | LM49453_P0_ANALOG_MIXER_ADC_REG, 0, |
218 | ARRAY_SIZE(lm49453_adcl_mux_text), | 218 | lm49453_adcl_mux_text); |
219 | lm49453_adcl_mux_text); | ||
220 | 219 | ||
221 | static const struct soc_enum lm49453_adcr_enum = | 220 | static SOC_ENUM_SINGLE_DECL(lm49453_adcr_enum, |
222 | SOC_ENUM_SINGLE(LM49453_P0_ANALOG_MIXER_ADC_REG, 1, | 221 | LM49453_P0_ANALOG_MIXER_ADC_REG, 1, |
223 | ARRAY_SIZE(lm49453_adcr_mux_text), | 222 | lm49453_adcr_mux_text); |
224 | lm49453_adcr_mux_text); | ||
225 | 223 | ||
226 | static const struct snd_kcontrol_new lm49453_adcl_mux_control = | 224 | static const struct snd_kcontrol_new lm49453_adcl_mux_control = |
227 | SOC_DAPM_ENUM("ADC Left Mux", lm49453_adcl_enum); | 225 | SOC_DAPM_ENUM("ADC Left Mux", lm49453_adcl_enum); |
@@ -1409,22 +1407,6 @@ static int lm49453_resume(struct snd_soc_codec *codec) | |||
1409 | return 0; | 1407 | return 0; |
1410 | } | 1408 | } |
1411 | 1409 | ||
1412 | static int lm49453_probe(struct snd_soc_codec *codec) | ||
1413 | { | ||
1414 | struct lm49453_priv *lm49453 = snd_soc_codec_get_drvdata(codec); | ||
1415 | int ret = 0; | ||
1416 | |||
1417 | codec->control_data = lm49453->regmap; | ||
1418 | |||
1419 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1420 | if (ret < 0) { | ||
1421 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1422 | return ret; | ||
1423 | } | ||
1424 | |||
1425 | return 0; | ||
1426 | } | ||
1427 | |||
1428 | /* power down chip */ | 1410 | /* power down chip */ |
1429 | static int lm49453_remove(struct snd_soc_codec *codec) | 1411 | static int lm49453_remove(struct snd_soc_codec *codec) |
1430 | { | 1412 | { |
@@ -1433,7 +1415,6 @@ static int lm49453_remove(struct snd_soc_codec *codec) | |||
1433 | } | 1415 | } |
1434 | 1416 | ||
1435 | static struct snd_soc_codec_driver soc_codec_dev_lm49453 = { | 1417 | static struct snd_soc_codec_driver soc_codec_dev_lm49453 = { |
1436 | .probe = lm49453_probe, | ||
1437 | .remove = lm49453_remove, | 1418 | .remove = lm49453_remove, |
1438 | .suspend = lm49453_suspend, | 1419 | .suspend = lm49453_suspend, |
1439 | .resume = lm49453_resume, | 1420 | .resume = lm49453_resume, |
diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c index 31f91560e9f6..ec481fc428c7 100644 --- a/sound/soc/codecs/max9768.c +++ b/sound/soc/codecs/max9768.c | |||
@@ -135,11 +135,6 @@ static int max9768_probe(struct snd_soc_codec *codec) | |||
135 | struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); | 135 | struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); |
136 | int ret; | 136 | int ret; |
137 | 137 | ||
138 | codec->control_data = max9768->regmap; | ||
139 | ret = snd_soc_codec_set_cache_io(codec, 2, 6, SND_SOC_REGMAP); | ||
140 | if (ret) | ||
141 | return ret; | ||
142 | |||
143 | if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) { | 138 | if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) { |
144 | ret = snd_soc_write(codec, MAX9768_CTRL, MAX9768_CTRL_PWM); | 139 | ret = snd_soc_write(codec, MAX9768_CTRL, MAX9768_CTRL_PWM); |
145 | if (ret) | 140 | if (ret) |
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index ee660e2d3df3..ef7cf89f5623 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -597,28 +597,27 @@ static const unsigned int max98088_exmode_values[] = { | |||
597 | 0x00, 0x43, 0x10, 0x20, 0x30, 0x40, 0x11, 0x22, 0x32 | 597 | 0x00, 0x43, 0x10, 0x20, 0x30, 0x40, 0x11, 0x22, 0x32 |
598 | }; | 598 | }; |
599 | 599 | ||
600 | static const struct soc_enum max98088_exmode_enum = | 600 | static SOC_VALUE_ENUM_SINGLE_DECL(max98088_exmode_enum, |
601 | SOC_VALUE_ENUM_SINGLE(M98088_REG_41_SPKDHP, 0, 127, | 601 | M98088_REG_41_SPKDHP, 0, 127, |
602 | ARRAY_SIZE(max98088_exmode_texts), | 602 | max98088_exmode_texts, |
603 | max98088_exmode_texts, | 603 | max98088_exmode_values); |
604 | max98088_exmode_values); | ||
605 | 604 | ||
606 | static const char *max98088_ex_thresh[] = { /* volts PP */ | 605 | static const char *max98088_ex_thresh[] = { /* volts PP */ |
607 | "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"}; | 606 | "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"}; |
608 | static const struct soc_enum max98088_ex_thresh_enum[] = { | 607 | static SOC_ENUM_SINGLE_DECL(max98088_ex_thresh_enum, |
609 | SOC_ENUM_SINGLE(M98088_REG_42_SPKDHP_THRESH, 0, 8, | 608 | M98088_REG_42_SPKDHP_THRESH, 0, |
610 | max98088_ex_thresh), | 609 | max98088_ex_thresh); |
611 | }; | ||
612 | 610 | ||
613 | static const char *max98088_fltr_mode[] = {"Voice", "Music" }; | 611 | static const char *max98088_fltr_mode[] = {"Voice", "Music" }; |
614 | static const struct soc_enum max98088_filter_mode_enum[] = { | 612 | static SOC_ENUM_SINGLE_DECL(max98088_filter_mode_enum, |
615 | SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 7, 2, max98088_fltr_mode), | 613 | M98088_REG_18_DAI1_FILTERS, 7, |
616 | }; | 614 | max98088_fltr_mode); |
617 | 615 | ||
618 | static const char *max98088_extmic_text[] = { "None", "MIC1", "MIC2" }; | 616 | static const char *max98088_extmic_text[] = { "None", "MIC1", "MIC2" }; |
619 | 617 | ||
620 | static const struct soc_enum max98088_extmic_enum = | 618 | static SOC_ENUM_SINGLE_DECL(max98088_extmic_enum, |
621 | SOC_ENUM_SINGLE(M98088_REG_48_CFG_MIC, 0, 3, max98088_extmic_text); | 619 | M98088_REG_48_CFG_MIC, 0, |
620 | max98088_extmic_text); | ||
622 | 621 | ||
623 | static const struct snd_kcontrol_new max98088_extmic_mux = | 622 | static const struct snd_kcontrol_new max98088_extmic_mux = |
624 | SOC_DAPM_ENUM("External MIC Mux", max98088_extmic_enum); | 623 | SOC_DAPM_ENUM("External MIC Mux", max98088_extmic_enum); |
@@ -626,12 +625,12 @@ static const struct snd_kcontrol_new max98088_extmic_mux = | |||
626 | static const char *max98088_dai1_fltr[] = { | 625 | static const char *max98088_dai1_fltr[] = { |
627 | "Off", "fc=258/fs=16k", "fc=500/fs=16k", | 626 | "Off", "fc=258/fs=16k", "fc=500/fs=16k", |
628 | "fc=258/fs=8k", "fc=500/fs=8k", "fc=200"}; | 627 | "fc=258/fs=8k", "fc=500/fs=8k", "fc=200"}; |
629 | static const struct soc_enum max98088_dai1_dac_filter_enum[] = { | 628 | static SOC_ENUM_SINGLE_DECL(max98088_dai1_dac_filter_enum, |
630 | SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 0, 6, max98088_dai1_fltr), | 629 | M98088_REG_18_DAI1_FILTERS, 0, |
631 | }; | 630 | max98088_dai1_fltr); |
632 | static const struct soc_enum max98088_dai1_adc_filter_enum[] = { | 631 | static SOC_ENUM_SINGLE_DECL(max98088_dai1_adc_filter_enum, |
633 | SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 4, 6, max98088_dai1_fltr), | 632 | M98088_REG_18_DAI1_FILTERS, 4, |
634 | }; | 633 | max98088_dai1_fltr); |
635 | 634 | ||
636 | static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol, | 635 | static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol, |
637 | struct snd_ctl_elem_value *ucontrol) | 636 | struct snd_ctl_elem_value *ucontrol) |
@@ -1849,7 +1848,7 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec) | |||
1849 | 1848 | ||
1850 | /* Now point the soc_enum to .texts array items */ | 1849 | /* Now point the soc_enum to .texts array items */ |
1851 | max98088->eq_enum.texts = max98088->eq_texts; | 1850 | max98088->eq_enum.texts = max98088->eq_texts; |
1852 | max98088->eq_enum.max = max98088->eq_textcnt; | 1851 | max98088->eq_enum.items = max98088->eq_textcnt; |
1853 | 1852 | ||
1854 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); | 1853 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); |
1855 | if (ret != 0) | 1854 | if (ret != 0) |
@@ -1915,12 +1914,6 @@ static int max98088_probe(struct snd_soc_codec *codec) | |||
1915 | 1914 | ||
1916 | regcache_mark_dirty(max98088->regmap); | 1915 | regcache_mark_dirty(max98088->regmap); |
1917 | 1916 | ||
1918 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1919 | if (ret != 0) { | ||
1920 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1921 | return ret; | ||
1922 | } | ||
1923 | |||
1924 | /* initialize private data */ | 1917 | /* initialize private data */ |
1925 | 1918 | ||
1926 | max98088->sysclk = (unsigned)-1; | 1919 | max98088->sysclk = (unsigned)-1; |
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 51f9b3d16b41..98c6e104357c 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c | |||
@@ -336,6 +336,7 @@ static bool max98090_readable_register(struct device *dev, unsigned int reg) | |||
336 | case M98090_REG_RECORD_TDM_SLOT: | 336 | case M98090_REG_RECORD_TDM_SLOT: |
337 | case M98090_REG_SAMPLE_RATE: | 337 | case M98090_REG_SAMPLE_RATE: |
338 | case M98090_REG_DMIC34_BIQUAD_BASE ... M98090_REG_DMIC34_BIQUAD_BASE + 0x0E: | 338 | case M98090_REG_DMIC34_BIQUAD_BASE ... M98090_REG_DMIC34_BIQUAD_BASE + 0x0E: |
339 | case M98090_REG_REVISION_ID: | ||
339 | return true; | 340 | return true; |
340 | default: | 341 | default: |
341 | return false; | 342 | return false; |
@@ -512,65 +513,75 @@ static const char *max98090_perf_pwr_text[] = | |||
512 | static const char *max98090_pwr_perf_text[] = | 513 | static const char *max98090_pwr_perf_text[] = |
513 | { "Low Power", "High Performance" }; | 514 | { "Low Power", "High Performance" }; |
514 | 515 | ||
515 | static const struct soc_enum max98090_vcmbandgap_enum = | 516 | static SOC_ENUM_SINGLE_DECL(max98090_vcmbandgap_enum, |
516 | SOC_ENUM_SINGLE(M98090_REG_BIAS_CONTROL, M98090_VCM_MODE_SHIFT, | 517 | M98090_REG_BIAS_CONTROL, |
517 | ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); | 518 | M98090_VCM_MODE_SHIFT, |
519 | max98090_pwr_perf_text); | ||
518 | 520 | ||
519 | static const char *max98090_osr128_text[] = { "64*fs", "128*fs" }; | 521 | static const char *max98090_osr128_text[] = { "64*fs", "128*fs" }; |
520 | 522 | ||
521 | static const struct soc_enum max98090_osr128_enum = | 523 | static SOC_ENUM_SINGLE_DECL(max98090_osr128_enum, |
522 | SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_OSR128_SHIFT, | 524 | M98090_REG_ADC_CONTROL, |
523 | ARRAY_SIZE(max98090_osr128_text), max98090_osr128_text); | 525 | M98090_OSR128_SHIFT, |
526 | max98090_osr128_text); | ||
524 | 527 | ||
525 | static const char *max98090_mode_text[] = { "Voice", "Music" }; | 528 | static const char *max98090_mode_text[] = { "Voice", "Music" }; |
526 | 529 | ||
527 | static const struct soc_enum max98090_mode_enum = | 530 | static SOC_ENUM_SINGLE_DECL(max98090_mode_enum, |
528 | SOC_ENUM_SINGLE(M98090_REG_FILTER_CONFIG, M98090_MODE_SHIFT, | 531 | M98090_REG_FILTER_CONFIG, |
529 | ARRAY_SIZE(max98090_mode_text), max98090_mode_text); | 532 | M98090_MODE_SHIFT, |
533 | max98090_mode_text); | ||
530 | 534 | ||
531 | static const struct soc_enum max98090_filter_dmic34mode_enum = | 535 | static SOC_ENUM_SINGLE_DECL(max98090_filter_dmic34mode_enum, |
532 | SOC_ENUM_SINGLE(M98090_REG_FILTER_CONFIG, | 536 | M98090_REG_FILTER_CONFIG, |
533 | M98090_FLT_DMIC34MODE_SHIFT, | 537 | M98090_FLT_DMIC34MODE_SHIFT, |
534 | ARRAY_SIZE(max98090_mode_text), max98090_mode_text); | 538 | max98090_mode_text); |
535 | 539 | ||
536 | static const char *max98090_drcatk_text[] = | 540 | static const char *max98090_drcatk_text[] = |
537 | { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" }; | 541 | { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" }; |
538 | 542 | ||
539 | static const struct soc_enum max98090_drcatk_enum = | 543 | static SOC_ENUM_SINGLE_DECL(max98090_drcatk_enum, |
540 | SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCATK_SHIFT, | 544 | M98090_REG_DRC_TIMING, |
541 | ARRAY_SIZE(max98090_drcatk_text), max98090_drcatk_text); | 545 | M98090_DRCATK_SHIFT, |
546 | max98090_drcatk_text); | ||
542 | 547 | ||
543 | static const char *max98090_drcrls_text[] = | 548 | static const char *max98090_drcrls_text[] = |
544 | { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" }; | 549 | { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" }; |
545 | 550 | ||
546 | static const struct soc_enum max98090_drcrls_enum = | 551 | static SOC_ENUM_SINGLE_DECL(max98090_drcrls_enum, |
547 | SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCRLS_SHIFT, | 552 | M98090_REG_DRC_TIMING, |
548 | ARRAY_SIZE(max98090_drcrls_text), max98090_drcrls_text); | 553 | M98090_DRCRLS_SHIFT, |
554 | max98090_drcrls_text); | ||
549 | 555 | ||
550 | static const char *max98090_alccmp_text[] = | 556 | static const char *max98090_alccmp_text[] = |
551 | { "1:1", "1:1.5", "1:2", "1:4", "1:INF" }; | 557 | { "1:1", "1:1.5", "1:2", "1:4", "1:INF" }; |
552 | 558 | ||
553 | static const struct soc_enum max98090_alccmp_enum = | 559 | static SOC_ENUM_SINGLE_DECL(max98090_alccmp_enum, |
554 | SOC_ENUM_SINGLE(M98090_REG_DRC_COMPRESSOR, M98090_DRCCMP_SHIFT, | 560 | M98090_REG_DRC_COMPRESSOR, |
555 | ARRAY_SIZE(max98090_alccmp_text), max98090_alccmp_text); | 561 | M98090_DRCCMP_SHIFT, |
562 | max98090_alccmp_text); | ||
556 | 563 | ||
557 | static const char *max98090_drcexp_text[] = { "1:1", "2:1", "3:1" }; | 564 | static const char *max98090_drcexp_text[] = { "1:1", "2:1", "3:1" }; |
558 | 565 | ||
559 | static const struct soc_enum max98090_drcexp_enum = | 566 | static SOC_ENUM_SINGLE_DECL(max98090_drcexp_enum, |
560 | SOC_ENUM_SINGLE(M98090_REG_DRC_EXPANDER, M98090_DRCEXP_SHIFT, | 567 | M98090_REG_DRC_EXPANDER, |
561 | ARRAY_SIZE(max98090_drcexp_text), max98090_drcexp_text); | 568 | M98090_DRCEXP_SHIFT, |
569 | max98090_drcexp_text); | ||
562 | 570 | ||
563 | static const struct soc_enum max98090_dac_perfmode_enum = | 571 | static SOC_ENUM_SINGLE_DECL(max98090_dac_perfmode_enum, |
564 | SOC_ENUM_SINGLE(M98090_REG_DAC_CONTROL, M98090_PERFMODE_SHIFT, | 572 | M98090_REG_DAC_CONTROL, |
565 | ARRAY_SIZE(max98090_perf_pwr_text), max98090_perf_pwr_text); | 573 | M98090_PERFMODE_SHIFT, |
574 | max98090_perf_pwr_text); | ||
566 | 575 | ||
567 | static const struct soc_enum max98090_dachp_enum = | 576 | static SOC_ENUM_SINGLE_DECL(max98090_dachp_enum, |
568 | SOC_ENUM_SINGLE(M98090_REG_DAC_CONTROL, M98090_DACHP_SHIFT, | 577 | M98090_REG_DAC_CONTROL, |
569 | ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); | 578 | M98090_DACHP_SHIFT, |
579 | max98090_pwr_perf_text); | ||
570 | 580 | ||
571 | static const struct soc_enum max98090_adchp_enum = | 581 | static SOC_ENUM_SINGLE_DECL(max98090_adchp_enum, |
572 | SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_ADCHP_SHIFT, | 582 | M98090_REG_ADC_CONTROL, |
573 | ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); | 583 | M98090_ADCHP_SHIFT, |
584 | max98090_pwr_perf_text); | ||
574 | 585 | ||
575 | static const struct snd_kcontrol_new max98090_snd_controls[] = { | 586 | static const struct snd_kcontrol_new max98090_snd_controls[] = { |
576 | SOC_ENUM("MIC Bias VCM Bandgap", max98090_vcmbandgap_enum), | 587 | SOC_ENUM("MIC Bias VCM Bandgap", max98090_vcmbandgap_enum), |
@@ -841,39 +852,42 @@ static int max98090_micinput_event(struct snd_soc_dapm_widget *w, | |||
841 | 852 | ||
842 | static const char *mic1_mux_text[] = { "IN12", "IN56" }; | 853 | static const char *mic1_mux_text[] = { "IN12", "IN56" }; |
843 | 854 | ||
844 | static const struct soc_enum mic1_mux_enum = | 855 | static SOC_ENUM_SINGLE_DECL(mic1_mux_enum, |
845 | SOC_ENUM_SINGLE(M98090_REG_INPUT_MODE, M98090_EXTMIC1_SHIFT, | 856 | M98090_REG_INPUT_MODE, |
846 | ARRAY_SIZE(mic1_mux_text), mic1_mux_text); | 857 | M98090_EXTMIC1_SHIFT, |
858 | mic1_mux_text); | ||
847 | 859 | ||
848 | static const struct snd_kcontrol_new max98090_mic1_mux = | 860 | static const struct snd_kcontrol_new max98090_mic1_mux = |
849 | SOC_DAPM_ENUM("MIC1 Mux", mic1_mux_enum); | 861 | SOC_DAPM_ENUM("MIC1 Mux", mic1_mux_enum); |
850 | 862 | ||
851 | static const char *mic2_mux_text[] = { "IN34", "IN56" }; | 863 | static const char *mic2_mux_text[] = { "IN34", "IN56" }; |
852 | 864 | ||
853 | static const struct soc_enum mic2_mux_enum = | 865 | static SOC_ENUM_SINGLE_DECL(mic2_mux_enum, |
854 | SOC_ENUM_SINGLE(M98090_REG_INPUT_MODE, M98090_EXTMIC2_SHIFT, | 866 | M98090_REG_INPUT_MODE, |
855 | ARRAY_SIZE(mic2_mux_text), mic2_mux_text); | 867 | M98090_EXTMIC2_SHIFT, |
868 | mic2_mux_text); | ||
856 | 869 | ||
857 | static const struct snd_kcontrol_new max98090_mic2_mux = | 870 | static const struct snd_kcontrol_new max98090_mic2_mux = |
858 | SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum); | 871 | SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum); |
859 | 872 | ||
860 | static const char *dmic_mux_text[] = { "ADC", "DMIC" }; | 873 | static const char *dmic_mux_text[] = { "ADC", "DMIC" }; |
861 | 874 | ||
862 | static const struct soc_enum dmic_mux_enum = | 875 | static SOC_ENUM_SINGLE_VIRT_DECL(dmic_mux_enum, dmic_mux_text); |
863 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dmic_mux_text), dmic_mux_text); | ||
864 | 876 | ||
865 | static const struct snd_kcontrol_new max98090_dmic_mux = | 877 | static const struct snd_kcontrol_new max98090_dmic_mux = |
866 | SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum); | 878 | SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum); |
867 | 879 | ||
868 | static const char *max98090_micpre_text[] = { "Off", "On" }; | 880 | static const char *max98090_micpre_text[] = { "Off", "On" }; |
869 | 881 | ||
870 | static const struct soc_enum max98090_pa1en_enum = | 882 | static SOC_ENUM_SINGLE_DECL(max98090_pa1en_enum, |
871 | SOC_ENUM_SINGLE(M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT, | 883 | M98090_REG_MIC1_INPUT_LEVEL, |
872 | ARRAY_SIZE(max98090_micpre_text), max98090_micpre_text); | 884 | M98090_MIC_PA1EN_SHIFT, |
885 | max98090_micpre_text); | ||
873 | 886 | ||
874 | static const struct soc_enum max98090_pa2en_enum = | 887 | static SOC_ENUM_SINGLE_DECL(max98090_pa2en_enum, |
875 | SOC_ENUM_SINGLE(M98090_REG_MIC2_INPUT_LEVEL, M98090_MIC_PA2EN_SHIFT, | 888 | M98090_REG_MIC2_INPUT_LEVEL, |
876 | ARRAY_SIZE(max98090_micpre_text), max98090_micpre_text); | 889 | M98090_MIC_PA2EN_SHIFT, |
890 | max98090_micpre_text); | ||
877 | 891 | ||
878 | /* LINEA mixer switch */ | 892 | /* LINEA mixer switch */ |
879 | static const struct snd_kcontrol_new max98090_linea_mixer_controls[] = { | 893 | static const struct snd_kcontrol_new max98090_linea_mixer_controls[] = { |
@@ -937,13 +951,15 @@ static const struct snd_kcontrol_new max98090_right_adc_mixer_controls[] = { | |||
937 | 951 | ||
938 | static const char *lten_mux_text[] = { "Normal", "Loopthrough" }; | 952 | static const char *lten_mux_text[] = { "Normal", "Loopthrough" }; |
939 | 953 | ||
940 | static const struct soc_enum ltenl_mux_enum = | 954 | static SOC_ENUM_SINGLE_DECL(ltenl_mux_enum, |
941 | SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LTEN_SHIFT, | 955 | M98090_REG_IO_CONFIGURATION, |
942 | ARRAY_SIZE(lten_mux_text), lten_mux_text); | 956 | M98090_LTEN_SHIFT, |
957 | lten_mux_text); | ||
943 | 958 | ||
944 | static const struct soc_enum ltenr_mux_enum = | 959 | static SOC_ENUM_SINGLE_DECL(ltenr_mux_enum, |
945 | SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LTEN_SHIFT, | 960 | M98090_REG_IO_CONFIGURATION, |
946 | ARRAY_SIZE(lten_mux_text), lten_mux_text); | 961 | M98090_LTEN_SHIFT, |
962 | lten_mux_text); | ||
947 | 963 | ||
948 | static const struct snd_kcontrol_new max98090_ltenl_mux = | 964 | static const struct snd_kcontrol_new max98090_ltenl_mux = |
949 | SOC_DAPM_ENUM("LTENL Mux", ltenl_mux_enum); | 965 | SOC_DAPM_ENUM("LTENL Mux", ltenl_mux_enum); |
@@ -953,13 +969,15 @@ static const struct snd_kcontrol_new max98090_ltenr_mux = | |||
953 | 969 | ||
954 | static const char *lben_mux_text[] = { "Normal", "Loopback" }; | 970 | static const char *lben_mux_text[] = { "Normal", "Loopback" }; |
955 | 971 | ||
956 | static const struct soc_enum lbenl_mux_enum = | 972 | static SOC_ENUM_SINGLE_DECL(lbenl_mux_enum, |
957 | SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LBEN_SHIFT, | 973 | M98090_REG_IO_CONFIGURATION, |
958 | ARRAY_SIZE(lben_mux_text), lben_mux_text); | 974 | M98090_LBEN_SHIFT, |
975 | lben_mux_text); | ||
959 | 976 | ||
960 | static const struct soc_enum lbenr_mux_enum = | 977 | static SOC_ENUM_SINGLE_DECL(lbenr_mux_enum, |
961 | SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LBEN_SHIFT, | 978 | M98090_REG_IO_CONFIGURATION, |
962 | ARRAY_SIZE(lben_mux_text), lben_mux_text); | 979 | M98090_LBEN_SHIFT, |
980 | lben_mux_text); | ||
963 | 981 | ||
964 | static const struct snd_kcontrol_new max98090_lbenl_mux = | 982 | static const struct snd_kcontrol_new max98090_lbenl_mux = |
965 | SOC_DAPM_ENUM("LBENL Mux", lbenl_mux_enum); | 983 | SOC_DAPM_ENUM("LBENL Mux", lbenl_mux_enum); |
@@ -971,13 +989,15 @@ static const char *stenl_mux_text[] = { "Normal", "Sidetone Left" }; | |||
971 | 989 | ||
972 | static const char *stenr_mux_text[] = { "Normal", "Sidetone Right" }; | 990 | static const char *stenr_mux_text[] = { "Normal", "Sidetone Right" }; |
973 | 991 | ||
974 | static const struct soc_enum stenl_mux_enum = | 992 | static SOC_ENUM_SINGLE_DECL(stenl_mux_enum, |
975 | SOC_ENUM_SINGLE(M98090_REG_ADC_SIDETONE, M98090_DSTSL_SHIFT, | 993 | M98090_REG_ADC_SIDETONE, |
976 | ARRAY_SIZE(stenl_mux_text), stenl_mux_text); | 994 | M98090_DSTSL_SHIFT, |
995 | stenl_mux_text); | ||
977 | 996 | ||
978 | static const struct soc_enum stenr_mux_enum = | 997 | static SOC_ENUM_SINGLE_DECL(stenr_mux_enum, |
979 | SOC_ENUM_SINGLE(M98090_REG_ADC_SIDETONE, M98090_DSTSR_SHIFT, | 998 | M98090_REG_ADC_SIDETONE, |
980 | ARRAY_SIZE(stenr_mux_text), stenr_mux_text); | 999 | M98090_DSTSR_SHIFT, |
1000 | stenr_mux_text); | ||
981 | 1001 | ||
982 | static const struct snd_kcontrol_new max98090_stenl_mux = | 1002 | static const struct snd_kcontrol_new max98090_stenl_mux = |
983 | SOC_DAPM_ENUM("STENL Mux", stenl_mux_enum); | 1003 | SOC_DAPM_ENUM("STENL Mux", stenl_mux_enum); |
@@ -1085,9 +1105,10 @@ static const struct snd_kcontrol_new max98090_right_rcv_mixer_controls[] = { | |||
1085 | 1105 | ||
1086 | static const char *linmod_mux_text[] = { "Left Only", "Left and Right" }; | 1106 | static const char *linmod_mux_text[] = { "Left Only", "Left and Right" }; |
1087 | 1107 | ||
1088 | static const struct soc_enum linmod_mux_enum = | 1108 | static SOC_ENUM_SINGLE_DECL(linmod_mux_enum, |
1089 | SOC_ENUM_SINGLE(M98090_REG_LOUTR_MIXER, M98090_LINMOD_SHIFT, | 1109 | M98090_REG_LOUTR_MIXER, |
1090 | ARRAY_SIZE(linmod_mux_text), linmod_mux_text); | 1110 | M98090_LINMOD_SHIFT, |
1111 | linmod_mux_text); | ||
1091 | 1112 | ||
1092 | static const struct snd_kcontrol_new max98090_linmod_mux = | 1113 | static const struct snd_kcontrol_new max98090_linmod_mux = |
1093 | SOC_DAPM_ENUM("LINMOD Mux", linmod_mux_enum); | 1114 | SOC_DAPM_ENUM("LINMOD Mux", linmod_mux_enum); |
@@ -1097,16 +1118,18 @@ static const char *mixhpsel_mux_text[] = { "DAC Only", "HP Mixer" }; | |||
1097 | /* | 1118 | /* |
1098 | * This is a mux as it selects the HP output, but to DAPM it is a Mixer enable | 1119 | * This is a mux as it selects the HP output, but to DAPM it is a Mixer enable |
1099 | */ | 1120 | */ |
1100 | static const struct soc_enum mixhplsel_mux_enum = | 1121 | static SOC_ENUM_SINGLE_DECL(mixhplsel_mux_enum, |
1101 | SOC_ENUM_SINGLE(M98090_REG_HP_CONTROL, M98090_MIXHPLSEL_SHIFT, | 1122 | M98090_REG_HP_CONTROL, |
1102 | ARRAY_SIZE(mixhpsel_mux_text), mixhpsel_mux_text); | 1123 | M98090_MIXHPLSEL_SHIFT, |
1124 | mixhpsel_mux_text); | ||
1103 | 1125 | ||
1104 | static const struct snd_kcontrol_new max98090_mixhplsel_mux = | 1126 | static const struct snd_kcontrol_new max98090_mixhplsel_mux = |
1105 | SOC_DAPM_ENUM("MIXHPLSEL Mux", mixhplsel_mux_enum); | 1127 | SOC_DAPM_ENUM("MIXHPLSEL Mux", mixhplsel_mux_enum); |
1106 | 1128 | ||
1107 | static const struct soc_enum mixhprsel_mux_enum = | 1129 | static SOC_ENUM_SINGLE_DECL(mixhprsel_mux_enum, |
1108 | SOC_ENUM_SINGLE(M98090_REG_HP_CONTROL, M98090_MIXHPRSEL_SHIFT, | 1130 | M98090_REG_HP_CONTROL, |
1109 | ARRAY_SIZE(mixhpsel_mux_text), mixhpsel_mux_text); | 1131 | M98090_MIXHPRSEL_SHIFT, |
1132 | mixhpsel_mux_text); | ||
1110 | 1133 | ||
1111 | static const struct snd_kcontrol_new max98090_mixhprsel_mux = | 1134 | static const struct snd_kcontrol_new max98090_mixhprsel_mux = |
1112 | SOC_DAPM_ENUM("MIXHPRSEL Mux", mixhprsel_mux_enum); | 1135 | SOC_DAPM_ENUM("MIXHPRSEL Mux", mixhprsel_mux_enum); |
@@ -1769,16 +1792,6 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec, | |||
1769 | 1792 | ||
1770 | switch (level) { | 1793 | switch (level) { |
1771 | case SND_SOC_BIAS_ON: | 1794 | case SND_SOC_BIAS_ON: |
1772 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
1773 | ret = regcache_sync(max98090->regmap); | ||
1774 | |||
1775 | if (ret != 0) { | ||
1776 | dev_err(codec->dev, | ||
1777 | "Failed to sync cache: %d\n", ret); | ||
1778 | return ret; | ||
1779 | } | ||
1780 | } | ||
1781 | |||
1782 | if (max98090->jack_state == M98090_JACK_STATE_HEADSET) { | 1795 | if (max98090->jack_state == M98090_JACK_STATE_HEADSET) { |
1783 | /* | 1796 | /* |
1784 | * Set to normal bias level. | 1797 | * Set to normal bias level. |
@@ -1792,6 +1805,16 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec, | |||
1792 | break; | 1805 | break; |
1793 | 1806 | ||
1794 | case SND_SOC_BIAS_STANDBY: | 1807 | case SND_SOC_BIAS_STANDBY: |
1808 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
1809 | ret = regcache_sync(max98090->regmap); | ||
1810 | if (ret != 0) { | ||
1811 | dev_err(codec->dev, | ||
1812 | "Failed to sync cache: %d\n", ret); | ||
1813 | return ret; | ||
1814 | } | ||
1815 | } | ||
1816 | break; | ||
1817 | |||
1795 | case SND_SOC_BIAS_OFF: | 1818 | case SND_SOC_BIAS_OFF: |
1796 | /* Set internal pull-up to lowest power mode */ | 1819 | /* Set internal pull-up to lowest power mode */ |
1797 | snd_soc_update_bits(codec, M98090_REG_JACK_DETECT, | 1820 | snd_soc_update_bits(codec, M98090_REG_JACK_DETECT, |
@@ -2195,14 +2218,6 @@ static int max98090_probe(struct snd_soc_codec *codec) | |||
2195 | 2218 | ||
2196 | max98090->codec = codec; | 2219 | max98090->codec = codec; |
2197 | 2220 | ||
2198 | codec->control_data = max98090->regmap; | ||
2199 | |||
2200 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
2201 | if (ret != 0) { | ||
2202 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
2203 | return ret; | ||
2204 | } | ||
2205 | |||
2206 | /* Reset the codec, the DSP core, and disable all interrupts */ | 2221 | /* Reset the codec, the DSP core, and disable all interrupts */ |
2207 | max98090_reset(max98090); | 2222 | max98090_reset(max98090); |
2208 | 2223 | ||
@@ -2328,7 +2343,6 @@ static int max98090_i2c_probe(struct i2c_client *i2c, | |||
2328 | 2343 | ||
2329 | max98090->devtype = id->driver_data; | 2344 | max98090->devtype = id->driver_data; |
2330 | i2c_set_clientdata(i2c, max98090); | 2345 | i2c_set_clientdata(i2c, max98090); |
2331 | max98090->control_data = i2c; | ||
2332 | max98090->pdata = i2c->dev.platform_data; | 2346 | max98090->pdata = i2c->dev.platform_data; |
2333 | max98090->irq = i2c->irq; | 2347 | max98090->irq = i2c->irq; |
2334 | 2348 | ||
diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h index 7e103f249053..1a4e2334a7b2 100644 --- a/sound/soc/codecs/max98090.h +++ b/sound/soc/codecs/max98090.h | |||
@@ -1523,7 +1523,6 @@ struct max98090_priv { | |||
1523 | struct regmap *regmap; | 1523 | struct regmap *regmap; |
1524 | struct snd_soc_codec *codec; | 1524 | struct snd_soc_codec *codec; |
1525 | enum max98090_type devtype; | 1525 | enum max98090_type devtype; |
1526 | void *control_data; | ||
1527 | struct max98090_pdata *pdata; | 1526 | struct max98090_pdata *pdata; |
1528 | unsigned int sysclk; | 1527 | unsigned int sysclk; |
1529 | unsigned int bclk; | 1528 | unsigned int bclk; |
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 3ba1170ebb53..03f0536e6f61 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c | |||
@@ -560,25 +560,27 @@ static void m98095_biquad_band(struct snd_soc_codec *codec, unsigned int dai, | |||
560 | } | 560 | } |
561 | 561 | ||
562 | static const char * const max98095_fltr_mode[] = { "Voice", "Music" }; | 562 | static const char * const max98095_fltr_mode[] = { "Voice", "Music" }; |
563 | static const struct soc_enum max98095_dai1_filter_mode_enum[] = { | 563 | static SOC_ENUM_SINGLE_DECL(max98095_dai1_filter_mode_enum, |
564 | SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 7, 2, max98095_fltr_mode), | 564 | M98095_02E_DAI1_FILTERS, 7, |
565 | }; | 565 | max98095_fltr_mode); |
566 | static const struct soc_enum max98095_dai2_filter_mode_enum[] = { | 566 | static SOC_ENUM_SINGLE_DECL(max98095_dai2_filter_mode_enum, |
567 | SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 7, 2, max98095_fltr_mode), | 567 | M98095_038_DAI2_FILTERS, 7, |
568 | }; | 568 | max98095_fltr_mode); |
569 | 569 | ||
570 | static const char * const max98095_extmic_text[] = { "None", "MIC1", "MIC2" }; | 570 | static const char * const max98095_extmic_text[] = { "None", "MIC1", "MIC2" }; |
571 | 571 | ||
572 | static const struct soc_enum max98095_extmic_enum = | 572 | static SOC_ENUM_SINGLE_DECL(max98095_extmic_enum, |
573 | SOC_ENUM_SINGLE(M98095_087_CFG_MIC, 0, 3, max98095_extmic_text); | 573 | M98095_087_CFG_MIC, 0, |
574 | max98095_extmic_text); | ||
574 | 575 | ||
575 | static const struct snd_kcontrol_new max98095_extmic_mux = | 576 | static const struct snd_kcontrol_new max98095_extmic_mux = |
576 | SOC_DAPM_ENUM("External MIC Mux", max98095_extmic_enum); | 577 | SOC_DAPM_ENUM("External MIC Mux", max98095_extmic_enum); |
577 | 578 | ||
578 | static const char * const max98095_linein_text[] = { "INA", "INB" }; | 579 | static const char * const max98095_linein_text[] = { "INA", "INB" }; |
579 | 580 | ||
580 | static const struct soc_enum max98095_linein_enum = | 581 | static SOC_ENUM_SINGLE_DECL(max98095_linein_enum, |
581 | SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 6, 2, max98095_linein_text); | 582 | M98095_086_CFG_LINE, 6, |
583 | max98095_linein_text); | ||
582 | 584 | ||
583 | static const struct snd_kcontrol_new max98095_linein_mux = | 585 | static const struct snd_kcontrol_new max98095_linein_mux = |
584 | SOC_DAPM_ENUM("Linein Input Mux", max98095_linein_enum); | 586 | SOC_DAPM_ENUM("Linein Input Mux", max98095_linein_enum); |
@@ -586,24 +588,26 @@ static const struct snd_kcontrol_new max98095_linein_mux = | |||
586 | static const char * const max98095_line_mode_text[] = { | 588 | static const char * const max98095_line_mode_text[] = { |
587 | "Stereo", "Differential"}; | 589 | "Stereo", "Differential"}; |
588 | 590 | ||
589 | static const struct soc_enum max98095_linein_mode_enum = | 591 | static SOC_ENUM_SINGLE_DECL(max98095_linein_mode_enum, |
590 | SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 7, 2, max98095_line_mode_text); | 592 | M98095_086_CFG_LINE, 7, |
593 | max98095_line_mode_text); | ||
591 | 594 | ||
592 | static const struct soc_enum max98095_lineout_mode_enum = | 595 | static SOC_ENUM_SINGLE_DECL(max98095_lineout_mode_enum, |
593 | SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 4, 2, max98095_line_mode_text); | 596 | M98095_086_CFG_LINE, 4, |
597 | max98095_line_mode_text); | ||
594 | 598 | ||
595 | static const char * const max98095_dai_fltr[] = { | 599 | static const char * const max98095_dai_fltr[] = { |
596 | "Off", "Elliptical-HPF-16k", "Butterworth-HPF-16k", | 600 | "Off", "Elliptical-HPF-16k", "Butterworth-HPF-16k", |
597 | "Elliptical-HPF-8k", "Butterworth-HPF-8k", "Butterworth-HPF-Fs/240"}; | 601 | "Elliptical-HPF-8k", "Butterworth-HPF-8k", "Butterworth-HPF-Fs/240"}; |
598 | static const struct soc_enum max98095_dai1_dac_filter_enum[] = { | 602 | static SOC_ENUM_SINGLE_DECL(max98095_dai1_dac_filter_enum, |
599 | SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 0, 6, max98095_dai_fltr), | 603 | M98095_02E_DAI1_FILTERS, 0, |
600 | }; | 604 | max98095_dai_fltr); |
601 | static const struct soc_enum max98095_dai2_dac_filter_enum[] = { | 605 | static SOC_ENUM_SINGLE_DECL(max98095_dai2_dac_filter_enum, |
602 | SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 0, 6, max98095_dai_fltr), | 606 | M98095_038_DAI2_FILTERS, 0, |
603 | }; | 607 | max98095_dai_fltr); |
604 | static const struct soc_enum max98095_dai3_dac_filter_enum[] = { | 608 | static SOC_ENUM_SINGLE_DECL(max98095_dai3_dac_filter_enum, |
605 | SOC_ENUM_SINGLE(M98095_042_DAI3_FILTERS, 0, 6, max98095_dai_fltr), | 609 | M98095_042_DAI3_FILTERS, 0, |
606 | }; | 610 | max98095_dai_fltr); |
607 | 611 | ||
608 | static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol, | 612 | static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol, |
609 | struct snd_ctl_elem_value *ucontrol) | 613 | struct snd_ctl_elem_value *ucontrol) |
@@ -1861,7 +1865,7 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec) | |||
1861 | 1865 | ||
1862 | /* Now point the soc_enum to .texts array items */ | 1866 | /* Now point the soc_enum to .texts array items */ |
1863 | max98095->eq_enum.texts = max98095->eq_texts; | 1867 | max98095->eq_enum.texts = max98095->eq_texts; |
1864 | max98095->eq_enum.max = max98095->eq_textcnt; | 1868 | max98095->eq_enum.items = max98095->eq_textcnt; |
1865 | 1869 | ||
1866 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); | 1870 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); |
1867 | if (ret != 0) | 1871 | if (ret != 0) |
@@ -2016,7 +2020,7 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec) | |||
2016 | 2020 | ||
2017 | /* Now point the soc_enum to .texts array items */ | 2021 | /* Now point the soc_enum to .texts array items */ |
2018 | max98095->bq_enum.texts = max98095->bq_texts; | 2022 | max98095->bq_enum.texts = max98095->bq_texts; |
2019 | max98095->bq_enum.max = max98095->bq_textcnt; | 2023 | max98095->bq_enum.items = max98095->bq_textcnt; |
2020 | 2024 | ||
2021 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); | 2025 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); |
2022 | if (ret != 0) | 2026 | if (ret != 0) |
@@ -2234,12 +2238,6 @@ static int max98095_probe(struct snd_soc_codec *codec) | |||
2234 | struct i2c_client *client; | 2238 | struct i2c_client *client; |
2235 | int ret = 0; | 2239 | int ret = 0; |
2236 | 2240 | ||
2237 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
2238 | if (ret != 0) { | ||
2239 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
2240 | return ret; | ||
2241 | } | ||
2242 | |||
2243 | /* reset the codec, the DSP core, and disable all interrupts */ | 2241 | /* reset the codec, the DSP core, and disable all interrupts */ |
2244 | max98095_reset(codec); | 2242 | max98095_reset(codec); |
2245 | 2243 | ||
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index 82757ebf0301..4fdf5aaa236f 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c | |||
@@ -312,14 +312,6 @@ static int max9850_resume(struct snd_soc_codec *codec) | |||
312 | 312 | ||
313 | static int max9850_probe(struct snd_soc_codec *codec) | 313 | static int max9850_probe(struct snd_soc_codec *codec) |
314 | { | 314 | { |
315 | int ret; | ||
316 | |||
317 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
318 | if (ret < 0) { | ||
319 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
320 | return ret; | ||
321 | } | ||
322 | |||
323 | /* enable zero-detect */ | 315 | /* enable zero-detect */ |
324 | snd_soc_update_bits(codec, MAX9850_GENERAL_PURPOSE, 1, 1); | 316 | snd_soc_update_bits(codec, MAX9850_GENERAL_PURPOSE, 1, 1); |
325 | /* enable slew-rate control */ | 317 | /* enable slew-rate control */ |
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 582c2bbd42cb..2c59b1fb69dc 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c | |||
@@ -106,8 +106,7 @@ static int mc13783_pcm_hw_params_dac(struct snd_pcm_substream *substream, | |||
106 | struct snd_pcm_hw_params *params, | 106 | struct snd_pcm_hw_params *params, |
107 | struct snd_soc_dai *dai) | 107 | struct snd_soc_dai *dai) |
108 | { | 108 | { |
109 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 109 | struct snd_soc_codec *codec = dai->codec; |
110 | struct snd_soc_codec *codec = rtd->codec; | ||
111 | unsigned int rate = params_rate(params); | 110 | unsigned int rate = params_rate(params); |
112 | int i; | 111 | int i; |
113 | 112 | ||
@@ -126,8 +125,7 @@ static int mc13783_pcm_hw_params_codec(struct snd_pcm_substream *substream, | |||
126 | struct snd_pcm_hw_params *params, | 125 | struct snd_pcm_hw_params *params, |
127 | struct snd_soc_dai *dai) | 126 | struct snd_soc_dai *dai) |
128 | { | 127 | { |
129 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 128 | struct snd_soc_codec *codec = dai->codec; |
130 | struct snd_soc_codec *codec = rtd->codec; | ||
131 | unsigned int rate = params_rate(params); | 129 | unsigned int rate = params_rate(params); |
132 | unsigned int val; | 130 | unsigned int val; |
133 | 131 | ||
@@ -408,8 +406,7 @@ static const char * const adcl_enum_text[] = { | |||
408 | "MC1L", "RXINL", | 406 | "MC1L", "RXINL", |
409 | }; | 407 | }; |
410 | 408 | ||
411 | static const struct soc_enum adcl_enum = | 409 | static SOC_ENUM_SINGLE_VIRT_DECL(adcl_enum, adcl_enum_text); |
412 | SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(adcl_enum_text), adcl_enum_text); | ||
413 | 410 | ||
414 | static const struct snd_kcontrol_new left_input_mux = | 411 | static const struct snd_kcontrol_new left_input_mux = |
415 | SOC_DAPM_ENUM_VIRT("Route", adcl_enum); | 412 | SOC_DAPM_ENUM_VIRT("Route", adcl_enum); |
@@ -418,8 +415,7 @@ static const char * const adcr_enum_text[] = { | |||
418 | "MC1R", "MC2", "RXINR", "TXIN", | 415 | "MC1R", "MC2", "RXINR", "TXIN", |
419 | }; | 416 | }; |
420 | 417 | ||
421 | static const struct soc_enum adcr_enum = | 418 | static SOC_ENUM_SINGLE_VIRT_DECL(adcr_enum, adcr_enum_text); |
422 | SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(adcr_enum_text), adcr_enum_text); | ||
423 | 419 | ||
424 | static const struct snd_kcontrol_new right_input_mux = | 420 | static const struct snd_kcontrol_new right_input_mux = |
425 | SOC_DAPM_ENUM_VIRT("Route", adcr_enum); | 421 | SOC_DAPM_ENUM_VIRT("Route", adcr_enum); |
@@ -430,8 +426,8 @@ static const struct snd_kcontrol_new samp_ctl = | |||
430 | static const char * const speaker_amp_source_text[] = { | 426 | static const char * const speaker_amp_source_text[] = { |
431 | "CODEC", "Right" | 427 | "CODEC", "Right" |
432 | }; | 428 | }; |
433 | static const SOC_ENUM_SINGLE_DECL(speaker_amp_source, MC13783_AUDIO_RX0, 4, | 429 | static SOC_ENUM_SINGLE_DECL(speaker_amp_source, MC13783_AUDIO_RX0, 4, |
434 | speaker_amp_source_text); | 430 | speaker_amp_source_text); |
435 | static const struct snd_kcontrol_new speaker_amp_source_mux = | 431 | static const struct snd_kcontrol_new speaker_amp_source_mux = |
436 | SOC_DAPM_ENUM("Speaker Amp Source MUX", speaker_amp_source); | 432 | SOC_DAPM_ENUM("Speaker Amp Source MUX", speaker_amp_source); |
437 | 433 | ||
@@ -439,8 +435,8 @@ static const char * const headset_amp_source_text[] = { | |||
439 | "CODEC", "Mixer" | 435 | "CODEC", "Mixer" |
440 | }; | 436 | }; |
441 | 437 | ||
442 | static const SOC_ENUM_SINGLE_DECL(headset_amp_source, MC13783_AUDIO_RX0, 11, | 438 | static SOC_ENUM_SINGLE_DECL(headset_amp_source, MC13783_AUDIO_RX0, 11, |
443 | headset_amp_source_text); | 439 | headset_amp_source_text); |
444 | static const struct snd_kcontrol_new headset_amp_source_mux = | 440 | static const struct snd_kcontrol_new headset_amp_source_mux = |
445 | SOC_DAPM_ENUM("Headset Amp Source MUX", headset_amp_source); | 441 | SOC_DAPM_ENUM("Headset Amp Source MUX", headset_amp_source); |
446 | 442 | ||
@@ -580,9 +576,9 @@ static struct snd_soc_dapm_route mc13783_routes[] = { | |||
580 | static const char * const mc13783_3d_mixer[] = {"Stereo", "Phase Mix", | 576 | static const char * const mc13783_3d_mixer[] = {"Stereo", "Phase Mix", |
581 | "Mono", "Mono Mix"}; | 577 | "Mono", "Mono Mix"}; |
582 | 578 | ||
583 | static const struct soc_enum mc13783_enum_3d_mixer = | 579 | static SOC_ENUM_SINGLE_DECL(mc13783_enum_3d_mixer, |
584 | SOC_ENUM_SINGLE(MC13783_AUDIO_RX1, 16, ARRAY_SIZE(mc13783_3d_mixer), | 580 | MC13783_AUDIO_RX1, 16, |
585 | mc13783_3d_mixer); | 581 | mc13783_3d_mixer); |
586 | 582 | ||
587 | static struct snd_kcontrol_new mc13783_control_list[] = { | 583 | static struct snd_kcontrol_new mc13783_control_list[] = { |
588 | SOC_SINGLE("Loudspeaker enable", MC13783_AUDIO_RX0, 5, 1, 0), | 584 | SOC_SINGLE("Loudspeaker enable", MC13783_AUDIO_RX0, 5, 1, 0), |
@@ -614,8 +610,8 @@ static int mc13783_probe(struct snd_soc_codec *codec) | |||
614 | struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); | 610 | struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); |
615 | int ret; | 611 | int ret; |
616 | 612 | ||
617 | codec->control_data = dev_get_regmap(codec->dev->parent, NULL); | 613 | ret = snd_soc_codec_set_cache_io(codec, |
618 | ret = snd_soc_codec_set_cache_io(codec, 8, 24, SND_SOC_REGMAP); | 614 | dev_get_regmap(codec->dev->parent, NULL)); |
619 | if (ret != 0) { | 615 | if (ret != 0) { |
620 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 616 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
621 | return ret; | 617 | return ret; |
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index 185fa3bc3052..e661e8420e3d 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c | |||
@@ -73,11 +73,11 @@ static const DECLARE_TLV_DB_SCALE(ngth, -7650, 150, 0); | |||
73 | static const char * const ml26124_companding[] = {"16bit PCM", "u-law", | 73 | static const char * const ml26124_companding[] = {"16bit PCM", "u-law", |
74 | "A-law"}; | 74 | "A-law"}; |
75 | 75 | ||
76 | static const struct soc_enum ml26124_adc_companding_enum | 76 | static SOC_ENUM_SINGLE_DECL(ml26124_adc_companding_enum, |
77 | = SOC_ENUM_SINGLE(ML26124_SAI_TRANS_CTL, 6, 3, ml26124_companding); | 77 | ML26124_SAI_TRANS_CTL, 6, ml26124_companding); |
78 | 78 | ||
79 | static const struct soc_enum ml26124_dac_companding_enum | 79 | static SOC_ENUM_SINGLE_DECL(ml26124_dac_companding_enum, |
80 | = SOC_ENUM_SINGLE(ML26124_SAI_RCV_CTL, 6, 3, ml26124_companding); | 80 | ML26124_SAI_RCV_CTL, 6, ml26124_companding); |
81 | 81 | ||
82 | static const struct snd_kcontrol_new ml26124_snd_controls[] = { | 82 | static const struct snd_kcontrol_new ml26124_snd_controls[] = { |
83 | SOC_SINGLE_TLV("Capture Digital Volume", ML26124_RECORD_DIG_VOL, 0, | 83 | SOC_SINGLE_TLV("Capture Digital Volume", ML26124_RECORD_DIG_VOL, 0, |
@@ -136,8 +136,8 @@ static const struct snd_kcontrol_new ml26124_output_mixer_controls[] = { | |||
136 | static const char * const ml26124_input_select[] = {"Analog MIC SingleEnded in", | 136 | static const char * const ml26124_input_select[] = {"Analog MIC SingleEnded in", |
137 | "Digital MIC in", "Analog MIC Differential in"}; | 137 | "Digital MIC in", "Analog MIC Differential in"}; |
138 | 138 | ||
139 | static const struct soc_enum ml26124_insel_enum = | 139 | static SOC_ENUM_SINGLE_DECL(ml26124_insel_enum, |
140 | SOC_ENUM_SINGLE(ML26124_MIC_IF_CTL, 0, 3, ml26124_input_select); | 140 | ML26124_MIC_IF_CTL, 0, ml26124_input_select); |
141 | 141 | ||
142 | static const struct snd_kcontrol_new ml26124_input_mux_controls = | 142 | static const struct snd_kcontrol_new ml26124_input_mux_controls = |
143 | SOC_DAPM_ENUM("Input Select", ml26124_insel_enum); | 143 | SOC_DAPM_ENUM("Input Select", ml26124_insel_enum); |
@@ -586,16 +586,6 @@ static int ml26124_resume(struct snd_soc_codec *codec) | |||
586 | 586 | ||
587 | static int ml26124_probe(struct snd_soc_codec *codec) | 587 | static int ml26124_probe(struct snd_soc_codec *codec) |
588 | { | 588 | { |
589 | int ret; | ||
590 | struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
591 | codec->control_data = priv->regmap; | ||
592 | |||
593 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
594 | if (ret < 0) { | ||
595 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | /* Software Reset */ | 589 | /* Software Reset */ |
600 | snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 1); | 590 | snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 1); |
601 | snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 0); | 591 | snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 0); |
diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index 73f9c3630e2c..e427544183d7 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c | |||
@@ -172,16 +172,21 @@ static int pcm1681_hw_params(struct snd_pcm_substream *substream, | |||
172 | struct snd_soc_codec *codec = dai->codec; | 172 | struct snd_soc_codec *codec = dai->codec; |
173 | struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); | 173 | struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); |
174 | int val = 0, ret; | 174 | int val = 0, ret; |
175 | int pcm_format = params_format(params); | ||
176 | 175 | ||
177 | priv->rate = params_rate(params); | 176 | priv->rate = params_rate(params); |
178 | 177 | ||
179 | switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { | 178 | switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { |
180 | case SND_SOC_DAIFMT_RIGHT_J: | 179 | case SND_SOC_DAIFMT_RIGHT_J: |
181 | if (pcm_format == SNDRV_PCM_FORMAT_S24_LE) | 180 | switch (params_width(params)) { |
182 | val = 0x00; | 181 | case 24: |
183 | else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE) | 182 | val = 0; |
184 | val = 0x03; | 183 | break; |
184 | case 16: | ||
185 | val = 3; | ||
186 | break; | ||
187 | default: | ||
188 | return -EINVAL; | ||
189 | } | ||
185 | break; | 190 | break; |
186 | case SND_SOC_DAIFMT_I2S: | 191 | case SND_SOC_DAIFMT_I2S: |
187 | val = 0x04; | 192 | val = 0x04; |
diff --git a/sound/soc/codecs/pcm1792a.c b/sound/soc/codecs/pcm1792a.c index 7146653a8e16..3a80ba4452df 100644 --- a/sound/soc/codecs/pcm1792a.c +++ b/sound/soc/codecs/pcm1792a.c | |||
@@ -107,24 +107,35 @@ static int pcm1792a_hw_params(struct snd_pcm_substream *substream, | |||
107 | struct snd_soc_codec *codec = dai->codec; | 107 | struct snd_soc_codec *codec = dai->codec; |
108 | struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec); | 108 | struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec); |
109 | int val = 0, ret; | 109 | int val = 0, ret; |
110 | int pcm_format = params_format(params); | ||
111 | 110 | ||
112 | priv->rate = params_rate(params); | 111 | priv->rate = params_rate(params); |
113 | 112 | ||
114 | switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { | 113 | switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { |
115 | case SND_SOC_DAIFMT_RIGHT_J: | 114 | case SND_SOC_DAIFMT_RIGHT_J: |
116 | if (pcm_format == SNDRV_PCM_FORMAT_S24_LE || | 115 | switch (params_width(params)) { |
117 | pcm_format == SNDRV_PCM_FORMAT_S32_LE) | 116 | case 24: |
118 | val = 0x02; | 117 | case 32: |
119 | else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE) | 118 | val = 2; |
120 | val = 0x00; | 119 | break; |
120 | case 16: | ||
121 | val = 0; | ||
122 | break; | ||
123 | default: | ||
124 | return -EINVAL; | ||
125 | } | ||
121 | break; | 126 | break; |
122 | case SND_SOC_DAIFMT_I2S: | 127 | case SND_SOC_DAIFMT_I2S: |
123 | if (pcm_format == SNDRV_PCM_FORMAT_S24_LE || | 128 | switch (params_width(params)) { |
124 | pcm_format == SNDRV_PCM_FORMAT_S32_LE) | 129 | case 24: |
125 | val = 0x05; | 130 | case 32: |
126 | else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE) | 131 | val = 5; |
127 | val = 0x04; | 132 | break; |
133 | case 16: | ||
134 | val = 4; | ||
135 | break; | ||
136 | default: | ||
137 | return -EINVAL; | ||
138 | } | ||
128 | break; | 139 | break; |
129 | default: | 140 | default: |
130 | dev_err(codec->dev, "Invalid DAI format\n"); | 141 | dev_err(codec->dev, "Invalid DAI format\n"); |
diff --git a/sound/soc/codecs/pcm512x-i2c.c b/sound/soc/codecs/pcm512x-i2c.c new file mode 100644 index 000000000000..4d62230bd378 --- /dev/null +++ b/sound/soc/codecs/pcm512x-i2c.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * Driver for the PCM512x CODECs | ||
3 | * | ||
4 | * Author: Mark Brown <broonie@linaro.org> | ||
5 | * Copyright 2014 Linaro Ltd | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/init.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/i2c.h> | ||
20 | |||
21 | #include "pcm512x.h" | ||
22 | |||
23 | static int pcm512x_i2c_probe(struct i2c_client *i2c, | ||
24 | const struct i2c_device_id *id) | ||
25 | { | ||
26 | struct regmap *regmap; | ||
27 | |||
28 | regmap = devm_regmap_init_i2c(i2c, &pcm512x_regmap); | ||
29 | if (IS_ERR(regmap)) | ||
30 | return PTR_ERR(regmap); | ||
31 | |||
32 | return pcm512x_probe(&i2c->dev, regmap); | ||
33 | } | ||
34 | |||
35 | static int pcm512x_i2c_remove(struct i2c_client *i2c) | ||
36 | { | ||
37 | pcm512x_remove(&i2c->dev); | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static const struct i2c_device_id pcm512x_i2c_id[] = { | ||
42 | { "pcm5121", }, | ||
43 | { "pcm5122", }, | ||
44 | { } | ||
45 | }; | ||
46 | MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id); | ||
47 | |||
48 | static const struct of_device_id pcm512x_of_match[] = { | ||
49 | { .compatible = "ti,pcm5121", }, | ||
50 | { .compatible = "ti,pcm5122", }, | ||
51 | { } | ||
52 | }; | ||
53 | MODULE_DEVICE_TABLE(of, pcm512x_of_match); | ||
54 | |||
55 | static struct i2c_driver pcm512x_i2c_driver = { | ||
56 | .probe = pcm512x_i2c_probe, | ||
57 | .remove = pcm512x_i2c_remove, | ||
58 | .id_table = pcm512x_i2c_id, | ||
59 | .driver = { | ||
60 | .name = "pcm512x", | ||
61 | .owner = THIS_MODULE, | ||
62 | .of_match_table = pcm512x_of_match, | ||
63 | .pm = &pcm512x_pm_ops, | ||
64 | }, | ||
65 | }; | ||
66 | |||
67 | module_i2c_driver(pcm512x_i2c_driver); | ||
68 | |||
69 | MODULE_DESCRIPTION("ASoC PCM512x codec driver - I2C"); | ||
70 | MODULE_AUTHOR("Mark Brown <broonie@linaro.org>"); | ||
71 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/pcm512x-spi.c b/sound/soc/codecs/pcm512x-spi.c new file mode 100644 index 000000000000..f297058c0038 --- /dev/null +++ b/sound/soc/codecs/pcm512x-spi.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Driver for the PCM512x CODECs | ||
3 | * | ||
4 | * Author: Mark Brown <broonie@linaro.org> | ||
5 | * Copyright 2014 Linaro Ltd | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/init.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/spi/spi.h> | ||
20 | |||
21 | #include "pcm512x.h" | ||
22 | |||
23 | static int pcm512x_spi_probe(struct spi_device *spi) | ||
24 | { | ||
25 | struct regmap *regmap; | ||
26 | int ret; | ||
27 | |||
28 | regmap = devm_regmap_init_spi(spi, &pcm512x_regmap); | ||
29 | if (IS_ERR(regmap)) { | ||
30 | ret = PTR_ERR(regmap); | ||
31 | return ret; | ||
32 | } | ||
33 | |||
34 | return pcm512x_probe(&spi->dev, regmap); | ||
35 | } | ||
36 | |||
37 | static int pcm512x_spi_remove(struct spi_device *spi) | ||
38 | { | ||
39 | pcm512x_remove(&spi->dev); | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static const struct spi_device_id pcm512x_spi_id[] = { | ||
44 | { "pcm5121", }, | ||
45 | { "pcm5122", }, | ||
46 | { }, | ||
47 | }; | ||
48 | MODULE_DEVICE_TABLE(spi, pcm512x_spi_id); | ||
49 | |||
50 | static const struct of_device_id pcm512x_of_match[] = { | ||
51 | { .compatible = "ti,pcm5121", }, | ||
52 | { .compatible = "ti,pcm5122", }, | ||
53 | { } | ||
54 | }; | ||
55 | MODULE_DEVICE_TABLE(of, pcm512x_of_match); | ||
56 | |||
57 | static struct spi_driver pcm512x_spi_driver = { | ||
58 | .probe = pcm512x_spi_probe, | ||
59 | .remove = pcm512x_spi_remove, | ||
60 | .id_table = pcm512x_spi_id, | ||
61 | .driver = { | ||
62 | .name = "pcm512x", | ||
63 | .owner = THIS_MODULE, | ||
64 | .of_match_table = pcm512x_of_match, | ||
65 | .pm = &pcm512x_pm_ops, | ||
66 | }, | ||
67 | }; | ||
68 | |||
69 | module_spi_driver(pcm512x_spi_driver); | ||
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c new file mode 100644 index 000000000000..4b4c0c7bb918 --- /dev/null +++ b/sound/soc/codecs/pcm512x.c | |||
@@ -0,0 +1,589 @@ | |||
1 | /* | ||
2 | * Driver for the PCM512x CODECs | ||
3 | * | ||
4 | * Author: Mark Brown <broonie@linaro.org> | ||
5 | * Copyright 2014 Linaro Ltd | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/clk.h> | ||
21 | #include <linux/pm_runtime.h> | ||
22 | #include <linux/regmap.h> | ||
23 | #include <linux/regulator/consumer.h> | ||
24 | #include <sound/soc.h> | ||
25 | #include <sound/soc-dapm.h> | ||
26 | #include <sound/tlv.h> | ||
27 | |||
28 | #include "pcm512x.h" | ||
29 | |||
30 | #define PCM512x_NUM_SUPPLIES 3 | ||
31 | static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = { | ||
32 | "AVDD", | ||
33 | "DVDD", | ||
34 | "CPVDD", | ||
35 | }; | ||
36 | |||
37 | struct pcm512x_priv { | ||
38 | struct regmap *regmap; | ||
39 | struct clk *sclk; | ||
40 | struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES]; | ||
41 | struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES]; | ||
42 | }; | ||
43 | |||
44 | /* | ||
45 | * We can't use the same notifier block for more than one supply and | ||
46 | * there's no way I can see to get from a callback to the caller | ||
47 | * except container_of(). | ||
48 | */ | ||
49 | #define PCM512x_REGULATOR_EVENT(n) \ | ||
50 | static int pcm512x_regulator_event_##n(struct notifier_block *nb, \ | ||
51 | unsigned long event, void *data) \ | ||
52 | { \ | ||
53 | struct pcm512x_priv *pcm512x = container_of(nb, struct pcm512x_priv, \ | ||
54 | supply_nb[n]); \ | ||
55 | if (event & REGULATOR_EVENT_DISABLE) { \ | ||
56 | regcache_mark_dirty(pcm512x->regmap); \ | ||
57 | regcache_cache_only(pcm512x->regmap, true); \ | ||
58 | } \ | ||
59 | return 0; \ | ||
60 | } | ||
61 | |||
62 | PCM512x_REGULATOR_EVENT(0) | ||
63 | PCM512x_REGULATOR_EVENT(1) | ||
64 | PCM512x_REGULATOR_EVENT(2) | ||
65 | |||
66 | static const struct reg_default pcm512x_reg_defaults[] = { | ||
67 | { PCM512x_RESET, 0x00 }, | ||
68 | { PCM512x_POWER, 0x00 }, | ||
69 | { PCM512x_MUTE, 0x00 }, | ||
70 | { PCM512x_DSP, 0x00 }, | ||
71 | { PCM512x_PLL_REF, 0x00 }, | ||
72 | { PCM512x_DAC_ROUTING, 0x11 }, | ||
73 | { PCM512x_DSP_PROGRAM, 0x01 }, | ||
74 | { PCM512x_CLKDET, 0x00 }, | ||
75 | { PCM512x_AUTO_MUTE, 0x00 }, | ||
76 | { PCM512x_ERROR_DETECT, 0x00 }, | ||
77 | { PCM512x_DIGITAL_VOLUME_1, 0x00 }, | ||
78 | { PCM512x_DIGITAL_VOLUME_2, 0x30 }, | ||
79 | { PCM512x_DIGITAL_VOLUME_3, 0x30 }, | ||
80 | { PCM512x_DIGITAL_MUTE_1, 0x22 }, | ||
81 | { PCM512x_DIGITAL_MUTE_2, 0x00 }, | ||
82 | { PCM512x_DIGITAL_MUTE_3, 0x07 }, | ||
83 | { PCM512x_OUTPUT_AMPLITUDE, 0x00 }, | ||
84 | { PCM512x_ANALOG_GAIN_CTRL, 0x00 }, | ||
85 | { PCM512x_UNDERVOLTAGE_PROT, 0x00 }, | ||
86 | { PCM512x_ANALOG_MUTE_CTRL, 0x00 }, | ||
87 | { PCM512x_ANALOG_GAIN_BOOST, 0x00 }, | ||
88 | { PCM512x_VCOM_CTRL_1, 0x00 }, | ||
89 | { PCM512x_VCOM_CTRL_2, 0x01 }, | ||
90 | }; | ||
91 | |||
92 | static bool pcm512x_readable(struct device *dev, unsigned int reg) | ||
93 | { | ||
94 | switch (reg) { | ||
95 | case PCM512x_RESET: | ||
96 | case PCM512x_POWER: | ||
97 | case PCM512x_MUTE: | ||
98 | case PCM512x_PLL_EN: | ||
99 | case PCM512x_SPI_MISO_FUNCTION: | ||
100 | case PCM512x_DSP: | ||
101 | case PCM512x_GPIO_EN: | ||
102 | case PCM512x_BCLK_LRCLK_CFG: | ||
103 | case PCM512x_DSP_GPIO_INPUT: | ||
104 | case PCM512x_MASTER_MODE: | ||
105 | case PCM512x_PLL_REF: | ||
106 | case PCM512x_PLL_COEFF_0: | ||
107 | case PCM512x_PLL_COEFF_1: | ||
108 | case PCM512x_PLL_COEFF_2: | ||
109 | case PCM512x_PLL_COEFF_3: | ||
110 | case PCM512x_PLL_COEFF_4: | ||
111 | case PCM512x_DSP_CLKDIV: | ||
112 | case PCM512x_DAC_CLKDIV: | ||
113 | case PCM512x_NCP_CLKDIV: | ||
114 | case PCM512x_OSR_CLKDIV: | ||
115 | case PCM512x_MASTER_CLKDIV_1: | ||
116 | case PCM512x_MASTER_CLKDIV_2: | ||
117 | case PCM512x_FS_SPEED_MODE: | ||
118 | case PCM512x_IDAC_1: | ||
119 | case PCM512x_IDAC_2: | ||
120 | case PCM512x_ERROR_DETECT: | ||
121 | case PCM512x_I2S_1: | ||
122 | case PCM512x_I2S_2: | ||
123 | case PCM512x_DAC_ROUTING: | ||
124 | case PCM512x_DSP_PROGRAM: | ||
125 | case PCM512x_CLKDET: | ||
126 | case PCM512x_AUTO_MUTE: | ||
127 | case PCM512x_DIGITAL_VOLUME_1: | ||
128 | case PCM512x_DIGITAL_VOLUME_2: | ||
129 | case PCM512x_DIGITAL_VOLUME_3: | ||
130 | case PCM512x_DIGITAL_MUTE_1: | ||
131 | case PCM512x_DIGITAL_MUTE_2: | ||
132 | case PCM512x_DIGITAL_MUTE_3: | ||
133 | case PCM512x_GPIO_OUTPUT_1: | ||
134 | case PCM512x_GPIO_OUTPUT_2: | ||
135 | case PCM512x_GPIO_OUTPUT_3: | ||
136 | case PCM512x_GPIO_OUTPUT_4: | ||
137 | case PCM512x_GPIO_OUTPUT_5: | ||
138 | case PCM512x_GPIO_OUTPUT_6: | ||
139 | case PCM512x_GPIO_CONTROL_1: | ||
140 | case PCM512x_GPIO_CONTROL_2: | ||
141 | case PCM512x_OVERFLOW: | ||
142 | case PCM512x_RATE_DET_1: | ||
143 | case PCM512x_RATE_DET_2: | ||
144 | case PCM512x_RATE_DET_3: | ||
145 | case PCM512x_RATE_DET_4: | ||
146 | case PCM512x_ANALOG_MUTE_DET: | ||
147 | case PCM512x_GPIN: | ||
148 | case PCM512x_DIGITAL_MUTE_DET: | ||
149 | case PCM512x_OUTPUT_AMPLITUDE: | ||
150 | case PCM512x_ANALOG_GAIN_CTRL: | ||
151 | case PCM512x_UNDERVOLTAGE_PROT: | ||
152 | case PCM512x_ANALOG_MUTE_CTRL: | ||
153 | case PCM512x_ANALOG_GAIN_BOOST: | ||
154 | case PCM512x_VCOM_CTRL_1: | ||
155 | case PCM512x_VCOM_CTRL_2: | ||
156 | case PCM512x_CRAM_CTRL: | ||
157 | return true; | ||
158 | default: | ||
159 | /* There are 256 raw register addresses */ | ||
160 | return reg < 0xff; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | static bool pcm512x_volatile(struct device *dev, unsigned int reg) | ||
165 | { | ||
166 | switch (reg) { | ||
167 | case PCM512x_PLL_EN: | ||
168 | case PCM512x_OVERFLOW: | ||
169 | case PCM512x_RATE_DET_1: | ||
170 | case PCM512x_RATE_DET_2: | ||
171 | case PCM512x_RATE_DET_3: | ||
172 | case PCM512x_RATE_DET_4: | ||
173 | case PCM512x_ANALOG_MUTE_DET: | ||
174 | case PCM512x_GPIN: | ||
175 | case PCM512x_DIGITAL_MUTE_DET: | ||
176 | case PCM512x_CRAM_CTRL: | ||
177 | return true; | ||
178 | default: | ||
179 | /* There are 256 raw register addresses */ | ||
180 | return reg < 0xff; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -10350, 50, 1); | ||
185 | static const DECLARE_TLV_DB_SCALE(analog_tlv, -600, 600, 0); | ||
186 | static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0); | ||
187 | |||
188 | static const char * const pcm512x_dsp_program_texts[] = { | ||
189 | "FIR interpolation with de-emphasis", | ||
190 | "Low latency IIR with de-emphasis", | ||
191 | "Fixed process flow", | ||
192 | "High attenuation with de-emphasis", | ||
193 | "Ringing-less low latency FIR", | ||
194 | }; | ||
195 | |||
196 | static const unsigned int pcm512x_dsp_program_values[] = { | ||
197 | 1, | ||
198 | 2, | ||
199 | 3, | ||
200 | 5, | ||
201 | 7, | ||
202 | }; | ||
203 | |||
204 | static SOC_VALUE_ENUM_SINGLE_DECL(pcm512x_dsp_program, | ||
205 | PCM512x_DSP_PROGRAM, 0, 0x1f, | ||
206 | pcm512x_dsp_program_texts, | ||
207 | pcm512x_dsp_program_values); | ||
208 | |||
209 | static const char * const pcm512x_clk_missing_text[] = { | ||
210 | "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s" | ||
211 | }; | ||
212 | |||
213 | static const struct soc_enum pcm512x_clk_missing = | ||
214 | SOC_ENUM_SINGLE(PCM512x_CLKDET, 0, 8, pcm512x_clk_missing_text); | ||
215 | |||
216 | static const char * const pcm512x_autom_text[] = { | ||
217 | "21ms", "106ms", "213ms", "533ms", "1.07s", "2.13s", "5.33s", "10.66s" | ||
218 | }; | ||
219 | |||
220 | static const struct soc_enum pcm512x_autom_l = | ||
221 | SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATML_SHIFT, 8, | ||
222 | pcm512x_autom_text); | ||
223 | |||
224 | static const struct soc_enum pcm512x_autom_r = | ||
225 | SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATMR_SHIFT, 8, | ||
226 | pcm512x_autom_text); | ||
227 | |||
228 | static const char * const pcm512x_ramp_rate_text[] = { | ||
229 | "1 sample/update", "2 samples/update", "4 samples/update", | ||
230 | "Immediate" | ||
231 | }; | ||
232 | |||
233 | static const struct soc_enum pcm512x_vndf = | ||
234 | SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDF_SHIFT, 4, | ||
235 | pcm512x_ramp_rate_text); | ||
236 | |||
237 | static const struct soc_enum pcm512x_vnuf = | ||
238 | SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUF_SHIFT, 4, | ||
239 | pcm512x_ramp_rate_text); | ||
240 | |||
241 | static const struct soc_enum pcm512x_vedf = | ||
242 | SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDF_SHIFT, 4, | ||
243 | pcm512x_ramp_rate_text); | ||
244 | |||
245 | static const char * const pcm512x_ramp_step_text[] = { | ||
246 | "4dB/step", "2dB/step", "1dB/step", "0.5dB/step" | ||
247 | }; | ||
248 | |||
249 | static const struct soc_enum pcm512x_vnds = | ||
250 | SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDS_SHIFT, 4, | ||
251 | pcm512x_ramp_step_text); | ||
252 | |||
253 | static const struct soc_enum pcm512x_vnus = | ||
254 | SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUS_SHIFT, 4, | ||
255 | pcm512x_ramp_step_text); | ||
256 | |||
257 | static const struct soc_enum pcm512x_veds = | ||
258 | SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4, | ||
259 | pcm512x_ramp_step_text); | ||
260 | |||
261 | static const struct snd_kcontrol_new pcm512x_controls[] = { | ||
262 | SOC_DOUBLE_R_TLV("Playback Digital Volume", PCM512x_DIGITAL_VOLUME_2, | ||
263 | PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv), | ||
264 | SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL, | ||
265 | PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), | ||
266 | SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, | ||
267 | PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv), | ||
268 | SOC_DOUBLE("Playback Digital Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, | ||
269 | PCM512x_RQMR_SHIFT, 1, 1), | ||
270 | |||
271 | SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), | ||
272 | SOC_VALUE_ENUM("DSP Program", pcm512x_dsp_program), | ||
273 | |||
274 | SOC_ENUM("Clock Missing Period", pcm512x_clk_missing), | ||
275 | SOC_ENUM("Auto Mute Time Left", pcm512x_autom_l), | ||
276 | SOC_ENUM("Auto Mute Time Right", pcm512x_autom_r), | ||
277 | SOC_SINGLE("Auto Mute Mono Switch", PCM512x_DIGITAL_MUTE_3, | ||
278 | PCM512x_ACTL_SHIFT, 1, 0), | ||
279 | SOC_DOUBLE("Auto Mute Switch", PCM512x_DIGITAL_MUTE_3, PCM512x_AMLE_SHIFT, | ||
280 | PCM512x_AMLR_SHIFT, 1, 0), | ||
281 | |||
282 | SOC_ENUM("Volume Ramp Down Rate", pcm512x_vndf), | ||
283 | SOC_ENUM("Volume Ramp Down Step", pcm512x_vnds), | ||
284 | SOC_ENUM("Volume Ramp Up Rate", pcm512x_vnuf), | ||
285 | SOC_ENUM("Volume Ramp Up Step", pcm512x_vnus), | ||
286 | SOC_ENUM("Volume Ramp Down Emergency Rate", pcm512x_vedf), | ||
287 | SOC_ENUM("Volume Ramp Down Emergency Step", pcm512x_veds), | ||
288 | }; | ||
289 | |||
290 | static const struct snd_soc_dapm_widget pcm512x_dapm_widgets[] = { | ||
291 | SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0), | ||
292 | SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0), | ||
293 | |||
294 | SND_SOC_DAPM_OUTPUT("OUTL"), | ||
295 | SND_SOC_DAPM_OUTPUT("OUTR"), | ||
296 | }; | ||
297 | |||
298 | static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = { | ||
299 | { "DACL", NULL, "Playback" }, | ||
300 | { "DACR", NULL, "Playback" }, | ||
301 | |||
302 | { "OUTL", NULL, "DACL" }, | ||
303 | { "OUTR", NULL, "DACR" }, | ||
304 | }; | ||
305 | |||
306 | static int pcm512x_set_bias_level(struct snd_soc_codec *codec, | ||
307 | enum snd_soc_bias_level level) | ||
308 | { | ||
309 | struct pcm512x_priv *pcm512x = dev_get_drvdata(codec->dev); | ||
310 | int ret; | ||
311 | |||
312 | switch (level) { | ||
313 | case SND_SOC_BIAS_ON: | ||
314 | case SND_SOC_BIAS_PREPARE: | ||
315 | break; | ||
316 | |||
317 | case SND_SOC_BIAS_STANDBY: | ||
318 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, | ||
319 | PCM512x_RQST, 0); | ||
320 | if (ret != 0) { | ||
321 | dev_err(codec->dev, "Failed to remove standby: %d\n", | ||
322 | ret); | ||
323 | return ret; | ||
324 | } | ||
325 | break; | ||
326 | |||
327 | case SND_SOC_BIAS_OFF: | ||
328 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, | ||
329 | PCM512x_RQST, PCM512x_RQST); | ||
330 | if (ret != 0) { | ||
331 | dev_err(codec->dev, "Failed to request standby: %d\n", | ||
332 | ret); | ||
333 | return ret; | ||
334 | } | ||
335 | break; | ||
336 | } | ||
337 | |||
338 | codec->dapm.bias_level = level; | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static struct snd_soc_dai_driver pcm512x_dai = { | ||
344 | .name = "pcm512x-hifi", | ||
345 | .playback = { | ||
346 | .stream_name = "Playback", | ||
347 | .channels_min = 2, | ||
348 | .channels_max = 2, | ||
349 | .rates = SNDRV_PCM_RATE_8000_192000, | ||
350 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | ||
351 | SNDRV_PCM_FMTBIT_S24_LE | | ||
352 | SNDRV_PCM_FMTBIT_S32_LE | ||
353 | }, | ||
354 | }; | ||
355 | |||
356 | static struct snd_soc_codec_driver pcm512x_codec_driver = { | ||
357 | .set_bias_level = pcm512x_set_bias_level, | ||
358 | .idle_bias_off = true, | ||
359 | |||
360 | .controls = pcm512x_controls, | ||
361 | .num_controls = ARRAY_SIZE(pcm512x_controls), | ||
362 | .dapm_widgets = pcm512x_dapm_widgets, | ||
363 | .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets), | ||
364 | .dapm_routes = pcm512x_dapm_routes, | ||
365 | .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes), | ||
366 | }; | ||
367 | |||
368 | static const struct regmap_range_cfg pcm512x_range = { | ||
369 | .name = "Pages", .range_min = PCM512x_VIRT_BASE, | ||
370 | .range_max = PCM512x_MAX_REGISTER, | ||
371 | .selector_reg = PCM512x_PAGE, | ||
372 | .selector_mask = 0xff, | ||
373 | .window_start = 0, .window_len = 0x100, | ||
374 | }; | ||
375 | |||
376 | const struct regmap_config pcm512x_regmap = { | ||
377 | .reg_bits = 8, | ||
378 | .val_bits = 8, | ||
379 | |||
380 | .readable_reg = pcm512x_readable, | ||
381 | .volatile_reg = pcm512x_volatile, | ||
382 | |||
383 | .ranges = &pcm512x_range, | ||
384 | .num_ranges = 1, | ||
385 | |||
386 | .max_register = PCM512x_MAX_REGISTER, | ||
387 | .reg_defaults = pcm512x_reg_defaults, | ||
388 | .num_reg_defaults = ARRAY_SIZE(pcm512x_reg_defaults), | ||
389 | .cache_type = REGCACHE_RBTREE, | ||
390 | }; | ||
391 | EXPORT_SYMBOL_GPL(pcm512x_regmap); | ||
392 | |||
393 | int pcm512x_probe(struct device *dev, struct regmap *regmap) | ||
394 | { | ||
395 | struct pcm512x_priv *pcm512x; | ||
396 | int i, ret; | ||
397 | |||
398 | pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL); | ||
399 | if (!pcm512x) | ||
400 | return -ENOMEM; | ||
401 | |||
402 | dev_set_drvdata(dev, pcm512x); | ||
403 | pcm512x->regmap = regmap; | ||
404 | |||
405 | for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) | ||
406 | pcm512x->supplies[i].supply = pcm512x_supply_names[i]; | ||
407 | |||
408 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pcm512x->supplies), | ||
409 | pcm512x->supplies); | ||
410 | if (ret != 0) { | ||
411 | dev_err(dev, "Failed to get supplies: %d\n", ret); | ||
412 | return ret; | ||
413 | } | ||
414 | |||
415 | pcm512x->supply_nb[0].notifier_call = pcm512x_regulator_event_0; | ||
416 | pcm512x->supply_nb[1].notifier_call = pcm512x_regulator_event_1; | ||
417 | pcm512x->supply_nb[2].notifier_call = pcm512x_regulator_event_2; | ||
418 | |||
419 | for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) { | ||
420 | ret = regulator_register_notifier(pcm512x->supplies[i].consumer, | ||
421 | &pcm512x->supply_nb[i]); | ||
422 | if (ret != 0) { | ||
423 | dev_err(dev, | ||
424 | "Failed to register regulator notifier: %d\n", | ||
425 | ret); | ||
426 | } | ||
427 | } | ||
428 | |||
429 | ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies), | ||
430 | pcm512x->supplies); | ||
431 | if (ret != 0) { | ||
432 | dev_err(dev, "Failed to enable supplies: %d\n", ret); | ||
433 | return ret; | ||
434 | } | ||
435 | |||
436 | /* Reset the device, verifying I/O in the process for I2C */ | ||
437 | ret = regmap_write(regmap, PCM512x_RESET, | ||
438 | PCM512x_RSTM | PCM512x_RSTR); | ||
439 | if (ret != 0) { | ||
440 | dev_err(dev, "Failed to reset device: %d\n", ret); | ||
441 | goto err; | ||
442 | } | ||
443 | |||
444 | ret = regmap_write(regmap, PCM512x_RESET, 0); | ||
445 | if (ret != 0) { | ||
446 | dev_err(dev, "Failed to reset device: %d\n", ret); | ||
447 | goto err; | ||
448 | } | ||
449 | |||
450 | pcm512x->sclk = devm_clk_get(dev, NULL); | ||
451 | if (IS_ERR(pcm512x->sclk)) { | ||
452 | if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) | ||
453 | return -EPROBE_DEFER; | ||
454 | |||
455 | dev_info(dev, "No SCLK, using BCLK: %ld\n", | ||
456 | PTR_ERR(pcm512x->sclk)); | ||
457 | |||
458 | /* Disable reporting of missing SCLK as an error */ | ||
459 | regmap_update_bits(regmap, PCM512x_ERROR_DETECT, | ||
460 | PCM512x_IDCH, PCM512x_IDCH); | ||
461 | |||
462 | /* Switch PLL input to BCLK */ | ||
463 | regmap_update_bits(regmap, PCM512x_PLL_REF, | ||
464 | PCM512x_SREF, PCM512x_SREF); | ||
465 | } else { | ||
466 | ret = clk_prepare_enable(pcm512x->sclk); | ||
467 | if (ret != 0) { | ||
468 | dev_err(dev, "Failed to enable SCLK: %d\n", ret); | ||
469 | return ret; | ||
470 | } | ||
471 | } | ||
472 | |||
473 | /* Default to standby mode */ | ||
474 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, | ||
475 | PCM512x_RQST, PCM512x_RQST); | ||
476 | if (ret != 0) { | ||
477 | dev_err(dev, "Failed to request standby: %d\n", | ||
478 | ret); | ||
479 | goto err_clk; | ||
480 | } | ||
481 | |||
482 | pm_runtime_set_active(dev); | ||
483 | pm_runtime_enable(dev); | ||
484 | pm_runtime_idle(dev); | ||
485 | |||
486 | ret = snd_soc_register_codec(dev, &pcm512x_codec_driver, | ||
487 | &pcm512x_dai, 1); | ||
488 | if (ret != 0) { | ||
489 | dev_err(dev, "Failed to register CODEC: %d\n", ret); | ||
490 | goto err_pm; | ||
491 | } | ||
492 | |||
493 | return 0; | ||
494 | |||
495 | err_pm: | ||
496 | pm_runtime_disable(dev); | ||
497 | err_clk: | ||
498 | if (!IS_ERR(pcm512x->sclk)) | ||
499 | clk_disable_unprepare(pcm512x->sclk); | ||
500 | err: | ||
501 | regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies), | ||
502 | pcm512x->supplies); | ||
503 | return ret; | ||
504 | } | ||
505 | EXPORT_SYMBOL_GPL(pcm512x_probe); | ||
506 | |||
507 | void pcm512x_remove(struct device *dev) | ||
508 | { | ||
509 | struct pcm512x_priv *pcm512x = dev_get_drvdata(dev); | ||
510 | |||
511 | snd_soc_unregister_codec(dev); | ||
512 | pm_runtime_disable(dev); | ||
513 | if (!IS_ERR(pcm512x->sclk)) | ||
514 | clk_disable_unprepare(pcm512x->sclk); | ||
515 | regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies), | ||
516 | pcm512x->supplies); | ||
517 | } | ||
518 | EXPORT_SYMBOL_GPL(pcm512x_remove); | ||
519 | |||
520 | static int pcm512x_suspend(struct device *dev) | ||
521 | { | ||
522 | struct pcm512x_priv *pcm512x = dev_get_drvdata(dev); | ||
523 | int ret; | ||
524 | |||
525 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, | ||
526 | PCM512x_RQPD, PCM512x_RQPD); | ||
527 | if (ret != 0) { | ||
528 | dev_err(dev, "Failed to request power down: %d\n", ret); | ||
529 | return ret; | ||
530 | } | ||
531 | |||
532 | ret = regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies), | ||
533 | pcm512x->supplies); | ||
534 | if (ret != 0) { | ||
535 | dev_err(dev, "Failed to disable supplies: %d\n", ret); | ||
536 | return ret; | ||
537 | } | ||
538 | |||
539 | if (!IS_ERR(pcm512x->sclk)) | ||
540 | clk_disable_unprepare(pcm512x->sclk); | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static int pcm512x_resume(struct device *dev) | ||
546 | { | ||
547 | struct pcm512x_priv *pcm512x = dev_get_drvdata(dev); | ||
548 | int ret; | ||
549 | |||
550 | if (!IS_ERR(pcm512x->sclk)) { | ||
551 | ret = clk_prepare_enable(pcm512x->sclk); | ||
552 | if (ret != 0) { | ||
553 | dev_err(dev, "Failed to enable SCLK: %d\n", ret); | ||
554 | return ret; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies), | ||
559 | pcm512x->supplies); | ||
560 | if (ret != 0) { | ||
561 | dev_err(dev, "Failed to enable supplies: %d\n", ret); | ||
562 | return ret; | ||
563 | } | ||
564 | |||
565 | regcache_cache_only(pcm512x->regmap, false); | ||
566 | ret = regcache_sync(pcm512x->regmap); | ||
567 | if (ret != 0) { | ||
568 | dev_err(dev, "Failed to sync cache: %d\n", ret); | ||
569 | return ret; | ||
570 | } | ||
571 | |||
572 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, | ||
573 | PCM512x_RQPD, 0); | ||
574 | if (ret != 0) { | ||
575 | dev_err(dev, "Failed to remove power down: %d\n", ret); | ||
576 | return ret; | ||
577 | } | ||
578 | |||
579 | return 0; | ||
580 | } | ||
581 | |||
582 | const struct dev_pm_ops pcm512x_pm_ops = { | ||
583 | SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL) | ||
584 | }; | ||
585 | EXPORT_SYMBOL_GPL(pcm512x_pm_ops); | ||
586 | |||
587 | MODULE_DESCRIPTION("ASoC PCM512x codec driver"); | ||
588 | MODULE_AUTHOR("Mark Brown <broonie@linaro.org>"); | ||
589 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/pcm512x.h b/sound/soc/codecs/pcm512x.h new file mode 100644 index 000000000000..6ee76aaca09a --- /dev/null +++ b/sound/soc/codecs/pcm512x.h | |||
@@ -0,0 +1,171 @@ | |||
1 | /* | ||
2 | * Driver for the PCM512x CODECs | ||
3 | * | ||
4 | * Author: Mark Brown <broonie@linaro.org> | ||
5 | * Copyright 2014 Linaro Ltd | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #ifndef _SND_SOC_PCM512X | ||
18 | #define _SND_SOC_PCM512X | ||
19 | |||
20 | #include <linux/pm.h> | ||
21 | #include <linux/regmap.h> | ||
22 | |||
23 | #define PCM512x_VIRT_BASE 0x100 | ||
24 | #define PCM512x_PAGE_LEN 0x100 | ||
25 | #define PCM512x_PAGE_BASE(n) (PCM512x_VIRT_BASE + (PCM512x_PAGE_LEN * n)) | ||
26 | |||
27 | #define PCM512x_PAGE 0 | ||
28 | |||
29 | #define PCM512x_RESET (PCM512x_PAGE_BASE(0) + 1) | ||
30 | #define PCM512x_POWER (PCM512x_PAGE_BASE(0) + 2) | ||
31 | #define PCM512x_MUTE (PCM512x_PAGE_BASE(0) + 3) | ||
32 | #define PCM512x_PLL_EN (PCM512x_PAGE_BASE(0) + 4) | ||
33 | #define PCM512x_SPI_MISO_FUNCTION (PCM512x_PAGE_BASE(0) + 6) | ||
34 | #define PCM512x_DSP (PCM512x_PAGE_BASE(0) + 7) | ||
35 | #define PCM512x_GPIO_EN (PCM512x_PAGE_BASE(0) + 8) | ||
36 | #define PCM512x_BCLK_LRCLK_CFG (PCM512x_PAGE_BASE(0) + 9) | ||
37 | #define PCM512x_DSP_GPIO_INPUT (PCM512x_PAGE_BASE(0) + 10) | ||
38 | #define PCM512x_MASTER_MODE (PCM512x_PAGE_BASE(0) + 12) | ||
39 | #define PCM512x_PLL_REF (PCM512x_PAGE_BASE(0) + 13) | ||
40 | #define PCM512x_PLL_COEFF_0 (PCM512x_PAGE_BASE(0) + 20) | ||
41 | #define PCM512x_PLL_COEFF_1 (PCM512x_PAGE_BASE(0) + 21) | ||
42 | #define PCM512x_PLL_COEFF_2 (PCM512x_PAGE_BASE(0) + 22) | ||
43 | #define PCM512x_PLL_COEFF_3 (PCM512x_PAGE_BASE(0) + 23) | ||
44 | #define PCM512x_PLL_COEFF_4 (PCM512x_PAGE_BASE(0) + 24) | ||
45 | #define PCM512x_DSP_CLKDIV (PCM512x_PAGE_BASE(0) + 27) | ||
46 | #define PCM512x_DAC_CLKDIV (PCM512x_PAGE_BASE(0) + 28) | ||
47 | #define PCM512x_NCP_CLKDIV (PCM512x_PAGE_BASE(0) + 29) | ||
48 | #define PCM512x_OSR_CLKDIV (PCM512x_PAGE_BASE(0) + 30) | ||
49 | #define PCM512x_MASTER_CLKDIV_1 (PCM512x_PAGE_BASE(0) + 32) | ||
50 | #define PCM512x_MASTER_CLKDIV_2 (PCM512x_PAGE_BASE(0) + 33) | ||
51 | #define PCM512x_FS_SPEED_MODE (PCM512x_PAGE_BASE(0) + 34) | ||
52 | #define PCM512x_IDAC_1 (PCM512x_PAGE_BASE(0) + 35) | ||
53 | #define PCM512x_IDAC_2 (PCM512x_PAGE_BASE(0) + 36) | ||
54 | #define PCM512x_ERROR_DETECT (PCM512x_PAGE_BASE(0) + 37) | ||
55 | #define PCM512x_I2S_1 (PCM512x_PAGE_BASE(0) + 40) | ||
56 | #define PCM512x_I2S_2 (PCM512x_PAGE_BASE(0) + 41) | ||
57 | #define PCM512x_DAC_ROUTING (PCM512x_PAGE_BASE(0) + 42) | ||
58 | #define PCM512x_DSP_PROGRAM (PCM512x_PAGE_BASE(0) + 43) | ||
59 | #define PCM512x_CLKDET (PCM512x_PAGE_BASE(0) + 44) | ||
60 | #define PCM512x_AUTO_MUTE (PCM512x_PAGE_BASE(0) + 59) | ||
61 | #define PCM512x_DIGITAL_VOLUME_1 (PCM512x_PAGE_BASE(0) + 60) | ||
62 | #define PCM512x_DIGITAL_VOLUME_2 (PCM512x_PAGE_BASE(0) + 61) | ||
63 | #define PCM512x_DIGITAL_VOLUME_3 (PCM512x_PAGE_BASE(0) + 62) | ||
64 | #define PCM512x_DIGITAL_MUTE_1 (PCM512x_PAGE_BASE(0) + 63) | ||
65 | #define PCM512x_DIGITAL_MUTE_2 (PCM512x_PAGE_BASE(0) + 64) | ||
66 | #define PCM512x_DIGITAL_MUTE_3 (PCM512x_PAGE_BASE(0) + 65) | ||
67 | #define PCM512x_GPIO_OUTPUT_1 (PCM512x_PAGE_BASE(0) + 80) | ||
68 | #define PCM512x_GPIO_OUTPUT_2 (PCM512x_PAGE_BASE(0) + 81) | ||
69 | #define PCM512x_GPIO_OUTPUT_3 (PCM512x_PAGE_BASE(0) + 82) | ||
70 | #define PCM512x_GPIO_OUTPUT_4 (PCM512x_PAGE_BASE(0) + 83) | ||
71 | #define PCM512x_GPIO_OUTPUT_5 (PCM512x_PAGE_BASE(0) + 84) | ||
72 | #define PCM512x_GPIO_OUTPUT_6 (PCM512x_PAGE_BASE(0) + 85) | ||
73 | #define PCM512x_GPIO_CONTROL_1 (PCM512x_PAGE_BASE(0) + 86) | ||
74 | #define PCM512x_GPIO_CONTROL_2 (PCM512x_PAGE_BASE(0) + 87) | ||
75 | #define PCM512x_OVERFLOW (PCM512x_PAGE_BASE(0) + 90) | ||
76 | #define PCM512x_RATE_DET_1 (PCM512x_PAGE_BASE(0) + 91) | ||
77 | #define PCM512x_RATE_DET_2 (PCM512x_PAGE_BASE(0) + 92) | ||
78 | #define PCM512x_RATE_DET_3 (PCM512x_PAGE_BASE(0) + 93) | ||
79 | #define PCM512x_RATE_DET_4 (PCM512x_PAGE_BASE(0) + 94) | ||
80 | #define PCM512x_ANALOG_MUTE_DET (PCM512x_PAGE_BASE(0) + 108) | ||
81 | #define PCM512x_GPIN (PCM512x_PAGE_BASE(0) + 119) | ||
82 | #define PCM512x_DIGITAL_MUTE_DET (PCM512x_PAGE_BASE(0) + 120) | ||
83 | |||
84 | #define PCM512x_OUTPUT_AMPLITUDE (PCM512x_PAGE_BASE(1) + 1) | ||
85 | #define PCM512x_ANALOG_GAIN_CTRL (PCM512x_PAGE_BASE(1) + 2) | ||
86 | #define PCM512x_UNDERVOLTAGE_PROT (PCM512x_PAGE_BASE(1) + 5) | ||
87 | #define PCM512x_ANALOG_MUTE_CTRL (PCM512x_PAGE_BASE(1) + 6) | ||
88 | #define PCM512x_ANALOG_GAIN_BOOST (PCM512x_PAGE_BASE(1) + 7) | ||
89 | #define PCM512x_VCOM_CTRL_1 (PCM512x_PAGE_BASE(1) + 8) | ||
90 | #define PCM512x_VCOM_CTRL_2 (PCM512x_PAGE_BASE(1) + 9) | ||
91 | |||
92 | #define PCM512x_CRAM_CTRL (PCM512x_PAGE_BASE(44) + 1) | ||
93 | |||
94 | #define PCM512x_MAX_REGISTER (PCM512x_PAGE_BASE(44) + 1) | ||
95 | |||
96 | /* Page 0, Register 1 - reset */ | ||
97 | #define PCM512x_RSTR (1 << 0) | ||
98 | #define PCM512x_RSTM (1 << 4) | ||
99 | |||
100 | /* Page 0, Register 2 - power */ | ||
101 | #define PCM512x_RQPD (1 << 0) | ||
102 | #define PCM512x_RQPD_SHIFT 0 | ||
103 | #define PCM512x_RQST (1 << 4) | ||
104 | #define PCM512x_RQST_SHIFT 4 | ||
105 | |||
106 | /* Page 0, Register 3 - mute */ | ||
107 | #define PCM512x_RQMR_SHIFT 0 | ||
108 | #define PCM512x_RQML_SHIFT 4 | ||
109 | |||
110 | /* Page 0, Register 4 - PLL */ | ||
111 | #define PCM512x_PLCE (1 << 0) | ||
112 | #define PCM512x_RLCE_SHIFT 0 | ||
113 | #define PCM512x_PLCK (1 << 4) | ||
114 | #define PCM512x_PLCK_SHIFT 4 | ||
115 | |||
116 | /* Page 0, Register 7 - DSP */ | ||
117 | #define PCM512x_SDSL (1 << 0) | ||
118 | #define PCM512x_SDSL_SHIFT 0 | ||
119 | #define PCM512x_DEMP (1 << 4) | ||
120 | #define PCM512x_DEMP_SHIFT 4 | ||
121 | |||
122 | /* Page 0, Register 13 - PLL reference */ | ||
123 | #define PCM512x_SREF (1 << 4) | ||
124 | |||
125 | /* Page 0, Register 37 - Error detection */ | ||
126 | #define PCM512x_IPLK (1 << 0) | ||
127 | #define PCM512x_DCAS (1 << 1) | ||
128 | #define PCM512x_IDCM (1 << 2) | ||
129 | #define PCM512x_IDCH (1 << 3) | ||
130 | #define PCM512x_IDSK (1 << 4) | ||
131 | #define PCM512x_IDBK (1 << 5) | ||
132 | #define PCM512x_IDFS (1 << 6) | ||
133 | |||
134 | /* Page 0, Register 42 - DAC routing */ | ||
135 | #define PCM512x_AUPR_SHIFT 0 | ||
136 | #define PCM512x_AUPL_SHIFT 4 | ||
137 | |||
138 | /* Page 0, Register 59 - auto mute */ | ||
139 | #define PCM512x_ATMR_SHIFT 0 | ||
140 | #define PCM512x_ATML_SHIFT 4 | ||
141 | |||
142 | /* Page 0, Register 63 - ramp rates */ | ||
143 | #define PCM512x_VNDF_SHIFT 6 | ||
144 | #define PCM512x_VNDS_SHIFT 4 | ||
145 | #define PCM512x_VNUF_SHIFT 2 | ||
146 | #define PCM512x_VNUS_SHIFT 0 | ||
147 | |||
148 | /* Page 0, Register 64 - emergency ramp rates */ | ||
149 | #define PCM512x_VEDF_SHIFT 6 | ||
150 | #define PCM512x_VEDS_SHIFT 4 | ||
151 | |||
152 | /* Page 0, Register 65 - Digital mute enables */ | ||
153 | #define PCM512x_ACTL_SHIFT 2 | ||
154 | #define PCM512x_AMLE_SHIFT 1 | ||
155 | #define PCM512x_AMLR_SHIFT 0 | ||
156 | |||
157 | /* Page 1, Register 2 - analog volume control */ | ||
158 | #define PCM512x_RAGN_SHIFT 0 | ||
159 | #define PCM512x_LAGN_SHIFT 4 | ||
160 | |||
161 | /* Page 1, Register 7 - analog boost control */ | ||
162 | #define PCM512x_AGBR_SHIFT 0 | ||
163 | #define PCM512x_AGBL_SHIFT 4 | ||
164 | |||
165 | extern const struct dev_pm_ops pcm512x_pm_ops; | ||
166 | extern const struct regmap_config pcm512x_regmap; | ||
167 | |||
168 | int pcm512x_probe(struct device *dev, struct regmap *regmap); | ||
169 | void pcm512x_remove(struct device *dev); | ||
170 | |||
171 | #endif | ||
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 912c9cbc2724..d4c229f0233f 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c | |||
@@ -210,26 +210,22 @@ static int rt5631_dmic_put(struct snd_kcontrol *kcontrol, | |||
210 | static const char *rt5631_input_mode[] = { | 210 | static const char *rt5631_input_mode[] = { |
211 | "Single ended", "Differential"}; | 211 | "Single ended", "Differential"}; |
212 | 212 | ||
213 | static const SOC_ENUM_SINGLE_DECL( | 213 | static SOC_ENUM_SINGLE_DECL(rt5631_mic1_mode_enum, RT5631_MIC_CTRL_1, |
214 | rt5631_mic1_mode_enum, RT5631_MIC_CTRL_1, | 214 | RT5631_MIC1_DIFF_INPUT_SHIFT, rt5631_input_mode); |
215 | RT5631_MIC1_DIFF_INPUT_SHIFT, rt5631_input_mode); | ||
216 | 215 | ||
217 | static const SOC_ENUM_SINGLE_DECL( | 216 | static SOC_ENUM_SINGLE_DECL(rt5631_mic2_mode_enum, RT5631_MIC_CTRL_1, |
218 | rt5631_mic2_mode_enum, RT5631_MIC_CTRL_1, | 217 | RT5631_MIC2_DIFF_INPUT_SHIFT, rt5631_input_mode); |
219 | RT5631_MIC2_DIFF_INPUT_SHIFT, rt5631_input_mode); | ||
220 | 218 | ||
221 | /* MONO Input Type */ | 219 | /* MONO Input Type */ |
222 | static const SOC_ENUM_SINGLE_DECL( | 220 | static SOC_ENUM_SINGLE_DECL(rt5631_monoin_mode_enum, RT5631_MONO_INPUT_VOL, |
223 | rt5631_monoin_mode_enum, RT5631_MONO_INPUT_VOL, | 221 | RT5631_MONO_DIFF_INPUT_SHIFT, rt5631_input_mode); |
224 | RT5631_MONO_DIFF_INPUT_SHIFT, rt5631_input_mode); | ||
225 | 222 | ||
226 | /* SPK Ratio Gain Control */ | 223 | /* SPK Ratio Gain Control */ |
227 | static const char *rt5631_spk_ratio[] = {"1.00x", "1.09x", "1.27x", "1.44x", | 224 | static const char *rt5631_spk_ratio[] = {"1.00x", "1.09x", "1.27x", "1.44x", |
228 | "1.56x", "1.68x", "1.99x", "2.34x"}; | 225 | "1.56x", "1.68x", "1.99x", "2.34x"}; |
229 | 226 | ||
230 | static const SOC_ENUM_SINGLE_DECL( | 227 | static SOC_ENUM_SINGLE_DECL(rt5631_spk_ratio_enum, RT5631_GEN_PUR_CTRL_REG, |
231 | rt5631_spk_ratio_enum, RT5631_GEN_PUR_CTRL_REG, | 228 | RT5631_SPK_AMP_RATIO_CTRL_SHIFT, rt5631_spk_ratio); |
232 | RT5631_SPK_AMP_RATIO_CTRL_SHIFT, rt5631_spk_ratio); | ||
233 | 229 | ||
234 | static const struct snd_kcontrol_new rt5631_snd_controls[] = { | 230 | static const struct snd_kcontrol_new rt5631_snd_controls[] = { |
235 | /* MIC */ | 231 | /* MIC */ |
@@ -759,9 +755,8 @@ static const struct snd_kcontrol_new rt5631_monomix_mixer_controls[] = { | |||
759 | /* Left SPK Volume Input */ | 755 | /* Left SPK Volume Input */ |
760 | static const char *rt5631_spkvoll_sel[] = {"Vmid", "SPKMIXL"}; | 756 | static const char *rt5631_spkvoll_sel[] = {"Vmid", "SPKMIXL"}; |
761 | 757 | ||
762 | static const SOC_ENUM_SINGLE_DECL( | 758 | static SOC_ENUM_SINGLE_DECL(rt5631_spkvoll_enum, RT5631_SPK_OUT_VOL, |
763 | rt5631_spkvoll_enum, RT5631_SPK_OUT_VOL, | 759 | RT5631_L_EN_SHIFT, rt5631_spkvoll_sel); |
764 | RT5631_L_EN_SHIFT, rt5631_spkvoll_sel); | ||
765 | 760 | ||
766 | static const struct snd_kcontrol_new rt5631_spkvoll_mux_control = | 761 | static const struct snd_kcontrol_new rt5631_spkvoll_mux_control = |
767 | SOC_DAPM_ENUM("Left SPKVOL SRC", rt5631_spkvoll_enum); | 762 | SOC_DAPM_ENUM("Left SPKVOL SRC", rt5631_spkvoll_enum); |
@@ -769,9 +764,8 @@ static const struct snd_kcontrol_new rt5631_spkvoll_mux_control = | |||
769 | /* Left HP Volume Input */ | 764 | /* Left HP Volume Input */ |
770 | static const char *rt5631_hpvoll_sel[] = {"Vmid", "OUTMIXL"}; | 765 | static const char *rt5631_hpvoll_sel[] = {"Vmid", "OUTMIXL"}; |
771 | 766 | ||
772 | static const SOC_ENUM_SINGLE_DECL( | 767 | static SOC_ENUM_SINGLE_DECL(rt5631_hpvoll_enum, RT5631_HP_OUT_VOL, |
773 | rt5631_hpvoll_enum, RT5631_HP_OUT_VOL, | 768 | RT5631_L_EN_SHIFT, rt5631_hpvoll_sel); |
774 | RT5631_L_EN_SHIFT, rt5631_hpvoll_sel); | ||
775 | 769 | ||
776 | static const struct snd_kcontrol_new rt5631_hpvoll_mux_control = | 770 | static const struct snd_kcontrol_new rt5631_hpvoll_mux_control = |
777 | SOC_DAPM_ENUM("Left HPVOL SRC", rt5631_hpvoll_enum); | 771 | SOC_DAPM_ENUM("Left HPVOL SRC", rt5631_hpvoll_enum); |
@@ -779,9 +773,8 @@ static const struct snd_kcontrol_new rt5631_hpvoll_mux_control = | |||
779 | /* Left Out Volume Input */ | 773 | /* Left Out Volume Input */ |
780 | static const char *rt5631_outvoll_sel[] = {"Vmid", "OUTMIXL"}; | 774 | static const char *rt5631_outvoll_sel[] = {"Vmid", "OUTMIXL"}; |
781 | 775 | ||
782 | static const SOC_ENUM_SINGLE_DECL( | 776 | static SOC_ENUM_SINGLE_DECL(rt5631_outvoll_enum, RT5631_MONO_AXO_1_2_VOL, |
783 | rt5631_outvoll_enum, RT5631_MONO_AXO_1_2_VOL, | 777 | RT5631_L_EN_SHIFT, rt5631_outvoll_sel); |
784 | RT5631_L_EN_SHIFT, rt5631_outvoll_sel); | ||
785 | 778 | ||
786 | static const struct snd_kcontrol_new rt5631_outvoll_mux_control = | 779 | static const struct snd_kcontrol_new rt5631_outvoll_mux_control = |
787 | SOC_DAPM_ENUM("Left OUTVOL SRC", rt5631_outvoll_enum); | 780 | SOC_DAPM_ENUM("Left OUTVOL SRC", rt5631_outvoll_enum); |
@@ -789,9 +782,8 @@ static const struct snd_kcontrol_new rt5631_outvoll_mux_control = | |||
789 | /* Right Out Volume Input */ | 782 | /* Right Out Volume Input */ |
790 | static const char *rt5631_outvolr_sel[] = {"Vmid", "OUTMIXR"}; | 783 | static const char *rt5631_outvolr_sel[] = {"Vmid", "OUTMIXR"}; |
791 | 784 | ||
792 | static const SOC_ENUM_SINGLE_DECL( | 785 | static SOC_ENUM_SINGLE_DECL(rt5631_outvolr_enum, RT5631_MONO_AXO_1_2_VOL, |
793 | rt5631_outvolr_enum, RT5631_MONO_AXO_1_2_VOL, | 786 | RT5631_R_EN_SHIFT, rt5631_outvolr_sel); |
794 | RT5631_R_EN_SHIFT, rt5631_outvolr_sel); | ||
795 | 787 | ||
796 | static const struct snd_kcontrol_new rt5631_outvolr_mux_control = | 788 | static const struct snd_kcontrol_new rt5631_outvolr_mux_control = |
797 | SOC_DAPM_ENUM("Right OUTVOL SRC", rt5631_outvolr_enum); | 789 | SOC_DAPM_ENUM("Right OUTVOL SRC", rt5631_outvolr_enum); |
@@ -799,9 +791,8 @@ static const struct snd_kcontrol_new rt5631_outvolr_mux_control = | |||
799 | /* Right HP Volume Input */ | 791 | /* Right HP Volume Input */ |
800 | static const char *rt5631_hpvolr_sel[] = {"Vmid", "OUTMIXR"}; | 792 | static const char *rt5631_hpvolr_sel[] = {"Vmid", "OUTMIXR"}; |
801 | 793 | ||
802 | static const SOC_ENUM_SINGLE_DECL( | 794 | static SOC_ENUM_SINGLE_DECL(rt5631_hpvolr_enum, RT5631_HP_OUT_VOL, |
803 | rt5631_hpvolr_enum, RT5631_HP_OUT_VOL, | 795 | RT5631_R_EN_SHIFT, rt5631_hpvolr_sel); |
804 | RT5631_R_EN_SHIFT, rt5631_hpvolr_sel); | ||
805 | 796 | ||
806 | static const struct snd_kcontrol_new rt5631_hpvolr_mux_control = | 797 | static const struct snd_kcontrol_new rt5631_hpvolr_mux_control = |
807 | SOC_DAPM_ENUM("Right HPVOL SRC", rt5631_hpvolr_enum); | 798 | SOC_DAPM_ENUM("Right HPVOL SRC", rt5631_hpvolr_enum); |
@@ -809,9 +800,8 @@ static const struct snd_kcontrol_new rt5631_hpvolr_mux_control = | |||
809 | /* Right SPK Volume Input */ | 800 | /* Right SPK Volume Input */ |
810 | static const char *rt5631_spkvolr_sel[] = {"Vmid", "SPKMIXR"}; | 801 | static const char *rt5631_spkvolr_sel[] = {"Vmid", "SPKMIXR"}; |
811 | 802 | ||
812 | static const SOC_ENUM_SINGLE_DECL( | 803 | static SOC_ENUM_SINGLE_DECL(rt5631_spkvolr_enum, RT5631_SPK_OUT_VOL, |
813 | rt5631_spkvolr_enum, RT5631_SPK_OUT_VOL, | 804 | RT5631_R_EN_SHIFT, rt5631_spkvolr_sel); |
814 | RT5631_R_EN_SHIFT, rt5631_spkvolr_sel); | ||
815 | 805 | ||
816 | static const struct snd_kcontrol_new rt5631_spkvolr_mux_control = | 806 | static const struct snd_kcontrol_new rt5631_spkvolr_mux_control = |
817 | SOC_DAPM_ENUM("Right SPKVOL SRC", rt5631_spkvolr_enum); | 807 | SOC_DAPM_ENUM("Right SPKVOL SRC", rt5631_spkvolr_enum); |
@@ -820,9 +810,8 @@ static const struct snd_kcontrol_new rt5631_spkvolr_mux_control = | |||
820 | static const char *rt5631_spol_src_sel[] = { | 810 | static const char *rt5631_spol_src_sel[] = { |
821 | "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"}; | 811 | "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"}; |
822 | 812 | ||
823 | static const SOC_ENUM_SINGLE_DECL( | 813 | static SOC_ENUM_SINGLE_DECL(rt5631_spol_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, |
824 | rt5631_spol_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | 814 | RT5631_SPK_L_MUX_SEL_SHIFT, rt5631_spol_src_sel); |
825 | RT5631_SPK_L_MUX_SEL_SHIFT, rt5631_spol_src_sel); | ||
826 | 815 | ||
827 | static const struct snd_kcontrol_new rt5631_spol_mux_control = | 816 | static const struct snd_kcontrol_new rt5631_spol_mux_control = |
828 | SOC_DAPM_ENUM("SPOL SRC", rt5631_spol_src_enum); | 817 | SOC_DAPM_ENUM("SPOL SRC", rt5631_spol_src_enum); |
@@ -831,9 +820,8 @@ static const struct snd_kcontrol_new rt5631_spol_mux_control = | |||
831 | static const char *rt5631_spor_src_sel[] = { | 820 | static const char *rt5631_spor_src_sel[] = { |
832 | "SPORMIX", "MONOIN_RX", "VDAC", "DACR"}; | 821 | "SPORMIX", "MONOIN_RX", "VDAC", "DACR"}; |
833 | 822 | ||
834 | static const SOC_ENUM_SINGLE_DECL( | 823 | static SOC_ENUM_SINGLE_DECL(rt5631_spor_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, |
835 | rt5631_spor_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | 824 | RT5631_SPK_R_MUX_SEL_SHIFT, rt5631_spor_src_sel); |
836 | RT5631_SPK_R_MUX_SEL_SHIFT, rt5631_spor_src_sel); | ||
837 | 825 | ||
838 | static const struct snd_kcontrol_new rt5631_spor_mux_control = | 826 | static const struct snd_kcontrol_new rt5631_spor_mux_control = |
839 | SOC_DAPM_ENUM("SPOR SRC", rt5631_spor_src_enum); | 827 | SOC_DAPM_ENUM("SPOR SRC", rt5631_spor_src_enum); |
@@ -841,9 +829,8 @@ static const struct snd_kcontrol_new rt5631_spor_mux_control = | |||
841 | /* MONO Input */ | 829 | /* MONO Input */ |
842 | static const char *rt5631_mono_src_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"}; | 830 | static const char *rt5631_mono_src_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"}; |
843 | 831 | ||
844 | static const SOC_ENUM_SINGLE_DECL( | 832 | static SOC_ENUM_SINGLE_DECL(rt5631_mono_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, |
845 | rt5631_mono_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | 833 | RT5631_MONO_MUX_SEL_SHIFT, rt5631_mono_src_sel); |
846 | RT5631_MONO_MUX_SEL_SHIFT, rt5631_mono_src_sel); | ||
847 | 834 | ||
848 | static const struct snd_kcontrol_new rt5631_mono_mux_control = | 835 | static const struct snd_kcontrol_new rt5631_mono_mux_control = |
849 | SOC_DAPM_ENUM("MONO SRC", rt5631_mono_src_enum); | 836 | SOC_DAPM_ENUM("MONO SRC", rt5631_mono_src_enum); |
@@ -851,9 +838,8 @@ static const struct snd_kcontrol_new rt5631_mono_mux_control = | |||
851 | /* Left HPO Input */ | 838 | /* Left HPO Input */ |
852 | static const char *rt5631_hpl_src_sel[] = {"Left HPVOL", "Left DAC"}; | 839 | static const char *rt5631_hpl_src_sel[] = {"Left HPVOL", "Left DAC"}; |
853 | 840 | ||
854 | static const SOC_ENUM_SINGLE_DECL( | 841 | static SOC_ENUM_SINGLE_DECL(rt5631_hpl_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, |
855 | rt5631_hpl_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | 842 | RT5631_HP_L_MUX_SEL_SHIFT, rt5631_hpl_src_sel); |
856 | RT5631_HP_L_MUX_SEL_SHIFT, rt5631_hpl_src_sel); | ||
857 | 843 | ||
858 | static const struct snd_kcontrol_new rt5631_hpl_mux_control = | 844 | static const struct snd_kcontrol_new rt5631_hpl_mux_control = |
859 | SOC_DAPM_ENUM("HPL SRC", rt5631_hpl_src_enum); | 845 | SOC_DAPM_ENUM("HPL SRC", rt5631_hpl_src_enum); |
@@ -861,9 +847,8 @@ static const struct snd_kcontrol_new rt5631_hpl_mux_control = | |||
861 | /* Right HPO Input */ | 847 | /* Right HPO Input */ |
862 | static const char *rt5631_hpr_src_sel[] = {"Right HPVOL", "Right DAC"}; | 848 | static const char *rt5631_hpr_src_sel[] = {"Right HPVOL", "Right DAC"}; |
863 | 849 | ||
864 | static const SOC_ENUM_SINGLE_DECL( | 850 | static SOC_ENUM_SINGLE_DECL(rt5631_hpr_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, |
865 | rt5631_hpr_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | 851 | RT5631_HP_R_MUX_SEL_SHIFT, rt5631_hpr_src_sel); |
866 | RT5631_HP_R_MUX_SEL_SHIFT, rt5631_hpr_src_sel); | ||
867 | 852 | ||
868 | static const struct snd_kcontrol_new rt5631_hpr_mux_control = | 853 | static const struct snd_kcontrol_new rt5631_hpr_mux_control = |
869 | SOC_DAPM_ENUM("HPR SRC", rt5631_hpr_src_enum); | 854 | SOC_DAPM_ENUM("HPR SRC", rt5631_hpr_src_enum); |
@@ -1585,15 +1570,6 @@ static int rt5631_probe(struct snd_soc_codec *codec) | |||
1585 | { | 1570 | { |
1586 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | 1571 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); |
1587 | unsigned int val; | 1572 | unsigned int val; |
1588 | int ret; | ||
1589 | |||
1590 | codec->control_data = rt5631->regmap; | ||
1591 | |||
1592 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1593 | if (ret != 0) { | ||
1594 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1595 | return ret; | ||
1596 | } | ||
1597 | 1573 | ||
1598 | val = rt5631_read_index(codec, RT5631_ADDA_MIXER_INTL_REG3); | 1574 | val = rt5631_read_index(codec, RT5631_ADDA_MIXER_INTL_REG3); |
1599 | if (val & 0x0002) | 1575 | if (val & 0x0002) |
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index a3fb41179636..0061ae6b6716 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c | |||
@@ -361,25 +361,24 @@ static unsigned int bst_tlv[] = { | |||
361 | static const char * const rt5640_data_select[] = { | 361 | static const char * const rt5640_data_select[] = { |
362 | "Normal", "left copy to right", "right copy to left", "Swap"}; | 362 | "Normal", "left copy to right", "right copy to left", "Swap"}; |
363 | 363 | ||
364 | static const SOC_ENUM_SINGLE_DECL(rt5640_if1_dac_enum, RT5640_DIG_INF_DATA, | 364 | static SOC_ENUM_SINGLE_DECL(rt5640_if1_dac_enum, RT5640_DIG_INF_DATA, |
365 | RT5640_IF1_DAC_SEL_SFT, rt5640_data_select); | 365 | RT5640_IF1_DAC_SEL_SFT, rt5640_data_select); |
366 | 366 | ||
367 | static const SOC_ENUM_SINGLE_DECL(rt5640_if1_adc_enum, RT5640_DIG_INF_DATA, | 367 | static SOC_ENUM_SINGLE_DECL(rt5640_if1_adc_enum, RT5640_DIG_INF_DATA, |
368 | RT5640_IF1_ADC_SEL_SFT, rt5640_data_select); | 368 | RT5640_IF1_ADC_SEL_SFT, rt5640_data_select); |
369 | 369 | ||
370 | static const SOC_ENUM_SINGLE_DECL(rt5640_if2_dac_enum, RT5640_DIG_INF_DATA, | 370 | static SOC_ENUM_SINGLE_DECL(rt5640_if2_dac_enum, RT5640_DIG_INF_DATA, |
371 | RT5640_IF2_DAC_SEL_SFT, rt5640_data_select); | 371 | RT5640_IF2_DAC_SEL_SFT, rt5640_data_select); |
372 | 372 | ||
373 | static const SOC_ENUM_SINGLE_DECL(rt5640_if2_adc_enum, RT5640_DIG_INF_DATA, | 373 | static SOC_ENUM_SINGLE_DECL(rt5640_if2_adc_enum, RT5640_DIG_INF_DATA, |
374 | RT5640_IF2_ADC_SEL_SFT, rt5640_data_select); | 374 | RT5640_IF2_ADC_SEL_SFT, rt5640_data_select); |
375 | 375 | ||
376 | /* Class D speaker gain ratio */ | 376 | /* Class D speaker gain ratio */ |
377 | static const char * const rt5640_clsd_spk_ratio[] = {"1.66x", "1.83x", "1.94x", | 377 | static const char * const rt5640_clsd_spk_ratio[] = {"1.66x", "1.83x", "1.94x", |
378 | "2x", "2.11x", "2.22x", "2.33x", "2.44x", "2.55x", "2.66x", "2.77x"}; | 378 | "2x", "2.11x", "2.22x", "2.33x", "2.44x", "2.55x", "2.66x", "2.77x"}; |
379 | 379 | ||
380 | static const SOC_ENUM_SINGLE_DECL( | 380 | static SOC_ENUM_SINGLE_DECL(rt5640_clsd_spk_ratio_enum, RT5640_CLS_D_OUT, |
381 | rt5640_clsd_spk_ratio_enum, RT5640_CLS_D_OUT, | 381 | RT5640_CLSD_RATIO_SFT, rt5640_clsd_spk_ratio); |
382 | RT5640_CLSD_RATIO_SFT, rt5640_clsd_spk_ratio); | ||
383 | 382 | ||
384 | static const struct snd_kcontrol_new rt5640_snd_controls[] = { | 383 | static const struct snd_kcontrol_new rt5640_snd_controls[] = { |
385 | /* Speaker Output Volume */ | 384 | /* Speaker Output Volume */ |
@@ -753,9 +752,8 @@ static const char * const rt5640_stereo_adc1_src[] = { | |||
753 | "DIG MIX", "ADC" | 752 | "DIG MIX", "ADC" |
754 | }; | 753 | }; |
755 | 754 | ||
756 | static const SOC_ENUM_SINGLE_DECL( | 755 | static SOC_ENUM_SINGLE_DECL(rt5640_stereo_adc1_enum, RT5640_STO_ADC_MIXER, |
757 | rt5640_stereo_adc1_enum, RT5640_STO_ADC_MIXER, | 756 | RT5640_ADC_1_SRC_SFT, rt5640_stereo_adc1_src); |
758 | RT5640_ADC_1_SRC_SFT, rt5640_stereo_adc1_src); | ||
759 | 757 | ||
760 | static const struct snd_kcontrol_new rt5640_sto_adc_1_mux = | 758 | static const struct snd_kcontrol_new rt5640_sto_adc_1_mux = |
761 | SOC_DAPM_ENUM("Stereo ADC1 Mux", rt5640_stereo_adc1_enum); | 759 | SOC_DAPM_ENUM("Stereo ADC1 Mux", rt5640_stereo_adc1_enum); |
@@ -764,9 +762,8 @@ static const char * const rt5640_stereo_adc2_src[] = { | |||
764 | "DMIC1", "DMIC2", "DIG MIX" | 762 | "DMIC1", "DMIC2", "DIG MIX" |
765 | }; | 763 | }; |
766 | 764 | ||
767 | static const SOC_ENUM_SINGLE_DECL( | 765 | static SOC_ENUM_SINGLE_DECL(rt5640_stereo_adc2_enum, RT5640_STO_ADC_MIXER, |
768 | rt5640_stereo_adc2_enum, RT5640_STO_ADC_MIXER, | 766 | RT5640_ADC_2_SRC_SFT, rt5640_stereo_adc2_src); |
769 | RT5640_ADC_2_SRC_SFT, rt5640_stereo_adc2_src); | ||
770 | 767 | ||
771 | static const struct snd_kcontrol_new rt5640_sto_adc_2_mux = | 768 | static const struct snd_kcontrol_new rt5640_sto_adc_2_mux = |
772 | SOC_DAPM_ENUM("Stereo ADC2 Mux", rt5640_stereo_adc2_enum); | 769 | SOC_DAPM_ENUM("Stereo ADC2 Mux", rt5640_stereo_adc2_enum); |
@@ -776,9 +773,8 @@ static const char * const rt5640_mono_adc_l1_src[] = { | |||
776 | "Mono DAC MIXL", "ADCL" | 773 | "Mono DAC MIXL", "ADCL" |
777 | }; | 774 | }; |
778 | 775 | ||
779 | static const SOC_ENUM_SINGLE_DECL( | 776 | static SOC_ENUM_SINGLE_DECL(rt5640_mono_adc_l1_enum, RT5640_MONO_ADC_MIXER, |
780 | rt5640_mono_adc_l1_enum, RT5640_MONO_ADC_MIXER, | 777 | RT5640_MONO_ADC_L1_SRC_SFT, rt5640_mono_adc_l1_src); |
781 | RT5640_MONO_ADC_L1_SRC_SFT, rt5640_mono_adc_l1_src); | ||
782 | 778 | ||
783 | static const struct snd_kcontrol_new rt5640_mono_adc_l1_mux = | 779 | static const struct snd_kcontrol_new rt5640_mono_adc_l1_mux = |
784 | SOC_DAPM_ENUM("Mono ADC1 left source", rt5640_mono_adc_l1_enum); | 780 | SOC_DAPM_ENUM("Mono ADC1 left source", rt5640_mono_adc_l1_enum); |
@@ -787,9 +783,8 @@ static const char * const rt5640_mono_adc_l2_src[] = { | |||
787 | "DMIC L1", "DMIC L2", "Mono DAC MIXL" | 783 | "DMIC L1", "DMIC L2", "Mono DAC MIXL" |
788 | }; | 784 | }; |
789 | 785 | ||
790 | static const SOC_ENUM_SINGLE_DECL( | 786 | static SOC_ENUM_SINGLE_DECL(rt5640_mono_adc_l2_enum, RT5640_MONO_ADC_MIXER, |
791 | rt5640_mono_adc_l2_enum, RT5640_MONO_ADC_MIXER, | 787 | RT5640_MONO_ADC_L2_SRC_SFT, rt5640_mono_adc_l2_src); |
792 | RT5640_MONO_ADC_L2_SRC_SFT, rt5640_mono_adc_l2_src); | ||
793 | 788 | ||
794 | static const struct snd_kcontrol_new rt5640_mono_adc_l2_mux = | 789 | static const struct snd_kcontrol_new rt5640_mono_adc_l2_mux = |
795 | SOC_DAPM_ENUM("Mono ADC2 left source", rt5640_mono_adc_l2_enum); | 790 | SOC_DAPM_ENUM("Mono ADC2 left source", rt5640_mono_adc_l2_enum); |
@@ -798,9 +793,8 @@ static const char * const rt5640_mono_adc_r1_src[] = { | |||
798 | "Mono DAC MIXR", "ADCR" | 793 | "Mono DAC MIXR", "ADCR" |
799 | }; | 794 | }; |
800 | 795 | ||
801 | static const SOC_ENUM_SINGLE_DECL( | 796 | static SOC_ENUM_SINGLE_DECL(rt5640_mono_adc_r1_enum, RT5640_MONO_ADC_MIXER, |
802 | rt5640_mono_adc_r1_enum, RT5640_MONO_ADC_MIXER, | 797 | RT5640_MONO_ADC_R1_SRC_SFT, rt5640_mono_adc_r1_src); |
803 | RT5640_MONO_ADC_R1_SRC_SFT, rt5640_mono_adc_r1_src); | ||
804 | 798 | ||
805 | static const struct snd_kcontrol_new rt5640_mono_adc_r1_mux = | 799 | static const struct snd_kcontrol_new rt5640_mono_adc_r1_mux = |
806 | SOC_DAPM_ENUM("Mono ADC1 right source", rt5640_mono_adc_r1_enum); | 800 | SOC_DAPM_ENUM("Mono ADC1 right source", rt5640_mono_adc_r1_enum); |
@@ -809,9 +803,8 @@ static const char * const rt5640_mono_adc_r2_src[] = { | |||
809 | "DMIC R1", "DMIC R2", "Mono DAC MIXR" | 803 | "DMIC R1", "DMIC R2", "Mono DAC MIXR" |
810 | }; | 804 | }; |
811 | 805 | ||
812 | static const SOC_ENUM_SINGLE_DECL( | 806 | static SOC_ENUM_SINGLE_DECL(rt5640_mono_adc_r2_enum, RT5640_MONO_ADC_MIXER, |
813 | rt5640_mono_adc_r2_enum, RT5640_MONO_ADC_MIXER, | 807 | RT5640_MONO_ADC_R2_SRC_SFT, rt5640_mono_adc_r2_src); |
814 | RT5640_MONO_ADC_R2_SRC_SFT, rt5640_mono_adc_r2_src); | ||
815 | 808 | ||
816 | static const struct snd_kcontrol_new rt5640_mono_adc_r2_mux = | 809 | static const struct snd_kcontrol_new rt5640_mono_adc_r2_mux = |
817 | SOC_DAPM_ENUM("Mono ADC2 right source", rt5640_mono_adc_r2_enum); | 810 | SOC_DAPM_ENUM("Mono ADC2 right source", rt5640_mono_adc_r2_enum); |
@@ -826,9 +819,9 @@ static int rt5640_dac_l2_values[] = { | |||
826 | 3, | 819 | 3, |
827 | }; | 820 | }; |
828 | 821 | ||
829 | static const SOC_VALUE_ENUM_SINGLE_DECL( | 822 | static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dac_l2_enum, |
830 | rt5640_dac_l2_enum, RT5640_DSP_PATH2, RT5640_DAC_L2_SEL_SFT, | 823 | RT5640_DSP_PATH2, RT5640_DAC_L2_SEL_SFT, |
831 | 0x3, rt5640_dac_l2_src, rt5640_dac_l2_values); | 824 | 0x3, rt5640_dac_l2_src, rt5640_dac_l2_values); |
832 | 825 | ||
833 | static const struct snd_kcontrol_new rt5640_dac_l2_mux = | 826 | static const struct snd_kcontrol_new rt5640_dac_l2_mux = |
834 | SOC_DAPM_VALUE_ENUM("DAC2 left channel source", rt5640_dac_l2_enum); | 827 | SOC_DAPM_VALUE_ENUM("DAC2 left channel source", rt5640_dac_l2_enum); |
@@ -841,9 +834,9 @@ static int rt5640_dac_r2_values[] = { | |||
841 | 0, | 834 | 0, |
842 | }; | 835 | }; |
843 | 836 | ||
844 | static const SOC_VALUE_ENUM_SINGLE_DECL( | 837 | static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dac_r2_enum, |
845 | rt5640_dac_r2_enum, RT5640_DSP_PATH2, RT5640_DAC_R2_SEL_SFT, | 838 | RT5640_DSP_PATH2, RT5640_DAC_R2_SEL_SFT, |
846 | 0x3, rt5640_dac_r2_src, rt5640_dac_r2_values); | 839 | 0x3, rt5640_dac_r2_src, rt5640_dac_r2_values); |
847 | 840 | ||
848 | static const struct snd_kcontrol_new rt5640_dac_r2_mux = | 841 | static const struct snd_kcontrol_new rt5640_dac_r2_mux = |
849 | SOC_DAPM_ENUM("DAC2 right channel source", rt5640_dac_r2_enum); | 842 | SOC_DAPM_ENUM("DAC2 right channel source", rt5640_dac_r2_enum); |
@@ -860,9 +853,10 @@ static int rt5640_dai_iis_map_values[] = { | |||
860 | 7, | 853 | 7, |
861 | }; | 854 | }; |
862 | 855 | ||
863 | static const SOC_VALUE_ENUM_SINGLE_DECL( | 856 | static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dai_iis_map_enum, |
864 | rt5640_dai_iis_map_enum, RT5640_I2S1_SDP, RT5640_I2S_IF_SFT, | 857 | RT5640_I2S1_SDP, RT5640_I2S_IF_SFT, |
865 | 0x7, rt5640_dai_iis_map, rt5640_dai_iis_map_values); | 858 | 0x7, rt5640_dai_iis_map, |
859 | rt5640_dai_iis_map_values); | ||
866 | 860 | ||
867 | static const struct snd_kcontrol_new rt5640_dai_mux = | 861 | static const struct snd_kcontrol_new rt5640_dai_mux = |
868 | SOC_DAPM_VALUE_ENUM("DAI select", rt5640_dai_iis_map_enum); | 862 | SOC_DAPM_VALUE_ENUM("DAI select", rt5640_dai_iis_map_enum); |
@@ -872,9 +866,8 @@ static const char * const rt5640_sdi_sel[] = { | |||
872 | "IF1", "IF2" | 866 | "IF1", "IF2" |
873 | }; | 867 | }; |
874 | 868 | ||
875 | static const SOC_ENUM_SINGLE_DECL( | 869 | static SOC_ENUM_SINGLE_DECL(rt5640_sdi_sel_enum, RT5640_I2S2_SDP, |
876 | rt5640_sdi_sel_enum, RT5640_I2S2_SDP, | 870 | RT5640_I2S2_SDI_SFT, rt5640_sdi_sel); |
877 | RT5640_I2S2_SDI_SFT, rt5640_sdi_sel); | ||
878 | 871 | ||
879 | static const struct snd_kcontrol_new rt5640_sdi_mux = | 872 | static const struct snd_kcontrol_new rt5640_sdi_mux = |
880 | SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); | 873 | SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); |
@@ -1601,8 +1594,7 @@ static int get_clk_info(int sclk, int rate) | |||
1601 | static int rt5640_hw_params(struct snd_pcm_substream *substream, | 1594 | static int rt5640_hw_params(struct snd_pcm_substream *substream, |
1602 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 1595 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
1603 | { | 1596 | { |
1604 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1597 | struct snd_soc_codec *codec = dai->codec; |
1605 | struct snd_soc_codec *codec = rtd->codec; | ||
1606 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | 1598 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); |
1607 | unsigned int val_len = 0, val_clk, mask_clk; | 1599 | unsigned int val_len = 0, val_clk, mask_clk; |
1608 | int dai_sel, pre_div, bclk_ms, frame_size; | 1600 | int dai_sel, pre_div, bclk_ms, frame_size; |
@@ -1943,16 +1935,8 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec, | |||
1943 | static int rt5640_probe(struct snd_soc_codec *codec) | 1935 | static int rt5640_probe(struct snd_soc_codec *codec) |
1944 | { | 1936 | { |
1945 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | 1937 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); |
1946 | int ret; | ||
1947 | 1938 | ||
1948 | rt5640->codec = codec; | 1939 | rt5640->codec = codec; |
1949 | codec->control_data = rt5640->regmap; | ||
1950 | |||
1951 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1952 | if (ret != 0) { | ||
1953 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1954 | return ret; | ||
1955 | } | ||
1956 | 1940 | ||
1957 | codec->dapm.idle_bias_off = 1; | 1941 | codec->dapm.idle_bias_off = 1; |
1958 | rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1942 | rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); |
@@ -2093,6 +2077,7 @@ MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id); | |||
2093 | #ifdef CONFIG_ACPI | 2077 | #ifdef CONFIG_ACPI |
2094 | static struct acpi_device_id rt5640_acpi_match[] = { | 2078 | static struct acpi_device_id rt5640_acpi_match[] = { |
2095 | { "INT33CA", 0 }, | 2079 | { "INT33CA", 0 }, |
2080 | { "10EC5640", 0 }, | ||
2096 | { }, | 2081 | { }, |
2097 | }; | 2082 | }; |
2098 | MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match); | 2083 | MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match); |
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 0fcbe90f3ef2..d3ed1be5a186 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -187,8 +187,9 @@ static const char *adc_mux_text[] = { | |||
187 | "MIC_IN", "LINE_IN" | 187 | "MIC_IN", "LINE_IN" |
188 | }; | 188 | }; |
189 | 189 | ||
190 | static const struct soc_enum adc_enum = | 190 | static SOC_ENUM_SINGLE_DECL(adc_enum, |
191 | SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 2, 2, adc_mux_text); | 191 | SGTL5000_CHIP_ANA_CTRL, 2, |
192 | adc_mux_text); | ||
192 | 193 | ||
193 | static const struct snd_kcontrol_new adc_mux = | 194 | static const struct snd_kcontrol_new adc_mux = |
194 | SOC_DAPM_ENUM("Capture Mux", adc_enum); | 195 | SOC_DAPM_ENUM("Capture Mux", adc_enum); |
@@ -198,8 +199,9 @@ static const char *dac_mux_text[] = { | |||
198 | "DAC", "LINE_IN" | 199 | "DAC", "LINE_IN" |
199 | }; | 200 | }; |
200 | 201 | ||
201 | static const struct soc_enum dac_enum = | 202 | static SOC_ENUM_SINGLE_DECL(dac_enum, |
202 | SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 6, 2, dac_mux_text); | 203 | SGTL5000_CHIP_ANA_CTRL, 6, |
204 | dac_mux_text); | ||
203 | 205 | ||
204 | static const struct snd_kcontrol_new dac_mux = | 206 | static const struct snd_kcontrol_new dac_mux = |
205 | SOC_DAPM_ENUM("Headphone Mux", dac_enum); | 207 | SOC_DAPM_ENUM("Headphone Mux", dac_enum); |
@@ -1350,14 +1352,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) | |||
1350 | int ret; | 1352 | int ret; |
1351 | struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); | 1353 | struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); |
1352 | 1354 | ||
1353 | /* setup i2c data ops */ | ||
1354 | codec->control_data = sgtl5000->regmap; | ||
1355 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | ||
1356 | if (ret < 0) { | ||
1357 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1358 | return ret; | ||
1359 | } | ||
1360 | |||
1361 | ret = sgtl5000_enable_regulators(codec); | 1355 | ret = sgtl5000_enable_regulators(codec); |
1362 | if (ret) | 1356 | if (ret) |
1363 | return ret; | 1357 | return ret; |
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 52e7cb08434b..244c097cd905 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <sound/pcm.h> | 22 | #include <sound/pcm.h> |
23 | #include <sound/pcm_params.h> | 23 | #include <sound/pcm_params.h> |
24 | #include <linux/regmap.h> | ||
24 | #include <sound/soc.h> | 25 | #include <sound/soc.h> |
25 | #include <sound/initval.h> | 26 | #include <sound/initval.h> |
26 | 27 | ||
@@ -209,8 +210,9 @@ out: | |||
209 | 210 | ||
210 | static int si476x_codec_probe(struct snd_soc_codec *codec) | 211 | static int si476x_codec_probe(struct snd_soc_codec *codec) |
211 | { | 212 | { |
212 | codec->control_data = dev_get_regmap(codec->dev->parent, NULL); | 213 | struct regmap *regmap = dev_get_regmap(codec->dev->parent, NULL); |
213 | return 0; | 214 | |
215 | return snd_soc_codec_set_cache_io(codec, regmap); | ||
214 | } | 216 | } |
215 | 217 | ||
216 | static struct snd_soc_dai_ops si476x_dai_ops = { | 218 | static struct snd_soc_dai_ops si476x_dai_ops = { |
diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c new file mode 100644 index 000000000000..90e3a228bae4 --- /dev/null +++ b/sound/soc/codecs/sirf-audio-codec.c | |||
@@ -0,0 +1,533 @@ | |||
1 | /* | ||
2 | * SiRF audio codec driver | ||
3 | * | ||
4 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/pm_runtime.h> | ||
12 | #include <linux/of.h> | ||
13 | #include <linux/of_device.h> | ||
14 | #include <linux/clk.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/regmap.h> | ||
18 | #include <sound/core.h> | ||
19 | #include <sound/pcm.h> | ||
20 | #include <sound/pcm_params.h> | ||
21 | #include <sound/initval.h> | ||
22 | #include <sound/tlv.h> | ||
23 | #include <sound/soc.h> | ||
24 | #include <sound/dmaengine_pcm.h> | ||
25 | |||
26 | #include "sirf-audio-codec.h" | ||
27 | |||
28 | struct sirf_audio_codec { | ||
29 | struct clk *clk; | ||
30 | struct regmap *regmap; | ||
31 | u32 reg_ctrl0, reg_ctrl1; | ||
32 | }; | ||
33 | |||
34 | static const char * const input_mode_mux[] = {"Single-ended", | ||
35 | "Differential"}; | ||
36 | |||
37 | static const struct soc_enum input_mode_mux_enum = | ||
38 | SOC_ENUM_SINGLE(AUDIO_IC_CODEC_CTRL1, 4, 2, input_mode_mux); | ||
39 | |||
40 | static const struct snd_kcontrol_new sirf_audio_codec_input_mode_control = | ||
41 | SOC_DAPM_ENUM("Route", input_mode_mux_enum); | ||
42 | |||
43 | static const DECLARE_TLV_DB_SCALE(playback_vol_tlv, -12400, 100, 0); | ||
44 | static const DECLARE_TLV_DB_SCALE(capture_vol_tlv_prima2, 500, 100, 0); | ||
45 | static const DECLARE_TLV_DB_RANGE(capture_vol_tlv_atlas6, | ||
46 | 0, 7, TLV_DB_SCALE_ITEM(-100, 100, 0), | ||
47 | 0x22, 0x3F, TLV_DB_SCALE_ITEM(700, 100, 0), | ||
48 | ); | ||
49 | |||
50 | static struct snd_kcontrol_new volume_controls_atlas6[] = { | ||
51 | SOC_DOUBLE_TLV("Playback Volume", AUDIO_IC_CODEC_CTRL0, 21, 14, | ||
52 | 0x7F, 0, playback_vol_tlv), | ||
53 | SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 16, 10, | ||
54 | 0x3F, 0, capture_vol_tlv_atlas6), | ||
55 | }; | ||
56 | |||
57 | static struct snd_kcontrol_new volume_controls_prima2[] = { | ||
58 | SOC_DOUBLE_TLV("Speaker Volume", AUDIO_IC_CODEC_CTRL0, 21, 14, | ||
59 | 0x7F, 0, playback_vol_tlv), | ||
60 | SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 15, 10, | ||
61 | 0x1F, 0, capture_vol_tlv_prima2), | ||
62 | }; | ||
63 | |||
64 | static struct snd_kcontrol_new left_input_path_controls[] = { | ||
65 | SOC_DAPM_SINGLE("Line Left Switch", AUDIO_IC_CODEC_CTRL1, 6, 1, 0), | ||
66 | SOC_DAPM_SINGLE("Mic Left Switch", AUDIO_IC_CODEC_CTRL1, 3, 1, 0), | ||
67 | }; | ||
68 | |||
69 | static struct snd_kcontrol_new right_input_path_controls[] = { | ||
70 | SOC_DAPM_SINGLE("Line Right Switch", AUDIO_IC_CODEC_CTRL1, 5, 1, 0), | ||
71 | SOC_DAPM_SINGLE("Mic Right Switch", AUDIO_IC_CODEC_CTRL1, 2, 1, 0), | ||
72 | }; | ||
73 | |||
74 | static struct snd_kcontrol_new left_dac_to_hp_left_amp_switch_control = | ||
75 | SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 9, 1, 0); | ||
76 | |||
77 | static struct snd_kcontrol_new left_dac_to_hp_right_amp_switch_control = | ||
78 | SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 8, 1, 0); | ||
79 | |||
80 | static struct snd_kcontrol_new right_dac_to_hp_left_amp_switch_control = | ||
81 | SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 7, 1, 0); | ||
82 | |||
83 | static struct snd_kcontrol_new right_dac_to_hp_right_amp_switch_control = | ||
84 | SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 6, 1, 0); | ||
85 | |||
86 | static struct snd_kcontrol_new left_dac_to_speaker_lineout_switch_control = | ||
87 | SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 11, 1, 0); | ||
88 | |||
89 | static struct snd_kcontrol_new right_dac_to_speaker_lineout_switch_control = | ||
90 | SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 10, 1, 0); | ||
91 | |||
92 | /* After enable adc, Delay 200ms to avoid pop noise */ | ||
93 | static int adc_enable_delay_event(struct snd_soc_dapm_widget *w, | ||
94 | struct snd_kcontrol *kcontrol, int event) | ||
95 | { | ||
96 | switch (event) { | ||
97 | case SND_SOC_DAPM_POST_PMU: | ||
98 | msleep(200); | ||
99 | break; | ||
100 | default: | ||
101 | break; | ||
102 | } | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static void enable_and_reset_codec(struct regmap *regmap, | ||
108 | u32 codec_enable_bits, u32 codec_reset_bits) | ||
109 | { | ||
110 | regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1, | ||
111 | codec_enable_bits | codec_reset_bits, | ||
112 | codec_enable_bits | ~codec_reset_bits); | ||
113 | msleep(20); | ||
114 | regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1, | ||
115 | codec_reset_bits, codec_reset_bits); | ||
116 | } | ||
117 | |||
118 | static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w, | ||
119 | struct snd_kcontrol *kcontrol, int event) | ||
120 | { | ||
121 | #define ATLAS6_CODEC_ENABLE_BITS (1 << 29) | ||
122 | #define ATLAS6_CODEC_RESET_BITS (1 << 28) | ||
123 | struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(w->codec->dev); | ||
124 | switch (event) { | ||
125 | case SND_SOC_DAPM_PRE_PMU: | ||
126 | enable_and_reset_codec(sirf_audio_codec->regmap, | ||
127 | ATLAS6_CODEC_ENABLE_BITS, ATLAS6_CODEC_RESET_BITS); | ||
128 | break; | ||
129 | case SND_SOC_DAPM_POST_PMD: | ||
130 | regmap_update_bits(sirf_audio_codec->regmap, | ||
131 | AUDIO_IC_CODEC_CTRL1, ATLAS6_CODEC_ENABLE_BITS, | ||
132 | ~ATLAS6_CODEC_ENABLE_BITS); | ||
133 | break; | ||
134 | default: | ||
135 | break; | ||
136 | } | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w, | ||
142 | struct snd_kcontrol *kcontrol, int event) | ||
143 | { | ||
144 | #define PRIMA2_CODEC_ENABLE_BITS (1 << 27) | ||
145 | #define PRIMA2_CODEC_RESET_BITS (1 << 26) | ||
146 | struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(w->codec->dev); | ||
147 | switch (event) { | ||
148 | case SND_SOC_DAPM_POST_PMU: | ||
149 | enable_and_reset_codec(sirf_audio_codec->regmap, | ||
150 | PRIMA2_CODEC_ENABLE_BITS, PRIMA2_CODEC_RESET_BITS); | ||
151 | break; | ||
152 | case SND_SOC_DAPM_POST_PMD: | ||
153 | regmap_update_bits(sirf_audio_codec->regmap, | ||
154 | AUDIO_IC_CODEC_CTRL1, PRIMA2_CODEC_ENABLE_BITS, | ||
155 | ~PRIMA2_CODEC_ENABLE_BITS); | ||
156 | break; | ||
157 | default: | ||
158 | break; | ||
159 | } | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static const struct snd_soc_dapm_widget atlas6_output_driver_dapm_widgets[] = { | ||
165 | SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1, | ||
166 | 25, 0, NULL, 0), | ||
167 | SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1, | ||
168 | 26, 0, NULL, 0), | ||
169 | SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1, | ||
170 | 27, 0, NULL, 0), | ||
171 | }; | ||
172 | |||
173 | static const struct snd_soc_dapm_widget prima2_output_driver_dapm_widgets[] = { | ||
174 | SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1, | ||
175 | 23, 0, NULL, 0), | ||
176 | SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1, | ||
177 | 24, 0, NULL, 0), | ||
178 | SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1, | ||
179 | 25, 0, NULL, 0), | ||
180 | }; | ||
181 | |||
182 | static const struct snd_soc_dapm_widget atlas6_codec_clock_dapm_widget = | ||
183 | SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0, | ||
184 | atlas6_codec_enable_and_reset_event, | ||
185 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD); | ||
186 | |||
187 | static const struct snd_soc_dapm_widget prima2_codec_clock_dapm_widget = | ||
188 | SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0, | ||
189 | prima2_codec_enable_and_reset_event, | ||
190 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD); | ||
191 | |||
192 | static const struct snd_soc_dapm_widget sirf_audio_codec_dapm_widgets[] = { | ||
193 | SND_SOC_DAPM_DAC("DAC left", NULL, AUDIO_IC_CODEC_CTRL0, 1, 0), | ||
194 | SND_SOC_DAPM_DAC("DAC right", NULL, AUDIO_IC_CODEC_CTRL0, 0, 0), | ||
195 | SND_SOC_DAPM_SWITCH("Left dac to hp left amp", SND_SOC_NOPM, 0, 0, | ||
196 | &left_dac_to_hp_left_amp_switch_control), | ||
197 | SND_SOC_DAPM_SWITCH("Left dac to hp right amp", SND_SOC_NOPM, 0, 0, | ||
198 | &left_dac_to_hp_right_amp_switch_control), | ||
199 | SND_SOC_DAPM_SWITCH("Right dac to hp left amp", SND_SOC_NOPM, 0, 0, | ||
200 | &right_dac_to_hp_left_amp_switch_control), | ||
201 | SND_SOC_DAPM_SWITCH("Right dac to hp right amp", SND_SOC_NOPM, 0, 0, | ||
202 | &right_dac_to_hp_right_amp_switch_control), | ||
203 | SND_SOC_DAPM_OUT_DRV("HP amp left driver", AUDIO_IC_CODEC_CTRL0, 3, 0, | ||
204 | NULL, 0), | ||
205 | SND_SOC_DAPM_OUT_DRV("HP amp right driver", AUDIO_IC_CODEC_CTRL0, 3, 0, | ||
206 | NULL, 0), | ||
207 | |||
208 | SND_SOC_DAPM_SWITCH("Left dac to speaker lineout", SND_SOC_NOPM, 0, 0, | ||
209 | &left_dac_to_speaker_lineout_switch_control), | ||
210 | SND_SOC_DAPM_SWITCH("Right dac to speaker lineout", SND_SOC_NOPM, 0, 0, | ||
211 | &right_dac_to_speaker_lineout_switch_control), | ||
212 | SND_SOC_DAPM_OUT_DRV("Speaker amp driver", AUDIO_IC_CODEC_CTRL0, 4, 0, | ||
213 | NULL, 0), | ||
214 | |||
215 | SND_SOC_DAPM_OUTPUT("HPOUTL"), | ||
216 | SND_SOC_DAPM_OUTPUT("HPOUTR"), | ||
217 | SND_SOC_DAPM_OUTPUT("SPKOUT"), | ||
218 | |||
219 | SND_SOC_DAPM_ADC_E("ADC left", NULL, AUDIO_IC_CODEC_CTRL1, 8, 0, | ||
220 | adc_enable_delay_event, SND_SOC_DAPM_POST_PMU), | ||
221 | SND_SOC_DAPM_ADC_E("ADC right", NULL, AUDIO_IC_CODEC_CTRL1, 7, 0, | ||
222 | adc_enable_delay_event, SND_SOC_DAPM_POST_PMU), | ||
223 | SND_SOC_DAPM_MIXER("Left PGA mixer", AUDIO_IC_CODEC_CTRL1, 1, 0, | ||
224 | &left_input_path_controls[0], | ||
225 | ARRAY_SIZE(left_input_path_controls)), | ||
226 | SND_SOC_DAPM_MIXER("Right PGA mixer", AUDIO_IC_CODEC_CTRL1, 0, 0, | ||
227 | &right_input_path_controls[0], | ||
228 | ARRAY_SIZE(right_input_path_controls)), | ||
229 | |||
230 | SND_SOC_DAPM_MUX("Mic input mode mux", SND_SOC_NOPM, 0, 0, | ||
231 | &sirf_audio_codec_input_mode_control), | ||
232 | SND_SOC_DAPM_MICBIAS("Mic Bias", AUDIO_IC_CODEC_PWR, 3, 0), | ||
233 | SND_SOC_DAPM_INPUT("MICIN1"), | ||
234 | SND_SOC_DAPM_INPUT("MICIN2"), | ||
235 | SND_SOC_DAPM_INPUT("LINEIN1"), | ||
236 | SND_SOC_DAPM_INPUT("LINEIN2"), | ||
237 | |||
238 | SND_SOC_DAPM_SUPPLY("HSL Phase Opposite", AUDIO_IC_CODEC_CTRL0, | ||
239 | 30, 0, NULL, 0), | ||
240 | }; | ||
241 | |||
242 | static const struct snd_soc_dapm_route sirf_audio_codec_map[] = { | ||
243 | {"SPKOUT", NULL, "Speaker Driver"}, | ||
244 | {"Speaker Driver", NULL, "Speaker amp driver"}, | ||
245 | {"Speaker amp driver", NULL, "Left dac to speaker lineout"}, | ||
246 | {"Speaker amp driver", NULL, "Right dac to speaker lineout"}, | ||
247 | {"Left dac to speaker lineout", "Switch", "DAC left"}, | ||
248 | {"Right dac to speaker lineout", "Switch", "DAC right"}, | ||
249 | {"HPOUTL", NULL, "HP Left Driver"}, | ||
250 | {"HPOUTR", NULL, "HP Right Driver"}, | ||
251 | {"HP Left Driver", NULL, "HP amp left driver"}, | ||
252 | {"HP Right Driver", NULL, "HP amp right driver"}, | ||
253 | {"HP amp left driver", NULL, "Right dac to hp left amp"}, | ||
254 | {"HP amp right driver", NULL , "Right dac to hp right amp"}, | ||
255 | {"HP amp left driver", NULL, "Left dac to hp left amp"}, | ||
256 | {"HP amp right driver", NULL , "Right dac to hp right amp"}, | ||
257 | {"Right dac to hp left amp", "Switch", "DAC left"}, | ||
258 | {"Right dac to hp right amp", "Switch", "DAC right"}, | ||
259 | {"Left dac to hp left amp", "Switch", "DAC left"}, | ||
260 | {"Left dac to hp right amp", "Switch", "DAC right"}, | ||
261 | {"DAC left", NULL, "codecclk"}, | ||
262 | {"DAC right", NULL, "codecclk"}, | ||
263 | {"DAC left", NULL, "Playback"}, | ||
264 | {"DAC right", NULL, "Playback"}, | ||
265 | {"DAC left", NULL, "HSL Phase Opposite"}, | ||
266 | {"DAC right", NULL, "HSL Phase Opposite"}, | ||
267 | |||
268 | {"Capture", NULL, "ADC left"}, | ||
269 | {"Capture", NULL, "ADC right"}, | ||
270 | {"ADC left", NULL, "codecclk"}, | ||
271 | {"ADC right", NULL, "codecclk"}, | ||
272 | {"ADC left", NULL, "Left PGA mixer"}, | ||
273 | {"ADC right", NULL, "Right PGA mixer"}, | ||
274 | {"Left PGA mixer", "Line Left Switch", "LINEIN2"}, | ||
275 | {"Right PGA mixer", "Line Right Switch", "LINEIN1"}, | ||
276 | {"Left PGA mixer", "Mic Left Switch", "MICIN2"}, | ||
277 | {"Right PGA mixer", "Mic Right Switch", "Mic input mode mux"}, | ||
278 | {"Mic input mode mux", "Single-ended", "MICIN1"}, | ||
279 | {"Mic input mode mux", "Differential", "MICIN1"}, | ||
280 | }; | ||
281 | |||
282 | static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, | ||
283 | int cmd, | ||
284 | struct snd_soc_dai *dai) | ||
285 | { | ||
286 | int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | ||
287 | struct snd_soc_codec *codec = dai->codec; | ||
288 | u32 val = 0; | ||
289 | |||
290 | /* | ||
291 | * This is a workaround, When stop playback, | ||
292 | * need disable HP amp, avoid the current noise. | ||
293 | */ | ||
294 | switch (cmd) { | ||
295 | case SNDRV_PCM_TRIGGER_STOP: | ||
296 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
297 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
298 | break; | ||
299 | case SNDRV_PCM_TRIGGER_START: | ||
300 | case SNDRV_PCM_TRIGGER_RESUME: | ||
301 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
302 | if (playback) | ||
303 | val = IC_HSLEN | IC_HSREN; | ||
304 | break; | ||
305 | default: | ||
306 | return -EINVAL; | ||
307 | } | ||
308 | |||
309 | if (playback) | ||
310 | snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, | ||
311 | IC_HSLEN | IC_HSREN, val); | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | struct snd_soc_dai_ops sirf_audio_codec_dai_ops = { | ||
316 | .trigger = sirf_audio_codec_trigger, | ||
317 | }; | ||
318 | |||
319 | struct snd_soc_dai_driver sirf_audio_codec_dai = { | ||
320 | .name = "sirf-audio-codec", | ||
321 | .playback = { | ||
322 | .stream_name = "Playback", | ||
323 | .channels_min = 2, | ||
324 | .channels_max = 2, | ||
325 | .rates = SNDRV_PCM_RATE_48000, | ||
326 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
327 | }, | ||
328 | .capture = { | ||
329 | .stream_name = "Capture", | ||
330 | .channels_min = 1, | ||
331 | .channels_max = 2, | ||
332 | .rates = SNDRV_PCM_RATE_48000, | ||
333 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
334 | }, | ||
335 | .ops = &sirf_audio_codec_dai_ops, | ||
336 | }; | ||
337 | |||
338 | static int sirf_audio_codec_probe(struct snd_soc_codec *codec) | ||
339 | { | ||
340 | int ret; | ||
341 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
342 | struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec); | ||
343 | |||
344 | pm_runtime_enable(codec->dev); | ||
345 | codec->control_data = sirf_audio_codec->regmap; | ||
346 | |||
347 | ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); | ||
348 | if (ret != 0) { | ||
349 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
350 | return ret; | ||
351 | } | ||
352 | |||
353 | if (of_device_is_compatible(codec->dev->of_node, "sirf,prima2-audio-codec")) { | ||
354 | snd_soc_dapm_new_controls(dapm, | ||
355 | prima2_output_driver_dapm_widgets, | ||
356 | ARRAY_SIZE(prima2_output_driver_dapm_widgets)); | ||
357 | snd_soc_dapm_new_controls(dapm, | ||
358 | &prima2_codec_clock_dapm_widget, 1); | ||
359 | return snd_soc_add_codec_controls(codec, | ||
360 | volume_controls_prima2, | ||
361 | ARRAY_SIZE(volume_controls_prima2)); | ||
362 | } | ||
363 | if (of_device_is_compatible(codec->dev->of_node, "sirf,atlas6-audio-codec")) { | ||
364 | snd_soc_dapm_new_controls(dapm, | ||
365 | atlas6_output_driver_dapm_widgets, | ||
366 | ARRAY_SIZE(atlas6_output_driver_dapm_widgets)); | ||
367 | snd_soc_dapm_new_controls(dapm, | ||
368 | &atlas6_codec_clock_dapm_widget, 1); | ||
369 | return snd_soc_add_codec_controls(codec, | ||
370 | volume_controls_atlas6, | ||
371 | ARRAY_SIZE(volume_controls_atlas6)); | ||
372 | } | ||
373 | |||
374 | return -EINVAL; | ||
375 | } | ||
376 | |||
377 | static int sirf_audio_codec_remove(struct snd_soc_codec *codec) | ||
378 | { | ||
379 | pm_runtime_disable(codec->dev); | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static struct snd_soc_codec_driver soc_codec_device_sirf_audio_codec = { | ||
384 | .probe = sirf_audio_codec_probe, | ||
385 | .remove = sirf_audio_codec_remove, | ||
386 | .dapm_widgets = sirf_audio_codec_dapm_widgets, | ||
387 | .num_dapm_widgets = ARRAY_SIZE(sirf_audio_codec_dapm_widgets), | ||
388 | .dapm_routes = sirf_audio_codec_map, | ||
389 | .num_dapm_routes = ARRAY_SIZE(sirf_audio_codec_map), | ||
390 | .idle_bias_off = true, | ||
391 | }; | ||
392 | |||
393 | static const struct of_device_id sirf_audio_codec_of_match[] = { | ||
394 | { .compatible = "sirf,prima2-audio-codec" }, | ||
395 | { .compatible = "sirf,atlas6-audio-codec" }, | ||
396 | {} | ||
397 | }; | ||
398 | MODULE_DEVICE_TABLE(of, sirf_audio_codec_of_match); | ||
399 | |||
400 | static const struct regmap_config sirf_audio_codec_regmap_config = { | ||
401 | .reg_bits = 32, | ||
402 | .reg_stride = 4, | ||
403 | .val_bits = 32, | ||
404 | .max_register = AUDIO_IC_CODEC_CTRL3, | ||
405 | .cache_type = REGCACHE_NONE, | ||
406 | }; | ||
407 | |||
408 | static int sirf_audio_codec_driver_probe(struct platform_device *pdev) | ||
409 | { | ||
410 | int ret; | ||
411 | struct sirf_audio_codec *sirf_audio_codec; | ||
412 | void __iomem *base; | ||
413 | struct resource *mem_res; | ||
414 | const struct of_device_id *match; | ||
415 | |||
416 | match = of_match_node(sirf_audio_codec_of_match, pdev->dev.of_node); | ||
417 | |||
418 | sirf_audio_codec = devm_kzalloc(&pdev->dev, | ||
419 | sizeof(struct sirf_audio_codec), GFP_KERNEL); | ||
420 | if (!sirf_audio_codec) | ||
421 | return -ENOMEM; | ||
422 | |||
423 | platform_set_drvdata(pdev, sirf_audio_codec); | ||
424 | |||
425 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
426 | base = devm_ioremap_resource(&pdev->dev, mem_res); | ||
427 | if (base == NULL) | ||
428 | return -ENOMEM; | ||
429 | |||
430 | sirf_audio_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base, | ||
431 | &sirf_audio_codec_regmap_config); | ||
432 | if (IS_ERR(sirf_audio_codec->regmap)) | ||
433 | return PTR_ERR(sirf_audio_codec->regmap); | ||
434 | |||
435 | sirf_audio_codec->clk = devm_clk_get(&pdev->dev, NULL); | ||
436 | if (IS_ERR(sirf_audio_codec->clk)) { | ||
437 | dev_err(&pdev->dev, "Get clock failed.\n"); | ||
438 | return PTR_ERR(sirf_audio_codec->clk); | ||
439 | } | ||
440 | |||
441 | ret = clk_prepare_enable(sirf_audio_codec->clk); | ||
442 | if (ret) { | ||
443 | dev_err(&pdev->dev, "Enable clock failed.\n"); | ||
444 | return ret; | ||
445 | } | ||
446 | |||
447 | ret = snd_soc_register_codec(&(pdev->dev), | ||
448 | &soc_codec_device_sirf_audio_codec, | ||
449 | &sirf_audio_codec_dai, 1); | ||
450 | if (ret) { | ||
451 | dev_err(&pdev->dev, "Register Audio Codec dai failed.\n"); | ||
452 | goto err_clk_put; | ||
453 | } | ||
454 | |||
455 | /* | ||
456 | * Always open charge pump, if not, when the charge pump closed the | ||
457 | * adc will not stable | ||
458 | */ | ||
459 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, | ||
460 | IC_CPFREQ, IC_CPFREQ); | ||
461 | |||
462 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas6-audio-codec")) | ||
463 | regmap_update_bits(sirf_audio_codec->regmap, | ||
464 | AUDIO_IC_CODEC_CTRL0, IC_CPEN, IC_CPEN); | ||
465 | return 0; | ||
466 | |||
467 | err_clk_put: | ||
468 | clk_disable_unprepare(sirf_audio_codec->clk); | ||
469 | return ret; | ||
470 | } | ||
471 | |||
472 | static int sirf_audio_codec_driver_remove(struct platform_device *pdev) | ||
473 | { | ||
474 | struct sirf_audio_codec *sirf_audio_codec = platform_get_drvdata(pdev); | ||
475 | |||
476 | clk_disable_unprepare(sirf_audio_codec->clk); | ||
477 | snd_soc_unregister_codec(&(pdev->dev)); | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | #ifdef CONFIG_PM_SLEEP | ||
483 | static int sirf_audio_codec_suspend(struct device *dev) | ||
484 | { | ||
485 | struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev); | ||
486 | |||
487 | regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, | ||
488 | &sirf_audio_codec->reg_ctrl0); | ||
489 | regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1, | ||
490 | &sirf_audio_codec->reg_ctrl1); | ||
491 | clk_disable_unprepare(sirf_audio_codec->clk); | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | static int sirf_audio_codec_resume(struct device *dev) | ||
497 | { | ||
498 | struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev); | ||
499 | int ret; | ||
500 | |||
501 | ret = clk_prepare_enable(sirf_audio_codec->clk); | ||
502 | if (ret) | ||
503 | return ret; | ||
504 | |||
505 | regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, | ||
506 | sirf_audio_codec->reg_ctrl0); | ||
507 | regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1, | ||
508 | sirf_audio_codec->reg_ctrl1); | ||
509 | |||
510 | return 0; | ||
511 | } | ||
512 | #endif | ||
513 | |||
514 | static const struct dev_pm_ops sirf_audio_codec_pm_ops = { | ||
515 | SET_SYSTEM_SLEEP_PM_OPS(sirf_audio_codec_suspend, sirf_audio_codec_resume) | ||
516 | }; | ||
517 | |||
518 | static struct platform_driver sirf_audio_codec_driver = { | ||
519 | .driver = { | ||
520 | .name = "sirf-audio-codec", | ||
521 | .owner = THIS_MODULE, | ||
522 | .of_match_table = sirf_audio_codec_of_match, | ||
523 | .pm = &sirf_audio_codec_pm_ops, | ||
524 | }, | ||
525 | .probe = sirf_audio_codec_driver_probe, | ||
526 | .remove = sirf_audio_codec_driver_remove, | ||
527 | }; | ||
528 | |||
529 | module_platform_driver(sirf_audio_codec_driver); | ||
530 | |||
531 | MODULE_DESCRIPTION("SiRF audio codec driver"); | ||
532 | MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>"); | ||
533 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/sirf-audio-codec.h b/sound/soc/codecs/sirf-audio-codec.h new file mode 100644 index 000000000000..d4c187b8e54a --- /dev/null +++ b/sound/soc/codecs/sirf-audio-codec.h | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | * SiRF inner codec controllers define | ||
3 | * | ||
4 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #ifndef _SIRF_AUDIO_CODEC_H | ||
10 | #define _SIRF_AUDIO_CODEC_H | ||
11 | |||
12 | |||
13 | #define AUDIO_IC_CODEC_PWR (0x00E0) | ||
14 | #define AUDIO_IC_CODEC_CTRL0 (0x00E4) | ||
15 | #define AUDIO_IC_CODEC_CTRL1 (0x00E8) | ||
16 | #define AUDIO_IC_CODEC_CTRL2 (0x00EC) | ||
17 | #define AUDIO_IC_CODEC_CTRL3 (0x00F0) | ||
18 | |||
19 | #define MICBIASEN (1 << 3) | ||
20 | |||
21 | #define IC_RDACEN (1 << 0) | ||
22 | #define IC_LDACEN (1 << 1) | ||
23 | #define IC_HSREN (1 << 2) | ||
24 | #define IC_HSLEN (1 << 3) | ||
25 | #define IC_SPEN (1 << 4) | ||
26 | #define IC_CPEN (1 << 5) | ||
27 | |||
28 | #define IC_HPRSELR (1 << 6) | ||
29 | #define IC_HPLSELR (1 << 7) | ||
30 | #define IC_HPRSELL (1 << 8) | ||
31 | #define IC_HPLSELL (1 << 9) | ||
32 | #define IC_SPSELR (1 << 10) | ||
33 | #define IC_SPSELL (1 << 11) | ||
34 | |||
35 | #define IC_MONOR (1 << 12) | ||
36 | #define IC_MONOL (1 << 13) | ||
37 | |||
38 | #define IC_RXOSRSEL (1 << 28) | ||
39 | #define IC_CPFREQ (1 << 29) | ||
40 | #define IC_HSINVEN (1 << 30) | ||
41 | |||
42 | #define IC_MICINREN (1 << 0) | ||
43 | #define IC_MICINLEN (1 << 1) | ||
44 | #define IC_MICIN1SEL (1 << 2) | ||
45 | #define IC_MICIN2SEL (1 << 3) | ||
46 | #define IC_MICDIFSEL (1 << 4) | ||
47 | #define IC_LINEIN1SEL (1 << 5) | ||
48 | #define IC_LINEIN2SEL (1 << 6) | ||
49 | #define IC_RADCEN (1 << 7) | ||
50 | #define IC_LADCEN (1 << 8) | ||
51 | #define IC_ALM (1 << 9) | ||
52 | |||
53 | #define IC_DIGMICEN (1 << 22) | ||
54 | #define IC_DIGMICFREQ (1 << 23) | ||
55 | #define IC_ADC14B_12 (1 << 24) | ||
56 | #define IC_FIRDAC_HSL_EN (1 << 25) | ||
57 | #define IC_FIRDAC_HSR_EN (1 << 26) | ||
58 | #define IC_FIRDAC_LOUT_EN (1 << 27) | ||
59 | #define IC_POR (1 << 28) | ||
60 | #define IC_CODEC_CLK_EN (1 << 29) | ||
61 | #define IC_HP_3DB_BOOST (1 << 30) | ||
62 | |||
63 | #define IC_ADC_LEFT_GAIN_SHIFT 16 | ||
64 | #define IC_ADC_RIGHT_GAIN_SHIFT 10 | ||
65 | #define IC_ADC_GAIN_MASK 0x3F | ||
66 | #define IC_MIC_MAX_GAIN 0x39 | ||
67 | |||
68 | #define IC_RXPGAR_MASK 0x3F | ||
69 | #define IC_RXPGAR_SHIFT 14 | ||
70 | #define IC_RXPGAL_MASK 0x3F | ||
71 | #define IC_RXPGAL_SHIFT 21 | ||
72 | #define IC_RXPGAR 0x7B | ||
73 | #define IC_RXPGAL 0x7B | ||
74 | |||
75 | #endif /*__SIRF_AUDIO_CODEC_H*/ | ||
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 13045f2af4d3..42dff26b3a2a 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c | |||
@@ -312,14 +312,14 @@ static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w, | |||
312 | /* mux controls */ | 312 | /* mux controls */ |
313 | static const char *sn95031_mic_texts[] = { "AMIC", "LineIn" }; | 313 | static const char *sn95031_mic_texts[] = { "AMIC", "LineIn" }; |
314 | 314 | ||
315 | static const struct soc_enum sn95031_micl_enum = | 315 | static SOC_ENUM_SINGLE_DECL(sn95031_micl_enum, |
316 | SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 1, 2, sn95031_mic_texts); | 316 | SN95031_ADCCONFIG, 1, sn95031_mic_texts); |
317 | 317 | ||
318 | static const struct snd_kcontrol_new sn95031_micl_mux_control = | 318 | static const struct snd_kcontrol_new sn95031_micl_mux_control = |
319 | SOC_DAPM_ENUM("Route", sn95031_micl_enum); | 319 | SOC_DAPM_ENUM("Route", sn95031_micl_enum); |
320 | 320 | ||
321 | static const struct soc_enum sn95031_micr_enum = | 321 | static SOC_ENUM_SINGLE_DECL(sn95031_micr_enum, |
322 | SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 3, 2, sn95031_mic_texts); | 322 | SN95031_ADCCONFIG, 3, sn95031_mic_texts); |
323 | 323 | ||
324 | static const struct snd_kcontrol_new sn95031_micr_mux_control = | 324 | static const struct snd_kcontrol_new sn95031_micr_mux_control = |
325 | SOC_DAPM_ENUM("Route", sn95031_micr_enum); | 325 | SOC_DAPM_ENUM("Route", sn95031_micr_enum); |
@@ -328,26 +328,26 @@ static const char *sn95031_input_texts[] = { "DMIC1", "DMIC2", "DMIC3", | |||
328 | "DMIC4", "DMIC5", "DMIC6", | 328 | "DMIC4", "DMIC5", "DMIC6", |
329 | "ADC Left", "ADC Right" }; | 329 | "ADC Left", "ADC Right" }; |
330 | 330 | ||
331 | static const struct soc_enum sn95031_input1_enum = | 331 | static SOC_ENUM_SINGLE_DECL(sn95031_input1_enum, |
332 | SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 0, 8, sn95031_input_texts); | 332 | SN95031_AUDIOMUX12, 0, sn95031_input_texts); |
333 | 333 | ||
334 | static const struct snd_kcontrol_new sn95031_input1_mux_control = | 334 | static const struct snd_kcontrol_new sn95031_input1_mux_control = |
335 | SOC_DAPM_ENUM("Route", sn95031_input1_enum); | 335 | SOC_DAPM_ENUM("Route", sn95031_input1_enum); |
336 | 336 | ||
337 | static const struct soc_enum sn95031_input2_enum = | 337 | static SOC_ENUM_SINGLE_DECL(sn95031_input2_enum, |
338 | SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 4, 8, sn95031_input_texts); | 338 | SN95031_AUDIOMUX12, 4, sn95031_input_texts); |
339 | 339 | ||
340 | static const struct snd_kcontrol_new sn95031_input2_mux_control = | 340 | static const struct snd_kcontrol_new sn95031_input2_mux_control = |
341 | SOC_DAPM_ENUM("Route", sn95031_input2_enum); | 341 | SOC_DAPM_ENUM("Route", sn95031_input2_enum); |
342 | 342 | ||
343 | static const struct soc_enum sn95031_input3_enum = | 343 | static SOC_ENUM_SINGLE_DECL(sn95031_input3_enum, |
344 | SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 0, 8, sn95031_input_texts); | 344 | SN95031_AUDIOMUX34, 0, sn95031_input_texts); |
345 | 345 | ||
346 | static const struct snd_kcontrol_new sn95031_input3_mux_control = | 346 | static const struct snd_kcontrol_new sn95031_input3_mux_control = |
347 | SOC_DAPM_ENUM("Route", sn95031_input3_enum); | 347 | SOC_DAPM_ENUM("Route", sn95031_input3_enum); |
348 | 348 | ||
349 | static const struct soc_enum sn95031_input4_enum = | 349 | static SOC_ENUM_SINGLE_DECL(sn95031_input4_enum, |
350 | SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 4, 8, sn95031_input_texts); | 350 | SN95031_AUDIOMUX34, 4, sn95031_input_texts); |
351 | 351 | ||
352 | static const struct snd_kcontrol_new sn95031_input4_mux_control = | 352 | static const struct snd_kcontrol_new sn95031_input4_mux_control = |
353 | SOC_DAPM_ENUM("Route", sn95031_input4_enum); | 353 | SOC_DAPM_ENUM("Route", sn95031_input4_enum); |
@@ -359,19 +359,19 @@ static const char *sn95031_micmode_text[] = {"Single Ended", "Differential"}; | |||
359 | /* 0dB to 30dB in 10dB steps */ | 359 | /* 0dB to 30dB in 10dB steps */ |
360 | static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 0); | 360 | static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 0); |
361 | 361 | ||
362 | static const struct soc_enum sn95031_micmode1_enum = | 362 | static SOC_ENUM_SINGLE_DECL(sn95031_micmode1_enum, |
363 | SOC_ENUM_SINGLE(SN95031_MICAMP1, 1, 2, sn95031_micmode_text); | 363 | SN95031_MICAMP1, 1, sn95031_micmode_text); |
364 | static const struct soc_enum sn95031_micmode2_enum = | 364 | static SOC_ENUM_SINGLE_DECL(sn95031_micmode2_enum, |
365 | SOC_ENUM_SINGLE(SN95031_MICAMP2, 1, 2, sn95031_micmode_text); | 365 | SN95031_MICAMP2, 1, sn95031_micmode_text); |
366 | 366 | ||
367 | static const char *sn95031_dmic_cfg_text[] = {"GPO", "DMIC"}; | 367 | static const char *sn95031_dmic_cfg_text[] = {"GPO", "DMIC"}; |
368 | 368 | ||
369 | static const struct soc_enum sn95031_dmic12_cfg_enum = | 369 | static SOC_ENUM_SINGLE_DECL(sn95031_dmic12_cfg_enum, |
370 | SOC_ENUM_SINGLE(SN95031_DMICMUX, 0, 2, sn95031_dmic_cfg_text); | 370 | SN95031_DMICMUX, 0, sn95031_dmic_cfg_text); |
371 | static const struct soc_enum sn95031_dmic34_cfg_enum = | 371 | static SOC_ENUM_SINGLE_DECL(sn95031_dmic34_cfg_enum, |
372 | SOC_ENUM_SINGLE(SN95031_DMICMUX, 1, 2, sn95031_dmic_cfg_text); | 372 | SN95031_DMICMUX, 1, sn95031_dmic_cfg_text); |
373 | static const struct soc_enum sn95031_dmic56_cfg_enum = | 373 | static SOC_ENUM_SINGLE_DECL(sn95031_dmic56_cfg_enum, |
374 | SOC_ENUM_SINGLE(SN95031_DMICMUX, 2, 2, sn95031_dmic_cfg_text); | 374 | SN95031_DMICMUX, 2, sn95031_dmic_cfg_text); |
375 | 375 | ||
376 | static const struct snd_kcontrol_new sn95031_snd_controls[] = { | 376 | static const struct snd_kcontrol_new sn95031_snd_controls[] = { |
377 | SOC_ENUM("Mic1Mode Capture Route", sn95031_micmode1_enum), | 377 | SOC_ENUM("Mic1Mode Capture Route", sn95031_micmode1_enum), |
@@ -825,8 +825,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec) | |||
825 | { | 825 | { |
826 | pr_debug("codec_probe called\n"); | 826 | pr_debug("codec_probe called\n"); |
827 | 827 | ||
828 | snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); | ||
829 | |||
830 | /* PCM interface config | 828 | /* PCM interface config |
831 | * This sets the pcm rx slot conguration to max 6 slots | 829 | * This sets the pcm rx slot conguration to max 6 slots |
832 | * for max 4 dais (2 stereo and 2 mono) | 830 | * for max 4 dais (2 stereo and 2 mono) |
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index cc8debce752f..56adb3e2def9 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c | |||
@@ -169,19 +169,19 @@ static const char * const ssm2518_drc_hold_time_text[] = { | |||
169 | "682.24 ms", "1364 ms", | 169 | "682.24 ms", "1364 ms", |
170 | }; | 170 | }; |
171 | 171 | ||
172 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_attack_time_enum, | 172 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_attack_time_enum, |
173 | SSM2518_REG_DRC_2, 4, ssm2518_drc_peak_detector_attack_time_text); | 173 | SSM2518_REG_DRC_2, 4, ssm2518_drc_peak_detector_attack_time_text); |
174 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_release_time_enum, | 174 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_release_time_enum, |
175 | SSM2518_REG_DRC_2, 0, ssm2518_drc_peak_detector_release_time_text); | 175 | SSM2518_REG_DRC_2, 0, ssm2518_drc_peak_detector_release_time_text); |
176 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_attack_time_enum, | 176 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_attack_time_enum, |
177 | SSM2518_REG_DRC_6, 4, ssm2518_drc_peak_detector_attack_time_text); | 177 | SSM2518_REG_DRC_6, 4, ssm2518_drc_peak_detector_attack_time_text); |
178 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_decay_time_enum, | 178 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_decay_time_enum, |
179 | SSM2518_REG_DRC_6, 0, ssm2518_drc_peak_detector_release_time_text); | 179 | SSM2518_REG_DRC_6, 0, ssm2518_drc_peak_detector_release_time_text); |
180 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_hold_time_enum, | 180 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_hold_time_enum, |
181 | SSM2518_REG_DRC_7, 4, ssm2518_drc_hold_time_text); | 181 | SSM2518_REG_DRC_7, 4, ssm2518_drc_hold_time_text); |
182 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_noise_gate_hold_time_enum, | 182 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_noise_gate_hold_time_enum, |
183 | SSM2518_REG_DRC_7, 0, ssm2518_drc_hold_time_text); | 183 | SSM2518_REG_DRC_7, 0, ssm2518_drc_hold_time_text); |
184 | static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_rms_averaging_time_enum, | 184 | static SOC_ENUM_SINGLE_DECL(ssm2518_drc_rms_averaging_time_enum, |
185 | SSM2518_REG_DRC_9, 0, ssm2518_drc_peak_detector_release_time_text); | 185 | SSM2518_REG_DRC_9, 0, ssm2518_drc_peak_detector_release_time_text); |
186 | 186 | ||
187 | static const struct snd_kcontrol_new ssm2518_snd_controls[] = { | 187 | static const struct snd_kcontrol_new ssm2518_snd_controls[] = { |
@@ -648,16 +648,6 @@ static struct snd_soc_dai_driver ssm2518_dai = { | |||
648 | 648 | ||
649 | static int ssm2518_probe(struct snd_soc_codec *codec) | 649 | static int ssm2518_probe(struct snd_soc_codec *codec) |
650 | { | 650 | { |
651 | struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec); | ||
652 | int ret; | ||
653 | |||
654 | codec->control_data = ssm2518->regmap; | ||
655 | ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); | ||
656 | if (ret < 0) { | ||
657 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
658 | return ret; | ||
659 | } | ||
660 | |||
661 | return ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF); | 651 | return ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF); |
662 | } | 652 | } |
663 | 653 | ||
diff --git a/sound/soc/codecs/ssm2602-i2c.c b/sound/soc/codecs/ssm2602-i2c.c new file mode 100644 index 000000000000..abd63d537173 --- /dev/null +++ b/sound/soc/codecs/ssm2602-i2c.c | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * SSM2602/SSM2603/SSM2604 I2C audio driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/regmap.h> | ||
12 | |||
13 | #include <sound/soc.h> | ||
14 | |||
15 | #include "ssm2602.h" | ||
16 | |||
17 | /* | ||
18 | * ssm2602 2 wire address is determined by GPIO5 | ||
19 | * state during powerup. | ||
20 | * low = 0x1a | ||
21 | * high = 0x1b | ||
22 | */ | ||
23 | static int ssm2602_i2c_probe(struct i2c_client *client, | ||
24 | const struct i2c_device_id *id) | ||
25 | { | ||
26 | return ssm2602_probe(&client->dev, id->driver_data, | ||
27 | devm_regmap_init_i2c(client, &ssm2602_regmap_config)); | ||
28 | } | ||
29 | |||
30 | static int ssm2602_i2c_remove(struct i2c_client *client) | ||
31 | { | ||
32 | snd_soc_unregister_codec(&client->dev); | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static const struct i2c_device_id ssm2602_i2c_id[] = { | ||
37 | { "ssm2602", SSM2602 }, | ||
38 | { "ssm2603", SSM2602 }, | ||
39 | { "ssm2604", SSM2604 }, | ||
40 | { } | ||
41 | }; | ||
42 | MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); | ||
43 | |||
44 | static struct i2c_driver ssm2602_i2c_driver = { | ||
45 | .driver = { | ||
46 | .name = "ssm2602", | ||
47 | .owner = THIS_MODULE, | ||
48 | }, | ||
49 | .probe = ssm2602_i2c_probe, | ||
50 | .remove = ssm2602_i2c_remove, | ||
51 | .id_table = ssm2602_i2c_id, | ||
52 | }; | ||
53 | module_i2c_driver(ssm2602_i2c_driver); | ||
54 | |||
55 | MODULE_DESCRIPTION("ASoC SSM2602/SSM2603/SSM2604 I2C driver"); | ||
56 | MODULE_AUTHOR("Cliff Cai"); | ||
57 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/ssm2602-spi.c b/sound/soc/codecs/ssm2602-spi.c new file mode 100644 index 000000000000..2bf55e24a7bb --- /dev/null +++ b/sound/soc/codecs/ssm2602-spi.c | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * SSM2602 SPI audio driver | ||
3 | * | ||
4 | * Copyright 2014 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/spi/spi.h> | ||
11 | #include <linux/regmap.h> | ||
12 | |||
13 | #include <sound/soc.h> | ||
14 | |||
15 | #include "ssm2602.h" | ||
16 | |||
17 | static int ssm2602_spi_probe(struct spi_device *spi) | ||
18 | { | ||
19 | return ssm2602_probe(&spi->dev, SSM2602, | ||
20 | devm_regmap_init_spi(spi, &ssm2602_regmap_config)); | ||
21 | } | ||
22 | |||
23 | static int ssm2602_spi_remove(struct spi_device *spi) | ||
24 | { | ||
25 | snd_soc_unregister_codec(&spi->dev); | ||
26 | return 0; | ||
27 | } | ||
28 | |||
29 | static struct spi_driver ssm2602_spi_driver = { | ||
30 | .driver = { | ||
31 | .name = "ssm2602", | ||
32 | .owner = THIS_MODULE, | ||
33 | }, | ||
34 | .probe = ssm2602_spi_probe, | ||
35 | .remove = ssm2602_spi_remove, | ||
36 | }; | ||
37 | module_spi_driver(ssm2602_spi_driver); | ||
38 | |||
39 | MODULE_DESCRIPTION("ASoC SSM2602 SPI driver"); | ||
40 | MODULE_AUTHOR("Cliff Cai"); | ||
41 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index af76bbd1b24f..97b0454eb346 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c | |||
@@ -27,32 +27,20 @@ | |||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/moduleparam.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/pm.h> | ||
34 | #include <linux/i2c.h> | ||
35 | #include <linux/spi/spi.h> | ||
36 | #include <linux/regmap.h> | 30 | #include <linux/regmap.h> |
37 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
38 | #include <sound/core.h> | 32 | |
39 | #include <sound/pcm.h> | 33 | #include <sound/pcm.h> |
40 | #include <sound/pcm_params.h> | 34 | #include <sound/pcm_params.h> |
41 | #include <sound/soc.h> | 35 | #include <sound/soc.h> |
42 | #include <sound/initval.h> | ||
43 | #include <sound/tlv.h> | 36 | #include <sound/tlv.h> |
44 | 37 | ||
45 | #include "ssm2602.h" | 38 | #include "ssm2602.h" |
46 | 39 | ||
47 | enum ssm2602_type { | ||
48 | SSM2602, | ||
49 | SSM2604, | ||
50 | }; | ||
51 | |||
52 | /* codec private data */ | 40 | /* codec private data */ |
53 | struct ssm2602_priv { | 41 | struct ssm2602_priv { |
54 | unsigned int sysclk; | 42 | unsigned int sysclk; |
55 | struct snd_pcm_hw_constraint_list *sysclk_constraints; | 43 | const struct snd_pcm_hw_constraint_list *sysclk_constraints; |
56 | 44 | ||
57 | struct regmap *regmap; | 45 | struct regmap *regmap; |
58 | 46 | ||
@@ -75,15 +63,16 @@ static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = { | |||
75 | 63 | ||
76 | /*Appending several "None"s just for OSS mixer use*/ | 64 | /*Appending several "None"s just for OSS mixer use*/ |
77 | static const char *ssm2602_input_select[] = { | 65 | static const char *ssm2602_input_select[] = { |
78 | "Line", "Mic", "None", "None", "None", | 66 | "Line", "Mic", |
79 | "None", "None", "None", | ||
80 | }; | 67 | }; |
81 | 68 | ||
82 | static const char *ssm2602_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; | 69 | static const char *ssm2602_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; |
83 | 70 | ||
84 | static const struct soc_enum ssm2602_enum[] = { | 71 | static const struct soc_enum ssm2602_enum[] = { |
85 | SOC_ENUM_SINGLE(SSM2602_APANA, 2, 2, ssm2602_input_select), | 72 | SOC_ENUM_SINGLE(SSM2602_APANA, 2, ARRAY_SIZE(ssm2602_input_select), |
86 | SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph), | 73 | ssm2602_input_select), |
74 | SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, ARRAY_SIZE(ssm2602_deemph), | ||
75 | ssm2602_deemph), | ||
87 | }; | 76 | }; |
88 | 77 | ||
89 | static const unsigned int ssm260x_outmix_tlv[] = { | 78 | static const unsigned int ssm260x_outmix_tlv[] = { |
@@ -197,7 +186,7 @@ static const unsigned int ssm2602_rates_12288000[] = { | |||
197 | 8000, 16000, 32000, 48000, 96000, | 186 | 8000, 16000, 32000, 48000, 96000, |
198 | }; | 187 | }; |
199 | 188 | ||
200 | static struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = { | 189 | static const struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = { |
201 | .list = ssm2602_rates_12288000, | 190 | .list = ssm2602_rates_12288000, |
202 | .count = ARRAY_SIZE(ssm2602_rates_12288000), | 191 | .count = ARRAY_SIZE(ssm2602_rates_12288000), |
203 | }; | 192 | }; |
@@ -206,7 +195,7 @@ static const unsigned int ssm2602_rates_11289600[] = { | |||
206 | 8000, 44100, 88200, | 195 | 8000, 44100, 88200, |
207 | }; | 196 | }; |
208 | 197 | ||
209 | static struct snd_pcm_hw_constraint_list ssm2602_constraints_11289600 = { | 198 | static const struct snd_pcm_hw_constraint_list ssm2602_constraints_11289600 = { |
210 | .list = ssm2602_rates_11289600, | 199 | .list = ssm2602_rates_11289600, |
211 | .count = ARRAY_SIZE(ssm2602_rates_11289600), | 200 | .count = ARRAY_SIZE(ssm2602_rates_11289600), |
212 | }; | 201 | }; |
@@ -529,7 +518,7 @@ static int ssm2602_resume(struct snd_soc_codec *codec) | |||
529 | return 0; | 518 | return 0; |
530 | } | 519 | } |
531 | 520 | ||
532 | static int ssm2602_probe(struct snd_soc_codec *codec) | 521 | static int ssm2602_codec_probe(struct snd_soc_codec *codec) |
533 | { | 522 | { |
534 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); | 523 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); |
535 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 524 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
@@ -554,7 +543,7 @@ static int ssm2602_probe(struct snd_soc_codec *codec) | |||
554 | ARRAY_SIZE(ssm2602_routes)); | 543 | ARRAY_SIZE(ssm2602_routes)); |
555 | } | 544 | } |
556 | 545 | ||
557 | static int ssm2604_probe(struct snd_soc_codec *codec) | 546 | static int ssm2604_codec_probe(struct snd_soc_codec *codec) |
558 | { | 547 | { |
559 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 548 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
560 | int ret; | 549 | int ret; |
@@ -568,18 +557,11 @@ static int ssm2604_probe(struct snd_soc_codec *codec) | |||
568 | ARRAY_SIZE(ssm2604_routes)); | 557 | ARRAY_SIZE(ssm2604_routes)); |
569 | } | 558 | } |
570 | 559 | ||
571 | static int ssm260x_probe(struct snd_soc_codec *codec) | 560 | static int ssm260x_codec_probe(struct snd_soc_codec *codec) |
572 | { | 561 | { |
573 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); | 562 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); |
574 | int ret; | 563 | int ret; |
575 | 564 | ||
576 | codec->control_data = ssm2602->regmap; | ||
577 | ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); | ||
578 | if (ret < 0) { | ||
579 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
580 | return ret; | ||
581 | } | ||
582 | |||
583 | ret = regmap_write(ssm2602->regmap, SSM2602_RESET, 0); | 565 | ret = regmap_write(ssm2602->regmap, SSM2602_RESET, 0); |
584 | if (ret < 0) { | 566 | if (ret < 0) { |
585 | dev_err(codec->dev, "Failed to issue reset: %d\n", ret); | 567 | dev_err(codec->dev, "Failed to issue reset: %d\n", ret); |
@@ -597,10 +579,10 @@ static int ssm260x_probe(struct snd_soc_codec *codec) | |||
597 | 579 | ||
598 | switch (ssm2602->type) { | 580 | switch (ssm2602->type) { |
599 | case SSM2602: | 581 | case SSM2602: |
600 | ret = ssm2602_probe(codec); | 582 | ret = ssm2602_codec_probe(codec); |
601 | break; | 583 | break; |
602 | case SSM2604: | 584 | case SSM2604: |
603 | ret = ssm2604_probe(codec); | 585 | ret = ssm2604_codec_probe(codec); |
604 | break; | 586 | break; |
605 | } | 587 | } |
606 | 588 | ||
@@ -620,7 +602,7 @@ static int ssm2602_remove(struct snd_soc_codec *codec) | |||
620 | } | 602 | } |
621 | 603 | ||
622 | static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { | 604 | static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { |
623 | .probe = ssm260x_probe, | 605 | .probe = ssm260x_codec_probe, |
624 | .remove = ssm2602_remove, | 606 | .remove = ssm2602_remove, |
625 | .suspend = ssm2602_suspend, | 607 | .suspend = ssm2602_suspend, |
626 | .resume = ssm2602_resume, | 608 | .resume = ssm2602_resume, |
@@ -639,7 +621,7 @@ static bool ssm2602_register_volatile(struct device *dev, unsigned int reg) | |||
639 | return reg == SSM2602_RESET; | 621 | return reg == SSM2602_RESET; |
640 | } | 622 | } |
641 | 623 | ||
642 | static const struct regmap_config ssm2602_regmap_config = { | 624 | const struct regmap_config ssm2602_regmap_config = { |
643 | .val_bits = 9, | 625 | .val_bits = 9, |
644 | .reg_bits = 7, | 626 | .reg_bits = 7, |
645 | 627 | ||
@@ -650,134 +632,28 @@ static const struct regmap_config ssm2602_regmap_config = { | |||
650 | .reg_defaults_raw = ssm2602_reg, | 632 | .reg_defaults_raw = ssm2602_reg, |
651 | .num_reg_defaults_raw = ARRAY_SIZE(ssm2602_reg), | 633 | .num_reg_defaults_raw = ARRAY_SIZE(ssm2602_reg), |
652 | }; | 634 | }; |
635 | EXPORT_SYMBOL_GPL(ssm2602_regmap_config); | ||
653 | 636 | ||
654 | #if defined(CONFIG_SPI_MASTER) | 637 | int ssm2602_probe(struct device *dev, enum ssm2602_type type, |
655 | static int ssm2602_spi_probe(struct spi_device *spi) | 638 | struct regmap *regmap) |
656 | { | 639 | { |
657 | struct ssm2602_priv *ssm2602; | 640 | struct ssm2602_priv *ssm2602; |
658 | int ret; | ||
659 | |||
660 | ssm2602 = devm_kzalloc(&spi->dev, sizeof(struct ssm2602_priv), | ||
661 | GFP_KERNEL); | ||
662 | if (ssm2602 == NULL) | ||
663 | return -ENOMEM; | ||
664 | |||
665 | spi_set_drvdata(spi, ssm2602); | ||
666 | ssm2602->type = SSM2602; | ||
667 | 641 | ||
668 | ssm2602->regmap = devm_regmap_init_spi(spi, &ssm2602_regmap_config); | 642 | if (IS_ERR(regmap)) |
669 | if (IS_ERR(ssm2602->regmap)) | 643 | return PTR_ERR(regmap); |
670 | return PTR_ERR(ssm2602->regmap); | ||
671 | 644 | ||
672 | ret = snd_soc_register_codec(&spi->dev, | 645 | ssm2602 = devm_kzalloc(dev, sizeof(*ssm2602), GFP_KERNEL); |
673 | &soc_codec_dev_ssm2602, &ssm2602_dai, 1); | ||
674 | return ret; | ||
675 | } | ||
676 | |||
677 | static int ssm2602_spi_remove(struct spi_device *spi) | ||
678 | { | ||
679 | snd_soc_unregister_codec(&spi->dev); | ||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | static struct spi_driver ssm2602_spi_driver = { | ||
684 | .driver = { | ||
685 | .name = "ssm2602", | ||
686 | .owner = THIS_MODULE, | ||
687 | }, | ||
688 | .probe = ssm2602_spi_probe, | ||
689 | .remove = ssm2602_spi_remove, | ||
690 | }; | ||
691 | #endif | ||
692 | |||
693 | #if IS_ENABLED(CONFIG_I2C) | ||
694 | /* | ||
695 | * ssm2602 2 wire address is determined by GPIO5 | ||
696 | * state during powerup. | ||
697 | * low = 0x1a | ||
698 | * high = 0x1b | ||
699 | */ | ||
700 | static int ssm2602_i2c_probe(struct i2c_client *i2c, | ||
701 | const struct i2c_device_id *id) | ||
702 | { | ||
703 | struct ssm2602_priv *ssm2602; | ||
704 | int ret; | ||
705 | |||
706 | ssm2602 = devm_kzalloc(&i2c->dev, sizeof(struct ssm2602_priv), | ||
707 | GFP_KERNEL); | ||
708 | if (ssm2602 == NULL) | 646 | if (ssm2602 == NULL) |
709 | return -ENOMEM; | 647 | return -ENOMEM; |
710 | 648 | ||
711 | i2c_set_clientdata(i2c, ssm2602); | 649 | dev_set_drvdata(dev, ssm2602); |
712 | ssm2602->type = id->driver_data; | 650 | ssm2602->type = SSM2602; |
713 | 651 | ssm2602->regmap = regmap; | |
714 | ssm2602->regmap = devm_regmap_init_i2c(i2c, &ssm2602_regmap_config); | ||
715 | if (IS_ERR(ssm2602->regmap)) | ||
716 | return PTR_ERR(ssm2602->regmap); | ||
717 | |||
718 | ret = snd_soc_register_codec(&i2c->dev, | ||
719 | &soc_codec_dev_ssm2602, &ssm2602_dai, 1); | ||
720 | return ret; | ||
721 | } | ||
722 | |||
723 | static int ssm2602_i2c_remove(struct i2c_client *client) | ||
724 | { | ||
725 | snd_soc_unregister_codec(&client->dev); | ||
726 | return 0; | ||
727 | } | ||
728 | |||
729 | static const struct i2c_device_id ssm2602_i2c_id[] = { | ||
730 | { "ssm2602", SSM2602 }, | ||
731 | { "ssm2603", SSM2602 }, | ||
732 | { "ssm2604", SSM2604 }, | ||
733 | { } | ||
734 | }; | ||
735 | MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); | ||
736 | |||
737 | /* corgi i2c codec control layer */ | ||
738 | static struct i2c_driver ssm2602_i2c_driver = { | ||
739 | .driver = { | ||
740 | .name = "ssm2602", | ||
741 | .owner = THIS_MODULE, | ||
742 | }, | ||
743 | .probe = ssm2602_i2c_probe, | ||
744 | .remove = ssm2602_i2c_remove, | ||
745 | .id_table = ssm2602_i2c_id, | ||
746 | }; | ||
747 | #endif | ||
748 | |||
749 | |||
750 | static int __init ssm2602_modinit(void) | ||
751 | { | ||
752 | int ret = 0; | ||
753 | |||
754 | #if defined(CONFIG_SPI_MASTER) | ||
755 | ret = spi_register_driver(&ssm2602_spi_driver); | ||
756 | if (ret) | ||
757 | return ret; | ||
758 | #endif | ||
759 | |||
760 | #if IS_ENABLED(CONFIG_I2C) | ||
761 | ret = i2c_add_driver(&ssm2602_i2c_driver); | ||
762 | if (ret) | ||
763 | return ret; | ||
764 | #endif | ||
765 | |||
766 | return ret; | ||
767 | } | ||
768 | module_init(ssm2602_modinit); | ||
769 | |||
770 | static void __exit ssm2602_exit(void) | ||
771 | { | ||
772 | #if defined(CONFIG_SPI_MASTER) | ||
773 | spi_unregister_driver(&ssm2602_spi_driver); | ||
774 | #endif | ||
775 | 652 | ||
776 | #if IS_ENABLED(CONFIG_I2C) | 653 | return snd_soc_register_codec(dev, &soc_codec_dev_ssm2602, |
777 | i2c_del_driver(&ssm2602_i2c_driver); | 654 | &ssm2602_dai, 1); |
778 | #endif | ||
779 | } | 655 | } |
780 | module_exit(ssm2602_exit); | 656 | EXPORT_SYMBOL_GPL(ssm2602_probe); |
781 | 657 | ||
782 | MODULE_DESCRIPTION("ASoC SSM2602/SSM2603/SSM2604 driver"); | 658 | MODULE_DESCRIPTION("ASoC SSM2602/SSM2603/SSM2604 driver"); |
783 | MODULE_AUTHOR("Cliff Cai"); | 659 | MODULE_AUTHOR("Cliff Cai"); |
diff --git a/sound/soc/codecs/ssm2602.h b/sound/soc/codecs/ssm2602.h index fbd07d7b73ca..747538847689 100644 --- a/sound/soc/codecs/ssm2602.h +++ b/sound/soc/codecs/ssm2602.h | |||
@@ -28,6 +28,20 @@ | |||
28 | #ifndef _SSM2602_H | 28 | #ifndef _SSM2602_H |
29 | #define _SSM2602_H | 29 | #define _SSM2602_H |
30 | 30 | ||
31 | #include <linux/regmap.h> | ||
32 | |||
33 | struct device; | ||
34 | |||
35 | enum ssm2602_type { | ||
36 | SSM2602, | ||
37 | SSM2604, | ||
38 | }; | ||
39 | |||
40 | extern const struct regmap_config ssm2602_regmap_config; | ||
41 | |||
42 | int ssm2602_probe(struct device *dev, enum ssm2602_type type, | ||
43 | struct regmap *regmap); | ||
44 | |||
31 | /* SSM2602 Codec Register definitions */ | 45 | /* SSM2602 Codec Register definitions */ |
32 | 46 | ||
33 | #define SSM2602_LINVOL 0x00 | 47 | #define SSM2602_LINVOL 0x00 |
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 06edb396e733..12577749b17b 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c | |||
@@ -187,42 +187,42 @@ static const unsigned int sta32x_limiter_drc_release_tlv[] = { | |||
187 | 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), | 187 | 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), |
188 | }; | 188 | }; |
189 | 189 | ||
190 | static const struct soc_enum sta32x_drc_ac_enum = | 190 | static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum, |
191 | SOC_ENUM_SINGLE(STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, | 191 | STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, |
192 | 2, sta32x_drc_ac); | 192 | sta32x_drc_ac); |
193 | static const struct soc_enum sta32x_auto_eq_enum = | 193 | static SOC_ENUM_SINGLE_DECL(sta32x_auto_eq_enum, |
194 | SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT, | 194 | STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT, |
195 | 3, sta32x_auto_eq_mode); | 195 | sta32x_auto_eq_mode); |
196 | static const struct soc_enum sta32x_auto_gc_enum = | 196 | static SOC_ENUM_SINGLE_DECL(sta32x_auto_gc_enum, |
197 | SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT, | 197 | STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT, |
198 | 4, sta32x_auto_gc_mode); | 198 | sta32x_auto_gc_mode); |
199 | static const struct soc_enum sta32x_auto_xo_enum = | 199 | static SOC_ENUM_SINGLE_DECL(sta32x_auto_xo_enum, |
200 | SOC_ENUM_SINGLE(STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT, | 200 | STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT, |
201 | 16, sta32x_auto_xo_mode); | 201 | sta32x_auto_xo_mode); |
202 | static const struct soc_enum sta32x_preset_eq_enum = | 202 | static SOC_ENUM_SINGLE_DECL(sta32x_preset_eq_enum, |
203 | SOC_ENUM_SINGLE(STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT, | 203 | STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT, |
204 | 32, sta32x_preset_eq_mode); | 204 | sta32x_preset_eq_mode); |
205 | static const struct soc_enum sta32x_limiter_ch1_enum = | 205 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch1_enum, |
206 | SOC_ENUM_SINGLE(STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT, | 206 | STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT, |
207 | 3, sta32x_limiter_select); | 207 | sta32x_limiter_select); |
208 | static const struct soc_enum sta32x_limiter_ch2_enum = | 208 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch2_enum, |
209 | SOC_ENUM_SINGLE(STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT, | 209 | STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT, |
210 | 3, sta32x_limiter_select); | 210 | sta32x_limiter_select); |
211 | static const struct soc_enum sta32x_limiter_ch3_enum = | 211 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch3_enum, |
212 | SOC_ENUM_SINGLE(STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT, | 212 | STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT, |
213 | 3, sta32x_limiter_select); | 213 | sta32x_limiter_select); |
214 | static const struct soc_enum sta32x_limiter1_attack_rate_enum = | 214 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_attack_rate_enum, |
215 | SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxA_SHIFT, | 215 | STA32X_L1AR, STA32X_LxA_SHIFT, |
216 | 16, sta32x_limiter_attack_rate); | 216 | sta32x_limiter_attack_rate); |
217 | static const struct soc_enum sta32x_limiter2_attack_rate_enum = | 217 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_attack_rate_enum, |
218 | SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxA_SHIFT, | 218 | STA32X_L2AR, STA32X_LxA_SHIFT, |
219 | 16, sta32x_limiter_attack_rate); | 219 | sta32x_limiter_attack_rate); |
220 | static const struct soc_enum sta32x_limiter1_release_rate_enum = | 220 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_release_rate_enum, |
221 | SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxR_SHIFT, | 221 | STA32X_L1AR, STA32X_LxR_SHIFT, |
222 | 16, sta32x_limiter_release_rate); | 222 | sta32x_limiter_release_rate); |
223 | static const struct soc_enum sta32x_limiter2_release_rate_enum = | 223 | static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_release_rate_enum, |
224 | SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxR_SHIFT, | 224 | STA32X_L2AR, STA32X_LxR_SHIFT, |
225 | 16, sta32x_limiter_release_rate); | 225 | sta32x_limiter_release_rate); |
226 | 226 | ||
227 | /* byte array controls for setting biquad, mixer, scaling coefficients; | 227 | /* byte array controls for setting biquad, mixer, scaling coefficients; |
228 | * for biquads all five coefficients need to be set in one go, | 228 | * for biquads all five coefficients need to be set in one go, |
@@ -331,7 +331,7 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec) | |||
331 | 331 | ||
332 | static int sta32x_cache_sync(struct snd_soc_codec *codec) | 332 | static int sta32x_cache_sync(struct snd_soc_codec *codec) |
333 | { | 333 | { |
334 | struct sta32x_priv *sta32x = codec->control_data; | 334 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); |
335 | unsigned int mute; | 335 | unsigned int mute; |
336 | int rc; | 336 | int rc; |
337 | 337 | ||
@@ -434,7 +434,7 @@ SOC_SINGLE_TLV("Treble Tone Control", STA32X_TONE, STA32X_TONE_TTC_SHIFT, 15, 0, | |||
434 | SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum), | 434 | SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum), |
435 | SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum), | 435 | SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum), |
436 | SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), | 436 | SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), |
437 | SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), | 437 | SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter2_release_rate_enum), |
438 | 438 | ||
439 | /* depending on mode, the attack/release thresholds have | 439 | /* depending on mode, the attack/release thresholds have |
440 | * two different enum definitions; provide both | 440 | * two different enum definitions; provide both |
@@ -872,16 +872,6 @@ static int sta32x_probe(struct snd_soc_codec *codec) | |||
872 | return ret; | 872 | return ret; |
873 | } | 873 | } |
874 | 874 | ||
875 | /* Tell ASoC what kind of I/O to use to read the registers. ASoC will | ||
876 | * then do the I2C transactions itself. | ||
877 | */ | ||
878 | codec->control_data = sta32x->regmap; | ||
879 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
880 | if (ret < 0) { | ||
881 | dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret); | ||
882 | goto err; | ||
883 | } | ||
884 | |||
885 | /* Chip documentation explicitly requires that the reset values | 875 | /* Chip documentation explicitly requires that the reset values |
886 | * of reserved register bits are left untouched. | 876 | * of reserved register bits are left untouched. |
887 | * Write the register default value to cache for reserved registers, | 877 | * Write the register default value to cache for reserved registers, |
@@ -946,10 +936,6 @@ static int sta32x_probe(struct snd_soc_codec *codec) | |||
946 | regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); | 936 | regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); |
947 | 937 | ||
948 | return 0; | 938 | return 0; |
949 | |||
950 | err: | ||
951 | regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); | ||
952 | return ret; | ||
953 | } | 939 | } |
954 | 940 | ||
955 | static int sta32x_remove(struct snd_soc_codec *codec) | 941 | static int sta32x_remove(struct snd_soc_codec *codec) |
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index 40c07be9b581..a40c4b0196a3 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c | |||
@@ -141,7 +141,7 @@ static const char *pwm_mode_text[] = { "Binary", "Headphone", "Ternary", | |||
141 | 141 | ||
142 | static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -9150, 50, 0); | 142 | static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -9150, 50, 0); |
143 | static const DECLARE_TLV_DB_SCALE(master_vol_tlv, -12750, 50, 0); | 143 | static const DECLARE_TLV_DB_SCALE(master_vol_tlv, -12750, 50, 0); |
144 | static const SOC_ENUM_SINGLE_DECL(pwm_src, STA529_FFXCFG1, 4, pwm_mode_text); | 144 | static SOC_ENUM_SINGLE_DECL(pwm_src, STA529_FFXCFG1, 4, pwm_mode_text); |
145 | 145 | ||
146 | static const struct snd_kcontrol_new sta529_snd_controls[] = { | 146 | static const struct snd_kcontrol_new sta529_snd_controls[] = { |
147 | SOC_DOUBLE_R_TLV("Digital Playback Volume", STA529_LVOL, STA529_RVOL, 0, | 147 | SOC_DOUBLE_R_TLV("Digital Playback Volume", STA529_LVOL, STA529_RVOL, 0, |
@@ -193,8 +193,7 @@ static int sta529_hw_params(struct snd_pcm_substream *substream, | |||
193 | struct snd_pcm_hw_params *params, | 193 | struct snd_pcm_hw_params *params, |
194 | struct snd_soc_dai *dai) | 194 | struct snd_soc_dai *dai) |
195 | { | 195 | { |
196 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 196 | struct snd_soc_codec *codec = dai->codec; |
197 | struct snd_soc_codec *codec = rtd->codec; | ||
198 | int pdata, play_freq_val, record_freq_val; | 197 | int pdata, play_freq_val, record_freq_val; |
199 | int bclk_to_fs_ratio; | 198 | int bclk_to_fs_ratio; |
200 | 199 | ||
@@ -322,16 +321,6 @@ static struct snd_soc_dai_driver sta529_dai = { | |||
322 | 321 | ||
323 | static int sta529_probe(struct snd_soc_codec *codec) | 322 | static int sta529_probe(struct snd_soc_codec *codec) |
324 | { | 323 | { |
325 | struct sta529 *sta529 = snd_soc_codec_get_drvdata(codec); | ||
326 | int ret; | ||
327 | |||
328 | codec->control_data = sta529->regmap; | ||
329 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
330 | |||
331 | if (ret < 0) { | ||
332 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
333 | return ret; | ||
334 | } | ||
335 | sta529_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 324 | sta529_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
336 | 325 | ||
337 | return 0; | 326 | return 0; |
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index a5455c1aea42..53b810d23fea 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c | |||
@@ -62,25 +62,25 @@ static const char *stac9766_boost1[] = {"0dB", "10dB"}; | |||
62 | static const char *stac9766_boost2[] = {"0dB", "20dB"}; | 62 | static const char *stac9766_boost2[] = {"0dB", "20dB"}; |
63 | static const char *stac9766_stereo_mic[] = {"Off", "On"}; | 63 | static const char *stac9766_stereo_mic[] = {"Off", "On"}; |
64 | 64 | ||
65 | static const struct soc_enum stac9766_record_enum = | 65 | static SOC_ENUM_DOUBLE_DECL(stac9766_record_enum, |
66 | SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, stac9766_record_mux); | 66 | AC97_REC_SEL, 8, 0, stac9766_record_mux); |
67 | static const struct soc_enum stac9766_mono_enum = | 67 | static SOC_ENUM_SINGLE_DECL(stac9766_mono_enum, |
68 | SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 9, 2, stac9766_mono_mux); | 68 | AC97_GENERAL_PURPOSE, 9, stac9766_mono_mux); |
69 | static const struct soc_enum stac9766_mic_enum = | 69 | static SOC_ENUM_SINGLE_DECL(stac9766_mic_enum, |
70 | SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, stac9766_mic_mux); | 70 | AC97_GENERAL_PURPOSE, 8, stac9766_mic_mux); |
71 | static const struct soc_enum stac9766_SPDIF_enum = | 71 | static SOC_ENUM_SINGLE_DECL(stac9766_SPDIF_enum, |
72 | SOC_ENUM_SINGLE(AC97_STAC_DA_CONTROL, 1, 2, stac9766_SPDIF_mux); | 72 | AC97_STAC_DA_CONTROL, 1, stac9766_SPDIF_mux); |
73 | static const struct soc_enum stac9766_popbypass_enum = | 73 | static SOC_ENUM_SINGLE_DECL(stac9766_popbypass_enum, |
74 | SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, stac9766_popbypass_mux); | 74 | AC97_GENERAL_PURPOSE, 15, stac9766_popbypass_mux); |
75 | static const struct soc_enum stac9766_record_all_enum = | 75 | static SOC_ENUM_SINGLE_DECL(stac9766_record_all_enum, |
76 | SOC_ENUM_SINGLE(AC97_STAC_ANALOG_SPECIAL, 12, 2, | 76 | AC97_STAC_ANALOG_SPECIAL, 12, |
77 | stac9766_record_all_mux); | 77 | stac9766_record_all_mux); |
78 | static const struct soc_enum stac9766_boost1_enum = | 78 | static SOC_ENUM_SINGLE_DECL(stac9766_boost1_enum, |
79 | SOC_ENUM_SINGLE(AC97_MIC, 6, 2, stac9766_boost1); /* 0/10dB */ | 79 | AC97_MIC, 6, stac9766_boost1); /* 0/10dB */ |
80 | static const struct soc_enum stac9766_boost2_enum = | 80 | static SOC_ENUM_SINGLE_DECL(stac9766_boost2_enum, |
81 | SOC_ENUM_SINGLE(AC97_STAC_ANALOG_SPECIAL, 2, 2, stac9766_boost2); /* 0/20dB */ | 81 | AC97_STAC_ANALOG_SPECIAL, 2, stac9766_boost2); /* 0/20dB */ |
82 | static const struct soc_enum stac9766_stereo_mic_enum = | 82 | static SOC_ENUM_SINGLE_DECL(stac9766_stereo_mic_enum, |
83 | SOC_ENUM_SINGLE(AC97_STAC_STEREO_MIC, 2, 1, stac9766_stereo_mic); | 83 | AC97_STAC_STEREO_MIC, 2, stac9766_stereo_mic); |
84 | 84 | ||
85 | static const DECLARE_TLV_DB_LINEAR(master_tlv, -4600, 0); | 85 | static const DECLARE_TLV_DB_LINEAR(master_tlv, -4600, 0); |
86 | static const DECLARE_TLV_DB_LINEAR(record_tlv, 0, 2250); | 86 | static const DECLARE_TLV_DB_LINEAR(record_tlv, 0, 2250); |
diff --git a/sound/soc/codecs/tlv320aic23-i2c.c b/sound/soc/codecs/tlv320aic23-i2c.c new file mode 100644 index 000000000000..20fc46092c2c --- /dev/null +++ b/sound/soc/codecs/tlv320aic23-i2c.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * ALSA SoC TLV320AIC23 codec driver I2C interface | ||
3 | * | ||
4 | * Author: Arun KS, <arunks@mistralsolutions.com> | ||
5 | * Copyright: (C) 2008 Mistral Solutions Pvt Ltd., | ||
6 | * | ||
7 | * Based on sound/soc/codecs/wm8731.c by Richard Purdie | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/i2c.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/regmap.h> | ||
17 | #include <sound/soc.h> | ||
18 | |||
19 | #include "tlv320aic23.h" | ||
20 | |||
21 | static int tlv320aic23_i2c_probe(struct i2c_client *i2c, | ||
22 | const struct i2c_device_id *i2c_id) | ||
23 | { | ||
24 | struct regmap *regmap; | ||
25 | |||
26 | if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
27 | return -EINVAL; | ||
28 | |||
29 | regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap); | ||
30 | return tlv320aic23_probe(&i2c->dev, regmap); | ||
31 | } | ||
32 | |||
33 | static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c) | ||
34 | { | ||
35 | snd_soc_unregister_codec(&i2c->dev); | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static const struct i2c_device_id tlv320aic23_id[] = { | ||
40 | {"tlv320aic23", 0}, | ||
41 | {} | ||
42 | }; | ||
43 | |||
44 | MODULE_DEVICE_TABLE(i2c, tlv320aic23_id); | ||
45 | |||
46 | static struct i2c_driver tlv320aic23_i2c_driver = { | ||
47 | .driver = { | ||
48 | .name = "tlv320aic23-codec", | ||
49 | }, | ||
50 | .probe = tlv320aic23_i2c_probe, | ||
51 | .remove = __exit_p(tlv320aic23_i2c_remove), | ||
52 | .id_table = tlv320aic23_id, | ||
53 | }; | ||
54 | |||
55 | module_i2c_driver(tlv320aic23_i2c_driver); | ||
56 | |||
57 | MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver I2C"); | ||
58 | MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); | ||
59 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/tlv320aic23-spi.c b/sound/soc/codecs/tlv320aic23-spi.c new file mode 100644 index 000000000000..3b387e41d75d --- /dev/null +++ b/sound/soc/codecs/tlv320aic23-spi.c | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * ALSA SoC TLV320AIC23 codec driver SPI interface | ||
3 | * | ||
4 | * Author: Arun KS, <arunks@mistralsolutions.com> | ||
5 | * Copyright: (C) 2008 Mistral Solutions Pvt Ltd., | ||
6 | * | ||
7 | * Based on sound/soc/codecs/wm8731.c by Richard Purdie | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/regmap.h> | ||
16 | #include <linux/spi/spi.h> | ||
17 | #include <sound/soc.h> | ||
18 | |||
19 | #include "tlv320aic23.h" | ||
20 | |||
21 | static int aic23_spi_probe(struct spi_device *spi) | ||
22 | { | ||
23 | int ret; | ||
24 | struct regmap *regmap; | ||
25 | |||
26 | dev_dbg(&spi->dev, "probing tlv320aic23 spi device\n"); | ||
27 | |||
28 | spi->mode = SPI_MODE_0; | ||
29 | ret = spi_setup(spi); | ||
30 | if (ret < 0) | ||
31 | return ret; | ||
32 | |||
33 | regmap = devm_regmap_init_spi(spi, &tlv320aic23_regmap); | ||
34 | return tlv320aic23_probe(&spi->dev, regmap); | ||
35 | } | ||
36 | |||
37 | static int aic23_spi_remove(struct spi_device *spi) | ||
38 | { | ||
39 | snd_soc_unregister_codec(&spi->dev); | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static struct spi_driver aic23_spi = { | ||
44 | .driver = { | ||
45 | .name = "tlv320aic23", | ||
46 | .owner = THIS_MODULE, | ||
47 | }, | ||
48 | .probe = aic23_spi_probe, | ||
49 | .remove = aic23_spi_remove, | ||
50 | }; | ||
51 | |||
52 | module_spi_driver(aic23_spi); | ||
53 | |||
54 | MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver SPI"); | ||
55 | MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); | ||
56 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 5d430cc56f51..20864ee8793b 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/pm.h> | 25 | #include <linux/pm.h> |
26 | #include <linux/i2c.h> | ||
27 | #include <linux/regmap.h> | 26 | #include <linux/regmap.h> |
28 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
29 | #include <sound/core.h> | 28 | #include <sound/core.h> |
@@ -51,7 +50,7 @@ static const struct reg_default tlv320aic23_reg[] = { | |||
51 | { 9, 0x0000 }, | 50 | { 9, 0x0000 }, |
52 | }; | 51 | }; |
53 | 52 | ||
54 | static const struct regmap_config tlv320aic23_regmap = { | 53 | const struct regmap_config tlv320aic23_regmap = { |
55 | .reg_bits = 7, | 54 | .reg_bits = 7, |
56 | .val_bits = 9, | 55 | .val_bits = 9, |
57 | 56 | ||
@@ -60,20 +59,21 @@ static const struct regmap_config tlv320aic23_regmap = { | |||
60 | .num_reg_defaults = ARRAY_SIZE(tlv320aic23_reg), | 59 | .num_reg_defaults = ARRAY_SIZE(tlv320aic23_reg), |
61 | .cache_type = REGCACHE_RBTREE, | 60 | .cache_type = REGCACHE_RBTREE, |
62 | }; | 61 | }; |
62 | EXPORT_SYMBOL(tlv320aic23_regmap); | ||
63 | 63 | ||
64 | static const char *rec_src_text[] = { "Line", "Mic" }; | 64 | static const char *rec_src_text[] = { "Line", "Mic" }; |
65 | static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; | 65 | static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; |
66 | 66 | ||
67 | static const struct soc_enum rec_src_enum = | 67 | static SOC_ENUM_SINGLE_DECL(rec_src_enum, |
68 | SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text); | 68 | TLV320AIC23_ANLG, 2, rec_src_text); |
69 | 69 | ||
70 | static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls = | 70 | static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls = |
71 | SOC_DAPM_ENUM("Input Select", rec_src_enum); | 71 | SOC_DAPM_ENUM("Input Select", rec_src_enum); |
72 | 72 | ||
73 | static const struct soc_enum tlv320aic23_rec_src = | 73 | static SOC_ENUM_SINGLE_DECL(tlv320aic23_rec_src, |
74 | SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text); | 74 | TLV320AIC23_ANLG, 2, rec_src_text); |
75 | static const struct soc_enum tlv320aic23_deemph = | 75 | static SOC_ENUM_SINGLE_DECL(tlv320aic23_deemph, |
76 | SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text); | 76 | TLV320AIC23_DIGT, 1, deemph_text); |
77 | 77 | ||
78 | static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0); | 78 | static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0); |
79 | static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0); | 79 | static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0); |
@@ -400,7 +400,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream, | |||
400 | struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); | 400 | struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); |
401 | 401 | ||
402 | /* deactivate */ | 402 | /* deactivate */ |
403 | if (!codec->active) { | 403 | if (!snd_soc_codec_is_active(codec)) { |
404 | udelay(50); | 404 | udelay(50); |
405 | snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); | 405 | snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); |
406 | } | 406 | } |
@@ -557,16 +557,8 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec) | |||
557 | return 0; | 557 | return 0; |
558 | } | 558 | } |
559 | 559 | ||
560 | static int tlv320aic23_probe(struct snd_soc_codec *codec) | 560 | static int tlv320aic23_codec_probe(struct snd_soc_codec *codec) |
561 | { | 561 | { |
562 | int ret; | ||
563 | |||
564 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
565 | if (ret < 0) { | ||
566 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
567 | return ret; | ||
568 | } | ||
569 | |||
570 | /* Reset codec */ | 562 | /* Reset codec */ |
571 | snd_soc_write(codec, TLV320AIC23_RESET, 0); | 563 | snd_soc_write(codec, TLV320AIC23_RESET, 0); |
572 | 564 | ||
@@ -604,7 +596,7 @@ static int tlv320aic23_remove(struct snd_soc_codec *codec) | |||
604 | } | 596 | } |
605 | 597 | ||
606 | static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { | 598 | static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { |
607 | .probe = tlv320aic23_probe, | 599 | .probe = tlv320aic23_codec_probe, |
608 | .remove = tlv320aic23_remove, | 600 | .remove = tlv320aic23_remove, |
609 | .suspend = tlv320aic23_suspend, | 601 | .suspend = tlv320aic23_suspend, |
610 | .resume = tlv320aic23_resume, | 602 | .resume = tlv320aic23_resume, |
@@ -617,56 +609,25 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { | |||
617 | .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon), | 609 | .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon), |
618 | }; | 610 | }; |
619 | 611 | ||
620 | /* | 612 | int tlv320aic23_probe(struct device *dev, struct regmap *regmap) |
621 | * If the i2c layer weren't so broken, we could pass this kind of data | ||
622 | * around | ||
623 | */ | ||
624 | static int tlv320aic23_codec_probe(struct i2c_client *i2c, | ||
625 | const struct i2c_device_id *i2c_id) | ||
626 | { | 613 | { |
627 | struct aic23 *aic23; | 614 | struct aic23 *aic23; |
628 | int ret; | ||
629 | 615 | ||
630 | if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 616 | if (IS_ERR(regmap)) |
631 | return -EINVAL; | 617 | return PTR_ERR(regmap); |
632 | 618 | ||
633 | aic23 = devm_kzalloc(&i2c->dev, sizeof(struct aic23), GFP_KERNEL); | 619 | aic23 = devm_kzalloc(dev, sizeof(struct aic23), GFP_KERNEL); |
634 | if (aic23 == NULL) | 620 | if (aic23 == NULL) |
635 | return -ENOMEM; | 621 | return -ENOMEM; |
636 | 622 | ||
637 | aic23->regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap); | 623 | aic23->regmap = regmap; |
638 | if (IS_ERR(aic23->regmap)) | ||
639 | return PTR_ERR(aic23->regmap); | ||
640 | 624 | ||
641 | i2c_set_clientdata(i2c, aic23); | 625 | dev_set_drvdata(dev, aic23); |
642 | 626 | ||
643 | ret = snd_soc_register_codec(&i2c->dev, | 627 | return snd_soc_register_codec(dev, &soc_codec_dev_tlv320aic23, |
644 | &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1); | 628 | &tlv320aic23_dai, 1); |
645 | return ret; | ||
646 | } | 629 | } |
647 | static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c) | 630 | EXPORT_SYMBOL(tlv320aic23_probe); |
648 | { | ||
649 | snd_soc_unregister_codec(&i2c->dev); | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | static const struct i2c_device_id tlv320aic23_id[] = { | ||
654 | {"tlv320aic23", 0}, | ||
655 | {} | ||
656 | }; | ||
657 | |||
658 | MODULE_DEVICE_TABLE(i2c, tlv320aic23_id); | ||
659 | |||
660 | static struct i2c_driver tlv320aic23_i2c_driver = { | ||
661 | .driver = { | ||
662 | .name = "tlv320aic23-codec", | ||
663 | }, | ||
664 | .probe = tlv320aic23_codec_probe, | ||
665 | .remove = __exit_p(tlv320aic23_i2c_remove), | ||
666 | .id_table = tlv320aic23_id, | ||
667 | }; | ||
668 | |||
669 | module_i2c_driver(tlv320aic23_i2c_driver); | ||
670 | 631 | ||
671 | MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver"); | 632 | MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver"); |
672 | MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); | 633 | MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); |
diff --git a/sound/soc/codecs/tlv320aic23.h b/sound/soc/codecs/tlv320aic23.h index e804120bd3da..3a7235a04a89 100644 --- a/sound/soc/codecs/tlv320aic23.h +++ b/sound/soc/codecs/tlv320aic23.h | |||
@@ -12,6 +12,12 @@ | |||
12 | #ifndef _TLV320AIC23_H | 12 | #ifndef _TLV320AIC23_H |
13 | #define _TLV320AIC23_H | 13 | #define _TLV320AIC23_H |
14 | 14 | ||
15 | struct device; | ||
16 | struct regmap_config; | ||
17 | |||
18 | extern const struct regmap_config tlv320aic23_regmap; | ||
19 | int tlv320aic23_probe(struct device *dev, struct regmap *regmap); | ||
20 | |||
15 | /* Codec TLV320AIC23 */ | 21 | /* Codec TLV320AIC23 */ |
16 | #define TLV320AIC23_LINVOL 0x00 | 22 | #define TLV320AIC23_LINVOL 0x00 |
17 | #define TLV320AIC23_RINVOL 0x01 | 23 | #define TLV320AIC23_RINVOL 0x01 |
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 94a658fa6d97..43069de3d56a 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c | |||
@@ -238,8 +238,9 @@ static struct snd_soc_dai_driver aic26_dai = { | |||
238 | * ALSA controls | 238 | * ALSA controls |
239 | */ | 239 | */ |
240 | static const char *aic26_capture_src_text[] = {"Mic", "Aux"}; | 240 | static const char *aic26_capture_src_text[] = {"Mic", "Aux"}; |
241 | static const struct soc_enum aic26_capture_src_enum = | 241 | static SOC_ENUM_SINGLE_DECL(aic26_capture_src_enum, |
242 | SOC_ENUM_SINGLE(AIC26_REG_AUDIO_CTRL1, 12, 2, aic26_capture_src_text); | 242 | AIC26_REG_AUDIO_CTRL1, 12, |
243 | aic26_capture_src_text); | ||
243 | 244 | ||
244 | static const struct snd_kcontrol_new aic26_snd_controls[] = { | 245 | static const struct snd_kcontrol_new aic26_snd_controls[] = { |
245 | /* Output */ | 246 | /* Output */ |
@@ -295,8 +296,6 @@ static int aic26_probe(struct snd_soc_codec *codec) | |||
295 | struct aic26 *aic26 = dev_get_drvdata(codec->dev); | 296 | struct aic26 *aic26 = dev_get_drvdata(codec->dev); |
296 | int ret, reg; | 297 | int ret, reg; |
297 | 298 | ||
298 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | ||
299 | |||
300 | aic26->codec = codec; | 299 | aic26->codec = codec; |
301 | 300 | ||
302 | /* Reset the codec to power on defaults */ | 301 | /* Reset the codec to power on defaults */ |
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c new file mode 100644 index 000000000000..fa158cfe9b32 --- /dev/null +++ b/sound/soc/codecs/tlv320aic31xx.c | |||
@@ -0,0 +1,1280 @@ | |||
1 | /* | ||
2 | * ALSA SoC TLV320AIC31XX codec driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Texas Instruments, Inc. | ||
5 | * | ||
6 | * Author: Jyri Sarha <jsarha@ti.com> | ||
7 | * | ||
8 | * Based on ground work by: Ajit Kulkarni <x0175765@ti.com> | ||
9 | * | ||
10 | * This package is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * THIS PACKAGE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR | ||
15 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
16 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
17 | * | ||
18 | * The TLV320AIC31xx series of audio codec is a low-power, highly integrated | ||
19 | * high performance codec which provides a stereo DAC, a mono ADC, | ||
20 | * and mono/stereo Class-D speaker driver. | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/moduleparam.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/pm.h> | ||
28 | #include <linux/i2c.h> | ||
29 | #include <linux/gpio.h> | ||
30 | #include <linux/regulator/consumer.h> | ||
31 | #include <linux/of_gpio.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <sound/core.h> | ||
34 | #include <sound/pcm.h> | ||
35 | #include <sound/pcm_params.h> | ||
36 | #include <sound/soc.h> | ||
37 | #include <sound/initval.h> | ||
38 | #include <sound/tlv.h> | ||
39 | #include <dt-bindings/sound/tlv320aic31xx-micbias.h> | ||
40 | |||
41 | #include "tlv320aic31xx.h" | ||
42 | |||
43 | static const struct reg_default aic31xx_reg_defaults[] = { | ||
44 | { AIC31XX_CLKMUX, 0x00 }, | ||
45 | { AIC31XX_PLLPR, 0x11 }, | ||
46 | { AIC31XX_PLLJ, 0x04 }, | ||
47 | { AIC31XX_PLLDMSB, 0x00 }, | ||
48 | { AIC31XX_PLLDLSB, 0x00 }, | ||
49 | { AIC31XX_NDAC, 0x01 }, | ||
50 | { AIC31XX_MDAC, 0x01 }, | ||
51 | { AIC31XX_DOSRMSB, 0x00 }, | ||
52 | { AIC31XX_DOSRLSB, 0x80 }, | ||
53 | { AIC31XX_NADC, 0x01 }, | ||
54 | { AIC31XX_MADC, 0x01 }, | ||
55 | { AIC31XX_AOSR, 0x80 }, | ||
56 | { AIC31XX_IFACE1, 0x00 }, | ||
57 | { AIC31XX_DATA_OFFSET, 0x00 }, | ||
58 | { AIC31XX_IFACE2, 0x00 }, | ||
59 | { AIC31XX_BCLKN, 0x01 }, | ||
60 | { AIC31XX_DACSETUP, 0x14 }, | ||
61 | { AIC31XX_DACMUTE, 0x0c }, | ||
62 | { AIC31XX_LDACVOL, 0x00 }, | ||
63 | { AIC31XX_RDACVOL, 0x00 }, | ||
64 | { AIC31XX_ADCSETUP, 0x00 }, | ||
65 | { AIC31XX_ADCFGA, 0x80 }, | ||
66 | { AIC31XX_ADCVOL, 0x00 }, | ||
67 | { AIC31XX_HPDRIVER, 0x04 }, | ||
68 | { AIC31XX_SPKAMP, 0x06 }, | ||
69 | { AIC31XX_DACMIXERROUTE, 0x00 }, | ||
70 | { AIC31XX_LANALOGHPL, 0x7f }, | ||
71 | { AIC31XX_RANALOGHPR, 0x7f }, | ||
72 | { AIC31XX_LANALOGSPL, 0x7f }, | ||
73 | { AIC31XX_RANALOGSPR, 0x7f }, | ||
74 | { AIC31XX_HPLGAIN, 0x02 }, | ||
75 | { AIC31XX_HPRGAIN, 0x02 }, | ||
76 | { AIC31XX_SPLGAIN, 0x00 }, | ||
77 | { AIC31XX_SPRGAIN, 0x00 }, | ||
78 | { AIC31XX_MICBIAS, 0x00 }, | ||
79 | { AIC31XX_MICPGA, 0x80 }, | ||
80 | { AIC31XX_MICPGAPI, 0x00 }, | ||
81 | { AIC31XX_MICPGAMI, 0x00 }, | ||
82 | }; | ||
83 | |||
84 | static bool aic31xx_volatile(struct device *dev, unsigned int reg) | ||
85 | { | ||
86 | switch (reg) { | ||
87 | case AIC31XX_PAGECTL: /* regmap implementation requires this */ | ||
88 | case AIC31XX_RESET: /* always clears after write */ | ||
89 | case AIC31XX_OT_FLAG: | ||
90 | case AIC31XX_ADCFLAG: | ||
91 | case AIC31XX_DACFLAG1: | ||
92 | case AIC31XX_DACFLAG2: | ||
93 | case AIC31XX_OFFLAG: /* Sticky interrupt flags */ | ||
94 | case AIC31XX_INTRDACFLAG: /* Sticky interrupt flags */ | ||
95 | case AIC31XX_INTRADCFLAG: /* Sticky interrupt flags */ | ||
96 | case AIC31XX_INTRDACFLAG2: | ||
97 | case AIC31XX_INTRADCFLAG2: | ||
98 | return true; | ||
99 | } | ||
100 | return false; | ||
101 | } | ||
102 | |||
103 | static bool aic31xx_writeable(struct device *dev, unsigned int reg) | ||
104 | { | ||
105 | switch (reg) { | ||
106 | case AIC31XX_OT_FLAG: | ||
107 | case AIC31XX_ADCFLAG: | ||
108 | case AIC31XX_DACFLAG1: | ||
109 | case AIC31XX_DACFLAG2: | ||
110 | case AIC31XX_OFFLAG: /* Sticky interrupt flags */ | ||
111 | case AIC31XX_INTRDACFLAG: /* Sticky interrupt flags */ | ||
112 | case AIC31XX_INTRADCFLAG: /* Sticky interrupt flags */ | ||
113 | case AIC31XX_INTRDACFLAG2: | ||
114 | case AIC31XX_INTRADCFLAG2: | ||
115 | return false; | ||
116 | } | ||
117 | return true; | ||
118 | } | ||
119 | |||
120 | static const struct regmap_range_cfg aic31xx_ranges[] = { | ||
121 | { | ||
122 | .range_min = 0, | ||
123 | .range_max = 12 * 128, | ||
124 | .selector_reg = AIC31XX_PAGECTL, | ||
125 | .selector_mask = 0xff, | ||
126 | .selector_shift = 0, | ||
127 | .window_start = 0, | ||
128 | .window_len = 128, | ||
129 | }, | ||
130 | }; | ||
131 | |||
132 | static const struct regmap_config aic31xx_i2c_regmap = { | ||
133 | .reg_bits = 8, | ||
134 | .val_bits = 8, | ||
135 | .writeable_reg = aic31xx_writeable, | ||
136 | .volatile_reg = aic31xx_volatile, | ||
137 | .reg_defaults = aic31xx_reg_defaults, | ||
138 | .num_reg_defaults = ARRAY_SIZE(aic31xx_reg_defaults), | ||
139 | .cache_type = REGCACHE_RBTREE, | ||
140 | .ranges = aic31xx_ranges, | ||
141 | .num_ranges = ARRAY_SIZE(aic31xx_ranges), | ||
142 | .max_register = 12 * 128, | ||
143 | }; | ||
144 | |||
145 | #define AIC31XX_NUM_SUPPLIES 6 | ||
146 | static const char * const aic31xx_supply_names[AIC31XX_NUM_SUPPLIES] = { | ||
147 | "HPVDD", | ||
148 | "SPRVDD", | ||
149 | "SPLVDD", | ||
150 | "AVDD", | ||
151 | "IOVDD", | ||
152 | "DVDD", | ||
153 | }; | ||
154 | |||
155 | struct aic31xx_disable_nb { | ||
156 | struct notifier_block nb; | ||
157 | struct aic31xx_priv *aic31xx; | ||
158 | }; | ||
159 | |||
160 | struct aic31xx_priv { | ||
161 | struct snd_soc_codec *codec; | ||
162 | u8 i2c_regs_status; | ||
163 | struct device *dev; | ||
164 | struct regmap *regmap; | ||
165 | struct aic31xx_pdata pdata; | ||
166 | struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES]; | ||
167 | struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES]; | ||
168 | unsigned int sysclk; | ||
169 | int rate_div_line; | ||
170 | }; | ||
171 | |||
172 | struct aic31xx_rate_divs { | ||
173 | u32 mclk; | ||
174 | u32 rate; | ||
175 | u8 p_val; | ||
176 | u8 pll_j; | ||
177 | u16 pll_d; | ||
178 | u16 dosr; | ||
179 | u8 ndac; | ||
180 | u8 mdac; | ||
181 | u8 aosr; | ||
182 | u8 nadc; | ||
183 | u8 madc; | ||
184 | }; | ||
185 | |||
186 | /* ADC dividers can be disabled by cofiguring them to 0 */ | ||
187 | static const struct aic31xx_rate_divs aic31xx_divs[] = { | ||
188 | /* mclk rate pll: p j d dosr ndac mdac aors nadc madc */ | ||
189 | /* 8k rate */ | ||
190 | {12000000, 8000, 1, 8, 1920, 128, 48, 2, 128, 48, 2}, | ||
191 | {24000000, 8000, 2, 8, 1920, 128, 48, 2, 128, 48, 2}, | ||
192 | {25000000, 8000, 2, 7, 8643, 128, 48, 2, 128, 48, 2}, | ||
193 | /* 11.025k rate */ | ||
194 | {12000000, 11025, 1, 7, 5264, 128, 32, 2, 128, 32, 2}, | ||
195 | {24000000, 11025, 2, 7, 5264, 128, 32, 2, 128, 32, 2}, | ||
196 | {25000000, 11025, 2, 7, 2253, 128, 32, 2, 128, 32, 2}, | ||
197 | /* 16k rate */ | ||
198 | {12000000, 16000, 1, 8, 1920, 128, 24, 2, 128, 24, 2}, | ||
199 | {24000000, 16000, 2, 8, 1920, 128, 24, 2, 128, 24, 2}, | ||
200 | {25000000, 16000, 2, 7, 8643, 128, 24, 2, 128, 24, 2}, | ||
201 | /* 22.05k rate */ | ||
202 | {12000000, 22050, 1, 7, 5264, 128, 16, 2, 128, 16, 2}, | ||
203 | {24000000, 22050, 2, 7, 5264, 128, 16, 2, 128, 16, 2}, | ||
204 | {25000000, 22050, 2, 7, 2253, 128, 16, 2, 128, 16, 2}, | ||
205 | /* 32k rate */ | ||
206 | {12000000, 32000, 1, 8, 1920, 128, 12, 2, 128, 12, 2}, | ||
207 | {24000000, 32000, 2, 8, 1920, 128, 12, 2, 128, 12, 2}, | ||
208 | {25000000, 32000, 2, 7, 8643, 128, 12, 2, 128, 12, 2}, | ||
209 | /* 44.1k rate */ | ||
210 | {12000000, 44100, 1, 7, 5264, 128, 8, 2, 128, 8, 2}, | ||
211 | {24000000, 44100, 2, 7, 5264, 128, 8, 2, 128, 8, 2}, | ||
212 | {25000000, 44100, 2, 7, 2253, 128, 8, 2, 128, 8, 2}, | ||
213 | /* 48k rate */ | ||
214 | {12000000, 48000, 1, 8, 1920, 128, 8, 2, 128, 8, 2}, | ||
215 | {24000000, 48000, 2, 8, 1920, 128, 8, 2, 128, 8, 2}, | ||
216 | {25000000, 48000, 2, 7, 8643, 128, 8, 2, 128, 8, 2}, | ||
217 | /* 88.2k rate */ | ||
218 | {12000000, 88200, 1, 7, 5264, 64, 8, 2, 64, 8, 2}, | ||
219 | {24000000, 88200, 2, 7, 5264, 64, 8, 2, 64, 8, 2}, | ||
220 | {25000000, 88200, 2, 7, 2253, 64, 8, 2, 64, 8, 2}, | ||
221 | /* 96k rate */ | ||
222 | {12000000, 96000, 1, 8, 1920, 64, 8, 2, 64, 8, 2}, | ||
223 | {24000000, 96000, 2, 8, 1920, 64, 8, 2, 64, 8, 2}, | ||
224 | {25000000, 96000, 2, 7, 8643, 64, 8, 2, 64, 8, 2}, | ||
225 | /* 176.4k rate */ | ||
226 | {12000000, 176400, 1, 7, 5264, 32, 8, 2, 32, 8, 2}, | ||
227 | {24000000, 176400, 2, 7, 5264, 32, 8, 2, 32, 8, 2}, | ||
228 | {25000000, 176400, 2, 7, 2253, 32, 8, 2, 32, 8, 2}, | ||
229 | /* 192k rate */ | ||
230 | {12000000, 192000, 1, 8, 1920, 32, 8, 2, 32, 8, 2}, | ||
231 | {24000000, 192000, 2, 8, 1920, 32, 8, 2, 32, 8, 2}, | ||
232 | {25000000, 192000, 2, 7, 8643, 32, 8, 2, 32, 8, 2}, | ||
233 | }; | ||
234 | |||
235 | static const char * const ldac_in_text[] = { | ||
236 | "Off", "Left Data", "Right Data", "Mono" | ||
237 | }; | ||
238 | |||
239 | static const char * const rdac_in_text[] = { | ||
240 | "Off", "Right Data", "Left Data", "Mono" | ||
241 | }; | ||
242 | |||
243 | static SOC_ENUM_SINGLE_DECL(ldac_in_enum, AIC31XX_DACSETUP, 4, ldac_in_text); | ||
244 | |||
245 | static SOC_ENUM_SINGLE_DECL(rdac_in_enum, AIC31XX_DACSETUP, 2, rdac_in_text); | ||
246 | |||
247 | static const char * const mic_select_text[] = { | ||
248 | "Off", "FFR 10 Ohm", "FFR 20 Ohm", "FFR 40 Ohm" | ||
249 | }; | ||
250 | |||
251 | static const | ||
252 | SOC_ENUM_SINGLE_DECL(mic1lp_p_enum, AIC31XX_MICPGAPI, 6, mic_select_text); | ||
253 | static const | ||
254 | SOC_ENUM_SINGLE_DECL(mic1rp_p_enum, AIC31XX_MICPGAPI, 4, mic_select_text); | ||
255 | static const | ||
256 | SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2, mic_select_text); | ||
257 | |||
258 | static const | ||
259 | SOC_ENUM_SINGLE_DECL(cm_m_enum, AIC31XX_MICPGAMI, 6, mic_select_text); | ||
260 | static const | ||
261 | SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4, mic_select_text); | ||
262 | |||
263 | static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6350, 50, 0); | ||
264 | static const DECLARE_TLV_DB_SCALE(adc_fgain_tlv, 0, 10, 0); | ||
265 | static const DECLARE_TLV_DB_SCALE(adc_cgain_tlv, -2000, 50, 0); | ||
266 | static const DECLARE_TLV_DB_SCALE(mic_pga_tlv, 0, 50, 0); | ||
267 | static const DECLARE_TLV_DB_SCALE(hp_drv_tlv, 0, 100, 0); | ||
268 | static const DECLARE_TLV_DB_SCALE(class_D_drv_tlv, 600, 600, 0); | ||
269 | static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -6350, 50, 0); | ||
270 | static const DECLARE_TLV_DB_SCALE(sp_vol_tlv, -6350, 50, 0); | ||
271 | |||
272 | /* | ||
273 | * controls to be exported to the user space | ||
274 | */ | ||
275 | static const struct snd_kcontrol_new aic31xx_snd_controls[] = { | ||
276 | SOC_DOUBLE_R_S_TLV("DAC Playback Volume", AIC31XX_LDACVOL, | ||
277 | AIC31XX_RDACVOL, 0, -127, 48, 7, 0, dac_vol_tlv), | ||
278 | |||
279 | SOC_SINGLE_TLV("ADC Fine Capture Volume", AIC31XX_ADCFGA, 4, 4, 1, | ||
280 | adc_fgain_tlv), | ||
281 | |||
282 | SOC_SINGLE("ADC Capture Switch", AIC31XX_ADCFGA, 7, 1, 1), | ||
283 | SOC_DOUBLE_R_S_TLV("ADC Capture Volume", AIC31XX_ADCVOL, AIC31XX_ADCVOL, | ||
284 | 0, -24, 40, 6, 0, adc_cgain_tlv), | ||
285 | |||
286 | SOC_SINGLE_TLV("Mic PGA Capture Volume", AIC31XX_MICPGA, 0, | ||
287 | 119, 0, mic_pga_tlv), | ||
288 | |||
289 | SOC_DOUBLE_R("HP Driver Playback Switch", AIC31XX_HPLGAIN, | ||
290 | AIC31XX_HPRGAIN, 2, 1, 0), | ||
291 | SOC_DOUBLE_R_TLV("HP Driver Playback Volume", AIC31XX_HPLGAIN, | ||
292 | AIC31XX_HPRGAIN, 3, 0x09, 0, hp_drv_tlv), | ||
293 | |||
294 | SOC_DOUBLE_R_TLV("HP Analog Playback Volume", AIC31XX_LANALOGHPL, | ||
295 | AIC31XX_RANALOGHPR, 0, 0x7F, 1, hp_vol_tlv), | ||
296 | }; | ||
297 | |||
298 | static const struct snd_kcontrol_new aic311x_snd_controls[] = { | ||
299 | SOC_DOUBLE_R("Speaker Driver Playback Switch", AIC31XX_SPLGAIN, | ||
300 | AIC31XX_SPRGAIN, 2, 1, 0), | ||
301 | SOC_DOUBLE_R_TLV("Speaker Driver Playback Volume", AIC31XX_SPLGAIN, | ||
302 | AIC31XX_SPRGAIN, 3, 3, 0, class_D_drv_tlv), | ||
303 | |||
304 | SOC_DOUBLE_R_TLV("Speaker Analog Playback Volume", AIC31XX_LANALOGSPL, | ||
305 | AIC31XX_RANALOGSPR, 0, 0x7F, 1, sp_vol_tlv), | ||
306 | }; | ||
307 | |||
308 | static const struct snd_kcontrol_new aic310x_snd_controls[] = { | ||
309 | SOC_SINGLE("Speaker Driver Playback Switch", AIC31XX_SPLGAIN, | ||
310 | 2, 1, 0), | ||
311 | SOC_SINGLE_TLV("Speaker Driver Playback Volume", AIC31XX_SPLGAIN, | ||
312 | 3, 3, 0, class_D_drv_tlv), | ||
313 | |||
314 | SOC_SINGLE_TLV("Speaker Analog Playback Volume", AIC31XX_LANALOGSPL, | ||
315 | 0, 0x7F, 1, sp_vol_tlv), | ||
316 | }; | ||
317 | |||
318 | static const struct snd_kcontrol_new ldac_in_control = | ||
319 | SOC_DAPM_ENUM("DAC Left Input", ldac_in_enum); | ||
320 | |||
321 | static const struct snd_kcontrol_new rdac_in_control = | ||
322 | SOC_DAPM_ENUM("DAC Right Input", rdac_in_enum); | ||
323 | |||
324 | static int aic31xx_wait_bits(struct aic31xx_priv *aic31xx, unsigned int reg, | ||
325 | unsigned int mask, unsigned int wbits, int sleep, | ||
326 | int count) | ||
327 | { | ||
328 | unsigned int bits; | ||
329 | int counter = count; | ||
330 | int ret = regmap_read(aic31xx->regmap, reg, &bits); | ||
331 | while ((bits & mask) != wbits && counter && !ret) { | ||
332 | usleep_range(sleep, sleep * 2); | ||
333 | ret = regmap_read(aic31xx->regmap, reg, &bits); | ||
334 | counter--; | ||
335 | } | ||
336 | if ((bits & mask) != wbits) { | ||
337 | dev_err(aic31xx->dev, | ||
338 | "%s: Failed! 0x%x was 0x%x expected 0x%x (%d, 0x%x, %d us)\n", | ||
339 | __func__, reg, bits, wbits, ret, mask, | ||
340 | (count - counter) * sleep); | ||
341 | ret = -1; | ||
342 | } | ||
343 | return ret; | ||
344 | } | ||
345 | |||
346 | #define WIDGET_BIT(reg, shift) (((shift) << 8) | (reg)) | ||
347 | |||
348 | static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w, | ||
349 | struct snd_kcontrol *kcontrol, int event) | ||
350 | { | ||
351 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(w->codec); | ||
352 | unsigned int reg = AIC31XX_DACFLAG1; | ||
353 | unsigned int mask; | ||
354 | |||
355 | switch (WIDGET_BIT(w->reg, w->shift)) { | ||
356 | case WIDGET_BIT(AIC31XX_DACSETUP, 7): | ||
357 | mask = AIC31XX_LDACPWRSTATUS_MASK; | ||
358 | break; | ||
359 | case WIDGET_BIT(AIC31XX_DACSETUP, 6): | ||
360 | mask = AIC31XX_RDACPWRSTATUS_MASK; | ||
361 | break; | ||
362 | case WIDGET_BIT(AIC31XX_HPDRIVER, 7): | ||
363 | mask = AIC31XX_HPLDRVPWRSTATUS_MASK; | ||
364 | break; | ||
365 | case WIDGET_BIT(AIC31XX_HPDRIVER, 6): | ||
366 | mask = AIC31XX_HPRDRVPWRSTATUS_MASK; | ||
367 | break; | ||
368 | case WIDGET_BIT(AIC31XX_SPKAMP, 7): | ||
369 | mask = AIC31XX_SPLDRVPWRSTATUS_MASK; | ||
370 | break; | ||
371 | case WIDGET_BIT(AIC31XX_SPKAMP, 6): | ||
372 | mask = AIC31XX_SPRDRVPWRSTATUS_MASK; | ||
373 | break; | ||
374 | case WIDGET_BIT(AIC31XX_ADCSETUP, 7): | ||
375 | mask = AIC31XX_ADCPWRSTATUS_MASK; | ||
376 | reg = AIC31XX_ADCFLAG; | ||
377 | break; | ||
378 | default: | ||
379 | dev_err(w->codec->dev, "Unknown widget '%s' calling %s/n", | ||
380 | w->name, __func__); | ||
381 | return -EINVAL; | ||
382 | } | ||
383 | |||
384 | switch (event) { | ||
385 | case SND_SOC_DAPM_POST_PMU: | ||
386 | return aic31xx_wait_bits(aic31xx, reg, mask, mask, 5000, 100); | ||
387 | case SND_SOC_DAPM_POST_PMD: | ||
388 | return aic31xx_wait_bits(aic31xx, reg, mask, 0, 5000, 100); | ||
389 | default: | ||
390 | dev_dbg(w->codec->dev, | ||
391 | "Unhandled dapm widget event %d from %s\n", | ||
392 | event, w->name); | ||
393 | } | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | static const struct snd_kcontrol_new left_output_switches[] = { | ||
398 | SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0), | ||
399 | SOC_DAPM_SINGLE("From MIC1LP", AIC31XX_DACMIXERROUTE, 5, 1, 0), | ||
400 | SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 4, 1, 0), | ||
401 | }; | ||
402 | |||
403 | static const struct snd_kcontrol_new right_output_switches[] = { | ||
404 | SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0), | ||
405 | SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 1, 1, 0), | ||
406 | }; | ||
407 | |||
408 | static const struct snd_kcontrol_new p_term_mic1lp = | ||
409 | SOC_DAPM_ENUM("MIC1LP P-Terminal", mic1lp_p_enum); | ||
410 | |||
411 | static const struct snd_kcontrol_new p_term_mic1rp = | ||
412 | SOC_DAPM_ENUM("MIC1RP P-Terminal", mic1rp_p_enum); | ||
413 | |||
414 | static const struct snd_kcontrol_new p_term_mic1lm = | ||
415 | SOC_DAPM_ENUM("MIC1LM P-Terminal", mic1lm_p_enum); | ||
416 | |||
417 | static const struct snd_kcontrol_new m_term_mic1lm = | ||
418 | SOC_DAPM_ENUM("MIC1LM M-Terminal", mic1lm_m_enum); | ||
419 | |||
420 | static const struct snd_kcontrol_new aic31xx_dapm_hpl_switch = | ||
421 | SOC_DAPM_SINGLE("Switch", AIC31XX_LANALOGHPL, 7, 1, 0); | ||
422 | |||
423 | static const struct snd_kcontrol_new aic31xx_dapm_hpr_switch = | ||
424 | SOC_DAPM_SINGLE("Switch", AIC31XX_RANALOGHPR, 7, 1, 0); | ||
425 | |||
426 | static const struct snd_kcontrol_new aic31xx_dapm_spl_switch = | ||
427 | SOC_DAPM_SINGLE("Switch", AIC31XX_LANALOGSPL, 7, 1, 0); | ||
428 | |||
429 | static const struct snd_kcontrol_new aic31xx_dapm_spr_switch = | ||
430 | SOC_DAPM_SINGLE("Switch", AIC31XX_RANALOGSPR, 7, 1, 0); | ||
431 | |||
432 | static int mic_bias_event(struct snd_soc_dapm_widget *w, | ||
433 | struct snd_kcontrol *kcontrol, int event) | ||
434 | { | ||
435 | struct snd_soc_codec *codec = w->codec; | ||
436 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | ||
437 | switch (event) { | ||
438 | case SND_SOC_DAPM_POST_PMU: | ||
439 | /* change mic bias voltage to user defined */ | ||
440 | snd_soc_update_bits(codec, AIC31XX_MICBIAS, | ||
441 | AIC31XX_MICBIAS_MASK, | ||
442 | aic31xx->pdata.micbias_vg << | ||
443 | AIC31XX_MICBIAS_SHIFT); | ||
444 | dev_dbg(codec->dev, "%s: turned on\n", __func__); | ||
445 | break; | ||
446 | case SND_SOC_DAPM_PRE_PMD: | ||
447 | /* turn mic bias off */ | ||
448 | snd_soc_update_bits(codec, AIC31XX_MICBIAS, | ||
449 | AIC31XX_MICBIAS_MASK, 0); | ||
450 | dev_dbg(codec->dev, "%s: turned off\n", __func__); | ||
451 | break; | ||
452 | } | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { | ||
457 | SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0), | ||
458 | |||
459 | SND_SOC_DAPM_MUX("DAC Left Input", | ||
460 | SND_SOC_NOPM, 0, 0, &ldac_in_control), | ||
461 | SND_SOC_DAPM_MUX("DAC Right Input", | ||
462 | SND_SOC_NOPM, 0, 0, &rdac_in_control), | ||
463 | /* DACs */ | ||
464 | SND_SOC_DAPM_DAC_E("DAC Left", "Left Playback", | ||
465 | AIC31XX_DACSETUP, 7, 0, aic31xx_dapm_power_event, | ||
466 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
467 | |||
468 | SND_SOC_DAPM_DAC_E("DAC Right", "Right Playback", | ||
469 | AIC31XX_DACSETUP, 6, 0, aic31xx_dapm_power_event, | ||
470 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
471 | |||
472 | /* Output Mixers */ | ||
473 | SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0, | ||
474 | left_output_switches, | ||
475 | ARRAY_SIZE(left_output_switches)), | ||
476 | SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0, | ||
477 | right_output_switches, | ||
478 | ARRAY_SIZE(right_output_switches)), | ||
479 | |||
480 | SND_SOC_DAPM_SWITCH("HP Left", SND_SOC_NOPM, 0, 0, | ||
481 | &aic31xx_dapm_hpl_switch), | ||
482 | SND_SOC_DAPM_SWITCH("HP Right", SND_SOC_NOPM, 0, 0, | ||
483 | &aic31xx_dapm_hpr_switch), | ||
484 | |||
485 | /* Output drivers */ | ||
486 | SND_SOC_DAPM_OUT_DRV_E("HPL Driver", AIC31XX_HPDRIVER, 7, 0, | ||
487 | NULL, 0, aic31xx_dapm_power_event, | ||
488 | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), | ||
489 | SND_SOC_DAPM_OUT_DRV_E("HPR Driver", AIC31XX_HPDRIVER, 6, 0, | ||
490 | NULL, 0, aic31xx_dapm_power_event, | ||
491 | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), | ||
492 | |||
493 | /* ADC */ | ||
494 | SND_SOC_DAPM_ADC_E("ADC", "Capture", AIC31XX_ADCSETUP, 7, 0, | ||
495 | aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | | ||
496 | SND_SOC_DAPM_POST_PMD), | ||
497 | |||
498 | /* Input Selection to MIC_PGA */ | ||
499 | SND_SOC_DAPM_MUX("MIC1LP P-Terminal", SND_SOC_NOPM, 0, 0, | ||
500 | &p_term_mic1lp), | ||
501 | SND_SOC_DAPM_MUX("MIC1RP P-Terminal", SND_SOC_NOPM, 0, 0, | ||
502 | &p_term_mic1rp), | ||
503 | SND_SOC_DAPM_MUX("MIC1LM P-Terminal", SND_SOC_NOPM, 0, 0, | ||
504 | &p_term_mic1lm), | ||
505 | |||
506 | SND_SOC_DAPM_MUX("MIC1LM M-Terminal", SND_SOC_NOPM, 0, 0, | ||
507 | &m_term_mic1lm), | ||
508 | /* Enabling & Disabling MIC Gain Ctl */ | ||
509 | SND_SOC_DAPM_PGA("MIC_GAIN_CTL", AIC31XX_MICPGA, | ||
510 | 7, 1, NULL, 0), | ||
511 | |||
512 | /* Mic Bias */ | ||
513 | SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, mic_bias_event, | ||
514 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
515 | |||
516 | /* Outputs */ | ||
517 | SND_SOC_DAPM_OUTPUT("HPL"), | ||
518 | SND_SOC_DAPM_OUTPUT("HPR"), | ||
519 | |||
520 | /* Inputs */ | ||
521 | SND_SOC_DAPM_INPUT("MIC1LP"), | ||
522 | SND_SOC_DAPM_INPUT("MIC1RP"), | ||
523 | SND_SOC_DAPM_INPUT("MIC1LM"), | ||
524 | }; | ||
525 | |||
526 | static const struct snd_soc_dapm_widget aic311x_dapm_widgets[] = { | ||
527 | /* AIC3111 and AIC3110 have stereo class-D amplifier */ | ||
528 | SND_SOC_DAPM_OUT_DRV_E("SPL ClassD", AIC31XX_SPKAMP, 7, 0, NULL, 0, | ||
529 | aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | | ||
530 | SND_SOC_DAPM_POST_PMD), | ||
531 | SND_SOC_DAPM_OUT_DRV_E("SPR ClassD", AIC31XX_SPKAMP, 6, 0, NULL, 0, | ||
532 | aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | | ||
533 | SND_SOC_DAPM_POST_PMD), | ||
534 | SND_SOC_DAPM_SWITCH("Speaker Left", SND_SOC_NOPM, 0, 0, | ||
535 | &aic31xx_dapm_spl_switch), | ||
536 | SND_SOC_DAPM_SWITCH("Speaker Right", SND_SOC_NOPM, 0, 0, | ||
537 | &aic31xx_dapm_spr_switch), | ||
538 | SND_SOC_DAPM_OUTPUT("SPL"), | ||
539 | SND_SOC_DAPM_OUTPUT("SPR"), | ||
540 | }; | ||
541 | |||
542 | /* AIC3100 and AIC3120 have only mono class-D amplifier */ | ||
543 | static const struct snd_soc_dapm_widget aic310x_dapm_widgets[] = { | ||
544 | SND_SOC_DAPM_OUT_DRV_E("SPK ClassD", AIC31XX_SPKAMP, 7, 0, NULL, 0, | ||
545 | aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | | ||
546 | SND_SOC_DAPM_POST_PMD), | ||
547 | SND_SOC_DAPM_SWITCH("Speaker", SND_SOC_NOPM, 0, 0, | ||
548 | &aic31xx_dapm_spl_switch), | ||
549 | SND_SOC_DAPM_OUTPUT("SPK"), | ||
550 | }; | ||
551 | |||
552 | static const struct snd_soc_dapm_route | ||
553 | aic31xx_audio_map[] = { | ||
554 | /* DAC Input Routing */ | ||
555 | {"DAC Left Input", "Left Data", "DAC IN"}, | ||
556 | {"DAC Left Input", "Right Data", "DAC IN"}, | ||
557 | {"DAC Left Input", "Mono", "DAC IN"}, | ||
558 | {"DAC Right Input", "Left Data", "DAC IN"}, | ||
559 | {"DAC Right Input", "Right Data", "DAC IN"}, | ||
560 | {"DAC Right Input", "Mono", "DAC IN"}, | ||
561 | {"DAC Left", NULL, "DAC Left Input"}, | ||
562 | {"DAC Right", NULL, "DAC Right Input"}, | ||
563 | |||
564 | /* Mic input */ | ||
565 | {"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"}, | ||
566 | {"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"}, | ||
567 | {"MIC1LP P-Terminal", "FFR 40 Ohm", "MIC1LP"}, | ||
568 | {"MIC1RP P-Terminal", "FFR 10 Ohm", "MIC1RP"}, | ||
569 | {"MIC1RP P-Terminal", "FFR 20 Ohm", "MIC1RP"}, | ||
570 | {"MIC1RP P-Terminal", "FFR 40 Ohm", "MIC1RP"}, | ||
571 | {"MIC1LM P-Terminal", "FFR 10 Ohm", "MIC1LM"}, | ||
572 | {"MIC1LM P-Terminal", "FFR 20 Ohm", "MIC1LM"}, | ||
573 | {"MIC1LM P-Terminal", "FFR 40 Ohm", "MIC1LM"}, | ||
574 | |||
575 | {"MIC1LM M-Terminal", "FFR 10 Ohm", "MIC1LM"}, | ||
576 | {"MIC1LM M-Terminal", "FFR 20 Ohm", "MIC1LM"}, | ||
577 | {"MIC1LM M-Terminal", "FFR 40 Ohm", "MIC1LM"}, | ||
578 | |||
579 | {"MIC_GAIN_CTL", NULL, "MIC1LP P-Terminal"}, | ||
580 | {"MIC_GAIN_CTL", NULL, "MIC1RP P-Terminal"}, | ||
581 | {"MIC_GAIN_CTL", NULL, "MIC1LM P-Terminal"}, | ||
582 | {"MIC_GAIN_CTL", NULL, "MIC1LM M-Terminal"}, | ||
583 | |||
584 | {"ADC", NULL, "MIC_GAIN_CTL"}, | ||
585 | |||
586 | /* Left Output */ | ||
587 | {"Output Left", "From Left DAC", "DAC Left"}, | ||
588 | {"Output Left", "From MIC1LP", "MIC1LP"}, | ||
589 | {"Output Left", "From MIC1RP", "MIC1RP"}, | ||
590 | |||
591 | /* Right Output */ | ||
592 | {"Output Right", "From Right DAC", "DAC Right"}, | ||
593 | {"Output Right", "From MIC1RP", "MIC1RP"}, | ||
594 | |||
595 | /* HPL path */ | ||
596 | {"HP Left", "Switch", "Output Left"}, | ||
597 | {"HPL Driver", NULL, "HP Left"}, | ||
598 | {"HPL", NULL, "HPL Driver"}, | ||
599 | |||
600 | /* HPR path */ | ||
601 | {"HP Right", "Switch", "Output Right"}, | ||
602 | {"HPR Driver", NULL, "HP Right"}, | ||
603 | {"HPR", NULL, "HPR Driver"}, | ||
604 | }; | ||
605 | |||
606 | static const struct snd_soc_dapm_route | ||
607 | aic311x_audio_map[] = { | ||
608 | /* SP L path */ | ||
609 | {"Speaker Left", "Switch", "Output Left"}, | ||
610 | {"SPL ClassD", NULL, "Speaker Left"}, | ||
611 | {"SPL", NULL, "SPL ClassD"}, | ||
612 | |||
613 | /* SP R path */ | ||
614 | {"Speaker Right", "Switch", "Output Right"}, | ||
615 | {"SPR ClassD", NULL, "Speaker Right"}, | ||
616 | {"SPR", NULL, "SPR ClassD"}, | ||
617 | }; | ||
618 | |||
619 | static const struct snd_soc_dapm_route | ||
620 | aic310x_audio_map[] = { | ||
621 | /* SP L path */ | ||
622 | {"Speaker", "Switch", "Output Left"}, | ||
623 | {"SPK ClassD", NULL, "Speaker"}, | ||
624 | {"SPK", NULL, "SPK ClassD"}, | ||
625 | }; | ||
626 | |||
627 | static int aic31xx_add_controls(struct snd_soc_codec *codec) | ||
628 | { | ||
629 | int ret = 0; | ||
630 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | ||
631 | |||
632 | if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) | ||
633 | ret = snd_soc_add_codec_controls( | ||
634 | codec, aic311x_snd_controls, | ||
635 | ARRAY_SIZE(aic311x_snd_controls)); | ||
636 | else | ||
637 | ret = snd_soc_add_codec_controls( | ||
638 | codec, aic310x_snd_controls, | ||
639 | ARRAY_SIZE(aic310x_snd_controls)); | ||
640 | |||
641 | return ret; | ||
642 | } | ||
643 | |||
644 | static int aic31xx_add_widgets(struct snd_soc_codec *codec) | ||
645 | { | ||
646 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
647 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | ||
648 | int ret = 0; | ||
649 | |||
650 | if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) { | ||
651 | ret = snd_soc_dapm_new_controls( | ||
652 | dapm, aic311x_dapm_widgets, | ||
653 | ARRAY_SIZE(aic311x_dapm_widgets)); | ||
654 | if (ret) | ||
655 | return ret; | ||
656 | |||
657 | ret = snd_soc_dapm_add_routes(dapm, aic311x_audio_map, | ||
658 | ARRAY_SIZE(aic311x_audio_map)); | ||
659 | if (ret) | ||
660 | return ret; | ||
661 | } else { | ||
662 | ret = snd_soc_dapm_new_controls( | ||
663 | dapm, aic310x_dapm_widgets, | ||
664 | ARRAY_SIZE(aic310x_dapm_widgets)); | ||
665 | if (ret) | ||
666 | return ret; | ||
667 | |||
668 | ret = snd_soc_dapm_add_routes(dapm, aic310x_audio_map, | ||
669 | ARRAY_SIZE(aic310x_audio_map)); | ||
670 | if (ret) | ||
671 | return ret; | ||
672 | } | ||
673 | |||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | static int aic31xx_setup_pll(struct snd_soc_codec *codec, | ||
678 | struct snd_pcm_hw_params *params) | ||
679 | { | ||
680 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | ||
681 | int bclk_n = 0; | ||
682 | int i; | ||
683 | |||
684 | /* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */ | ||
685 | snd_soc_update_bits(codec, AIC31XX_CLKMUX, | ||
686 | AIC31XX_CODEC_CLKIN_MASK, AIC31XX_CODEC_CLKIN_PLL); | ||
687 | snd_soc_update_bits(codec, AIC31XX_IFACE2, | ||
688 | AIC31XX_BDIVCLK_MASK, AIC31XX_DAC2BCLK); | ||
689 | |||
690 | for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) { | ||
691 | if (aic31xx_divs[i].rate == params_rate(params) && | ||
692 | aic31xx_divs[i].mclk == aic31xx->sysclk) | ||
693 | break; | ||
694 | } | ||
695 | |||
696 | if (i == ARRAY_SIZE(aic31xx_divs)) { | ||
697 | dev_err(codec->dev, "%s: Sampling rate %u not supported\n", | ||
698 | __func__, params_rate(params)); | ||
699 | return -EINVAL; | ||
700 | } | ||
701 | |||
702 | /* PLL configuration */ | ||
703 | snd_soc_update_bits(codec, AIC31XX_PLLPR, AIC31XX_PLL_MASK, | ||
704 | (aic31xx_divs[i].p_val << 4) | 0x01); | ||
705 | snd_soc_write(codec, AIC31XX_PLLJ, aic31xx_divs[i].pll_j); | ||
706 | |||
707 | snd_soc_write(codec, AIC31XX_PLLDMSB, | ||
708 | aic31xx_divs[i].pll_d >> 8); | ||
709 | snd_soc_write(codec, AIC31XX_PLLDLSB, | ||
710 | aic31xx_divs[i].pll_d & 0xff); | ||
711 | |||
712 | /* DAC dividers configuration */ | ||
713 | snd_soc_update_bits(codec, AIC31XX_NDAC, AIC31XX_PLL_MASK, | ||
714 | aic31xx_divs[i].ndac); | ||
715 | snd_soc_update_bits(codec, AIC31XX_MDAC, AIC31XX_PLL_MASK, | ||
716 | aic31xx_divs[i].mdac); | ||
717 | |||
718 | snd_soc_write(codec, AIC31XX_DOSRMSB, aic31xx_divs[i].dosr >> 8); | ||
719 | snd_soc_write(codec, AIC31XX_DOSRLSB, aic31xx_divs[i].dosr & 0xff); | ||
720 | |||
721 | /* ADC dividers configuration. Write reset value 1 if not used. */ | ||
722 | snd_soc_update_bits(codec, AIC31XX_NADC, AIC31XX_PLL_MASK, | ||
723 | aic31xx_divs[i].nadc ? aic31xx_divs[i].nadc : 1); | ||
724 | snd_soc_update_bits(codec, AIC31XX_MADC, AIC31XX_PLL_MASK, | ||
725 | aic31xx_divs[i].madc ? aic31xx_divs[i].madc : 1); | ||
726 | |||
727 | snd_soc_write(codec, AIC31XX_AOSR, aic31xx_divs[i].aosr); | ||
728 | |||
729 | /* Bit clock divider configuration. */ | ||
730 | bclk_n = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) | ||
731 | / snd_soc_params_to_frame_size(params); | ||
732 | if (bclk_n == 0) { | ||
733 | dev_err(codec->dev, "%s: Not enough BLCK bandwidth\n", | ||
734 | __func__); | ||
735 | return -EINVAL; | ||
736 | } | ||
737 | |||
738 | snd_soc_update_bits(codec, AIC31XX_BCLKN, | ||
739 | AIC31XX_PLL_MASK, bclk_n); | ||
740 | |||
741 | aic31xx->rate_div_line = i; | ||
742 | |||
743 | dev_dbg(codec->dev, | ||
744 | "pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n", | ||
745 | aic31xx_divs[i].pll_j, aic31xx_divs[i].pll_d, | ||
746 | aic31xx_divs[i].p_val, aic31xx_divs[i].dosr, | ||
747 | aic31xx_divs[i].ndac, aic31xx_divs[i].mdac, | ||
748 | aic31xx_divs[i].aosr, aic31xx_divs[i].nadc, | ||
749 | aic31xx_divs[i].madc, bclk_n); | ||
750 | |||
751 | return 0; | ||
752 | } | ||
753 | |||
754 | static int aic31xx_hw_params(struct snd_pcm_substream *substream, | ||
755 | struct snd_pcm_hw_params *params, | ||
756 | struct snd_soc_dai *dai) | ||
757 | { | ||
758 | struct snd_soc_codec *codec = dai->codec; | ||
759 | u8 data = 0; | ||
760 | |||
761 | dev_dbg(codec->dev, "## %s: format %d width %d rate %d\n", | ||
762 | __func__, params_format(params), params_width(params), | ||
763 | params_rate(params)); | ||
764 | |||
765 | switch (params_width(params)) { | ||
766 | case 16: | ||
767 | break; | ||
768 | case 20: | ||
769 | data = (AIC31XX_WORD_LEN_20BITS << | ||
770 | AIC31XX_IFACE1_DATALEN_SHIFT); | ||
771 | break; | ||
772 | case 24: | ||
773 | data = (AIC31XX_WORD_LEN_24BITS << | ||
774 | AIC31XX_IFACE1_DATALEN_SHIFT); | ||
775 | break; | ||
776 | case 32: | ||
777 | data = (AIC31XX_WORD_LEN_32BITS << | ||
778 | AIC31XX_IFACE1_DATALEN_SHIFT); | ||
779 | break; | ||
780 | default: | ||
781 | dev_err(codec->dev, "%s: Unsupported format %d\n", | ||
782 | __func__, params_format(params)); | ||
783 | return -EINVAL; | ||
784 | } | ||
785 | |||
786 | snd_soc_update_bits(codec, AIC31XX_IFACE1, | ||
787 | AIC31XX_IFACE1_DATALEN_MASK, | ||
788 | data); | ||
789 | |||
790 | return aic31xx_setup_pll(codec, params); | ||
791 | } | ||
792 | |||
793 | static int aic31xx_dac_mute(struct snd_soc_dai *codec_dai, int mute) | ||
794 | { | ||
795 | struct snd_soc_codec *codec = codec_dai->codec; | ||
796 | |||
797 | if (mute) { | ||
798 | snd_soc_update_bits(codec, AIC31XX_DACMUTE, | ||
799 | AIC31XX_DACMUTE_MASK, | ||
800 | AIC31XX_DACMUTE_MASK); | ||
801 | } else { | ||
802 | snd_soc_update_bits(codec, AIC31XX_DACMUTE, | ||
803 | AIC31XX_DACMUTE_MASK, 0x0); | ||
804 | } | ||
805 | |||
806 | return 0; | ||
807 | } | ||
808 | |||
809 | static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
810 | unsigned int fmt) | ||
811 | { | ||
812 | struct snd_soc_codec *codec = codec_dai->codec; | ||
813 | u8 iface_reg1 = 0; | ||
814 | u8 iface_reg3 = 0; | ||
815 | u8 dsp_a_val = 0; | ||
816 | |||
817 | dev_dbg(codec->dev, "## %s: fmt = 0x%x\n", __func__, fmt); | ||
818 | |||
819 | /* set master/slave audio interface */ | ||
820 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
821 | case SND_SOC_DAIFMT_CBM_CFM: | ||
822 | iface_reg1 |= AIC31XX_BCLK_MASTER | AIC31XX_WCLK_MASTER; | ||
823 | break; | ||
824 | default: | ||
825 | dev_alert(codec->dev, "Invalid DAI master/slave interface\n"); | ||
826 | return -EINVAL; | ||
827 | } | ||
828 | |||
829 | /* interface format */ | ||
830 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
831 | case SND_SOC_DAIFMT_I2S: | ||
832 | break; | ||
833 | case SND_SOC_DAIFMT_DSP_A: | ||
834 | dsp_a_val = 0x1; | ||
835 | case SND_SOC_DAIFMT_DSP_B: | ||
836 | /* NOTE: BCLKINV bit value 1 equas NB and 0 equals IB */ | ||
837 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
838 | case SND_SOC_DAIFMT_NB_NF: | ||
839 | iface_reg3 |= AIC31XX_BCLKINV_MASK; | ||
840 | break; | ||
841 | case SND_SOC_DAIFMT_IB_NF: | ||
842 | break; | ||
843 | default: | ||
844 | return -EINVAL; | ||
845 | } | ||
846 | iface_reg1 |= (AIC31XX_DSP_MODE << | ||
847 | AIC31XX_IFACE1_DATATYPE_SHIFT); | ||
848 | break; | ||
849 | case SND_SOC_DAIFMT_RIGHT_J: | ||
850 | iface_reg1 |= (AIC31XX_RIGHT_JUSTIFIED_MODE << | ||
851 | AIC31XX_IFACE1_DATATYPE_SHIFT); | ||
852 | break; | ||
853 | case SND_SOC_DAIFMT_LEFT_J: | ||
854 | iface_reg1 |= (AIC31XX_LEFT_JUSTIFIED_MODE << | ||
855 | AIC31XX_IFACE1_DATATYPE_SHIFT); | ||
856 | break; | ||
857 | default: | ||
858 | dev_err(codec->dev, "Invalid DAI interface format\n"); | ||
859 | return -EINVAL; | ||
860 | } | ||
861 | |||
862 | snd_soc_update_bits(codec, AIC31XX_IFACE1, | ||
863 | AIC31XX_IFACE1_DATATYPE_MASK | | ||
864 | AIC31XX_IFACE1_MASTER_MASK, | ||
865 | iface_reg1); | ||
866 | snd_soc_update_bits(codec, AIC31XX_DATA_OFFSET, | ||
867 | AIC31XX_DATA_OFFSET_MASK, | ||
868 | dsp_a_val); | ||
869 | snd_soc_update_bits(codec, AIC31XX_IFACE2, | ||
870 | AIC31XX_BCLKINV_MASK, | ||
871 | iface_reg3); | ||
872 | |||
873 | return 0; | ||
874 | } | ||
875 | |||
876 | static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, | ||
877 | int clk_id, unsigned int freq, int dir) | ||
878 | { | ||
879 | struct snd_soc_codec *codec = codec_dai->codec; | ||
880 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | ||
881 | int i; | ||
882 | |||
883 | dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n", | ||
884 | __func__, clk_id, freq, dir); | ||
885 | |||
886 | for (i = 0; aic31xx_divs[i].mclk != freq; i++) { | ||
887 | if (i == ARRAY_SIZE(aic31xx_divs)) { | ||
888 | dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n", | ||
889 | __func__, freq); | ||
890 | return -EINVAL; | ||
891 | } | ||
892 | } | ||
893 | |||
894 | /* set clock on MCLK, BCLK, or GPIO1 as PLL input */ | ||
895 | snd_soc_update_bits(codec, AIC31XX_CLKMUX, AIC31XX_PLL_CLKIN_MASK, | ||
896 | clk_id << AIC31XX_PLL_CLKIN_SHIFT); | ||
897 | |||
898 | aic31xx->sysclk = freq; | ||
899 | return 0; | ||
900 | } | ||
901 | |||
902 | static int aic31xx_regulator_event(struct notifier_block *nb, | ||
903 | unsigned long event, void *data) | ||
904 | { | ||
905 | struct aic31xx_disable_nb *disable_nb = | ||
906 | container_of(nb, struct aic31xx_disable_nb, nb); | ||
907 | struct aic31xx_priv *aic31xx = disable_nb->aic31xx; | ||
908 | |||
909 | if (event & REGULATOR_EVENT_DISABLE) { | ||
910 | /* | ||
911 | * Put codec to reset and as at least one of the | ||
912 | * supplies was disabled. | ||
913 | */ | ||
914 | if (gpio_is_valid(aic31xx->pdata.gpio_reset)) | ||
915 | gpio_set_value(aic31xx->pdata.gpio_reset, 0); | ||
916 | |||
917 | regcache_mark_dirty(aic31xx->regmap); | ||
918 | dev_dbg(aic31xx->dev, "## %s: DISABLE received\n", __func__); | ||
919 | } | ||
920 | |||
921 | return 0; | ||
922 | } | ||
923 | |||
924 | static void aic31xx_clk_on(struct snd_soc_codec *codec) | ||
925 | { | ||
926 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | ||
927 | u8 mask = AIC31XX_PM_MASK; | ||
928 | u8 on = AIC31XX_PM_MASK; | ||
929 | |||
930 | dev_dbg(codec->dev, "codec clock -> on (rate %d)\n", | ||
931 | aic31xx_divs[aic31xx->rate_div_line].rate); | ||
932 | snd_soc_update_bits(codec, AIC31XX_PLLPR, mask, on); | ||
933 | mdelay(10); | ||
934 | snd_soc_update_bits(codec, AIC31XX_NDAC, mask, on); | ||
935 | snd_soc_update_bits(codec, AIC31XX_MDAC, mask, on); | ||
936 | if (aic31xx_divs[aic31xx->rate_div_line].nadc) | ||
937 | snd_soc_update_bits(codec, AIC31XX_NADC, mask, on); | ||
938 | if (aic31xx_divs[aic31xx->rate_div_line].madc) | ||
939 | snd_soc_update_bits(codec, AIC31XX_MADC, mask, on); | ||
940 | snd_soc_update_bits(codec, AIC31XX_BCLKN, mask, on); | ||
941 | } | ||
942 | |||
943 | static void aic31xx_clk_off(struct snd_soc_codec *codec) | ||
944 | { | ||
945 | u8 mask = AIC31XX_PM_MASK; | ||
946 | u8 off = 0; | ||
947 | |||
948 | dev_dbg(codec->dev, "codec clock -> off\n"); | ||
949 | snd_soc_update_bits(codec, AIC31XX_BCLKN, mask, off); | ||
950 | snd_soc_update_bits(codec, AIC31XX_MADC, mask, off); | ||
951 | snd_soc_update_bits(codec, AIC31XX_NADC, mask, off); | ||
952 | snd_soc_update_bits(codec, AIC31XX_MDAC, mask, off); | ||
953 | snd_soc_update_bits(codec, AIC31XX_NDAC, mask, off); | ||
954 | snd_soc_update_bits(codec, AIC31XX_PLLPR, mask, off); | ||
955 | } | ||
956 | |||
957 | static int aic31xx_power_on(struct snd_soc_codec *codec) | ||
958 | { | ||
959 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | ||
960 | int ret = 0; | ||
961 | |||
962 | ret = regulator_bulk_enable(ARRAY_SIZE(aic31xx->supplies), | ||
963 | aic31xx->supplies); | ||
964 | if (ret) | ||
965 | return ret; | ||
966 | |||
967 | if (gpio_is_valid(aic31xx->pdata.gpio_reset)) { | ||
968 | gpio_set_value(aic31xx->pdata.gpio_reset, 1); | ||
969 | udelay(100); | ||
970 | } | ||
971 | regcache_cache_only(aic31xx->regmap, false); | ||
972 | ret = regcache_sync(aic31xx->regmap); | ||
973 | if (ret != 0) { | ||
974 | dev_err(codec->dev, | ||
975 | "Failed to restore cache: %d\n", ret); | ||
976 | regcache_cache_only(aic31xx->regmap, true); | ||
977 | regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies), | ||
978 | aic31xx->supplies); | ||
979 | return ret; | ||
980 | } | ||
981 | return 0; | ||
982 | } | ||
983 | |||
984 | static int aic31xx_power_off(struct snd_soc_codec *codec) | ||
985 | { | ||
986 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | ||
987 | int ret = 0; | ||
988 | |||
989 | regcache_cache_only(aic31xx->regmap, true); | ||
990 | ret = regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies), | ||
991 | aic31xx->supplies); | ||
992 | |||
993 | return ret; | ||
994 | } | ||
995 | |||
996 | static int aic31xx_set_bias_level(struct snd_soc_codec *codec, | ||
997 | enum snd_soc_bias_level level) | ||
998 | { | ||
999 | dev_dbg(codec->dev, "## %s: %d -> %d\n", __func__, | ||
1000 | codec->dapm.bias_level, level); | ||
1001 | |||
1002 | switch (level) { | ||
1003 | case SND_SOC_BIAS_ON: | ||
1004 | break; | ||
1005 | case SND_SOC_BIAS_PREPARE: | ||
1006 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) | ||
1007 | aic31xx_clk_on(codec); | ||
1008 | break; | ||
1009 | case SND_SOC_BIAS_STANDBY: | ||
1010 | switch (codec->dapm.bias_level) { | ||
1011 | case SND_SOC_BIAS_OFF: | ||
1012 | aic31xx_power_on(codec); | ||
1013 | break; | ||
1014 | case SND_SOC_BIAS_PREPARE: | ||
1015 | aic31xx_clk_off(codec); | ||
1016 | break; | ||
1017 | default: | ||
1018 | BUG(); | ||
1019 | } | ||
1020 | break; | ||
1021 | case SND_SOC_BIAS_OFF: | ||
1022 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) | ||
1023 | aic31xx_power_off(codec); | ||
1024 | break; | ||
1025 | } | ||
1026 | codec->dapm.bias_level = level; | ||
1027 | |||
1028 | return 0; | ||
1029 | } | ||
1030 | |||
1031 | static int aic31xx_suspend(struct snd_soc_codec *codec) | ||
1032 | { | ||
1033 | aic31xx_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1034 | return 0; | ||
1035 | } | ||
1036 | |||
1037 | static int aic31xx_resume(struct snd_soc_codec *codec) | ||
1038 | { | ||
1039 | aic31xx_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1040 | return 0; | ||
1041 | } | ||
1042 | |||
1043 | static int aic31xx_codec_probe(struct snd_soc_codec *codec) | ||
1044 | { | ||
1045 | int ret = 0; | ||
1046 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | ||
1047 | int i; | ||
1048 | |||
1049 | dev_dbg(aic31xx->dev, "## %s\n", __func__); | ||
1050 | |||
1051 | aic31xx = snd_soc_codec_get_drvdata(codec); | ||
1052 | |||
1053 | aic31xx->codec = codec; | ||
1054 | |||
1055 | for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) { | ||
1056 | aic31xx->disable_nb[i].nb.notifier_call = | ||
1057 | aic31xx_regulator_event; | ||
1058 | aic31xx->disable_nb[i].aic31xx = aic31xx; | ||
1059 | ret = regulator_register_notifier(aic31xx->supplies[i].consumer, | ||
1060 | &aic31xx->disable_nb[i].nb); | ||
1061 | if (ret) { | ||
1062 | dev_err(codec->dev, | ||
1063 | "Failed to request regulator notifier: %d\n", | ||
1064 | ret); | ||
1065 | return ret; | ||
1066 | } | ||
1067 | } | ||
1068 | |||
1069 | regcache_cache_only(aic31xx->regmap, true); | ||
1070 | regcache_mark_dirty(aic31xx->regmap); | ||
1071 | |||
1072 | ret = aic31xx_add_controls(codec); | ||
1073 | if (ret) | ||
1074 | return ret; | ||
1075 | |||
1076 | ret = aic31xx_add_widgets(codec); | ||
1077 | |||
1078 | return ret; | ||
1079 | } | ||
1080 | |||
1081 | static int aic31xx_codec_remove(struct snd_soc_codec *codec) | ||
1082 | { | ||
1083 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | ||
1084 | int i; | ||
1085 | /* power down chip */ | ||
1086 | aic31xx_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1087 | |||
1088 | for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) | ||
1089 | regulator_unregister_notifier(aic31xx->supplies[i].consumer, | ||
1090 | &aic31xx->disable_nb[i].nb); | ||
1091 | |||
1092 | return 0; | ||
1093 | } | ||
1094 | |||
1095 | static struct snd_soc_codec_driver soc_codec_driver_aic31xx = { | ||
1096 | .probe = aic31xx_codec_probe, | ||
1097 | .remove = aic31xx_codec_remove, | ||
1098 | .suspend = aic31xx_suspend, | ||
1099 | .resume = aic31xx_resume, | ||
1100 | .set_bias_level = aic31xx_set_bias_level, | ||
1101 | .controls = aic31xx_snd_controls, | ||
1102 | .num_controls = ARRAY_SIZE(aic31xx_snd_controls), | ||
1103 | .dapm_widgets = aic31xx_dapm_widgets, | ||
1104 | .num_dapm_widgets = ARRAY_SIZE(aic31xx_dapm_widgets), | ||
1105 | .dapm_routes = aic31xx_audio_map, | ||
1106 | .num_dapm_routes = ARRAY_SIZE(aic31xx_audio_map), | ||
1107 | }; | ||
1108 | |||
1109 | static struct snd_soc_dai_ops aic31xx_dai_ops = { | ||
1110 | .hw_params = aic31xx_hw_params, | ||
1111 | .set_sysclk = aic31xx_set_dai_sysclk, | ||
1112 | .set_fmt = aic31xx_set_dai_fmt, | ||
1113 | .digital_mute = aic31xx_dac_mute, | ||
1114 | }; | ||
1115 | |||
1116 | static struct snd_soc_dai_driver aic31xx_dai_driver[] = { | ||
1117 | { | ||
1118 | .name = "tlv320aic31xx-hifi", | ||
1119 | .playback = { | ||
1120 | .stream_name = "Playback", | ||
1121 | .channels_min = 1, | ||
1122 | .channels_max = 2, | ||
1123 | .rates = AIC31XX_RATES, | ||
1124 | .formats = AIC31XX_FORMATS, | ||
1125 | }, | ||
1126 | .capture = { | ||
1127 | .stream_name = "Capture", | ||
1128 | .channels_min = 1, | ||
1129 | .channels_max = 2, | ||
1130 | .rates = AIC31XX_RATES, | ||
1131 | .formats = AIC31XX_FORMATS, | ||
1132 | }, | ||
1133 | .ops = &aic31xx_dai_ops, | ||
1134 | .symmetric_rates = 1, | ||
1135 | } | ||
1136 | }; | ||
1137 | |||
1138 | #if defined(CONFIG_OF) | ||
1139 | static const struct of_device_id tlv320aic31xx_of_match[] = { | ||
1140 | { .compatible = "ti,tlv320aic310x" }, | ||
1141 | { .compatible = "ti,tlv320aic311x" }, | ||
1142 | { .compatible = "ti,tlv320aic3100" }, | ||
1143 | { .compatible = "ti,tlv320aic3110" }, | ||
1144 | { .compatible = "ti,tlv320aic3120" }, | ||
1145 | { .compatible = "ti,tlv320aic3111" }, | ||
1146 | {}, | ||
1147 | }; | ||
1148 | MODULE_DEVICE_TABLE(of, tlv320aic31xx_of_match); | ||
1149 | |||
1150 | static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx) | ||
1151 | { | ||
1152 | struct device_node *np = aic31xx->dev->of_node; | ||
1153 | unsigned int value = MICBIAS_2_0V; | ||
1154 | int ret; | ||
1155 | |||
1156 | of_property_read_u32(np, "ai31xx-micbias-vg", &value); | ||
1157 | switch (value) { | ||
1158 | case MICBIAS_2_0V: | ||
1159 | case MICBIAS_2_5V: | ||
1160 | case MICBIAS_AVDDV: | ||
1161 | aic31xx->pdata.micbias_vg = value; | ||
1162 | break; | ||
1163 | default: | ||
1164 | dev_err(aic31xx->dev, | ||
1165 | "Bad ai31xx-micbias-vg value %d DT\n", | ||
1166 | value); | ||
1167 | aic31xx->pdata.micbias_vg = MICBIAS_2_0V; | ||
1168 | } | ||
1169 | |||
1170 | ret = of_get_named_gpio(np, "gpio-reset", 0); | ||
1171 | if (ret > 0) | ||
1172 | aic31xx->pdata.gpio_reset = ret; | ||
1173 | } | ||
1174 | #else /* CONFIG_OF */ | ||
1175 | static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx) | ||
1176 | { | ||
1177 | } | ||
1178 | #endif /* CONFIG_OF */ | ||
1179 | |||
1180 | static void aic31xx_device_init(struct aic31xx_priv *aic31xx) | ||
1181 | { | ||
1182 | int ret, i; | ||
1183 | |||
1184 | dev_set_drvdata(aic31xx->dev, aic31xx); | ||
1185 | |||
1186 | if (dev_get_platdata(aic31xx->dev)) | ||
1187 | memcpy(&aic31xx->pdata, dev_get_platdata(aic31xx->dev), | ||
1188 | sizeof(aic31xx->pdata)); | ||
1189 | else if (aic31xx->dev->of_node) | ||
1190 | aic31xx_pdata_from_of(aic31xx); | ||
1191 | |||
1192 | if (aic31xx->pdata.gpio_reset) { | ||
1193 | ret = devm_gpio_request_one(aic31xx->dev, | ||
1194 | aic31xx->pdata.gpio_reset, | ||
1195 | GPIOF_OUT_INIT_HIGH, | ||
1196 | "aic31xx-reset-pin"); | ||
1197 | if (ret < 0) { | ||
1198 | dev_err(aic31xx->dev, "not able to acquire gpio\n"); | ||
1199 | return; | ||
1200 | } | ||
1201 | } | ||
1202 | |||
1203 | for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) | ||
1204 | aic31xx->supplies[i].supply = aic31xx_supply_names[i]; | ||
1205 | |||
1206 | ret = devm_regulator_bulk_get(aic31xx->dev, | ||
1207 | ARRAY_SIZE(aic31xx->supplies), | ||
1208 | aic31xx->supplies); | ||
1209 | if (ret != 0) | ||
1210 | dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret); | ||
1211 | |||
1212 | } | ||
1213 | |||
1214 | static int aic31xx_i2c_probe(struct i2c_client *i2c, | ||
1215 | const struct i2c_device_id *id) | ||
1216 | { | ||
1217 | struct aic31xx_priv *aic31xx; | ||
1218 | int ret; | ||
1219 | const struct regmap_config *regmap_config; | ||
1220 | |||
1221 | dev_dbg(&i2c->dev, "## %s: %s codec_type = %d\n", __func__, | ||
1222 | id->name, (int) id->driver_data); | ||
1223 | |||
1224 | regmap_config = &aic31xx_i2c_regmap; | ||
1225 | |||
1226 | aic31xx = devm_kzalloc(&i2c->dev, sizeof(*aic31xx), GFP_KERNEL); | ||
1227 | if (aic31xx == NULL) | ||
1228 | return -ENOMEM; | ||
1229 | |||
1230 | aic31xx->regmap = devm_regmap_init_i2c(i2c, regmap_config); | ||
1231 | if (IS_ERR(aic31xx->regmap)) { | ||
1232 | ret = PTR_ERR(aic31xx->regmap); | ||
1233 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
1234 | ret); | ||
1235 | return ret; | ||
1236 | } | ||
1237 | aic31xx->dev = &i2c->dev; | ||
1238 | |||
1239 | aic31xx->pdata.codec_type = id->driver_data; | ||
1240 | |||
1241 | aic31xx_device_init(aic31xx); | ||
1242 | |||
1243 | return snd_soc_register_codec(&i2c->dev, &soc_codec_driver_aic31xx, | ||
1244 | aic31xx_dai_driver, | ||
1245 | ARRAY_SIZE(aic31xx_dai_driver)); | ||
1246 | } | ||
1247 | |||
1248 | static int aic31xx_i2c_remove(struct i2c_client *i2c) | ||
1249 | { | ||
1250 | snd_soc_unregister_codec(&i2c->dev); | ||
1251 | return 0; | ||
1252 | } | ||
1253 | |||
1254 | static const struct i2c_device_id aic31xx_i2c_id[] = { | ||
1255 | { "tlv320aic310x", AIC3100 }, | ||
1256 | { "tlv320aic311x", AIC3110 }, | ||
1257 | { "tlv320aic3100", AIC3100 }, | ||
1258 | { "tlv320aic3110", AIC3110 }, | ||
1259 | { "tlv320aic3120", AIC3120 }, | ||
1260 | { "tlv320aic3111", AIC3111 }, | ||
1261 | { } | ||
1262 | }; | ||
1263 | MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id); | ||
1264 | |||
1265 | static struct i2c_driver aic31xx_i2c_driver = { | ||
1266 | .driver = { | ||
1267 | .name = "tlv320aic31xx-codec", | ||
1268 | .owner = THIS_MODULE, | ||
1269 | .of_match_table = of_match_ptr(tlv320aic31xx_of_match), | ||
1270 | }, | ||
1271 | .probe = aic31xx_i2c_probe, | ||
1272 | .remove = aic31xx_i2c_remove, | ||
1273 | .id_table = aic31xx_i2c_id, | ||
1274 | }; | ||
1275 | |||
1276 | module_i2c_driver(aic31xx_i2c_driver); | ||
1277 | |||
1278 | MODULE_DESCRIPTION("ASoC TLV320AIC3111 codec driver"); | ||
1279 | MODULE_AUTHOR("Jyri Sarha"); | ||
1280 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h new file mode 100644 index 000000000000..52ed57c69dfa --- /dev/null +++ b/sound/soc/codecs/tlv320aic31xx.h | |||
@@ -0,0 +1,258 @@ | |||
1 | /* | ||
2 | * ALSA SoC TLV320AIC31XX codec driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Texas Instruments, Inc. | ||
5 | * | ||
6 | * This package is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
11 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
12 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | * | ||
14 | */ | ||
15 | #ifndef _TLV320AIC31XX_H | ||
16 | #define _TLV320AIC31XX_H | ||
17 | |||
18 | #define AIC31XX_RATES SNDRV_PCM_RATE_8000_192000 | ||
19 | |||
20 | #define AIC31XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ | ||
21 | | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) | ||
22 | |||
23 | |||
24 | #define AIC31XX_STEREO_CLASS_D_BIT 0x1 | ||
25 | #define AIC31XX_MINIDSP_BIT 0x2 | ||
26 | |||
27 | enum aic31xx_type { | ||
28 | AIC3100 = 0, | ||
29 | AIC3110 = AIC31XX_STEREO_CLASS_D_BIT, | ||
30 | AIC3120 = AIC31XX_MINIDSP_BIT, | ||
31 | AIC3111 = (AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT), | ||
32 | }; | ||
33 | |||
34 | struct aic31xx_pdata { | ||
35 | enum aic31xx_type codec_type; | ||
36 | unsigned int gpio_reset; | ||
37 | int micbias_vg; | ||
38 | }; | ||
39 | |||
40 | /* Page Control Register */ | ||
41 | #define AIC31XX_PAGECTL 0x00 | ||
42 | |||
43 | /* Page 0 Registers */ | ||
44 | /* Software reset register */ | ||
45 | #define AIC31XX_RESET 0x01 | ||
46 | /* OT FLAG register */ | ||
47 | #define AIC31XX_OT_FLAG 0x03 | ||
48 | /* Clock clock Gen muxing, Multiplexers*/ | ||
49 | #define AIC31XX_CLKMUX 0x04 | ||
50 | /* PLL P and R-VAL register */ | ||
51 | #define AIC31XX_PLLPR 0x05 | ||
52 | /* PLL J-VAL register */ | ||
53 | #define AIC31XX_PLLJ 0x06 | ||
54 | /* PLL D-VAL MSB register */ | ||
55 | #define AIC31XX_PLLDMSB 0x07 | ||
56 | /* PLL D-VAL LSB register */ | ||
57 | #define AIC31XX_PLLDLSB 0x08 | ||
58 | /* DAC NDAC_VAL register*/ | ||
59 | #define AIC31XX_NDAC 0x0B | ||
60 | /* DAC MDAC_VAL register */ | ||
61 | #define AIC31XX_MDAC 0x0C | ||
62 | /* DAC OSR setting register 1, MSB value */ | ||
63 | #define AIC31XX_DOSRMSB 0x0D | ||
64 | /* DAC OSR setting register 2, LSB value */ | ||
65 | #define AIC31XX_DOSRLSB 0x0E | ||
66 | #define AIC31XX_MINI_DSP_INPOL 0x10 | ||
67 | /* Clock setting register 8, PLL */ | ||
68 | #define AIC31XX_NADC 0x12 | ||
69 | /* Clock setting register 9, PLL */ | ||
70 | #define AIC31XX_MADC 0x13 | ||
71 | /* ADC Oversampling (AOSR) Register */ | ||
72 | #define AIC31XX_AOSR 0x14 | ||
73 | /* Clock setting register 9, Multiplexers */ | ||
74 | #define AIC31XX_CLKOUTMUX 0x19 | ||
75 | /* Clock setting register 10, CLOCKOUT M divider value */ | ||
76 | #define AIC31XX_CLKOUTMVAL 0x1A | ||
77 | /* Audio Interface Setting Register 1 */ | ||
78 | #define AIC31XX_IFACE1 0x1B | ||
79 | /* Audio Data Slot Offset Programming */ | ||
80 | #define AIC31XX_DATA_OFFSET 0x1C | ||
81 | /* Audio Interface Setting Register 2 */ | ||
82 | #define AIC31XX_IFACE2 0x1D | ||
83 | /* Clock setting register 11, BCLK N Divider */ | ||
84 | #define AIC31XX_BCLKN 0x1E | ||
85 | /* Audio Interface Setting Register 3, Secondary Audio Interface */ | ||
86 | #define AIC31XX_IFACESEC1 0x1F | ||
87 | /* Audio Interface Setting Register 4 */ | ||
88 | #define AIC31XX_IFACESEC2 0x20 | ||
89 | /* Audio Interface Setting Register 5 */ | ||
90 | #define AIC31XX_IFACESEC3 0x21 | ||
91 | /* I2C Bus Condition */ | ||
92 | #define AIC31XX_I2C 0x22 | ||
93 | /* ADC FLAG */ | ||
94 | #define AIC31XX_ADCFLAG 0x24 | ||
95 | /* DAC Flag Registers */ | ||
96 | #define AIC31XX_DACFLAG1 0x25 | ||
97 | #define AIC31XX_DACFLAG2 0x26 | ||
98 | /* Sticky Interrupt flag (overflow) */ | ||
99 | #define AIC31XX_OFFLAG 0x27 | ||
100 | /* Sticy DAC Interrupt flags */ | ||
101 | #define AIC31XX_INTRDACFLAG 0x2C | ||
102 | /* Sticy ADC Interrupt flags */ | ||
103 | #define AIC31XX_INTRADCFLAG 0x2D | ||
104 | /* DAC Interrupt flags 2 */ | ||
105 | #define AIC31XX_INTRDACFLAG2 0x2E | ||
106 | /* ADC Interrupt flags 2 */ | ||
107 | #define AIC31XX_INTRADCFLAG2 0x2F | ||
108 | /* INT1 interrupt control */ | ||
109 | #define AIC31XX_INT1CTRL 0x30 | ||
110 | /* INT2 interrupt control */ | ||
111 | #define AIC31XX_INT2CTRL 0x31 | ||
112 | /* GPIO1 control */ | ||
113 | #define AIC31XX_GPIO1 0x33 | ||
114 | |||
115 | #define AIC31XX_DACPRB 0x3C | ||
116 | /* ADC Instruction Set Register */ | ||
117 | #define AIC31XX_ADCPRB 0x3D | ||
118 | /* DAC channel setup register */ | ||
119 | #define AIC31XX_DACSETUP 0x3F | ||
120 | /* DAC Mute and volume control register */ | ||
121 | #define AIC31XX_DACMUTE 0x40 | ||
122 | /* Left DAC channel digital volume control */ | ||
123 | #define AIC31XX_LDACVOL 0x41 | ||
124 | /* Right DAC channel digital volume control */ | ||
125 | #define AIC31XX_RDACVOL 0x42 | ||
126 | /* Headset detection */ | ||
127 | #define AIC31XX_HSDETECT 0x43 | ||
128 | /* ADC Digital Mic */ | ||
129 | #define AIC31XX_ADCSETUP 0x51 | ||
130 | /* ADC Digital Volume Control Fine Adjust */ | ||
131 | #define AIC31XX_ADCFGA 0x52 | ||
132 | /* ADC Digital Volume Control Coarse Adjust */ | ||
133 | #define AIC31XX_ADCVOL 0x53 | ||
134 | |||
135 | |||
136 | /* Page 1 Registers */ | ||
137 | /* Headphone drivers */ | ||
138 | #define AIC31XX_HPDRIVER 0x9F | ||
139 | /* Class-D Speakear Amplifier */ | ||
140 | #define AIC31XX_SPKAMP 0xA0 | ||
141 | /* HP Output Drivers POP Removal Settings */ | ||
142 | #define AIC31XX_HPPOP 0xA1 | ||
143 | /* Output Driver PGA Ramp-Down Period Control */ | ||
144 | #define AIC31XX_SPPGARAMP 0xA2 | ||
145 | /* DAC_L and DAC_R Output Mixer Routing */ | ||
146 | #define AIC31XX_DACMIXERROUTE 0xA3 | ||
147 | /* Left Analog Vol to HPL */ | ||
148 | #define AIC31XX_LANALOGHPL 0xA4 | ||
149 | /* Right Analog Vol to HPR */ | ||
150 | #define AIC31XX_RANALOGHPR 0xA5 | ||
151 | /* Left Analog Vol to SPL */ | ||
152 | #define AIC31XX_LANALOGSPL 0xA6 | ||
153 | /* Right Analog Vol to SPR */ | ||
154 | #define AIC31XX_RANALOGSPR 0xA7 | ||
155 | /* HPL Driver */ | ||
156 | #define AIC31XX_HPLGAIN 0xA8 | ||
157 | /* HPR Driver */ | ||
158 | #define AIC31XX_HPRGAIN 0xA9 | ||
159 | /* SPL Driver */ | ||
160 | #define AIC31XX_SPLGAIN 0xAA | ||
161 | /* SPR Driver */ | ||
162 | #define AIC31XX_SPRGAIN 0xAB | ||
163 | /* HP Driver Control */ | ||
164 | #define AIC31XX_HPCONTROL 0xAC | ||
165 | /* MIC Bias Control */ | ||
166 | #define AIC31XX_MICBIAS 0xAE | ||
167 | /* MIC PGA*/ | ||
168 | #define AIC31XX_MICPGA 0xAF | ||
169 | /* Delta-Sigma Mono ADC Channel Fine-Gain Input Selection for P-Terminal */ | ||
170 | #define AIC31XX_MICPGAPI 0xB0 | ||
171 | /* ADC Input Selection for M-Terminal */ | ||
172 | #define AIC31XX_MICPGAMI 0xB1 | ||
173 | /* Input CM Settings */ | ||
174 | #define AIC31XX_MICPGACM 0xB2 | ||
175 | |||
176 | /* Bits, masks and shifts */ | ||
177 | |||
178 | /* AIC31XX_CLKMUX */ | ||
179 | #define AIC31XX_PLL_CLKIN_MASK 0x0c | ||
180 | #define AIC31XX_PLL_CLKIN_SHIFT 2 | ||
181 | #define AIC31XX_PLL_CLKIN_MCLK 0 | ||
182 | #define AIC31XX_CODEC_CLKIN_MASK 0x03 | ||
183 | #define AIC31XX_CODEC_CLKIN_SHIFT 0 | ||
184 | #define AIC31XX_CODEC_CLKIN_PLL 3 | ||
185 | #define AIC31XX_CODEC_CLKIN_BCLK 1 | ||
186 | |||
187 | /* AIC31XX_PLLPR, AIC31XX_NDAC, AIC31XX_MDAC, AIC31XX_NADC, AIC31XX_MADC, | ||
188 | AIC31XX_BCLKN */ | ||
189 | #define AIC31XX_PLL_MASK 0x7f | ||
190 | #define AIC31XX_PM_MASK 0x80 | ||
191 | |||
192 | /* AIC31XX_IFACE1 */ | ||
193 | #define AIC31XX_WORD_LEN_16BITS 0x00 | ||
194 | #define AIC31XX_WORD_LEN_20BITS 0x01 | ||
195 | #define AIC31XX_WORD_LEN_24BITS 0x02 | ||
196 | #define AIC31XX_WORD_LEN_32BITS 0x03 | ||
197 | #define AIC31XX_IFACE1_DATALEN_MASK 0x30 | ||
198 | #define AIC31XX_IFACE1_DATALEN_SHIFT (4) | ||
199 | #define AIC31XX_IFACE1_DATATYPE_MASK 0xC0 | ||
200 | #define AIC31XX_IFACE1_DATATYPE_SHIFT (6) | ||
201 | #define AIC31XX_I2S_MODE 0x00 | ||
202 | #define AIC31XX_DSP_MODE 0x01 | ||
203 | #define AIC31XX_RIGHT_JUSTIFIED_MODE 0x02 | ||
204 | #define AIC31XX_LEFT_JUSTIFIED_MODE 0x03 | ||
205 | #define AIC31XX_IFACE1_MASTER_MASK 0x0C | ||
206 | #define AIC31XX_BCLK_MASTER 0x08 | ||
207 | #define AIC31XX_WCLK_MASTER 0x04 | ||
208 | |||
209 | /* AIC31XX_DATA_OFFSET */ | ||
210 | #define AIC31XX_DATA_OFFSET_MASK 0xFF | ||
211 | |||
212 | /* AIC31XX_IFACE2 */ | ||
213 | #define AIC31XX_BCLKINV_MASK 0x08 | ||
214 | #define AIC31XX_BDIVCLK_MASK 0x03 | ||
215 | #define AIC31XX_DAC2BCLK 0x00 | ||
216 | #define AIC31XX_DACMOD2BCLK 0x01 | ||
217 | #define AIC31XX_ADC2BCLK 0x02 | ||
218 | #define AIC31XX_ADCMOD2BCLK 0x03 | ||
219 | |||
220 | /* AIC31XX_ADCFLAG */ | ||
221 | #define AIC31XX_ADCPWRSTATUS_MASK 0x40 | ||
222 | |||
223 | /* AIC31XX_DACFLAG1 */ | ||
224 | #define AIC31XX_LDACPWRSTATUS_MASK 0x80 | ||
225 | #define AIC31XX_RDACPWRSTATUS_MASK 0x08 | ||
226 | #define AIC31XX_HPLDRVPWRSTATUS_MASK 0x20 | ||
227 | #define AIC31XX_HPRDRVPWRSTATUS_MASK 0x02 | ||
228 | #define AIC31XX_SPLDRVPWRSTATUS_MASK 0x10 | ||
229 | #define AIC31XX_SPRDRVPWRSTATUS_MASK 0x01 | ||
230 | |||
231 | /* AIC31XX_INTRDACFLAG */ | ||
232 | #define AIC31XX_HPSCDETECT_MASK 0x80 | ||
233 | #define AIC31XX_BUTTONPRESS_MASK 0x20 | ||
234 | #define AIC31XX_HSPLUG_MASK 0x10 | ||
235 | #define AIC31XX_LDRCTHRES_MASK 0x08 | ||
236 | #define AIC31XX_RDRCTHRES_MASK 0x04 | ||
237 | #define AIC31XX_DACSINT_MASK 0x02 | ||
238 | #define AIC31XX_DACAINT_MASK 0x01 | ||
239 | |||
240 | /* AIC31XX_INT1CTRL */ | ||
241 | #define AIC31XX_HSPLUGDET_MASK 0x80 | ||
242 | #define AIC31XX_BUTTONPRESSDET_MASK 0x40 | ||
243 | #define AIC31XX_DRCTHRES_MASK 0x20 | ||
244 | #define AIC31XX_AGCNOISE_MASK 0x10 | ||
245 | #define AIC31XX_OC_MASK 0x08 | ||
246 | #define AIC31XX_ENGINE_MASK 0x04 | ||
247 | |||
248 | /* AIC31XX_DACSETUP */ | ||
249 | #define AIC31XX_SOFTSTEP_MASK 0x03 | ||
250 | |||
251 | /* AIC31XX_DACMUTE */ | ||
252 | #define AIC31XX_DACMUTE_MASK 0x0C | ||
253 | |||
254 | /* AIC31XX_MICBIAS */ | ||
255 | #define AIC31XX_MICBIAS_MASK 0x03 | ||
256 | #define AIC31XX_MICBIAS_SHIFT 0 | ||
257 | |||
258 | #endif /* _TLV320AIC31XX_H */ | ||
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 688151ba309a..1d9b117345a3 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -29,9 +29,12 @@ | |||
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/pm.h> | 30 | #include <linux/pm.h> |
31 | #include <linux/gpio.h> | 31 | #include <linux/gpio.h> |
32 | #include <linux/of_gpio.h> | ||
32 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
33 | #include <linux/cdev.h> | 34 | #include <linux/cdev.h> |
34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/clk.h> | ||
37 | #include <linux/regulator/consumer.h> | ||
35 | 38 | ||
36 | #include <sound/tlv320aic32x4.h> | 39 | #include <sound/tlv320aic32x4.h> |
37 | #include <sound/core.h> | 40 | #include <sound/core.h> |
@@ -66,20 +69,32 @@ struct aic32x4_priv { | |||
66 | u32 micpga_routing; | 69 | u32 micpga_routing; |
67 | bool swapdacs; | 70 | bool swapdacs; |
68 | int rstn_gpio; | 71 | int rstn_gpio; |
72 | struct clk *mclk; | ||
73 | |||
74 | struct regulator *supply_ldo; | ||
75 | struct regulator *supply_iov; | ||
76 | struct regulator *supply_dv; | ||
77 | struct regulator *supply_av; | ||
69 | }; | 78 | }; |
70 | 79 | ||
71 | /* 0dB min, 1dB steps */ | ||
72 | static DECLARE_TLV_DB_SCALE(tlv_step_1, 0, 100, 0); | ||
73 | /* 0dB min, 0.5dB steps */ | 80 | /* 0dB min, 0.5dB steps */ |
74 | static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0); | 81 | static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0); |
82 | /* -63.5dB min, 0.5dB steps */ | ||
83 | static DECLARE_TLV_DB_SCALE(tlv_pcm, -6350, 50, 0); | ||
84 | /* -6dB min, 1dB steps */ | ||
85 | static DECLARE_TLV_DB_SCALE(tlv_driver_gain, -600, 100, 0); | ||
86 | /* -12dB min, 0.5dB steps */ | ||
87 | static DECLARE_TLV_DB_SCALE(tlv_adc_vol, -1200, 50, 0); | ||
75 | 88 | ||
76 | static const struct snd_kcontrol_new aic32x4_snd_controls[] = { | 89 | static const struct snd_kcontrol_new aic32x4_snd_controls[] = { |
77 | SOC_DOUBLE_R_TLV("PCM Playback Volume", AIC32X4_LDACVOL, | 90 | SOC_DOUBLE_R_S_TLV("PCM Playback Volume", AIC32X4_LDACVOL, |
78 | AIC32X4_RDACVOL, 0, 0x30, 0, tlv_step_0_5), | 91 | AIC32X4_RDACVOL, 0, -0x7f, 0x30, 7, 0, tlv_pcm), |
79 | SOC_DOUBLE_R_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN, | 92 | SOC_DOUBLE_R_S_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN, |
80 | AIC32X4_HPRGAIN, 0, 0x1D, 0, tlv_step_1), | 93 | AIC32X4_HPRGAIN, 0, -0x6, 0x1d, 5, 0, |
81 | SOC_DOUBLE_R_TLV("LO Driver Gain Volume", AIC32X4_LOLGAIN, | 94 | tlv_driver_gain), |
82 | AIC32X4_LORGAIN, 0, 0x1D, 0, tlv_step_1), | 95 | SOC_DOUBLE_R_S_TLV("LO Driver Gain Volume", AIC32X4_LOLGAIN, |
96 | AIC32X4_LORGAIN, 0, -0x6, 0x1d, 5, 0, | ||
97 | tlv_driver_gain), | ||
83 | SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN, | 98 | SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN, |
84 | AIC32X4_HPRGAIN, 6, 0x01, 1), | 99 | AIC32X4_HPRGAIN, 6, 0x01, 1), |
85 | SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN, | 100 | SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN, |
@@ -90,8 +105,8 @@ static const struct snd_kcontrol_new aic32x4_snd_controls[] = { | |||
90 | SOC_SINGLE("ADCFGA Left Mute Switch", AIC32X4_ADCFGA, 7, 1, 0), | 105 | SOC_SINGLE("ADCFGA Left Mute Switch", AIC32X4_ADCFGA, 7, 1, 0), |
91 | SOC_SINGLE("ADCFGA Right Mute Switch", AIC32X4_ADCFGA, 3, 1, 0), | 106 | SOC_SINGLE("ADCFGA Right Mute Switch", AIC32X4_ADCFGA, 3, 1, 0), |
92 | 107 | ||
93 | SOC_DOUBLE_R_TLV("ADC Level Volume", AIC32X4_LADCVOL, | 108 | SOC_DOUBLE_R_S_TLV("ADC Level Volume", AIC32X4_LADCVOL, |
94 | AIC32X4_RADCVOL, 0, 0x28, 0, tlv_step_0_5), | 109 | AIC32X4_RADCVOL, 0, -0x18, 0x28, 6, 0, tlv_adc_vol), |
95 | SOC_DOUBLE_R_TLV("PGA Level Volume", AIC32X4_LMICPGAVOL, | 110 | SOC_DOUBLE_R_TLV("PGA Level Volume", AIC32X4_LMICPGAVOL, |
96 | AIC32X4_RMICPGAVOL, 0, 0x5f, 0, tlv_step_0_5), | 111 | AIC32X4_RMICPGAVOL, 0, 0x5f, 0, tlv_step_0_5), |
97 | 112 | ||
@@ -480,8 +495,18 @@ static int aic32x4_mute(struct snd_soc_dai *dai, int mute) | |||
480 | static int aic32x4_set_bias_level(struct snd_soc_codec *codec, | 495 | static int aic32x4_set_bias_level(struct snd_soc_codec *codec, |
481 | enum snd_soc_bias_level level) | 496 | enum snd_soc_bias_level level) |
482 | { | 497 | { |
498 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | ||
499 | int ret; | ||
500 | |||
483 | switch (level) { | 501 | switch (level) { |
484 | case SND_SOC_BIAS_ON: | 502 | case SND_SOC_BIAS_ON: |
503 | /* Switch on master clock */ | ||
504 | ret = clk_prepare_enable(aic32x4->mclk); | ||
505 | if (ret) { | ||
506 | dev_err(codec->dev, "Failed to enable master clock\n"); | ||
507 | return ret; | ||
508 | } | ||
509 | |||
485 | /* Switch on PLL */ | 510 | /* Switch on PLL */ |
486 | snd_soc_update_bits(codec, AIC32X4_PLLPR, | 511 | snd_soc_update_bits(codec, AIC32X4_PLLPR, |
487 | AIC32X4_PLLEN, AIC32X4_PLLEN); | 512 | AIC32X4_PLLEN, AIC32X4_PLLEN); |
@@ -509,29 +534,32 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec, | |||
509 | case SND_SOC_BIAS_PREPARE: | 534 | case SND_SOC_BIAS_PREPARE: |
510 | break; | 535 | break; |
511 | case SND_SOC_BIAS_STANDBY: | 536 | case SND_SOC_BIAS_STANDBY: |
512 | /* Switch off PLL */ | 537 | /* Switch off BCLK_N Divider */ |
513 | snd_soc_update_bits(codec, AIC32X4_PLLPR, | 538 | snd_soc_update_bits(codec, AIC32X4_BCLKN, |
514 | AIC32X4_PLLEN, 0); | 539 | AIC32X4_BCLKEN, 0); |
515 | 540 | ||
516 | /* Switch off NDAC Divider */ | 541 | /* Switch off MADC Divider */ |
517 | snd_soc_update_bits(codec, AIC32X4_NDAC, | 542 | snd_soc_update_bits(codec, AIC32X4_MADC, |
518 | AIC32X4_NDACEN, 0); | 543 | AIC32X4_MADCEN, 0); |
544 | |||
545 | /* Switch off NADC Divider */ | ||
546 | snd_soc_update_bits(codec, AIC32X4_NADC, | ||
547 | AIC32X4_NADCEN, 0); | ||
519 | 548 | ||
520 | /* Switch off MDAC Divider */ | 549 | /* Switch off MDAC Divider */ |
521 | snd_soc_update_bits(codec, AIC32X4_MDAC, | 550 | snd_soc_update_bits(codec, AIC32X4_MDAC, |
522 | AIC32X4_MDACEN, 0); | 551 | AIC32X4_MDACEN, 0); |
523 | 552 | ||
524 | /* Switch off NADC Divider */ | 553 | /* Switch off NDAC Divider */ |
525 | snd_soc_update_bits(codec, AIC32X4_NADC, | 554 | snd_soc_update_bits(codec, AIC32X4_NDAC, |
526 | AIC32X4_NADCEN, 0); | 555 | AIC32X4_NDACEN, 0); |
527 | 556 | ||
528 | /* Switch off MADC Divider */ | 557 | /* Switch off PLL */ |
529 | snd_soc_update_bits(codec, AIC32X4_MADC, | 558 | snd_soc_update_bits(codec, AIC32X4_PLLPR, |
530 | AIC32X4_MADCEN, 0); | 559 | AIC32X4_PLLEN, 0); |
531 | 560 | ||
532 | /* Switch off BCLK_N Divider */ | 561 | /* Switch off master clock */ |
533 | snd_soc_update_bits(codec, AIC32X4_BCLKN, | 562 | clk_disable_unprepare(aic32x4->mclk); |
534 | AIC32X4_BCLKEN, 0); | ||
535 | break; | 563 | break; |
536 | case SND_SOC_BIAS_OFF: | 564 | case SND_SOC_BIAS_OFF: |
537 | break; | 565 | break; |
@@ -586,9 +614,7 @@ static int aic32x4_probe(struct snd_soc_codec *codec) | |||
586 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | 614 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); |
587 | u32 tmp_reg; | 615 | u32 tmp_reg; |
588 | 616 | ||
589 | snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | 617 | if (gpio_is_valid(aic32x4->rstn_gpio)) { |
590 | |||
591 | if (aic32x4->rstn_gpio >= 0) { | ||
592 | ndelay(10); | 618 | ndelay(10); |
593 | gpio_set_value(aic32x4->rstn_gpio, 1); | 619 | gpio_set_value(aic32x4->rstn_gpio, 1); |
594 | } | 620 | } |
@@ -663,11 +689,122 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { | |||
663 | .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), | 689 | .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), |
664 | }; | 690 | }; |
665 | 691 | ||
692 | static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, | ||
693 | struct device_node *np) | ||
694 | { | ||
695 | aic32x4->swapdacs = false; | ||
696 | aic32x4->micpga_routing = 0; | ||
697 | aic32x4->rstn_gpio = of_get_named_gpio(np, "reset-gpios", 0); | ||
698 | |||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | static void aic32x4_disable_regulators(struct aic32x4_priv *aic32x4) | ||
703 | { | ||
704 | regulator_disable(aic32x4->supply_iov); | ||
705 | |||
706 | if (!IS_ERR(aic32x4->supply_ldo)) | ||
707 | regulator_disable(aic32x4->supply_ldo); | ||
708 | |||
709 | if (!IS_ERR(aic32x4->supply_dv)) | ||
710 | regulator_disable(aic32x4->supply_dv); | ||
711 | |||
712 | if (!IS_ERR(aic32x4->supply_av)) | ||
713 | regulator_disable(aic32x4->supply_av); | ||
714 | } | ||
715 | |||
716 | static int aic32x4_setup_regulators(struct device *dev, | ||
717 | struct aic32x4_priv *aic32x4) | ||
718 | { | ||
719 | int ret = 0; | ||
720 | |||
721 | aic32x4->supply_ldo = devm_regulator_get_optional(dev, "ldoin"); | ||
722 | aic32x4->supply_iov = devm_regulator_get(dev, "iov"); | ||
723 | aic32x4->supply_dv = devm_regulator_get_optional(dev, "dv"); | ||
724 | aic32x4->supply_av = devm_regulator_get_optional(dev, "av"); | ||
725 | |||
726 | /* Check if the regulator requirements are fulfilled */ | ||
727 | |||
728 | if (IS_ERR(aic32x4->supply_iov)) { | ||
729 | dev_err(dev, "Missing supply 'iov'\n"); | ||
730 | return PTR_ERR(aic32x4->supply_iov); | ||
731 | } | ||
732 | |||
733 | if (IS_ERR(aic32x4->supply_ldo)) { | ||
734 | if (PTR_ERR(aic32x4->supply_ldo) == -EPROBE_DEFER) | ||
735 | return -EPROBE_DEFER; | ||
736 | |||
737 | if (IS_ERR(aic32x4->supply_dv)) { | ||
738 | dev_err(dev, "Missing supply 'dv' or 'ldoin'\n"); | ||
739 | return PTR_ERR(aic32x4->supply_dv); | ||
740 | } | ||
741 | if (IS_ERR(aic32x4->supply_av)) { | ||
742 | dev_err(dev, "Missing supply 'av' or 'ldoin'\n"); | ||
743 | return PTR_ERR(aic32x4->supply_av); | ||
744 | } | ||
745 | } else { | ||
746 | if (IS_ERR(aic32x4->supply_dv) && | ||
747 | PTR_ERR(aic32x4->supply_dv) == -EPROBE_DEFER) | ||
748 | return -EPROBE_DEFER; | ||
749 | if (IS_ERR(aic32x4->supply_av) && | ||
750 | PTR_ERR(aic32x4->supply_av) == -EPROBE_DEFER) | ||
751 | return -EPROBE_DEFER; | ||
752 | } | ||
753 | |||
754 | ret = regulator_enable(aic32x4->supply_iov); | ||
755 | if (ret) { | ||
756 | dev_err(dev, "Failed to enable regulator iov\n"); | ||
757 | return ret; | ||
758 | } | ||
759 | |||
760 | if (!IS_ERR(aic32x4->supply_ldo)) { | ||
761 | ret = regulator_enable(aic32x4->supply_ldo); | ||
762 | if (ret) { | ||
763 | dev_err(dev, "Failed to enable regulator ldo\n"); | ||
764 | goto error_ldo; | ||
765 | } | ||
766 | } | ||
767 | |||
768 | if (!IS_ERR(aic32x4->supply_dv)) { | ||
769 | ret = regulator_enable(aic32x4->supply_dv); | ||
770 | if (ret) { | ||
771 | dev_err(dev, "Failed to enable regulator dv\n"); | ||
772 | goto error_dv; | ||
773 | } | ||
774 | } | ||
775 | |||
776 | if (!IS_ERR(aic32x4->supply_av)) { | ||
777 | ret = regulator_enable(aic32x4->supply_av); | ||
778 | if (ret) { | ||
779 | dev_err(dev, "Failed to enable regulator av\n"); | ||
780 | goto error_av; | ||
781 | } | ||
782 | } | ||
783 | |||
784 | if (!IS_ERR(aic32x4->supply_ldo) && IS_ERR(aic32x4->supply_av)) | ||
785 | aic32x4->power_cfg |= AIC32X4_PWR_AIC32X4_LDO_ENABLE; | ||
786 | |||
787 | return 0; | ||
788 | |||
789 | error_av: | ||
790 | if (!IS_ERR(aic32x4->supply_dv)) | ||
791 | regulator_disable(aic32x4->supply_dv); | ||
792 | |||
793 | error_dv: | ||
794 | if (!IS_ERR(aic32x4->supply_ldo)) | ||
795 | regulator_disable(aic32x4->supply_ldo); | ||
796 | |||
797 | error_ldo: | ||
798 | regulator_disable(aic32x4->supply_iov); | ||
799 | return ret; | ||
800 | } | ||
801 | |||
666 | static int aic32x4_i2c_probe(struct i2c_client *i2c, | 802 | static int aic32x4_i2c_probe(struct i2c_client *i2c, |
667 | const struct i2c_device_id *id) | 803 | const struct i2c_device_id *id) |
668 | { | 804 | { |
669 | struct aic32x4_pdata *pdata = i2c->dev.platform_data; | 805 | struct aic32x4_pdata *pdata = i2c->dev.platform_data; |
670 | struct aic32x4_priv *aic32x4; | 806 | struct aic32x4_priv *aic32x4; |
807 | struct device_node *np = i2c->dev.of_node; | ||
671 | int ret; | 808 | int ret; |
672 | 809 | ||
673 | aic32x4 = devm_kzalloc(&i2c->dev, sizeof(struct aic32x4_priv), | 810 | aic32x4 = devm_kzalloc(&i2c->dev, sizeof(struct aic32x4_priv), |
@@ -686,6 +823,12 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c, | |||
686 | aic32x4->swapdacs = pdata->swapdacs; | 823 | aic32x4->swapdacs = pdata->swapdacs; |
687 | aic32x4->micpga_routing = pdata->micpga_routing; | 824 | aic32x4->micpga_routing = pdata->micpga_routing; |
688 | aic32x4->rstn_gpio = pdata->rstn_gpio; | 825 | aic32x4->rstn_gpio = pdata->rstn_gpio; |
826 | } else if (np) { | ||
827 | ret = aic32x4_parse_dt(aic32x4, np); | ||
828 | if (ret) { | ||
829 | dev_err(&i2c->dev, "Failed to parse DT node\n"); | ||
830 | return ret; | ||
831 | } | ||
689 | } else { | 832 | } else { |
690 | aic32x4->power_cfg = 0; | 833 | aic32x4->power_cfg = 0; |
691 | aic32x4->swapdacs = false; | 834 | aic32x4->swapdacs = false; |
@@ -693,20 +836,44 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c, | |||
693 | aic32x4->rstn_gpio = -1; | 836 | aic32x4->rstn_gpio = -1; |
694 | } | 837 | } |
695 | 838 | ||
696 | if (aic32x4->rstn_gpio >= 0) { | 839 | aic32x4->mclk = devm_clk_get(&i2c->dev, "mclk"); |
840 | if (IS_ERR(aic32x4->mclk)) { | ||
841 | dev_err(&i2c->dev, "Failed getting the mclk. The current implementation does not support the usage of this codec without mclk\n"); | ||
842 | return PTR_ERR(aic32x4->mclk); | ||
843 | } | ||
844 | |||
845 | if (gpio_is_valid(aic32x4->rstn_gpio)) { | ||
697 | ret = devm_gpio_request_one(&i2c->dev, aic32x4->rstn_gpio, | 846 | ret = devm_gpio_request_one(&i2c->dev, aic32x4->rstn_gpio, |
698 | GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); | 847 | GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); |
699 | if (ret != 0) | 848 | if (ret != 0) |
700 | return ret; | 849 | return ret; |
701 | } | 850 | } |
702 | 851 | ||
852 | ret = aic32x4_setup_regulators(&i2c->dev, aic32x4); | ||
853 | if (ret) { | ||
854 | dev_err(&i2c->dev, "Failed to setup regulators\n"); | ||
855 | return ret; | ||
856 | } | ||
857 | |||
703 | ret = snd_soc_register_codec(&i2c->dev, | 858 | ret = snd_soc_register_codec(&i2c->dev, |
704 | &soc_codec_dev_aic32x4, &aic32x4_dai, 1); | 859 | &soc_codec_dev_aic32x4, &aic32x4_dai, 1); |
705 | return ret; | 860 | if (ret) { |
861 | dev_err(&i2c->dev, "Failed to register codec\n"); | ||
862 | aic32x4_disable_regulators(aic32x4); | ||
863 | return ret; | ||
864 | } | ||
865 | |||
866 | i2c_set_clientdata(i2c, aic32x4); | ||
867 | |||
868 | return 0; | ||
706 | } | 869 | } |
707 | 870 | ||
708 | static int aic32x4_i2c_remove(struct i2c_client *client) | 871 | static int aic32x4_i2c_remove(struct i2c_client *client) |
709 | { | 872 | { |
873 | struct aic32x4_priv *aic32x4 = i2c_get_clientdata(client); | ||
874 | |||
875 | aic32x4_disable_regulators(aic32x4); | ||
876 | |||
710 | snd_soc_unregister_codec(&client->dev); | 877 | snd_soc_unregister_codec(&client->dev); |
711 | return 0; | 878 | return 0; |
712 | } | 879 | } |
@@ -717,10 +884,17 @@ static const struct i2c_device_id aic32x4_i2c_id[] = { | |||
717 | }; | 884 | }; |
718 | MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id); | 885 | MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id); |
719 | 886 | ||
887 | static const struct of_device_id aic32x4_of_id[] = { | ||
888 | { .compatible = "ti,tlv320aic32x4", }, | ||
889 | { /* senitel */ } | ||
890 | }; | ||
891 | MODULE_DEVICE_TABLE(of, aic32x4_of_id); | ||
892 | |||
720 | static struct i2c_driver aic32x4_i2c_driver = { | 893 | static struct i2c_driver aic32x4_i2c_driver = { |
721 | .driver = { | 894 | .driver = { |
722 | .name = "tlv320aic32x4", | 895 | .name = "tlv320aic32x4", |
723 | .owner = THIS_MODULE, | 896 | .owner = THIS_MODULE, |
897 | .of_match_table = aic32x4_of_id, | ||
724 | }, | 898 | }, |
725 | .probe = aic32x4_i2c_probe, | 899 | .probe = aic32x4_i2c_probe, |
726 | .remove = aic32x4_i2c_remove, | 900 | .remove = aic32x4_i2c_remove, |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 470fbfb4b386..b1835103e9b4 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -1344,12 +1344,6 @@ static int aic3x_probe(struct snd_soc_codec *codec) | |||
1344 | INIT_LIST_HEAD(&aic3x->list); | 1344 | INIT_LIST_HEAD(&aic3x->list); |
1345 | aic3x->codec = codec; | 1345 | aic3x->codec = codec; |
1346 | 1346 | ||
1347 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1348 | if (ret != 0) { | ||
1349 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1350 | return ret; | ||
1351 | } | ||
1352 | |||
1353 | for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) { | 1347 | for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) { |
1354 | aic3x->disable_nb[i].nb.notifier_call = aic3x_regulator_event; | 1348 | aic3x->disable_nb[i].nb.notifier_call = aic3x_regulator_event; |
1355 | aic3x->disable_nb[i].aic3x = aic3x; | 1349 | aic3x->disable_nb[i].aic3x = aic3x; |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 4f358393d6d6..6bfc8a17331b 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -122,7 +122,6 @@ struct tlv320dac33_priv { | |||
122 | unsigned int uthr; | 122 | unsigned int uthr; |
123 | 123 | ||
124 | enum dac33_state state; | 124 | enum dac33_state state; |
125 | enum snd_soc_control_type control_type; | ||
126 | void *control_data; | 125 | void *control_data; |
127 | }; | 126 | }; |
128 | 127 | ||
@@ -461,7 +460,7 @@ static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol, | |||
461 | if (dac33->fifo_mode == ucontrol->value.integer.value[0]) | 460 | if (dac33->fifo_mode == ucontrol->value.integer.value[0]) |
462 | return 0; | 461 | return 0; |
463 | /* Do not allow changes while stream is running*/ | 462 | /* Do not allow changes while stream is running*/ |
464 | if (codec->active) | 463 | if (snd_soc_codec_is_active(codec)) |
465 | return -EPERM; | 464 | return -EPERM; |
466 | 465 | ||
467 | if (ucontrol->value.integer.value[0] < 0 || | 466 | if (ucontrol->value.integer.value[0] < 0 || |
@@ -478,9 +477,7 @@ static const char *dac33_fifo_mode_texts[] = { | |||
478 | "Bypass", "Mode 1", "Mode 7" | 477 | "Bypass", "Mode 1", "Mode 7" |
479 | }; | 478 | }; |
480 | 479 | ||
481 | static const struct soc_enum dac33_fifo_mode_enum = | 480 | static SOC_ENUM_SINGLE_EXT_DECL(dac33_fifo_mode_enum, dac33_fifo_mode_texts); |
482 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dac33_fifo_mode_texts), | ||
483 | dac33_fifo_mode_texts); | ||
484 | 481 | ||
485 | /* L/R Line Output Gain */ | 482 | /* L/R Line Output Gain */ |
486 | static const char *lr_lineout_gain_texts[] = { | 483 | static const char *lr_lineout_gain_texts[] = { |
@@ -488,15 +485,13 @@ static const char *lr_lineout_gain_texts[] = { | |||
488 | "Line 0dB DAC 12dB", "Line 6dB DAC 18dB", | 485 | "Line 0dB DAC 12dB", "Line 6dB DAC 18dB", |
489 | }; | 486 | }; |
490 | 487 | ||
491 | static const struct soc_enum l_lineout_gain_enum = | 488 | static SOC_ENUM_SINGLE_DECL(l_lineout_gain_enum, |
492 | SOC_ENUM_SINGLE(DAC33_LDAC_PWR_CTRL, 0, | 489 | DAC33_LDAC_PWR_CTRL, 0, |
493 | ARRAY_SIZE(lr_lineout_gain_texts), | 490 | lr_lineout_gain_texts); |
494 | lr_lineout_gain_texts); | ||
495 | 491 | ||
496 | static const struct soc_enum r_lineout_gain_enum = | 492 | static SOC_ENUM_SINGLE_DECL(r_lineout_gain_enum, |
497 | SOC_ENUM_SINGLE(DAC33_RDAC_PWR_CTRL, 0, | 493 | DAC33_RDAC_PWR_CTRL, 0, |
498 | ARRAY_SIZE(lr_lineout_gain_texts), | 494 | lr_lineout_gain_texts); |
499 | lr_lineout_gain_texts); | ||
500 | 495 | ||
501 | /* | 496 | /* |
502 | * DACL/R digital volume control: | 497 | * DACL/R digital volume control: |
@@ -534,18 +529,16 @@ static const struct snd_kcontrol_new dac33_dapm_abypassr_control = | |||
534 | /* LOP L/R invert selection */ | 529 | /* LOP L/R invert selection */ |
535 | static const char *dac33_lr_lom_texts[] = {"DAC", "LOP"}; | 530 | static const char *dac33_lr_lom_texts[] = {"DAC", "LOP"}; |
536 | 531 | ||
537 | static const struct soc_enum dac33_left_lom_enum = | 532 | static SOC_ENUM_SINGLE_DECL(dac33_left_lom_enum, |
538 | SOC_ENUM_SINGLE(DAC33_OUT_AMP_CTRL, 3, | 533 | DAC33_OUT_AMP_CTRL, 3, |
539 | ARRAY_SIZE(dac33_lr_lom_texts), | 534 | dac33_lr_lom_texts); |
540 | dac33_lr_lom_texts); | ||
541 | 535 | ||
542 | static const struct snd_kcontrol_new dac33_dapm_left_lom_control = | 536 | static const struct snd_kcontrol_new dac33_dapm_left_lom_control = |
543 | SOC_DAPM_ENUM("Route", dac33_left_lom_enum); | 537 | SOC_DAPM_ENUM("Route", dac33_left_lom_enum); |
544 | 538 | ||
545 | static const struct soc_enum dac33_right_lom_enum = | 539 | static SOC_ENUM_SINGLE_DECL(dac33_right_lom_enum, |
546 | SOC_ENUM_SINGLE(DAC33_OUT_AMP_CTRL, 2, | 540 | DAC33_OUT_AMP_CTRL, 2, |
547 | ARRAY_SIZE(dac33_lr_lom_texts), | 541 | dac33_lr_lom_texts); |
548 | dac33_lr_lom_texts); | ||
549 | 542 | ||
550 | static const struct snd_kcontrol_new dac33_dapm_right_lom_control = | 543 | static const struct snd_kcontrol_new dac33_dapm_right_lom_control = |
551 | SOC_DAPM_ENUM("Route", dac33_right_lom_enum); | 544 | SOC_DAPM_ENUM("Route", dac33_right_lom_enum); |
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 00665ada23e2..975e0f760ac1 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -415,10 +415,9 @@ static const struct snd_kcontrol_new twl4030_dapm_carkitr_controls[] = { | |||
415 | static const char *twl4030_handsfreel_texts[] = | 415 | static const char *twl4030_handsfreel_texts[] = |
416 | {"Voice", "AudioL1", "AudioL2", "AudioR2"}; | 416 | {"Voice", "AudioL1", "AudioL2", "AudioR2"}; |
417 | 417 | ||
418 | static const struct soc_enum twl4030_handsfreel_enum = | 418 | static SOC_ENUM_SINGLE_DECL(twl4030_handsfreel_enum, |
419 | SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0, | 419 | TWL4030_REG_HFL_CTL, 0, |
420 | ARRAY_SIZE(twl4030_handsfreel_texts), | 420 | twl4030_handsfreel_texts); |
421 | twl4030_handsfreel_texts); | ||
422 | 421 | ||
423 | static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control = | 422 | static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control = |
424 | SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum); | 423 | SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum); |
@@ -431,10 +430,9 @@ static const struct snd_kcontrol_new twl4030_dapm_handsfreelmute_control = | |||
431 | static const char *twl4030_handsfreer_texts[] = | 430 | static const char *twl4030_handsfreer_texts[] = |
432 | {"Voice", "AudioR1", "AudioR2", "AudioL2"}; | 431 | {"Voice", "AudioR1", "AudioR2", "AudioL2"}; |
433 | 432 | ||
434 | static const struct soc_enum twl4030_handsfreer_enum = | 433 | static SOC_ENUM_SINGLE_DECL(twl4030_handsfreer_enum, |
435 | SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0, | 434 | TWL4030_REG_HFR_CTL, 0, |
436 | ARRAY_SIZE(twl4030_handsfreer_texts), | 435 | twl4030_handsfreer_texts); |
437 | twl4030_handsfreer_texts); | ||
438 | 436 | ||
439 | static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control = | 437 | static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control = |
440 | SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum); | 438 | SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum); |
@@ -448,10 +446,9 @@ static const struct snd_kcontrol_new twl4030_dapm_handsfreermute_control = | |||
448 | static const char *twl4030_vibra_texts[] = | 446 | static const char *twl4030_vibra_texts[] = |
449 | {"AudioL1", "AudioR1", "AudioL2", "AudioR2"}; | 447 | {"AudioL1", "AudioR1", "AudioL2", "AudioR2"}; |
450 | 448 | ||
451 | static const struct soc_enum twl4030_vibra_enum = | 449 | static SOC_ENUM_SINGLE_DECL(twl4030_vibra_enum, |
452 | SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 2, | 450 | TWL4030_REG_VIBRA_CTL, 2, |
453 | ARRAY_SIZE(twl4030_vibra_texts), | 451 | twl4030_vibra_texts); |
454 | twl4030_vibra_texts); | ||
455 | 452 | ||
456 | static const struct snd_kcontrol_new twl4030_dapm_vibra_control = | 453 | static const struct snd_kcontrol_new twl4030_dapm_vibra_control = |
457 | SOC_DAPM_ENUM("Route", twl4030_vibra_enum); | 454 | SOC_DAPM_ENUM("Route", twl4030_vibra_enum); |
@@ -460,10 +457,9 @@ SOC_DAPM_ENUM("Route", twl4030_vibra_enum); | |||
460 | static const char *twl4030_vibrapath_texts[] = | 457 | static const char *twl4030_vibrapath_texts[] = |
461 | {"Local vibrator", "Audio"}; | 458 | {"Local vibrator", "Audio"}; |
462 | 459 | ||
463 | static const struct soc_enum twl4030_vibrapath_enum = | 460 | static SOC_ENUM_SINGLE_DECL(twl4030_vibrapath_enum, |
464 | SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 4, | 461 | TWL4030_REG_VIBRA_CTL, 4, |
465 | ARRAY_SIZE(twl4030_vibrapath_texts), | 462 | twl4030_vibrapath_texts); |
466 | twl4030_vibrapath_texts); | ||
467 | 463 | ||
468 | static const struct snd_kcontrol_new twl4030_dapm_vibrapath_control = | 464 | static const struct snd_kcontrol_new twl4030_dapm_vibrapath_control = |
469 | SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum); | 465 | SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum); |
@@ -490,10 +486,9 @@ static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = { | |||
490 | static const char *twl4030_micpathtx1_texts[] = | 486 | static const char *twl4030_micpathtx1_texts[] = |
491 | {"Analog", "Digimic0"}; | 487 | {"Analog", "Digimic0"}; |
492 | 488 | ||
493 | static const struct soc_enum twl4030_micpathtx1_enum = | 489 | static SOC_ENUM_SINGLE_DECL(twl4030_micpathtx1_enum, |
494 | SOC_ENUM_SINGLE(TWL4030_REG_ADCMICSEL, 0, | 490 | TWL4030_REG_ADCMICSEL, 0, |
495 | ARRAY_SIZE(twl4030_micpathtx1_texts), | 491 | twl4030_micpathtx1_texts); |
496 | twl4030_micpathtx1_texts); | ||
497 | 492 | ||
498 | static const struct snd_kcontrol_new twl4030_dapm_micpathtx1_control = | 493 | static const struct snd_kcontrol_new twl4030_dapm_micpathtx1_control = |
499 | SOC_DAPM_ENUM("Route", twl4030_micpathtx1_enum); | 494 | SOC_DAPM_ENUM("Route", twl4030_micpathtx1_enum); |
@@ -502,10 +497,9 @@ SOC_DAPM_ENUM("Route", twl4030_micpathtx1_enum); | |||
502 | static const char *twl4030_micpathtx2_texts[] = | 497 | static const char *twl4030_micpathtx2_texts[] = |
503 | {"Analog", "Digimic1"}; | 498 | {"Analog", "Digimic1"}; |
504 | 499 | ||
505 | static const struct soc_enum twl4030_micpathtx2_enum = | 500 | static SOC_ENUM_SINGLE_DECL(twl4030_micpathtx2_enum, |
506 | SOC_ENUM_SINGLE(TWL4030_REG_ADCMICSEL, 2, | 501 | TWL4030_REG_ADCMICSEL, 2, |
507 | ARRAY_SIZE(twl4030_micpathtx2_texts), | 502 | twl4030_micpathtx2_texts); |
508 | twl4030_micpathtx2_texts); | ||
509 | 503 | ||
510 | static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control = | 504 | static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control = |
511 | SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum); | 505 | SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum); |
@@ -955,19 +949,15 @@ static const char *twl4030_op_modes_texts[] = { | |||
955 | "Option 2 (voice/audio)", "Option 1 (audio)" | 949 | "Option 2 (voice/audio)", "Option 1 (audio)" |
956 | }; | 950 | }; |
957 | 951 | ||
958 | static const struct soc_enum twl4030_op_modes_enum = | 952 | static SOC_ENUM_SINGLE_DECL(twl4030_op_modes_enum, |
959 | SOC_ENUM_SINGLE(TWL4030_REG_CODEC_MODE, 0, | 953 | TWL4030_REG_CODEC_MODE, 0, |
960 | ARRAY_SIZE(twl4030_op_modes_texts), | 954 | twl4030_op_modes_texts); |
961 | twl4030_op_modes_texts); | ||
962 | 955 | ||
963 | static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, | 956 | static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, |
964 | struct snd_ctl_elem_value *ucontrol) | 957 | struct snd_ctl_elem_value *ucontrol) |
965 | { | 958 | { |
966 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 959 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
967 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 960 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
968 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
969 | unsigned short val; | ||
970 | unsigned short mask; | ||
971 | 961 | ||
972 | if (twl4030->configured) { | 962 | if (twl4030->configured) { |
973 | dev_err(codec->dev, | 963 | dev_err(codec->dev, |
@@ -975,19 +965,7 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, | |||
975 | return -EBUSY; | 965 | return -EBUSY; |
976 | } | 966 | } |
977 | 967 | ||
978 | if (ucontrol->value.enumerated.item[0] > e->max - 1) | 968 | return snd_soc_put_enum_double(kcontrol, ucontrol); |
979 | return -EINVAL; | ||
980 | |||
981 | val = ucontrol->value.enumerated.item[0] << e->shift_l; | ||
982 | mask = e->mask << e->shift_l; | ||
983 | if (e->shift_l != e->shift_r) { | ||
984 | if (ucontrol->value.enumerated.item[1] > e->max - 1) | ||
985 | return -EINVAL; | ||
986 | val |= ucontrol->value.enumerated.item[1] << e->shift_r; | ||
987 | mask |= e->mask << e->shift_r; | ||
988 | } | ||
989 | |||
990 | return snd_soc_update_bits(codec, e->reg, mask, val); | ||
991 | } | 969 | } |
992 | 970 | ||
993 | /* | 971 | /* |
@@ -1044,10 +1022,9 @@ static const char *twl4030_avadc_clk_priority_texts[] = { | |||
1044 | "Voice high priority", "HiFi high priority" | 1022 | "Voice high priority", "HiFi high priority" |
1045 | }; | 1023 | }; |
1046 | 1024 | ||
1047 | static const struct soc_enum twl4030_avadc_clk_priority_enum = | 1025 | static SOC_ENUM_SINGLE_DECL(twl4030_avadc_clk_priority_enum, |
1048 | SOC_ENUM_SINGLE(TWL4030_REG_AVADC_CTL, 2, | 1026 | TWL4030_REG_AVADC_CTL, 2, |
1049 | ARRAY_SIZE(twl4030_avadc_clk_priority_texts), | 1027 | twl4030_avadc_clk_priority_texts); |
1050 | twl4030_avadc_clk_priority_texts); | ||
1051 | 1028 | ||
1052 | static const char *twl4030_rampdelay_texts[] = { | 1029 | static const char *twl4030_rampdelay_texts[] = { |
1053 | "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms", | 1030 | "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms", |
@@ -1055,40 +1032,36 @@ static const char *twl4030_rampdelay_texts[] = { | |||
1055 | "3495/2581/1748 ms" | 1032 | "3495/2581/1748 ms" |
1056 | }; | 1033 | }; |
1057 | 1034 | ||
1058 | static const struct soc_enum twl4030_rampdelay_enum = | 1035 | static SOC_ENUM_SINGLE_DECL(twl4030_rampdelay_enum, |
1059 | SOC_ENUM_SINGLE(TWL4030_REG_HS_POPN_SET, 2, | 1036 | TWL4030_REG_HS_POPN_SET, 2, |
1060 | ARRAY_SIZE(twl4030_rampdelay_texts), | 1037 | twl4030_rampdelay_texts); |
1061 | twl4030_rampdelay_texts); | ||
1062 | 1038 | ||
1063 | /* Vibra H-bridge direction mode */ | 1039 | /* Vibra H-bridge direction mode */ |
1064 | static const char *twl4030_vibradirmode_texts[] = { | 1040 | static const char *twl4030_vibradirmode_texts[] = { |
1065 | "Vibra H-bridge direction", "Audio data MSB", | 1041 | "Vibra H-bridge direction", "Audio data MSB", |
1066 | }; | 1042 | }; |
1067 | 1043 | ||
1068 | static const struct soc_enum twl4030_vibradirmode_enum = | 1044 | static SOC_ENUM_SINGLE_DECL(twl4030_vibradirmode_enum, |
1069 | SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 5, | 1045 | TWL4030_REG_VIBRA_CTL, 5, |
1070 | ARRAY_SIZE(twl4030_vibradirmode_texts), | 1046 | twl4030_vibradirmode_texts); |
1071 | twl4030_vibradirmode_texts); | ||
1072 | 1047 | ||
1073 | /* Vibra H-bridge direction */ | 1048 | /* Vibra H-bridge direction */ |
1074 | static const char *twl4030_vibradir_texts[] = { | 1049 | static const char *twl4030_vibradir_texts[] = { |
1075 | "Positive polarity", "Negative polarity", | 1050 | "Positive polarity", "Negative polarity", |
1076 | }; | 1051 | }; |
1077 | 1052 | ||
1078 | static const struct soc_enum twl4030_vibradir_enum = | 1053 | static SOC_ENUM_SINGLE_DECL(twl4030_vibradir_enum, |
1079 | SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 1, | 1054 | TWL4030_REG_VIBRA_CTL, 1, |
1080 | ARRAY_SIZE(twl4030_vibradir_texts), | 1055 | twl4030_vibradir_texts); |
1081 | twl4030_vibradir_texts); | ||
1082 | 1056 | ||
1083 | /* Digimic Left and right swapping */ | 1057 | /* Digimic Left and right swapping */ |
1084 | static const char *twl4030_digimicswap_texts[] = { | 1058 | static const char *twl4030_digimicswap_texts[] = { |
1085 | "Not swapped", "Swapped", | 1059 | "Not swapped", "Swapped", |
1086 | }; | 1060 | }; |
1087 | 1061 | ||
1088 | static const struct soc_enum twl4030_digimicswap_enum = | 1062 | static SOC_ENUM_SINGLE_DECL(twl4030_digimicswap_enum, |
1089 | SOC_ENUM_SINGLE(TWL4030_REG_MISC_SET_1, 0, | 1063 | TWL4030_REG_MISC_SET_1, 0, |
1090 | ARRAY_SIZE(twl4030_digimicswap_texts), | 1064 | twl4030_digimicswap_texts); |
1091 | twl4030_digimicswap_texts); | ||
1092 | 1065 | ||
1093 | static const struct snd_kcontrol_new twl4030_snd_controls[] = { | 1066 | static const struct snd_kcontrol_new twl4030_snd_controls[] = { |
1094 | /* Codec operation mode control */ | 1067 | /* Codec operation mode control */ |
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 0afe8bef6765..bd3a20647fdf 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
@@ -81,7 +81,7 @@ struct twl6040_data { | |||
81 | }; | 81 | }; |
82 | 82 | ||
83 | /* set of rates for each pll: low-power and high-performance */ | 83 | /* set of rates for each pll: low-power and high-performance */ |
84 | static unsigned int lp_rates[] = { | 84 | static const unsigned int lp_rates[] = { |
85 | 8000, | 85 | 8000, |
86 | 11250, | 86 | 11250, |
87 | 16000, | 87 | 16000, |
@@ -93,7 +93,7 @@ static unsigned int lp_rates[] = { | |||
93 | 96000, | 93 | 96000, |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static unsigned int hp_rates[] = { | 96 | static const unsigned int hp_rates[] = { |
97 | 8000, | 97 | 8000, |
98 | 16000, | 98 | 16000, |
99 | 32000, | 99 | 32000, |
@@ -101,7 +101,7 @@ static unsigned int hp_rates[] = { | |||
101 | 96000, | 101 | 96000, |
102 | }; | 102 | }; |
103 | 103 | ||
104 | static struct snd_pcm_hw_constraint_list sysclk_constraints[] = { | 104 | static const struct snd_pcm_hw_constraint_list sysclk_constraints[] = { |
105 | { .count = ARRAY_SIZE(lp_rates), .list = lp_rates, }, | 105 | { .count = ARRAY_SIZE(lp_rates), .list = lp_rates, }, |
106 | { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, }, | 106 | { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, }, |
107 | }; | 107 | }; |
@@ -392,8 +392,10 @@ static const char *twl6040_amicr_texts[] = | |||
392 | {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"}; | 392 | {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"}; |
393 | 393 | ||
394 | static const struct soc_enum twl6040_enum[] = { | 394 | static const struct soc_enum twl6040_enum[] = { |
395 | SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 4, twl6040_amicl_texts), | 395 | SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, |
396 | SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 4, twl6040_amicr_texts), | 396 | ARRAY_SIZE(twl6040_amicl_texts), twl6040_amicl_texts), |
397 | SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, | ||
398 | ARRAY_SIZE(twl6040_amicr_texts), twl6040_amicr_texts), | ||
397 | }; | 399 | }; |
398 | 400 | ||
399 | static const char *twl6040_hs_texts[] = { | 401 | static const char *twl6040_hs_texts[] = { |
@@ -476,9 +478,8 @@ static const char *twl6040_power_mode_texts[] = { | |||
476 | "Low-Power", "High-Performance", | 478 | "Low-Power", "High-Performance", |
477 | }; | 479 | }; |
478 | 480 | ||
479 | static const struct soc_enum twl6040_power_mode_enum = | 481 | static SOC_ENUM_SINGLE_EXT_DECL(twl6040_power_mode_enum, |
480 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl6040_power_mode_texts), | 482 | twl6040_power_mode_texts); |
481 | twl6040_power_mode_texts); | ||
482 | 483 | ||
483 | static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, | 484 | static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, |
484 | struct snd_ctl_elem_value *ucontrol) | 485 | struct snd_ctl_elem_value *ucontrol) |
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index c94d4c1e3dac..edf27acc1d77 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c | |||
@@ -203,8 +203,7 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream, | |||
203 | struct snd_pcm_hw_params *params, | 203 | struct snd_pcm_hw_params *params, |
204 | struct snd_soc_dai *dai) | 204 | struct snd_soc_dai *dai) |
205 | { | 205 | { |
206 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 206 | struct snd_soc_codec *codec = dai->codec; |
207 | struct snd_soc_codec *codec = rtd->codec; | ||
208 | struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); | 207 | struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); |
209 | u8 hw_params; | 208 | u8 hw_params; |
210 | 209 | ||
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 726df6d43c2b..e62e70781ec2 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c | |||
@@ -108,7 +108,7 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, | |||
108 | /* the interpolator & decimator regs must only be written when the | 108 | /* the interpolator & decimator regs must only be written when the |
109 | * codec DAI is active. | 109 | * codec DAI is active. |
110 | */ | 110 | */ |
111 | if (!codec->active && (reg >= UDA1380_MVOL)) | 111 | if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL)) |
112 | return 0; | 112 | return 0; |
113 | pr_debug("uda1380: hw write %x val %x\n", reg, value); | 113 | pr_debug("uda1380: hw write %x val %x\n", reg, value); |
114 | if (codec->hw_write(codec->control_data, data, 3) == 3) { | 114 | if (codec->hw_write(codec->control_data, data, 3) == 3) { |
@@ -237,25 +237,27 @@ static const char *uda1380_os_setting[] = { | |||
237 | }; | 237 | }; |
238 | 238 | ||
239 | static const struct soc_enum uda1380_deemp_enum[] = { | 239 | static const struct soc_enum uda1380_deemp_enum[] = { |
240 | SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, 5, uda1380_deemp), | 240 | SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, ARRAY_SIZE(uda1380_deemp), |
241 | SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, 5, uda1380_deemp), | 241 | uda1380_deemp), |
242 | SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, ARRAY_SIZE(uda1380_deemp), | ||
243 | uda1380_deemp), | ||
242 | }; | 244 | }; |
243 | static const struct soc_enum uda1380_input_sel_enum = | 245 | static SOC_ENUM_SINGLE_DECL(uda1380_input_sel_enum, |
244 | SOC_ENUM_SINGLE(UDA1380_ADC, 2, 4, uda1380_input_sel); /* SEL_MIC, SEL_LNA */ | 246 | UDA1380_ADC, 2, uda1380_input_sel); /* SEL_MIC, SEL_LNA */ |
245 | static const struct soc_enum uda1380_output_sel_enum = | 247 | static SOC_ENUM_SINGLE_DECL(uda1380_output_sel_enum, |
246 | SOC_ENUM_SINGLE(UDA1380_PM, 7, 2, uda1380_output_sel); /* R02_EN_AVC */ | 248 | UDA1380_PM, 7, uda1380_output_sel); /* R02_EN_AVC */ |
247 | static const struct soc_enum uda1380_spf_enum = | 249 | static SOC_ENUM_SINGLE_DECL(uda1380_spf_enum, |
248 | SOC_ENUM_SINGLE(UDA1380_MODE, 14, 4, uda1380_spf_mode); /* M */ | 250 | UDA1380_MODE, 14, uda1380_spf_mode); /* M */ |
249 | static const struct soc_enum uda1380_capture_sel_enum = | 251 | static SOC_ENUM_SINGLE_DECL(uda1380_capture_sel_enum, |
250 | SOC_ENUM_SINGLE(UDA1380_IFACE, 6, 2, uda1380_capture_sel); /* SEL_SOURCE */ | 252 | UDA1380_IFACE, 6, uda1380_capture_sel); /* SEL_SOURCE */ |
251 | static const struct soc_enum uda1380_sel_ns_enum = | 253 | static SOC_ENUM_SINGLE_DECL(uda1380_sel_ns_enum, |
252 | SOC_ENUM_SINGLE(UDA1380_MIXER, 14, 2, uda1380_sel_ns); /* SEL_NS */ | 254 | UDA1380_MIXER, 14, uda1380_sel_ns); /* SEL_NS */ |
253 | static const struct soc_enum uda1380_mix_enum = | 255 | static SOC_ENUM_SINGLE_DECL(uda1380_mix_enum, |
254 | SOC_ENUM_SINGLE(UDA1380_MIXER, 12, 4, uda1380_mix_control); /* MIX, MIX_POS */ | 256 | UDA1380_MIXER, 12, uda1380_mix_control); /* MIX, MIX_POS */ |
255 | static const struct soc_enum uda1380_sdet_enum = | 257 | static SOC_ENUM_SINGLE_DECL(uda1380_sdet_enum, |
256 | SOC_ENUM_SINGLE(UDA1380_MIXER, 4, 4, uda1380_sdet_setting); /* SD_VALUE */ | 258 | UDA1380_MIXER, 4, uda1380_sdet_setting); /* SD_VALUE */ |
257 | static const struct soc_enum uda1380_os_enum = | 259 | static SOC_ENUM_SINGLE_DECL(uda1380_os_enum, |
258 | SOC_ENUM_SINGLE(UDA1380_MIXER, 0, 3, uda1380_os_setting); /* OS */ | 260 | UDA1380_MIXER, 0, uda1380_os_setting); /* OS */ |
259 | 261 | ||
260 | /* | 262 | /* |
261 | * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB) | 263 | * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB) |
@@ -564,8 +566,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream, | |||
564 | static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream, | 566 | static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream, |
565 | struct snd_soc_dai *dai) | 567 | struct snd_soc_dai *dai) |
566 | { | 568 | { |
567 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 569 | struct snd_soc_codec *codec = dai->codec; |
568 | struct snd_soc_codec *codec = rtd->codec; | ||
569 | u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); | 570 | u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); |
570 | 571 | ||
571 | /* shut down WSPLL power if running from this clock */ | 572 | /* shut down WSPLL power if running from this clock */ |
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index b7ab2ef567c8..6be5f80b65f1 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c | |||
@@ -197,7 +197,7 @@ static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol, | |||
197 | return 0; | 197 | return 0; |
198 | 198 | ||
199 | /* Do not allow changes while stream is running */ | 199 | /* Do not allow changes while stream is running */ |
200 | if (codec->active) | 200 | if (snd_soc_codec_is_active(codec)) |
201 | return -EPERM; | 201 | return -EPERM; |
202 | 202 | ||
203 | if (ucontrol->value.integer.value[0] < 0 || | 203 | if (ucontrol->value.integer.value[0] < 0 || |
@@ -209,8 +209,7 @@ static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol, | |||
209 | return 1; | 209 | return 1; |
210 | } | 210 | } |
211 | 211 | ||
212 | static const struct soc_enum wl1273_enum = | 212 | static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route); |
213 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wl1273_audio_route), wl1273_audio_route); | ||
214 | 213 | ||
215 | static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol, | 214 | static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol, |
216 | struct snd_ctl_elem_value *ucontrol) | 215 | struct snd_ctl_elem_value *ucontrol) |
@@ -247,9 +246,7 @@ static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol, | |||
247 | 246 | ||
248 | static const char * const wl1273_audio_strings[] = { "Digital", "Analog" }; | 247 | static const char * const wl1273_audio_strings[] = { "Digital", "Analog" }; |
249 | 248 | ||
250 | static const struct soc_enum wl1273_audio_enum = | 249 | static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings); |
251 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wl1273_audio_strings), | ||
252 | wl1273_audio_strings); | ||
253 | 250 | ||
254 | static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol, | 251 | static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol, |
255 | struct snd_ctl_elem_value *ucontrol) | 252 | struct snd_ctl_elem_value *ucontrol) |
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 8ae50274ea8f..83a2c872925c 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -786,8 +786,6 @@ static int wm2000_probe(struct snd_soc_codec *codec) | |||
786 | { | 786 | { |
787 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); | 787 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); |
788 | 788 | ||
789 | snd_soc_codec_set_cache_io(codec, 16, 8, SND_SOC_REGMAP); | ||
790 | |||
791 | /* This will trigger a transition to standby mode by default */ | 789 | /* This will trigger a transition to standby mode by default */ |
792 | wm2000_anc_set_mode(wm2000); | 790 | wm2000_anc_set_mode(wm2000); |
793 | 791 | ||
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 57ba315d0c84..2e721e06671b 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c | |||
@@ -1113,11 +1113,10 @@ static const char *wm2200_rxanc_input_sel_texts[] = { | |||
1113 | "None", "IN1", "IN2", "IN3", | 1113 | "None", "IN1", "IN2", "IN3", |
1114 | }; | 1114 | }; |
1115 | 1115 | ||
1116 | static const struct soc_enum wm2200_rxanc_input_sel = | 1116 | static SOC_ENUM_SINGLE_DECL(wm2200_rxanc_input_sel, |
1117 | SOC_ENUM_SINGLE(WM2200_RXANC_SRC, | 1117 | WM2200_RXANC_SRC, |
1118 | WM2200_IN_RXANC_SEL_SHIFT, | 1118 | WM2200_IN_RXANC_SEL_SHIFT, |
1119 | ARRAY_SIZE(wm2200_rxanc_input_sel_texts), | 1119 | wm2200_rxanc_input_sel_texts); |
1120 | wm2200_rxanc_input_sel_texts); | ||
1121 | 1120 | ||
1122 | static const struct snd_kcontrol_new wm2200_snd_controls[] = { | 1121 | static const struct snd_kcontrol_new wm2200_snd_controls[] = { |
1123 | SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL, | 1122 | SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL, |
@@ -1288,11 +1287,10 @@ static const char *wm2200_aec_loopback_texts[] = { | |||
1288 | "OUT1L", "OUT1R", "OUT2L", "OUT2R", | 1287 | "OUT1L", "OUT1R", "OUT2L", "OUT2R", |
1289 | }; | 1288 | }; |
1290 | 1289 | ||
1291 | static const struct soc_enum wm2200_aec_loopback = | 1290 | static SOC_ENUM_SINGLE_DECL(wm2200_aec_loopback, |
1292 | SOC_ENUM_SINGLE(WM2200_DAC_AEC_CONTROL_1, | 1291 | WM2200_DAC_AEC_CONTROL_1, |
1293 | WM2200_AEC_LOOPBACK_SRC_SHIFT, | 1292 | WM2200_AEC_LOOPBACK_SRC_SHIFT, |
1294 | ARRAY_SIZE(wm2200_aec_loopback_texts), | 1293 | wm2200_aec_loopback_texts); |
1295 | wm2200_aec_loopback_texts); | ||
1296 | 1294 | ||
1297 | static const struct snd_kcontrol_new wm2200_aec_loopback_mux = | 1295 | static const struct snd_kcontrol_new wm2200_aec_loopback_mux = |
1298 | SOC_DAPM_ENUM("AEC Loopback", wm2200_aec_loopback); | 1296 | SOC_DAPM_ENUM("AEC Loopback", wm2200_aec_loopback); |
@@ -1556,15 +1554,8 @@ static int wm2200_probe(struct snd_soc_codec *codec) | |||
1556 | int ret; | 1554 | int ret; |
1557 | 1555 | ||
1558 | wm2200->codec = codec; | 1556 | wm2200->codec = codec; |
1559 | codec->control_data = wm2200->regmap; | ||
1560 | codec->dapm.bias_level = SND_SOC_BIAS_OFF; | 1557 | codec->dapm.bias_level = SND_SOC_BIAS_OFF; |
1561 | 1558 | ||
1562 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | ||
1563 | if (ret != 0) { | ||
1564 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1565 | return ret; | ||
1566 | } | ||
1567 | |||
1568 | ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2); | 1559 | ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2); |
1569 | if (ret != 0) | 1560 | if (ret != 0) |
1570 | return ret; | 1561 | return ret; |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 4e3e31aaf509..eca983fad891 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -506,21 +506,21 @@ static const char *wm5100_lhpf_mode_text[] = { | |||
506 | "Low-pass", "High-pass" | 506 | "Low-pass", "High-pass" |
507 | }; | 507 | }; |
508 | 508 | ||
509 | static const struct soc_enum wm5100_lhpf1_mode = | 509 | static SOC_ENUM_SINGLE_DECL(wm5100_lhpf1_mode, |
510 | SOC_ENUM_SINGLE(WM5100_HPLPF1_1, WM5100_LHPF1_MODE_SHIFT, 2, | 510 | WM5100_HPLPF1_1, WM5100_LHPF1_MODE_SHIFT, |
511 | wm5100_lhpf_mode_text); | 511 | wm5100_lhpf_mode_text); |
512 | 512 | ||
513 | static const struct soc_enum wm5100_lhpf2_mode = | 513 | static SOC_ENUM_SINGLE_DECL(wm5100_lhpf2_mode, |
514 | SOC_ENUM_SINGLE(WM5100_HPLPF2_1, WM5100_LHPF2_MODE_SHIFT, 2, | 514 | WM5100_HPLPF2_1, WM5100_LHPF2_MODE_SHIFT, |
515 | wm5100_lhpf_mode_text); | 515 | wm5100_lhpf_mode_text); |
516 | 516 | ||
517 | static const struct soc_enum wm5100_lhpf3_mode = | 517 | static SOC_ENUM_SINGLE_DECL(wm5100_lhpf3_mode, |
518 | SOC_ENUM_SINGLE(WM5100_HPLPF3_1, WM5100_LHPF3_MODE_SHIFT, 2, | 518 | WM5100_HPLPF3_1, WM5100_LHPF3_MODE_SHIFT, |
519 | wm5100_lhpf_mode_text); | 519 | wm5100_lhpf_mode_text); |
520 | 520 | ||
521 | static const struct soc_enum wm5100_lhpf4_mode = | 521 | static SOC_ENUM_SINGLE_DECL(wm5100_lhpf4_mode, |
522 | SOC_ENUM_SINGLE(WM5100_HPLPF4_1, WM5100_LHPF4_MODE_SHIFT, 2, | 522 | WM5100_HPLPF4_1, WM5100_LHPF4_MODE_SHIFT, |
523 | wm5100_lhpf_mode_text); | 523 | wm5100_lhpf_mode_text); |
524 | 524 | ||
525 | static const struct snd_kcontrol_new wm5100_snd_controls[] = { | 525 | static const struct snd_kcontrol_new wm5100_snd_controls[] = { |
526 | SOC_SINGLE("IN1 High Performance Switch", WM5100_IN1L_CONTROL, | 526 | SOC_SINGLE("IN1 High Performance Switch", WM5100_IN1L_CONTROL, |
@@ -2100,6 +2100,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100) | |||
2100 | int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | 2100 | int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) |
2101 | { | 2101 | { |
2102 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | 2102 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); |
2103 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
2103 | 2104 | ||
2104 | if (jack) { | 2105 | if (jack) { |
2105 | wm5100->jack = jack; | 2106 | wm5100->jack = jack; |
@@ -2117,9 +2118,14 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | |||
2117 | WM5100_ACCDET_RATE_MASK); | 2118 | WM5100_ACCDET_RATE_MASK); |
2118 | 2119 | ||
2119 | /* We need the charge pump to power MICBIAS */ | 2120 | /* We need the charge pump to power MICBIAS */ |
2120 | snd_soc_dapm_force_enable_pin(&codec->dapm, "CP2"); | 2121 | snd_soc_dapm_mutex_lock(dapm); |
2121 | snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); | 2122 | |
2122 | snd_soc_dapm_sync(&codec->dapm); | 2123 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "CP2"); |
2124 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK"); | ||
2125 | |||
2126 | snd_soc_dapm_sync_unlocked(dapm); | ||
2127 | |||
2128 | snd_soc_dapm_mutex_unlock(dapm); | ||
2123 | 2129 | ||
2124 | /* We start off just enabling microphone detection - even a | 2130 | /* We start off just enabling microphone detection - even a |
2125 | * plain headphone will trigger detection. | 2131 | * plain headphone will trigger detection. |
@@ -2337,13 +2343,6 @@ static int wm5100_probe(struct snd_soc_codec *codec) | |||
2337 | int ret, i; | 2343 | int ret, i; |
2338 | 2344 | ||
2339 | wm5100->codec = codec; | 2345 | wm5100->codec = codec; |
2340 | codec->control_data = wm5100->regmap; | ||
2341 | |||
2342 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | ||
2343 | if (ret != 0) { | ||
2344 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
2345 | return ret; | ||
2346 | } | ||
2347 | 2346 | ||
2348 | for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++) | 2347 | for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++) |
2349 | snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU, | 2348 | snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU, |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index ce9c8e14d4bd..dcf1d12cfef8 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -582,7 +582,7 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, | |||
582 | { | 582 | { |
583 | struct snd_soc_codec *codec = w->codec; | 583 | struct snd_soc_codec *codec = w->codec; |
584 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | 584 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); |
585 | struct regmap *regmap = codec->control_data; | 585 | struct regmap *regmap = arizona->regmap; |
586 | const struct reg_default *patch = NULL; | 586 | const struct reg_default *patch = NULL; |
587 | int i, patch_size; | 587 | int i, patch_size; |
588 | 588 | ||
@@ -622,13 +622,16 @@ static const unsigned int wm5102_osr_val[] = { | |||
622 | 622 | ||
623 | static const struct soc_enum wm5102_hpout_osr[] = { | 623 | static const struct soc_enum wm5102_hpout_osr[] = { |
624 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, | 624 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, |
625 | ARIZONA_OUT1_OSR_SHIFT, 0x7, 3, | 625 | ARIZONA_OUT1_OSR_SHIFT, 0x7, |
626 | ARRAY_SIZE(wm5102_osr_text), | ||
626 | wm5102_osr_text, wm5102_osr_val), | 627 | wm5102_osr_text, wm5102_osr_val), |
627 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L, | 628 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L, |
628 | ARIZONA_OUT2_OSR_SHIFT, 0x7, 3, | 629 | ARIZONA_OUT2_OSR_SHIFT, 0x7, |
630 | ARRAY_SIZE(wm5102_osr_text), | ||
629 | wm5102_osr_text, wm5102_osr_val), | 631 | wm5102_osr_text, wm5102_osr_val), |
630 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, | 632 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, |
631 | ARIZONA_OUT3_OSR_SHIFT, 0x7, 3, | 633 | ARIZONA_OUT3_OSR_SHIFT, 0x7, |
634 | ARRAY_SIZE(wm5102_osr_text), | ||
632 | wm5102_osr_text, wm5102_osr_val), | 635 | wm5102_osr_text, wm5102_osr_val), |
633 | }; | 636 | }; |
634 | 637 | ||
@@ -685,15 +688,8 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), | |||
685 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), | 688 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), |
686 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), | 689 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), |
687 | 690 | ||
688 | SND_SOC_BYTES_MASK("EQ1 Coefficients", ARIZONA_EQ1_1, 21, | 691 | SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19), |
689 | ARIZONA_EQ1_ENA_MASK), | 692 | SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE, 1, 0), |
690 | SND_SOC_BYTES_MASK("EQ2 Coefficients", ARIZONA_EQ2_1, 21, | ||
691 | ARIZONA_EQ2_ENA_MASK), | ||
692 | SND_SOC_BYTES_MASK("EQ3 Coefficients", ARIZONA_EQ3_1, 21, | ||
693 | ARIZONA_EQ3_ENA_MASK), | ||
694 | SND_SOC_BYTES_MASK("EQ4 Coefficients", ARIZONA_EQ4_1, 21, | ||
695 | ARIZONA_EQ4_ENA_MASK), | ||
696 | |||
697 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, | 693 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, |
698 | 24, 0, eq_tlv), | 694 | 24, 0, eq_tlv), |
699 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, | 695 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, |
@@ -705,6 +701,8 @@ SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT, | |||
705 | SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, | 701 | SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, |
706 | 24, 0, eq_tlv), | 702 | 24, 0, eq_tlv), |
707 | 703 | ||
704 | SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19), | ||
705 | SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE, 1, 0), | ||
708 | SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, | 706 | SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, |
709 | 24, 0, eq_tlv), | 707 | 24, 0, eq_tlv), |
710 | SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, | 708 | SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, |
@@ -716,6 +714,8 @@ SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT, | |||
716 | SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, | 714 | SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, |
717 | 24, 0, eq_tlv), | 715 | 24, 0, eq_tlv), |
718 | 716 | ||
717 | SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19), | ||
718 | SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE, 1, 0), | ||
719 | SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, | 719 | SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, |
720 | 24, 0, eq_tlv), | 720 | 24, 0, eq_tlv), |
721 | SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, | 721 | SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, |
@@ -727,6 +727,8 @@ SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT, | |||
727 | SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, | 727 | SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, |
728 | 24, 0, eq_tlv), | 728 | 24, 0, eq_tlv), |
729 | 729 | ||
730 | SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19), | ||
731 | SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE, 1, 0), | ||
730 | SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, | 732 | SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, |
731 | 24, 0, eq_tlv), | 733 | 24, 0, eq_tlv), |
732 | SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, | 734 | SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, |
@@ -1758,9 +1760,7 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec) | |||
1758 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); | 1760 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); |
1759 | int ret; | 1761 | int ret; |
1760 | 1762 | ||
1761 | codec->control_data = priv->core.arizona->regmap; | 1763 | ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap); |
1762 | |||
1763 | ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); | ||
1764 | if (ret != 0) | 1764 | if (ret != 0) |
1765 | return ret; | 1765 | return ret; |
1766 | 1766 | ||
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 2c3c962d9a85..df5a38dd8328 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -136,7 +136,7 @@ static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w, | |||
136 | { | 136 | { |
137 | struct snd_soc_codec *codec = w->codec; | 137 | struct snd_soc_codec *codec = w->codec; |
138 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | 138 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); |
139 | struct regmap *regmap = codec->control_data; | 139 | struct regmap *regmap = arizona->regmap; |
140 | const struct reg_default *patch = NULL; | 140 | const struct reg_default *patch = NULL; |
141 | int i, patch_size; | 141 | int i, patch_size; |
142 | 142 | ||
@@ -247,15 +247,8 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), | |||
247 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), | 247 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), |
248 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), | 248 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), |
249 | 249 | ||
250 | SND_SOC_BYTES_MASK("EQ1 Coefficients", ARIZONA_EQ1_1, 21, | 250 | SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19), |
251 | ARIZONA_EQ1_ENA_MASK), | 251 | SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE, 1, 0), |
252 | SND_SOC_BYTES_MASK("EQ2 Coefficients", ARIZONA_EQ2_1, 21, | ||
253 | ARIZONA_EQ2_ENA_MASK), | ||
254 | SND_SOC_BYTES_MASK("EQ3 Coefficients", ARIZONA_EQ3_1, 21, | ||
255 | ARIZONA_EQ3_ENA_MASK), | ||
256 | SND_SOC_BYTES_MASK("EQ4 Coefficients", ARIZONA_EQ4_1, 21, | ||
257 | ARIZONA_EQ4_ENA_MASK), | ||
258 | |||
259 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, | 252 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, |
260 | 24, 0, eq_tlv), | 253 | 24, 0, eq_tlv), |
261 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, | 254 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, |
@@ -267,6 +260,8 @@ SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT, | |||
267 | SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, | 260 | SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, |
268 | 24, 0, eq_tlv), | 261 | 24, 0, eq_tlv), |
269 | 262 | ||
263 | SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19), | ||
264 | SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE, 1, 0), | ||
270 | SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, | 265 | SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, |
271 | 24, 0, eq_tlv), | 266 | 24, 0, eq_tlv), |
272 | SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, | 267 | SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, |
@@ -278,6 +273,8 @@ SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT, | |||
278 | SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, | 273 | SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, |
279 | 24, 0, eq_tlv), | 274 | 24, 0, eq_tlv), |
280 | 275 | ||
276 | SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19), | ||
277 | SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE, 1, 0), | ||
281 | SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, | 278 | SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, |
282 | 24, 0, eq_tlv), | 279 | 24, 0, eq_tlv), |
283 | SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, | 280 | SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, |
@@ -289,6 +286,8 @@ SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT, | |||
289 | SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, | 286 | SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, |
290 | 24, 0, eq_tlv), | 287 | 24, 0, eq_tlv), |
291 | 288 | ||
289 | SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19), | ||
290 | SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE, 1, 0), | ||
292 | SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, | 291 | SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, |
293 | 24, 0, eq_tlv), | 292 | 24, 0, eq_tlv), |
294 | SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, | 293 | SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, |
@@ -1588,10 +1587,9 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) | |||
1588 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); | 1587 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); |
1589 | int ret; | 1588 | int ret; |
1590 | 1589 | ||
1591 | codec->control_data = priv->core.arizona->regmap; | ||
1592 | priv->core.arizona->dapm = &codec->dapm; | 1590 | priv->core.arizona->dapm = &codec->dapm; |
1593 | 1591 | ||
1594 | ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); | 1592 | ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap); |
1595 | if (ret != 0) | 1593 | if (ret != 0) |
1596 | return ret; | 1594 | return ret; |
1597 | 1595 | ||
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index a183dcf3d5c1..757256bf7672 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -1505,9 +1505,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) | |||
1505 | if (ret != 0) | 1505 | if (ret != 0) |
1506 | return ret; | 1506 | return ret; |
1507 | 1507 | ||
1508 | codec->control_data = wm8350->regmap; | 1508 | snd_soc_codec_set_cache_io(codec, wm8350->regmap); |
1509 | |||
1510 | snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1511 | 1509 | ||
1512 | /* Put the codec into reset if it wasn't already */ | 1510 | /* Put the codec into reset if it wasn't already */ |
1513 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); | 1511 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); |
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 48dc7d2fee36..146564feaea0 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -117,19 +117,23 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | |||
117 | static const char *wm8400_digital_sidetone[] = | 117 | static const char *wm8400_digital_sidetone[] = |
118 | {"None", "Left ADC", "Right ADC", "Reserved"}; | 118 | {"None", "Left ADC", "Right ADC", "Reserved"}; |
119 | 119 | ||
120 | static const struct soc_enum wm8400_left_digital_sidetone_enum = | 120 | static SOC_ENUM_SINGLE_DECL(wm8400_left_digital_sidetone_enum, |
121 | SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, | 121 | WM8400_DIGITAL_SIDE_TONE, |
122 | WM8400_ADC_TO_DACL_SHIFT, 2, wm8400_digital_sidetone); | 122 | WM8400_ADC_TO_DACL_SHIFT, |
123 | wm8400_digital_sidetone); | ||
123 | 124 | ||
124 | static const struct soc_enum wm8400_right_digital_sidetone_enum = | 125 | static SOC_ENUM_SINGLE_DECL(wm8400_right_digital_sidetone_enum, |
125 | SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, | 126 | WM8400_DIGITAL_SIDE_TONE, |
126 | WM8400_ADC_TO_DACR_SHIFT, 2, wm8400_digital_sidetone); | 127 | WM8400_ADC_TO_DACR_SHIFT, |
128 | wm8400_digital_sidetone); | ||
127 | 129 | ||
128 | static const char *wm8400_adcmode[] = | 130 | static const char *wm8400_adcmode[] = |
129 | {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; | 131 | {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; |
130 | 132 | ||
131 | static const struct soc_enum wm8400_right_adcmode_enum = | 133 | static SOC_ENUM_SINGLE_DECL(wm8400_right_adcmode_enum, |
132 | SOC_ENUM_SINGLE(WM8400_ADC_CTRL, WM8400_ADC_HPF_CUT_SHIFT, 3, wm8400_adcmode); | 134 | WM8400_ADC_CTRL, |
135 | WM8400_ADC_HPF_CUT_SHIFT, | ||
136 | wm8400_adcmode); | ||
133 | 137 | ||
134 | static const struct snd_kcontrol_new wm8400_snd_controls[] = { | 138 | static const struct snd_kcontrol_new wm8400_snd_controls[] = { |
135 | /* INMIXL */ | 139 | /* INMIXL */ |
@@ -422,9 +426,10 @@ SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT, | |||
422 | static const char *wm8400_ainlmux[] = | 426 | static const char *wm8400_ainlmux[] = |
423 | {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; | 427 | {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; |
424 | 428 | ||
425 | static const struct soc_enum wm8400_ainlmux_enum = | 429 | static SOC_ENUM_SINGLE_DECL(wm8400_ainlmux_enum, |
426 | SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINLMODE_SHIFT, | 430 | WM8400_INPUT_MIXER1, |
427 | ARRAY_SIZE(wm8400_ainlmux), wm8400_ainlmux); | 431 | WM8400_AINLMODE_SHIFT, |
432 | wm8400_ainlmux); | ||
428 | 433 | ||
429 | static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls = | 434 | static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls = |
430 | SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); | 435 | SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); |
@@ -435,9 +440,10 @@ SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); | |||
435 | static const char *wm8400_ainrmux[] = | 440 | static const char *wm8400_ainrmux[] = |
436 | {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; | 441 | {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; |
437 | 442 | ||
438 | static const struct soc_enum wm8400_ainrmux_enum = | 443 | static SOC_ENUM_SINGLE_DECL(wm8400_ainrmux_enum, |
439 | SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINRMODE_SHIFT, | 444 | WM8400_INPUT_MIXER1, |
440 | ARRAY_SIZE(wm8400_ainrmux), wm8400_ainrmux); | 445 | WM8400_AINRMODE_SHIFT, |
446 | wm8400_ainrmux); | ||
441 | 447 | ||
442 | static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls = | 448 | static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls = |
443 | SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum); | 449 | SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum); |
@@ -1310,10 +1316,9 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) | |||
1310 | 1316 | ||
1311 | snd_soc_codec_set_drvdata(codec, priv); | 1317 | snd_soc_codec_set_drvdata(codec, priv); |
1312 | priv->wm8400 = wm8400; | 1318 | priv->wm8400 = wm8400; |
1313 | codec->control_data = wm8400->regmap; | ||
1314 | priv->codec = codec; | 1319 | priv->codec = codec; |
1315 | 1320 | ||
1316 | snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | 1321 | snd_soc_codec_set_cache_io(codec, wm8400->regmap); |
1317 | 1322 | ||
1318 | ret = devm_regulator_bulk_get(wm8400->dev, | 1323 | ret = devm_regulator_bulk_get(wm8400->dev, |
1319 | ARRAY_SIZE(power), &power[0]); | 1324 | ARRAY_SIZE(power), &power[0]); |
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 7df7d4572755..1c1e328feeb8 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c | |||
@@ -589,20 +589,12 @@ static int wm8510_resume(struct snd_soc_codec *codec) | |||
589 | 589 | ||
590 | static int wm8510_probe(struct snd_soc_codec *codec) | 590 | static int wm8510_probe(struct snd_soc_codec *codec) |
591 | { | 591 | { |
592 | int ret; | ||
593 | |||
594 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
595 | if (ret < 0) { | ||
596 | printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret); | ||
597 | return ret; | ||
598 | } | ||
599 | |||
600 | wm8510_reset(codec); | 592 | wm8510_reset(codec); |
601 | 593 | ||
602 | /* power on device */ | 594 | /* power on device */ |
603 | wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 595 | wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
604 | 596 | ||
605 | return ret; | 597 | return 0; |
606 | } | 598 | } |
607 | 599 | ||
608 | /* power down chip */ | 600 | /* power down chip */ |
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 74d106dc7667..601ee8178af1 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c | |||
@@ -75,8 +75,8 @@ static const char *wm8523_zd_count_text[] = { | |||
75 | "2048", | 75 | "2048", |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static const struct soc_enum wm8523_zc_count = | 78 | static SOC_ENUM_SINGLE_DECL(wm8523_zc_count, WM8523_ZERO_DETECT, 0, |
79 | SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text); | 79 | wm8523_zd_count_text); |
80 | 80 | ||
81 | static const struct snd_kcontrol_new wm8523_controls[] = { | 81 | static const struct snd_kcontrol_new wm8523_controls[] = { |
82 | SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR, | 82 | SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR, |
@@ -392,18 +392,11 @@ static int wm8523_resume(struct snd_soc_codec *codec) | |||
392 | static int wm8523_probe(struct snd_soc_codec *codec) | 392 | static int wm8523_probe(struct snd_soc_codec *codec) |
393 | { | 393 | { |
394 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); | 394 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); |
395 | int ret; | ||
396 | 395 | ||
397 | wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; | 396 | wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; |
398 | wm8523->rate_constraint.count = | 397 | wm8523->rate_constraint.count = |
399 | ARRAY_SIZE(wm8523->rate_constraint_list); | 398 | ARRAY_SIZE(wm8523->rate_constraint_list); |
400 | 399 | ||
401 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
402 | if (ret != 0) { | ||
403 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
404 | return ret; | ||
405 | } | ||
406 | |||
407 | /* Change some default settings - latch VU and enable ZC */ | 400 | /* Change some default settings - latch VU and enable ZC */ |
408 | snd_soc_update_bits(codec, WM8523_DAC_GAINR, | 401 | snd_soc_update_bits(codec, WM8523_DAC_GAINR, |
409 | WM8523_DACR_VU, WM8523_DACR_VU); | 402 | WM8523_DACR_VU, WM8523_DACR_VU); |
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 318989acbbe5..af7ed8b5d4e1 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c | |||
@@ -504,8 +504,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream, | |||
504 | struct snd_pcm_hw_params *params, | 504 | struct snd_pcm_hw_params *params, |
505 | struct snd_soc_dai *dai) | 505 | struct snd_soc_dai *dai) |
506 | { | 506 | { |
507 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 507 | struct snd_soc_codec *codec = dai->codec; |
508 | struct snd_soc_codec *codec = rtd->codec; | ||
509 | struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); | 508 | struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); |
510 | u16 paifa = 0; | 509 | u16 paifa = 0; |
511 | u16 paifb = 0; | 510 | u16 paifb = 0; |
@@ -869,12 +868,6 @@ static int wm8580_probe(struct snd_soc_codec *codec) | |||
869 | struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); | 868 | struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); |
870 | int ret = 0; | 869 | int ret = 0; |
871 | 870 | ||
872 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
873 | if (ret < 0) { | ||
874 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
875 | return ret; | ||
876 | } | ||
877 | |||
878 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies), | 871 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies), |
879 | wm8580->supplies); | 872 | wm8580->supplies); |
880 | if (ret != 0) { | 873 | if (ret != 0) { |
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index d99f948c513c..b0fbcb377baf 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c | |||
@@ -201,7 +201,7 @@ static void wm8711_shutdown(struct snd_pcm_substream *substream, | |||
201 | struct snd_soc_codec *codec = dai->codec; | 201 | struct snd_soc_codec *codec = dai->codec; |
202 | 202 | ||
203 | /* deactivate */ | 203 | /* deactivate */ |
204 | if (!codec->active) { | 204 | if (!snd_soc_codec_is_active(codec)) { |
205 | udelay(50); | 205 | udelay(50); |
206 | snd_soc_write(codec, WM8711_ACTIVE, 0x0); | 206 | snd_soc_write(codec, WM8711_ACTIVE, 0x0); |
207 | } | 207 | } |
@@ -367,12 +367,6 @@ static int wm8711_probe(struct snd_soc_codec *codec) | |||
367 | { | 367 | { |
368 | int ret; | 368 | int ret; |
369 | 369 | ||
370 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
371 | if (ret < 0) { | ||
372 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
373 | return ret; | ||
374 | } | ||
375 | |||
376 | ret = wm8711_reset(codec); | 370 | ret = wm8711_reset(codec); |
377 | if (ret < 0) { | 371 | if (ret < 0) { |
378 | dev_err(codec->dev, "Failed to issue reset\n"); | 372 | dev_err(codec->dev, "Failed to issue reset\n"); |
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index cd89033e84c0..bac7fc28fe71 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c | |||
@@ -228,19 +228,10 @@ static int wm8728_resume(struct snd_soc_codec *codec) | |||
228 | 228 | ||
229 | static int wm8728_probe(struct snd_soc_codec *codec) | 229 | static int wm8728_probe(struct snd_soc_codec *codec) |
230 | { | 230 | { |
231 | int ret; | ||
232 | |||
233 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
234 | if (ret < 0) { | ||
235 | printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n", | ||
236 | ret); | ||
237 | return ret; | ||
238 | } | ||
239 | |||
240 | /* power on device */ | 231 | /* power on device */ |
241 | wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 232 | wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
242 | 233 | ||
243 | return ret; | 234 | return 0; |
244 | } | 235 | } |
245 | 236 | ||
246 | static int wm8728_remove(struct snd_soc_codec *codec) | 237 | static int wm8728_remove(struct snd_soc_codec *codec) |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 029720366ff8..d74f43975b90 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -83,8 +83,8 @@ static bool wm8731_writeable(struct device *dev, unsigned int reg) | |||
83 | 83 | ||
84 | static const char *wm8731_input_select[] = {"Line In", "Mic"}; | 84 | static const char *wm8731_input_select[] = {"Line In", "Mic"}; |
85 | 85 | ||
86 | static const struct soc_enum wm8731_insel_enum = | 86 | static SOC_ENUM_SINGLE_DECL(wm8731_insel_enum, |
87 | SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select); | 87 | WM8731_APANA, 2, wm8731_input_select); |
88 | 88 | ||
89 | static int wm8731_deemph[] = { 0, 32000, 44100, 48000 }; | 89 | static int wm8731_deemph[] = { 0, 32000, 44100, 48000 }; |
90 | 90 | ||
@@ -583,13 +583,6 @@ static int wm8731_probe(struct snd_soc_codec *codec) | |||
583 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 583 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
584 | int ret = 0, i; | 584 | int ret = 0, i; |
585 | 585 | ||
586 | codec->control_data = wm8731->regmap; | ||
587 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
588 | if (ret < 0) { | ||
589 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
590 | return ret; | ||
591 | } | ||
592 | |||
593 | for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) | 586 | for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) |
594 | wm8731->supplies[i].supply = wm8731_supply_names[i]; | 587 | wm8731->supplies[i].supply = wm8731_supply_names[i]; |
595 | 588 | ||
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index 2f167a8ca01b..b27f26cdc049 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c | |||
@@ -99,29 +99,29 @@ static const char *micbias_enum_text[] = { | |||
99 | "100%", | 99 | "100%", |
100 | }; | 100 | }; |
101 | 101 | ||
102 | static const struct soc_enum micbias_enum = | 102 | static SOC_ENUM_SINGLE_DECL(micbias_enum, |
103 | SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 0, 4, micbias_enum_text); | 103 | WM8737_MIC_PREAMP_CONTROL, 0, micbias_enum_text); |
104 | 104 | ||
105 | static const char *low_cutoff_text[] = { | 105 | static const char *low_cutoff_text[] = { |
106 | "Low", "High" | 106 | "Low", "High" |
107 | }; | 107 | }; |
108 | 108 | ||
109 | static const struct soc_enum low_3d = | 109 | static SOC_ENUM_SINGLE_DECL(low_3d, |
110 | SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 6, 2, low_cutoff_text); | 110 | WM8737_3D_ENHANCE, 6, low_cutoff_text); |
111 | 111 | ||
112 | static const char *high_cutoff_text[] = { | 112 | static const char *high_cutoff_text[] = { |
113 | "High", "Low" | 113 | "High", "Low" |
114 | }; | 114 | }; |
115 | 115 | ||
116 | static const struct soc_enum high_3d = | 116 | static SOC_ENUM_SINGLE_DECL(high_3d, |
117 | SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 5, 2, high_cutoff_text); | 117 | WM8737_3D_ENHANCE, 5, high_cutoff_text); |
118 | 118 | ||
119 | static const char *alc_fn_text[] = { | 119 | static const char *alc_fn_text[] = { |
120 | "Disabled", "Right", "Left", "Stereo" | 120 | "Disabled", "Right", "Left", "Stereo" |
121 | }; | 121 | }; |
122 | 122 | ||
123 | static const struct soc_enum alc_fn = | 123 | static SOC_ENUM_SINGLE_DECL(alc_fn, |
124 | SOC_ENUM_SINGLE(WM8737_ALC1, 7, 4, alc_fn_text); | 124 | WM8737_ALC1, 7, alc_fn_text); |
125 | 125 | ||
126 | static const char *alc_hold_text[] = { | 126 | static const char *alc_hold_text[] = { |
127 | "0", "2.67ms", "5.33ms", "10.66ms", "21.32ms", "42.64ms", "85.28ms", | 127 | "0", "2.67ms", "5.33ms", "10.66ms", "21.32ms", "42.64ms", "85.28ms", |
@@ -129,24 +129,24 @@ static const char *alc_hold_text[] = { | |||
129 | "10.916s", "21.832s", "43.691s" | 129 | "10.916s", "21.832s", "43.691s" |
130 | }; | 130 | }; |
131 | 131 | ||
132 | static const struct soc_enum alc_hold = | 132 | static SOC_ENUM_SINGLE_DECL(alc_hold, |
133 | SOC_ENUM_SINGLE(WM8737_ALC2, 0, 16, alc_hold_text); | 133 | WM8737_ALC2, 0, alc_hold_text); |
134 | 134 | ||
135 | static const char *alc_atk_text[] = { | 135 | static const char *alc_atk_text[] = { |
136 | "8.4ms", "16.8ms", "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", | 136 | "8.4ms", "16.8ms", "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", |
137 | "1.075s", "2.15s", "4.3s", "8.6s" | 137 | "1.075s", "2.15s", "4.3s", "8.6s" |
138 | }; | 138 | }; |
139 | 139 | ||
140 | static const struct soc_enum alc_atk = | 140 | static SOC_ENUM_SINGLE_DECL(alc_atk, |
141 | SOC_ENUM_SINGLE(WM8737_ALC3, 0, 11, alc_atk_text); | 141 | WM8737_ALC3, 0, alc_atk_text); |
142 | 142 | ||
143 | static const char *alc_dcy_text[] = { | 143 | static const char *alc_dcy_text[] = { |
144 | "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", "1.075s", "2.15s", | 144 | "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", "1.075s", "2.15s", |
145 | "4.3s", "8.6s", "17.2s", "34.41s" | 145 | "4.3s", "8.6s", "17.2s", "34.41s" |
146 | }; | 146 | }; |
147 | 147 | ||
148 | static const struct soc_enum alc_dcy = | 148 | static SOC_ENUM_SINGLE_DECL(alc_dcy, |
149 | SOC_ENUM_SINGLE(WM8737_ALC3, 4, 11, alc_dcy_text); | 149 | WM8737_ALC3, 4, alc_dcy_text); |
150 | 150 | ||
151 | static const struct snd_kcontrol_new wm8737_snd_controls[] = { | 151 | static const struct snd_kcontrol_new wm8737_snd_controls[] = { |
152 | SOC_DOUBLE_R_TLV("Mic Boost Volume", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R, | 152 | SOC_DOUBLE_R_TLV("Mic Boost Volume", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R, |
@@ -191,8 +191,8 @@ static const char *linsel_text[] = { | |||
191 | "LINPUT1", "LINPUT2", "LINPUT3", "LINPUT1 DC", | 191 | "LINPUT1", "LINPUT2", "LINPUT3", "LINPUT1 DC", |
192 | }; | 192 | }; |
193 | 193 | ||
194 | static const struct soc_enum linsel_enum = | 194 | static SOC_ENUM_SINGLE_DECL(linsel_enum, |
195 | SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_L, 7, 4, linsel_text); | 195 | WM8737_AUDIO_PATH_L, 7, linsel_text); |
196 | 196 | ||
197 | static const struct snd_kcontrol_new linsel_mux = | 197 | static const struct snd_kcontrol_new linsel_mux = |
198 | SOC_DAPM_ENUM("LINSEL", linsel_enum); | 198 | SOC_DAPM_ENUM("LINSEL", linsel_enum); |
@@ -202,8 +202,8 @@ static const char *rinsel_text[] = { | |||
202 | "RINPUT1", "RINPUT2", "RINPUT3", "RINPUT1 DC", | 202 | "RINPUT1", "RINPUT2", "RINPUT3", "RINPUT1 DC", |
203 | }; | 203 | }; |
204 | 204 | ||
205 | static const struct soc_enum rinsel_enum = | 205 | static SOC_ENUM_SINGLE_DECL(rinsel_enum, |
206 | SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_R, 7, 4, rinsel_text); | 206 | WM8737_AUDIO_PATH_R, 7, rinsel_text); |
207 | 207 | ||
208 | static const struct snd_kcontrol_new rinsel_mux = | 208 | static const struct snd_kcontrol_new rinsel_mux = |
209 | SOC_DAPM_ENUM("RINSEL", rinsel_enum); | 209 | SOC_DAPM_ENUM("RINSEL", rinsel_enum); |
@@ -212,15 +212,15 @@ static const char *bypass_text[] = { | |||
212 | "Direct", "Preamp" | 212 | "Direct", "Preamp" |
213 | }; | 213 | }; |
214 | 214 | ||
215 | static const struct soc_enum lbypass_enum = | 215 | static SOC_ENUM_SINGLE_DECL(lbypass_enum, |
216 | SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 2, 2, bypass_text); | 216 | WM8737_MIC_PREAMP_CONTROL, 2, bypass_text); |
217 | 217 | ||
218 | static const struct snd_kcontrol_new lbypass_mux = | 218 | static const struct snd_kcontrol_new lbypass_mux = |
219 | SOC_DAPM_ENUM("Left Bypass", lbypass_enum); | 219 | SOC_DAPM_ENUM("Left Bypass", lbypass_enum); |
220 | 220 | ||
221 | 221 | ||
222 | static const struct soc_enum rbypass_enum = | 222 | static SOC_ENUM_SINGLE_DECL(rbypass_enum, |
223 | SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 3, 2, bypass_text); | 223 | WM8737_MIC_PREAMP_CONTROL, 3, bypass_text); |
224 | 224 | ||
225 | static const struct snd_kcontrol_new rbypass_mux = | 225 | static const struct snd_kcontrol_new rbypass_mux = |
226 | SOC_DAPM_ENUM("Left Bypass", rbypass_enum); | 226 | SOC_DAPM_ENUM("Left Bypass", rbypass_enum); |
@@ -570,12 +570,6 @@ static int wm8737_probe(struct snd_soc_codec *codec) | |||
570 | struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); | 570 | struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); |
571 | int ret; | 571 | int ret; |
572 | 572 | ||
573 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
574 | if (ret != 0) { | ||
575 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
576 | return ret; | ||
577 | } | ||
578 | |||
579 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), | 573 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), |
580 | wm8737->supplies); | 574 | wm8737->supplies); |
581 | if (ret != 0) { | 575 | if (ret != 0) { |
@@ -644,7 +638,7 @@ static const struct regmap_config wm8737_regmap = { | |||
644 | .volatile_reg = wm8737_volatile, | 638 | .volatile_reg = wm8737_volatile, |
645 | }; | 639 | }; |
646 | 640 | ||
647 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 641 | #if IS_ENABLED(CONFIG_I2C) |
648 | static int wm8737_i2c_probe(struct i2c_client *i2c, | 642 | static int wm8737_i2c_probe(struct i2c_client *i2c, |
649 | const struct i2c_device_id *id) | 643 | const struct i2c_device_id *id) |
650 | { | 644 | { |
@@ -758,7 +752,7 @@ static struct spi_driver wm8737_spi_driver = { | |||
758 | static int __init wm8737_modinit(void) | 752 | static int __init wm8737_modinit(void) |
759 | { | 753 | { |
760 | int ret; | 754 | int ret; |
761 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 755 | #if IS_ENABLED(CONFIG_I2C) |
762 | ret = i2c_add_driver(&wm8737_i2c_driver); | 756 | ret = i2c_add_driver(&wm8737_i2c_driver); |
763 | if (ret != 0) { | 757 | if (ret != 0) { |
764 | printk(KERN_ERR "Failed to register WM8737 I2C driver: %d\n", | 758 | printk(KERN_ERR "Failed to register WM8737 I2C driver: %d\n", |
@@ -781,7 +775,7 @@ static void __exit wm8737_exit(void) | |||
781 | #if defined(CONFIG_SPI_MASTER) | 775 | #if defined(CONFIG_SPI_MASTER) |
782 | spi_unregister_driver(&wm8737_spi_driver); | 776 | spi_unregister_driver(&wm8737_spi_driver); |
783 | #endif | 777 | #endif |
784 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 778 | #if IS_ENABLED(CONFIG_I2C) |
785 | i2c_del_driver(&wm8737_i2c_driver); | 779 | i2c_del_driver(&wm8737_i2c_driver); |
786 | #endif | 780 | #endif |
787 | } | 781 | } |
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 2895c8d3b5e4..b33542a04607 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c | |||
@@ -44,7 +44,7 @@ struct wm8741_priv { | |||
44 | struct regmap *regmap; | 44 | struct regmap *regmap; |
45 | struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; | 45 | struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; |
46 | unsigned int sysclk; | 46 | unsigned int sysclk; |
47 | struct snd_pcm_hw_constraint_list *sysclk_constraints; | 47 | const struct snd_pcm_hw_constraint_list *sysclk_constraints; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static const struct reg_default wm8741_reg_defaults[] = { | 50 | static const struct reg_default wm8741_reg_defaults[] = { |
@@ -122,74 +122,74 @@ static struct { | |||
122 | { 6, 768 }, | 122 | { 6, 768 }, |
123 | }; | 123 | }; |
124 | 124 | ||
125 | static unsigned int rates_11289[] = { | 125 | static const unsigned int rates_11289[] = { |
126 | 44100, 88235, | 126 | 44100, 88235, |
127 | }; | 127 | }; |
128 | 128 | ||
129 | static struct snd_pcm_hw_constraint_list constraints_11289 = { | 129 | static const struct snd_pcm_hw_constraint_list constraints_11289 = { |
130 | .count = ARRAY_SIZE(rates_11289), | 130 | .count = ARRAY_SIZE(rates_11289), |
131 | .list = rates_11289, | 131 | .list = rates_11289, |
132 | }; | 132 | }; |
133 | 133 | ||
134 | static unsigned int rates_12288[] = { | 134 | static const unsigned int rates_12288[] = { |
135 | 32000, 48000, 96000, | 135 | 32000, 48000, 96000, |
136 | }; | 136 | }; |
137 | 137 | ||
138 | static struct snd_pcm_hw_constraint_list constraints_12288 = { | 138 | static const struct snd_pcm_hw_constraint_list constraints_12288 = { |
139 | .count = ARRAY_SIZE(rates_12288), | 139 | .count = ARRAY_SIZE(rates_12288), |
140 | .list = rates_12288, | 140 | .list = rates_12288, |
141 | }; | 141 | }; |
142 | 142 | ||
143 | static unsigned int rates_16384[] = { | 143 | static const unsigned int rates_16384[] = { |
144 | 32000, | 144 | 32000, |
145 | }; | 145 | }; |
146 | 146 | ||
147 | static struct snd_pcm_hw_constraint_list constraints_16384 = { | 147 | static const struct snd_pcm_hw_constraint_list constraints_16384 = { |
148 | .count = ARRAY_SIZE(rates_16384), | 148 | .count = ARRAY_SIZE(rates_16384), |
149 | .list = rates_16384, | 149 | .list = rates_16384, |
150 | }; | 150 | }; |
151 | 151 | ||
152 | static unsigned int rates_16934[] = { | 152 | static const unsigned int rates_16934[] = { |
153 | 44100, 88235, | 153 | 44100, 88235, |
154 | }; | 154 | }; |
155 | 155 | ||
156 | static struct snd_pcm_hw_constraint_list constraints_16934 = { | 156 | static const struct snd_pcm_hw_constraint_list constraints_16934 = { |
157 | .count = ARRAY_SIZE(rates_16934), | 157 | .count = ARRAY_SIZE(rates_16934), |
158 | .list = rates_16934, | 158 | .list = rates_16934, |
159 | }; | 159 | }; |
160 | 160 | ||
161 | static unsigned int rates_18432[] = { | 161 | static const unsigned int rates_18432[] = { |
162 | 48000, 96000, | 162 | 48000, 96000, |
163 | }; | 163 | }; |
164 | 164 | ||
165 | static struct snd_pcm_hw_constraint_list constraints_18432 = { | 165 | static const struct snd_pcm_hw_constraint_list constraints_18432 = { |
166 | .count = ARRAY_SIZE(rates_18432), | 166 | .count = ARRAY_SIZE(rates_18432), |
167 | .list = rates_18432, | 167 | .list = rates_18432, |
168 | }; | 168 | }; |
169 | 169 | ||
170 | static unsigned int rates_22579[] = { | 170 | static const unsigned int rates_22579[] = { |
171 | 44100, 88235, 1764000 | 171 | 44100, 88235, 1764000 |
172 | }; | 172 | }; |
173 | 173 | ||
174 | static struct snd_pcm_hw_constraint_list constraints_22579 = { | 174 | static const struct snd_pcm_hw_constraint_list constraints_22579 = { |
175 | .count = ARRAY_SIZE(rates_22579), | 175 | .count = ARRAY_SIZE(rates_22579), |
176 | .list = rates_22579, | 176 | .list = rates_22579, |
177 | }; | 177 | }; |
178 | 178 | ||
179 | static unsigned int rates_24576[] = { | 179 | static const unsigned int rates_24576[] = { |
180 | 32000, 48000, 96000, 192000 | 180 | 32000, 48000, 96000, 192000 |
181 | }; | 181 | }; |
182 | 182 | ||
183 | static struct snd_pcm_hw_constraint_list constraints_24576 = { | 183 | static const struct snd_pcm_hw_constraint_list constraints_24576 = { |
184 | .count = ARRAY_SIZE(rates_24576), | 184 | .count = ARRAY_SIZE(rates_24576), |
185 | .list = rates_24576, | 185 | .list = rates_24576, |
186 | }; | 186 | }; |
187 | 187 | ||
188 | static unsigned int rates_36864[] = { | 188 | static const unsigned int rates_36864[] = { |
189 | 48000, 96000, 19200 | 189 | 48000, 96000, 19200 |
190 | }; | 190 | }; |
191 | 191 | ||
192 | static struct snd_pcm_hw_constraint_list constraints_36864 = { | 192 | static const struct snd_pcm_hw_constraint_list constraints_36864 = { |
193 | .count = ARRAY_SIZE(rates_36864), | 193 | .count = ARRAY_SIZE(rates_36864), |
194 | .list = rates_36864, | 194 | .list = rates_36864, |
195 | }; | 195 | }; |
@@ -429,12 +429,6 @@ static int wm8741_probe(struct snd_soc_codec *codec) | |||
429 | goto err_get; | 429 | goto err_get; |
430 | } | 430 | } |
431 | 431 | ||
432 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
433 | if (ret != 0) { | ||
434 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
435 | goto err_enable; | ||
436 | } | ||
437 | |||
438 | ret = wm8741_reset(codec); | 432 | ret = wm8741_reset(codec); |
439 | if (ret < 0) { | 433 | if (ret < 0) { |
440 | dev_err(codec->dev, "Failed to issue reset\n"); | 434 | dev_err(codec->dev, "Failed to issue reset\n"); |
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 78616a638a55..33990b63d214 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
@@ -702,12 +702,6 @@ static int wm8750_probe(struct snd_soc_codec *codec) | |||
702 | { | 702 | { |
703 | int ret; | 703 | int ret; |
704 | 704 | ||
705 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
706 | if (ret < 0) { | ||
707 | printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret); | ||
708 | return ret; | ||
709 | } | ||
710 | |||
711 | ret = wm8750_reset(codec); | 705 | ret = wm8750_reset(codec); |
712 | if (ret < 0) { | 706 | if (ret < 0) { |
713 | printk(KERN_ERR "wm8750: failed to reset: %d\n", ret); | 707 | printk(KERN_ERR "wm8750: failed to reset: %d\n", ret); |
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index be85da93a268..cbb8d55052a4 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -251,7 +251,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol, | |||
251 | if (wm8753->dai_func == ucontrol->value.integer.value[0]) | 251 | if (wm8753->dai_func == ucontrol->value.integer.value[0]) |
252 | return 0; | 252 | return 0; |
253 | 253 | ||
254 | if (codec->active) | 254 | if (snd_soc_codec_is_active(codec)) |
255 | return -EBUSY; | 255 | return -EBUSY; |
256 | 256 | ||
257 | ioctl = snd_soc_read(codec, WM8753_IOCTL); | 257 | ioctl = snd_soc_read(codec, WM8753_IOCTL); |
@@ -1314,7 +1314,7 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute) | |||
1314 | /* the digital mute covers the HiFi and Voice DAC's on the WM8753. | 1314 | /* the digital mute covers the HiFi and Voice DAC's on the WM8753. |
1315 | * make sure we check if they are not both active when we mute */ | 1315 | * make sure we check if they are not both active when we mute */ |
1316 | if (mute && wm8753->dai_func == 1) { | 1316 | if (mute && wm8753->dai_func == 1) { |
1317 | if (!codec->active) | 1317 | if (!snd_soc_codec_is_active(codec)) |
1318 | snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8); | 1318 | snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8); |
1319 | } else { | 1319 | } else { |
1320 | if (mute) | 1320 | if (mute) |
@@ -1440,7 +1440,6 @@ static void wm8753_work(struct work_struct *work) | |||
1440 | static int wm8753_suspend(struct snd_soc_codec *codec) | 1440 | static int wm8753_suspend(struct snd_soc_codec *codec) |
1441 | { | 1441 | { |
1442 | wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1442 | wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1443 | codec->cache_sync = 1; | ||
1444 | return 0; | 1443 | return 0; |
1445 | } | 1444 | } |
1446 | 1445 | ||
@@ -1471,13 +1470,6 @@ static int wm8753_probe(struct snd_soc_codec *codec) | |||
1471 | 1470 | ||
1472 | INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work); | 1471 | INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work); |
1473 | 1472 | ||
1474 | codec->control_data = wm8753->regmap; | ||
1475 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
1476 | if (ret < 0) { | ||
1477 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1478 | return ret; | ||
1479 | } | ||
1480 | |||
1481 | ret = wm8753_reset(codec); | 1473 | ret = wm8753_reset(codec); |
1482 | if (ret < 0) { | 1474 | if (ret < 0) { |
1483 | dev_err(codec->dev, "Failed to issue reset: %d\n", ret); | 1475 | dev_err(codec->dev, "Failed to issue reset: %d\n", ret); |
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 89a18d82f303..c61aeb38efb8 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c | |||
@@ -196,8 +196,8 @@ static const char *ain_text[] = { | |||
196 | "AIN5", "AIN6", "AIN7", "AIN8" | 196 | "AIN5", "AIN6", "AIN7", "AIN8" |
197 | }; | 197 | }; |
198 | 198 | ||
199 | static const struct soc_enum ain_enum = | 199 | static SOC_ENUM_DOUBLE_DECL(ain_enum, |
200 | SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text); | 200 | WM8770_ADCMUX, 0, 4, ain_text); |
201 | 201 | ||
202 | static const struct snd_kcontrol_new ain_mux = | 202 | static const struct snd_kcontrol_new ain_mux = |
203 | SOC_DAPM_ENUM("Capture Mux", ain_enum); | 203 | SOC_DAPM_ENUM("Capture Mux", ain_enum); |
@@ -580,12 +580,6 @@ static int wm8770_probe(struct snd_soc_codec *codec) | |||
580 | wm8770 = snd_soc_codec_get_drvdata(codec); | 580 | wm8770 = snd_soc_codec_get_drvdata(codec); |
581 | wm8770->codec = codec; | 581 | wm8770->codec = codec; |
582 | 582 | ||
583 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
584 | if (ret < 0) { | ||
585 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
586 | return ret; | ||
587 | } | ||
588 | |||
589 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies), | 583 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies), |
590 | wm8770->supplies); | 584 | wm8770->supplies); |
591 | if (ret) { | 585 | if (ret) { |
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index ef8246725232..70952ceb278b 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c | |||
@@ -430,12 +430,6 @@ static int wm8776_probe(struct snd_soc_codec *codec) | |||
430 | { | 430 | { |
431 | int ret = 0; | 431 | int ret = 0; |
432 | 432 | ||
433 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
434 | if (ret < 0) { | ||
435 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
436 | return ret; | ||
437 | } | ||
438 | |||
439 | ret = wm8776_reset(codec); | 433 | ret = wm8776_reset(codec); |
440 | if (ret < 0) { | 434 | if (ret < 0) { |
441 | dev_err(codec->dev, "Failed to issue reset: %d\n", ret); | 435 | dev_err(codec->dev, "Failed to issue reset: %d\n", ret); |
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 9bc8206a6807..ee76f0fb4299 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c | |||
@@ -92,7 +92,7 @@ WM8804_REGULATOR_EVENT(0) | |||
92 | WM8804_REGULATOR_EVENT(1) | 92 | WM8804_REGULATOR_EVENT(1) |
93 | 93 | ||
94 | static const char *txsrc_text[] = { "S/PDIF RX", "AIF" }; | 94 | static const char *txsrc_text[] = { "S/PDIF RX", "AIF" }; |
95 | static const SOC_ENUM_SINGLE_EXT_DECL(txsrc, txsrc_text); | 95 | static SOC_ENUM_SINGLE_EXT_DECL(txsrc, txsrc_text); |
96 | 96 | ||
97 | static const struct snd_kcontrol_new wm8804_snd_controls[] = { | 97 | static const struct snd_kcontrol_new wm8804_snd_controls[] = { |
98 | SOC_ENUM_EXT("Input Source", txsrc, txsrc_get, txsrc_put), | 98 | SOC_ENUM_EXT("Input Source", txsrc, txsrc_get, txsrc_put), |
@@ -546,14 +546,6 @@ static int wm8804_probe(struct snd_soc_codec *codec) | |||
546 | 546 | ||
547 | wm8804 = snd_soc_codec_get_drvdata(codec); | 547 | wm8804 = snd_soc_codec_get_drvdata(codec); |
548 | 548 | ||
549 | codec->control_data = wm8804->regmap; | ||
550 | |||
551 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
552 | if (ret < 0) { | ||
553 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); | ||
554 | return ret; | ||
555 | } | ||
556 | |||
557 | for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) | 549 | for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) |
558 | wm8804->supplies[i].supply = wm8804_supply_names[i]; | 550 | wm8804->supplies[i].supply = wm8804_supply_names[i]; |
559 | 551 | ||
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index e98bc7038a08..d09fdce57f5a 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c | |||
@@ -304,53 +304,53 @@ static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1); | |||
304 | 304 | ||
305 | static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" }; | 305 | static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" }; |
306 | 306 | ||
307 | static const struct soc_enum mic_bias_level = | 307 | static SOC_ENUM_SINGLE_DECL(mic_bias_level, |
308 | SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt); | 308 | WM8900_REG_INCTL, 8, mic_bias_level_txt); |
309 | 309 | ||
310 | static const char *dac_mute_rate_txt[] = { "Fast", "Slow" }; | 310 | static const char *dac_mute_rate_txt[] = { "Fast", "Slow" }; |
311 | 311 | ||
312 | static const struct soc_enum dac_mute_rate = | 312 | static SOC_ENUM_SINGLE_DECL(dac_mute_rate, |
313 | SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 7, 2, dac_mute_rate_txt); | 313 | WM8900_REG_DACCTRL, 7, dac_mute_rate_txt); |
314 | 314 | ||
315 | static const char *dac_deemphasis_txt[] = { | 315 | static const char *dac_deemphasis_txt[] = { |
316 | "Disabled", "32kHz", "44.1kHz", "48kHz" | 316 | "Disabled", "32kHz", "44.1kHz", "48kHz" |
317 | }; | 317 | }; |
318 | 318 | ||
319 | static const struct soc_enum dac_deemphasis = | 319 | static SOC_ENUM_SINGLE_DECL(dac_deemphasis, |
320 | SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 4, 4, dac_deemphasis_txt); | 320 | WM8900_REG_DACCTRL, 4, dac_deemphasis_txt); |
321 | 321 | ||
322 | static const char *adc_hpf_cut_txt[] = { | 322 | static const char *adc_hpf_cut_txt[] = { |
323 | "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3" | 323 | "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3" |
324 | }; | 324 | }; |
325 | 325 | ||
326 | static const struct soc_enum adc_hpf_cut = | 326 | static SOC_ENUM_SINGLE_DECL(adc_hpf_cut, |
327 | SOC_ENUM_SINGLE(WM8900_REG_ADCCTRL, 5, 4, adc_hpf_cut_txt); | 327 | WM8900_REG_ADCCTRL, 5, adc_hpf_cut_txt); |
328 | 328 | ||
329 | static const char *lr_txt[] = { | 329 | static const char *lr_txt[] = { |
330 | "Left", "Right" | 330 | "Left", "Right" |
331 | }; | 331 | }; |
332 | 332 | ||
333 | static const struct soc_enum aifl_src = | 333 | static SOC_ENUM_SINGLE_DECL(aifl_src, |
334 | SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 15, 2, lr_txt); | 334 | WM8900_REG_AUDIO1, 15, lr_txt); |
335 | 335 | ||
336 | static const struct soc_enum aifr_src = | 336 | static SOC_ENUM_SINGLE_DECL(aifr_src, |
337 | SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 14, 2, lr_txt); | 337 | WM8900_REG_AUDIO1, 14, lr_txt); |
338 | 338 | ||
339 | static const struct soc_enum dacl_src = | 339 | static SOC_ENUM_SINGLE_DECL(dacl_src, |
340 | SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 15, 2, lr_txt); | 340 | WM8900_REG_AUDIO2, 15, lr_txt); |
341 | 341 | ||
342 | static const struct soc_enum dacr_src = | 342 | static SOC_ENUM_SINGLE_DECL(dacr_src, |
343 | SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 14, 2, lr_txt); | 343 | WM8900_REG_AUDIO2, 14, lr_txt); |
344 | 344 | ||
345 | static const char *sidetone_txt[] = { | 345 | static const char *sidetone_txt[] = { |
346 | "Disabled", "Left ADC", "Right ADC" | 346 | "Disabled", "Left ADC", "Right ADC" |
347 | }; | 347 | }; |
348 | 348 | ||
349 | static const struct soc_enum dacl_sidetone = | 349 | static SOC_ENUM_SINGLE_DECL(dacl_sidetone, |
350 | SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 2, 3, sidetone_txt); | 350 | WM8900_REG_SIDETONE, 2, sidetone_txt); |
351 | 351 | ||
352 | static const struct soc_enum dacr_sidetone = | 352 | static SOC_ENUM_SINGLE_DECL(dacr_sidetone, |
353 | SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 0, 3, sidetone_txt); | 353 | WM8900_REG_SIDETONE, 0, sidetone_txt); |
354 | 354 | ||
355 | static const struct snd_kcontrol_new wm8900_snd_controls[] = { | 355 | static const struct snd_kcontrol_new wm8900_snd_controls[] = { |
356 | SOC_ENUM("Mic Bias Level", mic_bias_level), | 356 | SOC_ENUM("Mic Bias Level", mic_bias_level), |
@@ -496,8 +496,8 @@ SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0), | |||
496 | 496 | ||
497 | static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" }; | 497 | static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" }; |
498 | 498 | ||
499 | static const struct soc_enum wm8900_lineout2_lp_mux = | 499 | static SOC_ENUM_SINGLE_DECL(wm8900_lineout2_lp_mux, |
500 | SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm8900_lp_mux); | 500 | WM8900_REG_LOUTMIXCTL1, 1, wm8900_lp_mux); |
501 | 501 | ||
502 | static const struct snd_kcontrol_new wm8900_lineout2_lp = | 502 | static const struct snd_kcontrol_new wm8900_lineout2_lp = |
503 | SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux); | 503 | SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux); |
@@ -1178,13 +1178,7 @@ static int wm8900_resume(struct snd_soc_codec *codec) | |||
1178 | 1178 | ||
1179 | static int wm8900_probe(struct snd_soc_codec *codec) | 1179 | static int wm8900_probe(struct snd_soc_codec *codec) |
1180 | { | 1180 | { |
1181 | int ret = 0, reg; | 1181 | int reg; |
1182 | |||
1183 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1184 | if (ret != 0) { | ||
1185 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1186 | return ret; | ||
1187 | } | ||
1188 | 1182 | ||
1189 | reg = snd_soc_read(codec, WM8900_REG_ID); | 1183 | reg = snd_soc_read(codec, WM8900_REG_ID); |
1190 | if (reg != 0x8900) { | 1184 | if (reg != 0x8900) { |
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index eebcb1da3b7b..b0084a127d18 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -489,28 +489,28 @@ static const char *hpf_mode_text[] = { | |||
489 | "Hi-fi", "Voice 1", "Voice 2", "Voice 3" | 489 | "Hi-fi", "Voice 1", "Voice 2", "Voice 3" |
490 | }; | 490 | }; |
491 | 491 | ||
492 | static const struct soc_enum hpf_mode = | 492 | static SOC_ENUM_SINGLE_DECL(hpf_mode, |
493 | SOC_ENUM_SINGLE(WM8903_ADC_DIGITAL_0, 5, 4, hpf_mode_text); | 493 | WM8903_ADC_DIGITAL_0, 5, hpf_mode_text); |
494 | 494 | ||
495 | static const char *osr_text[] = { | 495 | static const char *osr_text[] = { |
496 | "Low power", "High performance" | 496 | "Low power", "High performance" |
497 | }; | 497 | }; |
498 | 498 | ||
499 | static const struct soc_enum adc_osr = | 499 | static SOC_ENUM_SINGLE_DECL(adc_osr, |
500 | SOC_ENUM_SINGLE(WM8903_ANALOGUE_ADC_0, 0, 2, osr_text); | 500 | WM8903_ANALOGUE_ADC_0, 0, osr_text); |
501 | 501 | ||
502 | static const struct soc_enum dac_osr = | 502 | static SOC_ENUM_SINGLE_DECL(dac_osr, |
503 | SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 0, 2, osr_text); | 503 | WM8903_DAC_DIGITAL_1, 0, osr_text); |
504 | 504 | ||
505 | static const char *drc_slope_text[] = { | 505 | static const char *drc_slope_text[] = { |
506 | "1", "1/2", "1/4", "1/8", "1/16", "0" | 506 | "1", "1/2", "1/4", "1/8", "1/16", "0" |
507 | }; | 507 | }; |
508 | 508 | ||
509 | static const struct soc_enum drc_slope_r0 = | 509 | static SOC_ENUM_SINGLE_DECL(drc_slope_r0, |
510 | SOC_ENUM_SINGLE(WM8903_DRC_2, 3, 6, drc_slope_text); | 510 | WM8903_DRC_2, 3, drc_slope_text); |
511 | 511 | ||
512 | static const struct soc_enum drc_slope_r1 = | 512 | static SOC_ENUM_SINGLE_DECL(drc_slope_r1, |
513 | SOC_ENUM_SINGLE(WM8903_DRC_2, 0, 6, drc_slope_text); | 513 | WM8903_DRC_2, 0, drc_slope_text); |
514 | 514 | ||
515 | static const char *drc_attack_text[] = { | 515 | static const char *drc_attack_text[] = { |
516 | "instantaneous", | 516 | "instantaneous", |
@@ -518,125 +518,125 @@ static const char *drc_attack_text[] = { | |||
518 | "46.4ms", "92.8ms", "185.6ms" | 518 | "46.4ms", "92.8ms", "185.6ms" |
519 | }; | 519 | }; |
520 | 520 | ||
521 | static const struct soc_enum drc_attack = | 521 | static SOC_ENUM_SINGLE_DECL(drc_attack, |
522 | SOC_ENUM_SINGLE(WM8903_DRC_1, 12, 11, drc_attack_text); | 522 | WM8903_DRC_1, 12, drc_attack_text); |
523 | 523 | ||
524 | static const char *drc_decay_text[] = { | 524 | static const char *drc_decay_text[] = { |
525 | "186ms", "372ms", "743ms", "1.49s", "2.97s", "5.94s", "11.89s", | 525 | "186ms", "372ms", "743ms", "1.49s", "2.97s", "5.94s", "11.89s", |
526 | "23.87s", "47.56s" | 526 | "23.87s", "47.56s" |
527 | }; | 527 | }; |
528 | 528 | ||
529 | static const struct soc_enum drc_decay = | 529 | static SOC_ENUM_SINGLE_DECL(drc_decay, |
530 | SOC_ENUM_SINGLE(WM8903_DRC_1, 8, 9, drc_decay_text); | 530 | WM8903_DRC_1, 8, drc_decay_text); |
531 | 531 | ||
532 | static const char *drc_ff_delay_text[] = { | 532 | static const char *drc_ff_delay_text[] = { |
533 | "5 samples", "9 samples" | 533 | "5 samples", "9 samples" |
534 | }; | 534 | }; |
535 | 535 | ||
536 | static const struct soc_enum drc_ff_delay = | 536 | static SOC_ENUM_SINGLE_DECL(drc_ff_delay, |
537 | SOC_ENUM_SINGLE(WM8903_DRC_0, 5, 2, drc_ff_delay_text); | 537 | WM8903_DRC_0, 5, drc_ff_delay_text); |
538 | 538 | ||
539 | static const char *drc_qr_decay_text[] = { | 539 | static const char *drc_qr_decay_text[] = { |
540 | "0.725ms", "1.45ms", "5.8ms" | 540 | "0.725ms", "1.45ms", "5.8ms" |
541 | }; | 541 | }; |
542 | 542 | ||
543 | static const struct soc_enum drc_qr_decay = | 543 | static SOC_ENUM_SINGLE_DECL(drc_qr_decay, |
544 | SOC_ENUM_SINGLE(WM8903_DRC_1, 4, 3, drc_qr_decay_text); | 544 | WM8903_DRC_1, 4, drc_qr_decay_text); |
545 | 545 | ||
546 | static const char *drc_smoothing_text[] = { | 546 | static const char *drc_smoothing_text[] = { |
547 | "Low", "Medium", "High" | 547 | "Low", "Medium", "High" |
548 | }; | 548 | }; |
549 | 549 | ||
550 | static const struct soc_enum drc_smoothing = | 550 | static SOC_ENUM_SINGLE_DECL(drc_smoothing, |
551 | SOC_ENUM_SINGLE(WM8903_DRC_0, 11, 3, drc_smoothing_text); | 551 | WM8903_DRC_0, 11, drc_smoothing_text); |
552 | 552 | ||
553 | static const char *soft_mute_text[] = { | 553 | static const char *soft_mute_text[] = { |
554 | "Fast (fs/2)", "Slow (fs/32)" | 554 | "Fast (fs/2)", "Slow (fs/32)" |
555 | }; | 555 | }; |
556 | 556 | ||
557 | static const struct soc_enum soft_mute = | 557 | static SOC_ENUM_SINGLE_DECL(soft_mute, |
558 | SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 10, 2, soft_mute_text); | 558 | WM8903_DAC_DIGITAL_1, 10, soft_mute_text); |
559 | 559 | ||
560 | static const char *mute_mode_text[] = { | 560 | static const char *mute_mode_text[] = { |
561 | "Hard", "Soft" | 561 | "Hard", "Soft" |
562 | }; | 562 | }; |
563 | 563 | ||
564 | static const struct soc_enum mute_mode = | 564 | static SOC_ENUM_SINGLE_DECL(mute_mode, |
565 | SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text); | 565 | WM8903_DAC_DIGITAL_1, 9, mute_mode_text); |
566 | 566 | ||
567 | static const char *companding_text[] = { | 567 | static const char *companding_text[] = { |
568 | "ulaw", "alaw" | 568 | "ulaw", "alaw" |
569 | }; | 569 | }; |
570 | 570 | ||
571 | static const struct soc_enum dac_companding = | 571 | static SOC_ENUM_SINGLE_DECL(dac_companding, |
572 | SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 0, 2, companding_text); | 572 | WM8903_AUDIO_INTERFACE_0, 0, companding_text); |
573 | 573 | ||
574 | static const struct soc_enum adc_companding = | 574 | static SOC_ENUM_SINGLE_DECL(adc_companding, |
575 | SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 2, 2, companding_text); | 575 | WM8903_AUDIO_INTERFACE_0, 2, companding_text); |
576 | 576 | ||
577 | static const char *input_mode_text[] = { | 577 | static const char *input_mode_text[] = { |
578 | "Single-Ended", "Differential Line", "Differential Mic" | 578 | "Single-Ended", "Differential Line", "Differential Mic" |
579 | }; | 579 | }; |
580 | 580 | ||
581 | static const struct soc_enum linput_mode_enum = | 581 | static SOC_ENUM_SINGLE_DECL(linput_mode_enum, |
582 | SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text); | 582 | WM8903_ANALOGUE_LEFT_INPUT_1, 0, input_mode_text); |
583 | 583 | ||
584 | static const struct soc_enum rinput_mode_enum = | 584 | static SOC_ENUM_SINGLE_DECL(rinput_mode_enum, |
585 | SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text); | 585 | WM8903_ANALOGUE_RIGHT_INPUT_1, 0, input_mode_text); |
586 | 586 | ||
587 | static const char *linput_mux_text[] = { | 587 | static const char *linput_mux_text[] = { |
588 | "IN1L", "IN2L", "IN3L" | 588 | "IN1L", "IN2L", "IN3L" |
589 | }; | 589 | }; |
590 | 590 | ||
591 | static const struct soc_enum linput_enum = | 591 | static SOC_ENUM_SINGLE_DECL(linput_enum, |
592 | SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 2, 3, linput_mux_text); | 592 | WM8903_ANALOGUE_LEFT_INPUT_1, 2, linput_mux_text); |
593 | 593 | ||
594 | static const struct soc_enum linput_inv_enum = | 594 | static SOC_ENUM_SINGLE_DECL(linput_inv_enum, |
595 | SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 4, 3, linput_mux_text); | 595 | WM8903_ANALOGUE_LEFT_INPUT_1, 4, linput_mux_text); |
596 | 596 | ||
597 | static const char *rinput_mux_text[] = { | 597 | static const char *rinput_mux_text[] = { |
598 | "IN1R", "IN2R", "IN3R" | 598 | "IN1R", "IN2R", "IN3R" |
599 | }; | 599 | }; |
600 | 600 | ||
601 | static const struct soc_enum rinput_enum = | 601 | static SOC_ENUM_SINGLE_DECL(rinput_enum, |
602 | SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 2, 3, rinput_mux_text); | 602 | WM8903_ANALOGUE_RIGHT_INPUT_1, 2, rinput_mux_text); |
603 | 603 | ||
604 | static const struct soc_enum rinput_inv_enum = | 604 | static SOC_ENUM_SINGLE_DECL(rinput_inv_enum, |
605 | SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 4, 3, rinput_mux_text); | 605 | WM8903_ANALOGUE_RIGHT_INPUT_1, 4, rinput_mux_text); |
606 | 606 | ||
607 | 607 | ||
608 | static const char *sidetone_text[] = { | 608 | static const char *sidetone_text[] = { |
609 | "None", "Left", "Right" | 609 | "None", "Left", "Right" |
610 | }; | 610 | }; |
611 | 611 | ||
612 | static const struct soc_enum lsidetone_enum = | 612 | static SOC_ENUM_SINGLE_DECL(lsidetone_enum, |
613 | SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 2, 3, sidetone_text); | 613 | WM8903_DAC_DIGITAL_0, 2, sidetone_text); |
614 | 614 | ||
615 | static const struct soc_enum rsidetone_enum = | 615 | static SOC_ENUM_SINGLE_DECL(rsidetone_enum, |
616 | SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); | 616 | WM8903_DAC_DIGITAL_0, 0, sidetone_text); |
617 | 617 | ||
618 | static const char *adcinput_text[] = { | 618 | static const char *adcinput_text[] = { |
619 | "ADC", "DMIC" | 619 | "ADC", "DMIC" |
620 | }; | 620 | }; |
621 | 621 | ||
622 | static const struct soc_enum adcinput_enum = | 622 | static SOC_ENUM_SINGLE_DECL(adcinput_enum, |
623 | SOC_ENUM_SINGLE(WM8903_CLOCK_RATE_TEST_4, 9, 2, adcinput_text); | 623 | WM8903_CLOCK_RATE_TEST_4, 9, adcinput_text); |
624 | 624 | ||
625 | static const char *aif_text[] = { | 625 | static const char *aif_text[] = { |
626 | "Left", "Right" | 626 | "Left", "Right" |
627 | }; | 627 | }; |
628 | 628 | ||
629 | static const struct soc_enum lcapture_enum = | 629 | static SOC_ENUM_SINGLE_DECL(lcapture_enum, |
630 | SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 7, 2, aif_text); | 630 | WM8903_AUDIO_INTERFACE_0, 7, aif_text); |
631 | 631 | ||
632 | static const struct soc_enum rcapture_enum = | 632 | static SOC_ENUM_SINGLE_DECL(rcapture_enum, |
633 | SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 6, 2, aif_text); | 633 | WM8903_AUDIO_INTERFACE_0, 6, aif_text); |
634 | 634 | ||
635 | static const struct soc_enum lplay_enum = | 635 | static SOC_ENUM_SINGLE_DECL(lplay_enum, |
636 | SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 5, 2, aif_text); | 636 | WM8903_AUDIO_INTERFACE_0, 5, aif_text); |
637 | 637 | ||
638 | static const struct soc_enum rplay_enum = | 638 | static SOC_ENUM_SINGLE_DECL(rplay_enum, |
639 | SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 4, 2, aif_text); | 639 | WM8903_AUDIO_INTERFACE_0, 4, aif_text); |
640 | 640 | ||
641 | static const struct snd_kcontrol_new wm8903_snd_controls[] = { | 641 | static const struct snd_kcontrol_new wm8903_snd_controls[] = { |
642 | 642 | ||
@@ -1897,21 +1897,13 @@ static void wm8903_free_gpio(struct wm8903_priv *wm8903) | |||
1897 | static int wm8903_probe(struct snd_soc_codec *codec) | 1897 | static int wm8903_probe(struct snd_soc_codec *codec) |
1898 | { | 1898 | { |
1899 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 1899 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
1900 | int ret; | ||
1901 | 1900 | ||
1902 | wm8903->codec = codec; | 1901 | wm8903->codec = codec; |
1903 | codec->control_data = wm8903->regmap; | ||
1904 | |||
1905 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1906 | if (ret != 0) { | ||
1907 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1908 | return ret; | ||
1909 | } | ||
1910 | 1902 | ||
1911 | /* power on device */ | 1903 | /* power on device */ |
1912 | wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1904 | wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1913 | 1905 | ||
1914 | return ret; | 1906 | return 0; |
1915 | } | 1907 | } |
1916 | 1908 | ||
1917 | /* power down chip */ | 1909 | /* power down chip */ |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 53bbfac6a83a..49c35c36935e 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
@@ -552,18 +552,20 @@ static const char *input_mode_text[] = { | |||
552 | "Single-Ended", "Differential Line", "Differential Mic" | 552 | "Single-Ended", "Differential Line", "Differential Mic" |
553 | }; | 553 | }; |
554 | 554 | ||
555 | static const struct soc_enum lin_mode = | 555 | static SOC_ENUM_SINGLE_DECL(lin_mode, |
556 | SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text); | 556 | WM8904_ANALOGUE_LEFT_INPUT_1, 0, |
557 | input_mode_text); | ||
557 | 558 | ||
558 | static const struct soc_enum rin_mode = | 559 | static SOC_ENUM_SINGLE_DECL(rin_mode, |
559 | SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text); | 560 | WM8904_ANALOGUE_RIGHT_INPUT_1, 0, |
561 | input_mode_text); | ||
560 | 562 | ||
561 | static const char *hpf_mode_text[] = { | 563 | static const char *hpf_mode_text[] = { |
562 | "Hi-fi", "Voice 1", "Voice 2", "Voice 3" | 564 | "Hi-fi", "Voice 1", "Voice 2", "Voice 3" |
563 | }; | 565 | }; |
564 | 566 | ||
565 | static const struct soc_enum hpf_mode = | 567 | static SOC_ENUM_SINGLE_DECL(hpf_mode, WM8904_ADC_DIGITAL_0, 5, |
566 | SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text); | 568 | hpf_mode_text); |
567 | 569 | ||
568 | static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol, | 570 | static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol, |
569 | struct snd_ctl_elem_value *ucontrol) | 571 | struct snd_ctl_elem_value *ucontrol) |
@@ -611,8 +613,7 @@ static const char *drc_path_text[] = { | |||
611 | "ADC", "DAC" | 613 | "ADC", "DAC" |
612 | }; | 614 | }; |
613 | 615 | ||
614 | static const struct soc_enum drc_path = | 616 | static SOC_ENUM_SINGLE_DECL(drc_path, WM8904_DRC_0, 14, drc_path_text); |
615 | SOC_ENUM_SINGLE(WM8904_DRC_0, 14, 2, drc_path_text); | ||
616 | 617 | ||
617 | static const struct snd_kcontrol_new wm8904_dac_snd_controls[] = { | 618 | static const struct snd_kcontrol_new wm8904_dac_snd_controls[] = { |
618 | SOC_SINGLE_TLV("Digital Playback Boost Volume", | 619 | SOC_SINGLE_TLV("Digital Playback Boost Volume", |
@@ -858,14 +859,14 @@ static const char *lin_text[] = { | |||
858 | "IN1L", "IN2L", "IN3L" | 859 | "IN1L", "IN2L", "IN3L" |
859 | }; | 860 | }; |
860 | 861 | ||
861 | static const struct soc_enum lin_enum = | 862 | static SOC_ENUM_SINGLE_DECL(lin_enum, WM8904_ANALOGUE_LEFT_INPUT_1, 2, |
862 | SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 2, 3, lin_text); | 863 | lin_text); |
863 | 864 | ||
864 | static const struct snd_kcontrol_new lin_mux = | 865 | static const struct snd_kcontrol_new lin_mux = |
865 | SOC_DAPM_ENUM("Left Capture Mux", lin_enum); | 866 | SOC_DAPM_ENUM("Left Capture Mux", lin_enum); |
866 | 867 | ||
867 | static const struct soc_enum lin_inv_enum = | 868 | static SOC_ENUM_SINGLE_DECL(lin_inv_enum, WM8904_ANALOGUE_LEFT_INPUT_1, 4, |
868 | SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 4, 3, lin_text); | 869 | lin_text); |
869 | 870 | ||
870 | static const struct snd_kcontrol_new lin_inv_mux = | 871 | static const struct snd_kcontrol_new lin_inv_mux = |
871 | SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum); | 872 | SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum); |
@@ -874,14 +875,14 @@ static const char *rin_text[] = { | |||
874 | "IN1R", "IN2R", "IN3R" | 875 | "IN1R", "IN2R", "IN3R" |
875 | }; | 876 | }; |
876 | 877 | ||
877 | static const struct soc_enum rin_enum = | 878 | static SOC_ENUM_SINGLE_DECL(rin_enum, WM8904_ANALOGUE_RIGHT_INPUT_1, 2, |
878 | SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 2, 3, rin_text); | 879 | rin_text); |
879 | 880 | ||
880 | static const struct snd_kcontrol_new rin_mux = | 881 | static const struct snd_kcontrol_new rin_mux = |
881 | SOC_DAPM_ENUM("Right Capture Mux", rin_enum); | 882 | SOC_DAPM_ENUM("Right Capture Mux", rin_enum); |
882 | 883 | ||
883 | static const struct soc_enum rin_inv_enum = | 884 | static SOC_ENUM_SINGLE_DECL(rin_inv_enum, WM8904_ANALOGUE_RIGHT_INPUT_1, 4, |
884 | SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 4, 3, rin_text); | 885 | rin_text); |
885 | 886 | ||
886 | static const struct snd_kcontrol_new rin_inv_mux = | 887 | static const struct snd_kcontrol_new rin_inv_mux = |
887 | SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum); | 888 | SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum); |
@@ -890,26 +891,26 @@ static const char *aif_text[] = { | |||
890 | "Left", "Right" | 891 | "Left", "Right" |
891 | }; | 892 | }; |
892 | 893 | ||
893 | static const struct soc_enum aifoutl_enum = | 894 | static SOC_ENUM_SINGLE_DECL(aifoutl_enum, WM8904_AUDIO_INTERFACE_0, 7, |
894 | SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 7, 2, aif_text); | 895 | aif_text); |
895 | 896 | ||
896 | static const struct snd_kcontrol_new aifoutl_mux = | 897 | static const struct snd_kcontrol_new aifoutl_mux = |
897 | SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum); | 898 | SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum); |
898 | 899 | ||
899 | static const struct soc_enum aifoutr_enum = | 900 | static SOC_ENUM_SINGLE_DECL(aifoutr_enum, WM8904_AUDIO_INTERFACE_0, 6, |
900 | SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 6, 2, aif_text); | 901 | aif_text); |
901 | 902 | ||
902 | static const struct snd_kcontrol_new aifoutr_mux = | 903 | static const struct snd_kcontrol_new aifoutr_mux = |
903 | SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum); | 904 | SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum); |
904 | 905 | ||
905 | static const struct soc_enum aifinl_enum = | 906 | static SOC_ENUM_SINGLE_DECL(aifinl_enum, WM8904_AUDIO_INTERFACE_0, 5, |
906 | SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 5, 2, aif_text); | 907 | aif_text); |
907 | 908 | ||
908 | static const struct snd_kcontrol_new aifinl_mux = | 909 | static const struct snd_kcontrol_new aifinl_mux = |
909 | SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum); | 910 | SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum); |
910 | 911 | ||
911 | static const struct soc_enum aifinr_enum = | 912 | static SOC_ENUM_SINGLE_DECL(aifinr_enum, WM8904_AUDIO_INTERFACE_0, 4, |
912 | SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 4, 2, aif_text); | 913 | aif_text); |
913 | 914 | ||
914 | static const struct snd_kcontrol_new aifinr_mux = | 915 | static const struct snd_kcontrol_new aifinr_mux = |
915 | SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum); | 916 | SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum); |
@@ -991,26 +992,26 @@ static const char *out_mux_text[] = { | |||
991 | "DAC", "Bypass" | 992 | "DAC", "Bypass" |
992 | }; | 993 | }; |
993 | 994 | ||
994 | static const struct soc_enum hpl_enum = | 995 | static SOC_ENUM_SINGLE_DECL(hpl_enum, WM8904_ANALOGUE_OUT12_ZC, 3, |
995 | SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 3, 2, out_mux_text); | 996 | out_mux_text); |
996 | 997 | ||
997 | static const struct snd_kcontrol_new hpl_mux = | 998 | static const struct snd_kcontrol_new hpl_mux = |
998 | SOC_DAPM_ENUM("HPL Mux", hpl_enum); | 999 | SOC_DAPM_ENUM("HPL Mux", hpl_enum); |
999 | 1000 | ||
1000 | static const struct soc_enum hpr_enum = | 1001 | static SOC_ENUM_SINGLE_DECL(hpr_enum, WM8904_ANALOGUE_OUT12_ZC, 2, |
1001 | SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 2, 2, out_mux_text); | 1002 | out_mux_text); |
1002 | 1003 | ||
1003 | static const struct snd_kcontrol_new hpr_mux = | 1004 | static const struct snd_kcontrol_new hpr_mux = |
1004 | SOC_DAPM_ENUM("HPR Mux", hpr_enum); | 1005 | SOC_DAPM_ENUM("HPR Mux", hpr_enum); |
1005 | 1006 | ||
1006 | static const struct soc_enum linel_enum = | 1007 | static SOC_ENUM_SINGLE_DECL(linel_enum, WM8904_ANALOGUE_OUT12_ZC, 1, |
1007 | SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 1, 2, out_mux_text); | 1008 | out_mux_text); |
1008 | 1009 | ||
1009 | static const struct snd_kcontrol_new linel_mux = | 1010 | static const struct snd_kcontrol_new linel_mux = |
1010 | SOC_DAPM_ENUM("LINEL Mux", linel_enum); | 1011 | SOC_DAPM_ENUM("LINEL Mux", linel_enum); |
1011 | 1012 | ||
1012 | static const struct soc_enum liner_enum = | 1013 | static SOC_ENUM_SINGLE_DECL(liner_enum, WM8904_ANALOGUE_OUT12_ZC, 0, |
1013 | SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 0, 2, out_mux_text); | 1014 | out_mux_text); |
1014 | 1015 | ||
1015 | static const struct snd_kcontrol_new liner_mux = | 1016 | static const struct snd_kcontrol_new liner_mux = |
1016 | SOC_DAPM_ENUM("LINER Mux", liner_enum); | 1017 | SOC_DAPM_ENUM("LINER Mux", liner_enum); |
@@ -1019,14 +1020,14 @@ static const char *sidetone_text[] = { | |||
1019 | "None", "Left", "Right" | 1020 | "None", "Left", "Right" |
1020 | }; | 1021 | }; |
1021 | 1022 | ||
1022 | static const struct soc_enum dacl_sidetone_enum = | 1023 | static SOC_ENUM_SINGLE_DECL(dacl_sidetone_enum, WM8904_DAC_DIGITAL_0, 2, |
1023 | SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 2, 3, sidetone_text); | 1024 | sidetone_text); |
1024 | 1025 | ||
1025 | static const struct snd_kcontrol_new dacl_sidetone_mux = | 1026 | static const struct snd_kcontrol_new dacl_sidetone_mux = |
1026 | SOC_DAPM_ENUM("Left Sidetone Mux", dacl_sidetone_enum); | 1027 | SOC_DAPM_ENUM("Left Sidetone Mux", dacl_sidetone_enum); |
1027 | 1028 | ||
1028 | static const struct soc_enum dacr_sidetone_enum = | 1029 | static SOC_ENUM_SINGLE_DECL(dacr_sidetone_enum, WM8904_DAC_DIGITAL_0, 0, |
1029 | SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 0, 3, sidetone_text); | 1030 | sidetone_text); |
1030 | 1031 | ||
1031 | static const struct snd_kcontrol_new dacr_sidetone_mux = | 1032 | static const struct snd_kcontrol_new dacr_sidetone_mux = |
1032 | SOC_DAPM_ENUM("Right Sidetone Mux", dacr_sidetone_enum); | 1033 | SOC_DAPM_ENUM("Right Sidetone Mux", dacr_sidetone_enum); |
@@ -1981,7 +1982,7 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec) | |||
1981 | dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", | 1982 | dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", |
1982 | wm8904->num_retune_mobile_texts); | 1983 | wm8904->num_retune_mobile_texts); |
1983 | 1984 | ||
1984 | wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; | 1985 | wm8904->retune_mobile_enum.items = wm8904->num_retune_mobile_texts; |
1985 | wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; | 1986 | wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; |
1986 | 1987 | ||
1987 | ret = snd_soc_add_codec_controls(codec, &control, 1); | 1988 | ret = snd_soc_add_codec_controls(codec, &control, 1); |
@@ -2022,7 +2023,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec) | |||
2022 | for (i = 0; i < pdata->num_drc_cfgs; i++) | 2023 | for (i = 0; i < pdata->num_drc_cfgs; i++) |
2023 | wm8904->drc_texts[i] = pdata->drc_cfgs[i].name; | 2024 | wm8904->drc_texts[i] = pdata->drc_cfgs[i].name; |
2024 | 2025 | ||
2025 | wm8904->drc_enum.max = pdata->num_drc_cfgs; | 2026 | wm8904->drc_enum.items = pdata->num_drc_cfgs; |
2026 | wm8904->drc_enum.texts = wm8904->drc_texts; | 2027 | wm8904->drc_enum.texts = wm8904->drc_texts; |
2027 | 2028 | ||
2028 | ret = snd_soc_add_codec_controls(codec, &control, 1); | 2029 | ret = snd_soc_add_codec_controls(codec, &control, 1); |
@@ -2047,9 +2048,6 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec) | |||
2047 | static int wm8904_probe(struct snd_soc_codec *codec) | 2048 | static int wm8904_probe(struct snd_soc_codec *codec) |
2048 | { | 2049 | { |
2049 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 2050 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
2050 | int ret; | ||
2051 | |||
2052 | codec->control_data = wm8904->regmap; | ||
2053 | 2051 | ||
2054 | switch (wm8904->devtype) { | 2052 | switch (wm8904->devtype) { |
2055 | case WM8904: | 2053 | case WM8904: |
@@ -2063,12 +2061,6 @@ static int wm8904_probe(struct snd_soc_codec *codec) | |||
2063 | return -EINVAL; | 2061 | return -EINVAL; |
2064 | } | 2062 | } |
2065 | 2063 | ||
2066 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
2067 | if (ret != 0) { | ||
2068 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
2069 | return ret; | ||
2070 | } | ||
2071 | |||
2072 | wm8904_handle_pdata(codec); | 2064 | wm8904_handle_pdata(codec); |
2073 | 2065 | ||
2074 | wm8904_add_widgets(codec); | 2066 | wm8904_add_widgets(codec); |
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index b404c26c1753..fc6eec9ad66b 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c | |||
@@ -154,22 +154,22 @@ static const struct reg_default wm8940_reg_defaults[] = { | |||
154 | }; | 154 | }; |
155 | 155 | ||
156 | static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" }; | 156 | static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" }; |
157 | static const struct soc_enum wm8940_adc_companding_enum | 157 | static SOC_ENUM_SINGLE_DECL(wm8940_adc_companding_enum, |
158 | = SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 1, 4, wm8940_companding); | 158 | WM8940_COMPANDINGCTL, 1, wm8940_companding); |
159 | static const struct soc_enum wm8940_dac_companding_enum | 159 | static SOC_ENUM_SINGLE_DECL(wm8940_dac_companding_enum, |
160 | = SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 3, 4, wm8940_companding); | 160 | WM8940_COMPANDINGCTL, 3, wm8940_companding); |
161 | 161 | ||
162 | static const char *wm8940_alc_mode_text[] = {"ALC", "Limiter"}; | 162 | static const char *wm8940_alc_mode_text[] = {"ALC", "Limiter"}; |
163 | static const struct soc_enum wm8940_alc_mode_enum | 163 | static SOC_ENUM_SINGLE_DECL(wm8940_alc_mode_enum, |
164 | = SOC_ENUM_SINGLE(WM8940_ALC3, 8, 2, wm8940_alc_mode_text); | 164 | WM8940_ALC3, 8, wm8940_alc_mode_text); |
165 | 165 | ||
166 | static const char *wm8940_mic_bias_level_text[] = {"0.9", "0.65"}; | 166 | static const char *wm8940_mic_bias_level_text[] = {"0.9", "0.65"}; |
167 | static const struct soc_enum wm8940_mic_bias_level_enum | 167 | static SOC_ENUM_SINGLE_DECL(wm8940_mic_bias_level_enum, |
168 | = SOC_ENUM_SINGLE(WM8940_INPUTCTL, 8, 2, wm8940_mic_bias_level_text); | 168 | WM8940_INPUTCTL, 8, wm8940_mic_bias_level_text); |
169 | 169 | ||
170 | static const char *wm8940_filter_mode_text[] = {"Audio", "Application"}; | 170 | static const char *wm8940_filter_mode_text[] = {"Audio", "Application"}; |
171 | static const struct soc_enum wm8940_filter_mode_enum | 171 | static SOC_ENUM_SINGLE_DECL(wm8940_filter_mode_enum, |
172 | = SOC_ENUM_SINGLE(WM8940_ADC, 7, 2, wm8940_filter_mode_text); | 172 | WM8940_ADC, 7, wm8940_filter_mode_text); |
173 | 173 | ||
174 | static DECLARE_TLV_DB_SCALE(wm8940_spk_vol_tlv, -5700, 100, 1); | 174 | static DECLARE_TLV_DB_SCALE(wm8940_spk_vol_tlv, -5700, 100, 1); |
175 | static DECLARE_TLV_DB_SCALE(wm8940_att_tlv, -1000, 1000, 0); | 175 | static DECLARE_TLV_DB_SCALE(wm8940_att_tlv, -1000, 1000, 0); |
@@ -712,12 +712,6 @@ static int wm8940_probe(struct snd_soc_codec *codec) | |||
712 | int ret; | 712 | int ret; |
713 | u16 reg; | 713 | u16 reg; |
714 | 714 | ||
715 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
716 | if (ret < 0) { | ||
717 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
718 | return ret; | ||
719 | } | ||
720 | |||
721 | ret = wm8940_reset(codec); | 715 | ret = wm8940_reset(codec); |
722 | if (ret < 0) { | 716 | if (ret < 0) { |
723 | dev_err(codec->dev, "Failed to issue reset\n"); | 717 | dev_err(codec->dev, "Failed to issue reset\n"); |
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 82c8ba975720..fecd4e4f4c57 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c | |||
@@ -416,22 +416,21 @@ static const char *bass_mode_text[] = { | |||
416 | "Linear", "Adaptive", | 416 | "Linear", "Adaptive", |
417 | }; | 417 | }; |
418 | 418 | ||
419 | static const struct soc_enum bass_mode = | 419 | static SOC_ENUM_SINGLE_DECL(bass_mode, WM8955_BASS_CONTROL, 7, bass_mode_text); |
420 | SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 7, 2, bass_mode_text); | ||
421 | 420 | ||
422 | static const char *bass_cutoff_text[] = { | 421 | static const char *bass_cutoff_text[] = { |
423 | "Low", "High" | 422 | "Low", "High" |
424 | }; | 423 | }; |
425 | 424 | ||
426 | static const struct soc_enum bass_cutoff = | 425 | static SOC_ENUM_SINGLE_DECL(bass_cutoff, WM8955_BASS_CONTROL, 6, |
427 | SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 6, 2, bass_cutoff_text); | 426 | bass_cutoff_text); |
428 | 427 | ||
429 | static const char *treble_cutoff_text[] = { | 428 | static const char *treble_cutoff_text[] = { |
430 | "High", "Low" | 429 | "High", "Low" |
431 | }; | 430 | }; |
432 | 431 | ||
433 | static const struct soc_enum treble_cutoff = | 432 | static SOC_ENUM_SINGLE_DECL(treble_cutoff, WM8955_TREBLE_CONTROL, 2, |
434 | SOC_ENUM_SINGLE(WM8955_TREBLE_CONTROL, 6, 2, treble_cutoff_text); | 433 | treble_cutoff_text); |
435 | 434 | ||
436 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1); | 435 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1); |
437 | static const DECLARE_TLV_DB_SCALE(atten_tlv, -600, 600, 0); | 436 | static const DECLARE_TLV_DB_SCALE(atten_tlv, -600, 600, 0); |
@@ -896,14 +895,6 @@ static int wm8955_probe(struct snd_soc_codec *codec) | |||
896 | struct wm8955_pdata *pdata = dev_get_platdata(codec->dev); | 895 | struct wm8955_pdata *pdata = dev_get_platdata(codec->dev); |
897 | int ret, i; | 896 | int ret, i; |
898 | 897 | ||
899 | codec->control_data = wm8955->regmap; | ||
900 | |||
901 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
902 | if (ret != 0) { | ||
903 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
904 | return ret; | ||
905 | } | ||
906 | |||
907 | for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++) | 898 | for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++) |
908 | wm8955->supplies[i].supply = wm8955_supply_names[i]; | 899 | wm8955->supplies[i].supply = wm8955_supply_names[i]; |
909 | 900 | ||
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index b7488f190d2b..7ac2e511403c 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c | |||
@@ -153,7 +153,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, | |||
153 | 153 | ||
154 | data32 &= 0xffffff; | 154 | data32 &= 0xffffff; |
155 | 155 | ||
156 | wm8994_bulk_write(codec->control_data, | 156 | wm8994_bulk_write(wm8994->wm8994, |
157 | data32 & 0xffffff, | 157 | data32 & 0xffffff, |
158 | block_len / 2, | 158 | block_len / 2, |
159 | (void *)(data + 8)); | 159 | (void *)(data + 8)); |
@@ -944,7 +944,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
944 | for (i = 0; i < pdata->num_mbc_cfgs; i++) | 944 | for (i = 0; i < pdata->num_mbc_cfgs; i++) |
945 | wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name; | 945 | wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name; |
946 | 946 | ||
947 | wm8994->mbc_enum.max = pdata->num_mbc_cfgs; | 947 | wm8994->mbc_enum.items = pdata->num_mbc_cfgs; |
948 | wm8994->mbc_enum.texts = wm8994->mbc_texts; | 948 | wm8994->mbc_enum.texts = wm8994->mbc_texts; |
949 | 949 | ||
950 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, | 950 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
@@ -973,7 +973,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
973 | for (i = 0; i < pdata->num_vss_cfgs; i++) | 973 | for (i = 0; i < pdata->num_vss_cfgs; i++) |
974 | wm8994->vss_texts[i] = pdata->vss_cfgs[i].name; | 974 | wm8994->vss_texts[i] = pdata->vss_cfgs[i].name; |
975 | 975 | ||
976 | wm8994->vss_enum.max = pdata->num_vss_cfgs; | 976 | wm8994->vss_enum.items = pdata->num_vss_cfgs; |
977 | wm8994->vss_enum.texts = wm8994->vss_texts; | 977 | wm8994->vss_enum.texts = wm8994->vss_texts; |
978 | 978 | ||
979 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, | 979 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
@@ -1003,7 +1003,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1003 | for (i = 0; i < pdata->num_vss_hpf_cfgs; i++) | 1003 | for (i = 0; i < pdata->num_vss_hpf_cfgs; i++) |
1004 | wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name; | 1004 | wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name; |
1005 | 1005 | ||
1006 | wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; | 1006 | wm8994->vss_hpf_enum.items = pdata->num_vss_hpf_cfgs; |
1007 | wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; | 1007 | wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; |
1008 | 1008 | ||
1009 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, | 1009 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
@@ -1034,7 +1034,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1034 | for (i = 0; i < pdata->num_enh_eq_cfgs; i++) | 1034 | for (i = 0; i < pdata->num_enh_eq_cfgs; i++) |
1035 | wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name; | 1035 | wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name; |
1036 | 1036 | ||
1037 | wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; | 1037 | wm8994->enh_eq_enum.items = pdata->num_enh_eq_cfgs; |
1038 | wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; | 1038 | wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; |
1039 | 1039 | ||
1040 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, | 1040 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index f156010e52bc..d04e9cad445c 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -976,12 +976,6 @@ static int wm8960_probe(struct snd_soc_codec *codec) | |||
976 | wm8960->set_bias_level = wm8960_set_bias_level_capless; | 976 | wm8960->set_bias_level = wm8960_set_bias_level_capless; |
977 | } | 977 | } |
978 | 978 | ||
979 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
980 | if (ret < 0) { | ||
981 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
982 | return ret; | ||
983 | } | ||
984 | |||
985 | ret = wm8960_reset(codec); | 979 | ret = wm8960_reset(codec); |
986 | if (ret < 0) { | 980 | if (ret < 0) { |
987 | dev_err(codec->dev, "Failed to issue reset\n"); | 981 | dev_err(codec->dev, "Failed to issue reset\n"); |
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 900328e28a15..9c88f04442b3 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c | |||
@@ -317,15 +317,15 @@ static const char *adc_hpf_text[] = { | |||
317 | "Hi-fi", "Voice 1", "Voice 2", "Voice 3", | 317 | "Hi-fi", "Voice 1", "Voice 2", "Voice 3", |
318 | }; | 318 | }; |
319 | 319 | ||
320 | static const struct soc_enum adc_hpf = | 320 | static SOC_ENUM_SINGLE_DECL(adc_hpf, |
321 | SOC_ENUM_SINGLE(WM8961_ADC_DAC_CONTROL_2, 7, 4, adc_hpf_text); | 321 | WM8961_ADC_DAC_CONTROL_2, 7, adc_hpf_text); |
322 | 322 | ||
323 | static const char *dac_deemph_text[] = { | 323 | static const char *dac_deemph_text[] = { |
324 | "None", "32kHz", "44.1kHz", "48kHz", | 324 | "None", "32kHz", "44.1kHz", "48kHz", |
325 | }; | 325 | }; |
326 | 326 | ||
327 | static const struct soc_enum dac_deemph = | 327 | static SOC_ENUM_SINGLE_DECL(dac_deemph, |
328 | SOC_ENUM_SINGLE(WM8961_ADC_DAC_CONTROL_1, 1, 4, dac_deemph_text); | 328 | WM8961_ADC_DAC_CONTROL_1, 1, dac_deemph_text); |
329 | 329 | ||
330 | static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); | 330 | static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); |
331 | static const DECLARE_TLV_DB_SCALE(hp_sec_tlv, -700, 100, 0); | 331 | static const DECLARE_TLV_DB_SCALE(hp_sec_tlv, -700, 100, 0); |
@@ -385,11 +385,11 @@ static const char *sidetone_text[] = { | |||
385 | "None", "Left", "Right" | 385 | "None", "Left", "Right" |
386 | }; | 386 | }; |
387 | 387 | ||
388 | static const struct soc_enum dacl_sidetone = | 388 | static SOC_ENUM_SINGLE_DECL(dacl_sidetone, |
389 | SOC_ENUM_SINGLE(WM8961_DSP_SIDETONE_0, 2, 3, sidetone_text); | 389 | WM8961_DSP_SIDETONE_0, 2, sidetone_text); |
390 | 390 | ||
391 | static const struct soc_enum dacr_sidetone = | 391 | static SOC_ENUM_SINGLE_DECL(dacr_sidetone, |
392 | SOC_ENUM_SINGLE(WM8961_DSP_SIDETONE_1, 2, 3, sidetone_text); | 392 | WM8961_DSP_SIDETONE_1, 2, sidetone_text); |
393 | 393 | ||
394 | static const struct snd_kcontrol_new dacl_mux = | 394 | static const struct snd_kcontrol_new dacl_mux = |
395 | SOC_DAPM_ENUM("DACL Sidetone", dacl_sidetone); | 395 | SOC_DAPM_ENUM("DACL Sidetone", dacl_sidetone); |
@@ -836,15 +836,8 @@ static struct snd_soc_dai_driver wm8961_dai = { | |||
836 | static int wm8961_probe(struct snd_soc_codec *codec) | 836 | static int wm8961_probe(struct snd_soc_codec *codec) |
837 | { | 837 | { |
838 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 838 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
839 | int ret = 0; | ||
840 | u16 reg; | 839 | u16 reg; |
841 | 840 | ||
842 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
843 | if (ret != 0) { | ||
844 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
845 | return ret; | ||
846 | } | ||
847 | |||
848 | /* Enable class W */ | 841 | /* Enable class W */ |
849 | reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B); | 842 | reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B); |
850 | reg |= WM8961_CP_DYN_PWR_MASK; | 843 | reg |= WM8961_CP_DYN_PWR_MASK; |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 97db3b45b411..5522d2566c67 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -1479,7 +1479,9 @@ static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | |||
1479 | 1479 | ||
1480 | static int wm8962_dsp2_write_config(struct snd_soc_codec *codec) | 1480 | static int wm8962_dsp2_write_config(struct snd_soc_codec *codec) |
1481 | { | 1481 | { |
1482 | return regcache_sync_region(codec->control_data, | 1482 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
1483 | |||
1484 | return regcache_sync_region(wm8962->regmap, | ||
1483 | WM8962_HDBASS_AI_1, WM8962_MAX_REGISTER); | 1485 | WM8962_HDBASS_AI_1, WM8962_MAX_REGISTER); |
1484 | } | 1486 | } |
1485 | 1487 | ||
@@ -1658,16 +1660,16 @@ static const char *cap_hpf_mode_text[] = { | |||
1658 | "Hi-fi", "Application" | 1660 | "Hi-fi", "Application" |
1659 | }; | 1661 | }; |
1660 | 1662 | ||
1661 | static const struct soc_enum cap_hpf_mode = | 1663 | static SOC_ENUM_SINGLE_DECL(cap_hpf_mode, |
1662 | SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text); | 1664 | WM8962_ADC_DAC_CONTROL_2, 10, cap_hpf_mode_text); |
1663 | 1665 | ||
1664 | 1666 | ||
1665 | static const char *cap_lhpf_mode_text[] = { | 1667 | static const char *cap_lhpf_mode_text[] = { |
1666 | "LPF", "HPF" | 1668 | "LPF", "HPF" |
1667 | }; | 1669 | }; |
1668 | 1670 | ||
1669 | static const struct soc_enum cap_lhpf_mode = | 1671 | static SOC_ENUM_SINGLE_DECL(cap_lhpf_mode, |
1670 | SOC_ENUM_SINGLE(WM8962_LHPF1, 1, 2, cap_lhpf_mode_text); | 1672 | WM8962_LHPF1, 1, cap_lhpf_mode_text); |
1671 | 1673 | ||
1672 | static const struct snd_kcontrol_new wm8962_snd_controls[] = { | 1674 | static const struct snd_kcontrol_new wm8962_snd_controls[] = { |
1673 | SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1), | 1675 | SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1), |
@@ -2014,40 +2016,40 @@ static int dsp2_event(struct snd_soc_dapm_widget *w, | |||
2014 | 2016 | ||
2015 | static const char *st_text[] = { "None", "Left", "Right" }; | 2017 | static const char *st_text[] = { "None", "Left", "Right" }; |
2016 | 2018 | ||
2017 | static const struct soc_enum str_enum = | 2019 | static SOC_ENUM_SINGLE_DECL(str_enum, |
2018 | SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_1, 2, 3, st_text); | 2020 | WM8962_DAC_DSP_MIXING_1, 2, st_text); |
2019 | 2021 | ||
2020 | static const struct snd_kcontrol_new str_mux = | 2022 | static const struct snd_kcontrol_new str_mux = |
2021 | SOC_DAPM_ENUM("Right Sidetone", str_enum); | 2023 | SOC_DAPM_ENUM("Right Sidetone", str_enum); |
2022 | 2024 | ||
2023 | static const struct soc_enum stl_enum = | 2025 | static SOC_ENUM_SINGLE_DECL(stl_enum, |
2024 | SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_2, 2, 3, st_text); | 2026 | WM8962_DAC_DSP_MIXING_2, 2, st_text); |
2025 | 2027 | ||
2026 | static const struct snd_kcontrol_new stl_mux = | 2028 | static const struct snd_kcontrol_new stl_mux = |
2027 | SOC_DAPM_ENUM("Left Sidetone", stl_enum); | 2029 | SOC_DAPM_ENUM("Left Sidetone", stl_enum); |
2028 | 2030 | ||
2029 | static const char *outmux_text[] = { "DAC", "Mixer" }; | 2031 | static const char *outmux_text[] = { "DAC", "Mixer" }; |
2030 | 2032 | ||
2031 | static const struct soc_enum spkoutr_enum = | 2033 | static SOC_ENUM_SINGLE_DECL(spkoutr_enum, |
2032 | SOC_ENUM_SINGLE(WM8962_SPEAKER_MIXER_2, 7, 2, outmux_text); | 2034 | WM8962_SPEAKER_MIXER_2, 7, outmux_text); |
2033 | 2035 | ||
2034 | static const struct snd_kcontrol_new spkoutr_mux = | 2036 | static const struct snd_kcontrol_new spkoutr_mux = |
2035 | SOC_DAPM_ENUM("SPKOUTR Mux", spkoutr_enum); | 2037 | SOC_DAPM_ENUM("SPKOUTR Mux", spkoutr_enum); |
2036 | 2038 | ||
2037 | static const struct soc_enum spkoutl_enum = | 2039 | static SOC_ENUM_SINGLE_DECL(spkoutl_enum, |
2038 | SOC_ENUM_SINGLE(WM8962_SPEAKER_MIXER_1, 7, 2, outmux_text); | 2040 | WM8962_SPEAKER_MIXER_1, 7, outmux_text); |
2039 | 2041 | ||
2040 | static const struct snd_kcontrol_new spkoutl_mux = | 2042 | static const struct snd_kcontrol_new spkoutl_mux = |
2041 | SOC_DAPM_ENUM("SPKOUTL Mux", spkoutl_enum); | 2043 | SOC_DAPM_ENUM("SPKOUTL Mux", spkoutl_enum); |
2042 | 2044 | ||
2043 | static const struct soc_enum hpoutr_enum = | 2045 | static SOC_ENUM_SINGLE_DECL(hpoutr_enum, |
2044 | SOC_ENUM_SINGLE(WM8962_HEADPHONE_MIXER_2, 7, 2, outmux_text); | 2046 | WM8962_HEADPHONE_MIXER_2, 7, outmux_text); |
2045 | 2047 | ||
2046 | static const struct snd_kcontrol_new hpoutr_mux = | 2048 | static const struct snd_kcontrol_new hpoutr_mux = |
2047 | SOC_DAPM_ENUM("HPOUTR Mux", hpoutr_enum); | 2049 | SOC_DAPM_ENUM("HPOUTR Mux", hpoutr_enum); |
2048 | 2050 | ||
2049 | static const struct soc_enum hpoutl_enum = | 2051 | static SOC_ENUM_SINGLE_DECL(hpoutl_enum, |
2050 | SOC_ENUM_SINGLE(WM8962_HEADPHONE_MIXER_1, 7, 2, outmux_text); | 2052 | WM8962_HEADPHONE_MIXER_1, 7, outmux_text); |
2051 | 2053 | ||
2052 | static const struct snd_kcontrol_new hpoutl_mux = | 2054 | static const struct snd_kcontrol_new hpoutl_mux = |
2053 | SOC_DAPM_ENUM("HPOUTL Mux", hpoutl_enum); | 2055 | SOC_DAPM_ENUM("HPOUTL Mux", hpoutl_enum); |
@@ -2884,9 +2886,13 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
2884 | snd_soc_write(codec, WM8962_FLL_CONTROL_7, fll_div.lambda); | 2886 | snd_soc_write(codec, WM8962_FLL_CONTROL_7, fll_div.lambda); |
2885 | snd_soc_write(codec, WM8962_FLL_CONTROL_8, fll_div.n); | 2887 | snd_soc_write(codec, WM8962_FLL_CONTROL_8, fll_div.n); |
2886 | 2888 | ||
2887 | try_wait_for_completion(&wm8962->fll_lock); | 2889 | reinit_completion(&wm8962->fll_lock); |
2888 | 2890 | ||
2889 | pm_runtime_get_sync(codec->dev); | 2891 | ret = pm_runtime_get_sync(codec->dev); |
2892 | if (ret < 0) { | ||
2893 | dev_err(codec->dev, "Failed to resume device: %d\n", ret); | ||
2894 | return ret; | ||
2895 | } | ||
2890 | 2896 | ||
2891 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, | 2897 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, |
2892 | WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | | 2898 | WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | |
@@ -2894,8 +2900,6 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
2894 | 2900 | ||
2895 | dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); | 2901 | dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); |
2896 | 2902 | ||
2897 | ret = 0; | ||
2898 | |||
2899 | /* This should be a massive overestimate but go even | 2903 | /* This should be a massive overestimate but go even |
2900 | * higher if we'll error out | 2904 | * higher if we'll error out |
2901 | */ | 2905 | */ |
@@ -2909,14 +2913,17 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
2909 | 2913 | ||
2910 | if (timeout == 0 && wm8962->irq) { | 2914 | if (timeout == 0 && wm8962->irq) { |
2911 | dev_err(codec->dev, "FLL lock timed out"); | 2915 | dev_err(codec->dev, "FLL lock timed out"); |
2912 | ret = -ETIMEDOUT; | 2916 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, |
2917 | WM8962_FLL_ENA, 0); | ||
2918 | pm_runtime_put(codec->dev); | ||
2919 | return -ETIMEDOUT; | ||
2913 | } | 2920 | } |
2914 | 2921 | ||
2915 | wm8962->fll_fref = Fref; | 2922 | wm8962->fll_fref = Fref; |
2916 | wm8962->fll_fout = Fout; | 2923 | wm8962->fll_fout = Fout; |
2917 | wm8962->fll_src = source; | 2924 | wm8962->fll_src = source; |
2918 | 2925 | ||
2919 | return ret; | 2926 | return 0; |
2920 | } | 2927 | } |
2921 | 2928 | ||
2922 | static int wm8962_mute(struct snd_soc_dai *dai, int mute) | 2929 | static int wm8962_mute(struct snd_soc_dai *dai, int mute) |
@@ -3003,9 +3010,16 @@ static irqreturn_t wm8962_irq(int irq, void *data) | |||
3003 | unsigned int active; | 3010 | unsigned int active; |
3004 | int reg, ret; | 3011 | int reg, ret; |
3005 | 3012 | ||
3013 | ret = pm_runtime_get_sync(dev); | ||
3014 | if (ret < 0) { | ||
3015 | dev_err(dev, "Failed to resume: %d\n", ret); | ||
3016 | return IRQ_NONE; | ||
3017 | } | ||
3018 | |||
3006 | ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2_MASK, | 3019 | ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2_MASK, |
3007 | &mask); | 3020 | &mask); |
3008 | if (ret != 0) { | 3021 | if (ret != 0) { |
3022 | pm_runtime_put(dev); | ||
3009 | dev_err(dev, "Failed to read interrupt mask: %d\n", | 3023 | dev_err(dev, "Failed to read interrupt mask: %d\n", |
3010 | ret); | 3024 | ret); |
3011 | return IRQ_NONE; | 3025 | return IRQ_NONE; |
@@ -3013,14 +3027,17 @@ static irqreturn_t wm8962_irq(int irq, void *data) | |||
3013 | 3027 | ||
3014 | ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, &active); | 3028 | ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, &active); |
3015 | if (ret != 0) { | 3029 | if (ret != 0) { |
3030 | pm_runtime_put(dev); | ||
3016 | dev_err(dev, "Failed to read interrupt: %d\n", ret); | 3031 | dev_err(dev, "Failed to read interrupt: %d\n", ret); |
3017 | return IRQ_NONE; | 3032 | return IRQ_NONE; |
3018 | } | 3033 | } |
3019 | 3034 | ||
3020 | active &= ~mask; | 3035 | active &= ~mask; |
3021 | 3036 | ||
3022 | if (!active) | 3037 | if (!active) { |
3038 | pm_runtime_put(dev); | ||
3023 | return IRQ_NONE; | 3039 | return IRQ_NONE; |
3040 | } | ||
3024 | 3041 | ||
3025 | /* Acknowledge the interrupts */ | 3042 | /* Acknowledge the interrupts */ |
3026 | ret = regmap_write(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, active); | 3043 | ret = regmap_write(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, active); |
@@ -3070,6 +3087,8 @@ static irqreturn_t wm8962_irq(int irq, void *data) | |||
3070 | msecs_to_jiffies(250)); | 3087 | msecs_to_jiffies(250)); |
3071 | } | 3088 | } |
3072 | 3089 | ||
3090 | pm_runtime_put(dev); | ||
3091 | |||
3073 | return IRQ_HANDLED; | 3092 | return IRQ_HANDLED; |
3074 | } | 3093 | } |
3075 | 3094 | ||
@@ -3089,6 +3108,7 @@ static irqreturn_t wm8962_irq(int irq, void *data) | |||
3089 | int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | 3108 | int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) |
3090 | { | 3109 | { |
3091 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 3110 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
3111 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
3092 | int irq_mask, enable; | 3112 | int irq_mask, enable; |
3093 | 3113 | ||
3094 | wm8962->jack = jack; | 3114 | wm8962->jack = jack; |
@@ -3109,14 +3129,18 @@ int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | |||
3109 | snd_soc_jack_report(wm8962->jack, 0, | 3129 | snd_soc_jack_report(wm8962->jack, 0, |
3110 | SND_JACK_MICROPHONE | SND_JACK_BTN_0); | 3130 | SND_JACK_MICROPHONE | SND_JACK_BTN_0); |
3111 | 3131 | ||
3132 | snd_soc_dapm_mutex_lock(dapm); | ||
3133 | |||
3112 | if (jack) { | 3134 | if (jack) { |
3113 | snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); | 3135 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK"); |
3114 | snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS"); | 3136 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS"); |
3115 | } else { | 3137 | } else { |
3116 | snd_soc_dapm_disable_pin(&codec->dapm, "SYSCLK"); | 3138 | snd_soc_dapm_disable_pin_unlocked(dapm, "SYSCLK"); |
3117 | snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS"); | 3139 | snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS"); |
3118 | } | 3140 | } |
3119 | 3141 | ||
3142 | snd_soc_dapm_mutex_unlock(dapm); | ||
3143 | |||
3120 | return 0; | 3144 | return 0; |
3121 | } | 3145 | } |
3122 | EXPORT_SYMBOL_GPL(wm8962_mic_detect); | 3146 | EXPORT_SYMBOL_GPL(wm8962_mic_detect); |
@@ -3400,13 +3424,6 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
3400 | bool dmicclk, dmicdat; | 3424 | bool dmicclk, dmicdat; |
3401 | 3425 | ||
3402 | wm8962->codec = codec; | 3426 | wm8962->codec = codec; |
3403 | codec->control_data = wm8962->regmap; | ||
3404 | |||
3405 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | ||
3406 | if (ret != 0) { | ||
3407 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
3408 | return ret; | ||
3409 | } | ||
3410 | 3427 | ||
3411 | wm8962->disable_nb[0].notifier_call = wm8962_regulator_event_0; | 3428 | wm8962->disable_nb[0].notifier_call = wm8962_regulator_event_0; |
3412 | wm8962->disable_nb[1].notifier_call = wm8962_regulator_event_1; | 3429 | wm8962->disable_nb[1].notifier_call = wm8962_regulator_event_1; |
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 67aba78a7ca5..09b7b4200221 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c | |||
@@ -648,12 +648,6 @@ static int wm8971_probe(struct snd_soc_codec *codec) | |||
648 | int ret = 0; | 648 | int ret = 0; |
649 | u16 reg; | 649 | u16 reg; |
650 | 650 | ||
651 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
652 | if (ret < 0) { | ||
653 | printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret); | ||
654 | return ret; | ||
655 | } | ||
656 | |||
657 | INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work); | 651 | INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work); |
658 | wm8971_workq = create_workqueue("wm8971"); | 652 | wm8971_workq = create_workqueue("wm8971"); |
659 | if (wm8971_workq == NULL) | 653 | if (wm8971_workq == NULL) |
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 15f45c7bd833..0627c56fa44e 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c | |||
@@ -84,8 +84,8 @@ static const struct soc_enum wm8974_enum[] = { | |||
84 | 84 | ||
85 | static const char *wm8974_auxmode_text[] = { "Buffer", "Mixer" }; | 85 | static const char *wm8974_auxmode_text[] = { "Buffer", "Mixer" }; |
86 | 86 | ||
87 | static const struct soc_enum wm8974_auxmode = | 87 | static SOC_ENUM_SINGLE_DECL(wm8974_auxmode, |
88 | SOC_ENUM_SINGLE(WM8974_INPUT, 3, 2, wm8974_auxmode_text); | 88 | WM8974_INPUT, 3, wm8974_auxmode_text); |
89 | 89 | ||
90 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1); | 90 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1); |
91 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | 91 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); |
@@ -593,12 +593,6 @@ static int wm8974_probe(struct snd_soc_codec *codec) | |||
593 | { | 593 | { |
594 | int ret = 0; | 594 | int ret = 0; |
595 | 595 | ||
596 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
597 | if (ret < 0) { | ||
598 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
599 | return ret; | ||
600 | } | ||
601 | |||
602 | ret = wm8974_reset(codec); | 596 | ret = wm8974_reset(codec); |
603 | if (ret < 0) { | 597 | if (ret < 0) { |
604 | dev_err(codec->dev, "Failed to issue reset\n"); | 598 | dev_err(codec->dev, "Failed to issue reset\n"); |
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index d8fc531c0e59..28ef46c91f62 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c | |||
@@ -117,21 +117,21 @@ static const char *wm8978_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"}; | |||
117 | static const char *wm8978_alc3[] = {"ALC", "Limiter"}; | 117 | static const char *wm8978_alc3[] = {"ALC", "Limiter"}; |
118 | static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"}; | 118 | static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"}; |
119 | 119 | ||
120 | static const SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1, | 120 | static SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1, |
121 | wm8978_companding); | 121 | wm8978_companding); |
122 | static const SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL, 3, | 122 | static SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL, 3, |
123 | wm8978_companding); | 123 | wm8978_companding); |
124 | static const SOC_ENUM_SINGLE_DECL(eqmode, WM8978_EQ1, 8, wm8978_eqmode); | 124 | static SOC_ENUM_SINGLE_DECL(eqmode, WM8978_EQ1, 8, wm8978_eqmode); |
125 | static const SOC_ENUM_SINGLE_DECL(eq1, WM8978_EQ1, 5, wm8978_eq1); | 125 | static SOC_ENUM_SINGLE_DECL(eq1, WM8978_EQ1, 5, wm8978_eq1); |
126 | static const SOC_ENUM_SINGLE_DECL(eq2bw, WM8978_EQ2, 8, wm8978_bw); | 126 | static SOC_ENUM_SINGLE_DECL(eq2bw, WM8978_EQ2, 8, wm8978_bw); |
127 | static const SOC_ENUM_SINGLE_DECL(eq2, WM8978_EQ2, 5, wm8978_eq2); | 127 | static SOC_ENUM_SINGLE_DECL(eq2, WM8978_EQ2, 5, wm8978_eq2); |
128 | static const SOC_ENUM_SINGLE_DECL(eq3bw, WM8978_EQ3, 8, wm8978_bw); | 128 | static SOC_ENUM_SINGLE_DECL(eq3bw, WM8978_EQ3, 8, wm8978_bw); |
129 | static const SOC_ENUM_SINGLE_DECL(eq3, WM8978_EQ3, 5, wm8978_eq3); | 129 | static SOC_ENUM_SINGLE_DECL(eq3, WM8978_EQ3, 5, wm8978_eq3); |
130 | static const SOC_ENUM_SINGLE_DECL(eq4bw, WM8978_EQ4, 8, wm8978_bw); | 130 | static SOC_ENUM_SINGLE_DECL(eq4bw, WM8978_EQ4, 8, wm8978_bw); |
131 | static const SOC_ENUM_SINGLE_DECL(eq4, WM8978_EQ4, 5, wm8978_eq4); | 131 | static SOC_ENUM_SINGLE_DECL(eq4, WM8978_EQ4, 5, wm8978_eq4); |
132 | static const SOC_ENUM_SINGLE_DECL(eq5, WM8978_EQ5, 5, wm8978_eq5); | 132 | static SOC_ENUM_SINGLE_DECL(eq5, WM8978_EQ5, 5, wm8978_eq5); |
133 | static const SOC_ENUM_SINGLE_DECL(alc3, WM8978_ALC_CONTROL_3, 8, wm8978_alc3); | 133 | static SOC_ENUM_SINGLE_DECL(alc3, WM8978_ALC_CONTROL_3, 8, wm8978_alc3); |
134 | static const SOC_ENUM_SINGLE_DECL(alc1, WM8978_ALC_CONTROL_1, 7, wm8978_alc1); | 134 | static SOC_ENUM_SINGLE_DECL(alc1, WM8978_ALC_CONTROL_1, 7, wm8978_alc1); |
135 | 135 | ||
136 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1); | 136 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1); |
137 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | 137 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); |
@@ -975,19 +975,13 @@ static const int update_reg[] = { | |||
975 | static int wm8978_probe(struct snd_soc_codec *codec) | 975 | static int wm8978_probe(struct snd_soc_codec *codec) |
976 | { | 976 | { |
977 | struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); | 977 | struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); |
978 | int ret = 0, i; | 978 | int i; |
979 | 979 | ||
980 | /* | 980 | /* |
981 | * Set default system clock to PLL, it is more precise, this is also the | 981 | * Set default system clock to PLL, it is more precise, this is also the |
982 | * default hardware setting | 982 | * default hardware setting |
983 | */ | 983 | */ |
984 | wm8978->sysclk = WM8978_PLL; | 984 | wm8978->sysclk = WM8978_PLL; |
985 | codec->control_data = wm8978->regmap; | ||
986 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
987 | if (ret < 0) { | ||
988 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
989 | return ret; | ||
990 | } | ||
991 | 985 | ||
992 | /* | 986 | /* |
993 | * Set the update bit in all registers, that have one. This way all | 987 | * Set the update bit in all registers, that have one. This way all |
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index aa41ba0dfff4..2b9bfa53efbf 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c | |||
@@ -205,49 +205,44 @@ static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); | |||
205 | static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0); | 205 | static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0); |
206 | 206 | ||
207 | static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" }; | 207 | static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" }; |
208 | static const SOC_ENUM_SINGLE_DECL(alc_sel, WM8983_ALC_CONTROL_1, 7, | 208 | static SOC_ENUM_SINGLE_DECL(alc_sel, WM8983_ALC_CONTROL_1, 7, alc_sel_text); |
209 | alc_sel_text); | ||
210 | 209 | ||
211 | static const char *alc_mode_text[] = { "ALC", "Limiter" }; | 210 | static const char *alc_mode_text[] = { "ALC", "Limiter" }; |
212 | static const SOC_ENUM_SINGLE_DECL(alc_mode, WM8983_ALC_CONTROL_3, 8, | 211 | static SOC_ENUM_SINGLE_DECL(alc_mode, WM8983_ALC_CONTROL_3, 8, alc_mode_text); |
213 | alc_mode_text); | ||
214 | 212 | ||
215 | static const char *filter_mode_text[] = { "Audio", "Application" }; | 213 | static const char *filter_mode_text[] = { "Audio", "Application" }; |
216 | static const SOC_ENUM_SINGLE_DECL(filter_mode, WM8983_ADC_CONTROL, 7, | 214 | static SOC_ENUM_SINGLE_DECL(filter_mode, WM8983_ADC_CONTROL, 7, |
217 | filter_mode_text); | 215 | filter_mode_text); |
218 | 216 | ||
219 | static const char *eq_bw_text[] = { "Narrow", "Wide" }; | 217 | static const char *eq_bw_text[] = { "Narrow", "Wide" }; |
220 | static const char *eqmode_text[] = { "Capture", "Playback" }; | 218 | static const char *eqmode_text[] = { "Capture", "Playback" }; |
221 | static const SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text); | 219 | static SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text); |
222 | 220 | ||
223 | static const char *eq1_cutoff_text[] = { | 221 | static const char *eq1_cutoff_text[] = { |
224 | "80Hz", "105Hz", "135Hz", "175Hz" | 222 | "80Hz", "105Hz", "135Hz", "175Hz" |
225 | }; | 223 | }; |
226 | static const SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8983_EQ1_LOW_SHELF, 5, | 224 | static SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8983_EQ1_LOW_SHELF, 5, |
227 | eq1_cutoff_text); | 225 | eq1_cutoff_text); |
228 | static const char *eq2_cutoff_text[] = { | 226 | static const char *eq2_cutoff_text[] = { |
229 | "230Hz", "300Hz", "385Hz", "500Hz" | 227 | "230Hz", "300Hz", "385Hz", "500Hz" |
230 | }; | 228 | }; |
231 | static const SOC_ENUM_SINGLE_DECL(eq2_bw, WM8983_EQ2_PEAK_1, 8, eq_bw_text); | 229 | static SOC_ENUM_SINGLE_DECL(eq2_bw, WM8983_EQ2_PEAK_1, 8, eq_bw_text); |
232 | static const SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8983_EQ2_PEAK_1, 5, | 230 | static SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8983_EQ2_PEAK_1, 5, eq2_cutoff_text); |
233 | eq2_cutoff_text); | ||
234 | static const char *eq3_cutoff_text[] = { | 231 | static const char *eq3_cutoff_text[] = { |
235 | "650Hz", "850Hz", "1.1kHz", "1.4kHz" | 232 | "650Hz", "850Hz", "1.1kHz", "1.4kHz" |
236 | }; | 233 | }; |
237 | static const SOC_ENUM_SINGLE_DECL(eq3_bw, WM8983_EQ3_PEAK_2, 8, eq_bw_text); | 234 | static SOC_ENUM_SINGLE_DECL(eq3_bw, WM8983_EQ3_PEAK_2, 8, eq_bw_text); |
238 | static const SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8983_EQ3_PEAK_2, 5, | 235 | static SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8983_EQ3_PEAK_2, 5, eq3_cutoff_text); |
239 | eq3_cutoff_text); | ||
240 | static const char *eq4_cutoff_text[] = { | 236 | static const char *eq4_cutoff_text[] = { |
241 | "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" | 237 | "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" |
242 | }; | 238 | }; |
243 | static const SOC_ENUM_SINGLE_DECL(eq4_bw, WM8983_EQ4_PEAK_3, 8, eq_bw_text); | 239 | static SOC_ENUM_SINGLE_DECL(eq4_bw, WM8983_EQ4_PEAK_3, 8, eq_bw_text); |
244 | static const SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8983_EQ4_PEAK_3, 5, | 240 | static SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8983_EQ4_PEAK_3, 5, eq4_cutoff_text); |
245 | eq4_cutoff_text); | ||
246 | static const char *eq5_cutoff_text[] = { | 241 | static const char *eq5_cutoff_text[] = { |
247 | "5.3kHz", "6.9kHz", "9kHz", "11.7kHz" | 242 | "5.3kHz", "6.9kHz", "9kHz", "11.7kHz" |
248 | }; | 243 | }; |
249 | static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5, | 244 | static SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5, |
250 | eq5_cutoff_text); | 245 | eq5_cutoff_text); |
251 | 246 | ||
252 | static const char *depth_3d_text[] = { | 247 | static const char *depth_3d_text[] = { |
253 | "Off", | 248 | "Off", |
@@ -267,8 +262,8 @@ static const char *depth_3d_text[] = { | |||
267 | "93.3%", | 262 | "93.3%", |
268 | "100%" | 263 | "100%" |
269 | }; | 264 | }; |
270 | static const SOC_ENUM_SINGLE_DECL(depth_3d, WM8983_3D_CONTROL, 0, | 265 | static SOC_ENUM_SINGLE_DECL(depth_3d, WM8983_3D_CONTROL, 0, |
271 | depth_3d_text); | 266 | depth_3d_text); |
272 | 267 | ||
273 | static const struct snd_kcontrol_new wm8983_snd_controls[] = { | 268 | static const struct snd_kcontrol_new wm8983_snd_controls[] = { |
274 | SOC_SINGLE("Digital Loopback Switch", WM8983_COMPANDING_CONTROL, | 269 | SOC_SINGLE("Digital Loopback Switch", WM8983_COMPANDING_CONTROL, |
@@ -1000,12 +995,6 @@ static int wm8983_probe(struct snd_soc_codec *codec) | |||
1000 | int ret; | 995 | int ret; |
1001 | int i; | 996 | int i; |
1002 | 997 | ||
1003 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
1004 | if (ret < 0) { | ||
1005 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); | ||
1006 | return ret; | ||
1007 | } | ||
1008 | |||
1009 | ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0); | 998 | ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0); |
1010 | if (ret < 0) { | 999 | if (ret < 0) { |
1011 | dev_err(codec->dev, "Failed to issue reset: %d\n", ret); | 1000 | dev_err(codec->dev, "Failed to issue reset: %d\n", ret); |
@@ -1129,7 +1118,7 @@ static struct spi_driver wm8983_spi_driver = { | |||
1129 | }; | 1118 | }; |
1130 | #endif | 1119 | #endif |
1131 | 1120 | ||
1132 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1121 | #if IS_ENABLED(CONFIG_I2C) |
1133 | static int wm8983_i2c_probe(struct i2c_client *i2c, | 1122 | static int wm8983_i2c_probe(struct i2c_client *i2c, |
1134 | const struct i2c_device_id *id) | 1123 | const struct i2c_device_id *id) |
1135 | { | 1124 | { |
@@ -1182,7 +1171,7 @@ static int __init wm8983_modinit(void) | |||
1182 | { | 1171 | { |
1183 | int ret = 0; | 1172 | int ret = 0; |
1184 | 1173 | ||
1185 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1174 | #if IS_ENABLED(CONFIG_I2C) |
1186 | ret = i2c_add_driver(&wm8983_i2c_driver); | 1175 | ret = i2c_add_driver(&wm8983_i2c_driver); |
1187 | if (ret) { | 1176 | if (ret) { |
1188 | printk(KERN_ERR "Failed to register wm8983 I2C driver: %d\n", | 1177 | printk(KERN_ERR "Failed to register wm8983 I2C driver: %d\n", |
@@ -1202,7 +1191,7 @@ module_init(wm8983_modinit); | |||
1202 | 1191 | ||
1203 | static void __exit wm8983_exit(void) | 1192 | static void __exit wm8983_exit(void) |
1204 | { | 1193 | { |
1205 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1194 | #if IS_ENABLED(CONFIG_I2C) |
1206 | i2c_del_driver(&wm8983_i2c_driver); | 1195 | i2c_del_driver(&wm8983_i2c_driver); |
1207 | #endif | 1196 | #endif |
1208 | #if defined(CONFIG_SPI_MASTER) | 1197 | #if defined(CONFIG_SPI_MASTER) |
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index 271b517911a4..5473dc969585 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c | |||
@@ -226,52 +226,48 @@ static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); | |||
226 | static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0); | 226 | static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0); |
227 | 227 | ||
228 | static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" }; | 228 | static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" }; |
229 | static const SOC_ENUM_SINGLE_DECL(alc_sel, WM8985_ALC_CONTROL_1, 7, | 229 | static SOC_ENUM_SINGLE_DECL(alc_sel, WM8985_ALC_CONTROL_1, 7, alc_sel_text); |
230 | alc_sel_text); | ||
231 | 230 | ||
232 | static const char *alc_mode_text[] = { "ALC", "Limiter" }; | 231 | static const char *alc_mode_text[] = { "ALC", "Limiter" }; |
233 | static const SOC_ENUM_SINGLE_DECL(alc_mode, WM8985_ALC_CONTROL_3, 8, | 232 | static SOC_ENUM_SINGLE_DECL(alc_mode, WM8985_ALC_CONTROL_3, 8, alc_mode_text); |
234 | alc_mode_text); | ||
235 | 233 | ||
236 | static const char *filter_mode_text[] = { "Audio", "Application" }; | 234 | static const char *filter_mode_text[] = { "Audio", "Application" }; |
237 | static const SOC_ENUM_SINGLE_DECL(filter_mode, WM8985_ADC_CONTROL, 7, | 235 | static SOC_ENUM_SINGLE_DECL(filter_mode, WM8985_ADC_CONTROL, 7, |
238 | filter_mode_text); | 236 | filter_mode_text); |
239 | 237 | ||
240 | static const char *eq_bw_text[] = { "Narrow", "Wide" }; | 238 | static const char *eq_bw_text[] = { "Narrow", "Wide" }; |
241 | static const char *eqmode_text[] = { "Capture", "Playback" }; | 239 | static const char *eqmode_text[] = { "Capture", "Playback" }; |
242 | static const SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text); | 240 | static SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text); |
243 | 241 | ||
244 | static const char *eq1_cutoff_text[] = { | 242 | static const char *eq1_cutoff_text[] = { |
245 | "80Hz", "105Hz", "135Hz", "175Hz" | 243 | "80Hz", "105Hz", "135Hz", "175Hz" |
246 | }; | 244 | }; |
247 | static const SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8985_EQ1_LOW_SHELF, 5, | 245 | static SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8985_EQ1_LOW_SHELF, 5, |
248 | eq1_cutoff_text); | 246 | eq1_cutoff_text); |
249 | static const char *eq2_cutoff_text[] = { | 247 | static const char *eq2_cutoff_text[] = { |
250 | "230Hz", "300Hz", "385Hz", "500Hz" | 248 | "230Hz", "300Hz", "385Hz", "500Hz" |
251 | }; | 249 | }; |
252 | static const SOC_ENUM_SINGLE_DECL(eq2_bw, WM8985_EQ2_PEAK_1, 8, eq_bw_text); | 250 | static SOC_ENUM_SINGLE_DECL(eq2_bw, WM8985_EQ2_PEAK_1, 8, eq_bw_text); |
253 | static const SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8985_EQ2_PEAK_1, 5, | 251 | static SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8985_EQ2_PEAK_1, 5, eq2_cutoff_text); |
254 | eq2_cutoff_text); | ||
255 | static const char *eq3_cutoff_text[] = { | 252 | static const char *eq3_cutoff_text[] = { |
256 | "650Hz", "850Hz", "1.1kHz", "1.4kHz" | 253 | "650Hz", "850Hz", "1.1kHz", "1.4kHz" |
257 | }; | 254 | }; |
258 | static const SOC_ENUM_SINGLE_DECL(eq3_bw, WM8985_EQ3_PEAK_2, 8, eq_bw_text); | 255 | static SOC_ENUM_SINGLE_DECL(eq3_bw, WM8985_EQ3_PEAK_2, 8, eq_bw_text); |
259 | static const SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8985_EQ3_PEAK_2, 5, | 256 | static SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8985_EQ3_PEAK_2, 5, |
260 | eq3_cutoff_text); | 257 | eq3_cutoff_text); |
261 | static const char *eq4_cutoff_text[] = { | 258 | static const char *eq4_cutoff_text[] = { |
262 | "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" | 259 | "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" |
263 | }; | 260 | }; |
264 | static const SOC_ENUM_SINGLE_DECL(eq4_bw, WM8985_EQ4_PEAK_3, 8, eq_bw_text); | 261 | static SOC_ENUM_SINGLE_DECL(eq4_bw, WM8985_EQ4_PEAK_3, 8, eq_bw_text); |
265 | static const SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8985_EQ4_PEAK_3, 5, | 262 | static SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8985_EQ4_PEAK_3, 5, eq4_cutoff_text); |
266 | eq4_cutoff_text); | ||
267 | static const char *eq5_cutoff_text[] = { | 263 | static const char *eq5_cutoff_text[] = { |
268 | "5.3kHz", "6.9kHz", "9kHz", "11.7kHz" | 264 | "5.3kHz", "6.9kHz", "9kHz", "11.7kHz" |
269 | }; | 265 | }; |
270 | static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8985_EQ5_HIGH_SHELF, 5, | 266 | static SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8985_EQ5_HIGH_SHELF, 5, |
271 | eq5_cutoff_text); | 267 | eq5_cutoff_text); |
272 | 268 | ||
273 | static const char *speaker_mode_text[] = { "Class A/B", "Class D" }; | 269 | static const char *speaker_mode_text[] = { "Class A/B", "Class D" }; |
274 | static const SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text); | 270 | static SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text); |
275 | 271 | ||
276 | static const char *depth_3d_text[] = { | 272 | static const char *depth_3d_text[] = { |
277 | "Off", | 273 | "Off", |
@@ -291,8 +287,7 @@ static const char *depth_3d_text[] = { | |||
291 | "93.3%", | 287 | "93.3%", |
292 | "100%" | 288 | "100%" |
293 | }; | 289 | }; |
294 | static const SOC_ENUM_SINGLE_DECL(depth_3d, WM8985_3D_CONTROL, 0, | 290 | static SOC_ENUM_SINGLE_DECL(depth_3d, WM8985_3D_CONTROL, 0, depth_3d_text); |
295 | depth_3d_text); | ||
296 | 291 | ||
297 | static const struct snd_kcontrol_new wm8985_snd_controls[] = { | 292 | static const struct snd_kcontrol_new wm8985_snd_controls[] = { |
298 | SOC_SINGLE("Digital Loopback Switch", WM8985_COMPANDING_CONTROL, | 293 | SOC_SINGLE("Digital Loopback Switch", WM8985_COMPANDING_CONTROL, |
@@ -1000,13 +995,6 @@ static int wm8985_probe(struct snd_soc_codec *codec) | |||
1000 | int ret; | 995 | int ret; |
1001 | 996 | ||
1002 | wm8985 = snd_soc_codec_get_drvdata(codec); | 997 | wm8985 = snd_soc_codec_get_drvdata(codec); |
1003 | codec->control_data = wm8985->regmap; | ||
1004 | |||
1005 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
1006 | if (ret < 0) { | ||
1007 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); | ||
1008 | return ret; | ||
1009 | } | ||
1010 | 998 | ||
1011 | for (i = 0; i < ARRAY_SIZE(wm8985->supplies); i++) | 999 | for (i = 0; i < ARRAY_SIZE(wm8985->supplies); i++) |
1012 | wm8985->supplies[i].supply = wm8985_supply_names[i]; | 1000 | wm8985->supplies[i].supply = wm8985_supply_names[i]; |
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index a55e1c2c382e..3a1ae4f5164d 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c | |||
@@ -116,7 +116,7 @@ static bool wm8988_writeable(struct device *dev, unsigned int reg) | |||
116 | struct wm8988_priv { | 116 | struct wm8988_priv { |
117 | struct regmap *regmap; | 117 | struct regmap *regmap; |
118 | unsigned int sysclk; | 118 | unsigned int sysclk; |
119 | struct snd_pcm_hw_constraint_list *sysclk_constraints; | 119 | const struct snd_pcm_hw_constraint_list *sysclk_constraints; |
120 | }; | 120 | }; |
121 | 121 | ||
122 | #define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0) | 122 | #define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0) |
@@ -126,46 +126,46 @@ struct wm8988_priv { | |||
126 | */ | 126 | */ |
127 | 127 | ||
128 | static const char *bass_boost_txt[] = {"Linear Control", "Adaptive Boost"}; | 128 | static const char *bass_boost_txt[] = {"Linear Control", "Adaptive Boost"}; |
129 | static const struct soc_enum bass_boost = | 129 | static SOC_ENUM_SINGLE_DECL(bass_boost, |
130 | SOC_ENUM_SINGLE(WM8988_BASS, 7, 2, bass_boost_txt); | 130 | WM8988_BASS, 7, bass_boost_txt); |
131 | 131 | ||
132 | static const char *bass_filter_txt[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" }; | 132 | static const char *bass_filter_txt[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" }; |
133 | static const struct soc_enum bass_filter = | 133 | static SOC_ENUM_SINGLE_DECL(bass_filter, |
134 | SOC_ENUM_SINGLE(WM8988_BASS, 6, 2, bass_filter_txt); | 134 | WM8988_BASS, 6, bass_filter_txt); |
135 | 135 | ||
136 | static const char *treble_txt[] = {"8kHz", "4kHz"}; | 136 | static const char *treble_txt[] = {"8kHz", "4kHz"}; |
137 | static const struct soc_enum treble = | 137 | static SOC_ENUM_SINGLE_DECL(treble, |
138 | SOC_ENUM_SINGLE(WM8988_TREBLE, 6, 2, treble_txt); | 138 | WM8988_TREBLE, 6, treble_txt); |
139 | 139 | ||
140 | static const char *stereo_3d_lc_txt[] = {"200Hz", "500Hz"}; | 140 | static const char *stereo_3d_lc_txt[] = {"200Hz", "500Hz"}; |
141 | static const struct soc_enum stereo_3d_lc = | 141 | static SOC_ENUM_SINGLE_DECL(stereo_3d_lc, |
142 | SOC_ENUM_SINGLE(WM8988_3D, 5, 2, stereo_3d_lc_txt); | 142 | WM8988_3D, 5, stereo_3d_lc_txt); |
143 | 143 | ||
144 | static const char *stereo_3d_uc_txt[] = {"2.2kHz", "1.5kHz"}; | 144 | static const char *stereo_3d_uc_txt[] = {"2.2kHz", "1.5kHz"}; |
145 | static const struct soc_enum stereo_3d_uc = | 145 | static SOC_ENUM_SINGLE_DECL(stereo_3d_uc, |
146 | SOC_ENUM_SINGLE(WM8988_3D, 6, 2, stereo_3d_uc_txt); | 146 | WM8988_3D, 6, stereo_3d_uc_txt); |
147 | 147 | ||
148 | static const char *stereo_3d_func_txt[] = {"Capture", "Playback"}; | 148 | static const char *stereo_3d_func_txt[] = {"Capture", "Playback"}; |
149 | static const struct soc_enum stereo_3d_func = | 149 | static SOC_ENUM_SINGLE_DECL(stereo_3d_func, |
150 | SOC_ENUM_SINGLE(WM8988_3D, 7, 2, stereo_3d_func_txt); | 150 | WM8988_3D, 7, stereo_3d_func_txt); |
151 | 151 | ||
152 | static const char *alc_func_txt[] = {"Off", "Right", "Left", "Stereo"}; | 152 | static const char *alc_func_txt[] = {"Off", "Right", "Left", "Stereo"}; |
153 | static const struct soc_enum alc_func = | 153 | static SOC_ENUM_SINGLE_DECL(alc_func, |
154 | SOC_ENUM_SINGLE(WM8988_ALC1, 7, 4, alc_func_txt); | 154 | WM8988_ALC1, 7, alc_func_txt); |
155 | 155 | ||
156 | static const char *ng_type_txt[] = {"Constant PGA Gain", | 156 | static const char *ng_type_txt[] = {"Constant PGA Gain", |
157 | "Mute ADC Output"}; | 157 | "Mute ADC Output"}; |
158 | static const struct soc_enum ng_type = | 158 | static SOC_ENUM_SINGLE_DECL(ng_type, |
159 | SOC_ENUM_SINGLE(WM8988_NGATE, 1, 2, ng_type_txt); | 159 | WM8988_NGATE, 1, ng_type_txt); |
160 | 160 | ||
161 | static const char *deemph_txt[] = {"None", "32Khz", "44.1Khz", "48Khz"}; | 161 | static const char *deemph_txt[] = {"None", "32Khz", "44.1Khz", "48Khz"}; |
162 | static const struct soc_enum deemph = | 162 | static SOC_ENUM_SINGLE_DECL(deemph, |
163 | SOC_ENUM_SINGLE(WM8988_ADCDAC, 1, 4, deemph_txt); | 163 | WM8988_ADCDAC, 1, deemph_txt); |
164 | 164 | ||
165 | static const char *adcpol_txt[] = {"Normal", "L Invert", "R Invert", | 165 | static const char *adcpol_txt[] = {"Normal", "L Invert", "R Invert", |
166 | "L + R Invert"}; | 166 | "L + R Invert"}; |
167 | static const struct soc_enum adcpol = | 167 | static SOC_ENUM_SINGLE_DECL(adcpol, |
168 | SOC_ENUM_SINGLE(WM8988_ADCDAC, 5, 4, adcpol_txt); | 168 | WM8988_ADCDAC, 5, adcpol_txt); |
169 | 169 | ||
170 | static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0); | 170 | static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0); |
171 | static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1); | 171 | static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1); |
@@ -317,16 +317,16 @@ static const struct snd_kcontrol_new wm8988_right_pga_controls = | |||
317 | 317 | ||
318 | /* Differential Mux */ | 318 | /* Differential Mux */ |
319 | static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"}; | 319 | static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"}; |
320 | static const struct soc_enum diffmux = | 320 | static SOC_ENUM_SINGLE_DECL(diffmux, |
321 | SOC_ENUM_SINGLE(WM8988_ADCIN, 8, 2, wm8988_diff_sel); | 321 | WM8988_ADCIN, 8, wm8988_diff_sel); |
322 | static const struct snd_kcontrol_new wm8988_diffmux_controls = | 322 | static const struct snd_kcontrol_new wm8988_diffmux_controls = |
323 | SOC_DAPM_ENUM("Route", diffmux); | 323 | SOC_DAPM_ENUM("Route", diffmux); |
324 | 324 | ||
325 | /* Mono ADC Mux */ | 325 | /* Mono ADC Mux */ |
326 | static const char *wm8988_mono_mux[] = {"Stereo", "Mono (Left)", | 326 | static const char *wm8988_mono_mux[] = {"Stereo", "Mono (Left)", |
327 | "Mono (Right)", "Digital Mono"}; | 327 | "Mono (Right)", "Digital Mono"}; |
328 | static const struct soc_enum monomux = | 328 | static SOC_ENUM_SINGLE_DECL(monomux, |
329 | SOC_ENUM_SINGLE(WM8988_ADCIN, 6, 4, wm8988_mono_mux); | 329 | WM8988_ADCIN, 6, wm8988_mono_mux); |
330 | static const struct snd_kcontrol_new wm8988_monomux_controls = | 330 | static const struct snd_kcontrol_new wm8988_monomux_controls = |
331 | SOC_DAPM_ENUM("Route", monomux); | 331 | SOC_DAPM_ENUM("Route", monomux); |
332 | 332 | ||
@@ -521,30 +521,30 @@ static inline int get_coeff(int mclk, int rate) | |||
521 | 521 | ||
522 | /* The set of rates we can generate from the above for each SYSCLK */ | 522 | /* The set of rates we can generate from the above for each SYSCLK */ |
523 | 523 | ||
524 | static unsigned int rates_12288[] = { | 524 | static const unsigned int rates_12288[] = { |
525 | 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000, | 525 | 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000, |
526 | }; | 526 | }; |
527 | 527 | ||
528 | static struct snd_pcm_hw_constraint_list constraints_12288 = { | 528 | static const struct snd_pcm_hw_constraint_list constraints_12288 = { |
529 | .count = ARRAY_SIZE(rates_12288), | 529 | .count = ARRAY_SIZE(rates_12288), |
530 | .list = rates_12288, | 530 | .list = rates_12288, |
531 | }; | 531 | }; |
532 | 532 | ||
533 | static unsigned int rates_112896[] = { | 533 | static const unsigned int rates_112896[] = { |
534 | 8000, 11025, 22050, 44100, | 534 | 8000, 11025, 22050, 44100, |
535 | }; | 535 | }; |
536 | 536 | ||
537 | static struct snd_pcm_hw_constraint_list constraints_112896 = { | 537 | static const struct snd_pcm_hw_constraint_list constraints_112896 = { |
538 | .count = ARRAY_SIZE(rates_112896), | 538 | .count = ARRAY_SIZE(rates_112896), |
539 | .list = rates_112896, | 539 | .list = rates_112896, |
540 | }; | 540 | }; |
541 | 541 | ||
542 | static unsigned int rates_12[] = { | 542 | static const unsigned int rates_12[] = { |
543 | 8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000, | 543 | 8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000, |
544 | 48000, 88235, 96000, | 544 | 48000, 88235, 96000, |
545 | }; | 545 | }; |
546 | 546 | ||
547 | static struct snd_pcm_hw_constraint_list constraints_12 = { | 547 | static const struct snd_pcm_hw_constraint_list constraints_12 = { |
548 | .count = ARRAY_SIZE(rates_12), | 548 | .count = ARRAY_SIZE(rates_12), |
549 | .list = rates_12, | 549 | .list = rates_12, |
550 | }; | 550 | }; |
@@ -810,16 +810,8 @@ static int wm8988_resume(struct snd_soc_codec *codec) | |||
810 | 810 | ||
811 | static int wm8988_probe(struct snd_soc_codec *codec) | 811 | static int wm8988_probe(struct snd_soc_codec *codec) |
812 | { | 812 | { |
813 | struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); | ||
814 | int ret = 0; | 813 | int ret = 0; |
815 | 814 | ||
816 | codec->control_data = wm8988->regmap; | ||
817 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
818 | if (ret < 0) { | ||
819 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
820 | return ret; | ||
821 | } | ||
822 | |||
823 | ret = wm8988_reset(codec); | 815 | ret = wm8988_reset(codec); |
824 | if (ret < 0) { | 816 | if (ret < 0) { |
825 | dev_err(codec->dev, "Failed to issue reset\n"); | 817 | dev_err(codec->dev, "Failed to issue reset\n"); |
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 0ccd4d8d043b..c413c1991453 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
@@ -157,26 +157,23 @@ static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | |||
157 | static const char *wm8990_digital_sidetone[] = | 157 | static const char *wm8990_digital_sidetone[] = |
158 | {"None", "Left ADC", "Right ADC", "Reserved"}; | 158 | {"None", "Left ADC", "Right ADC", "Reserved"}; |
159 | 159 | ||
160 | static const struct soc_enum wm8990_left_digital_sidetone_enum = | 160 | static SOC_ENUM_SINGLE_DECL(wm8990_left_digital_sidetone_enum, |
161 | SOC_ENUM_SINGLE(WM8990_DIGITAL_SIDE_TONE, | 161 | WM8990_DIGITAL_SIDE_TONE, |
162 | WM8990_ADC_TO_DACL_SHIFT, | 162 | WM8990_ADC_TO_DACL_SHIFT, |
163 | WM8990_ADC_TO_DACL_MASK, | 163 | wm8990_digital_sidetone); |
164 | wm8990_digital_sidetone); | 164 | |
165 | 165 | static SOC_ENUM_SINGLE_DECL(wm8990_right_digital_sidetone_enum, | |
166 | static const struct soc_enum wm8990_right_digital_sidetone_enum = | 166 | WM8990_DIGITAL_SIDE_TONE, |
167 | SOC_ENUM_SINGLE(WM8990_DIGITAL_SIDE_TONE, | 167 | WM8990_ADC_TO_DACR_SHIFT, |
168 | WM8990_ADC_TO_DACR_SHIFT, | 168 | wm8990_digital_sidetone); |
169 | WM8990_ADC_TO_DACR_MASK, | ||
170 | wm8990_digital_sidetone); | ||
171 | 169 | ||
172 | static const char *wm8990_adcmode[] = | 170 | static const char *wm8990_adcmode[] = |
173 | {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; | 171 | {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; |
174 | 172 | ||
175 | static const struct soc_enum wm8990_right_adcmode_enum = | 173 | static SOC_ENUM_SINGLE_DECL(wm8990_right_adcmode_enum, |
176 | SOC_ENUM_SINGLE(WM8990_ADC_CTRL, | 174 | WM8990_ADC_CTRL, |
177 | WM8990_ADC_HPF_CUT_SHIFT, | 175 | WM8990_ADC_HPF_CUT_SHIFT, |
178 | WM8990_ADC_HPF_CUT_MASK, | 176 | wm8990_adcmode); |
179 | wm8990_adcmode); | ||
180 | 177 | ||
181 | static const struct snd_kcontrol_new wm8990_snd_controls[] = { | 178 | static const struct snd_kcontrol_new wm8990_snd_controls[] = { |
182 | /* INMIXL */ | 179 | /* INMIXL */ |
@@ -475,9 +472,9 @@ SOC_DAPM_SINGLE("RINPGA34 Switch", WM8990_INPUT_MIXER3, WM8990_L34MNB_BIT, | |||
475 | static const char *wm8990_ainlmux[] = | 472 | static const char *wm8990_ainlmux[] = |
476 | {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; | 473 | {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; |
477 | 474 | ||
478 | static const struct soc_enum wm8990_ainlmux_enum = | 475 | static SOC_ENUM_SINGLE_DECL(wm8990_ainlmux_enum, |
479 | SOC_ENUM_SINGLE(WM8990_INPUT_MIXER1, WM8990_AINLMODE_SHIFT, | 476 | WM8990_INPUT_MIXER1, WM8990_AINLMODE_SHIFT, |
480 | ARRAY_SIZE(wm8990_ainlmux), wm8990_ainlmux); | 477 | wm8990_ainlmux); |
481 | 478 | ||
482 | static const struct snd_kcontrol_new wm8990_dapm_ainlmux_controls = | 479 | static const struct snd_kcontrol_new wm8990_dapm_ainlmux_controls = |
483 | SOC_DAPM_ENUM("Route", wm8990_ainlmux_enum); | 480 | SOC_DAPM_ENUM("Route", wm8990_ainlmux_enum); |
@@ -488,9 +485,9 @@ SOC_DAPM_ENUM("Route", wm8990_ainlmux_enum); | |||
488 | static const char *wm8990_ainrmux[] = | 485 | static const char *wm8990_ainrmux[] = |
489 | {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; | 486 | {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; |
490 | 487 | ||
491 | static const struct soc_enum wm8990_ainrmux_enum = | 488 | static SOC_ENUM_SINGLE_DECL(wm8990_ainrmux_enum, |
492 | SOC_ENUM_SINGLE(WM8990_INPUT_MIXER1, WM8990_AINRMODE_SHIFT, | 489 | WM8990_INPUT_MIXER1, WM8990_AINRMODE_SHIFT, |
493 | ARRAY_SIZE(wm8990_ainrmux), wm8990_ainrmux); | 490 | wm8990_ainrmux); |
494 | 491 | ||
495 | static const struct snd_kcontrol_new wm8990_dapm_ainrmux_controls = | 492 | static const struct snd_kcontrol_new wm8990_dapm_ainrmux_controls = |
496 | SOC_DAPM_ENUM("Route", wm8990_ainrmux_enum); | 493 | SOC_DAPM_ENUM("Route", wm8990_ainrmux_enum); |
@@ -1292,14 +1289,6 @@ static int wm8990_resume(struct snd_soc_codec *codec) | |||
1292 | */ | 1289 | */ |
1293 | static int wm8990_probe(struct snd_soc_codec *codec) | 1290 | static int wm8990_probe(struct snd_soc_codec *codec) |
1294 | { | 1291 | { |
1295 | int ret; | ||
1296 | |||
1297 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1298 | if (ret < 0) { | ||
1299 | printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret); | ||
1300 | return ret; | ||
1301 | } | ||
1302 | |||
1303 | wm8990_reset(codec); | 1292 | wm8990_reset(codec); |
1304 | 1293 | ||
1305 | /* charge output caps */ | 1294 | /* charge output caps */ |
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index dba0306c42a5..844cc4a60d66 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c | |||
@@ -171,26 +171,23 @@ static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | |||
171 | static const char *wm8991_digital_sidetone[] = | 171 | static const char *wm8991_digital_sidetone[] = |
172 | {"None", "Left ADC", "Right ADC", "Reserved"}; | 172 | {"None", "Left ADC", "Right ADC", "Reserved"}; |
173 | 173 | ||
174 | static const struct soc_enum wm8991_left_digital_sidetone_enum = | 174 | static SOC_ENUM_SINGLE_DECL(wm8991_left_digital_sidetone_enum, |
175 | SOC_ENUM_SINGLE(WM8991_DIGITAL_SIDE_TONE, | 175 | WM8991_DIGITAL_SIDE_TONE, |
176 | WM8991_ADC_TO_DACL_SHIFT, | 176 | WM8991_ADC_TO_DACL_SHIFT, |
177 | WM8991_ADC_TO_DACL_MASK, | 177 | wm8991_digital_sidetone); |
178 | wm8991_digital_sidetone); | 178 | |
179 | 179 | static SOC_ENUM_SINGLE_DECL(wm8991_right_digital_sidetone_enum, | |
180 | static const struct soc_enum wm8991_right_digital_sidetone_enum = | 180 | WM8991_DIGITAL_SIDE_TONE, |
181 | SOC_ENUM_SINGLE(WM8991_DIGITAL_SIDE_TONE, | 181 | WM8991_ADC_TO_DACR_SHIFT, |
182 | WM8991_ADC_TO_DACR_SHIFT, | 182 | wm8991_digital_sidetone); |
183 | WM8991_ADC_TO_DACR_MASK, | ||
184 | wm8991_digital_sidetone); | ||
185 | 183 | ||
186 | static const char *wm8991_adcmode[] = | 184 | static const char *wm8991_adcmode[] = |
187 | {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; | 185 | {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; |
188 | 186 | ||
189 | static const struct soc_enum wm8991_right_adcmode_enum = | 187 | static SOC_ENUM_SINGLE_DECL(wm8991_right_adcmode_enum, |
190 | SOC_ENUM_SINGLE(WM8991_ADC_CTRL, | 188 | WM8991_ADC_CTRL, |
191 | WM8991_ADC_HPF_CUT_SHIFT, | 189 | WM8991_ADC_HPF_CUT_SHIFT, |
192 | WM8991_ADC_HPF_CUT_MASK, | 190 | wm8991_adcmode); |
193 | wm8991_adcmode); | ||
194 | 191 | ||
195 | static const struct snd_kcontrol_new wm8991_snd_controls[] = { | 192 | static const struct snd_kcontrol_new wm8991_snd_controls[] = { |
196 | /* INMIXL */ | 193 | /* INMIXL */ |
@@ -486,9 +483,9 @@ static const struct snd_kcontrol_new wm8991_dapm_inmixr_controls[] = { | |||
486 | static const char *wm8991_ainlmux[] = | 483 | static const char *wm8991_ainlmux[] = |
487 | {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; | 484 | {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; |
488 | 485 | ||
489 | static const struct soc_enum wm8991_ainlmux_enum = | 486 | static SOC_ENUM_SINGLE_DECL(wm8991_ainlmux_enum, |
490 | SOC_ENUM_SINGLE(WM8991_INPUT_MIXER1, WM8991_AINLMODE_SHIFT, | 487 | WM8991_INPUT_MIXER1, WM8991_AINLMODE_SHIFT, |
491 | ARRAY_SIZE(wm8991_ainlmux), wm8991_ainlmux); | 488 | wm8991_ainlmux); |
492 | 489 | ||
493 | static const struct snd_kcontrol_new wm8991_dapm_ainlmux_controls = | 490 | static const struct snd_kcontrol_new wm8991_dapm_ainlmux_controls = |
494 | SOC_DAPM_ENUM("Route", wm8991_ainlmux_enum); | 491 | SOC_DAPM_ENUM("Route", wm8991_ainlmux_enum); |
@@ -499,9 +496,9 @@ static const struct snd_kcontrol_new wm8991_dapm_ainlmux_controls = | |||
499 | static const char *wm8991_ainrmux[] = | 496 | static const char *wm8991_ainrmux[] = |
500 | {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; | 497 | {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; |
501 | 498 | ||
502 | static const struct soc_enum wm8991_ainrmux_enum = | 499 | static SOC_ENUM_SINGLE_DECL(wm8991_ainrmux_enum, |
503 | SOC_ENUM_SINGLE(WM8991_INPUT_MIXER1, WM8991_AINRMODE_SHIFT, | 500 | WM8991_INPUT_MIXER1, WM8991_AINRMODE_SHIFT, |
504 | ARRAY_SIZE(wm8991_ainrmux), wm8991_ainrmux); | 501 | wm8991_ainrmux); |
505 | 502 | ||
506 | static const struct snd_kcontrol_new wm8991_dapm_ainrmux_controls = | 503 | static const struct snd_kcontrol_new wm8991_dapm_ainrmux_controls = |
507 | SOC_DAPM_ENUM("Route", wm8991_ainrmux_enum); | 504 | SOC_DAPM_ENUM("Route", wm8991_ainrmux_enum); |
@@ -1251,17 +1248,6 @@ static int wm8991_remove(struct snd_soc_codec *codec) | |||
1251 | 1248 | ||
1252 | static int wm8991_probe(struct snd_soc_codec *codec) | 1249 | static int wm8991_probe(struct snd_soc_codec *codec) |
1253 | { | 1250 | { |
1254 | struct wm8991_priv *wm8991; | ||
1255 | int ret; | ||
1256 | |||
1257 | wm8991 = snd_soc_codec_get_drvdata(codec); | ||
1258 | |||
1259 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1260 | if (ret < 0) { | ||
1261 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); | ||
1262 | return ret; | ||
1263 | } | ||
1264 | |||
1265 | wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1251 | wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1266 | 1252 | ||
1267 | return 0; | 1253 | return 0; |
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 433d59a0f3ef..f825dc04ebe1 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -646,8 +646,8 @@ static const char *dac_deemph_text[] = { | |||
646 | "48kHz", | 646 | "48kHz", |
647 | }; | 647 | }; |
648 | 648 | ||
649 | static const struct soc_enum dac_deemph = | 649 | static SOC_ENUM_SINGLE_DECL(dac_deemph, |
650 | SOC_ENUM_SINGLE(WM8993_DAC_CTRL, 4, 4, dac_deemph_text); | 650 | WM8993_DAC_CTRL, 4, dac_deemph_text); |
651 | 651 | ||
652 | static const char *adc_hpf_text[] = { | 652 | static const char *adc_hpf_text[] = { |
653 | "Hi-Fi", | 653 | "Hi-Fi", |
@@ -656,16 +656,16 @@ static const char *adc_hpf_text[] = { | |||
656 | "Voice 3", | 656 | "Voice 3", |
657 | }; | 657 | }; |
658 | 658 | ||
659 | static const struct soc_enum adc_hpf = | 659 | static SOC_ENUM_SINGLE_DECL(adc_hpf, |
660 | SOC_ENUM_SINGLE(WM8993_ADC_CTRL, 5, 4, adc_hpf_text); | 660 | WM8993_ADC_CTRL, 5, adc_hpf_text); |
661 | 661 | ||
662 | static const char *drc_path_text[] = { | 662 | static const char *drc_path_text[] = { |
663 | "ADC", | 663 | "ADC", |
664 | "DAC" | 664 | "DAC" |
665 | }; | 665 | }; |
666 | 666 | ||
667 | static const struct soc_enum drc_path = | 667 | static SOC_ENUM_SINGLE_DECL(drc_path, |
668 | SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_1, 14, 2, drc_path_text); | 668 | WM8993_DRC_CONTROL_1, 14, drc_path_text); |
669 | 669 | ||
670 | static const char *drc_r0_text[] = { | 670 | static const char *drc_r0_text[] = { |
671 | "1", | 671 | "1", |
@@ -676,8 +676,8 @@ static const char *drc_r0_text[] = { | |||
676 | "0", | 676 | "0", |
677 | }; | 677 | }; |
678 | 678 | ||
679 | static const struct soc_enum drc_r0 = | 679 | static SOC_ENUM_SINGLE_DECL(drc_r0, |
680 | SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_3, 8, 6, drc_r0_text); | 680 | WM8993_DRC_CONTROL_3, 8, drc_r0_text); |
681 | 681 | ||
682 | static const char *drc_r1_text[] = { | 682 | static const char *drc_r1_text[] = { |
683 | "1", | 683 | "1", |
@@ -687,8 +687,8 @@ static const char *drc_r1_text[] = { | |||
687 | "0", | 687 | "0", |
688 | }; | 688 | }; |
689 | 689 | ||
690 | static const struct soc_enum drc_r1 = | 690 | static SOC_ENUM_SINGLE_DECL(drc_r1, |
691 | SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_4, 13, 5, drc_r1_text); | 691 | WM8993_DRC_CONTROL_4, 13, drc_r1_text); |
692 | 692 | ||
693 | static const char *drc_attack_text[] = { | 693 | static const char *drc_attack_text[] = { |
694 | "Reserved", | 694 | "Reserved", |
@@ -705,8 +705,8 @@ static const char *drc_attack_text[] = { | |||
705 | "185.6ms", | 705 | "185.6ms", |
706 | }; | 706 | }; |
707 | 707 | ||
708 | static const struct soc_enum drc_attack = | 708 | static SOC_ENUM_SINGLE_DECL(drc_attack, |
709 | SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_2, 12, 12, drc_attack_text); | 709 | WM8993_DRC_CONTROL_2, 12, drc_attack_text); |
710 | 710 | ||
711 | static const char *drc_decay_text[] = { | 711 | static const char *drc_decay_text[] = { |
712 | "186ms", | 712 | "186ms", |
@@ -720,16 +720,16 @@ static const char *drc_decay_text[] = { | |||
720 | "47.56ms", | 720 | "47.56ms", |
721 | }; | 721 | }; |
722 | 722 | ||
723 | static const struct soc_enum drc_decay = | 723 | static SOC_ENUM_SINGLE_DECL(drc_decay, |
724 | SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_2, 8, 9, drc_decay_text); | 724 | WM8993_DRC_CONTROL_2, 8, drc_decay_text); |
725 | 725 | ||
726 | static const char *drc_ff_text[] = { | 726 | static const char *drc_ff_text[] = { |
727 | "5 samples", | 727 | "5 samples", |
728 | "9 samples", | 728 | "9 samples", |
729 | }; | 729 | }; |
730 | 730 | ||
731 | static const struct soc_enum drc_ff = | 731 | static SOC_ENUM_SINGLE_DECL(drc_ff, |
732 | SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_3, 7, 2, drc_ff_text); | 732 | WM8993_DRC_CONTROL_3, 7, drc_ff_text); |
733 | 733 | ||
734 | static const char *drc_qr_rate_text[] = { | 734 | static const char *drc_qr_rate_text[] = { |
735 | "0.725ms", | 735 | "0.725ms", |
@@ -737,8 +737,8 @@ static const char *drc_qr_rate_text[] = { | |||
737 | "5.8ms", | 737 | "5.8ms", |
738 | }; | 738 | }; |
739 | 739 | ||
740 | static const struct soc_enum drc_qr_rate = | 740 | static SOC_ENUM_SINGLE_DECL(drc_qr_rate, |
741 | SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_3, 0, 3, drc_qr_rate_text); | 741 | WM8993_DRC_CONTROL_3, 0, drc_qr_rate_text); |
742 | 742 | ||
743 | static const char *drc_smooth_text[] = { | 743 | static const char *drc_smooth_text[] = { |
744 | "Low", | 744 | "Low", |
@@ -746,8 +746,8 @@ static const char *drc_smooth_text[] = { | |||
746 | "High", | 746 | "High", |
747 | }; | 747 | }; |
748 | 748 | ||
749 | static const struct soc_enum drc_smooth = | 749 | static SOC_ENUM_SINGLE_DECL(drc_smooth, |
750 | SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_1, 4, 3, drc_smooth_text); | 750 | WM8993_DRC_CONTROL_1, 4, drc_smooth_text); |
751 | 751 | ||
752 | static const struct snd_kcontrol_new wm8993_snd_controls[] = { | 752 | static const struct snd_kcontrol_new wm8993_snd_controls[] = { |
753 | SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8993_DIGITAL_SIDE_TONE, | 753 | SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8993_DIGITAL_SIDE_TONE, |
@@ -841,26 +841,26 @@ static const char *aif_text[] = { | |||
841 | "Left", "Right" | 841 | "Left", "Right" |
842 | }; | 842 | }; |
843 | 843 | ||
844 | static const struct soc_enum aifoutl_enum = | 844 | static SOC_ENUM_SINGLE_DECL(aifoutl_enum, |
845 | SOC_ENUM_SINGLE(WM8993_AUDIO_INTERFACE_1, 15, 2, aif_text); | 845 | WM8993_AUDIO_INTERFACE_1, 15, aif_text); |
846 | 846 | ||
847 | static const struct snd_kcontrol_new aifoutl_mux = | 847 | static const struct snd_kcontrol_new aifoutl_mux = |
848 | SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum); | 848 | SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum); |
849 | 849 | ||
850 | static const struct soc_enum aifoutr_enum = | 850 | static SOC_ENUM_SINGLE_DECL(aifoutr_enum, |
851 | SOC_ENUM_SINGLE(WM8993_AUDIO_INTERFACE_1, 14, 2, aif_text); | 851 | WM8993_AUDIO_INTERFACE_1, 14, aif_text); |
852 | 852 | ||
853 | static const struct snd_kcontrol_new aifoutr_mux = | 853 | static const struct snd_kcontrol_new aifoutr_mux = |
854 | SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum); | 854 | SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum); |
855 | 855 | ||
856 | static const struct soc_enum aifinl_enum = | 856 | static SOC_ENUM_SINGLE_DECL(aifinl_enum, |
857 | SOC_ENUM_SINGLE(WM8993_AUDIO_INTERFACE_2, 15, 2, aif_text); | 857 | WM8993_AUDIO_INTERFACE_2, 15, aif_text); |
858 | 858 | ||
859 | static const struct snd_kcontrol_new aifinl_mux = | 859 | static const struct snd_kcontrol_new aifinl_mux = |
860 | SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum); | 860 | SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum); |
861 | 861 | ||
862 | static const struct soc_enum aifinr_enum = | 862 | static SOC_ENUM_SINGLE_DECL(aifinr_enum, |
863 | SOC_ENUM_SINGLE(WM8993_AUDIO_INTERFACE_2, 14, 2, aif_text); | 863 | WM8993_AUDIO_INTERFACE_2, 14, aif_text); |
864 | 864 | ||
865 | static const struct snd_kcontrol_new aifinr_mux = | 865 | static const struct snd_kcontrol_new aifinr_mux = |
866 | SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum); | 866 | SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum); |
@@ -869,14 +869,14 @@ static const char *sidetone_text[] = { | |||
869 | "None", "Left", "Right" | 869 | "None", "Left", "Right" |
870 | }; | 870 | }; |
871 | 871 | ||
872 | static const struct soc_enum sidetonel_enum = | 872 | static SOC_ENUM_SINGLE_DECL(sidetonel_enum, |
873 | SOC_ENUM_SINGLE(WM8993_DIGITAL_SIDE_TONE, 2, 3, sidetone_text); | 873 | WM8993_DIGITAL_SIDE_TONE, 2, sidetone_text); |
874 | 874 | ||
875 | static const struct snd_kcontrol_new sidetonel_mux = | 875 | static const struct snd_kcontrol_new sidetonel_mux = |
876 | SOC_DAPM_ENUM("Left Sidetone", sidetonel_enum); | 876 | SOC_DAPM_ENUM("Left Sidetone", sidetonel_enum); |
877 | 877 | ||
878 | static const struct soc_enum sidetoner_enum = | 878 | static SOC_ENUM_SINGLE_DECL(sidetoner_enum, |
879 | SOC_ENUM_SINGLE(WM8993_DIGITAL_SIDE_TONE, 0, 3, sidetone_text); | 879 | WM8993_DIGITAL_SIDE_TONE, 0, sidetone_text); |
880 | 880 | ||
881 | static const struct snd_kcontrol_new sidetoner_mux = | 881 | static const struct snd_kcontrol_new sidetoner_mux = |
882 | SOC_DAPM_ENUM("Right Sidetone", sidetoner_enum); | 882 | SOC_DAPM_ENUM("Right Sidetone", sidetoner_enum); |
@@ -1493,13 +1493,6 @@ static int wm8993_probe(struct snd_soc_codec *codec) | |||
1493 | wm8993->hubs_data.dcs_codes_r = -2; | 1493 | wm8993->hubs_data.dcs_codes_r = -2; |
1494 | wm8993->hubs_data.series_startup = 1; | 1494 | wm8993->hubs_data.series_startup = 1; |
1495 | 1495 | ||
1496 | codec->control_data = wm8993->regmap; | ||
1497 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1498 | if (ret != 0) { | ||
1499 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1500 | return ret; | ||
1501 | } | ||
1502 | |||
1503 | /* Latch volume update bits and default ZC on */ | 1496 | /* Latch volume update bits and default ZC on */ |
1504 | snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME, | 1497 | snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME, |
1505 | WM8993_DAC_VU, WM8993_DAC_VU); | 1498 | WM8993_DAC_VU, WM8993_DAC_VU); |
@@ -1559,10 +1552,7 @@ static int wm8993_probe(struct snd_soc_codec *codec) | |||
1559 | 1552 | ||
1560 | static int wm8993_remove(struct snd_soc_codec *codec) | 1553 | static int wm8993_remove(struct snd_soc_codec *codec) |
1561 | { | 1554 | { |
1562 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); | ||
1563 | |||
1564 | wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1555 | wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1565 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1566 | return 0; | 1556 | return 0; |
1567 | } | 1557 | } |
1568 | 1558 | ||
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b9be9cbc4603..6303537f54c6 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -265,21 +265,21 @@ static const char *sidetone_hpf_text[] = { | |||
265 | "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz" | 265 | "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz" |
266 | }; | 266 | }; |
267 | 267 | ||
268 | static const struct soc_enum sidetone_hpf = | 268 | static SOC_ENUM_SINGLE_DECL(sidetone_hpf, |
269 | SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text); | 269 | WM8994_SIDETONE, 7, sidetone_hpf_text); |
270 | 270 | ||
271 | static const char *adc_hpf_text[] = { | 271 | static const char *adc_hpf_text[] = { |
272 | "HiFi", "Voice 1", "Voice 2", "Voice 3" | 272 | "HiFi", "Voice 1", "Voice 2", "Voice 3" |
273 | }; | 273 | }; |
274 | 274 | ||
275 | static const struct soc_enum aif1adc1_hpf = | 275 | static SOC_ENUM_SINGLE_DECL(aif1adc1_hpf, |
276 | SOC_ENUM_SINGLE(WM8994_AIF1_ADC1_FILTERS, 13, 4, adc_hpf_text); | 276 | WM8994_AIF1_ADC1_FILTERS, 13, adc_hpf_text); |
277 | 277 | ||
278 | static const struct soc_enum aif1adc2_hpf = | 278 | static SOC_ENUM_SINGLE_DECL(aif1adc2_hpf, |
279 | SOC_ENUM_SINGLE(WM8994_AIF1_ADC2_FILTERS, 13, 4, adc_hpf_text); | 279 | WM8994_AIF1_ADC2_FILTERS, 13, adc_hpf_text); |
280 | 280 | ||
281 | static const struct soc_enum aif2adc_hpf = | 281 | static SOC_ENUM_SINGLE_DECL(aif2adc_hpf, |
282 | SOC_ENUM_SINGLE(WM8994_AIF2_ADC_FILTERS, 13, 4, adc_hpf_text); | 282 | WM8994_AIF2_ADC_FILTERS, 13, adc_hpf_text); |
283 | 283 | ||
284 | static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0); | 284 | static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0); |
285 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); | 285 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); |
@@ -501,39 +501,39 @@ static const char *aif_chan_src_text[] = { | |||
501 | "Left", "Right" | 501 | "Left", "Right" |
502 | }; | 502 | }; |
503 | 503 | ||
504 | static const struct soc_enum aif1adcl_src = | 504 | static SOC_ENUM_SINGLE_DECL(aif1adcl_src, |
505 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text); | 505 | WM8994_AIF1_CONTROL_1, 15, aif_chan_src_text); |
506 | 506 | ||
507 | static const struct soc_enum aif1adcr_src = | 507 | static SOC_ENUM_SINGLE_DECL(aif1adcr_src, |
508 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text); | 508 | WM8994_AIF1_CONTROL_1, 14, aif_chan_src_text); |
509 | 509 | ||
510 | static const struct soc_enum aif2adcl_src = | 510 | static SOC_ENUM_SINGLE_DECL(aif2adcl_src, |
511 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text); | 511 | WM8994_AIF2_CONTROL_1, 15, aif_chan_src_text); |
512 | 512 | ||
513 | static const struct soc_enum aif2adcr_src = | 513 | static SOC_ENUM_SINGLE_DECL(aif2adcr_src, |
514 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text); | 514 | WM8994_AIF2_CONTROL_1, 14, aif_chan_src_text); |
515 | 515 | ||
516 | static const struct soc_enum aif1dacl_src = | 516 | static SOC_ENUM_SINGLE_DECL(aif1dacl_src, |
517 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text); | 517 | WM8994_AIF1_CONTROL_2, 15, aif_chan_src_text); |
518 | 518 | ||
519 | static const struct soc_enum aif1dacr_src = | 519 | static SOC_ENUM_SINGLE_DECL(aif1dacr_src, |
520 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text); | 520 | WM8994_AIF1_CONTROL_2, 14, aif_chan_src_text); |
521 | 521 | ||
522 | static const struct soc_enum aif2dacl_src = | 522 | static SOC_ENUM_SINGLE_DECL(aif2dacl_src, |
523 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text); | 523 | WM8994_AIF2_CONTROL_2, 15, aif_chan_src_text); |
524 | 524 | ||
525 | static const struct soc_enum aif2dacr_src = | 525 | static SOC_ENUM_SINGLE_DECL(aif2dacr_src, |
526 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text); | 526 | WM8994_AIF2_CONTROL_2, 14, aif_chan_src_text); |
527 | 527 | ||
528 | static const char *osr_text[] = { | 528 | static const char *osr_text[] = { |
529 | "Low Power", "High Performance", | 529 | "Low Power", "High Performance", |
530 | }; | 530 | }; |
531 | 531 | ||
532 | static const struct soc_enum dac_osr = | 532 | static SOC_ENUM_SINGLE_DECL(dac_osr, |
533 | SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text); | 533 | WM8994_OVERSAMPLING, 0, osr_text); |
534 | 534 | ||
535 | static const struct soc_enum adc_osr = | 535 | static SOC_ENUM_SINGLE_DECL(adc_osr, |
536 | SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text); | 536 | WM8994_OVERSAMPLING, 1, osr_text); |
537 | 537 | ||
538 | static const struct snd_kcontrol_new wm8994_snd_controls[] = { | 538 | static const struct snd_kcontrol_new wm8994_snd_controls[] = { |
539 | SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, | 539 | SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, |
@@ -690,17 +690,20 @@ static const char *wm8958_ng_text[] = { | |||
690 | "30ms", "125ms", "250ms", "500ms", | 690 | "30ms", "125ms", "250ms", "500ms", |
691 | }; | 691 | }; |
692 | 692 | ||
693 | static const struct soc_enum wm8958_aif1dac1_ng_hold = | 693 | static SOC_ENUM_SINGLE_DECL(wm8958_aif1dac1_ng_hold, |
694 | SOC_ENUM_SINGLE(WM8958_AIF1_DAC1_NOISE_GATE, | 694 | WM8958_AIF1_DAC1_NOISE_GATE, |
695 | WM8958_AIF1DAC1_NG_THR_SHIFT, 4, wm8958_ng_text); | 695 | WM8958_AIF1DAC1_NG_THR_SHIFT, |
696 | wm8958_ng_text); | ||
696 | 697 | ||
697 | static const struct soc_enum wm8958_aif1dac2_ng_hold = | 698 | static SOC_ENUM_SINGLE_DECL(wm8958_aif1dac2_ng_hold, |
698 | SOC_ENUM_SINGLE(WM8958_AIF1_DAC2_NOISE_GATE, | 699 | WM8958_AIF1_DAC2_NOISE_GATE, |
699 | WM8958_AIF1DAC2_NG_THR_SHIFT, 4, wm8958_ng_text); | 700 | WM8958_AIF1DAC2_NG_THR_SHIFT, |
701 | wm8958_ng_text); | ||
700 | 702 | ||
701 | static const struct soc_enum wm8958_aif2dac_ng_hold = | 703 | static SOC_ENUM_SINGLE_DECL(wm8958_aif2dac_ng_hold, |
702 | SOC_ENUM_SINGLE(WM8958_AIF2_DAC_NOISE_GATE, | 704 | WM8958_AIF2_DAC_NOISE_GATE, |
703 | WM8958_AIF2DAC_NG_THR_SHIFT, 4, wm8958_ng_text); | 705 | WM8958_AIF2DAC_NG_THR_SHIFT, |
706 | wm8958_ng_text); | ||
704 | 707 | ||
705 | static const struct snd_kcontrol_new wm8958_snd_controls[] = { | 708 | static const struct snd_kcontrol_new wm8958_snd_controls[] = { |
706 | SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), | 709 | SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), |
@@ -1341,8 +1344,7 @@ static const char *adc_mux_text[] = { | |||
1341 | "DMIC", | 1344 | "DMIC", |
1342 | }; | 1345 | }; |
1343 | 1346 | ||
1344 | static const struct soc_enum adc_enum = | 1347 | static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text); |
1345 | SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text); | ||
1346 | 1348 | ||
1347 | static const struct snd_kcontrol_new adcl_mux = | 1349 | static const struct snd_kcontrol_new adcl_mux = |
1348 | SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); | 1350 | SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); |
@@ -1478,14 +1480,14 @@ static const char *sidetone_text[] = { | |||
1478 | "ADC/DMIC1", "DMIC2", | 1480 | "ADC/DMIC1", "DMIC2", |
1479 | }; | 1481 | }; |
1480 | 1482 | ||
1481 | static const struct soc_enum sidetone1_enum = | 1483 | static SOC_ENUM_SINGLE_DECL(sidetone1_enum, |
1482 | SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text); | 1484 | WM8994_SIDETONE, 0, sidetone_text); |
1483 | 1485 | ||
1484 | static const struct snd_kcontrol_new sidetone1_mux = | 1486 | static const struct snd_kcontrol_new sidetone1_mux = |
1485 | SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); | 1487 | SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); |
1486 | 1488 | ||
1487 | static const struct soc_enum sidetone2_enum = | 1489 | static SOC_ENUM_SINGLE_DECL(sidetone2_enum, |
1488 | SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text); | 1490 | WM8994_SIDETONE, 1, sidetone_text); |
1489 | 1491 | ||
1490 | static const struct snd_kcontrol_new sidetone2_mux = | 1492 | static const struct snd_kcontrol_new sidetone2_mux = |
1491 | SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); | 1493 | SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); |
@@ -1498,22 +1500,24 @@ static const char *loopback_text[] = { | |||
1498 | "None", "ADCDAT", | 1500 | "None", "ADCDAT", |
1499 | }; | 1501 | }; |
1500 | 1502 | ||
1501 | static const struct soc_enum aif1_loopback_enum = | 1503 | static SOC_ENUM_SINGLE_DECL(aif1_loopback_enum, |
1502 | SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, WM8994_AIF1_LOOPBACK_SHIFT, 2, | 1504 | WM8994_AIF1_CONTROL_2, |
1503 | loopback_text); | 1505 | WM8994_AIF1_LOOPBACK_SHIFT, |
1506 | loopback_text); | ||
1504 | 1507 | ||
1505 | static const struct snd_kcontrol_new aif1_loopback = | 1508 | static const struct snd_kcontrol_new aif1_loopback = |
1506 | SOC_DAPM_ENUM("AIF1 Loopback", aif1_loopback_enum); | 1509 | SOC_DAPM_ENUM("AIF1 Loopback", aif1_loopback_enum); |
1507 | 1510 | ||
1508 | static const struct soc_enum aif2_loopback_enum = | 1511 | static SOC_ENUM_SINGLE_DECL(aif2_loopback_enum, |
1509 | SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, WM8994_AIF2_LOOPBACK_SHIFT, 2, | 1512 | WM8994_AIF2_CONTROL_2, |
1510 | loopback_text); | 1513 | WM8994_AIF2_LOOPBACK_SHIFT, |
1514 | loopback_text); | ||
1511 | 1515 | ||
1512 | static const struct snd_kcontrol_new aif2_loopback = | 1516 | static const struct snd_kcontrol_new aif2_loopback = |
1513 | SOC_DAPM_ENUM("AIF2 Loopback", aif2_loopback_enum); | 1517 | SOC_DAPM_ENUM("AIF2 Loopback", aif2_loopback_enum); |
1514 | 1518 | ||
1515 | static const struct soc_enum aif1dac_enum = | 1519 | static SOC_ENUM_SINGLE_DECL(aif1dac_enum, |
1516 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text); | 1520 | WM8994_POWER_MANAGEMENT_6, 0, aif1dac_text); |
1517 | 1521 | ||
1518 | static const struct snd_kcontrol_new aif1dac_mux = | 1522 | static const struct snd_kcontrol_new aif1dac_mux = |
1519 | SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum); | 1523 | SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum); |
@@ -1522,8 +1526,8 @@ static const char *aif2dac_text[] = { | |||
1522 | "AIF2DACDAT", "AIF3DACDAT", | 1526 | "AIF2DACDAT", "AIF3DACDAT", |
1523 | }; | 1527 | }; |
1524 | 1528 | ||
1525 | static const struct soc_enum aif2dac_enum = | 1529 | static SOC_ENUM_SINGLE_DECL(aif2dac_enum, |
1526 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text); | 1530 | WM8994_POWER_MANAGEMENT_6, 1, aif2dac_text); |
1527 | 1531 | ||
1528 | static const struct snd_kcontrol_new aif2dac_mux = | 1532 | static const struct snd_kcontrol_new aif2dac_mux = |
1529 | SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum); | 1533 | SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum); |
@@ -1532,8 +1536,8 @@ static const char *aif2adc_text[] = { | |||
1532 | "AIF2ADCDAT", "AIF3DACDAT", | 1536 | "AIF2ADCDAT", "AIF3DACDAT", |
1533 | }; | 1537 | }; |
1534 | 1538 | ||
1535 | static const struct soc_enum aif2adc_enum = | 1539 | static SOC_ENUM_SINGLE_DECL(aif2adc_enum, |
1536 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text); | 1540 | WM8994_POWER_MANAGEMENT_6, 2, aif2adc_text); |
1537 | 1541 | ||
1538 | static const struct snd_kcontrol_new aif2adc_mux = | 1542 | static const struct snd_kcontrol_new aif2adc_mux = |
1539 | SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); | 1543 | SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); |
@@ -1542,14 +1546,14 @@ static const char *aif3adc_text[] = { | |||
1542 | "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM", | 1546 | "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM", |
1543 | }; | 1547 | }; |
1544 | 1548 | ||
1545 | static const struct soc_enum wm8994_aif3adc_enum = | 1549 | static SOC_ENUM_SINGLE_DECL(wm8994_aif3adc_enum, |
1546 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text); | 1550 | WM8994_POWER_MANAGEMENT_6, 3, aif3adc_text); |
1547 | 1551 | ||
1548 | static const struct snd_kcontrol_new wm8994_aif3adc_mux = | 1552 | static const struct snd_kcontrol_new wm8994_aif3adc_mux = |
1549 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum); | 1553 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum); |
1550 | 1554 | ||
1551 | static const struct soc_enum wm8958_aif3adc_enum = | 1555 | static SOC_ENUM_SINGLE_DECL(wm8958_aif3adc_enum, |
1552 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text); | 1556 | WM8994_POWER_MANAGEMENT_6, 3, aif3adc_text); |
1553 | 1557 | ||
1554 | static const struct snd_kcontrol_new wm8958_aif3adc_mux = | 1558 | static const struct snd_kcontrol_new wm8958_aif3adc_mux = |
1555 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum); | 1559 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum); |
@@ -1558,8 +1562,8 @@ static const char *mono_pcm_out_text[] = { | |||
1558 | "None", "AIF2ADCL", "AIF2ADCR", | 1562 | "None", "AIF2ADCL", "AIF2ADCR", |
1559 | }; | 1563 | }; |
1560 | 1564 | ||
1561 | static const struct soc_enum mono_pcm_out_enum = | 1565 | static SOC_ENUM_SINGLE_DECL(mono_pcm_out_enum, |
1562 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text); | 1566 | WM8994_POWER_MANAGEMENT_6, 9, mono_pcm_out_text); |
1563 | 1567 | ||
1564 | static const struct snd_kcontrol_new mono_pcm_out_mux = | 1568 | static const struct snd_kcontrol_new mono_pcm_out_mux = |
1565 | SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum); | 1569 | SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum); |
@@ -1569,14 +1573,14 @@ static const char *aif2dac_src_text[] = { | |||
1569 | }; | 1573 | }; |
1570 | 1574 | ||
1571 | /* Note that these two control shouldn't be simultaneously switched to AIF3 */ | 1575 | /* Note that these two control shouldn't be simultaneously switched to AIF3 */ |
1572 | static const struct soc_enum aif2dacl_src_enum = | 1576 | static SOC_ENUM_SINGLE_DECL(aif2dacl_src_enum, |
1573 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text); | 1577 | WM8994_POWER_MANAGEMENT_6, 7, aif2dac_src_text); |
1574 | 1578 | ||
1575 | static const struct snd_kcontrol_new aif2dacl_src_mux = | 1579 | static const struct snd_kcontrol_new aif2dacl_src_mux = |
1576 | SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum); | 1580 | SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum); |
1577 | 1581 | ||
1578 | static const struct soc_enum aif2dacr_src_enum = | 1582 | static SOC_ENUM_SINGLE_DECL(aif2dacr_src_enum, |
1579 | SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text); | 1583 | WM8994_POWER_MANAGEMENT_6, 8, aif2dac_src_text); |
1580 | 1584 | ||
1581 | static const struct snd_kcontrol_new aif2dacr_src_mux = | 1585 | static const struct snd_kcontrol_new aif2dacr_src_mux = |
1582 | SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); | 1586 | SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); |
@@ -2549,43 +2553,52 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
2549 | int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode) | 2553 | int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode) |
2550 | { | 2554 | { |
2551 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2555 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2556 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
2552 | 2557 | ||
2553 | switch (mode) { | 2558 | switch (mode) { |
2554 | case WM8994_VMID_NORMAL: | 2559 | case WM8994_VMID_NORMAL: |
2560 | snd_soc_dapm_mutex_lock(dapm); | ||
2561 | |||
2555 | if (wm8994->hubs.lineout1_se) { | 2562 | if (wm8994->hubs.lineout1_se) { |
2556 | snd_soc_dapm_disable_pin(&codec->dapm, | 2563 | snd_soc_dapm_disable_pin_unlocked(dapm, |
2557 | "LINEOUT1N Driver"); | 2564 | "LINEOUT1N Driver"); |
2558 | snd_soc_dapm_disable_pin(&codec->dapm, | 2565 | snd_soc_dapm_disable_pin_unlocked(dapm, |
2559 | "LINEOUT1P Driver"); | 2566 | "LINEOUT1P Driver"); |
2560 | } | 2567 | } |
2561 | if (wm8994->hubs.lineout2_se) { | 2568 | if (wm8994->hubs.lineout2_se) { |
2562 | snd_soc_dapm_disable_pin(&codec->dapm, | 2569 | snd_soc_dapm_disable_pin_unlocked(dapm, |
2563 | "LINEOUT2N Driver"); | 2570 | "LINEOUT2N Driver"); |
2564 | snd_soc_dapm_disable_pin(&codec->dapm, | 2571 | snd_soc_dapm_disable_pin_unlocked(dapm, |
2565 | "LINEOUT2P Driver"); | 2572 | "LINEOUT2P Driver"); |
2566 | } | 2573 | } |
2567 | 2574 | ||
2568 | /* Do the sync with the old mode to allow it to clean up */ | 2575 | /* Do the sync with the old mode to allow it to clean up */ |
2569 | snd_soc_dapm_sync(&codec->dapm); | 2576 | snd_soc_dapm_sync_unlocked(dapm); |
2570 | wm8994->vmid_mode = mode; | 2577 | wm8994->vmid_mode = mode; |
2578 | |||
2579 | snd_soc_dapm_mutex_unlock(dapm); | ||
2571 | break; | 2580 | break; |
2572 | 2581 | ||
2573 | case WM8994_VMID_FORCE: | 2582 | case WM8994_VMID_FORCE: |
2583 | snd_soc_dapm_mutex_lock(dapm); | ||
2584 | |||
2574 | if (wm8994->hubs.lineout1_se) { | 2585 | if (wm8994->hubs.lineout1_se) { |
2575 | snd_soc_dapm_force_enable_pin(&codec->dapm, | 2586 | snd_soc_dapm_force_enable_pin_unlocked(dapm, |
2576 | "LINEOUT1N Driver"); | 2587 | "LINEOUT1N Driver"); |
2577 | snd_soc_dapm_force_enable_pin(&codec->dapm, | 2588 | snd_soc_dapm_force_enable_pin_unlocked(dapm, |
2578 | "LINEOUT1P Driver"); | 2589 | "LINEOUT1P Driver"); |
2579 | } | 2590 | } |
2580 | if (wm8994->hubs.lineout2_se) { | 2591 | if (wm8994->hubs.lineout2_se) { |
2581 | snd_soc_dapm_force_enable_pin(&codec->dapm, | 2592 | snd_soc_dapm_force_enable_pin_unlocked(dapm, |
2582 | "LINEOUT2N Driver"); | 2593 | "LINEOUT2N Driver"); |
2583 | snd_soc_dapm_force_enable_pin(&codec->dapm, | 2594 | snd_soc_dapm_force_enable_pin_unlocked(dapm, |
2584 | "LINEOUT2P Driver"); | 2595 | "LINEOUT2P Driver"); |
2585 | } | 2596 | } |
2586 | 2597 | ||
2587 | wm8994->vmid_mode = mode; | 2598 | wm8994->vmid_mode = mode; |
2588 | snd_soc_dapm_sync(&codec->dapm); | 2599 | snd_soc_dapm_sync_unlocked(dapm); |
2600 | |||
2601 | snd_soc_dapm_mutex_unlock(dapm); | ||
2589 | break; | 2602 | break; |
2590 | 2603 | ||
2591 | default: | 2604 | default: |
@@ -3237,7 +3250,7 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | |||
3237 | dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", | 3250 | dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", |
3238 | wm8994->num_retune_mobile_texts); | 3251 | wm8994->num_retune_mobile_texts); |
3239 | 3252 | ||
3240 | wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; | 3253 | wm8994->retune_mobile_enum.items = wm8994->num_retune_mobile_texts; |
3241 | wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; | 3254 | wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; |
3242 | 3255 | ||
3243 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, | 3256 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, |
@@ -3293,7 +3306,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
3293 | for (i = 0; i < pdata->num_drc_cfgs; i++) | 3306 | for (i = 0; i < pdata->num_drc_cfgs; i++) |
3294 | wm8994->drc_texts[i] = pdata->drc_cfgs[i].name; | 3307 | wm8994->drc_texts[i] = pdata->drc_cfgs[i].name; |
3295 | 3308 | ||
3296 | wm8994->drc_enum.max = pdata->num_drc_cfgs; | 3309 | wm8994->drc_enum.items = pdata->num_drc_cfgs; |
3297 | wm8994->drc_enum.texts = wm8994->drc_texts; | 3310 | wm8994->drc_enum.texts = wm8994->drc_texts; |
3298 | 3311 | ||
3299 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, | 3312 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, |
@@ -3985,9 +3998,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3985 | int ret, i; | 3998 | int ret, i; |
3986 | 3999 | ||
3987 | wm8994->hubs.codec = codec; | 4000 | wm8994->hubs.codec = codec; |
3988 | codec->control_data = control->regmap; | ||
3989 | 4001 | ||
3990 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | 4002 | snd_soc_codec_set_cache_io(codec, control->regmap); |
3991 | 4003 | ||
3992 | mutex_init(&wm8994->accdet_lock); | 4004 | mutex_init(&wm8994->accdet_lock); |
3993 | INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, | 4005 | INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, |
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 4300caff1783..d3152cf5bd56 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c | |||
@@ -423,24 +423,24 @@ static const char *in1l_text[] = { | |||
423 | "Differential", "Single-ended IN1LN", "Single-ended IN1LP" | 423 | "Differential", "Single-ended IN1LN", "Single-ended IN1LP" |
424 | }; | 424 | }; |
425 | 425 | ||
426 | static const SOC_ENUM_SINGLE_DECL(in1l_enum, WM8995_LEFT_LINE_INPUT_CONTROL, | 426 | static SOC_ENUM_SINGLE_DECL(in1l_enum, WM8995_LEFT_LINE_INPUT_CONTROL, |
427 | 2, in1l_text); | 427 | 2, in1l_text); |
428 | 428 | ||
429 | static const char *in1r_text[] = { | 429 | static const char *in1r_text[] = { |
430 | "Differential", "Single-ended IN1RN", "Single-ended IN1RP" | 430 | "Differential", "Single-ended IN1RN", "Single-ended IN1RP" |
431 | }; | 431 | }; |
432 | 432 | ||
433 | static const SOC_ENUM_SINGLE_DECL(in1r_enum, WM8995_LEFT_LINE_INPUT_CONTROL, | 433 | static SOC_ENUM_SINGLE_DECL(in1r_enum, WM8995_LEFT_LINE_INPUT_CONTROL, |
434 | 0, in1r_text); | 434 | 0, in1r_text); |
435 | 435 | ||
436 | static const char *dmic_src_text[] = { | 436 | static const char *dmic_src_text[] = { |
437 | "DMICDAT1", "DMICDAT2", "DMICDAT3" | 437 | "DMICDAT1", "DMICDAT2", "DMICDAT3" |
438 | }; | 438 | }; |
439 | 439 | ||
440 | static const SOC_ENUM_SINGLE_DECL(dmic_src1_enum, WM8995_POWER_MANAGEMENT_5, | 440 | static SOC_ENUM_SINGLE_DECL(dmic_src1_enum, WM8995_POWER_MANAGEMENT_5, |
441 | 8, dmic_src_text); | 441 | 8, dmic_src_text); |
442 | static const SOC_ENUM_SINGLE_DECL(dmic_src2_enum, WM8995_POWER_MANAGEMENT_5, | 442 | static SOC_ENUM_SINGLE_DECL(dmic_src2_enum, WM8995_POWER_MANAGEMENT_5, |
443 | 6, dmic_src_text); | 443 | 6, dmic_src_text); |
444 | 444 | ||
445 | static const struct snd_kcontrol_new wm8995_snd_controls[] = { | 445 | static const struct snd_kcontrol_new wm8995_snd_controls[] = { |
446 | SOC_DOUBLE_R_TLV("DAC1 Volume", WM8995_DAC1_LEFT_VOLUME, | 446 | SOC_DOUBLE_R_TLV("DAC1 Volume", WM8995_DAC1_LEFT_VOLUME, |
@@ -561,10 +561,8 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w, | |||
561 | struct snd_kcontrol *kcontrol, int event) | 561 | struct snd_kcontrol *kcontrol, int event) |
562 | { | 562 | { |
563 | struct snd_soc_codec *codec; | 563 | struct snd_soc_codec *codec; |
564 | struct wm8995_priv *wm8995; | ||
565 | 564 | ||
566 | codec = w->codec; | 565 | codec = w->codec; |
567 | wm8995 = snd_soc_codec_get_drvdata(codec); | ||
568 | 566 | ||
569 | switch (event) { | 567 | switch (event) { |
570 | case SND_SOC_DAPM_PRE_PMU: | 568 | case SND_SOC_DAPM_PRE_PMU: |
@@ -783,14 +781,12 @@ static const char *sidetone_text[] = { | |||
783 | "ADC/DMIC1", "DMIC2", | 781 | "ADC/DMIC1", "DMIC2", |
784 | }; | 782 | }; |
785 | 783 | ||
786 | static const struct soc_enum sidetone1_enum = | 784 | static SOC_ENUM_SINGLE_DECL(sidetone1_enum, WM8995_SIDETONE, 0, sidetone_text); |
787 | SOC_ENUM_SINGLE(WM8995_SIDETONE, 0, 2, sidetone_text); | ||
788 | 785 | ||
789 | static const struct snd_kcontrol_new sidetone1_mux = | 786 | static const struct snd_kcontrol_new sidetone1_mux = |
790 | SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); | 787 | SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); |
791 | 788 | ||
792 | static const struct soc_enum sidetone2_enum = | 789 | static SOC_ENUM_SINGLE_DECL(sidetone2_enum, WM8995_SIDETONE, 1, sidetone_text); |
793 | SOC_ENUM_SINGLE(WM8995_SIDETONE, 1, 2, sidetone_text); | ||
794 | 790 | ||
795 | static const struct snd_kcontrol_new sidetone2_mux = | 791 | static const struct snd_kcontrol_new sidetone2_mux = |
796 | SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); | 792 | SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); |
@@ -886,8 +882,7 @@ static const char *adc_mux_text[] = { | |||
886 | "DMIC", | 882 | "DMIC", |
887 | }; | 883 | }; |
888 | 884 | ||
889 | static const struct soc_enum adc_enum = | 885 | static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text); |
890 | SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text); | ||
891 | 886 | ||
892 | static const struct snd_kcontrol_new adcl_mux = | 887 | static const struct snd_kcontrol_new adcl_mux = |
893 | SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); | 888 | SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); |
@@ -899,14 +894,14 @@ static const char *spk_src_text[] = { | |||
899 | "DAC1L", "DAC1R", "DAC2L", "DAC2R" | 894 | "DAC1L", "DAC1R", "DAC2L", "DAC2R" |
900 | }; | 895 | }; |
901 | 896 | ||
902 | static const SOC_ENUM_SINGLE_DECL(spk1l_src_enum, WM8995_LEFT_PDM_SPEAKER_1, | 897 | static SOC_ENUM_SINGLE_DECL(spk1l_src_enum, WM8995_LEFT_PDM_SPEAKER_1, |
903 | 0, spk_src_text); | 898 | 0, spk_src_text); |
904 | static const SOC_ENUM_SINGLE_DECL(spk1r_src_enum, WM8995_RIGHT_PDM_SPEAKER_1, | 899 | static SOC_ENUM_SINGLE_DECL(spk1r_src_enum, WM8995_RIGHT_PDM_SPEAKER_1, |
905 | 0, spk_src_text); | 900 | 0, spk_src_text); |
906 | static const SOC_ENUM_SINGLE_DECL(spk2l_src_enum, WM8995_LEFT_PDM_SPEAKER_2, | 901 | static SOC_ENUM_SINGLE_DECL(spk2l_src_enum, WM8995_LEFT_PDM_SPEAKER_2, |
907 | 0, spk_src_text); | 902 | 0, spk_src_text); |
908 | static const SOC_ENUM_SINGLE_DECL(spk2r_src_enum, WM8995_RIGHT_PDM_SPEAKER_2, | 903 | static SOC_ENUM_SINGLE_DECL(spk2r_src_enum, WM8995_RIGHT_PDM_SPEAKER_2, |
909 | 0, spk_src_text); | 904 | 0, spk_src_text); |
910 | 905 | ||
911 | static const struct snd_kcontrol_new spk1l_mux = | 906 | static const struct snd_kcontrol_new spk1l_mux = |
912 | SOC_DAPM_ENUM("SPK1L SRC", spk1l_src_enum); | 907 | SOC_DAPM_ENUM("SPK1L SRC", spk1l_src_enum); |
@@ -2047,13 +2042,6 @@ static int wm8995_probe(struct snd_soc_codec *codec) | |||
2047 | wm8995 = snd_soc_codec_get_drvdata(codec); | 2042 | wm8995 = snd_soc_codec_get_drvdata(codec); |
2048 | wm8995->codec = codec; | 2043 | wm8995->codec = codec; |
2049 | 2044 | ||
2050 | codec->control_data = wm8995->regmap; | ||
2051 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | ||
2052 | if (ret < 0) { | ||
2053 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); | ||
2054 | return ret; | ||
2055 | } | ||
2056 | |||
2057 | for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++) | 2045 | for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++) |
2058 | wm8995->supplies[i].supply = wm8995_supply_names[i]; | 2046 | wm8995->supplies[i].supply = wm8995_supply_names[i]; |
2059 | 2047 | ||
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 1a7655b0aa22..c6cbb3b8ace9 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -311,28 +311,28 @@ static const char *sidetone_hpf_text[] = { | |||
311 | "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz" | 311 | "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz" |
312 | }; | 312 | }; |
313 | 313 | ||
314 | static const struct soc_enum sidetone_hpf = | 314 | static SOC_ENUM_SINGLE_DECL(sidetone_hpf, |
315 | SOC_ENUM_SINGLE(WM8996_SIDETONE, 7, 7, sidetone_hpf_text); | 315 | WM8996_SIDETONE, 7, sidetone_hpf_text); |
316 | 316 | ||
317 | static const char *hpf_mode_text[] = { | 317 | static const char *hpf_mode_text[] = { |
318 | "HiFi", "Custom", "Voice" | 318 | "HiFi", "Custom", "Voice" |
319 | }; | 319 | }; |
320 | 320 | ||
321 | static const struct soc_enum dsp1tx_hpf_mode = | 321 | static SOC_ENUM_SINGLE_DECL(dsp1tx_hpf_mode, |
322 | SOC_ENUM_SINGLE(WM8996_DSP1_TX_FILTERS, 3, 3, hpf_mode_text); | 322 | WM8996_DSP1_TX_FILTERS, 3, hpf_mode_text); |
323 | 323 | ||
324 | static const struct soc_enum dsp2tx_hpf_mode = | 324 | static SOC_ENUM_SINGLE_DECL(dsp2tx_hpf_mode, |
325 | SOC_ENUM_SINGLE(WM8996_DSP2_TX_FILTERS, 3, 3, hpf_mode_text); | 325 | WM8996_DSP2_TX_FILTERS, 3, hpf_mode_text); |
326 | 326 | ||
327 | static const char *hpf_cutoff_text[] = { | 327 | static const char *hpf_cutoff_text[] = { |
328 | "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" | 328 | "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" |
329 | }; | 329 | }; |
330 | 330 | ||
331 | static const struct soc_enum dsp1tx_hpf_cutoff = | 331 | static SOC_ENUM_SINGLE_DECL(dsp1tx_hpf_cutoff, |
332 | SOC_ENUM_SINGLE(WM8996_DSP1_TX_FILTERS, 0, 7, hpf_cutoff_text); | 332 | WM8996_DSP1_TX_FILTERS, 0, hpf_cutoff_text); |
333 | 333 | ||
334 | static const struct soc_enum dsp2tx_hpf_cutoff = | 334 | static SOC_ENUM_SINGLE_DECL(dsp2tx_hpf_cutoff, |
335 | SOC_ENUM_SINGLE(WM8996_DSP2_TX_FILTERS, 0, 7, hpf_cutoff_text); | 335 | WM8996_DSP2_TX_FILTERS, 0, hpf_cutoff_text); |
336 | 336 | ||
337 | static void wm8996_set_retune_mobile(struct snd_soc_codec *codec, int block) | 337 | static void wm8996_set_retune_mobile(struct snd_soc_codec *codec, int block) |
338 | { | 338 | { |
@@ -780,14 +780,14 @@ static const char *sidetone_text[] = { | |||
780 | "IN1", "IN2", | 780 | "IN1", "IN2", |
781 | }; | 781 | }; |
782 | 782 | ||
783 | static const struct soc_enum left_sidetone_enum = | 783 | static SOC_ENUM_SINGLE_DECL(left_sidetone_enum, |
784 | SOC_ENUM_SINGLE(WM8996_SIDETONE, 0, 2, sidetone_text); | 784 | WM8996_SIDETONE, 0, sidetone_text); |
785 | 785 | ||
786 | static const struct snd_kcontrol_new left_sidetone = | 786 | static const struct snd_kcontrol_new left_sidetone = |
787 | SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum); | 787 | SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum); |
788 | 788 | ||
789 | static const struct soc_enum right_sidetone_enum = | 789 | static SOC_ENUM_SINGLE_DECL(right_sidetone_enum, |
790 | SOC_ENUM_SINGLE(WM8996_SIDETONE, 1, 2, sidetone_text); | 790 | WM8996_SIDETONE, 1, sidetone_text); |
791 | 791 | ||
792 | static const struct snd_kcontrol_new right_sidetone = | 792 | static const struct snd_kcontrol_new right_sidetone = |
793 | SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum); | 793 | SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum); |
@@ -796,14 +796,14 @@ static const char *spk_text[] = { | |||
796 | "DAC1L", "DAC1R", "DAC2L", "DAC2R" | 796 | "DAC1L", "DAC1R", "DAC2L", "DAC2R" |
797 | }; | 797 | }; |
798 | 798 | ||
799 | static const struct soc_enum spkl_enum = | 799 | static SOC_ENUM_SINGLE_DECL(spkl_enum, |
800 | SOC_ENUM_SINGLE(WM8996_LEFT_PDM_SPEAKER, 0, 4, spk_text); | 800 | WM8996_LEFT_PDM_SPEAKER, 0, spk_text); |
801 | 801 | ||
802 | static const struct snd_kcontrol_new spkl_mux = | 802 | static const struct snd_kcontrol_new spkl_mux = |
803 | SOC_DAPM_ENUM("SPKL", spkl_enum); | 803 | SOC_DAPM_ENUM("SPKL", spkl_enum); |
804 | 804 | ||
805 | static const struct soc_enum spkr_enum = | 805 | static SOC_ENUM_SINGLE_DECL(spkr_enum, |
806 | SOC_ENUM_SINGLE(WM8996_RIGHT_PDM_SPEAKER, 0, 4, spk_text); | 806 | WM8996_RIGHT_PDM_SPEAKER, 0, spk_text); |
807 | 807 | ||
808 | static const struct snd_kcontrol_new spkr_mux = | 808 | static const struct snd_kcontrol_new spkr_mux = |
809 | SOC_DAPM_ENUM("SPKR", spkr_enum); | 809 | SOC_DAPM_ENUM("SPKR", spkr_enum); |
@@ -812,8 +812,8 @@ static const char *dsp1rx_text[] = { | |||
812 | "AIF1", "AIF2" | 812 | "AIF1", "AIF2" |
813 | }; | 813 | }; |
814 | 814 | ||
815 | static const struct soc_enum dsp1rx_enum = | 815 | static SOC_ENUM_SINGLE_DECL(dsp1rx_enum, |
816 | SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_8, 0, 2, dsp1rx_text); | 816 | WM8996_POWER_MANAGEMENT_8, 0, dsp1rx_text); |
817 | 817 | ||
818 | static const struct snd_kcontrol_new dsp1rx = | 818 | static const struct snd_kcontrol_new dsp1rx = |
819 | SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum); | 819 | SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum); |
@@ -822,8 +822,8 @@ static const char *dsp2rx_text[] = { | |||
822 | "AIF2", "AIF1" | 822 | "AIF2", "AIF1" |
823 | }; | 823 | }; |
824 | 824 | ||
825 | static const struct soc_enum dsp2rx_enum = | 825 | static SOC_ENUM_SINGLE_DECL(dsp2rx_enum, |
826 | SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_8, 4, 2, dsp2rx_text); | 826 | WM8996_POWER_MANAGEMENT_8, 4, dsp2rx_text); |
827 | 827 | ||
828 | static const struct snd_kcontrol_new dsp2rx = | 828 | static const struct snd_kcontrol_new dsp2rx = |
829 | SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum); | 829 | SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum); |
@@ -832,8 +832,8 @@ static const char *aif2tx_text[] = { | |||
832 | "DSP2", "DSP1", "AIF1" | 832 | "DSP2", "DSP1", "AIF1" |
833 | }; | 833 | }; |
834 | 834 | ||
835 | static const struct soc_enum aif2tx_enum = | 835 | static SOC_ENUM_SINGLE_DECL(aif2tx_enum, |
836 | SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_8, 6, 3, aif2tx_text); | 836 | WM8996_POWER_MANAGEMENT_8, 6, aif2tx_text); |
837 | 837 | ||
838 | static const struct snd_kcontrol_new aif2tx = | 838 | static const struct snd_kcontrol_new aif2tx = |
839 | SOC_DAPM_ENUM("AIF2TX", aif2tx_enum); | 839 | SOC_DAPM_ENUM("AIF2TX", aif2tx_enum); |
@@ -842,14 +842,14 @@ static const char *inmux_text[] = { | |||
842 | "ADC", "DMIC1", "DMIC2" | 842 | "ADC", "DMIC1", "DMIC2" |
843 | }; | 843 | }; |
844 | 844 | ||
845 | static const struct soc_enum in1_enum = | 845 | static SOC_ENUM_SINGLE_DECL(in1_enum, |
846 | SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_7, 0, 3, inmux_text); | 846 | WM8996_POWER_MANAGEMENT_7, 0, inmux_text); |
847 | 847 | ||
848 | static const struct snd_kcontrol_new in1_mux = | 848 | static const struct snd_kcontrol_new in1_mux = |
849 | SOC_DAPM_ENUM("IN1 Mux", in1_enum); | 849 | SOC_DAPM_ENUM("IN1 Mux", in1_enum); |
850 | 850 | ||
851 | static const struct soc_enum in2_enum = | 851 | static SOC_ENUM_SINGLE_DECL(in2_enum, |
852 | SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_7, 4, 3, inmux_text); | 852 | WM8996_POWER_MANAGEMENT_7, 4, inmux_text); |
853 | 853 | ||
854 | static const struct snd_kcontrol_new in2_mux = | 854 | static const struct snd_kcontrol_new in2_mux = |
855 | SOC_DAPM_ENUM("IN2 Mux", in2_enum); | 855 | SOC_DAPM_ENUM("IN2 Mux", in2_enum); |
@@ -1608,8 +1608,8 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec, | |||
1608 | msleep(5); | 1608 | msleep(5); |
1609 | } | 1609 | } |
1610 | 1610 | ||
1611 | regcache_cache_only(codec->control_data, false); | 1611 | regcache_cache_only(wm8996->regmap, false); |
1612 | regcache_sync(codec->control_data); | 1612 | regcache_sync(wm8996->regmap); |
1613 | } | 1613 | } |
1614 | 1614 | ||
1615 | /* Bypass the MICBIASes for lowest power */ | 1615 | /* Bypass the MICBIASes for lowest power */ |
@@ -1620,10 +1620,10 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec, | |||
1620 | break; | 1620 | break; |
1621 | 1621 | ||
1622 | case SND_SOC_BIAS_OFF: | 1622 | case SND_SOC_BIAS_OFF: |
1623 | regcache_cache_only(codec->control_data, true); | 1623 | regcache_cache_only(wm8996->regmap, true); |
1624 | if (wm8996->pdata.ldo_ena >= 0) { | 1624 | if (wm8996->pdata.ldo_ena >= 0) { |
1625 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | 1625 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); |
1626 | regcache_cache_only(codec->control_data, true); | 1626 | regcache_cache_only(wm8996->regmap, true); |
1627 | } | 1627 | } |
1628 | regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), | 1628 | regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), |
1629 | wm8996->supplies); | 1629 | wm8996->supplies); |
@@ -2251,6 +2251,7 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
2251 | wm8996_polarity_fn polarity_cb) | 2251 | wm8996_polarity_fn polarity_cb) |
2252 | { | 2252 | { |
2253 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | 2253 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); |
2254 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
2254 | 2255 | ||
2255 | wm8996->jack = jack; | 2256 | wm8996->jack = jack; |
2256 | wm8996->detecting = true; | 2257 | wm8996->detecting = true; |
@@ -2267,8 +2268,12 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
2267 | WM8996_MICB2_DISCH, 0); | 2268 | WM8996_MICB2_DISCH, 0); |
2268 | 2269 | ||
2269 | /* LDO2 powers the microphones, SYSCLK clocks detection */ | 2270 | /* LDO2 powers the microphones, SYSCLK clocks detection */ |
2270 | snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); | 2271 | snd_soc_dapm_mutex_lock(dapm); |
2271 | snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); | 2272 | |
2273 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO2"); | ||
2274 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK"); | ||
2275 | |||
2276 | snd_soc_dapm_mutex_unlock(dapm); | ||
2272 | 2277 | ||
2273 | /* We start off just enabling microphone detection - even a | 2278 | /* We start off just enabling microphone detection - even a |
2274 | * plain headphone will trigger detection. | 2279 | * plain headphone will trigger detection. |
@@ -2595,7 +2600,7 @@ static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec) | |||
2595 | dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", | 2600 | dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", |
2596 | wm8996->num_retune_mobile_texts); | 2601 | wm8996->num_retune_mobile_texts); |
2597 | 2602 | ||
2598 | wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts; | 2603 | wm8996->retune_mobile_enum.items = wm8996->num_retune_mobile_texts; |
2599 | wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts; | 2604 | wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts; |
2600 | 2605 | ||
2601 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); | 2606 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); |
@@ -2628,14 +2633,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
2628 | init_completion(&wm8996->dcs_done); | 2633 | init_completion(&wm8996->dcs_done); |
2629 | init_completion(&wm8996->fll_lock); | 2634 | init_completion(&wm8996->fll_lock); |
2630 | 2635 | ||
2631 | codec->control_data = wm8996->regmap; | ||
2632 | |||
2633 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | ||
2634 | if (ret != 0) { | ||
2635 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
2636 | goto err; | ||
2637 | } | ||
2638 | |||
2639 | if (wm8996->pdata.num_retune_mobile_cfgs) | 2636 | if (wm8996->pdata.num_retune_mobile_cfgs) |
2640 | wm8996_retune_mobile_pdata(codec); | 2637 | wm8996_retune_mobile_pdata(codec); |
2641 | else | 2638 | else |
@@ -2674,13 +2671,11 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
2674 | } else { | 2671 | } else { |
2675 | dev_err(codec->dev, "Failed to request IRQ: %d\n", | 2672 | dev_err(codec->dev, "Failed to request IRQ: %d\n", |
2676 | ret); | 2673 | ret); |
2674 | return ret; | ||
2677 | } | 2675 | } |
2678 | } | 2676 | } |
2679 | 2677 | ||
2680 | return 0; | 2678 | return 0; |
2681 | |||
2682 | err: | ||
2683 | return ret; | ||
2684 | } | 2679 | } |
2685 | 2680 | ||
2686 | static int wm8996_remove(struct snd_soc_codec *codec) | 2681 | static int wm8996_remove(struct snd_soc_codec *codec) |
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 555115ee2159..004186b6bd48 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c | |||
@@ -86,7 +86,7 @@ static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w, | |||
86 | { | 86 | { |
87 | struct snd_soc_codec *codec = w->codec; | 87 | struct snd_soc_codec *codec = w->codec; |
88 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | 88 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); |
89 | struct regmap *regmap = codec->control_data; | 89 | struct regmap *regmap = arizona->regmap; |
90 | const struct reg_default *patch = NULL; | 90 | const struct reg_default *patch = NULL; |
91 | int i, patch_size; | 91 | int i, patch_size; |
92 | 92 | ||
@@ -123,10 +123,12 @@ static const unsigned int wm8997_osr_val[] = { | |||
123 | 123 | ||
124 | static const struct soc_enum wm8997_hpout_osr[] = { | 124 | static const struct soc_enum wm8997_hpout_osr[] = { |
125 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, | 125 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, |
126 | ARIZONA_OUT1_OSR_SHIFT, 0x7, 3, | 126 | ARIZONA_OUT1_OSR_SHIFT, 0x7, |
127 | ARRAY_SIZE(wm8997_osr_text), | ||
127 | wm8997_osr_text, wm8997_osr_val), | 128 | wm8997_osr_text, wm8997_osr_val), |
128 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, | 129 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, |
129 | ARIZONA_OUT3_OSR_SHIFT, 0x7, 3, | 130 | ARIZONA_OUT3_OSR_SHIFT, 0x7, |
131 | ARRAY_SIZE(wm8997_osr_text), | ||
130 | wm8997_osr_text, wm8997_osr_val), | 132 | wm8997_osr_text, wm8997_osr_val), |
131 | }; | 133 | }; |
132 | 134 | ||
@@ -170,15 +172,8 @@ ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), | |||
170 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), | 172 | ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), |
171 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), | 173 | ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), |
172 | 174 | ||
173 | SND_SOC_BYTES_MASK("EQ1 Coefficients", ARIZONA_EQ1_1, 21, | 175 | SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19), |
174 | ARIZONA_EQ1_ENA_MASK), | 176 | SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE, 1, 0), |
175 | SND_SOC_BYTES_MASK("EQ2 Coefficients", ARIZONA_EQ2_1, 21, | ||
176 | ARIZONA_EQ2_ENA_MASK), | ||
177 | SND_SOC_BYTES_MASK("EQ3 Coefficients", ARIZONA_EQ3_1, 21, | ||
178 | ARIZONA_EQ3_ENA_MASK), | ||
179 | SND_SOC_BYTES_MASK("EQ4 Coefficients", ARIZONA_EQ4_1, 21, | ||
180 | ARIZONA_EQ4_ENA_MASK), | ||
181 | |||
182 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, | 177 | SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, |
183 | 24, 0, eq_tlv), | 178 | 24, 0, eq_tlv), |
184 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, | 179 | SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, |
@@ -190,6 +185,8 @@ SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT, | |||
190 | SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, | 185 | SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, |
191 | 24, 0, eq_tlv), | 186 | 24, 0, eq_tlv), |
192 | 187 | ||
188 | SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19), | ||
189 | SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE, 1, 0), | ||
193 | SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, | 190 | SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, |
194 | 24, 0, eq_tlv), | 191 | 24, 0, eq_tlv), |
195 | SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, | 192 | SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, |
@@ -201,6 +198,8 @@ SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT, | |||
201 | SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, | 198 | SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, |
202 | 24, 0, eq_tlv), | 199 | 24, 0, eq_tlv), |
203 | 200 | ||
201 | SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19), | ||
202 | SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE, 1, 0), | ||
204 | SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, | 203 | SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, |
205 | 24, 0, eq_tlv), | 204 | 24, 0, eq_tlv), |
206 | SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, | 205 | SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, |
@@ -212,6 +211,8 @@ SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT, | |||
212 | SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, | 211 | SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, |
213 | 24, 0, eq_tlv), | 212 | 24, 0, eq_tlv), |
214 | 213 | ||
214 | SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19), | ||
215 | SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE, 1, 0), | ||
215 | SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, | 216 | SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, |
216 | 24, 0, eq_tlv), | 217 | 24, 0, eq_tlv), |
217 | SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, | 218 | SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, |
@@ -1052,9 +1053,7 @@ static int wm8997_codec_probe(struct snd_soc_codec *codec) | |||
1052 | struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec); | 1053 | struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec); |
1053 | int ret; | 1054 | int ret; |
1054 | 1055 | ||
1055 | codec->control_data = priv->core.arizona->regmap; | 1056 | ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap); |
1056 | |||
1057 | ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); | ||
1058 | if (ret != 0) | 1057 | if (ret != 0) |
1059 | return ret; | 1058 | return ret; |
1060 | 1059 | ||
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 0982c1d38ec4..d18eff31fbbc 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -268,8 +268,7 @@ static const char *drc_high_text[] = { | |||
268 | "0", | 268 | "0", |
269 | }; | 269 | }; |
270 | 270 | ||
271 | static const struct soc_enum drc_high = | 271 | static SOC_ENUM_SINGLE_DECL(drc_high, WM9081_DRC_3, 3, drc_high_text); |
272 | SOC_ENUM_SINGLE(WM9081_DRC_3, 3, 6, drc_high_text); | ||
273 | 272 | ||
274 | static const char *drc_low_text[] = { | 273 | static const char *drc_low_text[] = { |
275 | "1", | 274 | "1", |
@@ -279,8 +278,7 @@ static const char *drc_low_text[] = { | |||
279 | "0", | 278 | "0", |
280 | }; | 279 | }; |
281 | 280 | ||
282 | static const struct soc_enum drc_low = | 281 | static SOC_ENUM_SINGLE_DECL(drc_low, WM9081_DRC_3, 0, drc_low_text); |
283 | SOC_ENUM_SINGLE(WM9081_DRC_3, 0, 5, drc_low_text); | ||
284 | 282 | ||
285 | static const char *drc_atk_text[] = { | 283 | static const char *drc_atk_text[] = { |
286 | "181us", | 284 | "181us", |
@@ -297,8 +295,7 @@ static const char *drc_atk_text[] = { | |||
297 | "185.6ms", | 295 | "185.6ms", |
298 | }; | 296 | }; |
299 | 297 | ||
300 | static const struct soc_enum drc_atk = | 298 | static SOC_ENUM_SINGLE_DECL(drc_atk, WM9081_DRC_2, 12, drc_atk_text); |
301 | SOC_ENUM_SINGLE(WM9081_DRC_2, 12, 12, drc_atk_text); | ||
302 | 299 | ||
303 | static const char *drc_dcy_text[] = { | 300 | static const char *drc_dcy_text[] = { |
304 | "186ms", | 301 | "186ms", |
@@ -312,8 +309,7 @@ static const char *drc_dcy_text[] = { | |||
312 | "47.56s", | 309 | "47.56s", |
313 | }; | 310 | }; |
314 | 311 | ||
315 | static const struct soc_enum drc_dcy = | 312 | static SOC_ENUM_SINGLE_DECL(drc_dcy, WM9081_DRC_2, 8, drc_dcy_text); |
316 | SOC_ENUM_SINGLE(WM9081_DRC_2, 8, 9, drc_dcy_text); | ||
317 | 313 | ||
318 | static const char *drc_qr_dcy_text[] = { | 314 | static const char *drc_qr_dcy_text[] = { |
319 | "0.725ms", | 315 | "0.725ms", |
@@ -321,8 +317,7 @@ static const char *drc_qr_dcy_text[] = { | |||
321 | "5.8ms", | 317 | "5.8ms", |
322 | }; | 318 | }; |
323 | 319 | ||
324 | static const struct soc_enum drc_qr_dcy = | 320 | static SOC_ENUM_SINGLE_DECL(drc_qr_dcy, WM9081_DRC_2, 4, drc_qr_dcy_text); |
325 | SOC_ENUM_SINGLE(WM9081_DRC_2, 4, 3, drc_qr_dcy_text); | ||
326 | 321 | ||
327 | static const char *dac_deemph_text[] = { | 322 | static const char *dac_deemph_text[] = { |
328 | "None", | 323 | "None", |
@@ -331,16 +326,16 @@ static const char *dac_deemph_text[] = { | |||
331 | "48kHz", | 326 | "48kHz", |
332 | }; | 327 | }; |
333 | 328 | ||
334 | static const struct soc_enum dac_deemph = | 329 | static SOC_ENUM_SINGLE_DECL(dac_deemph, WM9081_DAC_DIGITAL_2, 1, |
335 | SOC_ENUM_SINGLE(WM9081_DAC_DIGITAL_2, 1, 4, dac_deemph_text); | 330 | dac_deemph_text); |
336 | 331 | ||
337 | static const char *speaker_mode_text[] = { | 332 | static const char *speaker_mode_text[] = { |
338 | "Class D", | 333 | "Class D", |
339 | "Class AB", | 334 | "Class AB", |
340 | }; | 335 | }; |
341 | 336 | ||
342 | static const struct soc_enum speaker_mode = | 337 | static SOC_ENUM_SINGLE_DECL(speaker_mode, WM9081_ANALOGUE_SPEAKER_2, 6, |
343 | SOC_ENUM_SINGLE(WM9081_ANALOGUE_SPEAKER_2, 6, 2, speaker_mode_text); | 338 | speaker_mode_text); |
344 | 339 | ||
345 | static int speaker_mode_get(struct snd_kcontrol *kcontrol, | 340 | static int speaker_mode_get(struct snd_kcontrol *kcontrol, |
346 | struct snd_ctl_elem_value *ucontrol) | 341 | struct snd_ctl_elem_value *ucontrol) |
@@ -1265,15 +1260,6 @@ static struct snd_soc_dai_driver wm9081_dai = { | |||
1265 | static int wm9081_probe(struct snd_soc_codec *codec) | 1260 | static int wm9081_probe(struct snd_soc_codec *codec) |
1266 | { | 1261 | { |
1267 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); | 1262 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); |
1268 | int ret; | ||
1269 | |||
1270 | codec->control_data = wm9081->regmap; | ||
1271 | |||
1272 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1273 | if (ret != 0) { | ||
1274 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1275 | return ret; | ||
1276 | } | ||
1277 | 1263 | ||
1278 | /* Enable zero cross by default */ | 1264 | /* Enable zero cross by default */ |
1279 | snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT, | 1265 | snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT, |
@@ -1288,7 +1274,7 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
1288 | ARRAY_SIZE(wm9081_eq_controls)); | 1274 | ARRAY_SIZE(wm9081_eq_controls)); |
1289 | } | 1275 | } |
1290 | 1276 | ||
1291 | return ret; | 1277 | return 0; |
1292 | } | 1278 | } |
1293 | 1279 | ||
1294 | static int wm9081_remove(struct snd_soc_codec *codec) | 1280 | static int wm9081_remove(struct snd_soc_codec *codec) |
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index a07fe1618eec..87934171f063 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c | |||
@@ -522,16 +522,6 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, | |||
522 | 522 | ||
523 | static int wm9090_probe(struct snd_soc_codec *codec) | 523 | static int wm9090_probe(struct snd_soc_codec *codec) |
524 | { | 524 | { |
525 | struct wm9090_priv *wm9090 = dev_get_drvdata(codec->dev); | ||
526 | int ret; | ||
527 | |||
528 | codec->control_data = wm9090->regmap; | ||
529 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
530 | if (ret != 0) { | ||
531 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
532 | return ret; | ||
533 | } | ||
534 | |||
535 | /* Configure some defaults; they will be written out when we | 525 | /* Configure some defaults; they will be written out when we |
536 | * bring the bias up. | 526 | * bring the bias up. |
537 | */ | 527 | */ |
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 70ce6793c5bd..c0b7f45dfa37 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c | |||
@@ -67,12 +67,12 @@ static const char *wm9705_mic[] = {"Mic 1", "Mic 2"}; | |||
67 | static const char *wm9705_rec_sel[] = {"Mic", "CD", "NC", "NC", | 67 | static const char *wm9705_rec_sel[] = {"Mic", "CD", "NC", "NC", |
68 | "Line", "Stereo Mix", "Mono Mix", "Phone"}; | 68 | "Line", "Stereo Mix", "Mono Mix", "Phone"}; |
69 | 69 | ||
70 | static const struct soc_enum wm9705_enum_mic = | 70 | static SOC_ENUM_SINGLE_DECL(wm9705_enum_mic, |
71 | SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, wm9705_mic); | 71 | AC97_GENERAL_PURPOSE, 8, wm9705_mic); |
72 | static const struct soc_enum wm9705_enum_rec_l = | 72 | static SOC_ENUM_SINGLE_DECL(wm9705_enum_rec_l, |
73 | SOC_ENUM_SINGLE(AC97_REC_SEL, 8, 8, wm9705_rec_sel); | 73 | AC97_REC_SEL, 8, wm9705_rec_sel); |
74 | static const struct soc_enum wm9705_enum_rec_r = | 74 | static SOC_ENUM_SINGLE_DECL(wm9705_enum_rec_r, |
75 | SOC_ENUM_SINGLE(AC97_REC_SEL, 0, 8, wm9705_rec_sel); | 75 | AC97_REC_SEL, 0, wm9705_rec_sel); |
76 | 76 | ||
77 | /* Headphone Mixer */ | 77 | /* Headphone Mixer */ |
78 | static const struct snd_kcontrol_new wm9705_hp_mixer_controls[] = { | 78 | static const struct snd_kcontrol_new wm9705_hp_mixer_controls[] = { |
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 444626fcab40..bb5f7b4e3ebb 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -684,24 +684,38 @@ static int wm_adsp_load(struct wm_adsp *dsp) | |||
684 | } | 684 | } |
685 | 685 | ||
686 | if (reg) { | 686 | if (reg) { |
687 | buf = wm_adsp_buf_alloc(region->data, | 687 | size_t to_write = PAGE_SIZE; |
688 | le32_to_cpu(region->len), | 688 | size_t remain = le32_to_cpu(region->len); |
689 | &buf_list); | 689 | const u8 *data = region->data; |
690 | if (!buf) { | 690 | |
691 | adsp_err(dsp, "Out of memory\n"); | 691 | while (remain > 0) { |
692 | ret = -ENOMEM; | 692 | if (remain < PAGE_SIZE) |
693 | goto out_fw; | 693 | to_write = remain; |
694 | } | 694 | |
695 | buf = wm_adsp_buf_alloc(data, | ||
696 | to_write, | ||
697 | &buf_list); | ||
698 | if (!buf) { | ||
699 | adsp_err(dsp, "Out of memory\n"); | ||
700 | ret = -ENOMEM; | ||
701 | goto out_fw; | ||
702 | } | ||
695 | 703 | ||
696 | ret = regmap_raw_write_async(regmap, reg, buf->buf, | 704 | ret = regmap_raw_write_async(regmap, reg, |
697 | le32_to_cpu(region->len)); | 705 | buf->buf, |
698 | if (ret != 0) { | 706 | to_write); |
699 | adsp_err(dsp, | 707 | if (ret != 0) { |
700 | "%s.%d: Failed to write %d bytes at %d in %s: %d\n", | 708 | adsp_err(dsp, |
701 | file, regions, | 709 | "%s.%d: Failed to write %zd bytes at %d in %s: %d\n", |
702 | le32_to_cpu(region->len), offset, | 710 | file, regions, |
703 | region_name, ret); | 711 | to_write, offset, |
704 | goto out_fw; | 712 | region_name, ret); |
713 | goto out_fw; | ||
714 | } | ||
715 | |||
716 | data += to_write; | ||
717 | reg += to_write / 2; | ||
718 | remain -= to_write; | ||
705 | } | 719 | } |
706 | } | 720 | } |
707 | 721 | ||
@@ -1679,6 +1693,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
1679 | list_del(&alg_region->list); | 1693 | list_del(&alg_region->list); |
1680 | kfree(alg_region); | 1694 | kfree(alg_region); |
1681 | } | 1695 | } |
1696 | |||
1697 | adsp_dbg(dsp, "Shutdown complete\n"); | ||
1682 | break; | 1698 | break; |
1683 | 1699 | ||
1684 | default: | 1700 | default: |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index b371066dd5bc..b6209662ab13 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -50,16 +50,16 @@ static const char *speaker_ref_text[] = { | |||
50 | "VMID", | 50 | "VMID", |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static const struct soc_enum speaker_ref = | 53 | static SOC_ENUM_SINGLE_DECL(speaker_ref, |
54 | SOC_ENUM_SINGLE(WM8993_SPEAKER_MIXER, 8, 2, speaker_ref_text); | 54 | WM8993_SPEAKER_MIXER, 8, speaker_ref_text); |
55 | 55 | ||
56 | static const char *speaker_mode_text[] = { | 56 | static const char *speaker_mode_text[] = { |
57 | "Class D", | 57 | "Class D", |
58 | "Class AB", | 58 | "Class AB", |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static const struct soc_enum speaker_mode = | 61 | static SOC_ENUM_SINGLE_DECL(speaker_mode, |
62 | SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text); | 62 | WM8993_SPKMIXR_ATTENUATION, 8, speaker_mode_text); |
63 | 63 | ||
64 | static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op) | 64 | static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op) |
65 | { | 65 | { |
@@ -735,15 +735,15 @@ static const char *hp_mux_text[] = { | |||
735 | "DAC", | 735 | "DAC", |
736 | }; | 736 | }; |
737 | 737 | ||
738 | static const struct soc_enum hpl_enum = | 738 | static SOC_ENUM_SINGLE_DECL(hpl_enum, |
739 | SOC_ENUM_SINGLE(WM8993_OUTPUT_MIXER1, 8, 2, hp_mux_text); | 739 | WM8993_OUTPUT_MIXER1, 8, hp_mux_text); |
740 | 740 | ||
741 | const struct snd_kcontrol_new wm_hubs_hpl_mux = | 741 | const struct snd_kcontrol_new wm_hubs_hpl_mux = |
742 | WM_HUBS_ENUM_W("Left Headphone Mux", hpl_enum); | 742 | WM_HUBS_ENUM_W("Left Headphone Mux", hpl_enum); |
743 | EXPORT_SYMBOL_GPL(wm_hubs_hpl_mux); | 743 | EXPORT_SYMBOL_GPL(wm_hubs_hpl_mux); |
744 | 744 | ||
745 | static const struct soc_enum hpr_enum = | 745 | static SOC_ENUM_SINGLE_DECL(hpr_enum, |
746 | SOC_ENUM_SINGLE(WM8993_OUTPUT_MIXER2, 8, 2, hp_mux_text); | 746 | WM8993_OUTPUT_MIXER2, 8, hp_mux_text); |
747 | 747 | ||
748 | const struct snd_kcontrol_new wm_hubs_hpr_mux = | 748 | const struct snd_kcontrol_new wm_hubs_hpr_mux = |
749 | WM_HUBS_ENUM_W("Right Headphone Mux", hpr_enum); | 749 | WM_HUBS_ENUM_W("Right Headphone Mux", hpr_enum); |