diff options
author | Mark Brown <broonie@kernel.org> | 2020-09-17 17:35:38 +0200 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2020-09-17 17:35:38 +0200 |
commit | 4db68e62a0b912655c598de829b05b2383da0cab (patch) | |
tree | 14c717646e8de62283aaa9c08b747e8db3871dbd /sound/soc/codecs | |
parent | Merge series "ASoC: SOF: DSP core management fixes for 5.10" from Kai Vehmane... (diff) | |
parent | ASoC: tlv320adcx140: Fix BCLK inversion for DSP modes (diff) | |
download | linux-4db68e62a0b912655c598de829b05b2383da0cab.tar.xz linux-4db68e62a0b912655c598de829b05b2383da0cab.zip |
Merge branch 'asoc-5.9' into asoc-5.10
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r-- | sound/soc/codecs/max98373-sdw.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/pcm3168a.c | 7 | ||||
-rw-r--r-- | sound/soc/codecs/rt1015.c | 111 | ||||
-rw-r--r-- | sound/soc/codecs/rt1015.h | 8 | ||||
-rw-r--r-- | sound/soc/codecs/rt1308-sdw.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/rt700-sdw.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/rt711-sdw.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/rt715-sdw.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/tlv320adcx140.c | 117 | ||||
-rw-r--r-- | sound/soc/codecs/tlv320adcx140.h | 2 | ||||
-rw-r--r-- | sound/soc/codecs/wm8994.c | 10 | ||||
-rw-r--r-- | sound/soc/codecs/wm_hubs.c | 3 | ||||
-rw-r--r-- | sound/soc/codecs/wm_hubs.h | 1 |
13 files changed, 202 insertions, 77 deletions
diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c index 6469612c42cb..c1bd320633ad 100644 --- a/sound/soc/codecs/max98373-sdw.c +++ b/sound/soc/codecs/max98373-sdw.c @@ -841,8 +841,8 @@ static int max98373_sdw_probe(struct sdw_slave *slave, /* Regmap Initialization */ regmap = devm_regmap_init_sdw(slave, &max98373_sdw_regmap); - if (!regmap) - return -EINVAL; + if (IS_ERR(regmap)) + return PTR_ERR(regmap); return max98373_init(slave, regmap); } diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 5e445fee4ef5..821e7395f90f 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -306,6 +306,13 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai, struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component); int ret; + /* + * Some sound card sets 0 Hz as reset, + * but it is impossible to set. Ignore it here + */ + if (freq == 0) + return 0; + if (freq > PCM3168A_MAX_SYSCLK) return -EINVAL; diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index 548f68649064..25fe2ddedd54 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -484,6 +484,33 @@ static int rt1015_bypass_boost_get(struct snd_kcontrol *kcontrol, return 0; } +static void rt1015_calibrate(struct rt1015_priv *rt1015) +{ + struct snd_soc_component *component = rt1015->component; + struct regmap *regmap = rt1015->regmap; + + snd_soc_dapm_mutex_lock(&component->dapm); + regcache_cache_bypass(regmap, true); + + regmap_write(regmap, RT1015_PWR1, 0xd7df); + regmap_write(regmap, RT1015_PWR4, 0x00b2); + regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2008); + regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0140); + regmap_write(regmap, RT1015_GAT_BOOST, 0x0efe); + regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000d); + regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000e); + regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x5a00); + regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x5a01); + regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x5a05); + msleep(500); + regmap_write(regmap, RT1015_PWR1, 0x0); + + regcache_cache_bypass(regmap, false); + regcache_mark_dirty(regmap); + regcache_sync(regmap); + snd_soc_dapm_mutex_unlock(&component->dapm); +} + static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -494,20 +521,12 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol, if (!rt1015->dac_is_used) { rt1015->bypass_boost = ucontrol->value.integer.value[0]; - if (rt1015->bypass_boost == RT1015_Bypass_Boost) { - snd_soc_component_write(component, - RT1015_PWR4, 0x00b2); - snd_soc_component_write(component, - RT1015_CLSD_INTERNAL8, 0x2008); - snd_soc_component_write(component, - RT1015_CLSD_INTERNAL9, 0x0140); - snd_soc_component_write(component, - RT1015_GAT_BOOST, 0x0efe); - snd_soc_component_write(component, - RT1015_PWR_STATE_CTRL, 0x000d); - msleep(500); - snd_soc_component_write(component, - RT1015_PWR_STATE_CTRL, 0x000e); + if (rt1015->bypass_boost == RT1015_Bypass_Boost && + !rt1015->cali_done) { + rt1015_calibrate(rt1015); + rt1015->cali_done = 1; + + regmap_write(rt1015->regmap, RT1015_MONO_DYNA_CTRL, 0x0010); } } else dev_err(component->dev, "DAC is being used!\n"); @@ -515,6 +534,32 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol, return 0; } +static void rt1015_flush_work(struct work_struct *work) +{ + struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv, + flush_work.work); + struct snd_soc_component *component = rt1015->component; + unsigned int val, i = 0, count = 20; + + while (i < count) { + usleep_range(1000, 1500); + dev_dbg(component->dev, "Flush DAC (retry:%u)\n", i); + regmap_read(rt1015->regmap, RT1015_CLK_DET, &val); + if (val & 0x800) + break; + i++; + } + + regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x0597); + regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x05f7); + regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x0028); + + if (val & 0x800) + dev_dbg(component->dev, "Flush DAC completed.\n"); + else + dev_warn(component->dev, "Fail to flush DAC data.\n"); +} + static const struct snd_kcontrol_new rt1015_snd_controls[] = { SOC_SINGLE_TLV("DAC Playback Volume", RT1015_DAC1, RT1015_DAC_VOL_SFT, 127, 0, dac_vol_tlv), @@ -568,12 +613,7 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMU: - if (rt1015->bypass_boost == RT1015_Bypass_Boost) { - regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x00a8); - regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x0597); - regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x05f7); - regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x0028); - } + regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x00a8); break; case SND_SOC_DAPM_POST_PMD: @@ -589,6 +629,8 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w, RT1015_SYS_RST1, 0x05f5); } rt1015->dac_is_used = 0; + + cancel_delayed_work_sync(&rt1015->flush_work); break; default: @@ -597,6 +639,24 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w, return 0; } +static int rt1015_amp_drv_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (rt1015->hw_config == RT1015_HW_28) + schedule_delayed_work(&rt1015->flush_work, msecs_to_jiffies(10)); + break; + default: + break; + } + return 0; +} + static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("LDO2", RT1015_PWR1, RT1015_PWR_LDO2_BIT, 0, NULL, 0), @@ -630,6 +690,8 @@ static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = { r1015_dac_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_OUT_DRV_E("Amp Drv", SND_SOC_NOPM, 0, 0, NULL, 0, + rt1015_amp_drv_event, SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_OUTPUT("SPO"), }; @@ -648,7 +710,8 @@ static const struct snd_soc_dapm_route rt1015_dapm_routes[] = { { "DAC", NULL, "MIXERV" }, { "DAC", NULL, "SUMV" }, { "DAC", NULL, "VREFLV" }, - { "SPO", NULL, "DAC" }, + { "Amp Drv", NULL, "DAC" }, + { "SPO", NULL, "Amp Drv" }, }; static int rt1015_hw_params(struct snd_pcm_substream *substream, @@ -888,8 +951,11 @@ static int rt1015_probe(struct snd_soc_component *component) rt1015->component = component; rt1015->bclk_ratio = 0; + rt1015->cali_done = 0; snd_soc_component_write(component, RT1015_BAT_RPO_STEP1, 0x061c); + INIT_DELAYED_WORK(&rt1015->flush_work, rt1015_flush_work); + return 0; } @@ -897,6 +963,7 @@ static void rt1015_remove(struct snd_soc_component *component) { struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component); + cancel_delayed_work_sync(&rt1015->flush_work); regmap_write(rt1015->regmap, RT1015_RESET, 0); } @@ -1022,6 +1089,8 @@ static int rt1015_i2c_probe(struct i2c_client *i2c, return ret; } + rt1015->hw_config = (i2c->addr == 0x29) ? RT1015_HW_29 : RT1015_HW_28; + regmap_read(rt1015->regmap, RT1015_DEVICE_ID, &val); if ((val != RT1015_DEVICE_ID_VAL) && (val != RT1015_DEVICE_ID_VAL2)) { dev_err(&i2c->dev, diff --git a/sound/soc/codecs/rt1015.h b/sound/soc/codecs/rt1015.h index 7bd159e8f958..d3fdd30aca6d 100644 --- a/sound/soc/codecs/rt1015.h +++ b/sound/soc/codecs/rt1015.h @@ -373,6 +373,11 @@ enum { RT1015_Bypass_Boost, }; +enum { + RT1015_HW_28 = 0, + RT1015_HW_29, +}; + struct rt1015_priv { struct snd_soc_component *component; struct regmap *regmap; @@ -389,6 +394,9 @@ struct rt1015_priv { int bypass_boost; int amp_ver; int dac_is_used; + int cali_done; + int hw_config; + struct delayed_work flush_work; }; #endif /* __RT1015_H__ */ diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c index 6a2318e04bb7..b288e1a7d956 100644 --- a/sound/soc/codecs/rt1308-sdw.c +++ b/sound/soc/codecs/rt1308-sdw.c @@ -684,8 +684,8 @@ static int rt1308_sdw_probe(struct sdw_slave *slave, /* Regmap Initialization */ regmap = devm_regmap_init_sdw(slave, &rt1308_sdw_regmap); - if (!regmap) - return -EINVAL; + if (IS_ERR(regmap)) + return PTR_ERR(regmap); rt1308_sdw_init(&slave->dev, regmap, slave); diff --git a/sound/soc/codecs/rt700-sdw.c b/sound/soc/codecs/rt700-sdw.c index 5430941cb2da..ead4918bbf90 100644 --- a/sound/soc/codecs/rt700-sdw.c +++ b/sound/soc/codecs/rt700-sdw.c @@ -452,8 +452,8 @@ static int rt700_sdw_probe(struct sdw_slave *slave, /* Regmap Initialization */ sdw_regmap = devm_regmap_init_sdw(slave, &rt700_sdw_regmap); - if (!sdw_regmap) - return -EINVAL; + if (IS_ERR(sdw_regmap)) + return PTR_ERR(sdw_regmap); regmap = devm_regmap_init(&slave->dev, NULL, &slave->dev, &rt700_regmap); diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c index dff098ddde01..28d663673320 100644 --- a/sound/soc/codecs/rt711-sdw.c +++ b/sound/soc/codecs/rt711-sdw.c @@ -452,8 +452,8 @@ static int rt711_sdw_probe(struct sdw_slave *slave, /* Regmap Initialization */ sdw_regmap = devm_regmap_init_sdw(slave, &rt711_sdw_regmap); - if (!sdw_regmap) - return -EINVAL; + if (IS_ERR(sdw_regmap)) + return PTR_ERR(sdw_regmap); regmap = devm_regmap_init(&slave->dev, NULL, &slave->dev, &rt711_regmap); diff --git a/sound/soc/codecs/rt715-sdw.c b/sound/soc/codecs/rt715-sdw.c index 00e441560f00..dbb8895150a6 100644 --- a/sound/soc/codecs/rt715-sdw.c +++ b/sound/soc/codecs/rt715-sdw.c @@ -527,8 +527,8 @@ static int rt715_sdw_probe(struct sdw_slave *slave, /* Regmap Initialization */ sdw_regmap = devm_regmap_init_sdw(slave, &rt715_sdw_regmap); - if (!sdw_regmap) - return -EINVAL; + if (IS_ERR(sdw_regmap)) + return PTR_ERR(sdw_regmap); regmap = devm_regmap_init(&slave->dev, NULL, &slave->dev, &rt715_regmap); diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 5d1b2a03f0ac..cf5cbe314f7e 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -30,7 +30,7 @@ struct adcx140_priv { struct regmap *regmap; struct device *dev; - int micbias_vg; + bool micbias_vg; unsigned int dai_fmt; unsigned int tdm_delay; @@ -161,7 +161,7 @@ static const struct regmap_config adcx140_i2c_regmap = { }; /* Digital Volume control. From -100 to 27 dB in 0.5 dB steps */ -static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10000, 50, 0); +static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10050, 50, 0); /* ADC gain. From 0 to 42 dB in 1 dB steps */ static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0); @@ -651,11 +651,26 @@ static int adcx140_reset(struct adcx140_priv *adcx140) return ret; } +static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state) +{ + int pwr_ctrl = 0; + + if (power_state) + pwr_ctrl = ADCX140_PWR_CFG_ADC_PDZ | ADCX140_PWR_CFG_PLL_PDZ; + + if (adcx140->micbias_vg && power_state) + pwr_ctrl |= ADCX140_PWR_CFG_BIAS_PDZ; + + regmap_update_bits(adcx140->regmap, ADCX140_PWR_CFG, + ADCX140_PWR_CTRL_MSK, pwr_ctrl); +} + static int adcx140_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; + struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); u8 data = 0; switch (params_width(params)) { @@ -677,9 +692,13 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } + adcx140_pwr_ctrl(adcx140, false); + snd_soc_component_update_bits(component, ADCX140_ASI_CFG0, ADCX140_WORD_LEN_MSK, data); + adcx140_pwr_ctrl(adcx140, true); + return 0; } @@ -691,7 +710,7 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, u8 iface_reg1 = 0; u8 iface_reg2 = 0; int offset = 0; - int width = adcx140->slot_width; + bool inverted_bclk = false; /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -707,24 +726,6 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; } - /* signal polarity */ - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_IF: - iface_reg1 |= ADCX140_FSYNCINV_BIT; - break; - case SND_SOC_DAIFMT_IB_IF: - iface_reg1 |= ADCX140_BCLKINV_BIT | ADCX140_FSYNCINV_BIT; - break; - case SND_SOC_DAIFMT_IB_NF: - iface_reg1 |= ADCX140_BCLKINV_BIT; - break; - case SND_SOC_DAIFMT_NB_NF: - break; - default: - dev_err(component->dev, "Invalid DAI clock signal polarity\n"); - return -EINVAL; - } - /* interface format */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: @@ -734,18 +735,40 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, iface_reg1 |= ADCX140_LEFT_JUST_BIT; break; case SND_SOC_DAIFMT_DSP_A: - offset += (adcx140->tdm_delay * width + 1); + offset = 1; + inverted_bclk = true; break; case SND_SOC_DAIFMT_DSP_B: - offset += adcx140->tdm_delay * width; + inverted_bclk = true; break; default: dev_err(component->dev, "Invalid DAI interface format\n"); return -EINVAL; } + /* signal polarity */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_IB_NF: + case SND_SOC_DAIFMT_IB_IF: + inverted_bclk = !inverted_bclk; + break; + case SND_SOC_DAIFMT_NB_IF: + iface_reg1 |= ADCX140_FSYNCINV_BIT; + break; + case SND_SOC_DAIFMT_NB_NF: + break; + default: + dev_err(component->dev, "Invalid DAI clock signal polarity\n"); + return -EINVAL; + } + + if (inverted_bclk) + iface_reg1 |= ADCX140_BCLKINV_BIT; + adcx140->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; + adcx140_pwr_ctrl(adcx140, false); + snd_soc_component_update_bits(component, ADCX140_ASI_CFG0, ADCX140_FSYNCINV_BIT | ADCX140_BCLKINV_BIT | @@ -758,6 +781,7 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, snd_soc_component_update_bits(component, ADCX140_ASI_CFG1, ADCX140_TX_OFFSET_MASK, offset); + adcx140_pwr_ctrl(adcx140, true); return 0; } @@ -855,12 +879,11 @@ static int adcx140_codec_probe(struct snd_soc_component *component) ret = device_property_read_u32(adcx140->dev, "ti,mic-bias-source", &bias_source); - if (ret) + if (ret || bias_source > ADCX140_MIC_BIAS_VAL_AVDD) { bias_source = ADCX140_MIC_BIAS_VAL_VREF; - - if (bias_source > ADCX140_MIC_BIAS_VAL_AVDD) { - dev_err(adcx140->dev, "Mic Bias source value is invalid\n"); - return -EINVAL; + adcx140->micbias_vg = false; + } else { + adcx140->micbias_vg = true; } ret = device_property_read_u32(adcx140->dev, "ti,vref-source", @@ -879,6 +902,18 @@ static int adcx140_codec_probe(struct snd_soc_component *component) if (ret) goto out; + if (adcx140->supply_areg == NULL) + sleep_cfg_val |= ADCX140_AREG_INTERNAL; + + ret = regmap_write(adcx140->regmap, ADCX140_SLEEP_CFG, sleep_cfg_val); + if (ret) { + dev_err(adcx140->dev, "setting sleep config failed %d\n", ret); + goto out; + } + + /* 8.4.3: Wait >= 1ms after entering active mode. */ + usleep_range(1000, 100000); + pdm_count = device_property_count_u32(adcx140->dev, "ti,pdm-edge-select"); if (pdm_count <= ADCX140_NUM_PDM_EDGES && pdm_count > 0) { @@ -926,23 +961,13 @@ static int adcx140_codec_probe(struct snd_soc_component *component) if (ret) goto out; - if (adcx140->supply_areg == NULL) - sleep_cfg_val |= ADCX140_AREG_INTERNAL; - - ret = regmap_write(adcx140->regmap, ADCX140_SLEEP_CFG, sleep_cfg_val); - if (ret) { - dev_err(adcx140->dev, "setting sleep config failed %d\n", ret); - goto out; - } - - /* 8.4.3: Wait >= 1ms after entering active mode. */ - usleep_range(1000, 100000); - ret = regmap_update_bits(adcx140->regmap, ADCX140_BIAS_CFG, ADCX140_MIC_BIAS_VAL_MSK | ADCX140_MIC_BIAS_VREF_MSK, bias_cfg); if (ret) dev_err(adcx140->dev, "setting MIC bias failed %d\n", ret); + + adcx140_pwr_ctrl(adcx140, true); out: return ret; } @@ -951,21 +976,19 @@ static int adcx140_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); - int pwr_cfg = 0; switch (level) { case SND_SOC_BIAS_ON: case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_STANDBY: - pwr_cfg = ADCX140_PWR_CFG_BIAS_PDZ | ADCX140_PWR_CFG_PLL_PDZ | - ADCX140_PWR_CFG_ADC_PDZ; + adcx140_pwr_ctrl(adcx140, true); break; case SND_SOC_BIAS_OFF: - pwr_cfg = 0x0; + adcx140_pwr_ctrl(adcx140, false); break; } - return regmap_write(adcx140->regmap, ADCX140_PWR_CFG, pwr_cfg); + return 0; } static const struct snd_soc_component_driver soc_codec_driver_adcx140 = { @@ -1017,6 +1040,8 @@ static int adcx140_i2c_probe(struct i2c_client *i2c, if (!adcx140) return -ENOMEM; + adcx140->dev = &i2c->dev; + adcx140->gpio_reset = devm_gpiod_get_optional(adcx140->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(adcx140->gpio_reset)) @@ -1044,7 +1069,7 @@ static int adcx140_i2c_probe(struct i2c_client *i2c, ret); return ret; } - adcx140->dev = &i2c->dev; + i2c_set_clientdata(i2c, adcx140); return devm_snd_soc_register_component(&i2c->dev, diff --git a/sound/soc/codecs/tlv320adcx140.h b/sound/soc/codecs/tlv320adcx140.h index eedbc1d7221f..94c6d1fd2977 100644 --- a/sound/soc/codecs/tlv320adcx140.h +++ b/sound/soc/codecs/tlv320adcx140.h @@ -123,6 +123,7 @@ #define ADCX140_MIC_BIAS_VREF_1375V 2 #define ADCX140_MIC_BIAS_VREF_MSK GENMASK(1, 0) +#define ADCX140_PWR_CTRL_MSK GENMASK(7, 5) #define ADCX140_PWR_CFG_BIAS_PDZ BIT(7) #define ADCX140_PWR_CFG_ADC_PDZ BIT(6) #define ADCX140_PWR_CFG_PLL_PDZ BIT(5) @@ -145,4 +146,5 @@ #define ADCX140_GPO_CFG_MAX 4 #define ADCX140_GPO_DRV_MAX 5 + #endif /* _TLV320ADCX140_ */ diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 038be667c1a6..fc9ea198ac79 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3514,6 +3514,8 @@ int wm8994_mic_detect(struct snd_soc_component *component, struct snd_soc_jack * return -EINVAL; } + pm_runtime_get_sync(component->dev); + switch (micbias) { case 1: micdet = &wm8994->micdet[0]; @@ -3561,6 +3563,8 @@ int wm8994_mic_detect(struct snd_soc_component *component, struct snd_soc_jack * snd_soc_dapm_sync(dapm); + pm_runtime_put(component->dev); + return 0; } EXPORT_SYMBOL_GPL(wm8994_mic_detect); @@ -3932,6 +3936,8 @@ int wm8958_mic_detect(struct snd_soc_component *component, struct snd_soc_jack * return -EINVAL; } + pm_runtime_get_sync(component->dev); + if (jack) { snd_soc_dapm_force_enable_pin(dapm, "CLK_SYS"); snd_soc_dapm_sync(dapm); @@ -4000,6 +4006,8 @@ int wm8958_mic_detect(struct snd_soc_component *component, struct snd_soc_jack * snd_soc_dapm_sync(dapm); } + pm_runtime_put(component->dev); + return 0; } EXPORT_SYMBOL_GPL(wm8958_mic_detect); @@ -4193,11 +4201,13 @@ static int wm8994_component_probe(struct snd_soc_component *component) wm8994->hubs.dcs_readback_mode = 2; break; } + wm8994->hubs.micd_scthr = true; break; case WM8958: wm8994->hubs.dcs_readback_mode = 1; wm8994->hubs.hp_startup_mode = 1; + wm8994->hubs.micd_scthr = true; switch (control->revision) { case 0: diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 891effe220fe..0c881846f485 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -1223,6 +1223,9 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_component *component, snd_soc_component_update_bits(component, WM8993_ADDITIONAL_CONTROL, WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB); + if (!hubs->micd_scthr) + return 0; + snd_soc_component_update_bits(component, WM8993_MICBIAS, WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK | WM8993_MICB1_LVL | WM8993_MICB2_LVL, diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h index 4b8e5f0d6e32..988b29e63060 100644 --- a/sound/soc/codecs/wm_hubs.h +++ b/sound/soc/codecs/wm_hubs.h @@ -27,6 +27,7 @@ struct wm_hubs_data { int hp_startup_mode; int series_startup; int no_series_update; + bool micd_scthr; bool no_cache_dac_hp_direct; struct list_head dcs_cache; |