diff options
-rw-r--r-- | drivers/mfd/wm8994-core.c | 35 | ||||
-rw-r--r-- | include/linux/mfd/wm8994/core.h | 4 | ||||
-rw-r--r-- | include/linux/mfd/wm8994/pdata.h | 5 | ||||
-rw-r--r-- | sound/soc/codecs/wm8958-dsp2.c | 79 | ||||
-rw-r--r-- | sound/soc/codecs/wm8994.c | 343 | ||||
-rw-r--r-- | sound/soc/codecs/wm8994.h | 13 | ||||
-rw-r--r-- | sound/soc/samsung/littlemill.c | 2 |
7 files changed, 273 insertions, 208 deletions
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 8fefc961ec06..45a20c573aa3 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -401,13 +401,19 @@ static const __devinitconst struct reg_default wm1811_reva_patch[] = { | |||
401 | */ | 401 | */ |
402 | static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) | 402 | static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) |
403 | { | 403 | { |
404 | struct wm8994_pdata *pdata = wm8994->dev->platform_data; | 404 | struct wm8994_pdata *pdata; |
405 | struct regmap_config *regmap_config; | 405 | struct regmap_config *regmap_config; |
406 | const struct reg_default *regmap_patch = NULL; | 406 | const struct reg_default *regmap_patch = NULL; |
407 | const char *devname; | 407 | const char *devname; |
408 | int ret, i, patch_regs; | 408 | int ret, i, patch_regs; |
409 | int pulls = 0; | 409 | int pulls = 0; |
410 | 410 | ||
411 | if (dev_get_platdata(wm8994->dev)) { | ||
412 | pdata = dev_get_platdata(wm8994->dev); | ||
413 | wm8994->pdata = *pdata; | ||
414 | } | ||
415 | pdata = &wm8994->pdata; | ||
416 | |||
411 | dev_set_drvdata(wm8994->dev, wm8994); | 417 | dev_set_drvdata(wm8994->dev, wm8994); |
412 | 418 | ||
413 | /* Add the on-chip regulators first for bootstrapping */ | 419 | /* Add the on-chip regulators first for bootstrapping */ |
@@ -604,24 +610,21 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
604 | } | 610 | } |
605 | } | 611 | } |
606 | 612 | ||
607 | if (pdata) { | 613 | wm8994->irq_base = pdata->irq_base; |
608 | wm8994->irq_base = pdata->irq_base; | 614 | wm8994->gpio_base = pdata->gpio_base; |
609 | wm8994->gpio_base = pdata->gpio_base; | 615 | |
610 | 616 | /* GPIO configuration is only applied if it's non-zero */ | |
611 | /* GPIO configuration is only applied if it's non-zero */ | 617 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { |
612 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { | 618 | if (pdata->gpio_defaults[i]) { |
613 | if (pdata->gpio_defaults[i]) { | 619 | wm8994_set_bits(wm8994, WM8994_GPIO_1 + i, |
614 | wm8994_set_bits(wm8994, WM8994_GPIO_1 + i, | 620 | 0xffff, pdata->gpio_defaults[i]); |
615 | 0xffff, | ||
616 | pdata->gpio_defaults[i]); | ||
617 | } | ||
618 | } | 621 | } |
622 | } | ||
619 | 623 | ||
620 | wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven; | 624 | wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven; |
621 | 625 | ||
622 | if (pdata->spkmode_pu) | 626 | if (pdata->spkmode_pu) |
623 | pulls |= WM8994_SPKMODE_PU; | 627 | pulls |= WM8994_SPKMODE_PU; |
624 | } | ||
625 | 628 | ||
626 | /* Disable unneeded pulls */ | 629 | /* Disable unneeded pulls */ |
627 | wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, | 630 | wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, |
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h index 1f173306bf05..ae5c249530b4 100644 --- a/include/linux/mfd/wm8994/core.h +++ b/include/linux/mfd/wm8994/core.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/regmap.h> | 20 | #include <linux/regmap.h> |
21 | 21 | ||
22 | #include <linux/mfd/wm8994/pdata.h> | ||
23 | |||
22 | enum wm8994_type { | 24 | enum wm8994_type { |
23 | WM8994 = 0, | 25 | WM8994 = 0, |
24 | WM8958 = 1, | 26 | WM8958 = 1, |
@@ -55,6 +57,8 @@ struct regulator_bulk_data; | |||
55 | struct wm8994 { | 57 | struct wm8994 { |
56 | struct mutex irq_lock; | 58 | struct mutex irq_lock; |
57 | 59 | ||
60 | struct wm8994_pdata pdata; | ||
61 | |||
58 | enum wm8994_type type; | 62 | enum wm8994_type type; |
59 | int revision; | 63 | int revision; |
60 | int cust_id; | 64 | int cust_id; |
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index fc87be4fdc25..8e21a094836d 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h | |||
@@ -176,6 +176,11 @@ struct wm8994_pdata { | |||
176 | unsigned int lineout1fb:1; | 176 | unsigned int lineout1fb:1; |
177 | unsigned int lineout2fb:1; | 177 | unsigned int lineout2fb:1; |
178 | 178 | ||
179 | /* Delay between detecting a jack and starting microphone | ||
180 | * detect (specified in ms) | ||
181 | */ | ||
182 | int micdet_delay; | ||
183 | |||
179 | /* IRQ for microphone detection if brought out directly as a | 184 | /* IRQ for microphone detection if brought out directly as a |
180 | * signal. | 185 | * signal. |
181 | */ | 186 | */ |
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 00121ba36597..b0710d817a65 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c | |||
@@ -195,7 +195,7 @@ ok: | |||
195 | static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) | 195 | static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) |
196 | { | 196 | { |
197 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 197 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
198 | struct wm8994_pdata *pdata = wm8994->pdata; | 198 | struct wm8994 *control = wm8994->wm8994; |
199 | int i; | 199 | int i; |
200 | 200 | ||
201 | /* If the DSP is already running then noop */ | 201 | /* If the DSP is already running then noop */ |
@@ -210,9 +210,9 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) | |||
210 | WM8958_DSP2_ENA, WM8958_DSP2_ENA); | 210 | WM8958_DSP2_ENA, WM8958_DSP2_ENA); |
211 | 211 | ||
212 | /* If we've got user supplied MBC settings use them */ | 212 | /* If we've got user supplied MBC settings use them */ |
213 | if (pdata && pdata->num_mbc_cfgs) { | 213 | if (control->pdata.num_mbc_cfgs) { |
214 | struct wm8958_mbc_cfg *cfg | 214 | struct wm8958_mbc_cfg *cfg |
215 | = &pdata->mbc_cfgs[wm8994->mbc_cfg]; | 215 | = &control->pdata.mbc_cfgs[wm8994->mbc_cfg]; |
216 | 216 | ||
217 | for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) | 217 | for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) |
218 | snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1, | 218 | snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1, |
@@ -239,7 +239,7 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) | |||
239 | static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) | 239 | static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) |
240 | { | 240 | { |
241 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 241 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
242 | struct wm8994_pdata *pdata = wm8994->pdata; | 242 | struct wm8994 *control = wm8994->wm8994; |
243 | int i, ena; | 243 | int i, ena; |
244 | 244 | ||
245 | if (wm8994->mbc_vss) | 245 | if (wm8994->mbc_vss) |
@@ -249,26 +249,26 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) | |||
249 | WM8958_DSP2_ENA, WM8958_DSP2_ENA); | 249 | WM8958_DSP2_ENA, WM8958_DSP2_ENA); |
250 | 250 | ||
251 | /* If we've got user supplied settings use them */ | 251 | /* If we've got user supplied settings use them */ |
252 | if (pdata && pdata->num_mbc_cfgs) { | 252 | if (control->pdata.num_mbc_cfgs) { |
253 | struct wm8958_mbc_cfg *cfg | 253 | struct wm8958_mbc_cfg *cfg |
254 | = &pdata->mbc_cfgs[wm8994->mbc_cfg]; | 254 | = &control->pdata.mbc_cfgs[wm8994->mbc_cfg]; |
255 | 255 | ||
256 | for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++) | 256 | for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++) |
257 | snd_soc_write(codec, i + 0x2800, | 257 | snd_soc_write(codec, i + 0x2800, |
258 | cfg->combined_regs[i]); | 258 | cfg->combined_regs[i]); |
259 | } | 259 | } |
260 | 260 | ||
261 | if (pdata && pdata->num_vss_cfgs) { | 261 | if (control->pdata.num_vss_cfgs) { |
262 | struct wm8958_vss_cfg *cfg | 262 | struct wm8958_vss_cfg *cfg |
263 | = &pdata->vss_cfgs[wm8994->vss_cfg]; | 263 | = &control->pdata.vss_cfgs[wm8994->vss_cfg]; |
264 | 264 | ||
265 | for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) | 265 | for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) |
266 | snd_soc_write(codec, i + 0x2600, cfg->regs[i]); | 266 | snd_soc_write(codec, i + 0x2600, cfg->regs[i]); |
267 | } | 267 | } |
268 | 268 | ||
269 | if (pdata && pdata->num_vss_hpf_cfgs) { | 269 | if (control->pdata.num_vss_hpf_cfgs) { |
270 | struct wm8958_vss_hpf_cfg *cfg | 270 | struct wm8958_vss_hpf_cfg *cfg |
271 | = &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg]; | 271 | = &control->pdata.vss_hpf_cfgs[wm8994->vss_hpf_cfg]; |
272 | 272 | ||
273 | for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) | 273 | for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) |
274 | snd_soc_write(codec, i + 0x2400, cfg->regs[i]); | 274 | snd_soc_write(codec, i + 0x2400, cfg->regs[i]); |
@@ -300,7 +300,7 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) | |||
300 | static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) | 300 | static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) |
301 | { | 301 | { |
302 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 302 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
303 | struct wm8994_pdata *pdata = wm8994->pdata; | 303 | struct wm8994 *control = wm8994->wm8994; |
304 | int i; | 304 | int i; |
305 | 305 | ||
306 | wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false); | 306 | wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false); |
@@ -309,9 +309,9 @@ static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) | |||
309 | WM8958_DSP2_ENA, WM8958_DSP2_ENA); | 309 | WM8958_DSP2_ENA, WM8958_DSP2_ENA); |
310 | 310 | ||
311 | /* If we've got user supplied settings use them */ | 311 | /* If we've got user supplied settings use them */ |
312 | if (pdata && pdata->num_enh_eq_cfgs) { | 312 | if (control->pdata.num_enh_eq_cfgs) { |
313 | struct wm8958_enh_eq_cfg *cfg | 313 | struct wm8958_enh_eq_cfg *cfg |
314 | = &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg]; | 314 | = &control->pdata.enh_eq_cfgs[wm8994->enh_eq_cfg]; |
315 | 315 | ||
316 | for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) | 316 | for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) |
317 | snd_soc_write(codec, i + 0x2200, | 317 | snd_soc_write(codec, i + 0x2200, |
@@ -458,7 +458,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, | |||
458 | { | 458 | { |
459 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 459 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
460 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 460 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
461 | struct wm8994_pdata *pdata = wm8994->pdata; | 461 | struct wm8994 *control = wm8994->wm8994; |
462 | int value = ucontrol->value.integer.value[0]; | 462 | int value = ucontrol->value.integer.value[0]; |
463 | int reg; | 463 | int reg; |
464 | 464 | ||
@@ -467,7 +467,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, | |||
467 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) | 467 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) |
468 | return -EBUSY; | 468 | return -EBUSY; |
469 | 469 | ||
470 | if (value >= pdata->num_mbc_cfgs) | 470 | if (value >= control->pdata.num_mbc_cfgs) |
471 | return -EINVAL; | 471 | return -EINVAL; |
472 | 472 | ||
473 | wm8994->mbc_cfg = value; | 473 | wm8994->mbc_cfg = value; |
@@ -548,7 +548,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, | |||
548 | { | 548 | { |
549 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 549 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
550 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 550 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
551 | struct wm8994_pdata *pdata = wm8994->pdata; | 551 | struct wm8994 *control = wm8994->wm8994; |
552 | int value = ucontrol->value.integer.value[0]; | 552 | int value = ucontrol->value.integer.value[0]; |
553 | int reg; | 553 | int reg; |
554 | 554 | ||
@@ -557,7 +557,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, | |||
557 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) | 557 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) |
558 | return -EBUSY; | 558 | return -EBUSY; |
559 | 559 | ||
560 | if (value >= pdata->num_vss_cfgs) | 560 | if (value >= control->pdata.num_vss_cfgs) |
561 | return -EINVAL; | 561 | return -EINVAL; |
562 | 562 | ||
563 | wm8994->vss_cfg = value; | 563 | wm8994->vss_cfg = value; |
@@ -581,7 +581,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, | |||
581 | { | 581 | { |
582 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 582 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
583 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 583 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
584 | struct wm8994_pdata *pdata = wm8994->pdata; | 584 | struct wm8994 *control = wm8994->wm8994; |
585 | int value = ucontrol->value.integer.value[0]; | 585 | int value = ucontrol->value.integer.value[0]; |
586 | int reg; | 586 | int reg; |
587 | 587 | ||
@@ -590,7 +590,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, | |||
590 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) | 590 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) |
591 | return -EBUSY; | 591 | return -EBUSY; |
592 | 592 | ||
593 | if (value >= pdata->num_vss_hpf_cfgs) | 593 | if (value >= control->pdata.num_vss_hpf_cfgs) |
594 | return -EINVAL; | 594 | return -EINVAL; |
595 | 595 | ||
596 | wm8994->vss_hpf_cfg = value; | 596 | wm8994->vss_hpf_cfg = value; |
@@ -748,7 +748,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, | |||
748 | { | 748 | { |
749 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 749 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
750 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 750 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
751 | struct wm8994_pdata *pdata = wm8994->pdata; | 751 | struct wm8994 *control = wm8994->wm8994; |
752 | int value = ucontrol->value.integer.value[0]; | 752 | int value = ucontrol->value.integer.value[0]; |
753 | int reg; | 753 | int reg; |
754 | 754 | ||
@@ -757,7 +757,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, | |||
757 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) | 757 | if (reg < 0 || reg & WM8958_DSP2CLK_ENA) |
758 | return -EBUSY; | 758 | return -EBUSY; |
759 | 759 | ||
760 | if (value >= pdata->num_enh_eq_cfgs) | 760 | if (value >= control->pdata.num_enh_eq_cfgs) |
761 | return -EINVAL; | 761 | return -EINVAL; |
762 | 762 | ||
763 | wm8994->enh_eq_cfg = value; | 763 | wm8994->enh_eq_cfg = value; |
@@ -883,13 +883,6 @@ static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) | |||
883 | wm8994->mbc_vss = fw; | 883 | wm8994->mbc_vss = fw; |
884 | mutex_unlock(&codec->mutex); | 884 | mutex_unlock(&codec->mutex); |
885 | } | 885 | } |
886 | |||
887 | /* We can't have more than one request outstanding at once so | ||
888 | * we daisy chain. | ||
889 | */ | ||
890 | request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | ||
891 | "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL, | ||
892 | codec, wm8958_enh_eq_loaded); | ||
893 | } | 886 | } |
894 | 887 | ||
895 | static void wm8958_mbc_loaded(const struct firmware *fw, void *context) | 888 | static void wm8958_mbc_loaded(const struct firmware *fw, void *context) |
@@ -897,25 +890,18 @@ static void wm8958_mbc_loaded(const struct firmware *fw, void *context) | |||
897 | struct snd_soc_codec *codec = context; | 890 | struct snd_soc_codec *codec = context; |
898 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 891 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
899 | 892 | ||
900 | if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0) | 893 | if (fw && (wm8958_dsp2_fw(codec, "MBC", fw, true) == 0)) { |
901 | return; | 894 | mutex_lock(&codec->mutex); |
902 | 895 | wm8994->mbc = fw; | |
903 | mutex_lock(&codec->mutex); | 896 | mutex_unlock(&codec->mutex); |
904 | wm8994->mbc = fw; | 897 | } |
905 | mutex_unlock(&codec->mutex); | ||
906 | |||
907 | /* We can't have more than one request outstanding at once so | ||
908 | * we daisy chain. | ||
909 | */ | ||
910 | request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | ||
911 | "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL, | ||
912 | codec, wm8958_mbc_vss_loaded); | ||
913 | } | 898 | } |
914 | 899 | ||
915 | void wm8958_dsp2_init(struct snd_soc_codec *codec) | 900 | void wm8958_dsp2_init(struct snd_soc_codec *codec) |
916 | { | 901 | { |
917 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 902 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
918 | struct wm8994_pdata *pdata = wm8994->pdata; | 903 | struct wm8994 *control = wm8994->wm8994; |
904 | struct wm8994_pdata *pdata = &control->pdata; | ||
919 | int ret, i; | 905 | int ret, i; |
920 | 906 | ||
921 | wm8994->dsp_active = -1; | 907 | wm8994->dsp_active = -1; |
@@ -932,9 +918,12 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
932 | request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | 918 | request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, |
933 | "wm8958_mbc.wfw", codec->dev, GFP_KERNEL, | 919 | "wm8958_mbc.wfw", codec->dev, GFP_KERNEL, |
934 | codec, wm8958_mbc_loaded); | 920 | codec, wm8958_mbc_loaded); |
935 | 921 | request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | |
936 | if (!pdata) | 922 | "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL, |
937 | return; | 923 | codec, wm8958_mbc_vss_loaded); |
924 | request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, | ||
925 | "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL, | ||
926 | codec, wm8958_enh_eq_loaded); | ||
938 | 927 | ||
939 | if (pdata->num_mbc_cfgs) { | 928 | if (pdata->num_mbc_cfgs) { |
940 | struct snd_kcontrol_new control[] = { | 929 | struct snd_kcontrol_new control[] = { |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b2b2b37131bd..60b34ff8179b 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -91,8 +91,6 @@ static int wm8994_retune_mobile_base[] = { | |||
91 | WM8994_AIF2_EQ_GAINS_1, | 91 | WM8994_AIF2_EQ_GAINS_1, |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static void wm8958_default_micdet(u16 status, void *data); | ||
95 | |||
96 | static const struct wm8958_micd_rate micdet_rates[] = { | 94 | static const struct wm8958_micd_rate micdet_rates[] = { |
97 | { 32768, true, 1, 4 }, | 95 | { 32768, true, 1, 4 }, |
98 | { 32768, false, 1, 1 }, | 96 | { 32768, false, 1, 1 }, |
@@ -110,15 +108,12 @@ static const struct wm8958_micd_rate jackdet_rates[] = { | |||
110 | static void wm8958_micd_set_rate(struct snd_soc_codec *codec) | 108 | static void wm8958_micd_set_rate(struct snd_soc_codec *codec) |
111 | { | 109 | { |
112 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 110 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
111 | struct wm8994 *control = wm8994->wm8994; | ||
113 | int best, i, sysclk, val; | 112 | int best, i, sysclk, val; |
114 | bool idle; | 113 | bool idle; |
115 | const struct wm8958_micd_rate *rates; | 114 | const struct wm8958_micd_rate *rates; |
116 | int num_rates; | 115 | int num_rates; |
117 | 116 | ||
118 | if (!(wm8994->pdata && wm8994->pdata->micd_rates) && | ||
119 | wm8994->jack_cb != wm8958_default_micdet) | ||
120 | return; | ||
121 | |||
122 | idle = !wm8994->jack_mic; | 117 | idle = !wm8994->jack_mic; |
123 | 118 | ||
124 | sysclk = snd_soc_read(codec, WM8994_CLOCKING_1); | 119 | sysclk = snd_soc_read(codec, WM8994_CLOCKING_1); |
@@ -127,9 +122,9 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec) | |||
127 | else | 122 | else |
128 | sysclk = wm8994->aifclk[0]; | 123 | sysclk = wm8994->aifclk[0]; |
129 | 124 | ||
130 | if (wm8994->pdata && wm8994->pdata->micd_rates) { | 125 | if (control->pdata.micd_rates) { |
131 | rates = wm8994->pdata->micd_rates; | 126 | rates = control->pdata.micd_rates; |
132 | num_rates = wm8994->pdata->num_micd_rates; | 127 | num_rates = control->pdata.num_micd_rates; |
133 | } else if (wm8994->jackdet) { | 128 | } else if (wm8994->jackdet) { |
134 | rates = jackdet_rates; | 129 | rates = jackdet_rates; |
135 | num_rates = ARRAY_SIZE(jackdet_rates); | 130 | num_rates = ARRAY_SIZE(jackdet_rates); |
@@ -326,7 +321,8 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, | |||
326 | static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) | 321 | static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) |
327 | { | 322 | { |
328 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 323 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
329 | struct wm8994_pdata *pdata = wm8994->pdata; | 324 | struct wm8994 *control = wm8994->wm8994; |
325 | struct wm8994_pdata *pdata = &control->pdata; | ||
330 | int base = wm8994_drc_base[drc]; | 326 | int base = wm8994_drc_base[drc]; |
331 | int cfg = wm8994->drc_cfg[drc]; | 327 | int cfg = wm8994->drc_cfg[drc]; |
332 | int save, i; | 328 | int save, i; |
@@ -362,7 +358,8 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, | |||
362 | { | 358 | { |
363 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 359 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
364 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 360 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
365 | struct wm8994_pdata *pdata = wm8994->pdata; | 361 | struct wm8994 *control = wm8994->wm8994; |
362 | struct wm8994_pdata *pdata = &control->pdata; | ||
366 | int drc = wm8994_get_drc(kcontrol->id.name); | 363 | int drc = wm8994_get_drc(kcontrol->id.name); |
367 | int value = ucontrol->value.integer.value[0]; | 364 | int value = ucontrol->value.integer.value[0]; |
368 | 365 | ||
@@ -394,7 +391,8 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, | |||
394 | static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) | 391 | static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) |
395 | { | 392 | { |
396 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 393 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
397 | struct wm8994_pdata *pdata = wm8994->pdata; | 394 | struct wm8994 *control = wm8994->wm8994; |
395 | struct wm8994_pdata *pdata = &control->pdata; | ||
398 | int base = wm8994_retune_mobile_base[block]; | 396 | int base = wm8994_retune_mobile_base[block]; |
399 | int iface, best, best_val, save, i, cfg; | 397 | int iface, best, best_val, save, i, cfg; |
400 | 398 | ||
@@ -465,7 +463,8 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, | |||
465 | { | 463 | { |
466 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 464 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
467 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 465 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
468 | struct wm8994_pdata *pdata = wm8994->pdata; | 466 | struct wm8994 *control = wm8994->wm8994; |
467 | struct wm8994_pdata *pdata = &control->pdata; | ||
469 | int block = wm8994_get_retune_mobile_block(kcontrol->id.name); | 468 | int block = wm8994_get_retune_mobile_block(kcontrol->id.name); |
470 | int value = ucontrol->value.integer.value[0]; | 469 | int value = ucontrol->value.integer.value[0]; |
471 | 470 | ||
@@ -736,7 +735,7 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode) | |||
736 | { | 735 | { |
737 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 736 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
738 | 737 | ||
739 | if (!wm8994->jackdet || !wm8994->jack_cb) | 738 | if (!wm8994->jackdet || !wm8994->micdet[0].jack) |
740 | return; | 739 | return; |
741 | 740 | ||
742 | if (wm8994->active_refcount) | 741 | if (wm8994->active_refcount) |
@@ -862,7 +861,7 @@ static void vmid_reference(struct snd_soc_codec *codec) | |||
862 | WM8994_BIAS_SRC | | 861 | WM8994_BIAS_SRC | |
863 | WM8994_STARTUP_BIAS_ENA | | 862 | WM8994_STARTUP_BIAS_ENA | |
864 | WM8994_VMID_BUF_ENA | | 863 | WM8994_VMID_BUF_ENA | |
865 | (0x3 << WM8994_VMID_RAMP_SHIFT)); | 864 | (0x2 << WM8994_VMID_RAMP_SHIFT)); |
866 | 865 | ||
867 | /* Main bias enable, VMID=2x40k */ | 866 | /* Main bias enable, VMID=2x40k */ |
868 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | 867 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, |
@@ -870,7 +869,7 @@ static void vmid_reference(struct snd_soc_codec *codec) | |||
870 | WM8994_VMID_SEL_MASK, | 869 | WM8994_VMID_SEL_MASK, |
871 | WM8994_BIAS_ENA | 0x2); | 870 | WM8994_BIAS_ENA | 0x2); |
872 | 871 | ||
873 | msleep(50); | 872 | msleep(300); |
874 | 873 | ||
875 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | 874 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, |
876 | WM8994_VMID_RAMP_MASK | | 875 | WM8994_VMID_RAMP_MASK | |
@@ -939,16 +938,10 @@ static void vmid_dereference(struct snd_soc_codec *codec) | |||
939 | WM8994_BIAS_SRC | | 938 | WM8994_BIAS_SRC | |
940 | WM8994_VMID_DISCH); | 939 | WM8994_VMID_DISCH); |
941 | 940 | ||
942 | switch (wm8994->vmid_mode) { | 941 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, |
943 | case WM8994_VMID_FORCE: | 942 | WM8994_VMID_SEL_MASK, 0); |
944 | msleep(350); | ||
945 | break; | ||
946 | default: | ||
947 | break; | ||
948 | } | ||
949 | 943 | ||
950 | snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL, | 944 | msleep(400); |
951 | WM8994_VROI, WM8994_VROI); | ||
952 | 945 | ||
953 | /* Active discharge */ | 946 | /* Active discharge */ |
954 | snd_soc_update_bits(codec, WM8994_ANTIPOP_1, | 947 | snd_soc_update_bits(codec, WM8994_ANTIPOP_1, |
@@ -957,17 +950,12 @@ static void vmid_dereference(struct snd_soc_codec *codec) | |||
957 | WM8994_LINEOUT1_DISCH | | 950 | WM8994_LINEOUT1_DISCH | |
958 | WM8994_LINEOUT2_DISCH); | 951 | WM8994_LINEOUT2_DISCH); |
959 | 952 | ||
960 | msleep(150); | ||
961 | |||
962 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3, | 953 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3, |
963 | WM8994_LINEOUT1N_ENA | | 954 | WM8994_LINEOUT1N_ENA | |
964 | WM8994_LINEOUT1P_ENA | | 955 | WM8994_LINEOUT1P_ENA | |
965 | WM8994_LINEOUT2N_ENA | | 956 | WM8994_LINEOUT2N_ENA | |
966 | WM8994_LINEOUT2P_ENA, 0); | 957 | WM8994_LINEOUT2P_ENA, 0); |
967 | 958 | ||
968 | snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL, | ||
969 | WM8994_VROI, 0); | ||
970 | |||
971 | /* Switch off startup biases */ | 959 | /* Switch off startup biases */ |
972 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | 960 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, |
973 | WM8994_BIAS_SRC | | 961 | WM8994_BIAS_SRC | |
@@ -976,10 +964,7 @@ static void vmid_dereference(struct snd_soc_codec *codec) | |||
976 | WM8994_VMID_RAMP_MASK, 0); | 964 | WM8994_VMID_RAMP_MASK, 0); |
977 | 965 | ||
978 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | 966 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, |
979 | WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0); | 967 | WM8994_VMID_SEL_MASK, 0); |
980 | |||
981 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
982 | WM8994_VMID_RAMP_MASK, 0); | ||
983 | } | 968 | } |
984 | 969 | ||
985 | pm_runtime_put(codec->dev); | 970 | pm_runtime_put(codec->dev); |
@@ -2277,6 +2262,18 @@ out: | |||
2277 | 2262 | ||
2278 | configure_clock(codec); | 2263 | configure_clock(codec); |
2279 | 2264 | ||
2265 | /* | ||
2266 | * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers | ||
2267 | * for detection. | ||
2268 | */ | ||
2269 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { | ||
2270 | dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); | ||
2271 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, | ||
2272 | WM8994_AIF1CLK_RATE_MASK, 0x1); | ||
2273 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, | ||
2274 | WM8994_AIF2CLK_RATE_MASK, 0x1); | ||
2275 | } | ||
2276 | |||
2280 | return 0; | 2277 | return 0; |
2281 | } | 2278 | } |
2282 | 2279 | ||
@@ -2365,6 +2362,18 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, | |||
2365 | 2362 | ||
2366 | configure_clock(codec); | 2363 | configure_clock(codec); |
2367 | 2364 | ||
2365 | /* | ||
2366 | * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers | ||
2367 | * for detection. | ||
2368 | */ | ||
2369 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { | ||
2370 | dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); | ||
2371 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, | ||
2372 | WM8994_AIF1CLK_RATE_MASK, 0x1); | ||
2373 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, | ||
2374 | WM8994_AIF2CLK_RATE_MASK, 0x1); | ||
2375 | } | ||
2376 | |||
2368 | return 0; | 2377 | return 0; |
2369 | } | 2378 | } |
2370 | 2379 | ||
@@ -3082,7 +3091,8 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec) | |||
3082 | static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | 3091 | static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) |
3083 | { | 3092 | { |
3084 | struct snd_soc_codec *codec = wm8994->hubs.codec; | 3093 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3085 | struct wm8994_pdata *pdata = wm8994->pdata; | 3094 | struct wm8994 *control = wm8994->wm8994; |
3095 | struct wm8994_pdata *pdata = &control->pdata; | ||
3086 | struct snd_kcontrol_new controls[] = { | 3096 | struct snd_kcontrol_new controls[] = { |
3087 | SOC_ENUM_EXT("AIF1.1 EQ Mode", | 3097 | SOC_ENUM_EXT("AIF1.1 EQ Mode", |
3088 | wm8994->retune_mobile_enum, | 3098 | wm8994->retune_mobile_enum, |
@@ -3149,7 +3159,8 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | |||
3149 | static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | 3159 | static void wm8994_handle_pdata(struct wm8994_priv *wm8994) |
3150 | { | 3160 | { |
3151 | struct snd_soc_codec *codec = wm8994->hubs.codec; | 3161 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3152 | struct wm8994_pdata *pdata = wm8994->pdata; | 3162 | struct wm8994 *control = wm8994->wm8994; |
3163 | struct wm8994_pdata *pdata = &control->pdata; | ||
3153 | int ret, i; | 3164 | int ret, i; |
3154 | 3165 | ||
3155 | if (!pdata) | 3166 | if (!pdata) |
@@ -3389,38 +3400,80 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) | |||
3389 | return IRQ_HANDLED; | 3400 | return IRQ_HANDLED; |
3390 | } | 3401 | } |
3391 | 3402 | ||
3392 | /* Default microphone detection handler for WM8958 - the user can | 3403 | static void wm1811_micd_stop(struct snd_soc_codec *codec) |
3393 | * override this if they wish. | 3404 | { |
3394 | */ | 3405 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
3395 | static void wm8958_default_micdet(u16 status, void *data) | 3406 | |
3407 | if (!wm8994->jackdet) | ||
3408 | return; | ||
3409 | |||
3410 | mutex_lock(&wm8994->accdet_lock); | ||
3411 | |||
3412 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); | ||
3413 | |||
3414 | wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK); | ||
3415 | |||
3416 | mutex_unlock(&wm8994->accdet_lock); | ||
3417 | |||
3418 | if (wm8994->wm8994->pdata.jd_ext_cap) | ||
3419 | snd_soc_dapm_disable_pin(&codec->dapm, | ||
3420 | "MICBIAS2"); | ||
3421 | } | ||
3422 | |||
3423 | static void wm8958_button_det(struct snd_soc_codec *codec, u16 status) | ||
3396 | { | 3424 | { |
3397 | struct snd_soc_codec *codec = data; | ||
3398 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 3425 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
3399 | int report; | 3426 | int report; |
3400 | 3427 | ||
3401 | dev_dbg(codec->dev, "MICDET %x\n", status); | 3428 | report = 0; |
3429 | if (status & 0x4) | ||
3430 | report |= SND_JACK_BTN_0; | ||
3431 | |||
3432 | if (status & 0x8) | ||
3433 | report |= SND_JACK_BTN_1; | ||
3434 | |||
3435 | if (status & 0x10) | ||
3436 | report |= SND_JACK_BTN_2; | ||
3437 | |||
3438 | if (status & 0x20) | ||
3439 | report |= SND_JACK_BTN_3; | ||
3440 | |||
3441 | if (status & 0x40) | ||
3442 | report |= SND_JACK_BTN_4; | ||
3443 | |||
3444 | if (status & 0x80) | ||
3445 | report |= SND_JACK_BTN_5; | ||
3446 | |||
3447 | snd_soc_jack_report(wm8994->micdet[0].jack, report, | ||
3448 | wm8994->btn_mask); | ||
3449 | } | ||
3450 | |||
3451 | static void wm8958_mic_id(void *data, u16 status) | ||
3452 | { | ||
3453 | struct snd_soc_codec *codec = data; | ||
3454 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
3402 | 3455 | ||
3403 | /* Either nothing present or just starting detection */ | 3456 | /* Either nothing present or just starting detection */ |
3404 | if (!(status & WM8958_MICD_STS)) { | 3457 | if (!(status & WM8958_MICD_STS)) { |
3405 | if (!wm8994->jackdet) { | 3458 | /* If nothing present then clear our statuses */ |
3406 | /* If nothing present then clear our statuses */ | 3459 | dev_dbg(codec->dev, "Detected open circuit\n"); |
3407 | dev_dbg(codec->dev, "Detected open circuit\n"); | 3460 | wm8994->jack_mic = false; |
3408 | wm8994->jack_mic = false; | 3461 | wm8994->mic_detecting = true; |
3409 | wm8994->mic_detecting = true; | ||
3410 | 3462 | ||
3411 | wm8958_micd_set_rate(codec); | 3463 | wm1811_micd_stop(codec); |
3412 | 3464 | ||
3413 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, | 3465 | wm8958_micd_set_rate(codec); |
3414 | wm8994->btn_mask | | 3466 | |
3415 | SND_JACK_HEADSET); | 3467 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, |
3416 | } | 3468 | wm8994->btn_mask | |
3469 | SND_JACK_HEADSET); | ||
3417 | return; | 3470 | return; |
3418 | } | 3471 | } |
3419 | 3472 | ||
3420 | /* If the measurement is showing a high impedence we've got a | 3473 | /* If the measurement is showing a high impedence we've got a |
3421 | * microphone. | 3474 | * microphone. |
3422 | */ | 3475 | */ |
3423 | if (wm8994->mic_detecting && (status & 0x600)) { | 3476 | if (status & 0x600) { |
3424 | dev_dbg(codec->dev, "Detected microphone\n"); | 3477 | dev_dbg(codec->dev, "Detected microphone\n"); |
3425 | 3478 | ||
3426 | wm8994->mic_detecting = false; | 3479 | wm8994->mic_detecting = false; |
@@ -3433,64 +3486,67 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3433 | } | 3486 | } |
3434 | 3487 | ||
3435 | 3488 | ||
3436 | if (wm8994->mic_detecting && status & 0xfc) { | 3489 | if (status & 0xfc) { |
3437 | dev_dbg(codec->dev, "Detected headphone\n"); | 3490 | dev_dbg(codec->dev, "Detected headphone\n"); |
3438 | wm8994->mic_detecting = false; | 3491 | wm8994->mic_detecting = false; |
3439 | 3492 | ||
3440 | wm8958_micd_set_rate(codec); | 3493 | wm8958_micd_set_rate(codec); |
3441 | 3494 | ||
3442 | /* If we have jackdet that will detect removal */ | 3495 | /* If we have jackdet that will detect removal */ |
3443 | if (wm8994->jackdet) { | 3496 | wm1811_micd_stop(codec); |
3444 | mutex_lock(&wm8994->accdet_lock); | ||
3445 | |||
3446 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | ||
3447 | WM8958_MICD_ENA, 0); | ||
3448 | |||
3449 | wm1811_jackdet_set_mode(codec, | ||
3450 | WM1811_JACKDET_MODE_JACK); | ||
3451 | |||
3452 | mutex_unlock(&wm8994->accdet_lock); | ||
3453 | |||
3454 | if (wm8994->pdata->jd_ext_cap) | ||
3455 | snd_soc_dapm_disable_pin(&codec->dapm, | ||
3456 | "MICBIAS2"); | ||
3457 | } | ||
3458 | 3497 | ||
3459 | snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE, | 3498 | snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE, |
3460 | SND_JACK_HEADSET); | 3499 | SND_JACK_HEADSET); |
3461 | } | 3500 | } |
3501 | } | ||
3462 | 3502 | ||
3463 | /* Report short circuit as a button */ | 3503 | /* Deferred mic detection to allow for extra settling time */ |
3464 | if (wm8994->jack_mic) { | 3504 | static void wm1811_mic_work(struct work_struct *work) |
3465 | report = 0; | 3505 | { |
3466 | if (status & 0x4) | 3506 | struct wm8994_priv *wm8994 = container_of(work, struct wm8994_priv, |
3467 | report |= SND_JACK_BTN_0; | 3507 | mic_work.work); |
3508 | struct wm8994 *control = wm8994->wm8994; | ||
3509 | struct snd_soc_codec *codec = wm8994->hubs.codec; | ||
3468 | 3510 | ||
3469 | if (status & 0x8) | 3511 | pm_runtime_get_sync(codec->dev); |
3470 | report |= SND_JACK_BTN_1; | ||
3471 | 3512 | ||
3472 | if (status & 0x10) | 3513 | /* If required for an external cap force MICBIAS on */ |
3473 | report |= SND_JACK_BTN_2; | 3514 | if (control->pdata.jd_ext_cap) { |
3515 | snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
3516 | "MICBIAS2"); | ||
3517 | snd_soc_dapm_sync(&codec->dapm); | ||
3518 | } | ||
3474 | 3519 | ||
3475 | if (status & 0x20) | 3520 | mutex_lock(&wm8994->accdet_lock); |
3476 | report |= SND_JACK_BTN_3; | ||
3477 | 3521 | ||
3478 | if (status & 0x40) | 3522 | dev_dbg(codec->dev, "Starting mic detection\n"); |
3479 | report |= SND_JACK_BTN_4; | ||
3480 | 3523 | ||
3481 | if (status & 0x80) | 3524 | /* Use a user-supplied callback if we have one */ |
3482 | report |= SND_JACK_BTN_5; | 3525 | if (wm8994->micd_cb) { |
3526 | wm8994->micd_cb(wm8994->micd_cb_data); | ||
3527 | } else { | ||
3528 | /* | ||
3529 | * Start off measument of microphone impedence to find out | ||
3530 | * what's actually there. | ||
3531 | */ | ||
3532 | wm8994->mic_detecting = true; | ||
3533 | wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); | ||
3483 | 3534 | ||
3484 | snd_soc_jack_report(wm8994->micdet[0].jack, report, | 3535 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
3485 | wm8994->btn_mask); | 3536 | WM8958_MICD_ENA, WM8958_MICD_ENA); |
3486 | } | 3537 | } |
3538 | |||
3539 | mutex_unlock(&wm8994->accdet_lock); | ||
3540 | |||
3541 | pm_runtime_put(codec->dev); | ||
3487 | } | 3542 | } |
3488 | 3543 | ||
3489 | static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | 3544 | static irqreturn_t wm1811_jackdet_irq(int irq, void *data) |
3490 | { | 3545 | { |
3491 | struct wm8994_priv *wm8994 = data; | 3546 | struct wm8994_priv *wm8994 = data; |
3547 | struct wm8994 *control = wm8994->wm8994; | ||
3492 | struct snd_soc_codec *codec = wm8994->hubs.codec; | 3548 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3493 | int reg; | 3549 | int reg, delay; |
3494 | bool present; | 3550 | bool present; |
3495 | 3551 | ||
3496 | pm_runtime_get_sync(codec->dev); | 3552 | pm_runtime_get_sync(codec->dev); |
@@ -3521,18 +3577,14 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3521 | snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, | 3577 | snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, |
3522 | WM1811_JACKDET_DB, 0); | 3578 | WM1811_JACKDET_DB, 0); |
3523 | 3579 | ||
3524 | /* | 3580 | delay = control->pdata.micdet_delay; |
3525 | * Start off measument of microphone impedence to find | 3581 | schedule_delayed_work(&wm8994->mic_work, |
3526 | * out what's actually there. | 3582 | msecs_to_jiffies(delay)); |
3527 | */ | ||
3528 | wm8994->mic_detecting = true; | ||
3529 | wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); | ||
3530 | |||
3531 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | ||
3532 | WM8958_MICD_ENA, WM8958_MICD_ENA); | ||
3533 | } else { | 3583 | } else { |
3534 | dev_dbg(codec->dev, "Jack not detected\n"); | 3584 | dev_dbg(codec->dev, "Jack not detected\n"); |
3535 | 3585 | ||
3586 | cancel_delayed_work_sync(&wm8994->mic_work); | ||
3587 | |||
3536 | snd_soc_update_bits(codec, WM8958_MICBIAS2, | 3588 | snd_soc_update_bits(codec, WM8958_MICBIAS2, |
3537 | WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); | 3589 | WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); |
3538 | 3590 | ||
@@ -3549,14 +3601,9 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3549 | 3601 | ||
3550 | mutex_unlock(&wm8994->accdet_lock); | 3602 | mutex_unlock(&wm8994->accdet_lock); |
3551 | 3603 | ||
3552 | /* If required for an external cap force MICBIAS on */ | 3604 | /* Turn off MICBIAS if it was on for an external cap */ |
3553 | if (wm8994->pdata->jd_ext_cap) { | 3605 | if (control->pdata.jd_ext_cap && !present) |
3554 | if (present) | 3606 | snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); |
3555 | snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
3556 | "MICBIAS2"); | ||
3557 | else | ||
3558 | snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); | ||
3559 | } | ||
3560 | 3607 | ||
3561 | if (present) | 3608 | if (present) |
3562 | snd_soc_jack_report(wm8994->micdet[0].jack, | 3609 | snd_soc_jack_report(wm8994->micdet[0].jack, |
@@ -3599,7 +3646,8 @@ static void wm1811_jackdet_bootstrap(struct work_struct *work) | |||
3599 | * detection algorithm. | 3646 | * detection algorithm. |
3600 | */ | 3647 | */ |
3601 | int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | 3648 | int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, |
3602 | wm8958_micdet_cb cb, void *cb_data) | 3649 | wm1811_micdet_cb det_cb, void *det_cb_data, |
3650 | wm1811_mic_id_cb id_cb, void *id_cb_data) | ||
3603 | { | 3651 | { |
3604 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 3652 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
3605 | struct wm8994 *control = wm8994->wm8994; | 3653 | struct wm8994 *control = wm8994->wm8994; |
@@ -3614,27 +3662,32 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
3614 | } | 3662 | } |
3615 | 3663 | ||
3616 | if (jack) { | 3664 | if (jack) { |
3617 | if (!cb) { | ||
3618 | dev_dbg(codec->dev, "Using default micdet callback\n"); | ||
3619 | cb = wm8958_default_micdet; | ||
3620 | cb_data = codec; | ||
3621 | } | ||
3622 | |||
3623 | snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS"); | 3665 | snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS"); |
3624 | snd_soc_dapm_sync(&codec->dapm); | 3666 | snd_soc_dapm_sync(&codec->dapm); |
3625 | 3667 | ||
3626 | wm8994->micdet[0].jack = jack; | 3668 | wm8994->micdet[0].jack = jack; |
3627 | wm8994->jack_cb = cb; | ||
3628 | wm8994->jack_cb_data = cb_data; | ||
3629 | 3669 | ||
3630 | wm8994->mic_detecting = true; | 3670 | if (det_cb) { |
3631 | wm8994->jack_mic = false; | 3671 | wm8994->micd_cb = det_cb; |
3672 | wm8994->micd_cb_data = det_cb_data; | ||
3673 | } else { | ||
3674 | wm8994->mic_detecting = true; | ||
3675 | wm8994->jack_mic = false; | ||
3676 | } | ||
3677 | |||
3678 | if (id_cb) { | ||
3679 | wm8994->mic_id_cb = id_cb; | ||
3680 | wm8994->mic_id_cb_data = id_cb_data; | ||
3681 | } else { | ||
3682 | wm8994->mic_id_cb = wm8958_mic_id; | ||
3683 | wm8994->mic_id_cb_data = codec; | ||
3684 | } | ||
3632 | 3685 | ||
3633 | wm8958_micd_set_rate(codec); | 3686 | wm8958_micd_set_rate(codec); |
3634 | 3687 | ||
3635 | /* Detect microphones and short circuits by default */ | 3688 | /* Detect microphones and short circuits by default */ |
3636 | if (wm8994->pdata->micd_lvl_sel) | 3689 | if (control->pdata.micd_lvl_sel) |
3637 | micd_lvl_sel = wm8994->pdata->micd_lvl_sel; | 3690 | micd_lvl_sel = control->pdata.micd_lvl_sel; |
3638 | else | 3691 | else |
3639 | micd_lvl_sel = 0x41; | 3692 | micd_lvl_sel = 0x41; |
3640 | 3693 | ||
@@ -3728,10 +3781,22 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3728 | trace_snd_soc_jack_irq(dev_name(codec->dev)); | 3781 | trace_snd_soc_jack_irq(dev_name(codec->dev)); |
3729 | #endif | 3782 | #endif |
3730 | 3783 | ||
3731 | if (wm8994->jack_cb) | 3784 | /* Avoid a transient report when the accessory is being removed */ |
3732 | wm8994->jack_cb(reg, wm8994->jack_cb_data); | 3785 | if (wm8994->jackdet) { |
3786 | reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); | ||
3787 | if (reg < 0) { | ||
3788 | dev_err(codec->dev, "Failed to read jack status: %d\n", | ||
3789 | reg); | ||
3790 | } else if (!(reg & WM1811_JACKDET_LVL)) { | ||
3791 | dev_dbg(codec->dev, "Ignoring removed jack\n"); | ||
3792 | return IRQ_HANDLED; | ||
3793 | } | ||
3794 | } | ||
3795 | |||
3796 | if (wm8994->mic_detecting) | ||
3797 | wm8994->mic_id_cb(wm8994->mic_id_cb_data, reg); | ||
3733 | else | 3798 | else |
3734 | dev_warn(codec->dev, "Accessory detection with no callback\n"); | 3799 | wm8958_button_det(codec, reg); |
3735 | 3800 | ||
3736 | out: | 3801 | out: |
3737 | pm_runtime_put(codec->dev); | 3802 | pm_runtime_put(codec->dev); |
@@ -3779,15 +3844,24 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3779 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | 3844 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); |
3780 | 3845 | ||
3781 | mutex_init(&wm8994->accdet_lock); | 3846 | mutex_init(&wm8994->accdet_lock); |
3782 | INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); | ||
3783 | INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, | 3847 | INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, |
3784 | wm1811_jackdet_bootstrap); | 3848 | wm1811_jackdet_bootstrap); |
3785 | 3849 | ||
3850 | switch (control->type) { | ||
3851 | case WM8994: | ||
3852 | INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); | ||
3853 | break; | ||
3854 | case WM1811: | ||
3855 | INIT_DELAYED_WORK(&wm8994->mic_work, wm1811_mic_work); | ||
3856 | break; | ||
3857 | default: | ||
3858 | break; | ||
3859 | } | ||
3860 | |||
3786 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) | 3861 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) |
3787 | init_completion(&wm8994->fll_locked[i]); | 3862 | init_completion(&wm8994->fll_locked[i]); |
3788 | 3863 | ||
3789 | if (wm8994->pdata && wm8994->pdata->micdet_irq) | 3864 | wm8994->micdet_irq = control->pdata.micdet_irq; |
3790 | wm8994->micdet_irq = wm8994->pdata->micdet_irq; | ||
3791 | 3865 | ||
3792 | pm_runtime_enable(codec->dev); | 3866 | pm_runtime_enable(codec->dev); |
3793 | pm_runtime_idle(codec->dev); | 3867 | pm_runtime_idle(codec->dev); |
@@ -3800,8 +3874,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3800 | switch (control->type) { | 3874 | switch (control->type) { |
3801 | case WM8994: | 3875 | case WM8994: |
3802 | /* Single ended line outputs should have VMID on. */ | 3876 | /* Single ended line outputs should have VMID on. */ |
3803 | if (!wm8994->pdata->lineout1_diff || | 3877 | if (!control->pdata.lineout1_diff || |
3804 | !wm8994->pdata->lineout2_diff) | 3878 | !control->pdata.lineout2_diff) |
3805 | codec->dapm.idle_bias_off = 0; | 3879 | codec->dapm.idle_bias_off = 0; |
3806 | 3880 | ||
3807 | switch (wm8994->revision) { | 3881 | switch (wm8994->revision) { |
@@ -3839,20 +3913,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3839 | wm8994->hubs.no_cache_dac_hp_direct = true; | 3913 | wm8994->hubs.no_cache_dac_hp_direct = true; |
3840 | wm8994->fll_byp = true; | 3914 | wm8994->fll_byp = true; |
3841 | 3915 | ||
3842 | switch (control->cust_id) { | 3916 | wm8994->hubs.dcs_codes_l = -9; |
3843 | case 0: | 3917 | wm8994->hubs.dcs_codes_r = -7; |
3844 | case 2: | ||
3845 | wm8994->hubs.dcs_codes_l = -9; | ||
3846 | wm8994->hubs.dcs_codes_r = -7; | ||
3847 | break; | ||
3848 | case 1: | ||
3849 | case 3: | ||
3850 | wm8994->hubs.dcs_codes_l = -8; | ||
3851 | wm8994->hubs.dcs_codes_r = -7; | ||
3852 | break; | ||
3853 | default: | ||
3854 | break; | ||
3855 | } | ||
3856 | 3918 | ||
3857 | snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1, | 3919 | snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1, |
3858 | WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN); | 3920 | WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN); |
@@ -4236,7 +4298,6 @@ static int __devinit wm8994_probe(struct platform_device *pdev) | |||
4236 | platform_set_drvdata(pdev, wm8994); | 4298 | platform_set_drvdata(pdev, wm8994); |
4237 | 4299 | ||
4238 | wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); | 4300 | wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); |
4239 | wm8994->pdata = dev_get_platdata(pdev->dev.parent); | ||
4240 | 4301 | ||
4241 | return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, | 4302 | return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, |
4242 | wm8994_dai, ARRAY_SIZE(wm8994_dai)); | 4303 | wm8994_dai, ARRAY_SIZE(wm8994_dai)); |
@@ -4266,7 +4327,7 @@ static int wm8994_resume(struct device *dev) | |||
4266 | { | 4327 | { |
4267 | struct wm8994_priv *wm8994 = dev_get_drvdata(dev); | 4328 | struct wm8994_priv *wm8994 = dev_get_drvdata(dev); |
4268 | 4329 | ||
4269 | if (wm8994->jackdet && wm8994->jack_cb) | 4330 | if (wm8994->jackdet && wm8994->jackdet_mode) |
4270 | regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2, | 4331 | regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2, |
4271 | WM1811_JACKDET_MODE_MASK, | 4332 | WM1811_JACKDET_MODE_MASK, |
4272 | WM1811_JACKDET_MODE_AUDIO); | 4333 | WM1811_JACKDET_MODE_AUDIO); |
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index ccbce5791e95..45f192702024 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h | |||
@@ -39,12 +39,14 @@ enum wm8994_vmid_mode { | |||
39 | WM8994_VMID_FORCE, | 39 | WM8994_VMID_FORCE, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | typedef void (*wm8958_micdet_cb)(u16 status, void *data); | 42 | typedef void (*wm1811_micdet_cb)(void *data); |
43 | typedef void (*wm1811_mic_id_cb)(void *data, u16 status); | ||
43 | 44 | ||
44 | int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | 45 | int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, |
45 | int micbias); | 46 | int micbias); |
46 | int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | 47 | int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, |
47 | wm8958_micdet_cb cb, void *cb_data); | 48 | wm1811_micdet_cb cb, void *det_cb_data, |
49 | wm1811_mic_id_cb id_cb, void *id_cb_data); | ||
48 | 50 | ||
49 | int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode); | 51 | int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode); |
50 | 52 | ||
@@ -138,12 +140,13 @@ struct wm8994_priv { | |||
138 | int jackdet_mode; | 140 | int jackdet_mode; |
139 | struct delayed_work jackdet_bootstrap; | 141 | struct delayed_work jackdet_bootstrap; |
140 | 142 | ||
141 | wm8958_micdet_cb jack_cb; | ||
142 | void *jack_cb_data; | ||
143 | int micdet_irq; | 143 | int micdet_irq; |
144 | wm1811_micdet_cb micd_cb; | ||
145 | void *micd_cb_data; | ||
146 | wm1811_mic_id_cb mic_id_cb; | ||
147 | void *mic_id_cb_data; | ||
144 | 148 | ||
145 | int revision; | 149 | int revision; |
146 | struct wm8994_pdata *pdata; | ||
147 | 150 | ||
148 | unsigned int aif1clk_enable:1; | 151 | unsigned int aif1clk_enable:1; |
149 | unsigned int aif2clk_enable:1; | 152 | unsigned int aif2clk_enable:1; |
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c index 0908bb05a5e7..de4cfdf5fdfc 100644 --- a/sound/soc/samsung/littlemill.c +++ b/sound/soc/samsung/littlemill.c | |||
@@ -270,7 +270,7 @@ static int littlemill_late_probe(struct snd_soc_card *card) | |||
270 | return ret; | 270 | return ret; |
271 | 271 | ||
272 | /* This will check device compatibility itself */ | 272 | /* This will check device compatibility itself */ |
273 | wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL); | 273 | wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL, NULL, NULL); |
274 | 274 | ||
275 | /* As will this */ | 275 | /* As will this */ |
276 | wm8994_mic_detect(codec, &littlemill_headset, 1); | 276 | wm8994_mic_detect(codec, &littlemill_headset, 1); |