forked from luck/tmp_suning_uos_patched
Merge branch 'asoc-5.9' into asoc-5.10
This commit is contained in:
commit
4db68e62a0
|
@ -1193,6 +1193,8 @@ struct snd_soc_pcm_runtime {
|
|||
((i) < (rtd)->num_cpus + (rtd)->num_codecs) && \
|
||||
((dai) = (rtd)->dais[i]); \
|
||||
(i)++)
|
||||
#define for_each_rtd_dais_rollback(rtd, i, dai) \
|
||||
for (; (--(i) >= 0) && ((dai) = (rtd)->dais[i]);)
|
||||
|
||||
void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
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,
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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[] = {
|
||||
/* FSL_AUDMIX_CTR controls */
|
||||
SOC_ENUM_EXT("Mixing Clock Source", fsl_audmix_enum[0],
|
||||
snd_soc_get_enum_double, fsl_audmix_put_mix_clk_src),
|
||||
SOC_ENUM_EXT("Output Source", fsl_audmix_enum[1],
|
||||
snd_soc_get_enum_double, fsl_audmix_put_out_src),
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Mixing Clock Source",
|
||||
.info = snd_soc_info_enum_double,
|
||||
.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("Frame Rate Diff Error", fsl_audmix_enum[3]),
|
||||
SOC_ENUM("Clock Freq Diff Error", fsl_audmix_enum[4]),
|
||||
|
|
|
@ -333,6 +333,17 @@ static int sst_media_open(struct snd_pcm_substream *substream,
|
|||
if (ret_val < 0)
|
||||
goto out_power_up;
|
||||
|
||||
/*
|
||||
* Make sure the period to be multiple of 1ms to align the
|
||||
* design of firmware. Apply same rule to buffer size to make
|
||||
* sure alsa could always find a value for period size
|
||||
* regardless the buffer size given by user space.
|
||||
*/
|
||||
snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 48);
|
||||
snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 48);
|
||||
|
||||
/* Make sure, that the period size is always even */
|
||||
snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_PERIODS, 2);
|
||||
|
|
|
@ -591,6 +591,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
|
|||
BYT_RT5640_SSP0_AIF1 |
|
||||
BYT_RT5640_MCLK_EN),
|
||||
},
|
||||
{ /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "MPMAN"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Converter9"),
|
||||
},
|
||||
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
|
||||
BYT_RT5640_MONO_SPEAKER |
|
||||
BYT_RT5640_SSP0_AIF1 |
|
||||
BYT_RT5640_MCLK_EN),
|
||||
},
|
||||
{
|
||||
/* MPMAN MPWIN895CL */
|
||||
.matches = {
|
||||
|
|
|
@ -181,7 +181,7 @@ static void skl_set_hda_codec_autosuspend_delay(struct snd_soc_card *card)
|
|||
struct snd_soc_dai *dai;
|
||||
|
||||
for_each_card_rtds(card, rtd) {
|
||||
if (!strstr(rtd->dai_link->codecs->name, "ehdaudio"))
|
||||
if (!strstr(rtd->dai_link->codecs->name, "ehdaudio0D0"))
|
||||
continue;
|
||||
dai = asoc_rtd_to_codec(rtd, 0);
|
||||
hda_pvt = snd_soc_component_get_drvdata(dai->component);
|
||||
|
|
|
@ -243,92 +243,45 @@ static irqreturn_t hsw_irq(int irq, void *context)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define CSR_DEFAULT_VALUE 0x8480040E
|
||||
#define ISC_DEFAULT_VALUE 0x0
|
||||
#define ISD_DEFAULT_VALUE 0x0
|
||||
#define IMC_DEFAULT_VALUE 0x7FFF0003
|
||||
#define IMD_DEFAULT_VALUE 0x7FFF0003
|
||||
#define IPCC_DEFAULT_VALUE 0x0
|
||||
#define IPCD_DEFAULT_VALUE 0x0
|
||||
#define CLKCTL_DEFAULT_VALUE 0x7FF
|
||||
#define CSR2_DEFAULT_VALUE 0x0
|
||||
#define LTR_CTRL_DEFAULT_VALUE 0x0
|
||||
#define HMD_CTRL_DEFAULT_VALUE 0x0
|
||||
|
||||
static void hsw_set_shim_defaults(struct sst_dsp *sst)
|
||||
{
|
||||
sst_dsp_shim_write_unlocked(sst, SST_CSR, CSR_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_ISRX, ISC_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_ISRD, ISD_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_IMRX, IMC_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_IMRD, IMD_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_IPCX, IPCC_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_IPCD, IPCD_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_CLKCTL, CLKCTL_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_CSR2, CSR2_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_LTRC, LTR_CTRL_DEFAULT_VALUE);
|
||||
sst_dsp_shim_write_unlocked(sst, SST_HMDC, HMD_CTRL_DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
/* all clock-gating minus DCLCGE and DTCGE */
|
||||
#define SST_VDRTCL2_CG_OTHER 0xB7D
|
||||
|
||||
static void hsw_set_dsp_D3(struct sst_dsp *sst)
|
||||
{
|
||||
u32 val;
|
||||
u32 reg;
|
||||
|
||||
/* disable clock core gating */
|
||||
/* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg &= ~(SST_VDRTCL2_DCLCGE);
|
||||
reg &= ~(SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE);
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* stall, reset and set 24MHz XOSC */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CSR,
|
||||
SST_CSR_24MHZ_LPCS | SST_CSR_STALL | SST_CSR_RST,
|
||||
SST_CSR_24MHZ_LPCS | SST_CSR_STALL | SST_CSR_RST);
|
||||
/* enable power gating and switch off DRAM & IRAM blocks */
|
||||
val = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
val |= SST_VDRTCL0_DSRAMPGE_MASK |
|
||||
SST_VDRTCL0_ISRAMPGE_MASK;
|
||||
val &= ~(SST_VDRTCL0_D3PGD | SST_VDRTCL0_D3SRAMPGD);
|
||||
writel(val, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
|
||||
/* DRAM power gating all */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
reg |= SST_VDRTCL0_ISRAMPGE_MASK |
|
||||
SST_VDRTCL0_DSRAMPGE_MASK;
|
||||
reg &= ~(SST_VDRTCL0_D3SRAMPGD);
|
||||
reg |= SST_VDRTCL0_D3PGD;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
udelay(50);
|
||||
/* switch off audio PLL */
|
||||
val = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
val |= SST_VDRTCL2_APLLSE_MASK;
|
||||
writel(val, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* PLL shutdown enable */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg |= SST_VDRTCL2_APLLSE_MASK;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* disable MCLK */
|
||||
/* disable MCLK(clkctl.smos = 0) */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CLKCTL,
|
||||
SST_CLKCTL_MASK, 0);
|
||||
|
||||
/* switch clock gating */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg |= SST_VDRTCL2_CG_OTHER;
|
||||
reg &= ~(SST_VDRTCL2_DTCGE);
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
/* enable DTCGE separatelly */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg |= SST_VDRTCL2_DTCGE;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* set shim defaults */
|
||||
hsw_set_shim_defaults(sst);
|
||||
|
||||
/* set D3 */
|
||||
reg = readl(sst->addr.pci_cfg + SST_PMCS);
|
||||
reg |= SST_PMCS_PS_MASK;
|
||||
writel(reg, sst->addr.pci_cfg + SST_PMCS);
|
||||
/* Set D3 state, delay 50 us */
|
||||
val = readl(sst->addr.pci_cfg + SST_PMCS);
|
||||
val |= SST_PMCS_PS_MASK;
|
||||
writel(val, sst->addr.pci_cfg + SST_PMCS);
|
||||
udelay(50);
|
||||
|
||||
/* enable clock core gating */
|
||||
/* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg |= SST_VDRTCL2_DCLCGE;
|
||||
reg |= SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
udelay(50);
|
||||
|
||||
}
|
||||
|
||||
static void hsw_reset(struct sst_dsp *sst)
|
||||
|
@ -346,62 +299,75 @@ static void hsw_reset(struct sst_dsp *sst)
|
|||
SST_CSR_RST | SST_CSR_STALL, SST_CSR_STALL);
|
||||
}
|
||||
|
||||
/* recommended CSR state for power-up */
|
||||
#define SST_CSR_D0_MASK (0x18A09C0C | SST_CSR_DCS_MASK)
|
||||
|
||||
static int hsw_set_dsp_D0(struct sst_dsp *sst)
|
||||
{
|
||||
u32 reg;
|
||||
int tries = 10;
|
||||
u32 reg, fw_dump_bit;
|
||||
|
||||
/* disable clock core gating */
|
||||
/* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg &= ~(SST_VDRTCL2_DCLCGE);
|
||||
reg &= ~(SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE);
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* switch clock gating */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg |= SST_VDRTCL2_CG_OTHER;
|
||||
reg &= ~(SST_VDRTCL2_DTCGE);
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* set D0 */
|
||||
reg = readl(sst->addr.pci_cfg + SST_PMCS);
|
||||
reg &= ~(SST_PMCS_PS_MASK);
|
||||
writel(reg, sst->addr.pci_cfg + SST_PMCS);
|
||||
|
||||
/* DRAM power gating none */
|
||||
/* Disable D3PG (VDRTCTL0.D3PGD = 1) */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
reg &= ~(SST_VDRTCL0_ISRAMPGE_MASK |
|
||||
SST_VDRTCL0_DSRAMPGE_MASK);
|
||||
reg |= SST_VDRTCL0_D3SRAMPGD;
|
||||
reg |= SST_VDRTCL0_D3PGD;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
mdelay(10);
|
||||
|
||||
/* set shim defaults */
|
||||
hsw_set_shim_defaults(sst);
|
||||
/* Set D0 state */
|
||||
reg = readl(sst->addr.pci_cfg + SST_PMCS);
|
||||
reg &= ~SST_PMCS_PS_MASK;
|
||||
writel(reg, sst->addr.pci_cfg + SST_PMCS);
|
||||
|
||||
/* restore MCLK */
|
||||
/* check that ADSP shim is enabled */
|
||||
while (tries--) {
|
||||
reg = readl(sst->addr.pci_cfg + SST_PMCS) & SST_PMCS_PS_MASK;
|
||||
if (reg == 0)
|
||||
goto finish;
|
||||
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
|
||||
finish:
|
||||
/* select SSP1 19.2MHz base clock, SSP clock 0, turn off Low Power Clock */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CSR,
|
||||
SST_CSR_S1IOCS | SST_CSR_SBCS1 | SST_CSR_LPCS, 0x0);
|
||||
|
||||
/* stall DSP core, set clk to 192/96Mhz */
|
||||
sst_dsp_shim_update_bits_unlocked(sst,
|
||||
SST_CSR, SST_CSR_STALL | SST_CSR_DCS_MASK,
|
||||
SST_CSR_STALL | SST_CSR_DCS(4));
|
||||
|
||||
/* Set 24MHz MCLK, prevent local clock gating, enable SSP0 clock */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CLKCTL,
|
||||
SST_CLKCTL_MASK, SST_CLKCTL_MASK);
|
||||
SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0,
|
||||
SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0);
|
||||
|
||||
/* PLL shutdown disable */
|
||||
/* Stall and reset core, set CSR */
|
||||
hsw_reset(sst);
|
||||
|
||||
/* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg &= ~(SST_VDRTCL2_APLLSE_MASK);
|
||||
reg |= SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CSR,
|
||||
SST_CSR_D0_MASK, SST_CSR_SBCS0 | SST_CSR_SBCS1 |
|
||||
SST_CSR_STALL | SST_CSR_DCS(4));
|
||||
udelay(50);
|
||||
|
||||
/* enable clock core gating */
|
||||
/* switch on audio PLL */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
reg |= SST_VDRTCL2_DCLCGE;
|
||||
reg &= ~SST_VDRTCL2_APLLSE_MASK;
|
||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
|
||||
/* clear reset */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, SST_CSR_RST, 0);
|
||||
/* set default power gating control, enable power gating control for all blocks. that is,
|
||||
can't be accessed, please enable each block before accessing. */
|
||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK;
|
||||
/* for D0, always enable the block(DSRAM[0]) used for FW dump */
|
||||
fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT;
|
||||
writel(reg & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
|
||||
|
||||
/* disable DMA finish function for SSP0 & SSP1 */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_CSR2, SST_CSR2_SDFD_SSP1,
|
||||
|
@ -418,6 +384,12 @@ static int hsw_set_dsp_D0(struct sst_dsp *sst)
|
|||
sst_dsp_shim_update_bits(sst, SST_IMRD, (SST_IMRD_DONE | SST_IMRD_BUSY |
|
||||
SST_IMRD_SSP0 | SST_IMRD_DMAC), 0x0);
|
||||
|
||||
/* clear IPC registers */
|
||||
sst_dsp_shim_write(sst, SST_IPCX, 0x0);
|
||||
sst_dsp_shim_write(sst, SST_IPCD, 0x0);
|
||||
sst_dsp_shim_write(sst, 0x80, 0x6);
|
||||
sst_dsp_shim_write(sst, 0xe0, 0x300a);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -443,6 +415,11 @@ static void hsw_sleep(struct sst_dsp *sst)
|
|||
{
|
||||
dev_dbg(sst->dev, "HSW_PM dsp runtime suspend\n");
|
||||
|
||||
/* put DSP into reset and stall */
|
||||
sst_dsp_shim_update_bits(sst, SST_CSR,
|
||||
SST_CSR_24MHZ_LPCS | SST_CSR_RST | SST_CSR_STALL,
|
||||
SST_CSR_RST | SST_CSR_STALL | SST_CSR_24MHZ_LPCS);
|
||||
|
||||
hsw_set_dsp_D3(sst);
|
||||
dev_dbg(sst->dev, "HSW_PM dsp runtime suspend exit\n");
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define CTRL0_TODDR_SEL_RESAMPLE BIT(30)
|
||||
#define CTRL0_TODDR_EXT_SIGNED BIT(29)
|
||||
#define CTRL0_TODDR_PP_MODE BIT(28)
|
||||
#define CTRL0_TODDR_SYNC_CH BIT(27)
|
||||
#define CTRL0_TODDR_TYPE_MASK GENMASK(15, 13)
|
||||
#define CTRL0_TODDR_TYPE(x) ((x) << 13)
|
||||
#define CTRL0_TODDR_MSB_POS_MASK GENMASK(12, 8)
|
||||
|
@ -189,10 +190,31 @@ static const struct axg_fifo_match_data axg_toddr_match_data = {
|
|||
.dai_drv = &axg_toddr_dai_drv
|
||||
};
|
||||
|
||||
static int g12a_toddr_dai_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
|
||||
int ret;
|
||||
|
||||
ret = axg_toddr_dai_startup(substream, dai);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Make sure the first channel ends up in the at beginning of the output
|
||||
* As weird as it looks, without this the first channel may be misplaced
|
||||
* in memory, with a random shift of 2 channels.
|
||||
*/
|
||||
regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_SYNC_CH,
|
||||
CTRL0_TODDR_SYNC_CH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops g12a_toddr_ops = {
|
||||
.prepare = g12a_toddr_dai_prepare,
|
||||
.hw_params = axg_toddr_dai_hw_params,
|
||||
.startup = axg_toddr_dai_startup,
|
||||
.startup = g12a_toddr_dai_startup,
|
||||
.shutdown = axg_toddr_dai_shutdown,
|
||||
};
|
||||
|
||||
|
|
|
@ -143,6 +143,7 @@ static int apq8016_sbc_platform_probe(struct platform_device *pdev)
|
|||
|
||||
card = &data->card;
|
||||
card->dev = dev;
|
||||
card->owner = THIS_MODULE;
|
||||
card->dapm_widgets = apq8016_sbc_dapm_widgets;
|
||||
card->num_dapm_widgets = ARRAY_SIZE(apq8016_sbc_dapm_widgets);
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ static int apq8096_platform_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
|
||||
card->dev = dev;
|
||||
card->owner = THIS_MODULE;
|
||||
dev_set_drvdata(dev, card);
|
||||
ret = qcom_snd_parse_of(card);
|
||||
if (ret)
|
||||
|
|
|
@ -56,8 +56,10 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
|
|||
|
||||
for_each_child_of_node(dev->of_node, np) {
|
||||
dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL);
|
||||
if (!dlc)
|
||||
return -ENOMEM;
|
||||
if (!dlc) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
link->cpus = &dlc[0];
|
||||
link->platforms = &dlc[1];
|
||||
|
|
|
@ -555,6 +555,7 @@ static int sdm845_snd_platform_probe(struct platform_device *pdev)
|
|||
card->dapm_widgets = sdm845_snd_widgets;
|
||||
card->num_dapm_widgets = ARRAY_SIZE(sdm845_snd_widgets);
|
||||
card->dev = dev;
|
||||
card->owner = THIS_MODULE;
|
||||
dev_set_drvdata(dev, card);
|
||||
ret = qcom_snd_parse_of(card);
|
||||
if (ret)
|
||||
|
|
|
@ -96,6 +96,7 @@ static int storm_platform_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
card->owner = THIS_MODULE;
|
||||
|
||||
ret = snd_soc_of_parse_card_name(card, "qcom,model");
|
||||
if (ret) {
|
||||
|
|
|
@ -812,7 +812,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
|
|||
return 0;
|
||||
|
||||
config_err:
|
||||
for_each_rtd_dais(rtd, i, dai)
|
||||
for_each_rtd_dais_rollback(rtd, i, dai)
|
||||
snd_soc_dai_shutdown(dai, substream);
|
||||
|
||||
snd_soc_link_shutdown(substream);
|
||||
|
|
|
@ -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->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;
|
||||
num_ops = tplg->bytes_ext_ops_count;
|
||||
for (i = 0; i < num_ops; i++) {
|
||||
|
|
|
@ -446,12 +446,12 @@ static const struct snd_soc_dai_ops ams_delta_dai_ops = {
|
|||
/* Will be used if the codec ever has its own digital_mute function */
|
||||
static int ams_delta_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
return ams_delta_digital_mute(NULL, 0, substream->stream);
|
||||
return ams_delta_mute(NULL, 0, substream->stream);
|
||||
}
|
||||
|
||||
static void ams_delta_shutdown(struct snd_pcm_substream *substream)
|
||||
{
|
||||
ams_delta_digital_mute(NULL, 1, substream->stream);
|
||||
ams_delta_mute(NULL, 1, substream->stream);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user