diff options
Diffstat (limited to 'sound/soc/codecs/wm8804.c')
-rw-r--r-- | sound/soc/codecs/wm8804.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index ee76f0fb4299..d96e5963ee35 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -63,6 +63,7 @@ struct wm8804_priv { struct regmap *regmap; struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES]; struct notifier_block disable_nb[WM8804_NUM_SUPPLIES]; + int mclk_div; }; static int txsrc_get(struct snd_kcontrol *kcontrol, @@ -106,7 +107,7 @@ static int txsrc_get(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec; unsigned int src; - codec = snd_kcontrol_chip(kcontrol); + codec = snd_soc_kcontrol_codec(kcontrol); src = snd_soc_read(codec, WM8804_SPDTX4); if (src & 0x40) ucontrol->value.integer.value[0] = 1; @@ -122,7 +123,7 @@ static int txsrc_put(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec; unsigned int src, txpwr; - codec = snd_kcontrol_chip(kcontrol); + codec = snd_soc_kcontrol_codec(kcontrol); if (ucontrol->value.integer.value[0] != 0 && ucontrol->value.integer.value[0] != 1) @@ -318,7 +319,7 @@ static struct { #define FIXED_PLL_SIZE ((1ULL << 22) * 10) static int pll_factors(struct pll_div *pll_div, unsigned int target, - unsigned int source) + unsigned int source, unsigned int mclk_div) { u64 Kpart; unsigned long int K, Ndiv, Nmod, tmp; @@ -330,7 +331,8 @@ static int pll_factors(struct pll_div *pll_div, unsigned int target, */ for (i = 0; i < ARRAY_SIZE(post_table); i++) { tmp = target * post_table[i].div; - if (tmp >= 90000000 && tmp <= 100000000) { + if ((tmp >= 90000000 && tmp <= 100000000) && + (mclk_div == post_table[i].mclkdiv)) { pll_div->freqmode = post_table[i].freqmode; pll_div->mclkdiv = post_table[i].mclkdiv; target *= post_table[i].div; @@ -387,8 +389,12 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id, } else { int ret; struct pll_div pll_div; + struct wm8804_priv *wm8804; - ret = pll_factors(&pll_div, freq_out, freq_in); + wm8804 = snd_soc_codec_get_drvdata(codec); + + ret = pll_factors(&pll_div, freq_out, freq_in, + wm8804->mclk_div); if (ret) return ret; @@ -452,6 +458,7 @@ static int wm8804_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) { struct snd_soc_codec *codec; + struct wm8804_priv *wm8804; codec = dai->codec; switch (div_id) { @@ -459,6 +466,10 @@ static int wm8804_set_clkdiv(struct snd_soc_dai *dai, snd_soc_update_bits(codec, WM8804_PLL5, 0x30, (div & 0x3) << 4); break; + case WM8804_MCLK_DIV: + wm8804 = snd_soc_codec_get_drvdata(codec); + wm8804->mclk_div = div; + break; default: dev_err(dai->dev, "Unknown clock divider: %d\n", div_id); return -EINVAL; @@ -535,7 +546,6 @@ static int wm8804_remove(struct snd_soc_codec *codec) for (i = 0; i < ARRAY_SIZE(wm8804->supplies); ++i) regulator_unregister_notifier(wm8804->supplies[i].consumer, &wm8804->disable_nb[i]); - regulator_bulk_free(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); return 0; } @@ -549,7 +559,7 @@ static int wm8804_probe(struct snd_soc_codec *codec) for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) wm8804->supplies[i].supply = wm8804_supply_names[i]; - ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8804->supplies), + ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8804->supplies), wm8804->supplies); if (ret) { dev_err(codec->dev, "Failed to request supplies: %d\n", ret); @@ -574,7 +584,7 @@ static int wm8804_probe(struct snd_soc_codec *codec) wm8804->supplies); if (ret) { dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); - goto err_reg_get; + return ret; } id1 = snd_soc_read(codec, WM8804_RST_DEVID1); @@ -619,8 +629,6 @@ static int wm8804_probe(struct snd_soc_codec *codec) err_reg_enable: regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); -err_reg_get: - regulator_bulk_free(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); return ret; } |