aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/arizona.c530
-rw-r--r--sound/soc/codecs/arizona.h34
-rw-r--r--sound/soc/codecs/wm2200.c2
-rw-r--r--sound/soc/codecs/wm5102.c129
-rw-r--r--sound/soc/codecs/wm5102.h6
-rw-r--r--sound/soc/codecs/wm5110.c54
-rw-r--r--sound/soc/codecs/wm5110.h6
-rw-r--r--sound/soc/codecs/wm_adsp.c40
-rw-r--r--sound/soc/codecs/wm_adsp.h3
9 files changed, 631 insertions, 173 deletions
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index ac948a671ea6..389f23253831 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -10,6 +10,7 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/delay.h>
13#include <linux/gcd.h> 14#include <linux/gcd.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/pm_runtime.h> 16#include <linux/pm_runtime.h>
@@ -65,6 +66,163 @@
65#define arizona_aif_dbg(_dai, fmt, ...) \ 66#define arizona_aif_dbg(_dai, fmt, ...) \
66 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 67 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
67 68
69static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
70 struct snd_kcontrol *kcontrol,
71 int event)
72{
73 struct snd_soc_codec *codec = w->codec;
74 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
75 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
76 bool manual_ena = false;
77 int val;
78
79 switch (arizona->type) {
80 case WM5102:
81 switch (arizona->rev) {
82 case 0:
83 break;
84 default:
85 manual_ena = true;
86 break;
87 }
88 default:
89 break;
90 }
91
92 switch (event) {
93 case SND_SOC_DAPM_PRE_PMU:
94 if (!priv->spk_ena && manual_ena) {
95 snd_soc_write(codec, 0x4f5, 0x25a);
96 priv->spk_ena_pending = true;
97 }
98 break;
99 case SND_SOC_DAPM_POST_PMU:
100 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
101 if (val & ARIZONA_SPK_SHUTDOWN_STS) {
102 dev_crit(arizona->dev,
103 "Speaker not enabled due to temperature\n");
104 return -EBUSY;
105 }
106
107 snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
108 1 << w->shift, 1 << w->shift);
109
110 if (priv->spk_ena_pending) {
111 msleep(75);
112 snd_soc_write(codec, 0x4f5, 0xda);
113 priv->spk_ena_pending = false;
114 priv->spk_ena++;
115 }
116 break;
117 case SND_SOC_DAPM_PRE_PMD:
118 if (manual_ena) {
119 priv->spk_ena--;
120 if (!priv->spk_ena)
121 snd_soc_write(codec, 0x4f5, 0x25a);
122 }
123
124 snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
125 1 << w->shift, 0);
126 break;
127 case SND_SOC_DAPM_POST_PMD:
128 if (manual_ena) {
129 if (!priv->spk_ena)
130 snd_soc_write(codec, 0x4f5, 0x0da);
131 }
132 break;
133 }
134
135 return 0;
136}
137
138static irqreturn_t arizona_thermal_warn(int irq, void *data)
139{
140 struct arizona *arizona = data;
141 unsigned int val;
142 int ret;
143
144 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
145 &val);
146 if (ret != 0) {
147 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
148 ret);
149 } else if (val & ARIZONA_SPK_SHUTDOWN_WARN_STS) {
150 dev_crit(arizona->dev, "Thermal warning\n");
151 }
152
153 return IRQ_HANDLED;
154}
155
156static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
157{
158 struct arizona *arizona = data;
159 unsigned int val;
160 int ret;
161
162 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
163 &val);
164 if (ret != 0) {
165 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
166 ret);
167 } else if (val & ARIZONA_SPK_SHUTDOWN_STS) {
168 dev_crit(arizona->dev, "Thermal shutdown\n");
169 ret = regmap_update_bits(arizona->regmap,
170 ARIZONA_OUTPUT_ENABLES_1,
171 ARIZONA_OUT4L_ENA |
172 ARIZONA_OUT4R_ENA, 0);
173 if (ret != 0)
174 dev_crit(arizona->dev,
175 "Failed to disable speaker outputs: %d\n",
176 ret);
177 }
178
179 return IRQ_HANDLED;
180}
181
182static const struct snd_soc_dapm_widget arizona_spkl =
183 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
184 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
185 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
186
187static const struct snd_soc_dapm_widget arizona_spkr =
188 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
189 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
190 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
191
192int arizona_init_spk(struct snd_soc_codec *codec)
193{
194 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
195 struct arizona *arizona = priv->arizona;
196 int ret;
197
198 ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1);
199 if (ret != 0)
200 return ret;
201
202 ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkr, 1);
203 if (ret != 0)
204 return ret;
205
206 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN,
207 "Thermal warning", arizona_thermal_warn,
208 arizona);
209 if (ret != 0)
210 dev_err(arizona->dev,
211 "Failed to get thermal warning IRQ: %d\n",
212 ret);
213
214 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN,
215 "Thermal shutdown", arizona_thermal_shutdown,
216 arizona);
217 if (ret != 0)
218 dev_err(arizona->dev,
219 "Failed to get thermal shutdown IRQ: %d\n",
220 ret);
221
222 return 0;
223}
224EXPORT_SYMBOL_GPL(arizona_init_spk);
225
68const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { 226const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
69 "None", 227 "None",
70 "Tone Generator 1", 228 "Tone Generator 1",
@@ -274,6 +432,33 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values);
274const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); 432const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
275EXPORT_SYMBOL_GPL(arizona_mixer_tlv); 433EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
276 434
435const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
436 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
437};
438EXPORT_SYMBOL_GPL(arizona_rate_text);
439
440const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
441 0, 1, 2, 8,
442};
443EXPORT_SYMBOL_GPL(arizona_rate_val);
444
445
446const struct soc_enum arizona_isrc_fsl[] = {
447 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
448 ARIZONA_ISRC1_FSL_SHIFT, 0xf,
449 ARIZONA_RATE_ENUM_SIZE,
450 arizona_rate_text, arizona_rate_val),
451 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
452 ARIZONA_ISRC2_FSL_SHIFT, 0xf,
453 ARIZONA_RATE_ENUM_SIZE,
454 arizona_rate_text, arizona_rate_val),
455 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
456 ARIZONA_ISRC3_FSL_SHIFT, 0xf,
457 ARIZONA_RATE_ENUM_SIZE,
458 arizona_rate_text, arizona_rate_val),
459};
460EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
461
277static const char *arizona_vol_ramp_text[] = { 462static const char *arizona_vol_ramp_text[] = {
278 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", 463 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
279 "15ms/6dB", "30ms/6dB", 464 "15ms/6dB", "30ms/6dB",
@@ -332,9 +517,27 @@ const struct soc_enum arizona_ng_hold =
332 4, arizona_ng_hold_text); 517 4, arizona_ng_hold_text);
333EXPORT_SYMBOL_GPL(arizona_ng_hold); 518EXPORT_SYMBOL_GPL(arizona_ng_hold);
334 519
520static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
521{
522 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
523 unsigned int val;
524 int i;
525
526 if (ena)
527 val = ARIZONA_IN_VU;
528 else
529 val = 0;
530
531 for (i = 0; i < priv->num_inputs; i++)
532 snd_soc_update_bits(codec,
533 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
534 ARIZONA_IN_VU, val);
535}
536
335int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 537int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
336 int event) 538 int event)
337{ 539{
540 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
338 unsigned int reg; 541 unsigned int reg;
339 542
340 if (w->shift % 2) 543 if (w->shift % 2)
@@ -343,13 +546,29 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
343 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8); 546 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
344 547
345 switch (event) { 548 switch (event) {
549 case SND_SOC_DAPM_PRE_PMU:
550 priv->in_pending++;
551 break;
346 case SND_SOC_DAPM_POST_PMU: 552 case SND_SOC_DAPM_POST_PMU:
347 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); 553 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
554
555 /* If this is the last input pending then allow VU */
556 priv->in_pending--;
557 if (priv->in_pending == 0) {
558 msleep(1);
559 arizona_in_set_vu(w->codec, 1);
560 }
348 break; 561 break;
349 case SND_SOC_DAPM_PRE_PMD: 562 case SND_SOC_DAPM_PRE_PMD:
350 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 563 snd_soc_update_bits(w->codec, reg,
351 ARIZONA_IN1L_MUTE); 564 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
565 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
352 break; 566 break;
567 case SND_SOC_DAPM_POST_PMD:
568 /* Disable volume updates if no inputs are enabled */
569 reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
570 if (reg == 0)
571 arizona_in_set_vu(w->codec, 0);
353 } 572 }
354 573
355 return 0; 574 return 0;
@@ -360,10 +579,61 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
360 struct snd_kcontrol *kcontrol, 579 struct snd_kcontrol *kcontrol,
361 int event) 580 int event)
362{ 581{
582 switch (event) {
583 case SND_SOC_DAPM_POST_PMU:
584 switch (w->shift) {
585 case ARIZONA_OUT1L_ENA_SHIFT:
586 case ARIZONA_OUT1R_ENA_SHIFT:
587 case ARIZONA_OUT2L_ENA_SHIFT:
588 case ARIZONA_OUT2R_ENA_SHIFT:
589 case ARIZONA_OUT3L_ENA_SHIFT:
590 case ARIZONA_OUT3R_ENA_SHIFT:
591 msleep(17);
592 break;
593
594 default:
595 break;
596 }
597 break;
598 }
599
363 return 0; 600 return 0;
364} 601}
365EXPORT_SYMBOL_GPL(arizona_out_ev); 602EXPORT_SYMBOL_GPL(arizona_out_ev);
366 603
604int arizona_hp_ev(struct snd_soc_dapm_widget *w,
605 struct snd_kcontrol *kcontrol,
606 int event)
607{
608 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
609 unsigned int mask = 1 << w->shift;
610 unsigned int val;
611
612 switch (event) {
613 case SND_SOC_DAPM_POST_PMU:
614 val = mask;
615 break;
616 case SND_SOC_DAPM_PRE_PMD:
617 val = 0;
618 break;
619 default:
620 return -EINVAL;
621 }
622
623 /* Store the desired state for the HP outputs */
624 priv->arizona->hp_ena &= ~mask;
625 priv->arizona->hp_ena |= val;
626
627 /* Force off if HPDET magic is active */
628 if (priv->arizona->hpdet_magic)
629 val = 0;
630
631 snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val);
632
633 return arizona_out_ev(w, kcontrol, event);
634}
635EXPORT_SYMBOL_GPL(arizona_hp_ev);
636
367static unsigned int arizona_sysclk_48k_rates[] = { 637static unsigned int arizona_sysclk_48k_rates[] = {
368 6144000, 638 6144000,
369 12288000, 639 12288000,
@@ -469,27 +739,27 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
469 break; 739 break;
470 case 11289600: 740 case 11289600:
471 case 12288000: 741 case 12288000:
472 val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT; 742 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
473 break; 743 break;
474 case 22579200: 744 case 22579200:
475 case 24576000: 745 case 24576000:
476 val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT; 746 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
477 break; 747 break;
478 case 45158400: 748 case 45158400:
479 case 49152000: 749 case 49152000:
480 val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; 750 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
481 break; 751 break;
482 case 67737600: 752 case 67737600:
483 case 73728000: 753 case 73728000:
484 val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT; 754 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
485 break; 755 break;
486 case 90316800: 756 case 90316800:
487 case 98304000: 757 case 98304000:
488 val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; 758 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
489 break; 759 break;
490 case 135475200: 760 case 135475200:
491 case 147456000: 761 case 147456000:
492 val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; 762 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
493 break; 763 break;
494 case 0: 764 case 0:
495 dev_dbg(arizona->dev, "%s cleared\n", name); 765 dev_dbg(arizona->dev, "%s cleared\n", name);
@@ -783,7 +1053,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
783 struct arizona *arizona = priv->arizona; 1053 struct arizona *arizona = priv->arizona;
784 int base = dai->driver->base; 1054 int base = dai->driver->base;
785 const int *rates; 1055 const int *rates;
786 int i, ret; 1056 int i, ret, val;
787 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; 1057 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
788 int bclk, lrclk, wl, frame, bclk_target; 1058 int bclk, lrclk, wl, frame, bclk_target;
789 1059
@@ -799,6 +1069,13 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
799 bclk_target *= chan_limit; 1069 bclk_target *= chan_limit;
800 } 1070 }
801 1071
1072 /* Force stereo for I2S mode */
1073 val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
1074 if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) {
1075 arizona_aif_dbg(dai, "Forcing stereo mode\n");
1076 bclk_target *= 2;
1077 }
1078
802 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { 1079 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
803 if (rates[i] >= bclk_target && 1080 if (rates[i] >= bclk_target &&
804 rates[i] % params_rate(params) == 0) { 1081 rates[i] % params_rate(params) == 0) {
@@ -955,6 +1232,16 @@ static struct {
955 { 1000000, 13500000, 0, 1 }, 1232 { 1000000, 13500000, 0, 1 },
956}; 1233};
957 1234
1235static struct {
1236 unsigned int min;
1237 unsigned int max;
1238 u16 gain;
1239} fll_gains[] = {
1240 { 0, 256000, 0 },
1241 { 256000, 1000000, 2 },
1242 { 1000000, 13500000, 4 },
1243};
1244
958struct arizona_fll_cfg { 1245struct arizona_fll_cfg {
959 int n; 1246 int n;
960 int theta; 1247 int theta;
@@ -962,6 +1249,7 @@ struct arizona_fll_cfg {
962 int refdiv; 1249 int refdiv;
963 int outdiv; 1250 int outdiv;
964 int fratio; 1251 int fratio;
1252 int gain;
965}; 1253};
966 1254
967static int arizona_calc_fll(struct arizona_fll *fll, 1255static int arizona_calc_fll(struct arizona_fll *fll,
@@ -1021,6 +1309,18 @@ static int arizona_calc_fll(struct arizona_fll *fll,
1021 return -EINVAL; 1309 return -EINVAL;
1022 } 1310 }
1023 1311
1312 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
1313 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
1314 cfg->gain = fll_gains[i].gain;
1315 break;
1316 }
1317 }
1318 if (i == ARRAY_SIZE(fll_gains)) {
1319 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1320 Fref);
1321 return -EINVAL;
1322 }
1323
1024 cfg->n = target / (ratio * Fref); 1324 cfg->n = target / (ratio * Fref);
1025 1325
1026 if (target % (ratio * Fref)) { 1326 if (target % (ratio * Fref)) {
@@ -1048,13 +1348,15 @@ static int arizona_calc_fll(struct arizona_fll *fll,
1048 cfg->n, cfg->theta, cfg->lambda); 1348 cfg->n, cfg->theta, cfg->lambda);
1049 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", 1349 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
1050 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); 1350 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
1351 arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);
1051 1352
1052 return 0; 1353 return 0;
1053 1354
1054} 1355}
1055 1356
1056static void arizona_apply_fll(struct arizona *arizona, unsigned int base, 1357static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1057 struct arizona_fll_cfg *cfg, int source) 1358 struct arizona_fll_cfg *cfg, int source,
1359 bool sync)
1058{ 1360{
1059 regmap_update_bits(arizona->regmap, base + 3, 1361 regmap_update_bits(arizona->regmap, base + 3,
1060 ARIZONA_FLL1_THETA_MASK, cfg->theta); 1362 ARIZONA_FLL1_THETA_MASK, cfg->theta);
@@ -1069,87 +1371,84 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1069 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | 1371 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1070 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); 1372 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1071 1373
1374 if (sync)
1375 regmap_update_bits(arizona->regmap, base + 0x7,
1376 ARIZONA_FLL1_GAIN_MASK,
1377 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1378 else
1379 regmap_update_bits(arizona->regmap, base + 0x9,
1380 ARIZONA_FLL1_GAIN_MASK,
1381 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1382
1072 regmap_update_bits(arizona->regmap, base + 2, 1383 regmap_update_bits(arizona->regmap, base + 2,
1073 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, 1384 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
1074 ARIZONA_FLL1_CTRL_UPD | cfg->n); 1385 ARIZONA_FLL1_CTRL_UPD | cfg->n);
1075} 1386}
1076 1387
1077int arizona_set_fll(struct arizona_fll *fll, int source, 1388static bool arizona_is_enabled_fll(struct arizona_fll *fll)
1078 unsigned int Fref, unsigned int Fout)
1079{ 1389{
1080 struct arizona *arizona = fll->arizona; 1390 struct arizona *arizona = fll->arizona;
1081 struct arizona_fll_cfg cfg, sync; 1391 unsigned int reg;
1082 unsigned int reg, val;
1083 int syncsrc;
1084 bool ena;
1085 int ret; 1392 int ret;
1086 1393
1087 if (fll->fref == Fref && fll->fout == Fout)
1088 return 0;
1089
1090 ret = regmap_read(arizona->regmap, fll->base + 1, &reg); 1394 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1091 if (ret != 0) { 1395 if (ret != 0) {
1092 arizona_fll_err(fll, "Failed to read current state: %d\n", 1396 arizona_fll_err(fll, "Failed to read current state: %d\n",
1093 ret); 1397 ret);
1094 return ret; 1398 return ret;
1095 } 1399 }
1096 ena = reg & ARIZONA_FLL1_ENA;
1097 1400
1098 if (Fout) { 1401 return reg & ARIZONA_FLL1_ENA;
1099 /* Do we have a 32kHz reference? */ 1402}
1100 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1101 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1102 case ARIZONA_CLK_SRC_MCLK1:
1103 case ARIZONA_CLK_SRC_MCLK2:
1104 syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
1105 break;
1106 default:
1107 syncsrc = -1;
1108 }
1109 1403
1110 if (source == syncsrc) 1404static void arizona_enable_fll(struct arizona_fll *fll,
1111 syncsrc = -1; 1405 struct arizona_fll_cfg *ref,
1406 struct arizona_fll_cfg *sync)
1407{
1408 struct arizona *arizona = fll->arizona;
1409 int ret;
1112 1410
1113 if (syncsrc >= 0) { 1411 /*
1114 ret = arizona_calc_fll(fll, &sync, Fref, Fout); 1412 * If we have both REFCLK and SYNCCLK then enable both,
1115 if (ret != 0) 1413 * otherwise apply the SYNCCLK settings to REFCLK.
1116 return ret; 1414 */
1415 if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) {
1416 regmap_update_bits(arizona->regmap, fll->base + 5,
1417 ARIZONA_FLL1_OUTDIV_MASK,
1418 ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1419
1420 arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
1421 false);
1422 if (fll->sync_src >= 0)
1423 arizona_apply_fll(arizona, fll->base + 0x10, sync,
1424 fll->sync_src, true);
1425 } else if (fll->sync_src >= 0) {
1426 regmap_update_bits(arizona->regmap, fll->base + 5,
1427 ARIZONA_FLL1_OUTDIV_MASK,
1428 sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1429
1430 arizona_apply_fll(arizona, fll->base, sync,
1431 fll->sync_src, false);
1117 1432
1118 ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
1119 if (ret != 0)
1120 return ret;
1121 } else {
1122 ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
1123 if (ret != 0)
1124 return ret;
1125 }
1126 } else {
1127 regmap_update_bits(arizona->regmap, fll->base + 1,
1128 ARIZONA_FLL1_ENA, 0);
1129 regmap_update_bits(arizona->regmap, fll->base + 0x11, 1433 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1130 ARIZONA_FLL1_SYNC_ENA, 0); 1434 ARIZONA_FLL1_SYNC_ENA, 0);
1131
1132 if (ena)
1133 pm_runtime_put_autosuspend(arizona->dev);
1134
1135 fll->fref = Fref;
1136 fll->fout = Fout;
1137
1138 return 0;
1139 }
1140
1141 regmap_update_bits(arizona->regmap, fll->base + 5,
1142 ARIZONA_FLL1_OUTDIV_MASK,
1143 cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1144
1145 if (syncsrc >= 0) {
1146 arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
1147 arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
1148 } else { 1435 } else {
1149 arizona_apply_fll(arizona, fll->base, &cfg, source); 1436 arizona_fll_err(fll, "No clocks provided\n");
1437 return;
1150 } 1438 }
1151 1439
1152 if (!ena) 1440 /*
1441 * Increase the bandwidth if we're not using a low frequency
1442 * sync source.
1443 */
1444 if (fll->sync_src >= 0 && fll->sync_freq > 100000)
1445 regmap_update_bits(arizona->regmap, fll->base + 0x17,
1446 ARIZONA_FLL1_SYNC_BW, 0);
1447 else
1448 regmap_update_bits(arizona->regmap, fll->base + 0x17,
1449 ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW);
1450
1451 if (!arizona_is_enabled_fll(fll))
1153 pm_runtime_get(arizona->dev); 1452 pm_runtime_get(arizona->dev);
1154 1453
1155 /* Clear any pending completions */ 1454 /* Clear any pending completions */
@@ -1157,7 +1456,8 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1157 1456
1158 regmap_update_bits(arizona->regmap, fll->base + 1, 1457 regmap_update_bits(arizona->regmap, fll->base + 1,
1159 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); 1458 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1160 if (syncsrc >= 0) 1459 if (fll->ref_src >= 0 && fll->sync_src >= 0 &&
1460 fll->ref_src != fll->sync_src)
1161 regmap_update_bits(arizona->regmap, fll->base + 0x11, 1461 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1162 ARIZONA_FLL1_SYNC_ENA, 1462 ARIZONA_FLL1_SYNC_ENA,
1163 ARIZONA_FLL1_SYNC_ENA); 1463 ARIZONA_FLL1_SYNC_ENA);
@@ -1166,10 +1466,88 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1166 msecs_to_jiffies(250)); 1466 msecs_to_jiffies(250));
1167 if (ret == 0) 1467 if (ret == 0)
1168 arizona_fll_warn(fll, "Timed out waiting for lock\n"); 1468 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1469}
1470
1471static void arizona_disable_fll(struct arizona_fll *fll)
1472{
1473 struct arizona *arizona = fll->arizona;
1474 bool change;
1475
1476 regmap_update_bits_check(arizona->regmap, fll->base + 1,
1477 ARIZONA_FLL1_ENA, 0, &change);
1478 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1479 ARIZONA_FLL1_SYNC_ENA, 0);
1480
1481 if (change)
1482 pm_runtime_put_autosuspend(arizona->dev);
1483}
1484
1485int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1486 unsigned int Fref, unsigned int Fout)
1487{
1488 struct arizona_fll_cfg ref, sync;
1489 int ret;
1490
1491 if (fll->ref_src == source && fll->ref_freq == Fref)
1492 return 0;
1493
1494 if (fll->fout && Fref > 0) {
1495 ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
1496 if (ret != 0)
1497 return ret;
1498
1499 if (fll->sync_src >= 0) {
1500 ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
1501 fll->fout);
1502 if (ret != 0)
1503 return ret;
1504 }
1505 }
1506
1507 fll->ref_src = source;
1508 fll->ref_freq = Fref;
1169 1509
1170 fll->fref = Fref; 1510 if (fll->fout && Fref > 0) {
1511 arizona_enable_fll(fll, &ref, &sync);
1512 }
1513
1514 return 0;
1515}
1516EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1517
1518int arizona_set_fll(struct arizona_fll *fll, int source,
1519 unsigned int Fref, unsigned int Fout)
1520{
1521 struct arizona_fll_cfg ref, sync;
1522 int ret;
1523
1524 if (fll->sync_src == source &&
1525 fll->sync_freq == Fref && fll->fout == Fout)
1526 return 0;
1527
1528 if (Fout) {
1529 if (fll->ref_src >= 0) {
1530 ret = arizona_calc_fll(fll, &ref, fll->ref_freq,
1531 Fout);
1532 if (ret != 0)
1533 return ret;
1534 }
1535
1536 ret = arizona_calc_fll(fll, &sync, Fref, Fout);
1537 if (ret != 0)
1538 return ret;
1539 }
1540
1541 fll->sync_src = source;
1542 fll->sync_freq = Fref;
1171 fll->fout = Fout; 1543 fll->fout = Fout;
1172 1544
1545 if (Fout) {
1546 arizona_enable_fll(fll, &ref, &sync);
1547 } else {
1548 arizona_disable_fll(fll);
1549 }
1550
1173 return 0; 1551 return 0;
1174} 1552}
1175EXPORT_SYMBOL_GPL(arizona_set_fll); 1553EXPORT_SYMBOL_GPL(arizona_set_fll);
@@ -1178,12 +1556,26 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1178 int ok_irq, struct arizona_fll *fll) 1556 int ok_irq, struct arizona_fll *fll)
1179{ 1557{
1180 int ret; 1558 int ret;
1559 unsigned int val;
1181 1560
1182 init_completion(&fll->ok); 1561 init_completion(&fll->ok);
1183 1562
1184 fll->id = id; 1563 fll->id = id;
1185 fll->base = base; 1564 fll->base = base;
1186 fll->arizona = arizona; 1565 fll->arizona = arizona;
1566 fll->sync_src = ARIZONA_FLL_SRC_NONE;
1567
1568 /* Configure default refclk to 32kHz if we have one */
1569 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1570 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1571 case ARIZONA_CLK_SRC_MCLK1:
1572 case ARIZONA_CLK_SRC_MCLK2:
1573 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
1574 break;
1575 default:
1576 fll->ref_src = ARIZONA_FLL_SRC_NONE;
1577 }
1578 fll->ref_freq = 32768;
1187 1579
1188 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); 1580 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1189 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), 1581 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 116372c91f5d..af39f1006427 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -32,6 +32,7 @@
32#define ARIZONA_CLK_SRC_AIF2BCLK 0x9 32#define ARIZONA_CLK_SRC_AIF2BCLK 0x9
33#define ARIZONA_CLK_SRC_AIF3BCLK 0xa 33#define ARIZONA_CLK_SRC_AIF3BCLK 0xa
34 34
35#define ARIZONA_FLL_SRC_NONE -1
35#define ARIZONA_FLL_SRC_MCLK1 0 36#define ARIZONA_FLL_SRC_MCLK1 0
36#define ARIZONA_FLL_SRC_MCLK2 1 37#define ARIZONA_FLL_SRC_MCLK2 1
37#define ARIZONA_FLL_SRC_SLIMCLK 3 38#define ARIZONA_FLL_SRC_SLIMCLK 3
@@ -48,6 +49,14 @@
48#define ARIZONA_MIXER_VOL_SHIFT 1 49#define ARIZONA_MIXER_VOL_SHIFT 1
49#define ARIZONA_MIXER_VOL_WIDTH 7 50#define ARIZONA_MIXER_VOL_WIDTH 7
50 51
52#define ARIZONA_CLK_6MHZ 0
53#define ARIZONA_CLK_12MHZ 1
54#define ARIZONA_CLK_24MHZ 2
55#define ARIZONA_CLK_49MHZ 3
56#define ARIZONA_CLK_73MHZ 4
57#define ARIZONA_CLK_98MHZ 5
58#define ARIZONA_CLK_147MHZ 6
59
51#define ARIZONA_MAX_DAI 4 60#define ARIZONA_MAX_DAI 4
52#define ARIZONA_MAX_ADSP 4 61#define ARIZONA_MAX_ADSP 4
53 62
@@ -64,6 +73,12 @@ struct arizona_priv {
64 int sysclk; 73 int sysclk;
65 int asyncclk; 74 int asyncclk;
66 struct arizona_dai_priv dai[ARIZONA_MAX_DAI]; 75 struct arizona_dai_priv dai[ARIZONA_MAX_DAI];
76
77 int num_inputs;
78 unsigned int in_pending;
79
80 unsigned int spk_ena:2;
81 unsigned int spk_ena_pending:1;
67}; 82};
68 83
69#define ARIZONA_NUM_MIXER_INPUTS 99 84#define ARIZONA_NUM_MIXER_INPUTS 99
@@ -165,6 +180,12 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
165 ARIZONA_MIXER_ROUTES(name, name "L"), \ 180 ARIZONA_MIXER_ROUTES(name, name "L"), \
166 ARIZONA_MIXER_ROUTES(name, name "R") 181 ARIZONA_MIXER_ROUTES(name, name "R")
167 182
183#define ARIZONA_RATE_ENUM_SIZE 4
184extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];
185extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE];
186
187extern const struct soc_enum arizona_isrc_fsl[];
188
168extern const struct soc_enum arizona_in_vi_ramp; 189extern const struct soc_enum arizona_in_vi_ramp;
169extern const struct soc_enum arizona_in_vd_ramp; 190extern const struct soc_enum arizona_in_vd_ramp;
170 191
@@ -184,6 +205,9 @@ extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
184extern int arizona_out_ev(struct snd_soc_dapm_widget *w, 205extern int arizona_out_ev(struct snd_soc_dapm_widget *w,
185 struct snd_kcontrol *kcontrol, 206 struct snd_kcontrol *kcontrol,
186 int event); 207 int event);
208extern int arizona_hp_ev(struct snd_soc_dapm_widget *w,
209 struct snd_kcontrol *kcontrol,
210 int event);
187 211
188extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, 212extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
189 int source, unsigned int freq, int dir); 213 int source, unsigned int freq, int dir);
@@ -198,8 +222,12 @@ struct arizona_fll {
198 unsigned int base; 222 unsigned int base;
199 unsigned int vco_mult; 223 unsigned int vco_mult;
200 struct completion ok; 224 struct completion ok;
201 unsigned int fref; 225
202 unsigned int fout; 226 unsigned int fout;
227 int sync_src;
228 unsigned int sync_freq;
229 int ref_src;
230 unsigned int ref_freq;
203 231
204 char lock_name[ARIZONA_FLL_NAME_LEN]; 232 char lock_name[ARIZONA_FLL_NAME_LEN];
205 char clock_ok_name[ARIZONA_FLL_NAME_LEN]; 233 char clock_ok_name[ARIZONA_FLL_NAME_LEN];
@@ -207,9 +235,13 @@ struct arizona_fll {
207 235
208extern int arizona_init_fll(struct arizona *arizona, int id, int base, 236extern int arizona_init_fll(struct arizona *arizona, int id, int base,
209 int lock_irq, int ok_irq, struct arizona_fll *fll); 237 int lock_irq, int ok_irq, struct arizona_fll *fll);
238extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
239 unsigned int Fref, unsigned int Fout);
210extern int arizona_set_fll(struct arizona_fll *fll, int source, 240extern int arizona_set_fll(struct arizona_fll *fll, int source,
211 unsigned int Fref, unsigned int Fout); 241 unsigned int Fref, unsigned int Fout);
212 242
243extern int arizona_init_spk(struct snd_soc_codec *codec);
244
213extern int arizona_init_dai(struct arizona_priv *priv, int dai); 245extern int arizona_init_dai(struct arizona_priv *priv, int dai);
214 246
215int arizona_set_output_mode(struct snd_soc_codec *codec, int output, 247int arizona_set_output_mode(struct snd_soc_codec *codec, int output,
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index ddc98f02ecbd..57ba315d0c84 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -1565,7 +1565,7 @@ static int wm2200_probe(struct snd_soc_codec *codec)
1565 return ret; 1565 return ret;
1566 } 1566 }
1567 1567
1568 ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 2); 1568 ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2);
1569 if (ret != 0) 1569 if (ret != 0)
1570 return ret; 1570 return ret;
1571 1571
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 34d0201d6a78..e895d3939eef 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -36,9 +36,6 @@
36struct wm5102_priv { 36struct wm5102_priv {
37 struct arizona_priv core; 37 struct arizona_priv core;
38 struct arizona_fll fll[2]; 38 struct arizona_fll fll[2];
39
40 unsigned int spk_ena:2;
41 unsigned int spk_ena_pending:1;
42}; 39};
43 40
44static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); 41static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
@@ -615,6 +612,26 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
615 return 0; 612 return 0;
616} 613}
617 614
615static const char *wm5102_osr_text[] = {
616 "Low power", "Normal", "High performance",
617};
618
619static const unsigned int wm5102_osr_val[] = {
620 0x0, 0x3, 0x5,
621};
622
623static const struct soc_enum wm5102_hpout_osr[] = {
624 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
625 ARIZONA_OUT1_OSR_SHIFT, 0x7, 3,
626 wm5102_osr_text, wm5102_osr_val),
627 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
628 ARIZONA_OUT2_OSR_SHIFT, 0x7, 3,
629 wm5102_osr_text, wm5102_osr_val),
630 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
631 ARIZONA_OUT3_OSR_SHIFT, 0x7, 3,
632 wm5102_osr_text, wm5102_osr_val),
633};
634
618#define WM5102_NG_SRC(name, base) \ 635#define WM5102_NG_SRC(name, base) \
619 SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \ 636 SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \
620 SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \ 637 SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \
@@ -745,6 +762,9 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
745SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), 762SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
746SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), 763SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
747 764
765SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]),
766SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]),
767
748ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), 768ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),
749ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), 769ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE),
750 770
@@ -761,6 +781,8 @@ ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE),
761ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), 781ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
762ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), 782ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
763 783
784SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
785 ARIZONA_OUT4_OSR_SHIFT, 1, 0),
764SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, 786SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
765 ARIZONA_OUT5_OSR_SHIFT, 1, 0), 787 ARIZONA_OUT5_OSR_SHIFT, 1, 0),
766 788
@@ -790,6 +812,10 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
790 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 812 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT,
791 0xbf, 0, digital_tlv), 813 0xbf, 0, digital_tlv),
792 814
815SOC_VALUE_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]),
816SOC_VALUE_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]),
817SOC_VALUE_ENUM("HPOUT3 OSR", wm5102_hpout_osr[2]),
818
793SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), 819SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
794SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), 820SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
795 821
@@ -828,47 +854,6 @@ ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
828ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), 854ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
829}; 855};
830 856
831static int wm5102_spk_ev(struct snd_soc_dapm_widget *w,
832 struct snd_kcontrol *kcontrol,
833 int event)
834{
835 struct snd_soc_codec *codec = w->codec;
836 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
837 struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec);
838
839 if (arizona->rev < 1)
840 return 0;
841
842 switch (event) {
843 case SND_SOC_DAPM_PRE_PMU:
844 if (!wm5102->spk_ena) {
845 snd_soc_write(codec, 0x4f5, 0x25a);
846 wm5102->spk_ena_pending = true;
847 }
848 break;
849 case SND_SOC_DAPM_POST_PMU:
850 if (wm5102->spk_ena_pending) {
851 msleep(75);
852 snd_soc_write(codec, 0x4f5, 0xda);
853 wm5102->spk_ena_pending = false;
854 wm5102->spk_ena++;
855 }
856 break;
857 case SND_SOC_DAPM_PRE_PMD:
858 wm5102->spk_ena--;
859 if (!wm5102->spk_ena)
860 snd_soc_write(codec, 0x4f5, 0x25a);
861 break;
862 case SND_SOC_DAPM_POST_PMD:
863 if (!wm5102->spk_ena)
864 snd_soc_write(codec, 0x4f5, 0x0da);
865 break;
866 }
867
868 return 0;
869}
870
871
872ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); 857ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
873ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); 858ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
874ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); 859ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE);
@@ -984,22 +969,28 @@ SND_SOC_DAPM_INPUT("IN3R"),
984 969
985SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 970SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
986 0, NULL, 0, arizona_in_ev, 971 0, NULL, 0, arizona_in_ev,
987 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 972 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
973 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
988SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, 974SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
989 0, NULL, 0, arizona_in_ev, 975 0, NULL, 0, arizona_in_ev,
990 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 976 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
977 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
991SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, 978SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
992 0, NULL, 0, arizona_in_ev, 979 0, NULL, 0, arizona_in_ev,
993 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 980 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
981 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
994SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, 982SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
995 0, NULL, 0, arizona_in_ev, 983 0, NULL, 0, arizona_in_ev,
996 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 984 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
985 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
997SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, 986SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
998 0, NULL, 0, arizona_in_ev, 987 0, NULL, 0, arizona_in_ev,
999 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 988 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
989 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1000SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, 990SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
1001 0, NULL, 0, arizona_in_ev, 991 0, NULL, 0, arizona_in_ev,
1002 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 992 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
993 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1003 994
1004SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, 995SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
1005 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), 996 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
@@ -1131,11 +1122,11 @@ ARIZONA_DSP_WIDGETS(DSP1, "DSP1"),
1131SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, 1122SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
1132 ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), 1123 ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux),
1133 1124
1134SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, 1125SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
1135 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1126 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
1136 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1127 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1137SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1, 1128SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
1138 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1129 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
1139 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1130 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1140SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, 1131SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
1141 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1132 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
@@ -1146,12 +1137,6 @@ SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
1146SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, 1137SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
1147 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1138 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
1148 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1139 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1149SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
1150 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev,
1151 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1152SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1,
1153 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev,
1154 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1155SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, 1140SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
1156 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1141 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
1157 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1142 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
@@ -1494,6 +1479,12 @@ static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1494 return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout); 1479 return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout);
1495 case WM5102_FLL2: 1480 case WM5102_FLL2:
1496 return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout); 1481 return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout);
1482 case WM5102_FLL1_REFCLK:
1483 return arizona_set_fll_refclk(&wm5102->fll[0], source, Fref,
1484 Fout);
1485 case WM5102_FLL2_REFCLK:
1486 return arizona_set_fll_refclk(&wm5102->fll[1], source, Fref,
1487 Fout);
1497 default: 1488 default:
1498 return -EINVAL; 1489 return -EINVAL;
1499 } 1490 }
@@ -1581,10 +1572,12 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
1581 if (ret != 0) 1572 if (ret != 0)
1582 return ret; 1573 return ret;
1583 1574
1584 ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 1); 1575 ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 2);
1585 if (ret != 0) 1576 if (ret != 0)
1586 return ret; 1577 return ret;
1587 1578
1579 arizona_init_spk(codec);
1580
1588 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); 1581 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
1589 1582
1590 priv->core.arizona->dapm = &codec->dapm; 1583 priv->core.arizona->dapm = &codec->dapm;
@@ -1604,13 +1597,6 @@ static int wm5102_codec_remove(struct snd_soc_codec *codec)
1604#define WM5102_DIG_VU 0x0200 1597#define WM5102_DIG_VU 0x0200
1605 1598
1606static unsigned int wm5102_digital_vu[] = { 1599static unsigned int wm5102_digital_vu[] = {
1607 ARIZONA_ADC_DIGITAL_VOLUME_1L,
1608 ARIZONA_ADC_DIGITAL_VOLUME_1R,
1609 ARIZONA_ADC_DIGITAL_VOLUME_2L,
1610 ARIZONA_ADC_DIGITAL_VOLUME_2R,
1611 ARIZONA_ADC_DIGITAL_VOLUME_3L,
1612 ARIZONA_ADC_DIGITAL_VOLUME_3R,
1613
1614 ARIZONA_DAC_DIGITAL_VOLUME_1L, 1600 ARIZONA_DAC_DIGITAL_VOLUME_1L,
1615 ARIZONA_DAC_DIGITAL_VOLUME_1R, 1601 ARIZONA_DAC_DIGITAL_VOLUME_1R,
1616 ARIZONA_DAC_DIGITAL_VOLUME_2L, 1602 ARIZONA_DAC_DIGITAL_VOLUME_2L,
@@ -1653,6 +1639,7 @@ static int wm5102_probe(struct platform_device *pdev)
1653 platform_set_drvdata(pdev, wm5102); 1639 platform_set_drvdata(pdev, wm5102);
1654 1640
1655 wm5102->core.arizona = arizona; 1641 wm5102->core.arizona = arizona;
1642 wm5102->core.num_inputs = 6;
1656 1643
1657 wm5102->core.adsp[0].part = "wm5102"; 1644 wm5102->core.adsp[0].part = "wm5102";
1658 wm5102->core.adsp[0].num = 1; 1645 wm5102->core.adsp[0].num = 1;
@@ -1677,6 +1664,12 @@ static int wm5102_probe(struct platform_device *pdev)
1677 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK, 1664 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
1678 &wm5102->fll[1]); 1665 &wm5102->fll[1]);
1679 1666
1667 /* SR2 fixed at 8kHz, SR3 fixed at 16kHz */
1668 regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_2,
1669 ARIZONA_SAMPLE_RATE_2_MASK, 0x11);
1670 regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_3,
1671 ARIZONA_SAMPLE_RATE_3_MASK, 0x12);
1672
1680 for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++) 1673 for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++)
1681 arizona_init_dai(&wm5102->core, i); 1674 arizona_init_dai(&wm5102->core, i);
1682 1675
diff --git a/sound/soc/codecs/wm5102.h b/sound/soc/codecs/wm5102.h
index d30477f3070c..adb38040f661 100644
--- a/sound/soc/codecs/wm5102.h
+++ b/sound/soc/codecs/wm5102.h
@@ -15,7 +15,9 @@
15 15
16#include "arizona.h" 16#include "arizona.h"
17 17
18#define WM5102_FLL1 1 18#define WM5102_FLL1 1
19#define WM5102_FLL2 2 19#define WM5102_FLL2 2
20#define WM5102_FLL1_REFCLK 3
21#define WM5102_FLL2_REFCLK 4
20 22
21#endif 23#endif
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index cdeb301da1f6..731884e04776 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -416,28 +416,36 @@ SND_SOC_DAPM_INPUT("IN4R"),
416 416
417SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 417SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
418 0, NULL, 0, arizona_in_ev, 418 0, NULL, 0, arizona_in_ev,
419 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 419 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
420 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
420SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, 421SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
421 0, NULL, 0, arizona_in_ev, 422 0, NULL, 0, arizona_in_ev,
422 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 423 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
424 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
423SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, 425SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
424 0, NULL, 0, arizona_in_ev, 426 0, NULL, 0, arizona_in_ev,
425 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 427 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
428 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
426SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, 429SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
427 0, NULL, 0, arizona_in_ev, 430 0, NULL, 0, arizona_in_ev,
428 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 431 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
432 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
429SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, 433SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
430 0, NULL, 0, arizona_in_ev, 434 0, NULL, 0, arizona_in_ev,
431 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 435 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
436 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
432SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, 437SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
433 0, NULL, 0, arizona_in_ev, 438 0, NULL, 0, arizona_in_ev,
434 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 439 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
440 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
435SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT, 441SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT,
436 0, NULL, 0, arizona_in_ev, 442 0, NULL, 0, arizona_in_ev,
437 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 443 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
444 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
438SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT, 445SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT,
439 0, NULL, 0, arizona_in_ev, 446 0, NULL, 0, arizona_in_ev,
440 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 447 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
448 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
441 449
442SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, 450SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
443 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), 451 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
@@ -551,11 +559,11 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
551SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, 559SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
552 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), 560 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
553 561
554SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, 562SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
555 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 563 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
556 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 564 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
557SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1, 565SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
558 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 566 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
559 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 567 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
560SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, 568SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
561 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 569 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
@@ -569,12 +577,6 @@ SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
569SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1, 577SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1,
570 ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 578 ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
571 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 579 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
572SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
573 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
574 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
575SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1,
576 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
577 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
578SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, 580SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
579 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 581 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
580 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 582 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
@@ -880,6 +882,12 @@ static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
880 return arizona_set_fll(&wm5110->fll[0], source, Fref, Fout); 882 return arizona_set_fll(&wm5110->fll[0], source, Fref, Fout);
881 case WM5110_FLL2: 883 case WM5110_FLL2:
882 return arizona_set_fll(&wm5110->fll[1], source, Fref, Fout); 884 return arizona_set_fll(&wm5110->fll[1], source, Fref, Fout);
885 case WM5110_FLL1_REFCLK:
886 return arizona_set_fll_refclk(&wm5110->fll[0], source, Fref,
887 Fout);
888 case WM5110_FLL2_REFCLK:
889 return arizona_set_fll_refclk(&wm5110->fll[1], source, Fref,
890 Fout);
883 default: 891 default:
884 return -EINVAL; 892 return -EINVAL;
885 } 893 }
@@ -987,15 +995,6 @@ static int wm5110_codec_remove(struct snd_soc_codec *codec)
987#define WM5110_DIG_VU 0x0200 995#define WM5110_DIG_VU 0x0200
988 996
989static unsigned int wm5110_digital_vu[] = { 997static unsigned int wm5110_digital_vu[] = {
990 ARIZONA_ADC_DIGITAL_VOLUME_1L,
991 ARIZONA_ADC_DIGITAL_VOLUME_1R,
992 ARIZONA_ADC_DIGITAL_VOLUME_2L,
993 ARIZONA_ADC_DIGITAL_VOLUME_2R,
994 ARIZONA_ADC_DIGITAL_VOLUME_3L,
995 ARIZONA_ADC_DIGITAL_VOLUME_3R,
996 ARIZONA_ADC_DIGITAL_VOLUME_4L,
997 ARIZONA_ADC_DIGITAL_VOLUME_4R,
998
999 ARIZONA_DAC_DIGITAL_VOLUME_1L, 998 ARIZONA_DAC_DIGITAL_VOLUME_1L,
1000 ARIZONA_DAC_DIGITAL_VOLUME_1R, 999 ARIZONA_DAC_DIGITAL_VOLUME_1R,
1001 ARIZONA_DAC_DIGITAL_VOLUME_2L, 1000 ARIZONA_DAC_DIGITAL_VOLUME_2L,
@@ -1040,6 +1039,7 @@ static int wm5110_probe(struct platform_device *pdev)
1040 platform_set_drvdata(pdev, wm5110); 1039 platform_set_drvdata(pdev, wm5110);
1041 1040
1042 wm5110->core.arizona = arizona; 1041 wm5110->core.arizona = arizona;
1042 wm5110->core.num_inputs = 8;
1043 1043
1044 for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++) 1044 for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++)
1045 wm5110->fll[i].vco_mult = 3; 1045 wm5110->fll[i].vco_mult = 3;
diff --git a/sound/soc/codecs/wm5110.h b/sound/soc/codecs/wm5110.h
index 75e9351ccab0..e6c0cd4235c5 100644
--- a/sound/soc/codecs/wm5110.h
+++ b/sound/soc/codecs/wm5110.h
@@ -15,7 +15,9 @@
15 15
16#include "arizona.h" 16#include "arizona.h"
17 17
18#define WM5110_FLL1 1 18#define WM5110_FLL1 1
19#define WM5110_FLL2 2 19#define WM5110_FLL2 2
20#define WM5110_FLL1_REFCLK 3
21#define WM5110_FLL2_REFCLK 4
20 22
21#endif 23#endif
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 34f2905f0158..3470b649c0b2 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -31,6 +31,7 @@
31 31
32#include <linux/mfd/arizona/registers.h> 32#include <linux/mfd/arizona/registers.h>
33 33
34#include "arizona.h"
34#include "wm_adsp.h" 35#include "wm_adsp.h"
35 36
36#define adsp_crit(_dsp, fmt, ...) \ 37#define adsp_crit(_dsp, fmt, ...) \
@@ -254,17 +255,52 @@ static const struct soc_enum wm_adsp_fw_enum[] = {
254 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 255 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
255}; 256};
256 257
257const struct snd_kcontrol_new wm_adsp_fw_controls[] = { 258const struct snd_kcontrol_new wm_adsp1_fw_controls[] = {
258 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], 259 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
259 wm_adsp_fw_get, wm_adsp_fw_put), 260 wm_adsp_fw_get, wm_adsp_fw_put),
260 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], 261 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
261 wm_adsp_fw_get, wm_adsp_fw_put), 262 wm_adsp_fw_get, wm_adsp_fw_put),
262 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], 263 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
263 wm_adsp_fw_get, wm_adsp_fw_put), 264 wm_adsp_fw_get, wm_adsp_fw_put),
265};
266EXPORT_SYMBOL_GPL(wm_adsp1_fw_controls);
267
268#if IS_ENABLED(CONFIG_SND_SOC_ARIZONA)
269static const struct soc_enum wm_adsp2_rate_enum[] = {
270 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
271 ARIZONA_DSP1_RATE_SHIFT, 0xf,
272 ARIZONA_RATE_ENUM_SIZE,
273 arizona_rate_text, arizona_rate_val),
274 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
275 ARIZONA_DSP1_RATE_SHIFT, 0xf,
276 ARIZONA_RATE_ENUM_SIZE,
277 arizona_rate_text, arizona_rate_val),
278 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
279 ARIZONA_DSP1_RATE_SHIFT, 0xf,
280 ARIZONA_RATE_ENUM_SIZE,
281 arizona_rate_text, arizona_rate_val),
282 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
283 ARIZONA_DSP1_RATE_SHIFT, 0xf,
284 ARIZONA_RATE_ENUM_SIZE,
285 arizona_rate_text, arizona_rate_val),
286};
287
288const struct snd_kcontrol_new wm_adsp2_fw_controls[] = {
289 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
290 wm_adsp_fw_get, wm_adsp_fw_put),
291 SOC_ENUM("DSP1 Rate", wm_adsp2_rate_enum[0]),
292 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
293 wm_adsp_fw_get, wm_adsp_fw_put),
294 SOC_ENUM("DSP2 Rate", wm_adsp2_rate_enum[1]),
295 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
296 wm_adsp_fw_get, wm_adsp_fw_put),
297 SOC_ENUM("DSP3 Rate", wm_adsp2_rate_enum[2]),
264 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], 298 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3],
265 wm_adsp_fw_get, wm_adsp_fw_put), 299 wm_adsp_fw_get, wm_adsp_fw_put),
300 SOC_ENUM("DSP4 Rate", wm_adsp2_rate_enum[3]),
266}; 301};
267EXPORT_SYMBOL_GPL(wm_adsp_fw_controls); 302EXPORT_SYMBOL_GPL(wm_adsp2_fw_controls);
303#endif
268 304
269static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, 305static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp,
270 int type) 306 int type)
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index d6fd8af53b5d..fea514627526 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -67,7 +67,8 @@ struct wm_adsp {
67 .shift = num, .event = wm_adsp2_event, \ 67 .shift = num, .event = wm_adsp2_event, \
68 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } 68 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
69 69
70extern const struct snd_kcontrol_new wm_adsp_fw_controls[]; 70extern const struct snd_kcontrol_new wm_adsp1_fw_controls[];
71extern const struct snd_kcontrol_new wm_adsp2_fw_controls[];
71 72
72int wm_adsp1_init(struct wm_adsp *adsp); 73int wm_adsp1_init(struct wm_adsp *adsp);
73int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); 74int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs);