Commit 064841cc authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'asoc/for-5.9' into asoc-linus

parents bbf5c979 ebb11d1d
...@@ -4175,6 +4175,7 @@ CIRRUS LOGIC AUDIO CODEC DRIVERS ...@@ -4175,6 +4175,7 @@ CIRRUS LOGIC AUDIO CODEC DRIVERS
M: James Schulman <james.schulman@cirrus.com> M: James Schulman <james.schulman@cirrus.com>
M: David Rhodes <david.rhodes@cirrus.com> M: David Rhodes <david.rhodes@cirrus.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers) L: alsa-devel@alsa-project.org (moderated for non-subscribers)
L: patches@opensource.cirrus.com
S: Maintained S: Maintained
F: sound/soc/codecs/cs* F: sound/soc/codecs/cs*
......
...@@ -1089,6 +1089,7 @@ static const struct snd_soc_dapm_route cs47l15_dapm_routes[] = { ...@@ -1089,6 +1089,7 @@ static const struct snd_soc_dapm_route cs47l15_dapm_routes[] = {
{ "HPOUT1 Demux", NULL, "OUT1R" }, { "HPOUT1 Demux", NULL, "OUT1R" },
{ "OUT1R", NULL, "HPOUT1 Mono Mux" }, { "OUT1R", NULL, "HPOUT1 Mono Mux" },
{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
{ "HPOUTL", "HPOUT", "HPOUT1 Demux" }, { "HPOUTL", "HPOUT", "HPOUT1 Demux" },
{ "HPOUTR", "HPOUT", "HPOUT1 Demux" }, { "HPOUTR", "HPOUT", "HPOUT1 Demux" },
...@@ -1268,7 +1269,6 @@ static irqreturn_t cs47l15_adsp2_irq(int irq, void *data) ...@@ -1268,7 +1269,6 @@ static irqreturn_t cs47l15_adsp2_irq(int irq, void *data)
static const struct snd_soc_dapm_route cs47l15_mono_routes[] = { static const struct snd_soc_dapm_route cs47l15_mono_routes[] = {
{ "HPOUT1 Mono Mux", "HPOUT", "OUT1L" }, { "HPOUT1 Mono Mux", "HPOUT", "OUT1L" },
{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
}; };
static int cs47l15_component_probe(struct snd_soc_component *component) static int cs47l15_component_probe(struct snd_soc_component *component)
......
...@@ -1305,6 +1305,7 @@ static const struct snd_soc_dapm_route cs47l35_dapm_routes[] = { ...@@ -1305,6 +1305,7 @@ static const struct snd_soc_dapm_route cs47l35_dapm_routes[] = {
{ "SPKOUTP", NULL, "OUT4L" }, { "SPKOUTP", NULL, "OUT4L" },
{ "OUT1R", NULL, "HPOUT1 Mono Mux" }, { "OUT1R", NULL, "HPOUT1 Mono Mux" },
{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
{ "HPOUTL", "HPOUT", "HPOUT1 Demux" }, { "HPOUTL", "HPOUT", "HPOUT1 Demux" },
{ "HPOUTR", "HPOUT", "HPOUT1 Demux" }, { "HPOUTR", "HPOUT", "HPOUT1 Demux" },
...@@ -1550,7 +1551,6 @@ static irqreturn_t cs47l35_adsp2_irq(int irq, void *data) ...@@ -1550,7 +1551,6 @@ static irqreturn_t cs47l35_adsp2_irq(int irq, void *data)
static const struct snd_soc_dapm_route cs47l35_mono_routes[] = { static const struct snd_soc_dapm_route cs47l35_mono_routes[] = {
{ "HPOUT1 Mono Mux", "HPOUT", "OUT1L" }, { "HPOUT1 Mono Mux", "HPOUT", "OUT1L" },
{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
}; };
static int cs47l35_component_probe(struct snd_soc_component *component) static int cs47l35_component_probe(struct snd_soc_component *component)
......
...@@ -484,6 +484,33 @@ static int rt1015_bypass_boost_get(struct snd_kcontrol *kcontrol, ...@@ -484,6 +484,33 @@ static int rt1015_bypass_boost_get(struct snd_kcontrol *kcontrol,
return 0; 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, static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
...@@ -494,20 +521,12 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol, ...@@ -494,20 +521,12 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,
if (!rt1015->dac_is_used) { if (!rt1015->dac_is_used) {
rt1015->bypass_boost = ucontrol->value.integer.value[0]; rt1015->bypass_boost = ucontrol->value.integer.value[0];
if (rt1015->bypass_boost == RT1015_Bypass_Boost) { if (rt1015->bypass_boost == RT1015_Bypass_Boost &&
snd_soc_component_write(component, !rt1015->cali_done) {
RT1015_PWR4, 0x00b2); rt1015_calibrate(rt1015);
snd_soc_component_write(component, rt1015->cali_done = 1;
RT1015_CLSD_INTERNAL8, 0x2008);
snd_soc_component_write(component, regmap_write(rt1015->regmap, RT1015_MONO_DYNA_CTRL, 0x0010);
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);
} }
} else } else
dev_err(component->dev, "DAC is being used!\n"); dev_err(component->dev, "DAC is being used!\n");
...@@ -515,6 +534,32 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol, ...@@ -515,6 +534,32 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,
return 0; 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[] = { static const struct snd_kcontrol_new rt1015_snd_controls[] = {
SOC_SINGLE_TLV("DAC Playback Volume", RT1015_DAC1, RT1015_DAC_VOL_SFT, SOC_SINGLE_TLV("DAC Playback Volume", RT1015_DAC1, RT1015_DAC_VOL_SFT,
127, 0, dac_vol_tlv), 127, 0, dac_vol_tlv),
...@@ -568,12 +613,7 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w, ...@@ -568,12 +613,7 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
break; break;
case SND_SOC_DAPM_POST_PMU: 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_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);
}
break; break;
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
...@@ -589,6 +629,8 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w, ...@@ -589,6 +629,8 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
RT1015_SYS_RST1, 0x05f5); RT1015_SYS_RST1, 0x05f5);
} }
rt1015->dac_is_used = 0; rt1015->dac_is_used = 0;
cancel_delayed_work_sync(&rt1015->flush_work);
break; break;
default: default:
...@@ -597,6 +639,24 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w, ...@@ -597,6 +639,24 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
return 0; 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[] = { static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("LDO2", RT1015_PWR1, RT1015_PWR_LDO2_BIT, 0, SND_SOC_DAPM_SUPPLY("LDO2", RT1015_PWR1, RT1015_PWR_LDO2_BIT, 0,
NULL, 0), NULL, 0),
...@@ -630,6 +690,8 @@ static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = { ...@@ -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 | r1015_dac_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_POST_PMD), 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"), SND_SOC_DAPM_OUTPUT("SPO"),
}; };
...@@ -648,7 +710,8 @@ static const struct snd_soc_dapm_route rt1015_dapm_routes[] = { ...@@ -648,7 +710,8 @@ static const struct snd_soc_dapm_route rt1015_dapm_routes[] = {
{ "DAC", NULL, "MIXERV" }, { "DAC", NULL, "MIXERV" },
{ "DAC", NULL, "SUMV" }, { "DAC", NULL, "SUMV" },
{ "DAC", NULL, "VREFLV" }, { "DAC", NULL, "VREFLV" },
{ "SPO", NULL, "DAC" }, { "Amp Drv", NULL, "DAC" },
{ "SPO", NULL, "Amp Drv" },
}; };
static int rt1015_hw_params(struct snd_pcm_substream *substream, static int rt1015_hw_params(struct snd_pcm_substream *substream,
...@@ -888,8 +951,11 @@ static int rt1015_probe(struct snd_soc_component *component) ...@@ -888,8 +951,11 @@ static int rt1015_probe(struct snd_soc_component *component)
rt1015->component = component; rt1015->component = component;
rt1015->bclk_ratio = 0; rt1015->bclk_ratio = 0;
rt1015->cali_done = 0;
snd_soc_component_write(component, RT1015_BAT_RPO_STEP1, 0x061c); snd_soc_component_write(component, RT1015_BAT_RPO_STEP1, 0x061c);
INIT_DELAYED_WORK(&rt1015->flush_work, rt1015_flush_work);
return 0; return 0;
} }
...@@ -897,6 +963,7 @@ static void rt1015_remove(struct snd_soc_component *component) ...@@ -897,6 +963,7 @@ static void rt1015_remove(struct snd_soc_component *component)
{ {
struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(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); regmap_write(rt1015->regmap, RT1015_RESET, 0);
} }
...@@ -1022,6 +1089,8 @@ static int rt1015_i2c_probe(struct i2c_client *i2c, ...@@ -1022,6 +1089,8 @@ static int rt1015_i2c_probe(struct i2c_client *i2c,
return ret; return ret;
} }
rt1015->hw_config = (i2c->addr == 0x29) ? RT1015_HW_29 : RT1015_HW_28;
regmap_read(rt1015->regmap, RT1015_DEVICE_ID, &val); regmap_read(rt1015->regmap, RT1015_DEVICE_ID, &val);
if ((val != RT1015_DEVICE_ID_VAL) && (val != RT1015_DEVICE_ID_VAL2)) { if ((val != RT1015_DEVICE_ID_VAL) && (val != RT1015_DEVICE_ID_VAL2)) {
dev_err(&i2c->dev, dev_err(&i2c->dev,
......
...@@ -373,6 +373,11 @@ enum { ...@@ -373,6 +373,11 @@ enum {
RT1015_Bypass_Boost, RT1015_Bypass_Boost,
}; };
enum {
RT1015_HW_28 = 0,
RT1015_HW_29,
};
struct rt1015_priv { struct rt1015_priv {
struct snd_soc_component *component; struct snd_soc_component *component;
struct regmap *regmap; struct regmap *regmap;
...@@ -389,6 +394,9 @@ struct rt1015_priv { ...@@ -389,6 +394,9 @@ struct rt1015_priv {
int bypass_boost; int bypass_boost;
int amp_ver; int amp_ver;
int dac_is_used; int dac_is_used;
int cali_done;
int hw_config;
struct delayed_work flush_work;
}; };
#endif /* __RT1015_H__ */ #endif /* __RT1015_H__ */
...@@ -490,6 +490,9 @@ static int __maybe_unused rt700_dev_suspend(struct device *dev) ...@@ -490,6 +490,9 @@ static int __maybe_unused rt700_dev_suspend(struct device *dev)
if (!rt700->hw_init) if (!rt700->hw_init)
return 0; return 0;
cancel_delayed_work_sync(&rt700->jack_detect_work);
cancel_delayed_work_sync(&rt700->jack_btn_check_work);
regcache_cache_only(rt700->regmap, true); regcache_cache_only(rt700->regmap, true);
return 0; return 0;
......
...@@ -491,6 +491,10 @@ static int __maybe_unused rt711_dev_suspend(struct device *dev) ...@@ -491,6 +491,10 @@ static int __maybe_unused rt711_dev_suspend(struct device *dev)
if (!rt711->hw_init) if (!rt711->hw_init)
return 0; return 0;
cancel_delayed_work_sync(&rt711->jack_detect_work);
cancel_delayed_work_sync(&rt711->jack_btn_check_work);
cancel_work_sync(&rt711->calibration_work);
regcache_cache_only(rt711->regmap, true); regcache_cache_only(rt711->regmap, true);
return 0; return 0;
......
...@@ -57,7 +57,12 @@ static int tas2770_set_bias_level(struct snd_soc_component *component, ...@@ -57,7 +57,12 @@ static int tas2770_set_bias_level(struct snd_soc_component *component,
TAS2770_PWR_CTRL_MASK, TAS2770_PWR_CTRL_MASK,
TAS2770_PWR_CTRL_ACTIVE); TAS2770_PWR_CTRL_ACTIVE);
break; break;
case SND_SOC_BIAS_STANDBY:
case SND_SOC_BIAS_PREPARE:
snd_soc_component_update_bits(component,
TAS2770_PWR_CTRL,
TAS2770_PWR_CTRL_MASK, TAS2770_PWR_CTRL_MUTE);
break;
case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF:
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
TAS2770_PWR_CTRL, TAS2770_PWR_CTRL,
...@@ -135,23 +140,18 @@ static int tas2770_dac_event(struct snd_soc_dapm_widget *w, ...@@ -135,23 +140,18 @@ static int tas2770_dac_event(struct snd_soc_dapm_widget *w,
TAS2770_PWR_CTRL, TAS2770_PWR_CTRL,
TAS2770_PWR_CTRL_MASK, TAS2770_PWR_CTRL_MASK,
TAS2770_PWR_CTRL_MUTE); TAS2770_PWR_CTRL_MUTE);
if (ret)
goto end;
break; break;
case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_PRE_PMD:
ret = snd_soc_component_update_bits(component, ret = snd_soc_component_update_bits(component,
TAS2770_PWR_CTRL, TAS2770_PWR_CTRL,
TAS2770_PWR_CTRL_MASK, TAS2770_PWR_CTRL_MASK,
TAS2770_PWR_CTRL_SHUTDOWN); TAS2770_PWR_CTRL_SHUTDOWN);
if (ret)
goto end;
break; break;
default: default:
dev_err(tas2770->dev, "Not supported evevt\n"); dev_err(tas2770->dev, "Not supported evevt\n");
return -EINVAL; return -EINVAL;
} }
end:
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -243,6 +243,9 @@ static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth) ...@@ -243,6 +243,9 @@ static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth)
return -EINVAL; return -EINVAL;
} }
if (ret < 0)
return ret;
tas2770->channel_size = bitwidth; tas2770->channel_size = bitwidth;
ret = snd_soc_component_update_bits(component, ret = snd_soc_component_update_bits(component,
...@@ -251,16 +254,15 @@ static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth) ...@@ -251,16 +254,15 @@ static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth)
TAS2770_TDM_CFG_REG5_50_MASK, TAS2770_TDM_CFG_REG5_50_MASK,
TAS2770_TDM_CFG_REG5_VSNS_ENABLE | TAS2770_TDM_CFG_REG5_VSNS_ENABLE |
tas2770->v_sense_slot); tas2770->v_sense_slot);
if (ret) if (ret < 0)
goto end; return ret;
ret = snd_soc_component_update_bits(component, ret = snd_soc_component_update_bits(component,
TAS2770_TDM_CFG_REG6, TAS2770_TDM_CFG_REG6,
TAS2770_TDM_CFG_REG6_ISNS_MASK | TAS2770_TDM_CFG_REG6_ISNS_MASK |
TAS2770_TDM_CFG_REG6_50_MASK, TAS2770_TDM_CFG_REG6_50_MASK,
TAS2770_TDM_CFG_REG6_ISNS_ENABLE | TAS2770_TDM_CFG_REG6_ISNS_ENABLE |
tas2770->i_sense_slot); tas2770->i_sense_slot);
end:
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -278,36 +280,35 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate) ...@@ -278,36 +280,35 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
TAS2770_TDM_CFG_REG0, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_SMP_MASK, TAS2770_TDM_CFG_REG0_SMP_MASK,
TAS2770_TDM_CFG_REG0_SMP_48KHZ); TAS2770_TDM_CFG_REG0_SMP_48KHZ);
if (ret) if (ret < 0)
goto end; return ret;
ret = snd_soc_component_update_bits(component, ret = snd_soc_component_update_bits(component,
TAS2770_TDM_CFG_REG0, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_31_MASK, TAS2770_TDM_CFG_REG0_31_MASK,
TAS2770_TDM_CFG_REG0_31_44_1_48KHZ); TAS2770_TDM_CFG_REG0_31_44_1_48KHZ);
if (ret)
goto end;
break; break;
case 44100: case 44100:
ret = snd_soc_component_update_bits(component, ret = snd_soc_component_update_bits(component,
TAS2770_TDM_CFG_REG0, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_SMP_MASK, TAS2770_TDM_CFG_REG0_SMP_MASK,
TAS2770_TDM_CFG_REG0_SMP_44_1KHZ); TAS2770_TDM_CFG_REG0_SMP_44_1KHZ);
if (ret) if (ret < 0)
goto end; return ret;
ret = snd_soc_component_update_bits(component, ret = snd_soc_component_update_bits(component,
TAS2770_TDM_CFG_REG0, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_31_MASK, TAS2770_TDM_CFG_REG0_31_MASK,
TAS2770_TDM_CFG_REG0_31_44_1_48KHZ); TAS2770_TDM_CFG_REG0_31_44_1_48KHZ);
if (ret)
goto end;
break; break;
case 96000: case 96000:
ret = snd_soc_component_update_bits(component, ret = snd_soc_component_update_bits(component,
TAS2770_TDM_CFG_REG0, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_SMP_MASK, TAS2770_TDM_CFG_REG0_SMP_MASK,
TAS2770_TDM_CFG_REG0_SMP_48KHZ); TAS2770_TDM_CFG_REG0_SMP_48KHZ);
if (ret) if (ret < 0)
goto end; return ret;
ret = snd_soc_component_update_bits(component, ret = snd_soc_component_update_bits(component,
TAS2770_TDM_CFG_REG0, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_31_MASK, TAS2770_TDM_CFG_REG0_31_MASK,
...@@ -318,8 +319,9 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate) ...@@ -318,8 +319,9 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
TAS2770_TDM_CFG_REG0, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_SMP_MASK, TAS2770_TDM_CFG_REG0_SMP_MASK,
TAS2770_TDM_CFG_REG0_SMP_44_1KHZ); TAS2770_TDM_CFG_REG0_SMP_44_1KHZ);
if (ret) if (ret < 0)
goto end; return ret;
ret = snd_soc_component_update_bits(component, ret = snd_soc_component_update_bits(component,
TAS2770_TDM_CFG_REG0, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_31_MASK, TAS2770_TDM_CFG_REG0_31_MASK,
...@@ -330,22 +332,22 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate) ...@@ -330,22 +332,22 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
TAS2770_TDM_CFG_REG0, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_SMP_MASK, TAS2770_TDM_CFG_REG0_SMP_MASK,
TAS2770_TDM_CFG_REG0_SMP_48KHZ); TAS2770_TDM_CFG_REG0_SMP_48KHZ);
if (ret) if (ret < 0)
goto end; return ret;
ret = snd_soc_component_update_bits(component, ret = snd_soc_component_update_bits(component,
TAS2770_TDM_CFG_REG0, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_31_MASK, TAS2770_TDM_CFG_REG0_31_MASK,
TAS2770_TDM_CFG_REG0_31_176_4_192KHZ); TAS2770_TDM_CFG_REG0_31_176_4_192KHZ);
if (ret)
goto end;
break; break;
case 17640: case 17640:
ret = snd_soc_component_update_bits(component, ret = snd_soc_component_update_bits(component,
TAS2770_TDM_CFG_REG0, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_SMP_MASK, TAS2770_TDM_CFG_REG0_SMP_MASK,
TAS2770_TDM_CFG_REG0_SMP_44_1KHZ); TAS2770_TDM_CFG_REG0_SMP_44_1KHZ);
if (ret) if (ret < 0)
goto end; return ret;
ret = snd_soc_component_update_bits(component, ret = snd_soc_component_update_bits(component,
TAS2770_TDM_CFG_REG0, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_31_MASK, TAS2770_TDM_CFG_REG0_31_MASK,
...@@ -355,7 +357,6 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate) ...@@ -355,7 +357,6 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
ret = -EINVAL; ret = -EINVAL;
} }
end:
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -575,6 +576,8 @@ static int tas2770_codec_probe(struct snd_soc_component *component) ...@@ -575,6 +576,8 @@ static int tas2770_codec_probe(struct snd_soc_component *component)
tas2770->component = component; tas2770->component = component;
tas2770_reset(tas2770);
return 0; return 0;
} }
...@@ -701,29 +704,28 @@ static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *tas2770) ...@@ -701,29 +704,28 @@ static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *tas2770)
rc = fwnode_property_read_u32(dev->fwnode, "ti,asi-format", rc = fwnode_property_read_u32(dev->fwnode, "ti,asi-format",
&tas2770->asi_format); &tas2770->asi_format);
if (rc) { if (rc) {
dev_err(tas2770->dev, "Looking up %s property failed %d\n", dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
"ti,asi-format", rc); "ti,asi-format");
goto end; tas2770->asi_format = 0;
} }
rc = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no", rc = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no",
&tas2770->i_sense_slot); &tas2770->i_sense_slot);
if (rc) { if (rc) {
dev_err(tas2770->dev, "Looking up %s property failed %d\n", dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
"ti,imon-slot-no", rc); "ti,imon-slot-no");
goto end; tas2770->i_sense_slot = 0;
} }
rc = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no", rc = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no",
&tas2770->v_sense_slot); &tas2770->v_sense_slot);
if (rc) { if (rc) {
dev_err(tas2770->dev, "Looking up %s property failed %d\n", dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
"ti,vmon-slot-no", rc); "ti,vmon-slot-no");
goto end; tas2770->v_sense_slot = 2;
} }
end: return 0;
return rc;
} }
static int tas2770_i2c_probe(struct i2c_client *client, static int tas2770_i2c_probe(struct i2c_client *client,
...@@ -771,8 +773,6 @@ static int tas2770_i2c_probe(struct i2c_client *client, ...@@ -771,8 +773,6 @@ static int tas2770_i2c_probe(struct i2c_client *client,
tas2770->channel_size = 0; tas2770->channel_size = 0;
tas2770->slot_width = 0; tas2770->slot_width = 0;
tas2770_reset(tas2770);
result = tas2770_register_codec(tas2770); result = tas2770_register_codec(tas2770);
if (result) if (result)
dev_err(tas2770->dev, "Register codec failed.\n"); dev_err(tas2770->dev, "Register codec failed.\n");
......
...@@ -30,7 +30,7 @@ struct adcx140_priv { ...@@ -30,7 +30,7 @@ struct adcx140_priv {
struct regmap *regmap; struct regmap *regmap;
struct device *dev; struct device *dev;
int micbias_vg; bool micbias_vg;
unsigned int dai_fmt; unsigned int dai_fmt;
unsigned int tdm_delay; unsigned int tdm_delay;
...@@ -161,7 +161,7 @@ static const struct regmap_config adcx140_i2c_regmap = { ...@@ -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 */ /* 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 */ /* ADC gain. From 0 to 42 dB in 1 dB steps */
static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0); static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0);
...@@ -614,11 +614,26 @@ static int adcx140_reset(struct adcx140_priv *adcx140) ...@@ -614,11 +614,26 @@ static int adcx140_reset(struct adcx140_priv *adcx140)
return ret; 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, static int adcx140_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component);
u8 data = 0; u8 data = 0;
switch (params_width(params)) { switch (params_width(params)) {
...@@ -640,9 +655,13 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream, ...@@ -640,9 +655,13 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream,
return -EINVAL; return -EINVAL;
} }
adcx140_pwr_ctrl(adcx140, false);
snd_soc_component_update_bits(component, ADCX140_ASI_CFG0, snd_soc_component_update_bits(component, ADCX140_ASI_CFG0,
ADCX140_WORD_LEN_MSK, data); ADCX140_WORD_LEN_MSK, data);
adcx140_pwr_ctrl(adcx140, true);
return 0; return 0;
} }
...@@ -654,7 +673,7 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, ...@@ -654,7 +673,7 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai,
u8 iface_reg1 = 0; u8 iface_reg1 = 0;
u8 iface_reg2 = 0; u8 iface_reg2 = 0;
int offset = 0; int offset = 0;
int width = adcx140->slot_width; bool inverted_bclk = false;
/* set master/slave audio interface */ /* set master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
...@@ -670,24 +689,6 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, ...@@ -670,24 +689,6 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL; 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 */ /* interface format */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S: case SND_SOC_DAIFMT_I2S:
...@@ -697,18 +698,40 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, ...@@ -697,18 +698,40 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai,
iface_reg1 |= ADCX140_LEFT_JUST_BIT; iface_reg1 |= ADCX140_LEFT_JUST_BIT;
break; break;
case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_A:
offset += (adcx140->tdm_delay * width + 1); offset = 1;
inverted_bclk = true;
break; break;
case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_DSP_B:
offset += adcx140->tdm_delay * width; inverted_bclk = true;
break; break;
default: default:
dev_err(component->dev, "Invalid DAI interface format\n"); dev_err(component->dev, "Invalid DAI interface format\n");
return -EINVAL; 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->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
adcx140_pwr_ctrl(adcx140, false);
snd_soc_component_update_bits(component, ADCX140_ASI_CFG0, snd_soc_component_update_bits(component, ADCX140_ASI_CFG0,
ADCX140_FSYNCINV_BIT | ADCX140_FSYNCINV_BIT |
ADCX140_BCLKINV_BIT | ADCX140_BCLKINV_BIT |
...@@ -721,6 +744,7 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, ...@@ -721,6 +744,7 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai,
snd_soc_component_update_bits(component, ADCX140_ASI_CFG1, snd_soc_component_update_bits(component, ADCX140_ASI_CFG1,
ADCX140_TX_OFFSET_MASK, offset); ADCX140_TX_OFFSET_MASK, offset);
adcx140_pwr_ctrl(adcx140, true);
return 0; return 0;
} }
...@@ -818,12 +842,11 @@ static int adcx140_codec_probe(struct snd_soc_component *component) ...@@ -818,12 +842,11 @@ static int adcx140_codec_probe(struct snd_soc_component *component)
ret = device_property_read_u32(adcx140->dev, "ti,mic-bias-source", ret = device_property_read_u32(adcx140->dev, "ti,mic-bias-source",
&bias_source); &bias_source);
if (ret) if (ret || bias_source > ADCX140_MIC_BIAS_VAL_AVDD) {
bias_source = ADCX140_MIC_BIAS_VAL_VREF; bias_source = ADCX140_MIC_BIAS_VAL_VREF;
adcx140->micbias_vg = false;
if (bias_source > ADCX140_MIC_BIAS_VAL_AVDD) { } else {
dev_err(adcx140->dev, "Mic Bias source value is invalid\n"); adcx140->micbias_vg = true;
return -EINVAL;
} }
ret = device_property_read_u32(adcx140->dev, "ti,vref-source", ret = device_property_read_u32(adcx140->dev, "ti,vref-source",
...@@ -906,6 +929,8 @@ static int adcx140_codec_probe(struct snd_soc_component *component) ...@@ -906,6 +929,8 @@ static int adcx140_codec_probe(struct snd_soc_component *component)
ADCX140_MIC_BIAS_VREF_MSK, bias_cfg); ADCX140_MIC_BIAS_VREF_MSK, bias_cfg);
if (ret) if (ret)
dev_err(adcx140->dev, "setting MIC bias failed %d\n", ret); dev_err(adcx140->dev, "setting MIC bias failed %d\n", ret);
adcx140_pwr_ctrl(adcx140, true);
out: out:
return ret; return ret;
} }
...@@ -914,21 +939,19 @@ static int adcx140_set_bias_level(struct snd_soc_component *component, ...@@ -914,21 +939,19 @@ static int adcx140_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level) enum snd_soc_bias_level level)
{ {
struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component);
int pwr_cfg = 0;
switch (level) { switch (level) {
case SND_SOC_BIAS_ON: case SND_SOC_BIAS_ON:
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
pwr_cfg = ADCX140_PWR_CFG_BIAS_PDZ | ADCX140_PWR_CFG_PLL_PDZ | adcx140_pwr_ctrl(adcx140, true);
ADCX140_PWR_CFG_ADC_PDZ;
break; break;
case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF:
pwr_cfg = 0x0; adcx140_pwr_ctrl(adcx140, false);
break; break;
} }
return regmap_write(adcx140->regmap, ADCX140_PWR_CFG, pwr_cfg); return 0;
} }
static const struct snd_soc_component_driver soc_codec_driver_adcx140 = { static const struct snd_soc_component_driver soc_codec_driver_adcx140 = {
......
...@@ -123,6 +123,7 @@ ...@@ -123,6 +123,7 @@
#define ADCX140_MIC_BIAS_VREF_1375V 2 #define ADCX140_MIC_BIAS_VREF_1375V 2
#define ADCX140_MIC_BIAS_VREF_MSK GENMASK(1, 0) #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_BIAS_PDZ BIT(7)
#define ADCX140_PWR_CFG_ADC_PDZ BIT(6) #define ADCX140_PWR_CFG_ADC_PDZ BIT(6)
#define ADCX140_PWR_CFG_PLL_PDZ BIT(5) #define ADCX140_PWR_CFG_PLL_PDZ BIT(5)
...@@ -145,4 +146,5 @@ ...@@ -145,4 +146,5 @@
#define ADCX140_GPO_CFG_MAX 4 #define ADCX140_GPO_CFG_MAX 4
#define ADCX140_GPO_DRV_MAX 5 #define ADCX140_GPO_DRV_MAX 5
#endif /* _TLV320ADCX140_ */ #endif /* _TLV320ADCX140_ */
...@@ -230,7 +230,14 @@ static int clk_aic32x4_pll_set_rate(struct clk_hw *hw, ...@@ -230,7 +230,14 @@ static int clk_aic32x4_pll_set_rate(struct clk_hw *hw,
if (ret < 0) if (ret < 0)
return -EINVAL; return -EINVAL;
return clk_aic32x4_pll_set_muldiv(pll, &settings); ret = clk_aic32x4_pll_set_muldiv(pll, &settings);
if (ret)
return ret;
/* 10ms is the delay to wait before the clocks are stable */
msleep(10);
return 0;
} }
static int clk_aic32x4_pll_set_parent(struct clk_hw *hw, u8 index) static int clk_aic32x4_pll_set_parent(struct clk_hw *hw, u8 index)
......
...@@ -665,7 +665,7 @@ static int aic32x4_set_processing_blocks(struct snd_soc_component *component, ...@@ -665,7 +665,7 @@ static int aic32x4_set_processing_blocks(struct snd_soc_component *component,
} }
static int aic32x4_setup_clocks(struct snd_soc_component *component, static int aic32x4_setup_clocks(struct snd_soc_component *component,
unsigned int sample_rate) unsigned int sample_rate, unsigned int channels)
{ {
u8 aosr; u8 aosr;
u16 dosr; u16 dosr;
...@@ -753,7 +753,9 @@ static int aic32x4_setup_clocks(struct snd_soc_component *component, ...@@ -753,7 +753,9 @@ static int aic32x4_setup_clocks(struct snd_soc_component *component,
dosr); dosr);
clk_set_rate(clocks[5].clk, clk_set_rate(clocks[5].clk,
sample_rate * 32); sample_rate * 32 *
channels);
return 0; return 0;
} }
} }
...@@ -775,7 +777,8 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream, ...@@ -775,7 +777,8 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
u8 iface1_reg = 0; u8 iface1_reg = 0;
u8 dacsetup_reg = 0; u8 dacsetup_reg = 0;
aic32x4_setup_clocks(component, params_rate(params)); aic32x4_setup_clocks(component, params_rate(params),
params_channels(params));
switch (params_width(params)) { switch (params_width(params)) {
case 16: case 16:
...@@ -1010,6 +1013,14 @@ static int aic32x4_component_probe(struct snd_soc_component *component) ...@@ -1010,6 +1013,14 @@ static int aic32x4_component_probe(struct snd_soc_component *component)
AIC32X4_LADC_EN | AIC32X4_RADC_EN); AIC32X4_LADC_EN | AIC32X4_RADC_EN);
snd_soc_component_write(component, AIC32X4_ADCSETUP, tmp_reg); snd_soc_component_write(component, AIC32X4_ADCSETUP, tmp_reg);
/*
* Enable the fast charging feature and ensure the needed 40ms ellapsed
* before using the analog circuits.
*/
snd_soc_component_write(component, AIC32X4_REFPOWERUP,
AIC32X4_REFPOWERUP_40MS);
msleep(40);
return 0; return 0;
} }
......
...@@ -96,6 +96,7 @@ int aic32x4_register_clocks(struct device *dev, const char *mclk_name); ...@@ -96,6 +96,7 @@ int aic32x4_register_clocks(struct device *dev, const char *mclk_name);
#define AIC32X4_FLOATINGINPUT AIC32X4_REG(1, 58) #define AIC32X4_FLOATINGINPUT AIC32X4_REG(1, 58)
#define AIC32X4_LMICPGAVOL AIC32X4_REG(1, 59) #define AIC32X4_LMICPGAVOL AIC32X4_REG(1, 59)
#define AIC32X4_RMICPGAVOL AIC32X4_REG(1, 60) #define AIC32X4_RMICPGAVOL AIC32X4_REG(1, 60)
#define AIC32X4_REFPOWERUP AIC32X4_REG(1, 123)
/* Bits, masks, and shifts */ /* Bits, masks, and shifts */
...@@ -205,6 +206,12 @@ int aic32x4_register_clocks(struct device *dev, const char *mclk_name); ...@@ -205,6 +206,12 @@ int aic32x4_register_clocks(struct device *dev, const char *mclk_name);
#define AIC32X4_RMICPGANIN_IN1L_10K 0x10 #define AIC32X4_RMICPGANIN_IN1L_10K 0x10
#define AIC32X4_RMICPGANIN_CM1R_10K 0x40 #define AIC32X4_RMICPGANIN_CM1R_10K 0x40
/* AIC32X4_REFPOWERUP */
#define AIC32X4_REFPOWERUP_SLOW 0x04
#define AIC32X4_REFPOWERUP_40MS 0x05
#define AIC32X4_REFPOWERUP_80MS 0x06
#define AIC32X4_REFPOWERUP_120MS 0x07
/* Common mask and enable for all of the dividers */ /* Common mask and enable for all of the dividers */
#define AIC32X4_DIVEN BIT(7) #define AIC32X4_DIVEN BIT(7)
#define AIC32X4_DIV_MASK GENMASK(6, 0) #define AIC32X4_DIV_MASK GENMASK(6, 0)
......
...@@ -2049,6 +2049,7 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, ...@@ -2049,6 +2049,7 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type,
{ {
struct wm_coeff_ctl *ctl; struct wm_coeff_ctl *ctl;
struct snd_kcontrol *kcontrol; struct snd_kcontrol *kcontrol;
char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
int ret; int ret;
ctl = wm_adsp_get_ctl(dsp, name, type, alg); ctl = wm_adsp_get_ctl(dsp, name, type, alg);
...@@ -2059,8 +2060,25 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, ...@@ -2059,8 +2060,25 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type,
return -EINVAL; return -EINVAL;
ret = wm_coeff_write_ctrl(ctl, buf, len); ret = wm_coeff_write_ctrl(ctl, buf, len);
if (ret)
return ret;
if (ctl->flags & WMFW_CTL_FLAG_SYS)
return 0;
if (dsp->component->name_prefix)
snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s",
dsp->component->name_prefix, ctl->name);
else
snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s",
ctl->name);
kcontrol = snd_soc_card_get_kcontrol(dsp->component->card, ctl_name);
if (!kcontrol) {
adsp_err(dsp, "Can't find kcontrol %s\n", ctl_name);
return -EINVAL;
}
kcontrol = snd_soc_card_get_kcontrol(dsp->component->card, ctl->name);
snd_ctl_notify(dsp->component->card->snd_card, snd_ctl_notify(dsp->component->card->snd_card,
SNDRV_CTL_EVENT_MASK_VALUE, &kcontrol->id); SNDRV_CTL_EVENT_MASK_VALUE, &kcontrol->id);
......
...@@ -199,10 +199,18 @@ static int fsl_audmix_put_out_src(struct snd_kcontrol *kcontrol, ...@@ -199,10 +199,18 @@ static int fsl_audmix_put_out_src(struct snd_kcontrol *kcontrol,
static const struct snd_kcontrol_new fsl_audmix_snd_controls[] = { static const struct snd_kcontrol_new fsl_audmix_snd_controls[] = {
/* FSL_AUDMIX_CTR controls */ /* FSL_AUDMIX_CTR controls */
SOC_ENUM_EXT("Mixing Clock Source", fsl_audmix_enum[0], { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
snd_soc_get_enum_double, fsl_audmix_put_mix_clk_src), .name = "Mixing Clock Source",
SOC_ENUM_EXT("Output Source", fsl_audmix_enum[1], .info = snd_soc_info_enum_double,
snd_soc_get_enum_double, fsl_audmix_put_out_src), .access = SNDRV_CTL_ELEM_ACCESS_WRITE,
.put = fsl_audmix_put_mix_clk_src,
.private_value = (unsigned long)&fsl_audmix_enum[0] },
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Output Source",
.info = snd_soc_info_enum_double,
.access = SNDRV_CTL_ELEM_ACCESS_WRITE,
.put = fsl_audmix_put_out_src,
.private_value = (unsigned long)&fsl_audmix_enum[1] },
SOC_ENUM("Output Width", fsl_audmix_enum[2]), SOC_ENUM("Output Width", fsl_audmix_enum[2]),
SOC_ENUM("Frame Rate Diff Error", fsl_audmix_enum[3]), SOC_ENUM("Frame Rate Diff Error", fsl_audmix_enum[3]),
SOC_ENUM("Clock Freq Diff Error", fsl_audmix_enum[4]), SOC_ENUM("Clock Freq Diff Error", fsl_audmix_enum[4]),
......
...@@ -694,7 +694,7 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) ...@@ -694,7 +694,7 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
return 0; return 0;
} }
static struct snd_soc_dai_driver fsl_sai_dai = { static struct snd_soc_dai_driver fsl_sai_dai_template = {
.probe = fsl_sai_dai_probe, .probe = fsl_sai_dai_probe,
.playback = { .playback = {
.stream_name = "CPU-Playback", .stream_name = "CPU-Playback",
...@@ -966,12 +966,15 @@ static int fsl_sai_probe(struct platform_device *pdev) ...@@ -966,12 +966,15 @@ static int fsl_sai_probe(struct platform_device *pdev)
return ret; return ret;
} }
memcpy(&sai->cpu_dai_drv, &fsl_sai_dai_template,
sizeof(fsl_sai_dai_template));
/* Sync Tx with Rx as default by following old DT binding */ /* Sync Tx with Rx as default by following old DT binding */
sai->synchronous[RX] = true; sai->synchronous[RX] = true;
sai->synchronous[TX] = false; sai->synchronous[TX] = false;
fsl_sai_dai.symmetric_rates = 1; sai->cpu_dai_drv.symmetric_rates = 1;
fsl_sai_dai.symmetric_channels = 1; sai->cpu_dai_drv.symmetric_channels = 1;
fsl_sai_dai.symmetric_samplebits = 1; sai->cpu_dai_drv.symmetric_samplebits = 1;
if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) && if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) &&
of_find_property(np, "fsl,sai-asynchronous", NULL)) { of_find_property(np, "fsl,sai-asynchronous", NULL)) {
...@@ -988,9 +991,9 @@ static int fsl_sai_probe(struct platform_device *pdev) ...@@ -988,9 +991,9 @@ static int fsl_sai_probe(struct platform_device *pdev)
/* Discard all settings for asynchronous mode */ /* Discard all settings for asynchronous mode */
sai->synchronous[RX] = false; sai->synchronous[RX] = false;
sai->synchronous[TX] = false; sai->synchronous[TX] = false;
fsl_sai_dai.symmetric_rates = 0; sai->cpu_dai_drv.symmetric_rates = 0;
fsl_sai_dai.symmetric_channels = 0; sai->cpu_dai_drv.symmetric_channels = 0;
fsl_sai_dai.symmetric_samplebits = 0; sai->cpu_dai_drv.symmetric_samplebits = 0;
} }
if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
...@@ -1020,7 +1023,7 @@ static int fsl_sai_probe(struct platform_device *pdev) ...@@ -1020,7 +1023,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
regcache_cache_only(sai->regmap, true); regcache_cache_only(sai->regmap, true);
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
&fsl_sai_dai, 1); &sai->cpu_dai_drv, 1);
if (ret) if (ret)
goto err_pm_disable; goto err_pm_disable;
......
...@@ -180,6 +180,7 @@ struct fsl_sai { ...@@ -180,6 +180,7 @@ struct fsl_sai {
unsigned int bclk_ratio; unsigned int bclk_ratio;
const struct fsl_sai_soc_data *soc_data; const struct fsl_sai_soc_data *soc_data;
struct snd_soc_dai_driver cpu_dai_drv;
struct snd_dmaengine_dai_dma_data dma_params_rx; struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_tx;
}; };
......
...@@ -673,7 +673,7 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev) ...@@ -673,7 +673,7 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
if (card == &mt8183_da7219_max98357_card) { if (card == &mt8183_da7219_max98357_card) {
dai_link->be_hw_params_fixup = dai_link->be_hw_params_fixup =
mt8183_i2s_hw_params_fixup; mt8183_i2s_hw_params_fixup;
dai_link->ops = &mt8183_mt6358_i2s_ops; dai_link->ops = &mt8183_da7219_i2s_ops;
dai_link->cpus = i2s3_max98357a_cpus; dai_link->cpus = i2s3_max98357a_cpus;
dai_link->num_cpus = dai_link->num_cpus =
ARRAY_SIZE(i2s3_max98357a_cpus); ARRAY_SIZE(i2s3_max98357a_cpus);
......
...@@ -592,6 +592,17 @@ static int soc_tplg_kcontrol_bind_io(struct snd_soc_tplg_ctl_hdr *hdr, ...@@ -592,6 +592,17 @@ static int soc_tplg_kcontrol_bind_io(struct snd_soc_tplg_ctl_hdr *hdr,
k->info = snd_soc_bytes_info_ext; k->info = snd_soc_bytes_info_ext;
k->tlv.c = snd_soc_bytes_tlv_callback; k->tlv.c = snd_soc_bytes_tlv_callback;
/*
* When a topology-based implementation abuses the
* control interface and uses bytes_ext controls of
* more than 512 bytes, we need to disable the size
* checks, otherwise accesses to such controls will
* return an -EINVAL error and prevent the card from
* being configured.
*/
if (IS_ENABLED(CONFIG_SND_CTL_VALIDATION) && sbe->max > 512)
k->access |= SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK;
ext_ops = tplg->bytes_ext_ops; ext_ops = tplg->bytes_ext_ops;
num_ops = tplg->bytes_ext_ops_count; num_ops = tplg->bytes_ext_ops_count;
for (i = 0; i < num_ops; i++) { for (i = 0; i < num_ops; i++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment