diff options
Diffstat (limited to 'sound/soc/codecs')
31 files changed, 472 insertions, 146 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index cbfa1e18f651..0b9571c858f8 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -225,11 +225,11 @@ config SND_SOC_ADAU1373 config SND_SOC_ADAU1701 tristate "Analog Devices ADAU1701 CODEC" depends on I2C - select SND_SOC_SIGMADSP + select SND_SOC_SIGMADSP_I2C config SND_SOC_ADAU17X1 tristate - select SND_SOC_SIGMADSP + select SND_SOC_SIGMADSP_REGMAP config SND_SOC_ADAU1761 tristate @@ -476,6 +476,14 @@ config SND_SOC_SIGMADSP tristate select CRC32 +config SND_SOC_SIGMADSP_I2C + tristate + select SND_SOC_SIGMADSP + +config SND_SOC_SIGMADSP_REGMAP + tristate + select SND_SOC_SIGMADSP + config SND_SOC_SIRF_AUDIO_CODEC tristate "SiRF SoC internal audio codec" select REGMAP_MMIO diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index be3377b8d73f..1bd6e1cf6f82 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -77,6 +77,8 @@ snd-soc-sgtl5000-objs := sgtl5000.o snd-soc-alc5623-objs := alc5623.o snd-soc-alc5632-objs := alc5632.o snd-soc-sigmadsp-objs := sigmadsp.o +snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o +snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o snd-soc-si476x-objs := si476x.o snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o snd-soc-sn95031-objs := sn95031.o @@ -240,6 +242,8 @@ obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o +obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o +obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 8d9ba4ba4bfe..e889e1b84192 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -89,8 +89,8 @@ static int ac97_soc_probe(struct snd_soc_codec *codec) int ret; /* add codec as bus device for standard ac97 */ - ret = snd_ac97_bus(codec->card->snd_card, 0, soc_ac97_ops, NULL, - &ac97_bus); + ret = snd_ac97_bus(codec->component.card->snd_card, 0, soc_ac97_ops, + NULL, &ac97_bus); if (ret < 0) return ret; diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index d71c59cf7bdd..370b742117ef 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -230,8 +230,10 @@ static int adau1701_reg_read(void *context, unsigned int reg, *value = 0; - for (i = 0; i < size; i++) - *value |= recv_buf[i] << (i * 8); + for (i = 0; i < size; i++) { + *value <<= 8; + *value |= recv_buf[i]; + } return 0; } diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c index fd55da7cb9d4..70ab35744aba 100644 --- a/sound/soc/codecs/adau1977.c +++ b/sound/soc/codecs/adau1977.c @@ -968,7 +968,7 @@ int adau1977_probe(struct device *dev, struct regmap *regmap, if (adau1977->dvdd_reg) power_off_mask = ~0; else - power_off_mask = ~ADAU1977_BLOCK_POWER_SAI_LDO_EN; + power_off_mask = (unsigned int)~ADAU1977_BLOCK_POWER_SAI_LDO_EN; ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI, power_off_mask, 0x00); diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 3ba4c0f11418..041712592e29 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -547,7 +547,7 @@ static const struct ak4642_drvdata ak4648_drvdata = { .extended_frequencies = 1, }; -static struct of_device_id ak4642_of_match[]; +static const struct of_device_id ak4642_of_match[]; static int ak4642_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -593,7 +593,7 @@ static int ak4642_i2c_remove(struct i2c_client *client) return 0; } -static struct of_device_id ak4642_of_match[] = { +static const struct of_device_id ak4642_of_match[] = { { .compatible = "asahi-kasei,ak4642", .data = &ak4642_drvdata}, { .compatible = "asahi-kasei,ak4643", .data = &ak4643_drvdata}, { .compatible = "asahi-kasei,ak4648", .data = &ak4648_drvdata}, diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 29e198f57d4c..2f2e91ac690f 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -243,6 +243,31 @@ int arizona_init_spk(struct snd_soc_codec *codec) } EXPORT_SYMBOL_GPL(arizona_init_spk); +static const struct snd_soc_dapm_route arizona_mono_routes[] = { + { "OUT1R", NULL, "OUT1L" }, + { "OUT2R", NULL, "OUT2L" }, + { "OUT3R", NULL, "OUT3L" }, + { "OUT4R", NULL, "OUT4L" }, + { "OUT5R", NULL, "OUT5L" }, + { "OUT6R", NULL, "OUT6L" }, +}; + +int arizona_init_mono(struct snd_soc_codec *codec) +{ + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->arizona; + int i; + + for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) { + if (arizona->pdata.out_mono[i]) + snd_soc_dapm_add_routes(&codec->dapm, + &arizona_mono_routes[i], 1); + } + + return 0; +} +EXPORT_SYMBOL_GPL(arizona_init_mono); + int arizona_init_gpio(struct snd_soc_codec *codec) { struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); @@ -1127,6 +1152,31 @@ static int arizona_startup(struct snd_pcm_substream *substream, constraint); } +static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec, + unsigned int rate) +{ + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->arizona; + struct reg_default dac_comp[] = { + { 0x80, 0x3 }, + { ARIZONA_DAC_COMP_1, 0 }, + { ARIZONA_DAC_COMP_2, 0 }, + { 0x80, 0x0 }, + }; + + mutex_lock(&codec->mutex); + + dac_comp[1].def = arizona->dac_comp_coeff; + if (rate >= 176400) + dac_comp[2].def = arizona->dac_comp_enabled; + + mutex_unlock(&codec->mutex); + + regmap_multi_reg_write(arizona->regmap, + dac_comp, + ARRAY_SIZE(dac_comp)); +} + static int arizona_hw_params_rate(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -1153,6 +1203,15 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream, switch (dai_priv->clk) { case ARIZONA_CLK_SYSCLK: + switch (priv->arizona->type) { + case WM5102: + arizona_wm5102_set_dac_comp(codec, + params_rate(params)); + break; + default: + break; + } + snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1, ARIZONA_SAMPLE_RATE_1_MASK, sr_val); if (base) @@ -1175,6 +1234,27 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream, return 0; } +static bool arizona_aif_cfg_changed(struct snd_soc_codec *codec, + int base, int bclk, int lrclk, int frame) +{ + int val; + + val = snd_soc_read(codec, base + ARIZONA_AIF_BCLK_CTRL); + if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK)) + return true; + + val = snd_soc_read(codec, base + ARIZONA_AIF_TX_BCLK_RATE); + if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK)) + return true; + + val = snd_soc_read(codec, base + ARIZONA_AIF_FRAME_CTRL_1); + if (frame != (val & (ARIZONA_AIF1TX_WL_MASK | + ARIZONA_AIF1TX_SLOT_LEN_MASK))) + return true; + + return false; +} + static int arizona_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -1185,26 +1265,40 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, int base = dai->driver->base; const int *rates; int i, ret, val; + int channels = params_channels(params); int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; + int tdm_width = arizona->tdm_width[dai->id - 1]; + int tdm_slots = arizona->tdm_slots[dai->id - 1]; int bclk, lrclk, wl, frame, bclk_target; + bool reconfig; + unsigned int aif_tx_state, aif_rx_state; if (params_rate(params) % 8000) rates = &arizona_44k1_bclk_rates[0]; else rates = &arizona_48k_bclk_rates[0]; - bclk_target = snd_soc_params_to_bclk(params); - if (chan_limit && chan_limit < params_channels(params)) { + if (tdm_slots) { + arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n", + tdm_slots, tdm_width); + bclk_target = tdm_slots * tdm_width * params_rate(params); + channels = tdm_slots; + } else { + bclk_target = snd_soc_params_to_bclk(params); + } + + if (chan_limit && chan_limit < channels) { arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit); - bclk_target /= params_channels(params); + bclk_target /= channels; bclk_target *= chan_limit; } - /* Force stereo for I2S mode */ + /* Force multiple of 2 channels for I2S mode */ val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT); - if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) { + if ((channels & 1) && (val & ARIZONA_AIF1_FMT_MASK)) { arizona_aif_dbg(dai, "Forcing stereo mode\n"); - bclk_target *= 2; + bclk_target /= channels; + bclk_target *= channels + 1; } for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { @@ -1228,28 +1322,56 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, wl = snd_pcm_format_width(params_format(params)); frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl; + reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame); + + if (reconfig) { + /* Save AIF TX/RX state */ + aif_tx_state = snd_soc_read(codec, + base + ARIZONA_AIF_TX_ENABLES); + aif_rx_state = snd_soc_read(codec, + base + ARIZONA_AIF_RX_ENABLES); + /* Disable AIF TX/RX before reconfiguring it */ + regmap_update_bits_async(arizona->regmap, + base + ARIZONA_AIF_TX_ENABLES, 0xff, 0x0); + regmap_update_bits(arizona->regmap, + base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0); + } + ret = arizona_hw_params_rate(substream, params, dai); if (ret != 0) - return ret; + goto restore_aif; - 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); + if (reconfig) { + 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; +restore_aif: + if (reconfig) { + /* Restore AIF TX/RX state */ + regmap_update_bits_async(arizona->regmap, + base + ARIZONA_AIF_TX_ENABLES, + 0xff, aif_tx_state); + regmap_update_bits(arizona->regmap, + base + ARIZONA_AIF_RX_ENABLES, + 0xff, aif_rx_state); + } + return ret; } static const char *arizona_dai_clk_str(int clk_id) @@ -1324,9 +1446,63 @@ static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate) ARIZONA_AIF1_TRI, reg); } +static void arizona_set_channels_to_mask(struct snd_soc_dai *dai, + unsigned int base, + int channels, unsigned int mask) +{ + struct snd_soc_codec *codec = dai->codec; + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->arizona; + int slot, i; + + for (i = 0; i < channels; ++i) { + slot = ffs(mask) - 1; + if (slot < 0) + return; + + regmap_write(arizona->regmap, base + i, slot); + + mask &= ~(1 << slot); + } + + if (mask) + arizona_aif_warn(dai, "Too many channels in TDM mask\n"); +} + +static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, + unsigned int rx_mask, int slots, int slot_width) +{ + struct snd_soc_codec *codec = dai->codec; + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->arizona; + int base = dai->driver->base; + int rx_max_chan = dai->driver->playback.channels_max; + int tx_max_chan = dai->driver->capture.channels_max; + + /* Only support TDM for the physical AIFs */ + if (dai->id > ARIZONA_MAX_AIF) + return -ENOTSUPP; + + if (slots == 0) { + tx_mask = (1 << tx_max_chan) - 1; + rx_mask = (1 << rx_max_chan) - 1; + } + + arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_3, + tx_max_chan, tx_mask); + arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_11, + rx_max_chan, rx_mask); + + arizona->tdm_width[dai->id - 1] = slot_width; + arizona->tdm_slots[dai->id - 1] = slots; + + return 0; +} + const struct snd_soc_dai_ops arizona_dai_ops = { .startup = arizona_startup, .set_fmt = arizona_set_fmt, + .set_tdm_slot = arizona_set_tdm_slot, .hw_params = arizona_hw_params, .set_sysclk = arizona_dai_set_sysclk, .set_tristate = arizona_set_tristate, @@ -1400,6 +1576,12 @@ static int arizona_validate_fll(struct arizona_fll *fll, { unsigned int Fvco_min; + if (fll->fout && Fout != fll->fout) { + arizona_fll_err(fll, + "Can't change output on active FLL\n"); + return -EINVAL; + } + if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) { arizona_fll_err(fll, "Can't scale %dMHz in to <=13.5MHz\n", @@ -1478,6 +1660,10 @@ static int arizona_calc_fratio(struct arizona_fll *fll, while (div <= ARIZONA_FLL_MAX_REFDIV) { for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO; ratio++) { + if ((ARIZONA_FLL_VCO_CORNER / 2) / + (fll->vco_mult * ratio) < Fref) + break; + if (target % (ratio * Fref)) { cfg->refdiv = refdiv; cfg->fratio = ratio - 1; @@ -1485,11 +1671,7 @@ static int arizona_calc_fratio(struct arizona_fll *fll, } } - for (ratio = init_ratio - 1; ratio >= 0; ratio--) { - if (ARIZONA_FLL_VCO_CORNER / (fll->vco_mult * ratio) < - Fref) - break; - + for (ratio = init_ratio - 1; ratio > 0; ratio--) { if (target % (ratio * Fref)) { cfg->refdiv = refdiv; cfg->fratio = ratio - 1; @@ -1616,7 +1798,7 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base, ARIZONA_FLL1_CTRL_UPD | cfg->n); } -static bool arizona_is_enabled_fll(struct arizona_fll *fll) +static int arizona_is_enabled_fll(struct arizona_fll *fll) { struct arizona *arizona = fll->arizona; unsigned int reg; @@ -1632,13 +1814,26 @@ static bool arizona_is_enabled_fll(struct arizona_fll *fll) return reg & ARIZONA_FLL1_ENA; } -static void arizona_enable_fll(struct arizona_fll *fll) +static int arizona_enable_fll(struct arizona_fll *fll) { struct arizona *arizona = fll->arizona; int ret; bool use_sync = false; + int already_enabled = arizona_is_enabled_fll(fll); struct arizona_fll_cfg cfg; + if (already_enabled < 0) + return already_enabled; + + if (already_enabled) { + /* Facilitate smooth refclk across the transition */ + regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x7, + ARIZONA_FLL1_GAIN_MASK, 0); + regmap_update_bits_async(fll->arizona->regmap, fll->base + 1, + ARIZONA_FLL1_FREERUN, + ARIZONA_FLL1_FREERUN); + } + /* * If we have both REFCLK and SYNCCLK then enable both, * otherwise apply the SYNCCLK settings to REFCLK. @@ -1666,7 +1861,7 @@ static void arizona_enable_fll(struct arizona_fll *fll) ARIZONA_FLL1_SYNC_ENA, 0); } else { arizona_fll_err(fll, "No clocks provided\n"); - return; + return -EINVAL; } /* @@ -1681,25 +1876,29 @@ static void arizona_enable_fll(struct arizona_fll *fll) ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW); - if (!arizona_is_enabled_fll(fll)) + if (!already_enabled) pm_runtime_get(arizona->dev); /* Clear any pending completions */ try_wait_for_completion(&fll->ok); 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_async(arizona->regmap, fll->base + 0x11, ARIZONA_FLL1_SYNC_ENA, ARIZONA_FLL1_SYNC_ENA); + if (already_enabled) + regmap_update_bits_async(arizona->regmap, fll->base + 1, + ARIZONA_FLL1_FREERUN, 0); + ret = wait_for_completion_timeout(&fll->ok, msecs_to_jiffies(250)); if (ret == 0) arizona_fll_warn(fll, "Timed out waiting for lock\n"); + + return 0; } static void arizona_disable_fll(struct arizona_fll *fll) @@ -1713,6 +1912,8 @@ static void arizona_disable_fll(struct arizona_fll *fll) ARIZONA_FLL1_ENA, 0, &change); regmap_update_bits(arizona->regmap, fll->base + 0x11, ARIZONA_FLL1_SYNC_ENA, 0); + regmap_update_bits_async(arizona->regmap, fll->base + 1, + ARIZONA_FLL1_FREERUN, 0); if (change) pm_runtime_put_autosuspend(arizona->dev); @@ -1721,7 +1922,7 @@ static void arizona_disable_fll(struct arizona_fll *fll) int arizona_set_fll_refclk(struct arizona_fll *fll, int source, unsigned int Fref, unsigned int Fout) { - int ret; + int ret = 0; if (fll->ref_src == source && fll->ref_freq == Fref) return 0; @@ -1736,17 +1937,17 @@ int arizona_set_fll_refclk(struct arizona_fll *fll, int source, fll->ref_freq = Fref; if (fll->fout && Fref > 0) { - arizona_enable_fll(fll); + ret = arizona_enable_fll(fll); } - return 0; + return ret; } EXPORT_SYMBOL_GPL(arizona_set_fll_refclk); int arizona_set_fll(struct arizona_fll *fll, int source, unsigned int Fref, unsigned int Fout) { - int ret; + int ret = 0; if (fll->sync_src == source && fll->sync_freq == Fref && fll->fout == Fout) @@ -1768,13 +1969,12 @@ int arizona_set_fll(struct arizona_fll *fll, int source, fll->sync_freq = Fref; fll->fout = Fout; - if (Fout) { - arizona_enable_fll(fll); - } else { + if (Fout) + ret = arizona_enable_fll(fll); + else arizona_disable_fll(fll); - } - return 0; + return ret; } EXPORT_SYMBOL_GPL(arizona_set_fll); diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 05ae17f5bca3..942cfb197b6d 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -249,6 +249,7 @@ extern int arizona_set_fll(struct arizona_fll *fll, int source, extern int arizona_init_spk(struct snd_soc_codec *codec); extern int arizona_init_gpio(struct snd_soc_codec *codec); +extern int arizona_init_mono(struct snd_soc_codec *codec); extern int arizona_init_dai(struct arizona_priv *priv, int dai); diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index fdc4bd27b0df..8e68ef5de849 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -445,9 +445,9 @@ static const struct snd_kcontrol_new cs42l56_snd_controls[] = { SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1), SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME, - CS42L56_HPA_VOLUME, 0, 0x44, 0x55, hl_tlv), + CS42L56_HPB_VOLUME, 0, 0x44, 0x55, hl_tlv), SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME, - CS42L56_LOA_VOLUME, 0, 0x44, 0x55, hl_tlv), + CS42L56_LOB_VOLUME, 0, 0x44, 0x55, hl_tlv), SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL, 0, 0x00, 1, tone_tlv), diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index d5fd00a64748..4ba60eb2cde1 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -253,7 +253,7 @@ static void v253_close(struct tty_struct *tty) /* Prevent the codec driver from further accessing the modem */ codec->hw_write = NULL; cx20442->control_data = NULL; - codec->card->pop_time = 0; + codec->component.card->pop_time = 0; } /* Line discipline .hangup() */ @@ -281,7 +281,7 @@ static void v253_receive(struct tty_struct *tty, /* Set up codec driver access to modem controls */ cx20442->control_data = tty; codec->hw_write = (hw_write_t)tty->ops->write; - codec->card->pop_time = 1; + codec->component.card->pop_time = 1; } } @@ -372,7 +372,7 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec) snd_soc_codec_set_drvdata(codec, cx20442); codec->hw_write = NULL; - codec->card->pop_time = 0; + codec->component.card->pop_time = 0; return 0; } diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index f5fccc7a8e89..d97f1ce7ff7d 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -2284,7 +2284,7 @@ static int max98090_probe(struct snd_soc_codec *codec) /* Register for interrupts */ dev_dbg(codec->dev, "irq = %d\n", max98090->irq); - ret = request_threaded_irq(max98090->irq, NULL, + ret = devm_request_threaded_irq(codec->dev, max98090->irq, NULL, max98090_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "max98090_interrupt", codec); if (ret < 0) { diff --git a/sound/soc/codecs/pcm1792a.c b/sound/soc/codecs/pcm1792a.c index 3a80ba4452df..57b0c94a710b 100644 --- a/sound/soc/codecs/pcm1792a.c +++ b/sound/soc/codecs/pcm1792a.c @@ -36,6 +36,7 @@ #define PCM1792A_DAC_VOL_LEFT 0x10 #define PCM1792A_DAC_VOL_RIGHT 0x11 #define PCM1792A_FMT_CONTROL 0x12 +#define PCM1792A_MODE_CONTROL 0x13 #define PCM1792A_SOFT_MUTE PCM1792A_FMT_CONTROL #define PCM1792A_FMT_MASK 0x70 @@ -164,6 +165,8 @@ static const struct snd_kcontrol_new pcm1792a_controls[] = { SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM1792A_DAC_VOL_LEFT, PCM1792A_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0, pcm1792a_dac_tlv), + SOC_SINGLE("DAC Invert Output Switch", PCM1792A_MODE_CONTROL, 7, 1, 0), + SOC_SINGLE("DAC Rolloff Filter Switch", PCM1792A_MODE_CONTROL, 1, 1, 0), }; static const struct snd_soc_dapm_widget pcm1792a_dapm_widgets[] = { diff --git a/sound/soc/codecs/pcm1792a.h b/sound/soc/codecs/pcm1792a.h index 7a83d1fc102a..51d5470fee16 100644 --- a/sound/soc/codecs/pcm1792a.h +++ b/sound/soc/codecs/pcm1792a.h @@ -18,7 +18,8 @@ #define __PCM1792A_H__ #define PCM1792A_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \ - SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \ + SNDRV_PCM_RATE_192000) #define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S16_LE) diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 3d39f0b5b4a8..8f4c73d17c87 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1277,7 +1277,7 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) return ret; } - ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); if (ret) goto err_ldo_remove; @@ -1285,13 +1285,16 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); if (ret) - goto err_ldo_remove; + goto err_regulator_free; /* wait for all power rails bring up */ udelay(10); return 0; +err_regulator_free: + regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), + sgtl5000->supplies); err_ldo_remove: if (!external_vddd) ldo_regulator_remove(codec); @@ -1361,6 +1364,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) err: regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); + regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), + sgtl5000->supplies); ldo_regulator_remove(codec); return ret; @@ -1374,6 +1379,8 @@ static int sgtl5000_remove(struct snd_soc_codec *codec) regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); + regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), + sgtl5000->supplies); ldo_regulator_remove(codec); return 0; diff --git a/sound/soc/codecs/sigmadsp-i2c.c b/sound/soc/codecs/sigmadsp-i2c.c new file mode 100644 index 000000000000..246081aae8ca --- /dev/null +++ b/sound/soc/codecs/sigmadsp-i2c.c @@ -0,0 +1,35 @@ +/* + * Load Analog Devices SigmaStudio firmware files + * + * Copyright 2009-2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <linux/i2c.h> +#include <linux/export.h> +#include <linux/module.h> + +#include "sigmadsp.h" + +static int sigma_action_write_i2c(void *control_data, + const struct sigma_action *sa, size_t len) +{ + return i2c_master_send(control_data, (const unsigned char *)&sa->addr, + len); +} + +int process_sigma_firmware(struct i2c_client *client, const char *name) +{ + struct sigma_firmware ssfw; + + ssfw.control_data = client; + ssfw.write = sigma_action_write_i2c; + + return _process_sigma_firmware(&client->dev, &ssfw, name); +} +EXPORT_SYMBOL(process_sigma_firmware); + +MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); +MODULE_DESCRIPTION("SigmaDSP I2C firmware loader"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/sigmadsp-regmap.c b/sound/soc/codecs/sigmadsp-regmap.c new file mode 100644 index 000000000000..f78ed8d2cfb2 --- /dev/null +++ b/sound/soc/codecs/sigmadsp-regmap.c @@ -0,0 +1,36 @@ +/* + * Load Analog Devices SigmaStudio firmware files + * + * Copyright 2009-2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <linux/regmap.h> +#include <linux/export.h> +#include <linux/module.h> + +#include "sigmadsp.h" + +static int sigma_action_write_regmap(void *control_data, + const struct sigma_action *sa, size_t len) +{ + return regmap_raw_write(control_data, be16_to_cpu(sa->addr), + sa->payload, len - 2); +} + +int process_sigma_firmware_regmap(struct device *dev, struct regmap *regmap, + const char *name) +{ + struct sigma_firmware ssfw; + + ssfw.control_data = regmap; + ssfw.write = sigma_action_write_regmap; + + return _process_sigma_firmware(dev, &ssfw, name); +} +EXPORT_SYMBOL(process_sigma_firmware_regmap); + +MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); +MODULE_DESCRIPTION("SigmaDSP regmap firmware loader"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c index 4068f2491232..f2de7e049bc6 100644 --- a/sound/soc/codecs/sigmadsp.c +++ b/sound/soc/codecs/sigmadsp.c @@ -34,23 +34,6 @@ enum { SIGMA_ACTION_END, }; -struct sigma_action { - u8 instr; - u8 len_hi; - __le16 len; - __be16 addr; - unsigned char payload[]; -} __packed; - -struct sigma_firmware { - const struct firmware *fw; - size_t pos; - - void *control_data; - int (*write)(void *control_data, const struct sigma_action *sa, - size_t len); -}; - static inline u32 sigma_action_len(struct sigma_action *sa) { return (sa->len_hi << 16) | le16_to_cpu(sa->len); @@ -138,7 +121,7 @@ process_sigma_actions(struct sigma_firmware *ssfw) return 0; } -static int _process_sigma_firmware(struct device *dev, +int _process_sigma_firmware(struct device *dev, struct sigma_firmware *ssfw, const char *name) { int ret; @@ -197,50 +180,6 @@ static int _process_sigma_firmware(struct device *dev, return ret; } - -#if IS_ENABLED(CONFIG_I2C) - -static int sigma_action_write_i2c(void *control_data, - const struct sigma_action *sa, size_t len) -{ - return i2c_master_send(control_data, (const unsigned char *)&sa->addr, - len); -} - -int process_sigma_firmware(struct i2c_client *client, const char *name) -{ - struct sigma_firmware ssfw; - - ssfw.control_data = client; - ssfw.write = sigma_action_write_i2c; - - return _process_sigma_firmware(&client->dev, &ssfw, name); -} -EXPORT_SYMBOL(process_sigma_firmware); - -#endif - -#if IS_ENABLED(CONFIG_REGMAP) - -static int sigma_action_write_regmap(void *control_data, - const struct sigma_action *sa, size_t len) -{ - return regmap_raw_write(control_data, be16_to_cpu(sa->addr), - sa->payload, len - 2); -} - -int process_sigma_firmware_regmap(struct device *dev, struct regmap *regmap, - const char *name) -{ - struct sigma_firmware ssfw; - - ssfw.control_data = regmap; - ssfw.write = sigma_action_write_regmap; - - return _process_sigma_firmware(dev, &ssfw, name); -} -EXPORT_SYMBOL(process_sigma_firmware_regmap); - -#endif +EXPORT_SYMBOL_GPL(_process_sigma_firmware); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/sigmadsp.h b/sound/soc/codecs/sigmadsp.h index e439cbd7af7d..c47cd23e9827 100644 --- a/sound/soc/codecs/sigmadsp.h +++ b/sound/soc/codecs/sigmadsp.h @@ -12,6 +12,26 @@ #include <linux/device.h> #include <linux/regmap.h> +struct sigma_action { + u8 instr; + u8 len_hi; + __le16 len; + __be16 addr; + unsigned char payload[]; +} __packed; + +struct sigma_firmware { + const struct firmware *fw; + size_t pos; + + void *control_data; + int (*write)(void *control_data, const struct sigma_action *sa, + size_t len); +}; + +int _process_sigma_firmware(struct device *dev, + struct sigma_firmware *ssfw, const char *name); + struct i2c_client; extern int process_sigma_firmware(struct i2c_client *client, const char *name); diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index 23419109ecac..1cdae8ccc61b 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -1178,7 +1178,7 @@ static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx) } #endif /* CONFIG_OF */ -static void aic31xx_device_init(struct aic31xx_priv *aic31xx) +static int aic31xx_device_init(struct aic31xx_priv *aic31xx) { int ret, i; @@ -1197,7 +1197,7 @@ static void aic31xx_device_init(struct aic31xx_priv *aic31xx) "aic31xx-reset-pin"); if (ret < 0) { dev_err(aic31xx->dev, "not able to acquire gpio\n"); - return; + return ret; } } @@ -1210,6 +1210,7 @@ static void aic31xx_device_init(struct aic31xx_priv *aic31xx) if (ret != 0) dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret); + return ret; } static int aic31xx_i2c_probe(struct i2c_client *i2c, @@ -1239,7 +1240,9 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c, aic31xx->pdata.codec_type = id->driver_data; - aic31xx_device_init(aic31xx); + ret = aic31xx_device_init(aic31xx); + if (ret) + return ret; return snd_soc_register_codec(&i2c->dev, &soc_codec_driver_aic31xx, aic31xx_dai_driver, diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index e12fafbb1e09..5360772bc1ad 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -879,7 +879,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, case SNDRV_PCM_FORMAT_S20_3LE: data |= (0x01 << 4); break; - case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: data |= (0x02 << 4); break; case SNDRV_PCM_FORMAT_S32_LE: diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index df3a7506c023..ff006cc95520 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1404,7 +1404,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) if (dac33->irq >= 0) { ret = request_irq(dac33->irq, dac33_interrupt_handler, IRQF_TRIGGER_RISING, - codec->name, codec); + codec->component.name, codec); if (ret < 0) { dev_err(codec->dev, "Could not request IRQ%d (%d)\n", dac33->irq, ret); diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index edf27acc1d77..12fc0aed7503 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -479,7 +479,7 @@ static struct snd_soc_dai_driver uda134x_dai = { static int uda134x_soc_probe(struct snd_soc_codec *codec) { struct uda134x_priv *uda134x; - struct uda134x_platform_data *pd = codec->card->dev->platform_data; + struct uda134x_platform_data *pd = codec->component.card->dev->platform_data; const struct snd_soc_dapm_widget *widgets; unsigned num_widgets; diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 91a9ea2a2056..7bb0d36d4c54 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -735,8 +735,7 @@ WM5100_MIXER_CONTROLS("LHPF4", WM5100_HPLP4MIX_INPUT_1_SOURCE), static void wm5100_seq_notifier(struct snd_soc_dapm_context *dapm, enum snd_soc_dapm_type event, int subseq) { - struct snd_soc_codec *codec = container_of(dapm, - struct snd_soc_codec, dapm); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); u16 val, expect, i; diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 289b64d89abd..f60234962527 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -612,6 +612,62 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, return 0; } +static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct arizona *arizona = dev_get_drvdata(codec->dev->parent); + uint16_t data; + + mutex_lock(&codec->mutex); + data = cpu_to_be16(arizona->dac_comp_coeff); + memcpy(ucontrol->value.bytes.data, &data, sizeof(data)); + mutex_unlock(&codec->mutex); + + return 0; +} + +static int wm5102_out_comp_coeff_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct arizona *arizona = dev_get_drvdata(codec->dev->parent); + + mutex_lock(&codec->mutex); + memcpy(&arizona->dac_comp_coeff, ucontrol->value.bytes.data, + sizeof(arizona->dac_comp_coeff)); + arizona->dac_comp_coeff = be16_to_cpu(arizona->dac_comp_coeff); + mutex_unlock(&codec->mutex); + + return 0; +} + +static int wm5102_out_comp_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct arizona *arizona = dev_get_drvdata(codec->dev->parent); + + mutex_lock(&codec->mutex); + ucontrol->value.integer.value[0] = arizona->dac_comp_enabled; + mutex_unlock(&codec->mutex); + + return 0; +} + +static int wm5102_out_comp_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct arizona *arizona = dev_get_drvdata(codec->dev->parent); + + mutex_lock(&codec->mutex); + arizona->dac_comp_enabled = ucontrol->value.integer.value[0]; + mutex_unlock(&codec->mutex); + + return 0; +} + static const char *wm5102_osr_text[] = { "Low power", "Normal", "High performance", }; @@ -843,6 +899,12 @@ SOC_SINGLE_TLV("Noise Gate Threshold Volume", ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_THR_SHIFT, 7, 1, ng_tlv), SOC_ENUM("Noise Gate Hold", arizona_ng_hold), +SND_SOC_BYTES_EXT("Output Compensation Coefficient", 2, + wm5102_out_comp_coeff_get, wm5102_out_comp_coeff_put), + +SOC_SINGLE_EXT("Output Compensation Switch", 0, 0, 1, 0, + wm5102_out_comp_switch_get, wm5102_out_comp_switch_put), + WM5102_NG_SRC("HPOUT1L", ARIZONA_NOISE_GATE_SELECT_1L), WM5102_NG_SRC("HPOUT1R", ARIZONA_NOISE_GATE_SELECT_1R), WM5102_NG_SRC("HPOUT2L", ARIZONA_NOISE_GATE_SELECT_2L), @@ -1653,6 +1715,7 @@ static struct snd_soc_dai_driver wm5102_dai[] = { }, .ops = &arizona_dai_ops, .symmetric_rates = 1, + .symmetric_samplebits = 1, }, { .name = "wm5102-aif2", @@ -1674,6 +1737,7 @@ static struct snd_soc_dai_driver wm5102_dai[] = { }, .ops = &arizona_dai_ops, .symmetric_rates = 1, + .symmetric_samplebits = 1, }, { .name = "wm5102-aif3", @@ -1695,6 +1759,7 @@ static struct snd_soc_dai_driver wm5102_dai[] = { }, .ops = &arizona_dai_ops, .symmetric_rates = 1, + .symmetric_samplebits = 1, }, { .name = "wm5102-slim1", diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 2e5fcb559e90..2f2ec26d831c 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -1485,6 +1485,7 @@ static struct snd_soc_dai_driver wm5110_dai[] = { }, .ops = &arizona_dai_ops, .symmetric_rates = 1, + .symmetric_samplebits = 1, }, { .name = "wm5110-aif2", @@ -1506,6 +1507,7 @@ static struct snd_soc_dai_driver wm5110_dai[] = { }, .ops = &arizona_dai_ops, .symmetric_rates = 1, + .symmetric_samplebits = 1, }, { .name = "wm5110-aif3", @@ -1527,6 +1529,7 @@ static struct snd_soc_dai_driver wm5110_dai[] = { }, .ops = &arizona_dai_ops, .symmetric_rates = 1, + .symmetric_samplebits = 1, }, { .name = "wm5110-slim1", @@ -1596,6 +1599,7 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) arizona_init_spk(codec); arizona_init_gpio(codec); + arizona_init_mono(codec); ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 8); if (ret != 0) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index b84940c359a1..ec3250daa93e 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -281,8 +281,7 @@ static int wm8903_dcs_event(struct snd_soc_dapm_widget *w, static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm, enum snd_soc_dapm_type event, int subseq) { - struct snd_soc_codec *codec = container_of(dapm, - struct snd_soc_codec, dapm); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); int dcs_mode = WM8903_DCS_MODE_WRITE_STOP; int i, val; diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index a145d0431b63..e96349b04ba6 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -472,7 +472,7 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec) * list each time to find the desired power state do so now * and save the result. */ - list_for_each_entry(w, &codec->card->widgets, list) { + list_for_each_entry(w, &codec->component.card->widgets, list) { if (w->dapm != &codec->dapm) continue; if (strcmp(w->name, "LOUT1 PGA") == 0) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 247b39013fba..9719d3ca8e47 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3505,6 +3505,7 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) return IRQ_HANDLED; } +/* Should be called with accdet_lock held */ static void wm1811_micd_stop(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); @@ -3512,14 +3513,10 @@ static void wm1811_micd_stop(struct snd_soc_codec *codec) if (!wm8994->jackdet) return; - mutex_lock(&wm8994->accdet_lock); - snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK); - mutex_unlock(&wm8994->accdet_lock); - if (wm8994->wm8994->pdata.jd_ext_cap) snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); @@ -3560,10 +3557,10 @@ static void wm8958_open_circuit_work(struct work_struct *work) open_circuit_work.work); struct device *dev = wm8994->wm8994->dev; - wm1811_micd_stop(wm8994->hubs.codec); - mutex_lock(&wm8994->accdet_lock); + wm1811_micd_stop(wm8994->hubs.codec); + dev_dbg(dev, "Reporting open circuit\n"); wm8994->jack_mic = false; diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 69266332760e..9304a91b8403 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -690,8 +690,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask) static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm, enum snd_soc_dapm_type event, int subseq) { - struct snd_soc_codec *codec = container_of(dapm, - struct snd_soc_codec, dapm); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); u16 val, mask; diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index bb9b47b956aa..ab33fe596519 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -967,6 +967,7 @@ static struct snd_soc_dai_driver wm8997_dai[] = { }, .ops = &arizona_dai_ops, .symmetric_rates = 1, + .symmetric_samplebits = 1, }, { .name = "wm8997-aif2", @@ -988,6 +989,7 @@ static struct snd_soc_dai_driver wm8997_dai[] = { }, .ops = &arizona_dai_ops, .symmetric_rates = 1, + .symmetric_samplebits = 1, }, { .name = "wm8997-slim1", diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 060027182dcb..f412a9911a75 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -1382,7 +1382,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, int ret; int val; - dsp->card = codec->card; + dsp->card = codec->component.card; switch (event) { case SND_SOC_DAPM_POST_PMU: @@ -1617,7 +1617,7 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); struct wm_adsp *dsp = &dsps[w->shift]; - dsp->card = codec->card; + dsp->card = codec->component.card; switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -1758,3 +1758,5 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) return 0; } EXPORT_SYMBOL_GPL(wm_adsp2_init); + +MODULE_LICENSE("GPL v2"); |