Loading drivers/mfd/wm8994-core.c +19 −16 Original line number Diff line number Diff line Loading @@ -401,13 +401,19 @@ static const __devinitconst struct reg_default wm1811_reva_patch[] = { */ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) { struct wm8994_pdata *pdata = wm8994->dev->platform_data; struct wm8994_pdata *pdata; struct regmap_config *regmap_config; const struct reg_default *regmap_patch = NULL; const char *devname; int ret, i, patch_regs; int pulls = 0; if (dev_get_platdata(wm8994->dev)) { pdata = dev_get_platdata(wm8994->dev); wm8994->pdata = *pdata; } pdata = &wm8994->pdata; dev_set_drvdata(wm8994->dev, wm8994); /* Add the on-chip regulators first for bootstrapping */ Loading Loading @@ -604,7 +610,6 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) } } if (pdata) { wm8994->irq_base = pdata->irq_base; wm8994->gpio_base = pdata->gpio_base; Loading @@ -612,8 +617,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { if (pdata->gpio_defaults[i]) { wm8994_set_bits(wm8994, WM8994_GPIO_1 + i, 0xffff, pdata->gpio_defaults[i]); 0xffff, pdata->gpio_defaults[i]); } } Loading @@ -621,7 +625,6 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) if (pdata->spkmode_pu) pulls |= WM8994_SPKMODE_PU; } /* Disable unneeded pulls */ wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, Loading include/linux/mfd/wm8994/core.h +4 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include <linux/interrupt.h> #include <linux/regmap.h> #include <linux/mfd/wm8994/pdata.h> enum wm8994_type { WM8994 = 0, WM8958 = 1, Loading Loading @@ -55,6 +57,8 @@ struct regulator_bulk_data; struct wm8994 { struct mutex irq_lock; struct wm8994_pdata pdata; enum wm8994_type type; int revision; int cust_id; Loading include/linux/mfd/wm8994/pdata.h +5 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,11 @@ struct wm8994_pdata { unsigned int lineout1fb:1; unsigned int lineout2fb:1; /* Delay between detecting a jack and starting microphone * detect (specified in ms) */ int micdet_delay; /* IRQ for microphone detection if brought out directly as a * signal. */ Loading sound/soc/codecs/wm8958-dsp2.c +34 −45 Original line number Diff line number Diff line Loading @@ -195,7 +195,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int i; /* If the DSP is already running then noop */ Loading @@ -210,9 +210,9 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) WM8958_DSP2_ENA, WM8958_DSP2_ENA); /* If we've got user supplied MBC settings use them */ if (pdata && pdata->num_mbc_cfgs) { if (control->pdata.num_mbc_cfgs) { struct wm8958_mbc_cfg *cfg = &pdata->mbc_cfgs[wm8994->mbc_cfg]; = &control->pdata.mbc_cfgs[wm8994->mbc_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1, Loading @@ -239,7 +239,7 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int i, ena; if (wm8994->mbc_vss) Loading @@ -249,26 +249,26 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) WM8958_DSP2_ENA, WM8958_DSP2_ENA); /* If we've got user supplied settings use them */ if (pdata && pdata->num_mbc_cfgs) { if (control->pdata.num_mbc_cfgs) { struct wm8958_mbc_cfg *cfg = &pdata->mbc_cfgs[wm8994->mbc_cfg]; = &control->pdata.mbc_cfgs[wm8994->mbc_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++) snd_soc_write(codec, i + 0x2800, cfg->combined_regs[i]); } if (pdata && pdata->num_vss_cfgs) { if (control->pdata.num_vss_cfgs) { struct wm8958_vss_cfg *cfg = &pdata->vss_cfgs[wm8994->vss_cfg]; = &control->pdata.vss_cfgs[wm8994->vss_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) snd_soc_write(codec, i + 0x2600, cfg->regs[i]); } if (pdata && pdata->num_vss_hpf_cfgs) { if (control->pdata.num_vss_hpf_cfgs) { struct wm8958_vss_hpf_cfg *cfg = &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg]; = &control->pdata.vss_hpf_cfgs[wm8994->vss_hpf_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) snd_soc_write(codec, i + 0x2400, cfg->regs[i]); Loading Loading @@ -300,7 +300,7 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int i; wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false); Loading @@ -309,9 +309,9 @@ static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) WM8958_DSP2_ENA, WM8958_DSP2_ENA); /* If we've got user supplied settings use them */ if (pdata && pdata->num_enh_eq_cfgs) { if (control->pdata.num_enh_eq_cfgs) { struct wm8958_enh_eq_cfg *cfg = &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg]; = &control->pdata.enh_eq_cfgs[wm8994->enh_eq_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) snd_soc_write(codec, i + 0x2200, Loading Loading @@ -458,7 +458,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; int reg; Loading @@ -467,7 +467,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, if (reg < 0 || reg & WM8958_DSP2CLK_ENA) return -EBUSY; if (value >= pdata->num_mbc_cfgs) if (value >= control->pdata.num_mbc_cfgs) return -EINVAL; wm8994->mbc_cfg = value; Loading Loading @@ -548,7 +548,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; int reg; Loading @@ -557,7 +557,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, if (reg < 0 || reg & WM8958_DSP2CLK_ENA) return -EBUSY; if (value >= pdata->num_vss_cfgs) if (value >= control->pdata.num_vss_cfgs) return -EINVAL; wm8994->vss_cfg = value; Loading @@ -581,7 +581,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; int reg; Loading @@ -590,7 +590,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, if (reg < 0 || reg & WM8958_DSP2CLK_ENA) return -EBUSY; if (value >= pdata->num_vss_hpf_cfgs) if (value >= control->pdata.num_vss_hpf_cfgs) return -EINVAL; wm8994->vss_hpf_cfg = value; Loading Loading @@ -748,7 +748,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; int reg; Loading @@ -757,7 +757,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, if (reg < 0 || reg & WM8958_DSP2CLK_ENA) return -EBUSY; if (value >= pdata->num_enh_eq_cfgs) if (value >= control->pdata.num_enh_eq_cfgs) return -EINVAL; wm8994->enh_eq_cfg = value; Loading Loading @@ -883,13 +883,6 @@ static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) wm8994->mbc_vss = fw; mutex_unlock(&codec->mutex); } /* We can't have more than one request outstanding at once so * we daisy chain. */ request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL, codec, wm8958_enh_eq_loaded); } static void wm8958_mbc_loaded(const struct firmware *fw, void *context) Loading @@ -897,25 +890,18 @@ static void wm8958_mbc_loaded(const struct firmware *fw, void *context) struct snd_soc_codec *codec = context; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0) return; if (fw && (wm8958_dsp2_fw(codec, "MBC", fw, true) == 0)) { mutex_lock(&codec->mutex); wm8994->mbc = fw; mutex_unlock(&codec->mutex); /* We can't have more than one request outstanding at once so * we daisy chain. */ request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL, codec, wm8958_mbc_vss_loaded); } } void wm8958_dsp2_init(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; int ret, i; wm8994->dsp_active = -1; Loading @@ -932,9 +918,12 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "wm8958_mbc.wfw", codec->dev, GFP_KERNEL, codec, wm8958_mbc_loaded); if (!pdata) return; request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL, codec, wm8958_mbc_vss_loaded); request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL, codec, wm8958_enh_eq_loaded); if (pdata->num_mbc_cfgs) { struct snd_kcontrol_new control[] = { Loading sound/soc/codecs/wm8994.c +112 −72 Original line number Diff line number Diff line Loading @@ -110,13 +110,13 @@ static const struct wm8958_micd_rate jackdet_rates[] = { static void wm8958_micd_set_rate(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; int best, i, sysclk, val; bool idle; const struct wm8958_micd_rate *rates; int num_rates; if (!(wm8994->pdata && wm8994->pdata->micd_rates) && wm8994->jack_cb != wm8958_default_micdet) if (wm8994->jack_cb != wm8958_default_micdet) return; idle = !wm8994->jack_mic; Loading @@ -127,9 +127,9 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec) else sysclk = wm8994->aifclk[0]; if (wm8994->pdata && wm8994->pdata->micd_rates) { rates = wm8994->pdata->micd_rates; num_rates = wm8994->pdata->num_micd_rates; if (control->pdata.micd_rates) { rates = control->pdata.micd_rates; num_rates = control->pdata.num_micd_rates; } else if (wm8994->jackdet) { rates = jackdet_rates; num_rates = ARRAY_SIZE(jackdet_rates); Loading Loading @@ -326,7 +326,8 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; int base = wm8994_drc_base[drc]; int cfg = wm8994->drc_cfg[drc]; int save, i; Loading Loading @@ -362,7 +363,8 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; int drc = wm8994_get_drc(kcontrol->id.name); int value = ucontrol->value.integer.value[0]; Loading Loading @@ -394,7 +396,8 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; int base = wm8994_retune_mobile_base[block]; int iface, best, best_val, save, i, cfg; Loading Loading @@ -465,7 +468,8 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; int block = wm8994_get_retune_mobile_block(kcontrol->id.name); int value = ucontrol->value.integer.value[0]; Loading Loading @@ -862,7 +866,7 @@ static void vmid_reference(struct snd_soc_codec *codec) WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA | WM8994_VMID_BUF_ENA | (0x3 << WM8994_VMID_RAMP_SHIFT)); (0x2 << WM8994_VMID_RAMP_SHIFT)); /* Main bias enable, VMID=2x40k */ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, Loading @@ -870,7 +874,7 @@ static void vmid_reference(struct snd_soc_codec *codec) WM8994_VMID_SEL_MASK, WM8994_BIAS_ENA | 0x2); msleep(50); msleep(300); snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM8994_VMID_RAMP_MASK | Loading Loading @@ -939,16 +943,10 @@ static void vmid_dereference(struct snd_soc_codec *codec) WM8994_BIAS_SRC | WM8994_VMID_DISCH); switch (wm8994->vmid_mode) { case WM8994_VMID_FORCE: msleep(350); break; default: break; } snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, WM8994_VMID_SEL_MASK, 0); snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL, WM8994_VROI, WM8994_VROI); msleep(400); /* Active discharge */ snd_soc_update_bits(codec, WM8994_ANTIPOP_1, Loading @@ -957,17 +955,12 @@ static void vmid_dereference(struct snd_soc_codec *codec) WM8994_LINEOUT1_DISCH | WM8994_LINEOUT2_DISCH); msleep(150); snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3, WM8994_LINEOUT1N_ENA | WM8994_LINEOUT1P_ENA | WM8994_LINEOUT2N_ENA | WM8994_LINEOUT2P_ENA, 0); snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL, WM8994_VROI, 0); /* Switch off startup biases */ snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM8994_BIAS_SRC | Loading @@ -976,10 +969,7 @@ static void vmid_dereference(struct snd_soc_codec *codec) WM8994_VMID_RAMP_MASK, 0); snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0); snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM8994_VMID_RAMP_MASK, 0); WM8994_VMID_SEL_MASK, 0); } pm_runtime_put(codec->dev); Loading Loading @@ -2277,6 +2267,18 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, configure_clock(codec); /* * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers * for detection. */ if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); snd_soc_update_bits(codec, WM8994_AIF1_RATE, WM8994_AIF1CLK_RATE_MASK, 0x1); snd_soc_update_bits(codec, WM8994_AIF2_RATE, WM8994_AIF2CLK_RATE_MASK, 0x1); } return 0; } Loading Loading @@ -2365,6 +2367,18 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, configure_clock(codec); /* * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers * for detection. */ if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); snd_soc_update_bits(codec, WM8994_AIF1_RATE, WM8994_AIF1CLK_RATE_MASK, 0x1); snd_soc_update_bits(codec, WM8994_AIF2_RATE, WM8994_AIF2CLK_RATE_MASK, 0x1); } return 0; } Loading Loading @@ -3082,7 +3096,8 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec) static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) { struct snd_soc_codec *codec = wm8994->hubs.codec; struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; struct snd_kcontrol_new controls[] = { SOC_ENUM_EXT("AIF1.1 EQ Mode", wm8994->retune_mobile_enum, Loading Loading @@ -3149,7 +3164,8 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) static void wm8994_handle_pdata(struct wm8994_priv *wm8994) { struct snd_soc_codec *codec = wm8994->hubs.codec; struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; int ret, i; if (!pdata) Loading Loading @@ -3451,7 +3467,7 @@ static void wm8958_default_micdet(u16 status, void *data) mutex_unlock(&wm8994->accdet_lock); if (wm8994->pdata->jd_ext_cap) if (wm8994->wm8994->pdata.jd_ext_cap) snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); } Loading Loading @@ -3486,11 +3502,48 @@ static void wm8958_default_micdet(u16 status, void *data) } } /* Deferred mic detection to allow for extra settling time */ static void wm1811_mic_work(struct work_struct *work) { struct wm8994_priv *wm8994 = container_of(work, struct wm8994_priv, mic_work.work); struct wm8994 *control = wm8994->wm8994; struct snd_soc_codec *codec = wm8994->hubs.codec; pm_runtime_get_sync(codec->dev); /* If required for an external cap force MICBIAS on */ if (control->pdata.jd_ext_cap) { snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS2"); snd_soc_dapm_sync(&codec->dapm); } mutex_lock(&wm8994->accdet_lock); dev_dbg(codec->dev, "Starting mic detection\n"); /* * Start off measument of microphone impedence to find out * what's actually there. */ wm8994->mic_detecting = true; wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, WM8958_MICD_ENA); mutex_unlock(&wm8994->accdet_lock); pm_runtime_put(codec->dev); } static irqreturn_t wm1811_jackdet_irq(int irq, void *data) { struct wm8994_priv *wm8994 = data; struct wm8994 *control = wm8994->wm8994; struct snd_soc_codec *codec = wm8994->hubs.codec; int reg; int reg, delay; bool present; pm_runtime_get_sync(codec->dev); Loading Loading @@ -3521,18 +3574,14 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, WM1811_JACKDET_DB, 0); /* * Start off measument of microphone impedence to find * out what's actually there. */ wm8994->mic_detecting = true; wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, WM8958_MICD_ENA); delay = control->pdata.micdet_delay; schedule_delayed_work(&wm8994->mic_work, msecs_to_jiffies(delay)); } else { dev_dbg(codec->dev, "Jack not detected\n"); cancel_delayed_work_sync(&wm8994->mic_work); snd_soc_update_bits(codec, WM8958_MICBIAS2, WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); Loading @@ -3549,14 +3598,9 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) mutex_unlock(&wm8994->accdet_lock); /* If required for an external cap force MICBIAS on */ if (wm8994->pdata->jd_ext_cap) { if (present) snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS2"); else /* Turn off MICBIAS if it was on for an external cap */ if (control->pdata.jd_ext_cap && !present) snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); } if (present) snd_soc_jack_report(wm8994->micdet[0].jack, Loading Loading @@ -3633,8 +3677,8 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, wm8958_micd_set_rate(codec); /* Detect microphones and short circuits by default */ if (wm8994->pdata->micd_lvl_sel) micd_lvl_sel = wm8994->pdata->micd_lvl_sel; if (control->pdata.micd_lvl_sel) micd_lvl_sel = control->pdata.micd_lvl_sel; else micd_lvl_sel = 0x41; Loading Loading @@ -3779,15 +3823,24 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); mutex_init(&wm8994->accdet_lock); INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, wm1811_jackdet_bootstrap); switch (control->type) { case WM8994: INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); break; case WM1811: INIT_DELAYED_WORK(&wm8994->mic_work, wm1811_mic_work); break; default: break; } for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) init_completion(&wm8994->fll_locked[i]); if (wm8994->pdata && wm8994->pdata->micdet_irq) wm8994->micdet_irq = wm8994->pdata->micdet_irq; wm8994->micdet_irq = control->pdata.micdet_irq; pm_runtime_enable(codec->dev); pm_runtime_idle(codec->dev); Loading @@ -3800,8 +3853,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) switch (control->type) { case WM8994: /* Single ended line outputs should have VMID on. */ if (!wm8994->pdata->lineout1_diff || !wm8994->pdata->lineout2_diff) if (!control->pdata.lineout1_diff || !control->pdata.lineout2_diff) codec->dapm.idle_bias_off = 0; switch (wm8994->revision) { Loading Loading @@ -3839,20 +3892,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm8994->hubs.no_cache_dac_hp_direct = true; wm8994->fll_byp = true; switch (control->cust_id) { case 0: case 2: wm8994->hubs.dcs_codes_l = -9; wm8994->hubs.dcs_codes_r = -7; break; case 1: case 3: wm8994->hubs.dcs_codes_l = -8; wm8994->hubs.dcs_codes_r = -7; break; default: break; } snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1, WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN); Loading Loading @@ -4236,7 +4277,6 @@ static int __devinit wm8994_probe(struct platform_device *pdev) platform_set_drvdata(pdev, wm8994); wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); wm8994->pdata = dev_get_platdata(pdev->dev.parent); return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, wm8994_dai, ARRAY_SIZE(wm8994_dai)); Loading Loading
drivers/mfd/wm8994-core.c +19 −16 Original line number Diff line number Diff line Loading @@ -401,13 +401,19 @@ static const __devinitconst struct reg_default wm1811_reva_patch[] = { */ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) { struct wm8994_pdata *pdata = wm8994->dev->platform_data; struct wm8994_pdata *pdata; struct regmap_config *regmap_config; const struct reg_default *regmap_patch = NULL; const char *devname; int ret, i, patch_regs; int pulls = 0; if (dev_get_platdata(wm8994->dev)) { pdata = dev_get_platdata(wm8994->dev); wm8994->pdata = *pdata; } pdata = &wm8994->pdata; dev_set_drvdata(wm8994->dev, wm8994); /* Add the on-chip regulators first for bootstrapping */ Loading Loading @@ -604,7 +610,6 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) } } if (pdata) { wm8994->irq_base = pdata->irq_base; wm8994->gpio_base = pdata->gpio_base; Loading @@ -612,8 +617,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { if (pdata->gpio_defaults[i]) { wm8994_set_bits(wm8994, WM8994_GPIO_1 + i, 0xffff, pdata->gpio_defaults[i]); 0xffff, pdata->gpio_defaults[i]); } } Loading @@ -621,7 +625,6 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) if (pdata->spkmode_pu) pulls |= WM8994_SPKMODE_PU; } /* Disable unneeded pulls */ wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, Loading
include/linux/mfd/wm8994/core.h +4 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include <linux/interrupt.h> #include <linux/regmap.h> #include <linux/mfd/wm8994/pdata.h> enum wm8994_type { WM8994 = 0, WM8958 = 1, Loading Loading @@ -55,6 +57,8 @@ struct regulator_bulk_data; struct wm8994 { struct mutex irq_lock; struct wm8994_pdata pdata; enum wm8994_type type; int revision; int cust_id; Loading
include/linux/mfd/wm8994/pdata.h +5 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,11 @@ struct wm8994_pdata { unsigned int lineout1fb:1; unsigned int lineout2fb:1; /* Delay between detecting a jack and starting microphone * detect (specified in ms) */ int micdet_delay; /* IRQ for microphone detection if brought out directly as a * signal. */ Loading
sound/soc/codecs/wm8958-dsp2.c +34 −45 Original line number Diff line number Diff line Loading @@ -195,7 +195,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int i; /* If the DSP is already running then noop */ Loading @@ -210,9 +210,9 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) WM8958_DSP2_ENA, WM8958_DSP2_ENA); /* If we've got user supplied MBC settings use them */ if (pdata && pdata->num_mbc_cfgs) { if (control->pdata.num_mbc_cfgs) { struct wm8958_mbc_cfg *cfg = &pdata->mbc_cfgs[wm8994->mbc_cfg]; = &control->pdata.mbc_cfgs[wm8994->mbc_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1, Loading @@ -239,7 +239,7 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int i, ena; if (wm8994->mbc_vss) Loading @@ -249,26 +249,26 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) WM8958_DSP2_ENA, WM8958_DSP2_ENA); /* If we've got user supplied settings use them */ if (pdata && pdata->num_mbc_cfgs) { if (control->pdata.num_mbc_cfgs) { struct wm8958_mbc_cfg *cfg = &pdata->mbc_cfgs[wm8994->mbc_cfg]; = &control->pdata.mbc_cfgs[wm8994->mbc_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++) snd_soc_write(codec, i + 0x2800, cfg->combined_regs[i]); } if (pdata && pdata->num_vss_cfgs) { if (control->pdata.num_vss_cfgs) { struct wm8958_vss_cfg *cfg = &pdata->vss_cfgs[wm8994->vss_cfg]; = &control->pdata.vss_cfgs[wm8994->vss_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) snd_soc_write(codec, i + 0x2600, cfg->regs[i]); } if (pdata && pdata->num_vss_hpf_cfgs) { if (control->pdata.num_vss_hpf_cfgs) { struct wm8958_vss_hpf_cfg *cfg = &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg]; = &control->pdata.vss_hpf_cfgs[wm8994->vss_hpf_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) snd_soc_write(codec, i + 0x2400, cfg->regs[i]); Loading Loading @@ -300,7 +300,7 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int i; wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false); Loading @@ -309,9 +309,9 @@ static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) WM8958_DSP2_ENA, WM8958_DSP2_ENA); /* If we've got user supplied settings use them */ if (pdata && pdata->num_enh_eq_cfgs) { if (control->pdata.num_enh_eq_cfgs) { struct wm8958_enh_eq_cfg *cfg = &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg]; = &control->pdata.enh_eq_cfgs[wm8994->enh_eq_cfg]; for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) snd_soc_write(codec, i + 0x2200, Loading Loading @@ -458,7 +458,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; int reg; Loading @@ -467,7 +467,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, if (reg < 0 || reg & WM8958_DSP2CLK_ENA) return -EBUSY; if (value >= pdata->num_mbc_cfgs) if (value >= control->pdata.num_mbc_cfgs) return -EINVAL; wm8994->mbc_cfg = value; Loading Loading @@ -548,7 +548,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; int reg; Loading @@ -557,7 +557,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, if (reg < 0 || reg & WM8958_DSP2CLK_ENA) return -EBUSY; if (value >= pdata->num_vss_cfgs) if (value >= control->pdata.num_vss_cfgs) return -EINVAL; wm8994->vss_cfg = value; Loading @@ -581,7 +581,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; int reg; Loading @@ -590,7 +590,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, if (reg < 0 || reg & WM8958_DSP2CLK_ENA) return -EBUSY; if (value >= pdata->num_vss_hpf_cfgs) if (value >= control->pdata.num_vss_hpf_cfgs) return -EINVAL; wm8994->vss_hpf_cfg = value; Loading Loading @@ -748,7 +748,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; int reg; Loading @@ -757,7 +757,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, if (reg < 0 || reg & WM8958_DSP2CLK_ENA) return -EBUSY; if (value >= pdata->num_enh_eq_cfgs) if (value >= control->pdata.num_enh_eq_cfgs) return -EINVAL; wm8994->enh_eq_cfg = value; Loading Loading @@ -883,13 +883,6 @@ static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) wm8994->mbc_vss = fw; mutex_unlock(&codec->mutex); } /* We can't have more than one request outstanding at once so * we daisy chain. */ request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL, codec, wm8958_enh_eq_loaded); } static void wm8958_mbc_loaded(const struct firmware *fw, void *context) Loading @@ -897,25 +890,18 @@ static void wm8958_mbc_loaded(const struct firmware *fw, void *context) struct snd_soc_codec *codec = context; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0) return; if (fw && (wm8958_dsp2_fw(codec, "MBC", fw, true) == 0)) { mutex_lock(&codec->mutex); wm8994->mbc = fw; mutex_unlock(&codec->mutex); /* We can't have more than one request outstanding at once so * we daisy chain. */ request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL, codec, wm8958_mbc_vss_loaded); } } void wm8958_dsp2_init(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; int ret, i; wm8994->dsp_active = -1; Loading @@ -932,9 +918,12 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "wm8958_mbc.wfw", codec->dev, GFP_KERNEL, codec, wm8958_mbc_loaded); if (!pdata) return; request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL, codec, wm8958_mbc_vss_loaded); request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL, codec, wm8958_enh_eq_loaded); if (pdata->num_mbc_cfgs) { struct snd_kcontrol_new control[] = { Loading
sound/soc/codecs/wm8994.c +112 −72 Original line number Diff line number Diff line Loading @@ -110,13 +110,13 @@ static const struct wm8958_micd_rate jackdet_rates[] = { static void wm8958_micd_set_rate(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; int best, i, sysclk, val; bool idle; const struct wm8958_micd_rate *rates; int num_rates; if (!(wm8994->pdata && wm8994->pdata->micd_rates) && wm8994->jack_cb != wm8958_default_micdet) if (wm8994->jack_cb != wm8958_default_micdet) return; idle = !wm8994->jack_mic; Loading @@ -127,9 +127,9 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec) else sysclk = wm8994->aifclk[0]; if (wm8994->pdata && wm8994->pdata->micd_rates) { rates = wm8994->pdata->micd_rates; num_rates = wm8994->pdata->num_micd_rates; if (control->pdata.micd_rates) { rates = control->pdata.micd_rates; num_rates = control->pdata.num_micd_rates; } else if (wm8994->jackdet) { rates = jackdet_rates; num_rates = ARRAY_SIZE(jackdet_rates); Loading Loading @@ -326,7 +326,8 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; int base = wm8994_drc_base[drc]; int cfg = wm8994->drc_cfg[drc]; int save, i; Loading Loading @@ -362,7 +363,8 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; int drc = wm8994_get_drc(kcontrol->id.name); int value = ucontrol->value.integer.value[0]; Loading Loading @@ -394,7 +396,8 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; int base = wm8994_retune_mobile_base[block]; int iface, best, best_val, save, i, cfg; Loading Loading @@ -465,7 +468,8 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; int block = wm8994_get_retune_mobile_block(kcontrol->id.name); int value = ucontrol->value.integer.value[0]; Loading Loading @@ -862,7 +866,7 @@ static void vmid_reference(struct snd_soc_codec *codec) WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA | WM8994_VMID_BUF_ENA | (0x3 << WM8994_VMID_RAMP_SHIFT)); (0x2 << WM8994_VMID_RAMP_SHIFT)); /* Main bias enable, VMID=2x40k */ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, Loading @@ -870,7 +874,7 @@ static void vmid_reference(struct snd_soc_codec *codec) WM8994_VMID_SEL_MASK, WM8994_BIAS_ENA | 0x2); msleep(50); msleep(300); snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM8994_VMID_RAMP_MASK | Loading Loading @@ -939,16 +943,10 @@ static void vmid_dereference(struct snd_soc_codec *codec) WM8994_BIAS_SRC | WM8994_VMID_DISCH); switch (wm8994->vmid_mode) { case WM8994_VMID_FORCE: msleep(350); break; default: break; } snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, WM8994_VMID_SEL_MASK, 0); snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL, WM8994_VROI, WM8994_VROI); msleep(400); /* Active discharge */ snd_soc_update_bits(codec, WM8994_ANTIPOP_1, Loading @@ -957,17 +955,12 @@ static void vmid_dereference(struct snd_soc_codec *codec) WM8994_LINEOUT1_DISCH | WM8994_LINEOUT2_DISCH); msleep(150); snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3, WM8994_LINEOUT1N_ENA | WM8994_LINEOUT1P_ENA | WM8994_LINEOUT2N_ENA | WM8994_LINEOUT2P_ENA, 0); snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL, WM8994_VROI, 0); /* Switch off startup biases */ snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM8994_BIAS_SRC | Loading @@ -976,10 +969,7 @@ static void vmid_dereference(struct snd_soc_codec *codec) WM8994_VMID_RAMP_MASK, 0); snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0); snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM8994_VMID_RAMP_MASK, 0); WM8994_VMID_SEL_MASK, 0); } pm_runtime_put(codec->dev); Loading Loading @@ -2277,6 +2267,18 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, configure_clock(codec); /* * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers * for detection. */ if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); snd_soc_update_bits(codec, WM8994_AIF1_RATE, WM8994_AIF1CLK_RATE_MASK, 0x1); snd_soc_update_bits(codec, WM8994_AIF2_RATE, WM8994_AIF2CLK_RATE_MASK, 0x1); } return 0; } Loading Loading @@ -2365,6 +2367,18 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, configure_clock(codec); /* * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers * for detection. */ if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); snd_soc_update_bits(codec, WM8994_AIF1_RATE, WM8994_AIF1CLK_RATE_MASK, 0x1); snd_soc_update_bits(codec, WM8994_AIF2_RATE, WM8994_AIF2CLK_RATE_MASK, 0x1); } return 0; } Loading Loading @@ -3082,7 +3096,8 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec) static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) { struct snd_soc_codec *codec = wm8994->hubs.codec; struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; struct snd_kcontrol_new controls[] = { SOC_ENUM_EXT("AIF1.1 EQ Mode", wm8994->retune_mobile_enum, Loading Loading @@ -3149,7 +3164,8 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) static void wm8994_handle_pdata(struct wm8994_priv *wm8994) { struct snd_soc_codec *codec = wm8994->hubs.codec; struct wm8994_pdata *pdata = wm8994->pdata; struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; int ret, i; if (!pdata) Loading Loading @@ -3451,7 +3467,7 @@ static void wm8958_default_micdet(u16 status, void *data) mutex_unlock(&wm8994->accdet_lock); if (wm8994->pdata->jd_ext_cap) if (wm8994->wm8994->pdata.jd_ext_cap) snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); } Loading Loading @@ -3486,11 +3502,48 @@ static void wm8958_default_micdet(u16 status, void *data) } } /* Deferred mic detection to allow for extra settling time */ static void wm1811_mic_work(struct work_struct *work) { struct wm8994_priv *wm8994 = container_of(work, struct wm8994_priv, mic_work.work); struct wm8994 *control = wm8994->wm8994; struct snd_soc_codec *codec = wm8994->hubs.codec; pm_runtime_get_sync(codec->dev); /* If required for an external cap force MICBIAS on */ if (control->pdata.jd_ext_cap) { snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS2"); snd_soc_dapm_sync(&codec->dapm); } mutex_lock(&wm8994->accdet_lock); dev_dbg(codec->dev, "Starting mic detection\n"); /* * Start off measument of microphone impedence to find out * what's actually there. */ wm8994->mic_detecting = true; wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, WM8958_MICD_ENA); mutex_unlock(&wm8994->accdet_lock); pm_runtime_put(codec->dev); } static irqreturn_t wm1811_jackdet_irq(int irq, void *data) { struct wm8994_priv *wm8994 = data; struct wm8994 *control = wm8994->wm8994; struct snd_soc_codec *codec = wm8994->hubs.codec; int reg; int reg, delay; bool present; pm_runtime_get_sync(codec->dev); Loading Loading @@ -3521,18 +3574,14 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, WM1811_JACKDET_DB, 0); /* * Start off measument of microphone impedence to find * out what's actually there. */ wm8994->mic_detecting = true; wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, WM8958_MICD_ENA); delay = control->pdata.micdet_delay; schedule_delayed_work(&wm8994->mic_work, msecs_to_jiffies(delay)); } else { dev_dbg(codec->dev, "Jack not detected\n"); cancel_delayed_work_sync(&wm8994->mic_work); snd_soc_update_bits(codec, WM8958_MICBIAS2, WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); Loading @@ -3549,14 +3598,9 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) mutex_unlock(&wm8994->accdet_lock); /* If required for an external cap force MICBIAS on */ if (wm8994->pdata->jd_ext_cap) { if (present) snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS2"); else /* Turn off MICBIAS if it was on for an external cap */ if (control->pdata.jd_ext_cap && !present) snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); } if (present) snd_soc_jack_report(wm8994->micdet[0].jack, Loading Loading @@ -3633,8 +3677,8 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, wm8958_micd_set_rate(codec); /* Detect microphones and short circuits by default */ if (wm8994->pdata->micd_lvl_sel) micd_lvl_sel = wm8994->pdata->micd_lvl_sel; if (control->pdata.micd_lvl_sel) micd_lvl_sel = control->pdata.micd_lvl_sel; else micd_lvl_sel = 0x41; Loading Loading @@ -3779,15 +3823,24 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); mutex_init(&wm8994->accdet_lock); INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, wm1811_jackdet_bootstrap); switch (control->type) { case WM8994: INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); break; case WM1811: INIT_DELAYED_WORK(&wm8994->mic_work, wm1811_mic_work); break; default: break; } for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) init_completion(&wm8994->fll_locked[i]); if (wm8994->pdata && wm8994->pdata->micdet_irq) wm8994->micdet_irq = wm8994->pdata->micdet_irq; wm8994->micdet_irq = control->pdata.micdet_irq; pm_runtime_enable(codec->dev); pm_runtime_idle(codec->dev); Loading @@ -3800,8 +3853,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) switch (control->type) { case WM8994: /* Single ended line outputs should have VMID on. */ if (!wm8994->pdata->lineout1_diff || !wm8994->pdata->lineout2_diff) if (!control->pdata.lineout1_diff || !control->pdata.lineout2_diff) codec->dapm.idle_bias_off = 0; switch (wm8994->revision) { Loading Loading @@ -3839,20 +3892,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm8994->hubs.no_cache_dac_hp_direct = true; wm8994->fll_byp = true; switch (control->cust_id) { case 0: case 2: wm8994->hubs.dcs_codes_l = -9; wm8994->hubs.dcs_codes_r = -7; break; case 1: case 3: wm8994->hubs.dcs_codes_l = -8; wm8994->hubs.dcs_codes_r = -7; break; default: break; } snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1, WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN); Loading Loading @@ -4236,7 +4277,6 @@ static int __devinit wm8994_probe(struct platform_device *pdev) platform_set_drvdata(pdev, wm8994); wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); wm8994->pdata = dev_get_platdata(pdev->dev.parent); return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, wm8994_dai, ARRAY_SIZE(wm8994_dai)); Loading