diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-12 10:29:53 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-12 10:29:53 +0400 |
commit | eeab517b68beb9e044e869bee18e3bdfa60e5aca (patch) | |
tree | 48a47e3223786919f664824842a5a23d7a8d99cd /sound/soc/codecs/adav80x.c | |
parent | f095ca6b31cfd20e6e7e0338ed8548d8a4374287 (diff) | |
parent | a6bc732b5a96b5403c2637e85c350b95ec6591f3 (diff) | |
download | linux-eeab517b68beb9e044e869bee18e3bdfa60e5aca.tar.xz |
Merge tag 'sound-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"There are no too intrusive changes in this update batch. The biggest
LOC is found in the new DICE driver, and other small changes are
scattered over the whole sound subtree (which is a common pattern).
Below are highlights:
- ALSA core:
* Memory allocation support with genpool
* Fix blocking in drain ioctl of compress_offload
- HD-audio:
* Improved AMD HDMI supports
* Intel HDMI detection improvements
* thinkpad_acpi mute-key integration
* New PCI ID, New ALC255,285,293 codecs, CX20952
- USB-audio:
* New buffer size management
* Clean up endpoint handling codes
- ASoC:
* Further work on the dmaengine helpers, including support for
configuring the parameters for DMA by reading the capabilities of
the DMA controller which removes some guesswork and magic numbers
from drivers.
* A refresh of the documentation.
* Conversions of many drivers to direct regmap API usage in order
to allow the ASoC level register I/O code to be removed, this
will hopefully be completed by v3.14.
* Support for using async register I/O in DAPM, reducing the time
taken to implement power transitions on systems that support it.
- Firewire: DICE driver
- Lots of small fixes for bugs reported by Coverity"
* tag 'sound-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (382 commits)
ALSA: hda/realtek - Add new codec ALC255/ALC3234 UAJ supported
ALSA: hda - Apply MacBook fixups for CS4208 correctly
ASoC: fsl: imx-wm8962: remove an unneeded check
ASoC: fsl: imx-pcm-fiq: Remove unused 'runtime' variable
ALSA: hda/realtek - Make fixup regs persist after resume
ALSA: hda_intel: ratelimit "spurious response" message
ASoC: generic-dmaengine-pcm: Use SNDRV_DMA_TYPE_DEV_IRAM as default
ASoC: dapm: Use WARN_ON() instead of BUG_ON()
ASoC: wm_adsp: Fix BUG_ON() and WARN_ON() usages
ASoC: Replace BUG() with WARN()
ASoC: wm_hubs: Replace BUG() with WARN()
ASoC: wm8996: Replace BUG() with WARN()
ASoC: wm8962: Replace BUG() with WARN()
ASoC: wm8958: Replace BUG() with WARN()
ASoC: wm8904: Replace BUG() with WARN()
ASoC: wm8900: Replace BUG() with WARN()
ASoC: wm8350: Replace BUG() with WARN()
ASoC: txx9: Use WARN_ON() instead of BUG_ON()
ASoC: sh: Use WARN_ON() instead of BUG_ON()
ASoC: rcar: Use WARN_ON() instead of BUG_ON()
...
Diffstat (limited to 'sound/soc/codecs/adav80x.c')
-rw-r--r-- | sound/soc/codecs/adav80x.c | 147 |
1 files changed, 102 insertions, 45 deletions
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index 15b012d0f226..14a7c169d004 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -115,22 +115,34 @@ #define ADAV80X_PLL_OUTE_SYSCLKPD(x) BIT(2 - (x)) -static u8 adav80x_default_regs[] = { - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x01, 0x80, 0x26, 0x00, 0x00, - 0x02, 0x40, 0x20, 0x00, 0x09, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x92, 0xb1, 0x37, - 0x48, 0xd2, 0xfb, 0xca, 0xd2, 0x15, 0xe8, 0x29, 0xb9, 0x6a, 0xda, 0x2b, - 0xb7, 0xc0, 0x11, 0x65, 0x5c, 0xf6, 0xff, 0x8d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, - 0x00, 0xe8, 0x46, 0xe1, 0x5b, 0xd3, 0x43, 0x77, 0x93, 0xa7, 0x44, 0xee, - 0x32, 0x12, 0xc0, 0x11, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x3f, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, +static struct reg_default adav80x_reg_defaults[] = { + { ADAV80X_PLAYBACK_CTRL, 0x01 }, + { ADAV80X_AUX_IN_CTRL, 0x01 }, + { ADAV80X_REC_CTRL, 0x02 }, + { ADAV80X_AUX_OUT_CTRL, 0x01 }, + { ADAV80X_DPATH_CTRL1, 0xc0 }, + { ADAV80X_DPATH_CTRL2, 0x11 }, + { ADAV80X_DAC_CTRL1, 0x00 }, + { ADAV80X_DAC_CTRL2, 0x00 }, + { ADAV80X_DAC_CTRL3, 0x00 }, + { ADAV80X_DAC_L_VOL, 0xff }, + { ADAV80X_DAC_R_VOL, 0xff }, + { ADAV80X_PGA_L_VOL, 0x00 }, + { ADAV80X_PGA_R_VOL, 0x00 }, + { ADAV80X_ADC_CTRL1, 0x00 }, + { ADAV80X_ADC_CTRL2, 0x00 }, + { ADAV80X_ADC_L_VOL, 0xff }, + { ADAV80X_ADC_R_VOL, 0xff }, + { ADAV80X_PLL_CTRL1, 0x00 }, + { ADAV80X_PLL_CTRL2, 0x00 }, + { ADAV80X_ICLK_CTRL1, 0x00 }, + { ADAV80X_ICLK_CTRL2, 0x00 }, + { ADAV80X_PLL_CLK_SRC, 0x00 }, + { ADAV80X_PLL_OUTE, 0x00 }, }; struct adav80x { - enum snd_soc_control_type control_type; + struct regmap *regmap; enum adav80x_clk_src clk_src; unsigned int sysclk; @@ -298,7 +310,7 @@ static int adav80x_set_deemph(struct snd_soc_codec *codec) val = ADAV80X_DAC_CTRL2_DEEMPH_NONE; } - return snd_soc_update_bits(codec, ADAV80X_DAC_CTRL2, + return regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL2, ADAV80X_DAC_CTRL2_DEEMPH_MASK, val); } @@ -394,10 +406,11 @@ static int adav80x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } - snd_soc_update_bits(codec, adav80x_port_ctrl_regs[dai->id][0], + regmap_update_bits(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][0], ADAV80X_CAPTURE_MODE_MASK | ADAV80X_CAPTURE_MODE_MASTER, capture); - snd_soc_write(codec, adav80x_port_ctrl_regs[dai->id][1], playback); + regmap_write(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][1], + playback); adav80x->dai_fmt[dai->id] = fmt & SND_SOC_DAIFMT_FORMAT_MASK; @@ -407,6 +420,7 @@ static int adav80x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) static int adav80x_set_adc_clock(struct snd_soc_codec *codec, unsigned int sample_rate) { + struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); unsigned int val; if (sample_rate <= 48000) @@ -414,7 +428,7 @@ static int adav80x_set_adc_clock(struct snd_soc_codec *codec, else val = ADAV80X_ADC_CTRL1_MODULATOR_64FS; - snd_soc_update_bits(codec, ADAV80X_ADC_CTRL1, + regmap_update_bits(adav80x->regmap, ADAV80X_ADC_CTRL1, ADAV80X_ADC_CTRL1_MODULATOR_MASK, val); return 0; @@ -423,6 +437,7 @@ static int adav80x_set_adc_clock(struct snd_soc_codec *codec, static int adav80x_set_dac_clock(struct snd_soc_codec *codec, unsigned int sample_rate) { + struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); unsigned int val; if (sample_rate <= 48000) @@ -430,7 +445,7 @@ static int adav80x_set_dac_clock(struct snd_soc_codec *codec, else val = ADAV80X_DAC_CTRL2_DIV2 | ADAV80X_DAC_CTRL2_INTERPOL_128FS; - snd_soc_update_bits(codec, ADAV80X_DAC_CTRL2, + regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL2, ADAV80X_DAC_CTRL2_DIV_MASK | ADAV80X_DAC_CTRL2_INTERPOL_MASK, val); @@ -440,6 +455,7 @@ static int adav80x_set_dac_clock(struct snd_soc_codec *codec, static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec, struct snd_soc_dai *dai, snd_pcm_format_t format) { + struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); unsigned int val; switch (format) { @@ -459,7 +475,7 @@ static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec, return -EINVAL; } - snd_soc_update_bits(codec, adav80x_port_ctrl_regs[dai->id][0], + regmap_update_bits(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][0], ADAV80X_CAPTURE_WORD_LEN_MASK, val); return 0; @@ -491,7 +507,7 @@ static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec, return -EINVAL; } - snd_soc_update_bits(codec, adav80x_port_ctrl_regs[dai->id][1], + regmap_update_bits(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][1], ADAV80X_PLAYBACK_MODE_MASK, val); return 0; @@ -554,8 +570,10 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec, ADAV80X_ICLK_CTRL1_ICLK2_SRC(clk_id); iclk_ctrl2 = ADAV80X_ICLK_CTRL2_ICLK1_SRC(clk_id); - snd_soc_write(codec, ADAV80X_ICLK_CTRL1, iclk_ctrl1); - snd_soc_write(codec, ADAV80X_ICLK_CTRL2, iclk_ctrl2); + regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL1, + iclk_ctrl1); + regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2, + iclk_ctrl2); snd_soc_dapm_sync(&codec->dapm); } @@ -575,10 +593,12 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec, mask = ADAV80X_PLL_OUTE_SYSCLKPD(clk_id); if (freq == 0) { - snd_soc_update_bits(codec, ADAV80X_PLL_OUTE, mask, mask); + regmap_update_bits(adav80x->regmap, ADAV80X_PLL_OUTE, + mask, mask); adav80x->sysclk_pd[clk_id] = true; } else { - snd_soc_update_bits(codec, ADAV80X_PLL_OUTE, mask, 0); + regmap_update_bits(adav80x->regmap, ADAV80X_PLL_OUTE, + mask, 0); adav80x->sysclk_pd[clk_id] = false; } @@ -650,9 +670,9 @@ static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id, return -EINVAL; } - snd_soc_update_bits(codec, ADAV80X_PLL_CTRL1, ADAV80X_PLL_CTRL1_PLLDIV, - pll_ctrl1); - snd_soc_update_bits(codec, ADAV80X_PLL_CTRL2, + regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CTRL1, + ADAV80X_PLL_CTRL1_PLLDIV, pll_ctrl1); + regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CTRL2, ADAV80X_PLL_CTRL2_PLL_MASK(pll_id), pll_ctrl2); if (source != adav80x->pll_src) { @@ -661,7 +681,7 @@ static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id, else pll_src = ADAV80X_PLL_CLK_SRC_PLL_XIN(pll_id); - snd_soc_update_bits(codec, ADAV80X_PLL_CLK_SRC, + regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CLK_SRC, ADAV80X_PLL_CLK_SRC_PLL_MASK(pll_id), pll_src); adav80x->pll_src = source; @@ -675,6 +695,7 @@ static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id, static int adav80x_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); unsigned int mask = ADAV80X_DAC_CTRL1_PD; switch (level) { @@ -683,10 +704,12 @@ static int adav80x_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - snd_soc_update_bits(codec, ADAV80X_DAC_CTRL1, mask, 0x00); + regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL1, mask, + 0x00); break; case SND_SOC_BIAS_OFF: - snd_soc_update_bits(codec, ADAV80X_DAC_CTRL1, mask, mask); + regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL1, mask, + mask); break; } @@ -780,7 +803,7 @@ static int adav80x_probe(struct snd_soc_codec *codec) int ret; struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); - ret = snd_soc_codec_set_cache_io(codec, 7, 9, adav80x->control_type); + ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); if (ret) { dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); return ret; @@ -791,23 +814,31 @@ static int adav80x_probe(struct snd_soc_codec *codec) snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2"); /* Power down S/PDIF receiver, since it is currently not supported */ - snd_soc_write(codec, ADAV80X_PLL_OUTE, 0x20); + regmap_write(adav80x->regmap, ADAV80X_PLL_OUTE, 0x20); /* Disable DAC zero flag */ - snd_soc_write(codec, ADAV80X_DAC_CTRL3, 0x6); + regmap_write(adav80x->regmap, ADAV80X_DAC_CTRL3, 0x6); return adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); } static int adav80x_suspend(struct snd_soc_codec *codec) { - return adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF); + struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); + int ret; + + ret = adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF); + regcache_cache_only(adav80x->regmap, true); + + return ret; } static int adav80x_resume(struct snd_soc_codec *codec) { + struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); + + regcache_cache_only(adav80x->regmap, false); adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - codec->cache_sync = 1; - snd_soc_cache_sync(codec); + regcache_sync(adav80x->regmap); return 0; } @@ -827,10 +858,6 @@ static struct snd_soc_codec_driver adav80x_codec_driver = { .set_pll = adav80x_set_pll, .set_sysclk = adav80x_set_sysclk, - .reg_word_size = sizeof(u8), - .reg_cache_size = ARRAY_SIZE(adav80x_default_regs), - .reg_cache_default = adav80x_default_regs, - .controls = adav80x_controls, .num_controls = ARRAY_SIZE(adav80x_controls), .dapm_widgets = adav80x_dapm_widgets, @@ -839,18 +866,21 @@ static struct snd_soc_codec_driver adav80x_codec_driver = { .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), }; -static int adav80x_bus_probe(struct device *dev, - enum snd_soc_control_type control_type) +static int adav80x_bus_probe(struct device *dev, struct regmap *regmap) { struct adav80x *adav80x; int ret; + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + adav80x = kzalloc(sizeof(*adav80x), GFP_KERNEL); if (!adav80x) return -ENOMEM; + dev_set_drvdata(dev, adav80x); - adav80x->control_type = control_type; + adav80x->regmap = regmap; ret = snd_soc_register_codec(dev, &adav80x_codec_driver, adav80x_dais, ARRAY_SIZE(adav80x_dais)); @@ -868,6 +898,19 @@ static int adav80x_bus_remove(struct device *dev) } #if defined(CONFIG_SPI_MASTER) +static const struct regmap_config adav80x_spi_regmap_config = { + .val_bits = 8, + .pad_bits = 1, + .reg_bits = 7, + .read_flag_mask = 0x01, + + .max_register = ADAV80X_PLL_OUTE, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = adav80x_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults), +}; + static const struct spi_device_id adav80x_spi_id[] = { { "adav801", 0 }, { } @@ -876,7 +919,8 @@ MODULE_DEVICE_TABLE(spi, adav80x_spi_id); static int adav80x_spi_probe(struct spi_device *spi) { - return adav80x_bus_probe(&spi->dev, SND_SOC_SPI); + return adav80x_bus_probe(&spi->dev, + devm_regmap_init_spi(spi, &adav80x_spi_regmap_config)); } static int adav80x_spi_remove(struct spi_device *spi) @@ -896,6 +940,18 @@ static struct spi_driver adav80x_spi_driver = { #endif #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +static const struct regmap_config adav80x_i2c_regmap_config = { + .val_bits = 8, + .pad_bits = 1, + .reg_bits = 7, + + .max_register = ADAV80X_PLL_OUTE, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = adav80x_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults), +}; + static const struct i2c_device_id adav80x_i2c_id[] = { { "adav803", 0 }, { } @@ -905,7 +961,8 @@ MODULE_DEVICE_TABLE(i2c, adav80x_i2c_id); static int adav80x_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { - return adav80x_bus_probe(&client->dev, SND_SOC_I2C); + return adav80x_bus_probe(&client->dev, + devm_regmap_init_i2c(client, &adav80x_i2c_regmap_config)); } static int adav80x_i2c_remove(struct i2c_client *client) |