diff options
Diffstat (limited to 'sound/soc/codecs/wm8974.c')
| -rw-r--r-- | sound/soc/codecs/wm8974.c | 77 |
1 files changed, 37 insertions, 40 deletions
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 593a11960888..0bb5e947f46d 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * wm8974.c -- WM8974 ALSA Soc Audio driver * * Copyright 2006-2009 Wolfson Microelectronics PLC. * * Author: Liam Girdwood <Liam.Girdwood@wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/module.h> @@ -189,7 +186,7 @@ SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 0), /* Boost mixer */ static const struct snd_kcontrol_new wm8974_boost_mixer[] = { -SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 0), +SOC_DAPM_SINGLE("PGA Switch", WM8974_INPPGA, 6, 1, 1), }; /* Input PGA */ @@ -199,14 +196,6 @@ SOC_DAPM_SINGLE("MicN Switch", WM8974_INPUT, 1, 1, 0), SOC_DAPM_SINGLE("MicP Switch", WM8974_INPUT, 0, 1, 0), }; -/* AUX Input boost vol */ -static const struct snd_kcontrol_new wm8974_aux_boost_controls = -SOC_DAPM_SINGLE("Aux Volume", WM8974_ADCBOOST, 0, 7, 0); - -/* Mic Input boost vol */ -static const struct snd_kcontrol_new wm8974_mic_boost_controls = -SOC_DAPM_SINGLE("Mic Volume", WM8974_ADCBOOST, 4, 7, 0); - static const struct snd_soc_dapm_widget wm8974_dapm_widgets[] = { SND_SOC_DAPM_MIXER("Speaker Mixer", WM8974_POWER3, 2, 0, &wm8974_speaker_mixer_controls[0], @@ -257,8 +246,8 @@ static const struct snd_soc_dapm_route wm8974_dapm_routes[] = { /* Boost Mixer */ {"ADC", NULL, "Boost Mixer"}, - {"Boost Mixer", "Aux Switch", "Aux Input"}, - {"Boost Mixer", NULL, "Input PGA"}, + {"Boost Mixer", NULL, "Aux Input"}, + {"Boost Mixer", "PGA Switch", "Input PGA"}, {"Boost Mixer", NULL, "MICP"}, /* Input PGA */ @@ -329,11 +318,11 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, if (freq_in == 0 || freq_out == 0) { /* Clock CODEC directly from MCLK */ - reg = snd_soc_component_read32(component, WM8974_CLOCK); + reg = snd_soc_component_read(component, WM8974_CLOCK); snd_soc_component_write(component, WM8974_CLOCK, reg & 0x0ff); /* Turn off PLL */ - reg = snd_soc_component_read32(component, WM8974_POWER1); + reg = snd_soc_component_read(component, WM8974_POWER1); snd_soc_component_write(component, WM8974_POWER1, reg & 0x1df); return 0; } @@ -344,11 +333,11 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, snd_soc_component_write(component, WM8974_PLLK1, pll_div.k >> 18); snd_soc_component_write(component, WM8974_PLLK2, (pll_div.k >> 9) & 0x1ff); snd_soc_component_write(component, WM8974_PLLK3, pll_div.k & 0x1ff); - reg = snd_soc_component_read32(component, WM8974_POWER1); + reg = snd_soc_component_read(component, WM8974_POWER1); snd_soc_component_write(component, WM8974_POWER1, reg | 0x020); /* Run CODEC from PLL instead of MCLK */ - reg = snd_soc_component_read32(component, WM8974_CLOCK); + reg = snd_soc_component_read(component, WM8974_CLOCK); snd_soc_component_write(component, WM8974_CLOCK, reg | 0x100); return 0; @@ -365,15 +354,15 @@ static int wm8974_set_dai_clkdiv(struct snd_soc_dai *codec_dai, switch (div_id) { case WM8974_OPCLKDIV: - reg = snd_soc_component_read32(component, WM8974_GPIO) & 0x1cf; + reg = snd_soc_component_read(component, WM8974_GPIO) & 0x1cf; snd_soc_component_write(component, WM8974_GPIO, reg | div); break; case WM8974_MCLKDIV: - reg = snd_soc_component_read32(component, WM8974_CLOCK) & 0x11f; + reg = snd_soc_component_read(component, WM8974_CLOCK) & 0x11f; snd_soc_component_write(component, WM8974_CLOCK, reg | div); break; case WM8974_BCLKDIV: - reg = snd_soc_component_read32(component, WM8974_CLOCK) & 0x1e3; + reg = snd_soc_component_read(component, WM8974_CLOCK) & 0x1e3; snd_soc_component_write(component, WM8974_CLOCK, reg | div); break; default: @@ -430,10 +419,14 @@ static int wm8974_update_clocks(struct snd_soc_dai *dai) fs256 = 256 * priv->fs; f = wm8974_get_mclkdiv(priv->mclk, fs256, &mclkdiv); - if (f != priv->mclk) { /* The PLL performs best around 90MHz */ - fpll = wm8974_get_mclkdiv(22500000, fs256, &mclkdiv); + if (fs256 % 8000) + f = 22579200; + else + f = 24576000; + + fpll = wm8974_get_mclkdiv(f, fs256, &mclkdiv); } wm8974_set_dai_pll(dai, 0, 0, priv->mclk, fpll); @@ -461,14 +454,14 @@ static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai, { struct snd_soc_component *component = codec_dai->component; u16 iface = 0; - u16 clk = snd_soc_component_read32(component, WM8974_CLOCK) & 0x1fe; + u16 clk = snd_soc_component_read(component, WM8974_CLOCK) & 0x1fe; /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: clk |= 0x0001; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; @@ -485,6 +478,10 @@ static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai, iface |= 0x0008; break; case SND_SOC_DAIFMT_DSP_A: + if ((fmt & SND_SOC_DAIFMT_INV_MASK) == SND_SOC_DAIFMT_IB_IF || + (fmt & SND_SOC_DAIFMT_INV_MASK) == SND_SOC_DAIFMT_NB_IF) { + return -EINVAL; + } iface |= 0x00018; break; default: @@ -519,8 +516,8 @@ static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_component *component = dai->component; struct wm8974_priv *priv = snd_soc_component_get_drvdata(component); - u16 iface = snd_soc_component_read32(component, WM8974_IFACE) & 0x19f; - u16 adn = snd_soc_component_read32(component, WM8974_ADD) & 0x1f1; + u16 iface = snd_soc_component_read(component, WM8974_IFACE) & 0x19f; + u16 adn = snd_soc_component_read(component, WM8974_ADD) & 0x1f1; int err; priv->fs = params_rate(params); @@ -570,10 +567,10 @@ static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream, return 0; } -static int wm8974_mute(struct snd_soc_dai *dai, int mute) +static int wm8974_mute(struct snd_soc_dai *dai, int mute, int direction) { struct snd_soc_component *component = dai->component; - u16 mute_reg = snd_soc_component_read32(component, WM8974_DAC) & 0xffbf; + u16 mute_reg = snd_soc_component_read(component, WM8974_DAC) & 0xffbf; if (mute) snd_soc_component_write(component, WM8974_DAC, mute_reg | 0x40); @@ -586,7 +583,8 @@ static int wm8974_mute(struct snd_soc_dai *dai, int mute) static int wm8974_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { - u16 power1 = snd_soc_component_read32(component, WM8974_POWER1) & ~0x3; + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + u16 power1 = snd_soc_component_read(component, WM8974_POWER1) & ~0x3; switch (level) { case SND_SOC_BIAS_ON: @@ -598,7 +596,7 @@ static int wm8974_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_STANDBY: power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN; - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { regcache_sync(dev_get_regmap(component->dev, NULL)); /* Initial cap charge at VMID 5k */ @@ -627,11 +625,12 @@ static int wm8974_set_bias_level(struct snd_soc_component *component, static const struct snd_soc_dai_ops wm8974_ops = { .hw_params = wm8974_pcm_hw_params, - .digital_mute = wm8974_mute, + .mute_stream = wm8974_mute, .set_fmt = wm8974_set_dai_fmt, .set_clkdiv = wm8974_set_dai_clkdiv, .set_pll = wm8974_set_dai_pll, .set_sysclk = wm8974_set_dai_sysclk, + .no_capture_mute = 1, }; static struct snd_soc_dai_driver wm8974_dai = { @@ -649,7 +648,7 @@ static struct snd_soc_dai_driver wm8974_dai = { .rates = WM8974_RATES, .formats = WM8974_FORMATS,}, .ops = &wm8974_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }; static const struct regmap_config wm8974_regmap = { @@ -688,11 +687,9 @@ static const struct snd_soc_component_driver soc_component_dev_wm8974 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; -static int wm8974_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int wm8974_i2c_probe(struct i2c_client *i2c) { struct wm8974_priv *priv; struct regmap *regmap; @@ -715,7 +712,7 @@ static int wm8974_i2c_probe(struct i2c_client *i2c, } static const struct i2c_device_id wm8974_i2c_id[] = { - { "wm8974", 0 }, + { "wm8974" }, { } }; MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id); @@ -731,7 +728,7 @@ static struct i2c_driver wm8974_i2c_driver = { .name = "wm8974", .of_match_table = wm8974_of_match, }, - .probe = wm8974_i2c_probe, + .probe = wm8974_i2c_probe, .id_table = wm8974_i2c_id, }; |
