aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-11-26 10:21:07 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-11-27 05:32:13 -0500
commitc4431df050ff124cae7716e301cead1e8f33c575 (patch)
treece6f2adc59834b24ef02040a9eab6ea36b51e6de
parent3a42315740fa80bb4579eb25fedec9d09ff154e7 (diff)
ASoC: Implement support for enhanced AIF3 on WM8958
Additional audio routing options are available on the WM8958 audio interface 3. Add support for these. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r--include/linux/mfd/wm8994/registers.h67
-rw-r--r--sound/soc/codecs/wm8994.c166
2 files changed, 224 insertions, 9 deletions
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h
index 967f62f54159..3eb70a4e7681 100644
--- a/include/linux/mfd/wm8994/registers.h
+++ b/include/linux/mfd/wm8994/registers.h
@@ -109,6 +109,10 @@
109#define WM8994_AIF2DAC_LRCLK 0x315 109#define WM8994_AIF2DAC_LRCLK 0x315
110#define WM8994_AIF2DAC_DATA 0x316 110#define WM8994_AIF2DAC_DATA 0x316
111#define WM8994_AIF2ADC_DATA 0x317 111#define WM8994_AIF2ADC_DATA 0x317
112#define WM8958_AIF3_CONTROL_1 0x320
113#define WM8958_AIF3_CONTROL_2 0x321
114#define WM8958_AIF3DAC_DATA 0x322
115#define WM8958_AIF3ADC_DATA 0x323
112#define WM8994_AIF1_ADC1_LEFT_VOLUME 0x400 116#define WM8994_AIF1_ADC1_LEFT_VOLUME 0x400
113#define WM8994_AIF1_ADC1_RIGHT_VOLUME 0x401 117#define WM8994_AIF1_ADC1_RIGHT_VOLUME 0x401
114#define WM8994_AIF1_DAC1_LEFT_VOLUME 0x402 118#define WM8994_AIF1_DAC1_LEFT_VOLUME 0x402
@@ -992,6 +996,12 @@
992/* 996/*
993 * R6 (0x06) - Power Management (6) 997 * R6 (0x06) - Power Management (6)
994 */ 998 */
999#define WM8958_AIF3ADC_SRC_MASK 0x0600 /* AIF3ADC_SRC - [10:9] */
1000#define WM8958_AIF3ADC_SRC_SHIFT 9 /* AIF3ADC_SRC - [10:9] */
1001#define WM8958_AIF3ADC_SRC_WIDTH 2 /* AIF3ADC_SRC - [10:9] */
1002#define WM8958_AIF2DAC_SRC_MASK 0x0180 /* AIF2DAC_SRC - [8:7] */
1003#define WM8958_AIF2DAC_SRC_SHIFT 7 /* AIF2DAC_SRC - [8:7] */
1004#define WM8958_AIF2DAC_SRC_WIDTH 2 /* AIF2DAC_SRC - [8:7] */
995#define WM8994_AIF3_TRI 0x0020 /* AIF3_TRI */ 1005#define WM8994_AIF3_TRI 0x0020 /* AIF3_TRI */
996#define WM8994_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */ 1006#define WM8994_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */
997#define WM8994_AIF3_TRI_SHIFT 5 /* AIF3_TRI */ 1007#define WM8994_AIF3_TRI_SHIFT 5 /* AIF3_TRI */
@@ -2553,6 +2563,63 @@
2553#define WM8994_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */ 2563#define WM8994_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */
2554 2564
2555/* 2565/*
2566 * R800 (0x320) - AIF3 Control (1)
2567 */
2568#define WM8958_AIF3_LRCLK_INV 0x0080 /* AIF3_LRCLK_INV */
2569#define WM8958_AIF3_LRCLK_INV_MASK 0x0080 /* AIF3_LRCLK_INV */
2570#define WM8958_AIF3_LRCLK_INV_SHIFT 7 /* AIF3_LRCLK_INV */
2571#define WM8958_AIF3_LRCLK_INV_WIDTH 1 /* AIF3_LRCLK_INV */
2572#define WM8958_AIF3_WL_MASK 0x0060 /* AIF3_WL - [6:5] */
2573#define WM8958_AIF3_WL_SHIFT 5 /* AIF3_WL - [6:5] */
2574#define WM8958_AIF3_WL_WIDTH 2 /* AIF3_WL - [6:5] */
2575#define WM8958_AIF3_FMT_MASK 0x0018 /* AIF3_FMT - [4:3] */
2576#define WM8958_AIF3_FMT_SHIFT 3 /* AIF3_FMT - [4:3] */
2577#define WM8958_AIF3_FMT_WIDTH 2 /* AIF3_FMT - [4:3] */
2578
2579/*
2580 * R801 (0x321) - AIF3 Control (2)
2581 */
2582#define WM8958_AIF3DAC_BOOST_MASK 0x0C00 /* AIF3DAC_BOOST - [11:10] */
2583#define WM8958_AIF3DAC_BOOST_SHIFT 10 /* AIF3DAC_BOOST - [11:10] */
2584#define WM8958_AIF3DAC_BOOST_WIDTH 2 /* AIF3DAC_BOOST - [11:10] */
2585#define WM8958_AIF3DAC_COMP 0x0010 /* AIF3DAC_COMP */
2586#define WM8958_AIF3DAC_COMP_MASK 0x0010 /* AIF3DAC_COMP */
2587#define WM8958_AIF3DAC_COMP_SHIFT 4 /* AIF3DAC_COMP */
2588#define WM8958_AIF3DAC_COMP_WIDTH 1 /* AIF3DAC_COMP */
2589#define WM8958_AIF3DAC_COMPMODE 0x0008 /* AIF3DAC_COMPMODE */
2590#define WM8958_AIF3DAC_COMPMODE_MASK 0x0008 /* AIF3DAC_COMPMODE */
2591#define WM8958_AIF3DAC_COMPMODE_SHIFT 3 /* AIF3DAC_COMPMODE */
2592#define WM8958_AIF3DAC_COMPMODE_WIDTH 1 /* AIF3DAC_COMPMODE */
2593#define WM8958_AIF3ADC_COMP 0x0004 /* AIF3ADC_COMP */
2594#define WM8958_AIF3ADC_COMP_MASK 0x0004 /* AIF3ADC_COMP */
2595#define WM8958_AIF3ADC_COMP_SHIFT 2 /* AIF3ADC_COMP */
2596#define WM8958_AIF3ADC_COMP_WIDTH 1 /* AIF3ADC_COMP */
2597#define WM8958_AIF3ADC_COMPMODE 0x0002 /* AIF3ADC_COMPMODE */
2598#define WM8958_AIF3ADC_COMPMODE_MASK 0x0002 /* AIF3ADC_COMPMODE */
2599#define WM8958_AIF3ADC_COMPMODE_SHIFT 1 /* AIF3ADC_COMPMODE */
2600#define WM8958_AIF3ADC_COMPMODE_WIDTH 1 /* AIF3ADC_COMPMODE */
2601#define WM8958_AIF3_LOOPBACK 0x0001 /* AIF3_LOOPBACK */
2602#define WM8958_AIF3_LOOPBACK_MASK 0x0001 /* AIF3_LOOPBACK */
2603#define WM8958_AIF3_LOOPBACK_SHIFT 0 /* AIF3_LOOPBACK */
2604#define WM8958_AIF3_LOOPBACK_WIDTH 1 /* AIF3_LOOPBACK */
2605
2606/*
2607 * R802 (0x322) - AIF3DAC Data
2608 */
2609#define WM8958_AIF3DAC_DAT_INV 0x0001 /* AIF3DAC_DAT_INV */
2610#define WM8958_AIF3DAC_DAT_INV_MASK 0x0001 /* AIF3DAC_DAT_INV */
2611#define WM8958_AIF3DAC_DAT_INV_SHIFT 0 /* AIF3DAC_DAT_INV */
2612#define WM8958_AIF3DAC_DAT_INV_WIDTH 1 /* AIF3DAC_DAT_INV */
2613
2614/*
2615 * R803 (0x323) - AIF3ADC Data
2616 */
2617#define WM8958_AIF3ADC_DAT_INV 0x0001 /* AIF3ADC_DAT_INV */
2618#define WM8958_AIF3ADC_DAT_INV_MASK 0x0001 /* AIF3ADC_DAT_INV */
2619#define WM8958_AIF3ADC_DAT_INV_SHIFT 0 /* AIF3ADC_DAT_INV */
2620#define WM8958_AIF3ADC_DAT_INV_WIDTH 1 /* AIF3ADC_DAT_INV */
2621
2622/*
2556 * R1024 (0x400) - AIF1 ADC1 Left Volume 2623 * R1024 (0x400) - AIF1 ADC1 Left Volume
2557 */ 2624 */
2558#define WM8994_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */ 2625#define WM8994_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 8232d5e73194..fb0609315cd6 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -647,6 +647,10 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
647 eq_tlv), 647 eq_tlv),
648}; 648};
649 649
650static const struct snd_kcontrol_new wm8958_snd_controls[] = {
651SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
652};
653
650static int clk_sys_event(struct snd_soc_dapm_widget *w, 654static int clk_sys_event(struct snd_soc_dapm_widget *w,
651 struct snd_kcontrol *kcontrol, int event) 655 struct snd_kcontrol *kcontrol, int event)
652{ 656{
@@ -953,14 +957,47 @@ static const struct snd_kcontrol_new aif2adc_mux =
953 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); 957 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
954 958
955static const char *aif3adc_text[] = { 959static const char *aif3adc_text[] = {
956 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", 960 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM",
957}; 961};
958 962
959static const struct soc_enum aif3adc_enum = 963static const struct soc_enum wm8994_aif3adc_enum =
960 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text); 964 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
961 965
962static const struct snd_kcontrol_new aif3adc_mux = 966static const struct snd_kcontrol_new wm8994_aif3adc_mux =
963 SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum); 967 SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum);
968
969static const struct soc_enum wm8958_aif3adc_enum =
970 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text);
971
972static const struct snd_kcontrol_new wm8958_aif3adc_mux =
973 SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum);
974
975static const char *mono_pcm_out_text[] = {
976 "None", "AIF2ADCL", "AIF2ADCR",
977};
978
979static const struct soc_enum mono_pcm_out_enum =
980 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text);
981
982static const struct snd_kcontrol_new mono_pcm_out_mux =
983 SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum);
984
985static const char *aif2dac_src_text[] = {
986 "AIF2", "AIF3",
987};
988
989/* Note that these two control shouldn't be simultaneously switched to AIF3 */
990static const struct soc_enum aif2dacl_src_enum =
991 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text);
992
993static const struct snd_kcontrol_new aif2dacl_src_mux =
994 SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum);
995
996static const struct soc_enum aif2dacr_src_enum =
997 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text);
998
999static const struct snd_kcontrol_new aif2dacr_src_mux =
1000 SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);
964 1001
965static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { 1002static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
966SND_SOC_DAPM_INPUT("DMIC1DAT"), 1003SND_SOC_DAPM_INPUT("DMIC1DAT"),
@@ -1034,7 +1071,6 @@ SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
1034SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), 1071SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
1035SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux), 1072SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
1036SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), 1073SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
1037SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux),
1038 1074
1039SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), 1075SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
1040SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), 1076SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
@@ -1072,8 +1108,18 @@ SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
1072SND_SOC_DAPM_POST("Debug log", post_ev), 1108SND_SOC_DAPM_POST("Debug log", post_ev),
1073}; 1109};
1074 1110
1075static const struct snd_soc_dapm_route intercon[] = { 1111static const struct snd_soc_dapm_widget wm8994_specific_dapm_widgets[] = {
1112SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8994_aif3adc_mux),
1113};
1076 1114
1115static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = {
1116SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux),
1117SND_SOC_DAPM_MUX("AIF2DACL Mux", SND_SOC_NOPM, 0, 0, &aif2dacl_src_mux),
1118SND_SOC_DAPM_MUX("AIF2DACR Mux", SND_SOC_NOPM, 0, 0, &aif2dacr_src_mux),
1119SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8958_aif3adc_mux),
1120};
1121
1122static const struct snd_soc_dapm_route intercon[] = {
1077 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys }, 1123 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
1078 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys }, 1124 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
1079 1125
@@ -1181,9 +1227,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1181 { "AIF1DAC2L", NULL, "AIF1DAC Mux" }, 1227 { "AIF1DAC2L", NULL, "AIF1DAC Mux" },
1182 { "AIF1DAC2R", NULL, "AIF1DAC Mux" }, 1228 { "AIF1DAC2R", NULL, "AIF1DAC Mux" },
1183 1229
1184 { "AIF2DACL", NULL, "AIF2DAC Mux" },
1185 { "AIF2DACR", NULL, "AIF2DAC Mux" },
1186
1187 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" }, 1230 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" },
1188 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" }, 1231 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
1189 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" }, 1232 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" },
@@ -1256,6 +1299,26 @@ static const struct snd_soc_dapm_route intercon[] = {
1256 { "Right Headphone Mux", "DAC", "DAC1R" }, 1299 { "Right Headphone Mux", "DAC", "DAC1R" },
1257}; 1300};
1258 1301
1302static const struct snd_soc_dapm_route wm8994_intercon[] = {
1303 { "AIF2DACL", NULL, "AIF2DAC Mux" },
1304 { "AIF2DACR", NULL, "AIF2DAC Mux" },
1305};
1306
1307static const struct snd_soc_dapm_route wm8958_intercon[] = {
1308 { "AIF2DACL", NULL, "AIF2DACL Mux" },
1309 { "AIF2DACR", NULL, "AIF2DACR Mux" },
1310
1311 { "AIF2DACL Mux", "AIF2", "AIF2DAC Mux" },
1312 { "AIF2DACL Mux", "AIF3", "AIF3DACDAT" },
1313 { "AIF2DACR Mux", "AIF2", "AIF2DAC Mux" },
1314 { "AIF2DACR Mux", "AIF3", "AIF3DACDAT" },
1315
1316 { "Mono PCM Out Mux", "AIF2ADCL", "AIF2ADCL" },
1317 { "Mono PCM Out Mux", "AIF2ADCR", "AIF2ADCR" },
1318
1319 { "AIF3ADC Mux", "Mono PCM", "Mono PCM Out Mux" },
1320};
1321
1259/* The size in bits of the FLL divide multiplied by 10 1322/* The size in bits of the FLL divide multiplied by 10
1260 * to allow rounding later */ 1323 * to allow rounding later */
1261#define FIXED_FLL_SIZE ((1 << 16) * 10) 1324#define FIXED_FLL_SIZE ((1 << 16) * 10)
@@ -1635,6 +1698,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
1635static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 1698static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1636{ 1699{
1637 struct snd_soc_codec *codec = dai->codec; 1700 struct snd_soc_codec *codec = dai->codec;
1701 struct wm8994 *control = codec->control_data;
1638 int ms_reg; 1702 int ms_reg;
1639 int aif1_reg; 1703 int aif1_reg;
1640 int ms = 0; 1704 int ms = 0;
@@ -1719,6 +1783,13 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1719 return -EINVAL; 1783 return -EINVAL;
1720 } 1784 }
1721 1785
1786 /* The AIF2 format configuration needs to be mirrored to AIF3
1787 * on WM8958 if it's in use so just do it all the time. */
1788 if (control->type == WM8958 && dai->id == 2)
1789 snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1,
1790 WM8994_AIF1_LRCLK_INV |
1791 WM8958_AIF3_FMT_MASK, aif1);
1792
1722 snd_soc_update_bits(codec, aif1_reg, 1793 snd_soc_update_bits(codec, aif1_reg,
1723 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV | 1794 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
1724 WM8994_AIF1_FMT_MASK, 1795 WM8994_AIF1_FMT_MASK,
@@ -1759,6 +1830,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
1759 struct snd_soc_dai *dai) 1830 struct snd_soc_dai *dai)
1760{ 1831{
1761 struct snd_soc_codec *codec = dai->codec; 1832 struct snd_soc_codec *codec = dai->codec;
1833 struct wm8994 *control = codec->control_data;
1762 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 1834 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1763 int aif1_reg; 1835 int aif1_reg;
1764 int bclk_reg; 1836 int bclk_reg;
@@ -1797,6 +1869,14 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
1797 dev_dbg(codec->dev, "AIF2 using split LRCLK\n"); 1869 dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
1798 } 1870 }
1799 break; 1871 break;
1872 case 3:
1873 switch (control->type) {
1874 case WM8958:
1875 aif1_reg = WM8958_AIF3_CONTROL_1;
1876 break;
1877 default:
1878 return 0;
1879 }
1800 default: 1880 default:
1801 return -EINVAL; 1881 return -EINVAL;
1802 } 1882 }
@@ -1900,6 +1980,47 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
1900 return 0; 1980 return 0;
1901} 1981}
1902 1982
1983static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
1984 struct snd_pcm_hw_params *params,
1985 struct snd_soc_dai *dai)
1986{
1987 struct snd_soc_codec *codec = dai->codec;
1988 struct wm8994 *control = codec->control_data;
1989 int aif1_reg;
1990 int aif1 = 0;
1991
1992 switch (dai->id) {
1993 case 3:
1994 switch (control->type) {
1995 case WM8958:
1996 aif1_reg = WM8958_AIF3_CONTROL_1;
1997 break;
1998 default:
1999 return 0;
2000 }
2001 default:
2002 return 0;
2003 }
2004
2005 switch (params_format(params)) {
2006 case SNDRV_PCM_FORMAT_S16_LE:
2007 break;
2008 case SNDRV_PCM_FORMAT_S20_3LE:
2009 aif1 |= 0x20;
2010 break;
2011 case SNDRV_PCM_FORMAT_S24_LE:
2012 aif1 |= 0x40;
2013 break;
2014 case SNDRV_PCM_FORMAT_S32_LE:
2015 aif1 |= 0x60;
2016 break;
2017 default:
2018 return -EINVAL;
2019 }
2020
2021 return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
2022}
2023
1903static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) 2024static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
1904{ 2025{
1905 struct snd_soc_codec *codec = codec_dai->codec; 2026 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1981,6 +2102,7 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
1981}; 2102};
1982 2103
1983static struct snd_soc_dai_ops wm8994_aif3_dai_ops = { 2104static struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
2105 .hw_params = wm8994_aif3_hw_params,
1984 .set_tristate = wm8994_set_tristate, 2106 .set_tristate = wm8994_set_tristate,
1985}; 2107};
1986 2108
@@ -2511,9 +2633,35 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2511 ARRAY_SIZE(wm8994_snd_controls)); 2633 ARRAY_SIZE(wm8994_snd_controls));
2512 snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, 2634 snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
2513 ARRAY_SIZE(wm8994_dapm_widgets)); 2635 ARRAY_SIZE(wm8994_dapm_widgets));
2636
2637 switch (control->type) {
2638 case WM8994:
2639 snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets,
2640 ARRAY_SIZE(wm8994_specific_dapm_widgets));
2641 break;
2642 case WM8958:
2643 snd_soc_add_controls(codec, wm8958_snd_controls,
2644 ARRAY_SIZE(wm8958_snd_controls));
2645 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
2646 ARRAY_SIZE(wm8958_dapm_widgets));
2647 break;
2648 }
2649
2650
2514 wm_hubs_add_analogue_routes(codec, 0, 0); 2651 wm_hubs_add_analogue_routes(codec, 0, 0);
2515 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); 2652 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
2516 2653
2654 switch (control->type) {
2655 case WM8994:
2656 snd_soc_dapm_add_routes(dapm, wm8994_intercon,
2657 ARRAY_SIZE(wm8994_intercon));
2658 break;
2659 case WM8958:
2660 snd_soc_dapm_add_routes(dapm, wm8958_intercon,
2661 ARRAY_SIZE(wm8958_intercon));
2662 break;
2663 }
2664
2517 return 0; 2665 return 0;
2518 2666
2519err_irq: 2667err_irq: