mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-20 17:41:09 +00:00
Merge series "Codec workaround" from Michael Sit Wei Hong <michael.wei.hong.sit@intel.com>:
This patch series enables some features on the tlv3204 codec and also fixes some issues faced while testing v2: Fixed the build error from snd_soc_component_read32 v1: initial ASoC: codec: tlv3204: Codec workaround series Michael Sit Wei Hong (3): ASoC: codec: tlv3204: Enable 24 bit audio support ASoC: codec: tlv3204: Increased maximum supported channels ASoC: codec: tlv3204: Moving GPIO reset and add ADC reset sound/soc/codecs/tlv320aic32x4.c | 60 +++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 16 deletions(-) -- 2.17.1
This commit is contained in:
commit
354caf5836
1 changed files with 44 additions and 16 deletions
|
@ -50,6 +50,28 @@ struct aic32x4_priv {
|
|||
struct device *dev;
|
||||
};
|
||||
|
||||
static int aic32x4_reset_adc(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
|
||||
u32 adc_reg;
|
||||
|
||||
/*
|
||||
* Workaround: the datasheet does not mention a required programming
|
||||
* sequence but experiments show the ADC needs to be reset after each
|
||||
* capture to avoid audible artifacts.
|
||||
*/
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
adc_reg = snd_soc_component_read(component, AIC32X4_ADCSETUP);
|
||||
snd_soc_component_write(component, AIC32X4_ADCSETUP, adc_reg |
|
||||
AIC32X4_LADC_EN | AIC32X4_RADC_EN);
|
||||
snd_soc_component_write(component, AIC32X4_ADCSETUP, adc_reg);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
static int mic_bias_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
|
@ -434,6 +456,7 @@ static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_SUPPLY("Mic Bias", AIC32X4_MICBIAS, 6, 0, mic_bias_event,
|
||||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
|
||||
|
||||
SND_SOC_DAPM_POST("ADC Reset", aic32x4_reset_adc),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("HPL"),
|
||||
SND_SOC_DAPM_OUTPUT("HPR"),
|
||||
|
@ -665,7 +688,8 @@ 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 channel,
|
||||
unsigned int bit_depth)
|
||||
{
|
||||
u8 aosr;
|
||||
u16 dosr;
|
||||
|
@ -753,7 +777,8 @@ static int aic32x4_setup_clocks(struct snd_soc_component *component,
|
|||
dosr);
|
||||
|
||||
clk_set_rate(clocks[5].clk,
|
||||
sample_rate * 32);
|
||||
sample_rate * channel *
|
||||
bit_depth);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -775,9 +800,11 @@ 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),
|
||||
params_physical_width(params));
|
||||
|
||||
switch (params_width(params)) {
|
||||
switch (params_physical_width(params)) {
|
||||
case 16:
|
||||
iface1_reg |= (AIC32X4_WORD_LEN_16BITS <<
|
||||
AIC32X4_IFACE1_DATALEN_SHIFT);
|
||||
|
@ -862,7 +889,8 @@ static int aic32x4_set_bias_level(struct snd_soc_component *component,
|
|||
|
||||
#define AIC32X4_RATES SNDRV_PCM_RATE_8000_192000
|
||||
#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
|
||||
| SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
|
||||
| SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE \
|
||||
| SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
||||
static const struct snd_soc_dai_ops aic32x4_ops = {
|
||||
.hw_params = aic32x4_hw_params,
|
||||
|
@ -883,7 +911,7 @@ static struct snd_soc_dai_driver aic32x4_dai = {
|
|||
.capture = {
|
||||
.stream_name = "Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.channels_max = 8,
|
||||
.rates = AIC32X4_RATES,
|
||||
.formats = AIC32X4_FORMATS,},
|
||||
.ops = &aic32x4_ops,
|
||||
|
@ -953,12 +981,6 @@ static int aic32x4_component_probe(struct snd_soc_component *component)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (gpio_is_valid(aic32x4->rstn_gpio)) {
|
||||
ndelay(10);
|
||||
gpio_set_value(aic32x4->rstn_gpio, 1);
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
snd_soc_component_write(component, AIC32X4_RESET, 0x01);
|
||||
|
||||
if (aic32x4->setup)
|
||||
|
@ -1191,10 +1213,6 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap)
|
|||
aic32x4->mclk_name = "mclk";
|
||||
}
|
||||
|
||||
ret = aic32x4_register_clocks(dev, aic32x4->mclk_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (gpio_is_valid(aic32x4->rstn_gpio)) {
|
||||
ret = devm_gpio_request_one(dev, aic32x4->rstn_gpio,
|
||||
GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn");
|
||||
|
@ -1216,6 +1234,16 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (gpio_is_valid(aic32x4->rstn_gpio)) {
|
||||
ndelay(10);
|
||||
gpio_set_value_cansleep(aic32x4->rstn_gpio, 1);
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
ret = aic32x4_register_clocks(dev, aic32x4->mclk_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(aic32x4_probe);
|
||||
|
|
Loading…
Reference in a new issue