diff options
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r-- | sound/soc/codecs/Kconfig | 5 | ||||
-rw-r--r-- | sound/soc/codecs/ac97.c | 8 | ||||
-rw-r--r-- | sound/soc/codecs/ad1836.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/adau1701.c | 125 | ||||
-rw-r--r-- | sound/soc/codecs/adau1761.c | 26 | ||||
-rw-r--r-- | sound/soc/codecs/adau1781.c | 9 | ||||
-rw-r--r-- | sound/soc/codecs/adau17x1.c | 20 | ||||
-rw-r--r-- | sound/soc/codecs/adau1977.c | 5 |
8 files changed, 145 insertions, 55 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 061c46587628..84cad9a9fafe 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -16,7 +16,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_88PM860X if MFD_88PM860X select SND_SOC_L3 select SND_SOC_AB8500_CODEC if ABX500_CORE - select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS + select SND_SOC_AC97_CODEC select SND_SOC_AD1836 if SPI_MASTER select SND_SOC_AD193X_SPI if SPI_MASTER select SND_SOC_AD193X_I2C if I2C @@ -211,8 +211,9 @@ config SND_SOC_AB8500_CODEC tristate config SND_SOC_AC97_CODEC - tristate + tristate "Build generic ASoC AC97 CODEC driver" select SND_AC97_CODEC + select SND_SOC_AC97_BUS config SND_SOC_AD1836 tristate diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index d0ac723eee32..5b3224c63943 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -44,10 +44,6 @@ static int ac97_prepare(struct snd_pcm_substream *substream, return snd_ac97_set_rate(ac97, reg, substream->runtime->rate); } -#define STD_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ - SNDRV_PCM_RATE_48000) - static const struct snd_soc_dai_ops ac97_dai_ops = { .prepare = ac97_prepare, }; @@ -58,13 +54,13 @@ static struct snd_soc_dai_driver ac97_dai = { .stream_name = "AC97 Playback", .channels_min = 1, .channels_max = 2, - .rates = STD_AC97_RATES, + .rates = SNDRV_PCM_RATE_KNOT, .formats = SND_SOC_STD_AC97_FMTS,}, .capture = { .stream_name = "AC97 Capture", .channels_min = 1, .channels_max = 2, - .rates = STD_AC97_RATES, + .rates = SNDRV_PCM_RATE_KNOT, .formats = SND_SOC_STD_AC97_FMTS,}, .ops = &ac97_dai_ops, }; diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 685998dd086e..95f0bec26a1b 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -251,7 +251,7 @@ static int ad1836_resume(struct snd_soc_codec *codec) static int ad1836_probe(struct snd_soc_codec *codec) { struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = &codec->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); int num_dacs, num_adcs; int ret = 0; int i; diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 808b964086e3..ff7f846e3b76 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -16,6 +16,7 @@ #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/of_device.h> +#include <linux/regulator/consumer.h> #include <linux/regmap.h> #include <sound/core.h> #include <sound/pcm.h> @@ -101,6 +102,10 @@ #define ADAU1701_FIRMWARE "adau1701.bin" +static const char * const supply_names[] = { + "dvdd", "avdd" +}; + struct adau1701 { int gpio_nreset; int gpio_pll_mode[2]; @@ -112,6 +117,7 @@ struct adau1701 { u8 pin_config[12]; struct sigmadsp *sigmadsp; + struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; }; static const struct snd_kcontrol_new adau1701_controls[] = { @@ -668,6 +674,13 @@ static int adau1701_probe(struct snd_soc_codec *codec) if (ret) return ret; + ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies), + adau1701->supplies); + if (ret < 0) { + dev_err(codec->dev, "Failed to enable regulators: %d\n", ret); + return ret; + } + /* * Let the pll_clkdiv variable default to something that won't happen * at runtime. That way, we can postpone the firmware download from @@ -679,7 +692,7 @@ static int adau1701_probe(struct snd_soc_codec *codec) /* initalize with pre-configured pll mode settings */ ret = adau1701_reset(codec, adau1701->pll_clkdiv, 0); if (ret < 0) - return ret; + goto exit_regulators_disable; /* set up pin config */ val = 0; @@ -695,10 +708,60 @@ static int adau1701_probe(struct snd_soc_codec *codec) regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val); return 0; + +exit_regulators_disable: + + regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies); + return ret; } +static int adau1701_remove(struct snd_soc_codec *codec) +{ + struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); + + if (gpio_is_valid(adau1701->gpio_nreset)) + gpio_set_value_cansleep(adau1701->gpio_nreset, 0); + + regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies); + + return 0; +} + +#ifdef CONFIG_PM +static int adau1701_suspend(struct snd_soc_codec *codec) +{ + struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); + + regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), + adau1701->supplies); + + return 0; +} + +static int adau1701_resume(struct snd_soc_codec *codec) +{ + struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies), + adau1701->supplies); + if (ret < 0) { + dev_err(codec->dev, "Failed to enable regulators: %d\n", ret); + return ret; + } + + return adau1701_reset(codec, adau1701->pll_clkdiv, 0); +} +#else +#define adau1701_resume NULL +#define adau1701_suspend NULL +#endif /* CONFIG_PM */ + static struct snd_soc_codec_driver adau1701_codec_drv = { .probe = adau1701_probe, + .remove = adau1701_remove, + .resume = adau1701_resume, + .suspend = adau1701_suspend, .set_bias_level = adau1701_set_bias_level, .idle_bias_off = true, @@ -729,32 +792,58 @@ static int adau1701_i2c_probe(struct i2c_client *client, struct device *dev = &client->dev; int gpio_nreset = -EINVAL; int gpio_pll_mode[2] = { -EINVAL, -EINVAL }; - int ret; + int ret, i; adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL); if (!adau1701) return -ENOMEM; + for (i = 0; i < ARRAY_SIZE(supply_names); i++) + adau1701->supplies[i].supply = supply_names[i]; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(adau1701->supplies), + adau1701->supplies); + if (ret < 0) { + dev_err(dev, "Failed to get regulators: %d\n", ret); + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies), + adau1701->supplies); + if (ret < 0) { + dev_err(dev, "Failed to enable regulators: %d\n", ret); + return ret; + } + adau1701->client = client; adau1701->regmap = devm_regmap_init(dev, NULL, client, &adau1701_regmap); - if (IS_ERR(adau1701->regmap)) - return PTR_ERR(adau1701->regmap); + if (IS_ERR(adau1701->regmap)) { + ret = PTR_ERR(adau1701->regmap); + goto exit_regulators_disable; + } + if (dev->of_node) { gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0); - if (gpio_nreset < 0 && gpio_nreset != -ENOENT) - return gpio_nreset; + if (gpio_nreset < 0 && gpio_nreset != -ENOENT) { + ret = gpio_nreset; + goto exit_regulators_disable; + } gpio_pll_mode[0] = of_get_named_gpio(dev->of_node, "adi,pll-mode-gpios", 0); - if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT) - return gpio_pll_mode[0]; + if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT) { + ret = gpio_pll_mode[0]; + goto exit_regulators_disable; + } gpio_pll_mode[1] = of_get_named_gpio(dev->of_node, "adi,pll-mode-gpios", 1); - if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT) - return gpio_pll_mode[1]; + if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT) { + ret = gpio_pll_mode[1]; + goto exit_regulators_disable; + } of_property_read_u32(dev->of_node, "adi,pll-clkdiv", &adau1701->pll_clkdiv); @@ -768,7 +857,7 @@ static int adau1701_i2c_probe(struct i2c_client *client, ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW, "ADAU1701 Reset"); if (ret < 0) - return ret; + goto exit_regulators_disable; } if (gpio_is_valid(gpio_pll_mode[0]) && @@ -777,13 +866,13 @@ static int adau1701_i2c_probe(struct i2c_client *client, GPIOF_OUT_INIT_LOW, "ADAU1701 PLL mode 0"); if (ret < 0) - return ret; + goto exit_regulators_disable; ret = devm_gpio_request_one(dev, gpio_pll_mode[1], GPIOF_OUT_INIT_LOW, "ADAU1701 PLL mode 1"); if (ret < 0) - return ret; + goto exit_regulators_disable; } adau1701->gpio_nreset = gpio_nreset; @@ -794,11 +883,17 @@ static int adau1701_i2c_probe(struct i2c_client *client, adau1701->sigmadsp = devm_sigmadsp_init_i2c(client, &adau1701_sigmadsp_ops, ADAU1701_FIRMWARE); - if (IS_ERR(adau1701->sigmadsp)) - return PTR_ERR(adau1701->sigmadsp); + if (IS_ERR(adau1701->sigmadsp)) { + ret = PTR_ERR(adau1701->sigmadsp); + goto exit_regulators_disable; + } ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, &adau1701_dai, 1); + +exit_regulators_disable: + + regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies); return ret; } diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index 5ba24618b576..2f12477e539e 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c @@ -482,6 +482,7 @@ static enum adau1761_output_mode adau1761_get_lineout_mode( static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct adau1761_platform_data *pdata = codec->dev->platform_data; struct adau *adau = snd_soc_codec_get_drvdata(codec); enum adau1761_digmic_jackdet_pin_mode mode; @@ -514,21 +515,18 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec) if (ret) return ret; case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: /* fallthrough */ - ret = snd_soc_dapm_add_routes(&codec->dapm, - adau1761_no_dmic_routes, + ret = snd_soc_dapm_add_routes(dapm, adau1761_no_dmic_routes, ARRAY_SIZE(adau1761_no_dmic_routes)); if (ret) return ret; break; case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC: - ret = snd_soc_dapm_new_controls(&codec->dapm, - adau1761_dmic_widgets, + ret = snd_soc_dapm_new_controls(dapm, adau1761_dmic_widgets, ARRAY_SIZE(adau1761_dmic_widgets)); if (ret) return ret; - ret = snd_soc_dapm_add_routes(&codec->dapm, - adau1761_dmic_routes, + ret = snd_soc_dapm_add_routes(dapm, adau1761_dmic_routes, ARRAY_SIZE(adau1761_dmic_routes)); if (ret) return ret; @@ -546,6 +544,7 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec) static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct adau *adau = snd_soc_codec_get_drvdata(codec); struct adau1761_platform_data *pdata = codec->dev->platform_data; enum adau1761_output_mode mode; @@ -576,12 +575,12 @@ static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec) } if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) { - ret = snd_soc_dapm_new_controls(&codec->dapm, + ret = snd_soc_dapm_new_controls(dapm, adau1761_capless_dapm_widgets, ARRAY_SIZE(adau1761_capless_dapm_widgets)); if (ret) return ret; - ret = snd_soc_dapm_add_routes(&codec->dapm, + ret = snd_soc_dapm_add_routes(dapm, adau1761_capless_dapm_routes, ARRAY_SIZE(adau1761_capless_dapm_routes)); } else { @@ -589,12 +588,12 @@ static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec) ARRAY_SIZE(adau1761_mono_controls)); if (ret) return ret; - ret = snd_soc_dapm_new_controls(&codec->dapm, + ret = snd_soc_dapm_new_controls(dapm, adau1761_mono_dapm_widgets, ARRAY_SIZE(adau1761_mono_dapm_widgets)); if (ret) return ret; - ret = snd_soc_dapm_add_routes(&codec->dapm, + ret = snd_soc_dapm_add_routes(dapm, adau1761_mono_dapm_routes, ARRAY_SIZE(adau1761_mono_dapm_routes)); } @@ -639,6 +638,7 @@ static bool adau1761_readable_register(struct device *dev, unsigned int reg) static int adau1761_codec_probe(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct adau1761_platform_data *pdata = codec->dev->platform_data; struct adau *adau = snd_soc_codec_get_drvdata(codec); int ret; @@ -691,14 +691,12 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec) return ret; if (adau->type == ADAU1761) { - ret = snd_soc_dapm_new_controls(&codec->dapm, - adau1761_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, adau1761_dapm_widgets, ARRAY_SIZE(adau1761_dapm_widgets)); if (ret) return ret; - ret = snd_soc_dapm_add_routes(&codec->dapm, - adau1761_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, adau1761_dapm_routes, ARRAY_SIZE(adau1761_dapm_routes)); if (ret) return ret; diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c index 9c01ef0de0c0..fde9068550a6 100644 --- a/sound/soc/codecs/adau1781.c +++ b/sound/soc/codecs/adau1781.c @@ -382,6 +382,7 @@ static int adau1781_set_input_mode(struct adau *adau, unsigned int reg, static int adau1781_codec_probe(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct adau1781_platform_data *pdata = dev_get_platdata(codec->dev); struct adau *adau = snd_soc_codec_get_drvdata(codec); int ret; @@ -402,19 +403,17 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec) } if (pdata && pdata->use_dmic) { - ret = snd_soc_dapm_new_controls(&codec->dapm, + ret = snd_soc_dapm_new_controls(dapm, adau1781_dmic_dapm_widgets, ARRAY_SIZE(adau1781_dmic_dapm_widgets)); if (ret) return ret; - ret = snd_soc_dapm_add_routes(&codec->dapm, - adau1781_dmic_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, adau1781_dmic_dapm_routes, ARRAY_SIZE(adau1781_dmic_dapm_routes)); if (ret) return ret; } else { - ret = snd_soc_dapm_add_routes(&codec->dapm, - adau1781_adc_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, adau1781_adc_dapm_routes, ARRAY_SIZE(adau1781_adc_dapm_routes)); if (ret) return ret; diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index fa2e690e51c8..fcf05b254ecd 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -155,6 +155,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct adau *adau = snd_soc_codec_get_drvdata(codec); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_dapm_update update; @@ -188,7 +189,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol, update.reg = reg; update.val = val; - snd_soc_dapm_mux_update_power(&codec->dapm, kcontrol, + snd_soc_dapm_mux_update_power(dapm, kcontrol, ucontrol->value.enumerated.item[0], e, &update); } @@ -444,8 +445,8 @@ static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id, static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(dai->codec); struct adau *adau = snd_soc_codec_get_drvdata(dai->codec); - struct snd_soc_dapm_context *dapm = &dai->codec->dapm; switch (clk_id) { case ADAU17X1_CLK_SRC_MCLK: @@ -804,6 +805,7 @@ EXPORT_SYMBOL_GPL(adau17x1_setup_firmware); int adau17x1_add_widgets(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct adau *adau = snd_soc_codec_get_drvdata(codec); int ret; @@ -811,14 +813,13 @@ int adau17x1_add_widgets(struct snd_soc_codec *codec) ARRAY_SIZE(adau17x1_controls)); if (ret) return ret; - ret = snd_soc_dapm_new_controls(&codec->dapm, adau17x1_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, adau17x1_dapm_widgets, ARRAY_SIZE(adau17x1_dapm_widgets)); if (ret) return ret; if (adau17x1_has_dsp(adau)) { - ret = snd_soc_dapm_new_controls(&codec->dapm, - adau17x1_dsp_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, adau17x1_dsp_dapm_widgets, ARRAY_SIZE(adau17x1_dsp_dapm_widgets)); if (ret) return ret; @@ -840,21 +841,20 @@ EXPORT_SYMBOL_GPL(adau17x1_add_widgets); int adau17x1_add_routes(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct adau *adau = snd_soc_codec_get_drvdata(codec); int ret; - ret = snd_soc_dapm_add_routes(&codec->dapm, adau17x1_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, adau17x1_dapm_routes, ARRAY_SIZE(adau17x1_dapm_routes)); if (ret) return ret; if (adau17x1_has_dsp(adau)) { - ret = snd_soc_dapm_add_routes(&codec->dapm, - adau17x1_dsp_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, adau17x1_dsp_dapm_routes, ARRAY_SIZE(adau17x1_dsp_dapm_routes)); } else { - ret = snd_soc_dapm_add_routes(&codec->dapm, - adau17x1_no_dsp_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, adau17x1_no_dsp_dapm_routes, ARRAY_SIZE(adau17x1_no_dsp_dapm_routes)); } return ret; diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c index 3fb09c165055..d203ec9ba5b6 100644 --- a/sound/soc/codecs/adau1977.c +++ b/sound/soc/codecs/adau1977.c @@ -485,7 +485,7 @@ static int adau1977_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) + if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) ret = adau1977_power_enable(adau1977); break; case SND_SOC_BIAS_OFF: @@ -848,12 +848,13 @@ static int adau1977_set_sysclk(struct snd_soc_codec *codec, static int adau1977_codec_probe(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec); int ret; switch (adau1977->type) { case ADAU1977: - ret = snd_soc_dapm_new_controls(&codec->dapm, + ret = snd_soc_dapm_new_controls(dapm, adau1977_micbias_dapm_widgets, ARRAY_SIZE(adau1977_micbias_dapm_widgets)); if (ret < 0) |