best = 0; for (i = 0; i < num_rates; i++) { if (rates[i].idle != idle) continue; if (abs(rates[i].sysclk - sysclk) <
abs(rates[best].sysclk - sysclk))
best = i; elseif (rates[best].idle != idle)
best = i;
}
val = rates[best].start << WM8958_MICD_BIAS_STARTTIME_SHIFT
| rates[best].rate << WM8958_MICD_RATE_SHIFT;
staticint configure_aif_clock(struct snd_soc_component *component, int aif)
{ struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); int rate; int reg1 = 0; int offset;
if (aif)
offset = 4; else
offset = 0;
switch (wm8994->sysclk[aif]) { case WM8994_SYSCLK_MCLK1:
rate = wm8994->mclk_rate[0]; break;
case WM8994_SYSCLK_MCLK2:
reg1 |= 0x8;
rate = wm8994->mclk_rate[1]; break;
case WM8994_SYSCLK_FLL1:
reg1 |= 0x10;
rate = wm8994->fll[0].out; break;
case WM8994_SYSCLK_FLL2:
reg1 |= 0x18;
rate = wm8994->fll[1].out; break;
/* Bring up the AIF clocks first */
configure_aif_clock(component, 0);
configure_aif_clock(component, 1);
/* Then switch CLK_SYS over to the higher of them; a change * can only happen as a result of a clocking change which can * only be made outside of DAPM so we can safely redo the * clocking.
*/
/* If they're equal it doesn't matter which is used */ if (wm8994->aifclk[0] == wm8994->aifclk[1]) {
wm8958_micd_set_rate(component); return 0;
}
if (wm8994->aifclk[0] < wm8994->aifclk[1]) new = WM8994_SYSCLK_SRC; else new = 0;
change = snd_soc_component_update_bits(component, WM8994_CLOCKING_1,
WM8994_SYSCLK_SRC, new); if (change)
snd_soc_dapm_sync(dapm);
/* Can't enable both ADC and DAC paths simultaneously */ if (mc->shift == WM8994_AIF1DAC1_DRC_ENA_SHIFT)
mask = WM8994_AIF1ADC1L_DRC_ENA_MASK |
WM8994_AIF1ADC1R_DRC_ENA_MASK; else
mask = WM8994_AIF1DAC1_DRC_ENA_MASK;
ret = snd_soc_component_read(component, mc->reg); if (ret < 0) return ret; if (ret & mask) return -EINVAL;
return snd_soc_put_volsw(kcontrol, ucontrol);
}
staticvoid wm8994_set_drc(struct snd_soc_component *component, int drc)
{ struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 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;
/* Save any enables; the configuration should clear them. */
save = snd_soc_component_read(component, base);
save &= WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
WM8994_AIF1ADC1R_DRC_ENA;
for (i = 0; i < WM8994_DRC_REGS; i++)
snd_soc_component_update_bits(component, base + i, 0xffff,
pdata->drc_cfgs[cfg].regs[i]);
if (drc < 0) return drc;
ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc];
return 0;
}
staticvoid wm8994_set_retune_mobile(struct snd_soc_component *component, int block)
{ struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 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;
if (!pdata || !wm8994->num_retune_mobile_texts) return;
switch (block) { case 0: case 1:
iface = 0; break; case 2:
iface = 1; break; default: return;
}
/* Find the version of the currently selected configuration
* with the nearest sample rate. */
cfg = wm8994->retune_mobile_cfg[block];
best = 0;
best_val = INT_MAX; for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) { if (strcmp(pdata->retune_mobile_cfgs[i].name,
wm8994->retune_mobile_texts[cfg]) == 0 &&
abs(pdata->retune_mobile_cfgs[i].rate
- wm8994->dac_rates[iface]) < best_val) {
best = i;
best_val = abs(pdata->retune_mobile_cfgs[i].rate
- wm8994->dac_rates[iface]);
}
}
dev_dbg(component->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
block,
pdata->retune_mobile_cfgs[best].name,
pdata->retune_mobile_cfgs[best].rate,
wm8994->dac_rates[iface]);
/* The EQ will be disabled while reconfiguring it, remember the * current configuration.
*/
save = snd_soc_component_read(component, base);
save &= WM8994_AIF1DAC1_EQ_ENA;
for (i = 0; i < WM8994_EQ_REGS; i++)
snd_soc_component_update_bits(component, base + i, 0xffff,
pdata->retune_mobile_cfgs[best].regs[i]);
/* We run all mode setting through a function to enforce audio mode */ staticvoid wm1811_jackdet_set_mode(struct snd_soc_component *component, u16 mode)
{ struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
if (!wm8994->jackdet || !wm8994->micdet[0].jack) return;
if (wm8994->active_refcount)
mode = WM1811_JACKDET_MODE_AUDIO;
if (mode == wm8994->jackdet_mode) return;
wm8994->jackdet_mode = mode;
/* Always use audio mode to detect while the system is active */ if (mode != WM1811_JACKDET_MODE_NONE)
mode = WM1811_JACKDET_MODE_AUDIO;
dev_dbg(component->dev, "Active refcount decremented, now %d\n",
wm8994->active_refcount);
if (wm8994->active_refcount == 0) { /* Go into appropriate detection only mode */ if (wm8994->jack_mic || wm8994->mic_detecting)
mode = WM1811_JACKDET_MODE_MIC; else
mode = WM1811_JACKDET_MODE_JACK;
switch (event) { case SND_SOC_DAPM_PRE_PMU: return configure_clock(component);
case SND_SOC_DAPM_POST_PMU: /* * JACKDET won't run until we start the clock and it * only reports deltas, make sure we notify the state * up the stack on startup. Use a *very* generous * timeout for paranoia, there's no urgency and we * don't want false reports.
*/ if (wm8994->jackdet && !wm8994->clk_has_run) {
queue_delayed_work(system_power_efficient_wq,
&wm8994->jackdet_bootstrap,
msecs_to_jiffies(1000));
wm8994->clk_has_run = true;
} break;
case SND_SOC_DAPM_POST_PMD:
configure_clock(component); break;
}
switch (event) { case SND_SOC_DAPM_PRE_PMU:
vmid_reference(component); break;
case SND_SOC_DAPM_POST_PMD:
vmid_dereference(component); break;
}
return 0;
}
staticbool wm8994_check_class_w_digital(struct snd_soc_component *component)
{ int source = 0; /* GCC flow analysis can't track enable */ int reg, reg_r;
/* We also need the same AIF source for L/R and only one path */
reg = snd_soc_component_read(component, WM8994_DAC1_LEFT_MIXER_ROUTING); switch (reg) { case WM8994_AIF2DACL_TO_DAC1L:
dev_vdbg(component->dev, "Class W source AIF2DAC\n");
source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT; break; case WM8994_AIF1DAC2L_TO_DAC1L:
dev_vdbg(component->dev, "Class W source AIF1DAC2\n");
source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT; break; case WM8994_AIF1DAC1L_TO_DAC1L:
dev_vdbg(component->dev, "Class W source AIF1DAC1\n");
source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT; break; default:
dev_vdbg(component->dev, "DAC mixer setting: %x\n", reg); returnfalse;
}
reg_r = snd_soc_component_read(component, WM8994_DAC1_RIGHT_MIXER_ROUTING); if (reg_r != reg) {
dev_vdbg(component->dev, "Left and right DAC mixers different\n"); returnfalse;
}
/* Set the source up */
snd_soc_component_update_bits(component, WM8994_CLASS_W_1,
WM8994_CP_DYN_SRC_SEL_MASK, source);
for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
snd_soc_component_write(component, wm8994_vu_bits[i].reg,
snd_soc_component_read(component,
wm8994_vu_bits[i].reg)); if (control->type == WM1811) return;
for (i = 0; i < ARRAY_SIZE(wm8994_adc2_dac2_vu_bits); i++)
snd_soc_component_write(component,
wm8994_adc2_dac2_vu_bits[i].reg,
snd_soc_component_read(component,
wm8994_adc2_dac2_vu_bits[i].reg));
}
staticint aif_mclk_set(struct snd_soc_component *component, int aif, bool enable)
{ struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); unsignedint offset, val, clk_idx; int ret;
if (aif)
offset = 4; else
offset = 0;
val = snd_soc_component_read(component, WM8994_AIF1_CLOCKING_1 + offset);
val &= WM8994_AIF1CLK_SRC_MASK;
switch (val) { case 0:
clk_idx = WM8994_MCLK1; break; case 1:
clk_idx = WM8994_MCLK2; break; default: return 0;
}
if (enable) {
ret = clk_prepare_enable(wm8994->mclk[clk_idx].clk); if (ret < 0) {
dev_err(component->dev, "Failed to enable MCLK%d\n",
clk_idx); return ret;
}
} else {
clk_disable_unprepare(wm8994->mclk[clk_idx].clk);
}
return 0;
}
staticint aif1clk_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event)
{ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); struct wm8994 *control = wm8994->wm8994; int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA; int ret; int dac; int adc; int val;
switch (control->type) { case WM8994: case WM8958:
mask |= WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA; break; default: break;
}
switch (event) { case SND_SOC_DAPM_PRE_PMU:
ret = aif_mclk_set(component, 0, true); if (ret < 0) return ret;
/* Don't enable timeslot 2 if not in use */ if (wm8994->channels[0] <= 2)
mask &= ~(WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
case SND_SOC_DAPM_POST_PMU:
wm8994_update_vu_bits(component); break;
case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_POST_PMD:
snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_5,
mask, 0);
snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_4,
mask, 0);
val = snd_soc_component_read(component, WM8994_CLOCKING_1); if (val & WM8994_AIF2DSPCLK_ENA)
val = WM8994_SYSDSPCLK_ENA; else
val = 0;
snd_soc_component_update_bits(component, WM8994_CLOCKING_1,
WM8994_SYSDSPCLK_ENA |
WM8994_AIF1DSPCLK_ENA, val); break;
}
switch (event) { case SND_SOC_DAPM_POST_PMD:
aif_mclk_set(component, 0, false); break;
}
return 0;
}
staticint aif2clk_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event)
{ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); int ret; int dac; int adc; int val;
switch (event) { case SND_SOC_DAPM_PRE_PMU:
ret = aif_mclk_set(component, 1, true); if (ret < 0) return ret;
/* Note that these two control shouldn't be simultaneously switched to AIF3 */ static SOC_ENUM_SINGLE_DECL(aif2dacl_src_enum,
WM8994_POWER_MANAGEMENT_6, 7, aif2dac_src_text);
/* Power is done with the muxes since the ADC power also controls the * downsampling chain, the chip will automatically manage the analogue * specific portions.
*/
SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
switch (src) { case 0: /* Allow no source specification when stopping */ if (freq_out) return -EINVAL;
src = wm8994->fll[id].src; break; case WM8994_FLL_SRC_MCLK1: case WM8994_FLL_SRC_MCLK2: case WM8994_FLL_SRC_LRCLK: case WM8994_FLL_SRC_BCLK: break; case WM8994_FLL_SRC_INTERNAL:
freq_in = 12000000;
freq_out = 12000000; break; default: return -EINVAL;
}
/* Are we changing anything? */ if (wm8994->fll[id].src == src &&
wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out) return 0;
/* If we're stopping the FLL redo the old config - no * registers will actually be written but we avoid GCC flow * analysis bugs spewing warnings.
*/ if (freq_out)
ret = wm8994_get_fll_config(control, &fll, freq_in, freq_out); else
ret = wm8994_get_fll_config(control, &fll, wm8994->fll[id].in,
wm8994->fll[id].out); if (ret < 0) return ret;
/* Make sure that we're not providing SYSCLK right now */
clk1 = snd_soc_component_read(component, WM8994_CLOCKING_1); if (clk1 & WM8994_SYSCLK_SRC)
aif_reg = WM8994_AIF2_CLOCKING_1; else
aif_reg = WM8994_AIF1_CLOCKING_1;
reg = snd_soc_component_read(component, aif_reg);
if ((reg & WM8994_AIF1CLK_ENA) &&
(reg & WM8994_AIF1CLK_SRC_MASK) == aif_src) {
dev_err(component->dev, "FLL%d is currently providing SYSCLK\n",
id + 1); return -EBUSY;
}
/* We always need to disable the FLL while reconfiguring */
snd_soc_component_update_bits(component, WM8994_FLL1_CONTROL_1 + reg_offset,
WM8994_FLL1_ENA, 0);
/* Disable MCLK if needed before we possibly change to new clock parent */ if (was_enabled) {
reg = snd_soc_component_read(component, WM8994_FLL1_CONTROL_5
+ reg_offset);
reg = ((reg & WM8994_FLL1_REFCLK_SRC_MASK)
>> WM8994_FLL1_REFCLK_SRC_SHIFT) + 1;
switch (reg) { case WM8994_FLL_SRC_MCLK1:
mclk = wm8994->mclk[WM8994_MCLK1].clk; break; case WM8994_FLL_SRC_MCLK2:
mclk = wm8994->mclk[WM8994_MCLK2].clk; break; default:
mclk = NULL;
}
/* Clear any pending completion from a previous failure */
try_wait_for_completion(&wm8994->fll_locked[id]);
switch (src) { case WM8994_FLL_SRC_MCLK1:
mclk = wm8994->mclk[WM8994_MCLK1].clk; break; case WM8994_FLL_SRC_MCLK2:
mclk = wm8994->mclk[WM8994_MCLK2].clk; break; default:
mclk = NULL;
}
/* Enable (with fractional mode if required) */ if (freq_out) {
ret = clk_prepare_enable(mclk); if (ret < 0) {
dev_err(component->dev, "Failed to enable MCLK for FLL%d\n",
id + 1); return ret;
}
/* Enable VMID if we need it */ if (!was_enabled) {
active_reference(component);
switch (control->type) { case WM8994:
vmid_reference(component); break; case WM8958: if (control->revision < 1)
vmid_reference(component); break; default: break;
}
}
reg = WM8994_FLL1_ENA;
if (fll.k)
reg |= WM8994_FLL1_FRAC; if (src == WM8994_FLL_SRC_INTERNAL)
reg |= WM8994_FLL1_OSC_ENA;
/* * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers * for detection.
*/ if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) {
dev_dbg(component->dev, "Configuring AIFs for 128fs\n");
switch (clk_id) { case WM8994_SYSCLK_MCLK1:
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1;
ret = wm8994_set_mclk_rate(wm8994, dai->id - 1, &freq); if (ret < 0) return ret;
wm8994->mclk_rate[0] = freq;
dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
dai->id, freq); break;
case WM8994_SYSCLK_MCLK2: /* TODO: Set GPIO AF */
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2;
ret = wm8994_set_mclk_rate(wm8994, dai->id - 1, &freq); if (ret < 0) return ret;
wm8994->mclk_rate[1] = freq;
dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
dai->id, freq); break;
case WM8994_SYSCLK_FLL1:
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL1;
dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id); break;
case WM8994_SYSCLK_FLL2:
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL2;
dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id); break;
case WM8994_SYSCLK_OPCLK: /* Special case - a division (times 10) is given and * no effect on main clocking.
*/ if (freq) { for (i = 0; i < ARRAY_SIZE(opclk_divs); i++) if (opclk_divs[i] == freq) break; if (i == ARRAY_SIZE(opclk_divs)) return -EINVAL;
snd_soc_component_update_bits(component, WM8994_CLOCKING_2,
WM8994_OPCLK_DIV_MASK, i);
snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_2,
WM8994_OPCLK_ENA, WM8994_OPCLK_ENA);
} else {
snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_2,
WM8994_OPCLK_ENA, 0);
} break;
default: return -EINVAL;
}
configure_clock(component);
/* * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers * for detection.
*/ if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) {
dev_dbg(component->dev, "Configuring AIFs for 128fs\n");
case SND_SOC_BIAS_PREPARE: /* MICBIAS into regulating mode */ switch (control->type) { case WM8958: case WM1811:
snd_soc_component_update_bits(component, WM8958_MICBIAS1,
WM8958_MICB1_MODE, 0);
snd_soc_component_update_bits(component, WM8958_MICBIAS2,
WM8958_MICB2_MODE, 0); break; default: break;
}
if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY)
active_reference(component); break;
case SND_SOC_BIAS_STANDBY: if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { switch (control->type) { case WM8958: if (control->revision == 0) { /* Optimise performance for rev A */
snd_soc_component_update_bits(component,
WM8958_CHARGE_PUMP_2,
WM8958_CP_DISCH,
WM8958_CP_DISCH);
} break;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBC_CFC: break; case SND_SOC_DAIFMT_CBP_CFP:
ms = WM8994_AIF1_MSTR; break; default: return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_DSP_B:
aif1 |= WM8994_AIF1_LRCLK_INV;
lrclk |= WM8958_AIF1_LRCLK_INV;
fallthrough; case SND_SOC_DAIFMT_DSP_A:
aif1 |= 0x18; break; case SND_SOC_DAIFMT_I2S:
aif1 |= 0x10; break; case SND_SOC_DAIFMT_RIGHT_J: break; case SND_SOC_DAIFMT_LEFT_J:
aif1 |= 0x8; break; default: return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_B: /* frame inversion not valid for DSP modes */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: break; case SND_SOC_DAIFMT_IB_NF:
aif1 |= WM8994_AIF1_BCLK_INV; break; default: return -EINVAL;
} break;
case SND_SOC_DAIFMT_I2S: case SND_SOC_DAIFMT_RIGHT_J: case SND_SOC_DAIFMT_LEFT_J: switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: break; case SND_SOC_DAIFMT_IB_IF:
aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
lrclk |= WM8958_AIF1_LRCLK_INV; break; case SND_SOC_DAIFMT_IB_NF:
aif1 |= WM8994_AIF1_BCLK_INV; break; case SND_SOC_DAIFMT_NB_IF:
aif1 |= WM8994_AIF1_LRCLK_INV;
lrclk |= WM8958_AIF1_LRCLK_INV; break; default: return -EINVAL;
} break; default: return -EINVAL;
}
/* The AIF2 format configuration needs to be mirrored to AIF3
* on WM8958 if it's in use so just do it all the time. */ switch (control->type) { case WM1811: case WM8958: if (dai->id == 2)
snd_soc_component_update_bits(component, WM8958_AIF3_CONTROL_1,
WM8994_AIF1_LRCLK_INV |
WM8958_AIF3_FMT_MASK, aif1); break;
wm8994->channels[id] = params_channels(params); if (pdata->max_channels_clocked[id] &&
wm8994->channels[id] > pdata->max_channels_clocked[id]) {
dev_dbg(dai->dev, "Constraining channels to %d from %d\n",
pdata->max_channels_clocked[id], wm8994->channels[id]);
wm8994->channels[id] = pdata->max_channels_clocked[id];
}
switch (wm8994->channels[id]) { case 1: case 2:
bclk_rate *= 2; break; default:
bclk_rate *= 4; break;
}
/* Try to find an appropriate sample rate; look for an exact match. */ for (i = 0; i < ARRAY_SIZE(srs); i++) if (srs[i].rate == params_rate(params)) break; if (i == ARRAY_SIZE(srs)) return -EINVAL;
rate_val |= srs[i].val << WM8994_AIF1_SR_SHIFT;
dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i].rate);
dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
dai->id, wm8994->aifclk[id], bclk_rate);
if (wm8994->aifclk[id] == 0) {
dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id); return -EINVAL;
}
/* AIFCLK/fs ratio; look for a close match in either direction */
best = 0;
best_val = abs((fs_ratios[0] * params_rate(params))
- wm8994->aifclk[id]); for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) {
cur_val = abs((fs_ratios[i] * params_rate(params))
- wm8994->aifclk[id]); if (cur_val >= best_val) continue;
best = i;
best_val = cur_val;
}
dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
dai->id, fs_ratios[best]);
rate_val |= best;
/* We may not get quite the right frequency if using * approximate clocks so look for the closest match that is * higher than the target (we need to ensure that there enough * BCLKs to clock out the samples).
*/
best = 0; for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
cur_val = (wm8994->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate; if (cur_val < 0) /* BCLK table is sorted */ break;
best = i;
}
bclk_rate = wm8994->aifclk[id] * 10 / bclk_divs[best];
dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
bclk_divs[best], bclk_rate);
bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT;
lrclk = bclk_rate / params_rate(params); if (!lrclk) {
dev_err(dai->dev, "Unable to generate LRCLK from %dHz BCLK\n",
bclk_rate); return -EINVAL;
}
dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
lrclk, bclk_rate / lrclk);
staticint wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute, int direction)
{ struct snd_soc_component *component = codec_dai->component; int mute_reg; int reg;
switch (codec_dai->id) { case 1:
mute_reg = WM8994_AIF1_DAC1_FILTERS_1; break; case 2:
mute_reg = WM8994_AIF2_DAC_FILTERS_1; break; default: return -EINVAL;
}
if (mute)
reg = WM8994_AIF1DAC1_MUTE; else
reg = 0;
/* Disable the pulls on the AIF if we're using it to save power. */
snd_soc_component_update_bits(component, WM8994_GPIO_3,
WM8994_GPN_PU | WM8994_GPN_PD, 0);
snd_soc_component_update_bits(component, WM8994_GPIO_4,
WM8994_GPN_PU | WM8994_GPN_PD, 0);
snd_soc_component_update_bits(component, WM8994_GPIO_5,
WM8994_GPN_PU | WM8994_GPN_PD, 0);
#ifdef CONFIG_PM staticint wm8994_component_suspend(struct snd_soc_component *component)
{ struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); int i, ret;
for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i], sizeof(struct wm8994_fll_config));
ret = _wm8994_set_fll(component, i + 1, 0, 0, 0); if (ret < 0)
dev_warn(component->dev, "Failed to stop FLL%d: %d\n",
i + 1, ret);
}
staticint wm8994_component_resume(struct snd_soc_component *component)
{ struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); int i, ret;
for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { if (!wm8994->fll_suspend[i].out) continue;
ret = _wm8994_set_fll(component, i + 1,
wm8994->fll_suspend[i].src,
wm8994->fll_suspend[i].in,
wm8994->fll_suspend[i].out); if (ret < 0)
dev_warn(component->dev, "Failed to restore FLL%d: %d\n",
i + 1, ret);
}
/* We need an array of texts for the enum API but the number * of texts is likely to be less than the number of * configurations due to the sample rate dependency of the
* configurations. */
wm8994->num_retune_mobile_texts = 0;
wm8994->retune_mobile_texts = NULL; for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) { for (j = 0; j < wm8994->num_retune_mobile_texts; j++) { if (strcmp(pdata->retune_mobile_cfgs[i].name,
wm8994->retune_mobile_texts[j]) == 0) break;
}
if (j != wm8994->num_retune_mobile_texts) continue;
/* Expand the array... */
t = krealloc(wm8994->retune_mobile_texts, sizeof(char *) *
(wm8994->num_retune_mobile_texts + 1),
GFP_KERNEL); if (t == NULL) continue;
/* ...store the new entry... */
t[wm8994->num_retune_mobile_texts] =
pdata->retune_mobile_cfgs[i].name;
/* ...and remember the new version. */
wm8994->num_retune_mobile_texts++;
wm8994->retune_mobile_texts = t;
}
dev_dbg(component->dev, "Allocated %d unique ReTune Mobile names\n",
wm8994->num_retune_mobile_texts);
ret = snd_soc_add_component_controls(wm8994->hubs.component, controls,
ARRAY_SIZE(controls)); if (ret != 0)
dev_err(wm8994->hubs.component->dev, "Failed to add ReTune Mobile controls: %d\n", ret);
}
/* We need an array of texts for the enum API */
wm8994->drc_texts = devm_kcalloc(wm8994->hubs.component->dev,
pdata->num_drc_cfgs, sizeof(char *), GFP_KERNEL); if (!wm8994->drc_texts) return;
for (i = 0; i < pdata->num_drc_cfgs; i++)
wm8994->drc_texts[i] = pdata->drc_cfgs[i].name;
ret = snd_soc_add_component_controls(wm8994->hubs.component, controls,
ARRAY_SIZE(controls)); for (i = 0; i < WM8994_NUM_DRC; i++)
wm8994_set_drc(component, i);
} else {
ret = snd_soc_add_component_controls(wm8994->hubs.component,
wm8994_drc_controls,
ARRAY_SIZE(wm8994_drc_controls));
}
if (ret != 0)
dev_err(wm8994->hubs.component->dev, "Failed to add DRC mode controls: %d\n", ret);
dev_dbg(component->dev, "%d ReTune Mobile configurations\n",
pdata->num_retune_mobile_cfgs);
if (pdata->num_retune_mobile_cfgs)
wm8994_handle_retune_mobile_pdata(wm8994); else
snd_soc_add_component_controls(wm8994->hubs.component, wm8994_eq_controls,
ARRAY_SIZE(wm8994_eq_controls));
for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) { if (pdata->micbias[i]) {
snd_soc_component_write(component, WM8958_MICBIAS1 + i,
pdata->micbias[i] & 0xffff);
}
}
}
/** * wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ * * @component: WM8994 component * @jack: jack to report detection events on * @micbias: microphone bias to detect on * * Enable microphone detection via IRQ on the WM8994. If GPIOs are * being used to bring out signals to the processor then only platform * data configuration is needed for WM8994 and processor GPIOs should * be configured using snd_soc_jack_add_gpios() instead. * * Configuration of detection levels is available via the micbias1_lvl * and micbias2_lvl platform data members.
*/ int wm8994_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack, int micbias)
{ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); struct wm8994_micdet *micdet; struct wm8994 *control = wm8994->wm8994; int reg, ret;
if (control->type != WM8994) {
dev_warn(component->dev, "Not a WM8994\n"); return -EINVAL;
}
pm_runtime_get_sync(component->dev);
switch (micbias) { case 1:
micdet = &wm8994->micdet[0]; if (jack)
ret = snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); else
ret = snd_soc_dapm_disable_pin(dapm, "MICBIAS1"); break; case 2:
micdet = &wm8994->micdet[1]; if (jack)
ret = snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); else
ret = snd_soc_dapm_disable_pin(dapm, "MICBIAS1"); break; default:
dev_warn(component->dev, "Invalid MICBIAS %d\n", micbias); return -EINVAL;
}
if (ret != 0)
dev_warn(component->dev, "Failed to configure MICBIAS%d: %d\n",
micbias, ret);
dev_dbg(component->dev, "Configuring microphone detection on %d %p\n",
micbias, jack);
/* Store the configuration */
micdet->jack = jack;
micdet->detecting = true;
/* If either of the jacks is set up then enable detection */ if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
reg = WM8994_MICD_ENA; else
reg = 0;
/* Should be called with accdet_lock held */ staticvoid wm1811_micd_stop(struct snd_soc_component *component)
{ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
/* Either nothing present or just starting detection */ if (!(status & WM8958_MICD_STS)) { /* If nothing present then clear our statuses */
dev_dbg(component->dev, "Detected open circuit\n");
/* Deferred mic detection to allow for extra settling time */ staticvoid 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_component *component = wm8994->hubs.component; struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
pm_runtime_get_sync(component->dev);
/* If required for an external cap force MICBIAS on */ if (control->pdata.jd_ext_cap) {
snd_soc_dapm_force_enable_pin(dapm, "MICBIAS2");
snd_soc_dapm_sync(dapm);
}
mutex_lock(&wm8994->accdet_lock);
dev_dbg(component->dev, "Starting mic detection\n");
/* Use a user-supplied callback if we have one */ if (wm8994->micd_cb) {
wm8994->micd_cb(wm8994->micd_cb_data);
} else { /* * Start off measument of microphone impedence to find out * what's actually there.
*/
wm8994->mic_detecting = true;
wm1811_jackdet_set_mode(component, WM1811_JACKDET_MODE_MIC);
/* Since we only report deltas force an update, ensures we
* avoid bootstrapping issues with the core. */
snd_soc_jack_report(wm8994->micdet[0].jack, 0, 0);
/** * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ * * @component: WM8958 component * @jack: jack to report detection events on * @det_cb: detection callback * @det_cb_data: data for detection callback * @id_cb: mic id callback * @id_cb_data: data for mic id callback * * Enable microphone detection functionality for the WM8958. By * default simple detection which supports the detection of up to 6 * buttons plus video and microphone functionality is supported. * * The WM8958 has an advanced jack detection facility which is able to * support complex accessory detection, especially when used in * conjunction with external circuitry. In order to provide maximum * flexiblity a callback is provided which allows a completely custom * detection algorithm.
*/ int wm8958_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack,
wm1811_micdet_cb det_cb, void *det_cb_data,
wm1811_mic_id_cb id_cb, void *id_cb_data)
{ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); struct wm8994 *control = wm8994->wm8994;
u16 micd_lvl_sel;
switch (control->type) { case WM1811: case WM8958: break; default: return -EINVAL;
}
pm_runtime_get_sync(component->dev);
if (jack) {
snd_soc_dapm_force_enable_pin(dapm, "CLK_SYS");
snd_soc_dapm_sync(dapm);
/* Detect microphones and short circuits by default */ if (control->pdata.micd_lvl_sel)
micd_lvl_sel = control->pdata.micd_lvl_sel; else
micd_lvl_sel = 0x41;
/* * If we can use jack detection start off with that, * otherwise jump straight to microphone detection.
*/ if (wm8994->jackdet) { /* Disable debounce for the initial detect */
snd_soc_component_update_bits(component, WM1811_JACKDET_CTRL,
WM1811_JACKDET_DB, 0);
/* * Jack detection may have detected a removal simulataneously * with an update of the MICDET status; if so it will have * stopped detection and we can ignore this interrupt.
*/ if (!(snd_soc_component_read(component, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) return IRQ_HANDLED;
/* We may occasionally read a detection without an impedence * range being provided - if that happens loop again.
*/
count = 10; do {
reg = snd_soc_component_read(component, WM8958_MIC_DETECT_3); if (reg < 0) {
dev_err(component->dev, "Failed to read mic detect status: %d\n",
reg);
pm_runtime_put(component->dev); return IRQ_NONE;
}
if (!(reg & WM8958_MICD_VALID)) {
dev_dbg(component->dev, "Mic detect data not valid\n"); goto out;
}
if (!(reg & WM8958_MICD_STS) || (reg & WM8958_MICD_LVL_MASK)) break;
msleep(1);
} while (count--);
if (count == 0)
dev_warn(component->dev, "No impedance range reported for jack\n");
for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
init_completion(&wm8994->fll_locked[i]);
wm8994->micdet_irq = control->pdata.micdet_irq;
/* By default use idle_bias_off, will override for WM8994 */
dapm->idle_bias_off = 1;
/* Set revision-specific configuration */ switch (control->type) { case WM8994: /* Single ended line outputs should have VMID on. */ if (!control->pdata.lineout1_diff ||
!control->pdata.lineout2_diff)
dapm->idle_bias_off = 0;
switch (control->type) { case WM8994: if (wm8994->micdet_irq)
ret = request_threaded_irq(wm8994->micdet_irq, NULL,
wm8994_mic_irq,
IRQF_TRIGGER_RISING |
IRQF_ONESHOT, "Mic1 detect",
wm8994); else
ret = wm8994_request_irq(wm8994->wm8994,
WM8994_IRQ_MIC1_DET,
wm8994_mic_irq, "Mic 1 detect",
wm8994);
if (ret != 0)
dev_warn(component->dev, "Failed to request Mic1 detect IRQ: %d\n",
ret);
ret = wm8994_request_irq(wm8994->wm8994,
WM8994_IRQ_MIC1_SHRT,
wm8994_mic_irq, "Mic 1 short",
wm8994); if (ret != 0)
dev_warn(component->dev, "Failed to request Mic1 short IRQ: %d\n",
ret);
ret = wm8994_request_irq(wm8994->wm8994,
WM8994_IRQ_MIC2_DET,
wm8994_mic_irq, "Mic 2 detect",
wm8994); if (ret != 0)
dev_warn(component->dev, "Failed to request Mic2 detect IRQ: %d\n",
ret);
ret = wm8994_request_irq(wm8994->wm8994,
WM8994_IRQ_MIC2_SHRT,
wm8994_mic_irq, "Mic 2 short",
wm8994); if (ret != 0)
dev_warn(component->dev, "Failed to request Mic2 short IRQ: %d\n",
ret); break;
case WM8958: case WM1811: if (wm8994->micdet_irq) {
ret = request_threaded_irq(wm8994->micdet_irq, NULL,
wm8958_mic_irq,
IRQF_TRIGGER_RISING |
IRQF_ONESHOT, "Mic detect",
wm8994); if (ret != 0)
dev_warn(component->dev, "Failed to request Mic detect IRQ: %d\n",
ret);
} else {
wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_MIC1_DET,
wm8958_mic_irq, "Mic detect",
wm8994);
}
}
switch (control->type) { case WM1811: if (control->cust_id > 1 || control->revision > 1) {
ret = wm8994_request_irq(wm8994->wm8994,
WM8994_IRQ_GPIO(6),
wm1811_jackdet_irq, "JACKDET",
wm8994); if (ret == 0)
wm8994->jackdet = true;
} break; default: break;
}
wm8994->fll_locked_irq = true; for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) {
ret = wm8994_request_irq(wm8994->wm8994,
WM8994_IRQ_FLL1_LOCK + i,
wm8994_fll_locked_irq, "FLL lock",
&wm8994->fll_locked[i]); if (ret != 0)
wm8994->fll_locked_irq = false;
}
/* Make sure we can read from the GPIOs if they're inputs */
pm_runtime_get_sync(component->dev);
/* Remember if AIFnLRCLK is configured as a GPIO. This should be * configured on init - if a system wants to do this dynamically * at runtime we can deal with that then.
*/
ret = regmap_read(control->regmap, WM8994_GPIO_1, ®); if (ret < 0) {
dev_err(component->dev, "Failed to read GPIO1 state: %d\n", ret); goto err_irq;
} if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
wm8994->lrclk_shared[0] = 1;
wm8994_dai[0].symmetric_rate = 1;
} else {
wm8994->lrclk_shared[0] = 0;
}
/* Latch volume update bits */ for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
snd_soc_component_update_bits(component, wm8994_vu_bits[i].reg,
wm8994_vu_bits[i].mask,
wm8994_vu_bits[i].mask);
if (control->type != WM1811) { for (i = 0; i < ARRAY_SIZE(wm8994_adc2_dac2_vu_bits); i++)
snd_soc_component_update_bits(component,
wm8994_adc2_dac2_vu_bits[i].reg,
wm8994_adc2_dac2_vu_bits[i].mask,
wm8994_adc2_dac2_vu_bits[i].mask);
}
/* Set the low bit of the 3D stereo depth so TLV matches */
snd_soc_component_update_bits(component, WM8994_AIF1_DAC1_FILTERS_2,
1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT,
1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT);
snd_soc_component_update_bits(component, WM8994_AIF1_DAC2_FILTERS_2,
1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT,
1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT);
snd_soc_component_update_bits(component, WM8994_AIF2_DAC_FILTERS_2,
1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
/* Unconditionally enable AIF1 ADC TDM mode on chips which can * use this; it only affects behaviour on idle TDM clock
* cycles. */ switch (control->type) { case WM8994: case WM8958:
snd_soc_component_update_bits(component, WM8994_AIF1_CONTROL_1,
WM8994_AIF1ADC_TDM, WM8994_AIF1ADC_TDM); break; default: break;
}
/* Put MICBIAS into bypass mode by default on newer devices */ switch (control->type) { case WM8958: case WM1811:
snd_soc_component_update_bits(component, WM8958_MICBIAS1,
WM8958_MICB1_MODE, WM8958_MICB1_MODE);
snd_soc_component_update_bits(component, WM8958_MICBIAS2,
WM8958_MICB2_MODE, WM8958_MICB2_MODE); break; default: break;
}
if (wm8994->jackdet)
wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_GPIO(6), wm8994);
switch (control->type) { case WM8994: if (wm8994->micdet_irq)
free_irq(wm8994->micdet_irq, wm8994);
wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_DET,
wm8994);
wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_SHRT,
wm8994);
wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_DET,
wm8994); break;
case WM1811: case WM8958: if (wm8994->micdet_irq)
free_irq(wm8994->micdet_irq, wm8994); break;
}
release_firmware(wm8994->mbc);
release_firmware(wm8994->mbc_vss);
release_firmware(wm8994->enh_eq);
kfree(wm8994->retune_mobile_texts);
}
ret = devm_clk_bulk_get_optional(pdev->dev.parent, ARRAY_SIZE(wm8994->mclk),
wm8994->mclk); if (ret < 0) {
dev_err(&pdev->dev, "Failed to get clocks: %d\n", ret); return ret;
}
/* Drop down to power saving mode when system is suspended */ if (wm8994->jackdet && !wm8994->active_refcount)
regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
WM1811_JACKDET_MODE_MASK,
wm8994->jackdet_mode);