|
|
@@ -93,7 +93,7 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, |
|
|
switch (event) {
|
|
|
case SND_SOC_DAPM_PRE_PMU:
|
|
|
if (!priv->spk_ena && manual_ena) {
|
|
|
snd_soc_write(codec, 0x4f5, 0x25a);
|
|
|
regmap_write_async(arizona->regmap, 0x4f5, 0x25a);
|
|
|
priv->spk_ena_pending = true;
|
|
|
}
|
|
|
break;
|
|
|
@@ -105,12 +105,13 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, |
|
|
return -EBUSY;
|
|
|
}
|
|
|
|
|
|
snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
|
|
|
1 << w->shift, 1 << w->shift);
|
|
|
regmap_update_bits_async(arizona->regmap,
|
|
|
ARIZONA_OUTPUT_ENABLES_1,
|
|
|
1 << w->shift, 1 << w->shift);
|
|
|
|
|
|
if (priv->spk_ena_pending) {
|
|
|
msleep(75);
|
|
|
snd_soc_write(codec, 0x4f5, 0xda);
|
|
|
regmap_write_async(arizona->regmap, 0x4f5, 0xda);
|
|
|
priv->spk_ena_pending = false;
|
|
|
priv->spk_ena++;
|
|
|
}
|
|
|
@@ -119,16 +120,19 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, |
|
|
if (manual_ena) {
|
|
|
priv->spk_ena--;
|
|
|
if (!priv->spk_ena)
|
|
|
snd_soc_write(codec, 0x4f5, 0x25a);
|
|
|
regmap_write_async(arizona->regmap,
|
|
|
0x4f5, 0x25a);
|
|
|
}
|
|
|
|
|
|
snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
|
|
|
1 << w->shift, 0);
|
|
|
regmap_update_bits_async(arizona->regmap,
|
|
|
ARIZONA_OUTPUT_ENABLES_1,
|
|
|
1 << w->shift, 0);
|
|
|
break;
|
|
|
case SND_SOC_DAPM_POST_PMD:
|
|
|
if (manual_ena) {
|
|
|
if (!priv->spk_ena)
|
|
|
snd_soc_write(codec, 0x4f5, 0x0da);
|
|
|
regmap_write_async(arizona->regmap,
|
|
|
0x4f5, 0x0da);
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
@@ -292,6 +296,10 @@ const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { |
|
|
"AIF1RX8",
|
|
|
"AIF2RX1",
|
|
|
"AIF2RX2",
|
|
|
"AIF2RX3",
|
|
|
"AIF2RX4",
|
|
|
"AIF2RX5",
|
|
|
"AIF2RX6",
|
|
|
"AIF3RX1",
|
|
|
"AIF3RX2",
|
|
|
"SLIMRX1",
|
|
|
@@ -395,6 +403,10 @@ int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = { |
|
|
0x27,
|
|
|
0x28, /* AIF2RX1 */
|
|
|
0x29,
|
|
|
0x2a,
|
|
|
0x2b,
|
|
|
0x2c,
|
|
|
0x2d,
|
|
|
0x30, /* AIF3RX1 */
|
|
|
0x31,
|
|
|
0x38, /* SLIMRX1 */
|
|
|
@@ -486,6 +498,22 @@ const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = { |
|
|
EXPORT_SYMBOL_GPL(arizona_rate_val);
|
|
|
|
|
|
|
|
|
const struct soc_enum arizona_isrc_fsh[] = {
|
|
|
SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1,
|
|
|
ARIZONA_ISRC1_FSH_SHIFT, 0xf,
|
|
|
ARIZONA_RATE_ENUM_SIZE,
|
|
|
arizona_rate_text, arizona_rate_val),
|
|
|
SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_1,
|
|
|
ARIZONA_ISRC2_FSH_SHIFT, 0xf,
|
|
|
ARIZONA_RATE_ENUM_SIZE,
|
|
|
arizona_rate_text, arizona_rate_val),
|
|
|
SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_1,
|
|
|
ARIZONA_ISRC3_FSH_SHIFT, 0xf,
|
|
|
ARIZONA_RATE_ENUM_SIZE,
|
|
|
arizona_rate_text, arizona_rate_val),
|
|
|
};
|
|
|
EXPORT_SYMBOL_GPL(arizona_isrc_fsh);
|
|
|
|
|
|
const struct soc_enum arizona_isrc_fsl[] = {
|
|
|
SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
|
|
|
ARIZONA_ISRC1_FSL_SHIFT, 0xf,
|
|
|
@@ -502,6 +530,13 @@ const struct soc_enum arizona_isrc_fsl[] = { |
|
|
};
|
|
|
EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
|
|
|
|
|
|
const struct soc_enum arizona_asrc_rate1 =
|
|
|
SOC_VALUE_ENUM_SINGLE(ARIZONA_ASRC_RATE1,
|
|
|
ARIZONA_ASRC_RATE1_SHIFT, 0xf,
|
|
|
ARIZONA_RATE_ENUM_SIZE - 1,
|
|
|
arizona_rate_text, arizona_rate_val);
|
|
|
EXPORT_SYMBOL_GPL(arizona_asrc_rate1);
|
|
|
|
|
|
static const char *arizona_vol_ramp_text[] = {
|
|
|
"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
|
|
|
"15ms/6dB", "30ms/6dB",
|
|
|
@@ -560,6 +595,16 @@ const struct soc_enum arizona_ng_hold = |
|
|
4, arizona_ng_hold_text);
|
|
|
EXPORT_SYMBOL_GPL(arizona_ng_hold);
|
|
|
|
|
|
static const char * const arizona_in_hpf_cut_text[] = {
|
|
|
"2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
|
|
|
};
|
|
|
|
|
|
const struct soc_enum arizona_in_hpf_cut_enum =
|
|
|
SOC_ENUM_SINGLE(ARIZONA_HPF_CONTROL, ARIZONA_IN_HPF_CUT_SHIFT,
|
|
|
ARRAY_SIZE(arizona_in_hpf_cut_text),
|
|
|
arizona_in_hpf_cut_text);
|
|
|
EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
|
|
|
|
|
|
static const char * const arizona_in_dmic_osr_text[] = {
|
|
|
"1.536MHz", "3.072MHz", "6.144MHz",
|
|
|
};
|
|
|
@@ -669,6 +714,7 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w, |
|
|
int event)
|
|
|
{
|
|
|
struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
|
|
|
struct arizona *arizona = priv->arizona;
|
|
|
unsigned int mask = 1 << w->shift;
|
|
|
unsigned int val;
|
|
|
|
|
|
@@ -691,7 +737,8 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w, |
|
|
if (priv->arizona->hpdet_magic)
|
|
|
val = 0;
|
|
|
|
|
|
snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val);
|
|
|
regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
|
|
|
mask, val);
|
|
|
|
|
|
return arizona_out_ev(w, kcontrol, event);
|
|
|
}
|
|
|
@@ -846,6 +893,8 @@ EXPORT_SYMBOL_GPL(arizona_set_sysclk); |
|
|
static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
|
|
{
|
|
|
struct snd_soc_codec *codec = dai->codec;
|
|
|
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
|
|
|
struct arizona *arizona = priv->arizona;
|
|
|
int lrclk, bclk, mode, base;
|
|
|
|
|
|
base = dai->driver->base;
|
|
|
@@ -902,17 +951,19 @@ static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
|
|
|
ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
|
|
|
bclk);
|
|
|
snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
|
|
|
ARIZONA_AIF1TX_LRCLK_INV |
|
|
|
ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
|
|
|
snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
|
|
|
ARIZONA_AIF1RX_LRCLK_INV |
|
|
|
ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
|
|
|
snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
|
|
|
ARIZONA_AIF1_FMT_MASK, mode);
|
|
|
regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
|
|
|
ARIZONA_AIF1_BCLK_INV |
|
|
|
ARIZONA_AIF1_BCLK_MSTR,
|
|
|
bclk);
|
|
|
regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL,
|
|
|
ARIZONA_AIF1TX_LRCLK_INV |
|
|
|
ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
|
|
|
regmap_update_bits_async(arizona->regmap,
|
|
|
base + ARIZONA_AIF_RX_PIN_CTRL,
|
|
|
ARIZONA_AIF1RX_LRCLK_INV |
|
|
|
ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
|
|
|
regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT,
|
|
|
ARIZONA_AIF1_FMT_MASK, mode);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
@@ -1164,18 +1215,22 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, |
|
|
if (ret != 0)
|
|
|
return ret;
|
|
|
|
|
|
snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
|
|
|
ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
|
|
|
snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
|
|
|
ARIZONA_AIF1TX_BCPF_MASK, lrclk);
|
|
|
snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
|
|
|
ARIZONA_AIF1RX_BCPF_MASK, lrclk);
|
|
|
snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
|
|
|
ARIZONA_AIF1TX_WL_MASK |
|
|
|
ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
|
|
|
snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
|
|
|
ARIZONA_AIF1RX_WL_MASK |
|
|
|
ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
|
|
|
regmap_update_bits_async(arizona->regmap,
|
|
|
base + ARIZONA_AIF_BCLK_CTRL,
|
|
|
ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
|
|
|
regmap_update_bits_async(arizona->regmap,
|
|
|
base + ARIZONA_AIF_TX_BCLK_RATE,
|
|
|
ARIZONA_AIF1TX_BCPF_MASK, lrclk);
|
|
|
regmap_update_bits_async(arizona->regmap,
|
|
|
base + ARIZONA_AIF_RX_BCLK_RATE,
|
|
|
ARIZONA_AIF1RX_BCPF_MASK, lrclk);
|
|
|
regmap_update_bits_async(arizona->regmap,
|
|
|
base + ARIZONA_AIF_FRAME_CTRL_1,
|
|
|
ARIZONA_AIF1TX_WL_MASK |
|
|
|
ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
|
|
|
regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FRAME_CTRL_2,
|
|
|
ARIZONA_AIF1RX_WL_MASK |
|
|
|
ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
@@ -1428,31 +1483,31 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base, |
|
|
struct arizona_fll_cfg *cfg, int source,
|
|
|
bool sync)
|
|
|
{
|
|
|
regmap_update_bits(arizona->regmap, base + 3,
|
|
|
ARIZONA_FLL1_THETA_MASK, cfg->theta);
|
|
|
regmap_update_bits(arizona->regmap, base + 4,
|
|
|
ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
|
|
|
regmap_update_bits(arizona->regmap, base + 5,
|
|
|
ARIZONA_FLL1_FRATIO_MASK,
|
|
|
cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
|
|
|
regmap_update_bits(arizona->regmap, base + 6,
|
|
|
ARIZONA_FLL1_CLK_REF_DIV_MASK |
|
|
|
ARIZONA_FLL1_CLK_REF_SRC_MASK,
|
|
|
cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
|
|
|
source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
|
|
|
regmap_update_bits_async(arizona->regmap, base + 3,
|
|
|
ARIZONA_FLL1_THETA_MASK, cfg->theta);
|
|
|
regmap_update_bits_async(arizona->regmap, base + 4,
|
|
|
ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
|
|
|
regmap_update_bits_async(arizona->regmap, base + 5,
|
|
|
ARIZONA_FLL1_FRATIO_MASK,
|
|
|
cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
|
|
|
regmap_update_bits_async(arizona->regmap, base + 6,
|
|
|
ARIZONA_FLL1_CLK_REF_DIV_MASK |
|
|
|
ARIZONA_FLL1_CLK_REF_SRC_MASK,
|
|
|
cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
|
|
|
source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
|
|
|
|
|
|
if (sync)
|
|
|
regmap_update_bits(arizona->regmap, base + 0x7,
|
|
|
ARIZONA_FLL1_GAIN_MASK,
|
|
|
cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
|
|
|
regmap_update_bits_async(arizona->regmap, base + 0x7,
|
|
|
ARIZONA_FLL1_GAIN_MASK,
|
|
|
cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
|
|
|
else
|
|
|
regmap_update_bits(arizona->regmap, base + 0x9,
|
|
|
ARIZONA_FLL1_GAIN_MASK,
|
|
|
cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
|
|
|
regmap_update_bits_async(arizona->regmap, base + 0x9,
|
|
|
ARIZONA_FLL1_GAIN_MASK,
|
|
|
cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
|
|
|
|
|
|
regmap_update_bits(arizona->regmap, base + 2,
|
|
|
ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
|
|
|
ARIZONA_FLL1_CTRL_UPD | cfg->n);
|
|
|
regmap_update_bits_async(arizona->regmap, base + 2,
|
|
|
ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
|
|
|
ARIZONA_FLL1_CTRL_UPD | cfg->n);
|
|
|
}
|
|
|
|
|
|
static bool arizona_is_enabled_fll(struct arizona_fll *fll)
|
|
|
@@ -1485,9 +1540,9 @@ static void arizona_enable_fll(struct arizona_fll *fll, |
|
|
*/
|
|
|
if (fll->ref_src >= 0 && fll->ref_freq &&
|
|
|
fll->ref_src != fll->sync_src) {
|
|
|
regmap_update_bits(arizona->regmap, fll->base + 5,
|
|
|
ARIZONA_FLL1_OUTDIV_MASK,
|
|
|
ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
|
|
|
regmap_update_bits_async(arizona->regmap, fll->base + 5,
|
|
|
ARIZONA_FLL1_OUTDIV_MASK,
|
|
|
ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
|
|
|
|
|
|
arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
|
|
|
false);
|
|
|
@@ -1497,15 +1552,15 @@ static void arizona_enable_fll(struct arizona_fll *fll, |
|
|
use_sync = true;
|
|
|
}
|
|
|
} else if (fll->sync_src >= 0) {
|
|
|
regmap_update_bits(arizona->regmap, fll->base + 5,
|
|
|
ARIZONA_FLL1_OUTDIV_MASK,
|
|
|
sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
|
|
|
regmap_update_bits_async(arizona->regmap, fll->base + 5,
|
|
|
ARIZONA_FLL1_OUTDIV_MASK,
|
|
|
sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
|
|
|
|
|
|
arizona_apply_fll(arizona, fll->base, sync,
|
|
|
fll->sync_src, false);
|
|
|
|
|
|
regmap_update_bits(arizona->regmap, fll->base + 0x11,
|
|
|
ARIZONA_FLL1_SYNC_ENA, 0);
|
|
|
regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
|
|
|
ARIZONA_FLL1_SYNC_ENA, 0);
|
|
|
} else {
|
|
|
arizona_fll_err(fll, "No clocks provided\n");
|
|
|
return;
|
|
|
@@ -1516,26 +1571,27 @@ static void arizona_enable_fll(struct arizona_fll *fll, |
|
|
* sync source.
|
|
|
*/
|
|
|
if (use_sync && fll->sync_freq > 100000)
|
|
|
regmap_update_bits(arizona->regmap, fll->base + 0x17,
|
|
|
ARIZONA_FLL1_SYNC_BW, 0);
|
|
|
regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
|
|
|
ARIZONA_FLL1_SYNC_BW, 0);
|
|
|
else
|
|
|
regmap_update_bits(arizona->regmap, fll->base + 0x17,
|
|
|
ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW);
|
|
|
regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
|
|
|
ARIZONA_FLL1_SYNC_BW,
|
|
|
ARIZONA_FLL1_SYNC_BW);
|
|
|
|
|
|
if (!arizona_is_enabled_fll(fll))
|
|
|
pm_runtime_get(arizona->dev);
|
|
|
|
|
|
/* Clear any pending completions */
|
|
|
try_wait_for_completion(&fll->ok);
|
|
|
|
|
|
regmap_update_bits(arizona->regmap, fll->base + 1,
|
|
|
ARIZONA_FLL1_FREERUN, 0);
|
|
|
regmap_update_bits(arizona->regmap, fll->base + 1,
|
|
|
ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
|
|
|
regmap_update_bits_async(arizona->regmap, fll->base + 1,
|
|
|
ARIZONA_FLL1_FREERUN, 0);
|
|
|
regmap_update_bits_async(arizona->regmap, fll->base + 1,
|
|
|
ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
|
|
|
if (use_sync)
|
|
|
regmap_update_bits(arizona->regmap, fll->base + 0x11,
|
|
|
ARIZONA_FLL1_SYNC_ENA,
|
|
|
ARIZONA_FLL1_SYNC_ENA);
|
|
|
regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
|
|
|
ARIZONA_FLL1_SYNC_ENA,
|
|
|
ARIZONA_FLL1_SYNC_ENA);
|
|
|
|
|
|
ret = wait_for_completion_timeout(&fll->ok,
|
|
|
msecs_to_jiffies(250));
|
|
|
@@ -1548,8 +1604,8 @@ static void arizona_disable_fll(struct arizona_fll *fll) |
|
|
struct arizona *arizona = fll->arizona;
|
|
|
bool change;
|
|
|
|
|
|
regmap_update_bits(arizona->regmap, fll->base + 1,
|
|
|
ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
|
|
|
regmap_update_bits_async(arizona->regmap, fll->base + 1,
|
|
|
ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
|
|
|
regmap_update_bits_check(arizona->regmap, fll->base + 1,
|
|
|
ARIZONA_FLL1_ENA, 0, &change);
|
|
|
regmap_update_bits(arizona->regmap, fll->base + 0x11,
|
|
|
|