diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/arizona.c | 479 | ||||
-rw-r--r-- | sound/soc/codecs/arizona.h | 31 | ||||
-rw-r--r-- | sound/soc/codecs/wm5102.c | 95 | ||||
-rw-r--r-- | sound/soc/codecs/wm5102.h | 6 | ||||
-rw-r--r-- | sound/soc/codecs/wm5110.c | 46 | ||||
-rw-r--r-- | sound/soc/codecs/wm5110.h | 6 | ||||
-rw-r--r-- | sound/soc/codecs/wm_adsp.c | 24 |
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 | ||
69 | static 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 | |||
138 | static 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 | |||
156 | static 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 | |||
182 | static 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 | |||
187 | static 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 | |||
192 | int 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 | } | ||
224 | EXPORT_SYMBOL_GPL(arizona_init_spk); | ||
225 | |||
68 | const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { | 226 | const 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); | |||
274 | const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); | 432 | const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); |
275 | EXPORT_SYMBOL_GPL(arizona_mixer_tlv); | 433 | EXPORT_SYMBOL_GPL(arizona_mixer_tlv); |
276 | 434 | ||
435 | const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = { | ||
436 | "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate", | ||
437 | }; | ||
438 | EXPORT_SYMBOL_GPL(arizona_rate_text); | ||
439 | |||
440 | const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = { | ||
441 | 0, 1, 2, 8, | ||
442 | }; | ||
443 | EXPORT_SYMBOL_GPL(arizona_rate_val); | ||
444 | |||
445 | |||
446 | const 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 | }; | ||
460 | EXPORT_SYMBOL_GPL(arizona_isrc_fsl); | ||
461 | |||
277 | static const char *arizona_vol_ramp_text[] = { | 462 | static 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); |
333 | EXPORT_SYMBOL_GPL(arizona_ng_hold); | 518 | EXPORT_SYMBOL_GPL(arizona_ng_hold); |
334 | 519 | ||
520 | static 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 | |||
335 | int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, | 537 | int 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 | ||
1217 | static 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 | |||
991 | struct arizona_fll_cfg { | 1227 | struct 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 | ||
1000 | static int arizona_calc_fll(struct arizona_fll *fll, | 1237 | static 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 | ||
1089 | static void arizona_apply_fll(struct arizona *arizona, unsigned int base, | 1339 | static 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 | ||
1110 | int arizona_set_fll(struct arizona_fll *fll, int source, | 1370 | static 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, ®); | 1376 | ret = regmap_read(arizona->regmap, fll->base + 1, ®); |
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) | 1386 | static 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 | |||
1453 | static 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 | |||
1467 | int 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 | } | ||
1498 | EXPORT_SYMBOL_GPL(arizona_set_fll_refclk); | ||
1499 | |||
1500 | int 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 | } |
1208 | EXPORT_SYMBOL_GPL(arizona_set_fll); | 1535 | EXPORT_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 | ||
184 | extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; | ||
185 | extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE]; | ||
186 | |||
187 | extern const struct soc_enum arizona_isrc_fsl[]; | ||
188 | |||
168 | extern const struct soc_enum arizona_in_vi_ramp; | 189 | extern const struct soc_enum arizona_in_vi_ramp; |
169 | extern const struct soc_enum arizona_in_vd_ramp; | 190 | extern 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 | ||
211 | extern int arizona_init_fll(struct arizona *arizona, int id, int base, | 236 | extern 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); |
238 | extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source, | ||
239 | unsigned int Fref, unsigned int Fout); | ||
213 | extern int arizona_set_fll(struct arizona_fll *fll, int source, | 240 | extern 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 | ||
243 | extern int arizona_init_spk(struct snd_soc_codec *codec); | ||
244 | |||
216 | extern int arizona_init_dai(struct arizona_priv *priv, int dai); | 245 | extern int arizona_init_dai(struct arizona_priv *priv, int dai); |
217 | 246 | ||
218 | int arizona_set_output_mode(struct snd_soc_codec *codec, int output, | 247 | int 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 @@ | |||
36 | struct wm5102_priv { | 36 | struct 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 | ||
44 | static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); | 41 | static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); |
@@ -745,6 +742,9 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), | |||
745 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), | 742 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), |
746 | SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), | 743 | SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), |
747 | 744 | ||
745 | SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), | ||
746 | SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), | ||
747 | |||
748 | ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), | 748 | ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), |
749 | ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), | 749 | ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), |
750 | 750 | ||
@@ -828,47 +828,6 @@ ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE), | |||
828 | ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), | 828 | ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), |
829 | }; | 829 | }; |
830 | 830 | ||
831 | static 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 | |||
872 | ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); | 831 | ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); |
873 | ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); | 832 | ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); |
874 | ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); | 833 | ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); |
@@ -984,22 +943,28 @@ SND_SOC_DAPM_INPUT("IN3R"), | |||
984 | 943 | ||
985 | SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, | 944 | SND_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), | ||
988 | SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, | 948 | SND_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), | ||
991 | SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, | 952 | SND_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), | ||
994 | SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, | 956 | SND_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), | ||
997 | SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, | 960 | SND_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), | ||
1000 | SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, | 964 | SND_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 | ||
1004 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, | 969 | SND_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, | |||
1146 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, | 1111 | SND_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), |
1149 | SND_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), | ||
1152 | SND_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), | ||
1155 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, | 1114 | SND_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 | ||
1606 | static unsigned int wm5102_digital_vu[] = { | 1573 | static 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 | ||
417 | SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, | 417 | SND_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), | ||
420 | SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, | 421 | SND_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), | ||
423 | SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, | 425 | SND_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), | ||
426 | SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, | 429 | SND_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), | ||
429 | SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, | 433 | SND_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), | ||
432 | SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, | 437 | SND_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), | ||
435 | SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT, | 441 | SND_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), | ||
438 | SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT, | 445 | SND_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 | ||
442 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, | 450 | SND_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, | |||
569 | SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1, | 577 | SND_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), |
572 | SND_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), | ||
575 | SND_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), | ||
578 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, | 580 | SND_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 | ||
989 | static unsigned int wm5110_digital_vu[] = { | 997 | static 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 | ||
250 | static 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 | |||
249 | const struct snd_kcontrol_new wm_adsp_fw_controls[] = { | 269 | const 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 | }; |
259 | EXPORT_SYMBOL_GPL(wm_adsp_fw_controls); | 283 | EXPORT_SYMBOL_GPL(wm_adsp_fw_controls); |
260 | 284 | ||