mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-30 07:34:12 +08:00
Merge remote-tracking branch 'asoc/for-5.9' into asoc-linus
This commit is contained in:
commit
7ffe09eebf
@ -4170,6 +4170,7 @@ CIRRUS LOGIC AUDIO CODEC DRIVERS
|
||||
M: James Schulman <james.schulman@cirrus.com>
|
||||
M: David Rhodes <david.rhodes@cirrus.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
L: patches@opensource.cirrus.com
|
||||
S: Maintained
|
||||
F: sound/soc/codecs/cs*
|
||||
|
||||
|
@ -1089,6 +1089,7 @@ static const struct snd_soc_dapm_route cs47l15_dapm_routes[] = {
|
||||
{ "HPOUT1 Demux", NULL, "OUT1R" },
|
||||
|
||||
{ "OUT1R", NULL, "HPOUT1 Mono Mux" },
|
||||
{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
|
||||
|
||||
{ "HPOUTL", "HPOUT", "HPOUT1 Demux" },
|
||||
{ "HPOUTR", "HPOUT", "HPOUT1 Demux" },
|
||||
@ -1268,7 +1269,6 @@ static irqreturn_t cs47l15_adsp2_irq(int irq, void *data)
|
||||
|
||||
static const struct snd_soc_dapm_route cs47l15_mono_routes[] = {
|
||||
{ "HPOUT1 Mono Mux", "HPOUT", "OUT1L" },
|
||||
{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
|
||||
};
|
||||
|
||||
static int cs47l15_component_probe(struct snd_soc_component *component)
|
||||
|
@ -1305,6 +1305,7 @@ static const struct snd_soc_dapm_route cs47l35_dapm_routes[] = {
|
||||
{ "SPKOUTP", NULL, "OUT4L" },
|
||||
|
||||
{ "OUT1R", NULL, "HPOUT1 Mono Mux" },
|
||||
{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
|
||||
|
||||
{ "HPOUTL", "HPOUT", "HPOUT1 Demux" },
|
||||
{ "HPOUTR", "HPOUT", "HPOUT1 Demux" },
|
||||
@ -1550,7 +1551,6 @@ static irqreturn_t cs47l35_adsp2_irq(int irq, void *data)
|
||||
|
||||
static const struct snd_soc_dapm_route cs47l35_mono_routes[] = {
|
||||
{ "HPOUT1 Mono Mux", "HPOUT", "OUT1L" },
|
||||
{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
|
||||
};
|
||||
|
||||
static int cs47l35_component_probe(struct snd_soc_component *component)
|
||||
|
@ -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,
|
||||
|
@ -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__ */
|
||||
|
@ -490,6 +490,9 @@ static int __maybe_unused rt700_dev_suspend(struct device *dev)
|
||||
if (!rt700->hw_init)
|
||||
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);
|
||||
|
||||
return 0;
|
||||
|
@ -491,6 +491,10 @@ static int __maybe_unused rt711_dev_suspend(struct device *dev)
|
||||
if (!rt711->hw_init)
|
||||
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);
|
||||
|
||||
return 0;
|
||||
|
@ -57,7 +57,12 @@ static int tas2770_set_bias_level(struct snd_soc_component *component,
|
||||
TAS2770_PWR_CTRL_MASK,
|
||||
TAS2770_PWR_CTRL_ACTIVE);
|
||||
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:
|
||||
snd_soc_component_update_bits(component,
|
||||
TAS2770_PWR_CTRL,
|
||||
@ -135,23 +140,18 @@ static int tas2770_dac_event(struct snd_soc_dapm_widget *w,
|
||||
TAS2770_PWR_CTRL,
|
||||
TAS2770_PWR_CTRL_MASK,
|
||||
TAS2770_PWR_CTRL_MUTE);
|
||||
if (ret)
|
||||
goto end;
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
ret = snd_soc_component_update_bits(component,
|
||||
TAS2770_PWR_CTRL,
|
||||
TAS2770_PWR_CTRL_MASK,
|
||||
TAS2770_PWR_CTRL_SHUTDOWN);
|
||||
if (ret)
|
||||
goto end;
|
||||
break;
|
||||
default:
|
||||
dev_err(tas2770->dev, "Not supported evevt\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
end:
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -243,6 +243,9 @@ static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
tas2770->channel_size = bitwidth;
|
||||
|
||||
ret = snd_soc_component_update_bits(component,
|
||||
@ -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_VSNS_ENABLE |
|
||||
tas2770->v_sense_slot);
|
||||
if (ret)
|
||||
goto end;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_component_update_bits(component,
|
||||
TAS2770_TDM_CFG_REG6,
|
||||
TAS2770_TDM_CFG_REG6_ISNS_MASK |
|
||||
TAS2770_TDM_CFG_REG6_50_MASK,
|
||||
TAS2770_TDM_CFG_REG6_ISNS_ENABLE |
|
||||
tas2770->i_sense_slot);
|
||||
|
||||
end:
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -278,36 +280,35 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
|
||||
TAS2770_TDM_CFG_REG0,
|
||||
TAS2770_TDM_CFG_REG0_SMP_MASK,
|
||||
TAS2770_TDM_CFG_REG0_SMP_48KHZ);
|
||||
if (ret)
|
||||
goto end;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_component_update_bits(component,
|
||||
TAS2770_TDM_CFG_REG0,
|
||||
TAS2770_TDM_CFG_REG0_31_MASK,
|
||||
TAS2770_TDM_CFG_REG0_31_44_1_48KHZ);
|
||||
if (ret)
|
||||
goto end;
|
||||
break;
|
||||
case 44100:
|
||||
ret = snd_soc_component_update_bits(component,
|
||||
TAS2770_TDM_CFG_REG0,
|
||||
TAS2770_TDM_CFG_REG0_SMP_MASK,
|
||||
TAS2770_TDM_CFG_REG0_SMP_44_1KHZ);
|
||||
if (ret)
|
||||
goto end;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_component_update_bits(component,
|
||||
TAS2770_TDM_CFG_REG0,
|
||||
TAS2770_TDM_CFG_REG0_31_MASK,
|
||||
TAS2770_TDM_CFG_REG0_31_44_1_48KHZ);
|
||||
if (ret)
|
||||
goto end;
|
||||
break;
|
||||
case 96000:
|
||||
ret = snd_soc_component_update_bits(component,
|
||||
TAS2770_TDM_CFG_REG0,
|
||||
TAS2770_TDM_CFG_REG0_SMP_MASK,
|
||||
TAS2770_TDM_CFG_REG0_SMP_48KHZ);
|
||||
if (ret)
|
||||
goto end;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_component_update_bits(component,
|
||||
TAS2770_TDM_CFG_REG0,
|
||||
TAS2770_TDM_CFG_REG0_31_MASK,
|
||||
@ -318,8 +319,9 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
|
||||
TAS2770_TDM_CFG_REG0,
|
||||
TAS2770_TDM_CFG_REG0_SMP_MASK,
|
||||
TAS2770_TDM_CFG_REG0_SMP_44_1KHZ);
|
||||
if (ret)
|
||||
goto end;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_component_update_bits(component,
|
||||
TAS2770_TDM_CFG_REG0,
|
||||
TAS2770_TDM_CFG_REG0_31_MASK,
|
||||
@ -330,22 +332,22 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
|
||||
TAS2770_TDM_CFG_REG0,
|
||||
TAS2770_TDM_CFG_REG0_SMP_MASK,
|
||||
TAS2770_TDM_CFG_REG0_SMP_48KHZ);
|
||||
if (ret)
|
||||
goto end;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_component_update_bits(component,
|
||||
TAS2770_TDM_CFG_REG0,
|
||||
TAS2770_TDM_CFG_REG0_31_MASK,
|
||||
TAS2770_TDM_CFG_REG0_31_176_4_192KHZ);
|
||||
if (ret)
|
||||
goto end;
|
||||
break;
|
||||
case 17640:
|
||||
ret = snd_soc_component_update_bits(component,
|
||||
TAS2770_TDM_CFG_REG0,
|
||||
TAS2770_TDM_CFG_REG0_SMP_MASK,
|
||||
TAS2770_TDM_CFG_REG0_SMP_44_1KHZ);
|
||||
if (ret)
|
||||
goto end;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_component_update_bits(component,
|
||||
TAS2770_TDM_CFG_REG0,
|
||||
TAS2770_TDM_CFG_REG0_31_MASK,
|
||||
@ -355,7 +357,6 @@ static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
end:
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -575,6 +576,8 @@ static int tas2770_codec_probe(struct snd_soc_component *component)
|
||||
|
||||
tas2770->component = component;
|
||||
|
||||
tas2770_reset(tas2770);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -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",
|
||||
&tas2770->asi_format);
|
||||
if (rc) {
|
||||
dev_err(tas2770->dev, "Looking up %s property failed %d\n",
|
||||
"ti,asi-format", rc);
|
||||
goto end;
|
||||
dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
|
||||
"ti,asi-format");
|
||||
tas2770->asi_format = 0;
|
||||
}
|
||||
|
||||
rc = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no",
|
||||
&tas2770->i_sense_slot);
|
||||
if (rc) {
|
||||
dev_err(tas2770->dev, "Looking up %s property failed %d\n",
|
||||
"ti,imon-slot-no", rc);
|
||||
goto end;
|
||||
dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
|
||||
"ti,imon-slot-no");
|
||||
tas2770->i_sense_slot = 0;
|
||||
}
|
||||
|
||||
rc = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no",
|
||||
&tas2770->v_sense_slot);
|
||||
if (rc) {
|
||||
dev_err(tas2770->dev, "Looking up %s property failed %d\n",
|
||||
"ti,vmon-slot-no", rc);
|
||||
goto end;
|
||||
dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
|
||||
"ti,vmon-slot-no");
|
||||
tas2770->v_sense_slot = 2;
|
||||
}
|
||||
|
||||
end:
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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->slot_width = 0;
|
||||
|
||||
tas2770_reset(tas2770);
|
||||
|
||||
result = tas2770_register_codec(tas2770);
|
||||
if (result)
|
||||
dev_err(tas2770->dev, "Register codec failed.\n");
|
||||
|
@ -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);
|
||||
@ -614,11 +614,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)) {
|
||||
@ -640,9 +655,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;
|
||||
}
|
||||
|
||||
@ -654,7 +673,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) {
|
||||
@ -670,24 +689,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:
|
||||
@ -697,18 +698,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 |
|
||||
@ -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,
|
||||
ADCX140_TX_OFFSET_MASK, offset);
|
||||
|
||||
adcx140_pwr_ctrl(adcx140, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -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",
|
||||
&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",
|
||||
@ -906,6 +929,8 @@ static int adcx140_codec_probe(struct snd_soc_component *component)
|
||||
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;
|
||||
}
|
||||
@ -914,21 +939,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 = {
|
||||
|
@ -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_ */
|
||||
|
@ -230,7 +230,14 @@ static int clk_aic32x4_pll_set_rate(struct clk_hw *hw,
|
||||
if (ret < 0)
|
||||
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)
|
||||
|
@ -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,
|
||||
unsigned int sample_rate)
|
||||
unsigned int sample_rate, unsigned int channels)
|
||||
{
|
||||
u8 aosr;
|
||||
u16 dosr;
|
||||
@ -753,7 +753,9 @@ static int aic32x4_setup_clocks(struct snd_soc_component *component,
|
||||
dosr);
|
||||
|
||||
clk_set_rate(clocks[5].clk,
|
||||
sample_rate * 32);
|
||||
sample_rate * 32 *
|
||||
channels);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -775,7 +777,8 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
|
||||
u8 iface1_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)) {
|
||||
case 16:
|
||||
@ -1010,6 +1013,14 @@ static int aic32x4_component_probe(struct snd_soc_component *component)
|
||||
AIC32X4_LADC_EN | AIC32X4_RADC_EN);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,7 @@ int aic32x4_register_clocks(struct device *dev, const char *mclk_name);
|
||||
#define AIC32X4_FLOATINGINPUT AIC32X4_REG(1, 58)
|
||||
#define AIC32X4_LMICPGAVOL AIC32X4_REG(1, 59)
|
||||
#define AIC32X4_RMICPGAVOL AIC32X4_REG(1, 60)
|
||||
#define AIC32X4_REFPOWERUP AIC32X4_REG(1, 123)
|
||||
|
||||
/* Bits, masks, and shifts */
|
||||
|
||||
@ -205,6 +206,12 @@ int aic32x4_register_clocks(struct device *dev, const char *mclk_name);
|
||||
#define AIC32X4_RMICPGANIN_IN1L_10K 0x10
|
||||
#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 */
|
||||
#define AIC32X4_DIVEN BIT(7)
|
||||
#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,
|
||||
{
|
||||
struct wm_coeff_ctl *ctl;
|
||||
struct snd_kcontrol *kcontrol;
|
||||
char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
int ret;
|
||||
|
||||
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,
|
||||
return -EINVAL;
|
||||
|
||||
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,
|
||||
SNDRV_CTL_EVENT_MASK_VALUE, &kcontrol->id);
|
||||
|
||||
|
@ -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]),
|
||||
|
@ -694,7 +694,7 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
|
||||
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,
|
||||
.playback = {
|
||||
.stream_name = "CPU-Playback",
|
||||
@ -966,12 +966,15 @@ static int fsl_sai_probe(struct platform_device *pdev)
|
||||
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 */
|
||||
sai->synchronous[RX] = true;
|
||||
sai->synchronous[TX] = false;
|
||||
fsl_sai_dai.symmetric_rates = 1;
|
||||
fsl_sai_dai.symmetric_channels = 1;
|
||||
fsl_sai_dai.symmetric_samplebits = 1;
|
||||
sai->cpu_dai_drv.symmetric_rates = 1;
|
||||
sai->cpu_dai_drv.symmetric_channels = 1;
|
||||
sai->cpu_dai_drv.symmetric_samplebits = 1;
|
||||
|
||||
if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) &&
|
||||
of_find_property(np, "fsl,sai-asynchronous", NULL)) {
|
||||
@ -988,9 +991,9 @@ static int fsl_sai_probe(struct platform_device *pdev)
|
||||
/* Discard all settings for asynchronous mode */
|
||||
sai->synchronous[RX] = false;
|
||||
sai->synchronous[TX] = false;
|
||||
fsl_sai_dai.symmetric_rates = 0;
|
||||
fsl_sai_dai.symmetric_channels = 0;
|
||||
fsl_sai_dai.symmetric_samplebits = 0;
|
||||
sai->cpu_dai_drv.symmetric_rates = 0;
|
||||
sai->cpu_dai_drv.symmetric_channels = 0;
|
||||
sai->cpu_dai_drv.symmetric_samplebits = 0;
|
||||
}
|
||||
|
||||
if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
|
||||
@ -1020,7 +1023,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
|
||||
regcache_cache_only(sai->regmap, true);
|
||||
|
||||
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
|
||||
&fsl_sai_dai, 1);
|
||||
&sai->cpu_dai_drv, 1);
|
||||
if (ret)
|
||||
goto err_pm_disable;
|
||||
|
||||
|
@ -180,6 +180,7 @@ struct fsl_sai {
|
||||
unsigned int bclk_ratio;
|
||||
|
||||
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_tx;
|
||||
};
|
||||
|
@ -673,7 +673,7 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
|
||||
if (card == &mt8183_da7219_max98357_card) {
|
||||
dai_link->be_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->num_cpus =
|
||||
ARRAY_SIZE(i2s3_max98357a_cpus);
|
||||
|
@ -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++) {
|
||||
|
Loading…
Reference in New Issue
Block a user