aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/arizona.c479
-rw-r--r--sound/soc/codecs/arizona.h31
-rw-r--r--sound/soc/codecs/wm5102.c95
-rw-r--r--sound/soc/codecs/wm5102.h6
-rw-r--r--sound/soc/codecs/wm5110.c46
-rw-r--r--sound/soc/codecs/wm5110.h6
-rw-r--r--sound/soc/codecs/wm_adsp.c24
7 files changed, 526 insertions, 161 deletions
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index e7d34711412c..abdd019c5b6e 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;
@@ -502,27 +721,27 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
502 break; 721 break;
503 case 11289600: 722 case 11289600:
504 case 12288000: 723 case 12288000:
505 val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT; 724 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
506 break; 725 break;
507 case 22579200: 726 case 22579200:
508 case 24576000: 727 case 24576000:
509 val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT; 728 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
510 break; 729 break;
511 case 45158400: 730 case 45158400:
512 case 49152000: 731 case 49152000:
513 val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; 732 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
514 break; 733 break;
515 case 67737600: 734 case 67737600:
516 case 73728000: 735 case 73728000:
517 val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT; 736 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
518 break; 737 break;
519 case 90316800: 738 case 90316800:
520 case 98304000: 739 case 98304000:
521 val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; 740 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
522 break; 741 break;
523 case 135475200: 742 case 135475200:
524 case 147456000: 743 case 147456000:
525 val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; 744 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
526 break; 745 break;
527 case 0: 746 case 0:
528 dev_dbg(arizona->dev, "%s cleared\n", name); 747 dev_dbg(arizona->dev, "%s cleared\n", name);
@@ -816,7 +1035,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
816 struct arizona *arizona = priv->arizona; 1035 struct arizona *arizona = priv->arizona;
817 int base = dai->driver->base; 1036 int base = dai->driver->base;
818 const int *rates; 1037 const int *rates;
819 int i, ret; 1038 int i, ret, val;
820 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; 1039 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
821 int bclk, lrclk, wl, frame, bclk_target; 1040 int bclk, lrclk, wl, frame, bclk_target;
822 1041
@@ -832,6 +1051,13 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
832 bclk_target *= chan_limit; 1051 bclk_target *= chan_limit;
833 } 1052 }
834 1053
1054 /* Force stereo for I2S mode */
1055 val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
1056 if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) {
1057 arizona_aif_dbg(dai, "Forcing stereo mode\n");
1058 bclk_target *= 2;
1059 }
1060
835 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { 1061 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
836 if (rates[i] >= bclk_target && 1062 if (rates[i] >= bclk_target &&
837 rates[i] % params_rate(params) == 0) { 1063 rates[i] % params_rate(params) == 0) {
@@ -988,6 +1214,16 @@ static struct {
988 { 1000000, 13500000, 0, 1 }, 1214 { 1000000, 13500000, 0, 1 },
989}; 1215};
990 1216
1217static struct {
1218 unsigned int min;
1219 unsigned int max;
1220 u16 gain;
1221} fll_gains[] = {
1222 { 0, 256000, 0 },
1223 { 256000, 1000000, 2 },
1224 { 1000000, 13500000, 4 },
1225};
1226
991struct arizona_fll_cfg { 1227struct arizona_fll_cfg {
992 int n; 1228 int n;
993 int theta; 1229 int theta;
@@ -995,6 +1231,7 @@ struct arizona_fll_cfg {
995 int refdiv; 1231 int refdiv;
996 int outdiv; 1232 int outdiv;
997 int fratio; 1233 int fratio;
1234 int gain;
998}; 1235};
999 1236
1000static int arizona_calc_fll(struct arizona_fll *fll, 1237static int arizona_calc_fll(struct arizona_fll *fll,
@@ -1054,6 +1291,18 @@ static int arizona_calc_fll(struct arizona_fll *fll,
1054 return -EINVAL; 1291 return -EINVAL;
1055 } 1292 }
1056 1293
1294 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
1295 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
1296 cfg->gain = fll_gains[i].gain;
1297 break;
1298 }
1299 }
1300 if (i == ARRAY_SIZE(fll_gains)) {
1301 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1302 Fref);
1303 return -EINVAL;
1304 }
1305
1057 cfg->n = target / (ratio * Fref); 1306 cfg->n = target / (ratio * Fref);
1058 1307
1059 if (target % (ratio * Fref)) { 1308 if (target % (ratio * Fref)) {
@@ -1081,13 +1330,15 @@ static int arizona_calc_fll(struct arizona_fll *fll,
1081 cfg->n, cfg->theta, cfg->lambda); 1330 cfg->n, cfg->theta, cfg->lambda);
1082 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", 1331 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
1083 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); 1332 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
1333 arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);
1084 1334
1085 return 0; 1335 return 0;
1086 1336
1087} 1337}
1088 1338
1089static void arizona_apply_fll(struct arizona *arizona, unsigned int base, 1339static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1090 struct arizona_fll_cfg *cfg, int source) 1340 struct arizona_fll_cfg *cfg, int source,
1341 bool sync)
1091{ 1342{
1092 regmap_update_bits(arizona->regmap, base + 3, 1343 regmap_update_bits(arizona->regmap, base + 3,
1093 ARIZONA_FLL1_THETA_MASK, cfg->theta); 1344 ARIZONA_FLL1_THETA_MASK, cfg->theta);
@@ -1102,87 +1353,84 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1102 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | 1353 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1103 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); 1354 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1104 1355
1356 if (sync)
1357 regmap_update_bits(arizona->regmap, base + 0x7,
1358 ARIZONA_FLL1_GAIN_MASK,
1359 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1360 else
1361 regmap_update_bits(arizona->regmap, base + 0x9,
1362 ARIZONA_FLL1_GAIN_MASK,
1363 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1364
1105 regmap_update_bits(arizona->regmap, base + 2, 1365 regmap_update_bits(arizona->regmap, base + 2,
1106 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, 1366 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
1107 ARIZONA_FLL1_CTRL_UPD | cfg->n); 1367 ARIZONA_FLL1_CTRL_UPD | cfg->n);
1108} 1368}
1109 1369
1110int arizona_set_fll(struct arizona_fll *fll, int source, 1370static bool arizona_is_enabled_fll(struct arizona_fll *fll)
1111 unsigned int Fref, unsigned int Fout)
1112{ 1371{
1113 struct arizona *arizona = fll->arizona; 1372 struct arizona *arizona = fll->arizona;
1114 struct arizona_fll_cfg cfg, sync; 1373 unsigned int reg;
1115 unsigned int reg, val;
1116 int syncsrc;
1117 bool ena;
1118 int ret; 1374 int ret;
1119 1375
1120 if (fll->fref == Fref && fll->fout == Fout)
1121 return 0;
1122
1123 ret = regmap_read(arizona->regmap, fll->base + 1, &reg); 1376 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1124 if (ret != 0) { 1377 if (ret != 0) {
1125 arizona_fll_err(fll, "Failed to read current state: %d\n", 1378 arizona_fll_err(fll, "Failed to read current state: %d\n",
1126 ret); 1379 ret);
1127 return ret; 1380 return ret;
1128 } 1381 }
1129 ena = reg & ARIZONA_FLL1_ENA;
1130 1382
1131 if (Fout) { 1383 return reg & ARIZONA_FLL1_ENA;
1132 /* Do we have a 32kHz reference? */ 1384}
1133 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1134 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1135 case ARIZONA_CLK_SRC_MCLK1:
1136 case ARIZONA_CLK_SRC_MCLK2:
1137 syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
1138 break;
1139 default:
1140 syncsrc = -1;
1141 }
1142 1385
1143 if (source == syncsrc) 1386static void arizona_enable_fll(struct arizona_fll *fll,
1144 syncsrc = -1; 1387 struct arizona_fll_cfg *ref,
1388 struct arizona_fll_cfg *sync)
1389{
1390 struct arizona *arizona = fll->arizona;
1391 int ret;
1145 1392
1146 if (syncsrc >= 0) { 1393 /*
1147 ret = arizona_calc_fll(fll, &sync, Fref, Fout); 1394 * If we have both REFCLK and SYNCCLK then enable both,
1148 if (ret != 0) 1395 * otherwise apply the SYNCCLK settings to REFCLK.
1149 return ret; 1396 */
1397 if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) {
1398 regmap_update_bits(arizona->regmap, fll->base + 5,
1399 ARIZONA_FLL1_OUTDIV_MASK,
1400 ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1401
1402 arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
1403 false);
1404 if (fll->sync_src >= 0)
1405 arizona_apply_fll(arizona, fll->base + 0x10, sync,
1406 fll->sync_src, true);
1407 } else if (fll->sync_src >= 0) {
1408 regmap_update_bits(arizona->regmap, fll->base + 5,
1409 ARIZONA_FLL1_OUTDIV_MASK,
1410 sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1411
1412 arizona_apply_fll(arizona, fll->base, sync,
1413 fll->sync_src, false);
1150 1414
1151 ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
1152 if (ret != 0)
1153 return ret;
1154 } else {
1155 ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
1156 if (ret != 0)
1157 return ret;
1158 }
1159 } else {
1160 regmap_update_bits(arizona->regmap, fll->base + 1,
1161 ARIZONA_FLL1_ENA, 0);
1162 regmap_update_bits(arizona->regmap, fll->base + 0x11, 1415 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1163 ARIZONA_FLL1_SYNC_ENA, 0); 1416 ARIZONA_FLL1_SYNC_ENA, 0);
1164
1165 if (ena)
1166 pm_runtime_put_autosuspend(arizona->dev);
1167
1168 fll->fref = Fref;
1169 fll->fout = Fout;
1170
1171 return 0;
1172 }
1173
1174 regmap_update_bits(arizona->regmap, fll->base + 5,
1175 ARIZONA_FLL1_OUTDIV_MASK,
1176 cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1177
1178 if (syncsrc >= 0) {
1179 arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
1180 arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
1181 } else { 1417 } else {
1182 arizona_apply_fll(arizona, fll->base, &cfg, source); 1418 arizona_fll_err(fll, "No clocks provided\n");
1419 return;
1183 } 1420 }
1184 1421
1185 if (!ena) 1422 /*
1423 * Increase the bandwidth if we're not using a low frequency
1424 * sync source.
1425 */
1426 if (fll->sync_src >= 0 && fll->sync_freq > 100000)
1427 regmap_update_bits(arizona->regmap, fll->base + 0x17,
1428 ARIZONA_FLL1_SYNC_BW, 0);
1429 else
1430 regmap_update_bits(arizona->regmap, fll->base + 0x17,
1431 ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW);
1432
1433 if (!arizona_is_enabled_fll(fll))
1186 pm_runtime_get(arizona->dev); 1434 pm_runtime_get(arizona->dev);
1187 1435
1188 /* Clear any pending completions */ 1436 /* Clear any pending completions */
@@ -1190,7 +1438,8 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1190 1438
1191 regmap_update_bits(arizona->regmap, fll->base + 1, 1439 regmap_update_bits(arizona->regmap, fll->base + 1,
1192 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); 1440 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1193 if (syncsrc >= 0) 1441 if (fll->ref_src >= 0 && fll->sync_src >= 0 &&
1442 fll->ref_src != fll->sync_src)
1194 regmap_update_bits(arizona->regmap, fll->base + 0x11, 1443 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1195 ARIZONA_FLL1_SYNC_ENA, 1444 ARIZONA_FLL1_SYNC_ENA,
1196 ARIZONA_FLL1_SYNC_ENA); 1445 ARIZONA_FLL1_SYNC_ENA);
@@ -1199,10 +1448,88 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1199 msecs_to_jiffies(250)); 1448 msecs_to_jiffies(250));
1200 if (ret == 0) 1449 if (ret == 0)
1201 arizona_fll_warn(fll, "Timed out waiting for lock\n"); 1450 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1451}
1452
1453static void arizona_disable_fll(struct arizona_fll *fll)
1454{
1455 struct arizona *arizona = fll->arizona;
1456 bool change;
1457
1458 regmap_update_bits_check(arizona->regmap, fll->base + 1,
1459 ARIZONA_FLL1_ENA, 0, &change);
1460 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1461 ARIZONA_FLL1_SYNC_ENA, 0);
1462
1463 if (change)
1464 pm_runtime_put_autosuspend(arizona->dev);
1465}
1466
1467int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1468 unsigned int Fref, unsigned int Fout)
1469{
1470 struct arizona_fll_cfg ref, sync;
1471 int ret;
1472
1473 if (fll->ref_src == source && fll->ref_freq == Fref)
1474 return 0;
1475
1476 if (fll->fout && Fref > 0) {
1477 ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
1478 if (ret != 0)
1479 return ret;
1480
1481 if (fll->sync_src >= 0) {
1482 ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
1483 fll->fout);
1484 if (ret != 0)
1485 return ret;
1486 }
1487 }
1488
1489 fll->ref_src = source;
1490 fll->ref_freq = Fref;
1491
1492 if (fll->fout && Fref > 0) {
1493 arizona_enable_fll(fll, &ref, &sync);
1494 }
1495
1496 return 0;
1497}
1498EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1499
1500int arizona_set_fll(struct arizona_fll *fll, int source,
1501 unsigned int Fref, unsigned int Fout)
1502{
1503 struct arizona_fll_cfg ref, sync;
1504 int ret;
1202 1505
1203 fll->fref = Fref; 1506 if (fll->sync_src == source &&
1507 fll->sync_freq == Fref && fll->fout == Fout)
1508 return 0;
1509
1510 if (Fout) {
1511 if (fll->ref_src >= 0) {
1512 ret = arizona_calc_fll(fll, &ref, fll->ref_freq,
1513 Fout);
1514 if (ret != 0)
1515 return ret;
1516 }
1517
1518 ret = arizona_calc_fll(fll, &sync, Fref, Fout);
1519 if (ret != 0)
1520 return ret;
1521 }
1522
1523 fll->sync_src = source;
1524 fll->sync_freq = Fref;
1204 fll->fout = Fout; 1525 fll->fout = Fout;
1205 1526
1527 if (Fout) {
1528 arizona_enable_fll(fll, &ref, &sync);
1529 } else {
1530 arizona_disable_fll(fll);
1531 }
1532
1206 return 0; 1533 return 0;
1207} 1534}
1208EXPORT_SYMBOL_GPL(arizona_set_fll); 1535EXPORT_SYMBOL_GPL(arizona_set_fll);
@@ -1211,12 +1538,26 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1211 int ok_irq, struct arizona_fll *fll) 1538 int ok_irq, struct arizona_fll *fll)
1212{ 1539{
1213 int ret; 1540 int ret;
1541 unsigned int val;
1214 1542
1215 init_completion(&fll->ok); 1543 init_completion(&fll->ok);
1216 1544
1217 fll->id = id; 1545 fll->id = id;
1218 fll->base = base; 1546 fll->base = base;
1219 fll->arizona = arizona; 1547 fll->arizona = arizona;
1548 fll->sync_src = ARIZONA_FLL_SRC_NONE;
1549
1550 /* Configure default refclk to 32kHz if we have one */
1551 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1552 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1553 case ARIZONA_CLK_SRC_MCLK1:
1554 case ARIZONA_CLK_SRC_MCLK2:
1555 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
1556 break;
1557 default:
1558 fll->ref_src = ARIZONA_FLL_SRC_NONE;
1559 }
1560 fll->ref_freq = 32768;
1220 1561
1221 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); 1562 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1222 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), 1563 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 13dd2916b721..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
@@ -201,8 +222,12 @@ struct arizona_fll {
201 unsigned int base; 222 unsigned int base;
202 unsigned int vco_mult; 223 unsigned int vco_mult;
203 struct completion ok; 224 struct completion ok;
204 unsigned int fref; 225
205 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;
206 231
207 char lock_name[ARIZONA_FLL_NAME_LEN]; 232 char lock_name[ARIZONA_FLL_NAME_LEN];
208 char clock_ok_name[ARIZONA_FLL_NAME_LEN]; 233 char clock_ok_name[ARIZONA_FLL_NAME_LEN];
@@ -210,9 +235,13 @@ struct arizona_fll {
210 235
211extern int arizona_init_fll(struct arizona *arizona, int id, int base, 236extern int arizona_init_fll(struct arizona *arizona, int id, int base,
212 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);
213extern int arizona_set_fll(struct arizona_fll *fll, int source, 240extern int arizona_set_fll(struct arizona_fll *fll, int source,
214 unsigned int Fref, unsigned int Fout); 241 unsigned int Fref, unsigned int Fout);
215 242
243extern int arizona_init_spk(struct snd_soc_codec *codec);
244
216extern int arizona_init_dai(struct arizona_priv *priv, int dai); 245extern int arizona_init_dai(struct arizona_priv *priv, int dai);
217 246
218int 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/wm5102.c b/sound/soc/codecs/wm5102.c
index 2657aad3f8b1..b7a3fdceec7f 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);
@@ -745,6 +742,9 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
745SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), 742SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
746SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), 743SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
747 744
745SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]),
746SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]),
747
748ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), 748ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),
749ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), 749ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE),
750 750
@@ -828,47 +828,6 @@ ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
828ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), 828ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
829}; 829};
830 830
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); 831ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
873ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); 832ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
874ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); 833ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE);
@@ -984,22 +943,28 @@ SND_SOC_DAPM_INPUT("IN3R"),
984 943
985SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 944SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
986 0, NULL, 0, arizona_in_ev, 945 0, NULL, 0, arizona_in_ev,
987 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 946 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
947 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
988SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, 948SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
989 0, NULL, 0, arizona_in_ev, 949 0, NULL, 0, arizona_in_ev,
990 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 950 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
951 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
991SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, 952SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
992 0, NULL, 0, arizona_in_ev, 953 0, NULL, 0, arizona_in_ev,
993 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 954 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
955 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
994SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, 956SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
995 0, NULL, 0, arizona_in_ev, 957 0, NULL, 0, arizona_in_ev,
996 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 958 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
959 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
997SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, 960SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
998 0, NULL, 0, arizona_in_ev, 961 0, NULL, 0, arizona_in_ev,
999 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 962 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
963 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1000SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, 964SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
1001 0, NULL, 0, arizona_in_ev, 965 0, NULL, 0, arizona_in_ev,
1002 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 966 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
967 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1003 968
1004SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, 969SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
1005 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), 970 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
@@ -1146,12 +1111,6 @@ SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
1146SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, 1111SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
1147 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1112 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
1148 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1113 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, 1114SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
1156 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1115 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
1157 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1116 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
@@ -1494,6 +1453,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); 1453 return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout);
1495 case WM5102_FLL2: 1454 case WM5102_FLL2:
1496 return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout); 1455 return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout);
1456 case WM5102_FLL1_REFCLK:
1457 return arizona_set_fll_refclk(&wm5102->fll[0], source, Fref,
1458 Fout);
1459 case WM5102_FLL2_REFCLK:
1460 return arizona_set_fll_refclk(&wm5102->fll[1], source, Fref,
1461 Fout);
1497 default: 1462 default:
1498 return -EINVAL; 1463 return -EINVAL;
1499 } 1464 }
@@ -1581,10 +1546,12 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
1581 if (ret != 0) 1546 if (ret != 0)
1582 return ret; 1547 return ret;
1583 1548
1584 ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 1); 1549 ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 2);
1585 if (ret != 0) 1550 if (ret != 0)
1586 return ret; 1551 return ret;
1587 1552
1553 arizona_init_spk(codec);
1554
1588 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); 1555 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
1589 1556
1590 priv->core.arizona->dapm = &codec->dapm; 1557 priv->core.arizona->dapm = &codec->dapm;
@@ -1604,13 +1571,6 @@ static int wm5102_codec_remove(struct snd_soc_codec *codec)
1604#define WM5102_DIG_VU 0x0200 1571#define WM5102_DIG_VU 0x0200
1605 1572
1606static unsigned int wm5102_digital_vu[] = { 1573static 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, 1574 ARIZONA_DAC_DIGITAL_VOLUME_1L,
1615 ARIZONA_DAC_DIGITAL_VOLUME_1R, 1575 ARIZONA_DAC_DIGITAL_VOLUME_1R,
1616 ARIZONA_DAC_DIGITAL_VOLUME_2L, 1576 ARIZONA_DAC_DIGITAL_VOLUME_2L,
@@ -1653,6 +1613,7 @@ static int wm5102_probe(struct platform_device *pdev)
1653 platform_set_drvdata(pdev, wm5102); 1613 platform_set_drvdata(pdev, wm5102);
1654 1614
1655 wm5102->core.arizona = arizona; 1615 wm5102->core.arizona = arizona;
1616 wm5102->core.num_inputs = 6;
1656 1617
1657 wm5102->core.adsp[0].part = "wm5102"; 1618 wm5102->core.adsp[0].part = "wm5102";
1658 wm5102->core.adsp[0].num = 1; 1619 wm5102->core.adsp[0].num = 1;
@@ -1677,6 +1638,12 @@ static int wm5102_probe(struct platform_device *pdev)
1677 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK, 1638 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
1678 &wm5102->fll[1]); 1639 &wm5102->fll[1]);
1679 1640
1641 /* SR2 fixed at 8kHz, SR3 fixed at 16kHz */
1642 regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_2,
1643 ARIZONA_SAMPLE_RATE_2_MASK, 0x11);
1644 regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_3,
1645 ARIZONA_SAMPLE_RATE_3_MASK, 0x12);
1646
1680 for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++) 1647 for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++)
1681 arizona_init_dai(&wm5102->core, i); 1648 arizona_init_dai(&wm5102->core, i);
1682 1649
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 7841b42a819c..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),
@@ -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 f3f7e75f8628..3a481fd1bf9a 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, ...) \
@@ -246,15 +247,38 @@ static const struct soc_enum wm_adsp_fw_enum[] = {
246 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 247 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
247}; 248};
248 249
250static const struct soc_enum wm_adsp_rate_enum[] = {
251 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
252 ARIZONA_DSP1_RATE_SHIFT, 0xf,
253 ARIZONA_RATE_ENUM_SIZE,
254 arizona_rate_text, arizona_rate_val),
255 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
256 ARIZONA_DSP1_RATE_SHIFT, 0xf,
257 ARIZONA_RATE_ENUM_SIZE,
258 arizona_rate_text, arizona_rate_val),
259 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
260 ARIZONA_DSP1_RATE_SHIFT, 0xf,
261 ARIZONA_RATE_ENUM_SIZE,
262 arizona_rate_text, arizona_rate_val),
263 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
264 ARIZONA_DSP1_RATE_SHIFT, 0xf,
265 ARIZONA_RATE_ENUM_SIZE,
266 arizona_rate_text, arizona_rate_val),
267};
268
249const struct snd_kcontrol_new wm_adsp_fw_controls[] = { 269const struct snd_kcontrol_new wm_adsp_fw_controls[] = {
250 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], 270 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
251 wm_adsp_fw_get, wm_adsp_fw_put), 271 wm_adsp_fw_get, wm_adsp_fw_put),
272 SOC_ENUM("DSP1 Rate", wm_adsp_rate_enum[0]),
252 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], 273 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
253 wm_adsp_fw_get, wm_adsp_fw_put), 274 wm_adsp_fw_get, wm_adsp_fw_put),
275 SOC_ENUM("DSP2 Rate", wm_adsp_rate_enum[1]),
254 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], 276 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
255 wm_adsp_fw_get, wm_adsp_fw_put), 277 wm_adsp_fw_get, wm_adsp_fw_put),
278 SOC_ENUM("DSP3 Rate", wm_adsp_rate_enum[2]),
256 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], 279 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3],
257 wm_adsp_fw_get, wm_adsp_fw_put), 280 wm_adsp_fw_get, wm_adsp_fw_put),
281 SOC_ENUM("DSP4 Rate", wm_adsp_rate_enum[3]),
258}; 282};
259EXPORT_SYMBOL_GPL(wm_adsp_fw_controls); 283EXPORT_SYMBOL_GPL(wm_adsp_fw_controls);
260 284