ASoC: Fixes for v6.0

Quite a few fixes here, all driver specific and fairly small.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmMZ3RMACgkQJNaLcl1U
 h9CJ3wf/Qvez0ooFNL+WnW2YSl56DgWO3lMbgkSyLmiS5L02jfDObB1CTvY76czT
 z057WQBYr589JEIHFy4etPY2l0l5NJn/cUGOw4kl7TOV9l2o8PU3dlQMqpGdsZfY
 6pMvNZgr9HO7N5jXvbNg80HW7jRfOJzLU3b7HLLfWRf909Vflw8/C7N/cRnjimud
 D3atQ/hqgEczTxsdLekgFdsg3qmj+VQ5iT5COiIjuTjYPwF5KVqgRkyq/Zvjorkd
 /sdVf3+tXuFpRotGEKscpnZWbfcY5sEFkq0qCHVoPW150UP7KJRbSKJqVO9Vrlj5
 fb34rwnXaqPDU8IUKL/9QQ+yaCbOlQ==
 =wX+x
 -----END PGP SIGNATURE-----

Merge tag 'asoc-fix-v6.0-rc4' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Fixes for v6.0

Quite a few fixes here, all driver specific and fairly small.
This commit is contained in:
Takashi Iwai 2022-09-08 14:24:05 +02:00
commit 09e3e3159c
13 changed files with 184 additions and 132 deletions

View File

@ -196,7 +196,7 @@ struct mchp_spdiftx_dev {
struct clk *pclk; struct clk *pclk;
struct clk *gclk; struct clk *gclk;
unsigned int fmt; unsigned int fmt;
int gclk_enabled:1; unsigned int gclk_enabled:1;
}; };
static inline int mchp_spdiftx_is_running(struct mchp_spdiftx_dev *dev) static inline int mchp_spdiftx_is_running(struct mchp_spdiftx_dev *dev)

View File

@ -1617,7 +1617,6 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
unsigned int current_plug_status; unsigned int current_plug_status;
unsigned int current_button_status; unsigned int current_button_status;
unsigned int i; unsigned int i;
int report = 0;
mutex_lock(&cs42l42->irq_lock); mutex_lock(&cs42l42->irq_lock);
if (cs42l42->suspended) { if (cs42l42->suspended) {
@ -1711,13 +1710,15 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
if (current_button_status & CS42L42_M_DETECT_TF_MASK) { if (current_button_status & CS42L42_M_DETECT_TF_MASK) {
dev_dbg(cs42l42->dev, "Button released\n"); dev_dbg(cs42l42->dev, "Button released\n");
report = 0; snd_soc_jack_report(cs42l42->jack, 0,
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3);
} else if (current_button_status & CS42L42_M_DETECT_FT_MASK) { } else if (current_button_status & CS42L42_M_DETECT_FT_MASK) {
report = cs42l42_handle_button_press(cs42l42); snd_soc_jack_report(cs42l42->jack,
cs42l42_handle_button_press(cs42l42),
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3);
} }
snd_soc_jack_report(cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3);
} }
} }

View File

@ -357,17 +357,32 @@ static const struct snd_soc_dapm_route nau8540_dapm_routes[] = {
{"AIFTX", NULL, "Digital CH4 Mux"}, {"AIFTX", NULL, "Digital CH4 Mux"},
}; };
static int nau8540_clock_check(struct nau8540 *nau8540, int rate, int osr) static const struct nau8540_osr_attr *
nau8540_get_osr(struct nau8540 *nau8540)
{ {
unsigned int osr;
regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr);
osr &= NAU8540_ADC_OSR_MASK;
if (osr >= ARRAY_SIZE(osr_adc_sel)) if (osr >= ARRAY_SIZE(osr_adc_sel))
return NULL;
return &osr_adc_sel[osr];
}
static int nau8540_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
const struct nau8540_osr_attr *osr;
osr = nau8540_get_osr(nau8540);
if (!osr || !osr->osr)
return -EINVAL; return -EINVAL;
if (rate * osr > CLK_ADC_MAX) { return snd_pcm_hw_constraint_minmax(substream->runtime,
dev_err(nau8540->dev, "exceed the maximum frequency of CLK_ADC\n"); SNDRV_PCM_HW_PARAM_RATE,
return -EINVAL; 0, CLK_ADC_MAX / osr->osr);
}
return 0;
} }
static int nau8540_hw_params(struct snd_pcm_substream *substream, static int nau8540_hw_params(struct snd_pcm_substream *substream,
@ -375,7 +390,8 @@ static int nau8540_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component); struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
unsigned int val_len = 0, osr; unsigned int val_len = 0;
const struct nau8540_osr_attr *osr;
/* CLK_ADC = OSR * FS /* CLK_ADC = OSR * FS
* ADC clock frequency is defined as Over Sampling Rate (OSR) * ADC clock frequency is defined as Over Sampling Rate (OSR)
@ -383,13 +399,14 @@ static int nau8540_hw_params(struct snd_pcm_substream *substream,
* values must be selected such that the maximum frequency is less * values must be selected such that the maximum frequency is less
* than 6.144 MHz. * than 6.144 MHz.
*/ */
regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr); osr = nau8540_get_osr(nau8540);
osr &= NAU8540_ADC_OSR_MASK; if (!osr || !osr->osr)
if (nau8540_clock_check(nau8540, params_rate(params), osr)) return -EINVAL;
if (params_rate(params) * osr->osr > CLK_ADC_MAX)
return -EINVAL; return -EINVAL;
regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC, regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,
NAU8540_CLK_ADC_SRC_MASK, NAU8540_CLK_ADC_SRC_MASK,
osr_adc_sel[osr].clk_src << NAU8540_CLK_ADC_SRC_SFT); osr->clk_src << NAU8540_CLK_ADC_SRC_SFT);
switch (params_width(params)) { switch (params_width(params)) {
case 16: case 16:
@ -515,6 +532,7 @@ static int nau8540_set_tdm_slot(struct snd_soc_dai *dai,
static const struct snd_soc_dai_ops nau8540_dai_ops = { static const struct snd_soc_dai_ops nau8540_dai_ops = {
.startup = nau8540_dai_startup,
.hw_params = nau8540_hw_params, .hw_params = nau8540_hw_params,
.set_fmt = nau8540_set_fmt, .set_fmt = nau8540_set_fmt,
.set_tdm_slot = nau8540_set_tdm_slot, .set_tdm_slot = nau8540_set_tdm_slot,

View File

@ -670,28 +670,40 @@ static const struct snd_soc_dapm_route nau8821_dapm_routes[] = {
{"HPOR", NULL, "Class G"}, {"HPOR", NULL, "Class G"},
}; };
static int nau8821_clock_check(struct nau8821 *nau8821, static const struct nau8821_osr_attr *
int stream, int rate, int osr) nau8821_get_osr(struct nau8821 *nau8821, int stream)
{ {
int osrate = 0; unsigned int osr;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
regmap_read(nau8821->regmap, NAU8821_R2C_DAC_CTRL1, &osr);
osr &= NAU8821_DAC_OVERSAMPLE_MASK;
if (osr >= ARRAY_SIZE(osr_dac_sel)) if (osr >= ARRAY_SIZE(osr_dac_sel))
return -EINVAL; return NULL;
osrate = osr_dac_sel[osr].osr; return &osr_dac_sel[osr];
} else { } else {
regmap_read(nau8821->regmap, NAU8821_R2B_ADC_RATE, &osr);
osr &= NAU8821_ADC_SYNC_DOWN_MASK;
if (osr >= ARRAY_SIZE(osr_adc_sel)) if (osr >= ARRAY_SIZE(osr_adc_sel))
return -EINVAL; return NULL;
osrate = osr_adc_sel[osr].osr; return &osr_adc_sel[osr];
} }
}
if (!osrate || rate * osrate > CLK_DA_AD_MAX) { static int nau8821_dai_startup(struct snd_pcm_substream *substream,
dev_err(nau8821->dev, struct snd_soc_dai *dai)
"exceed the maximum frequency of CLK_ADC or CLK_DAC"); {
struct snd_soc_component *component = dai->component;
struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component);
const struct nau8821_osr_attr *osr;
osr = nau8821_get_osr(nau8821, substream->stream);
if (!osr || !osr->osr)
return -EINVAL; return -EINVAL;
}
return 0; return snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
0, CLK_DA_AD_MAX / osr->osr);
} }
static int nau8821_hw_params(struct snd_pcm_substream *substream, static int nau8821_hw_params(struct snd_pcm_substream *substream,
@ -699,7 +711,8 @@ static int nau8821_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component); struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component);
unsigned int val_len = 0, osr, ctrl_val, bclk_fs, clk_div; unsigned int val_len = 0, ctrl_val, bclk_fs, clk_div;
const struct nau8821_osr_attr *osr;
nau8821->fs = params_rate(params); nau8821->fs = params_rate(params);
/* CLK_DAC or CLK_ADC = OSR * FS /* CLK_DAC or CLK_ADC = OSR * FS
@ -708,27 +721,19 @@ static int nau8821_hw_params(struct snd_pcm_substream *substream,
* values must be selected such that the maximum frequency is less * values must be selected such that the maximum frequency is less
* than 6.144 MHz. * than 6.144 MHz.
*/ */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { osr = nau8821_get_osr(nau8821, substream->stream);
regmap_read(nau8821->regmap, NAU8821_R2C_DAC_CTRL1, &osr); if (!osr || !osr->osr)
osr &= NAU8821_DAC_OVERSAMPLE_MASK; return -EINVAL;
if (nau8821_clock_check(nau8821, substream->stream, if (nau8821->fs * osr->osr > CLK_DA_AD_MAX)
nau8821->fs, osr)) { return -EINVAL;
return -EINVAL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
}
regmap_update_bits(nau8821->regmap, NAU8821_R03_CLK_DIVIDER, regmap_update_bits(nau8821->regmap, NAU8821_R03_CLK_DIVIDER,
NAU8821_CLK_DAC_SRC_MASK, NAU8821_CLK_DAC_SRC_MASK,
osr_dac_sel[osr].clk_src << NAU8821_CLK_DAC_SRC_SFT); osr->clk_src << NAU8821_CLK_DAC_SRC_SFT);
} else { else
regmap_read(nau8821->regmap, NAU8821_R2B_ADC_RATE, &osr);
osr &= NAU8821_ADC_SYNC_DOWN_MASK;
if (nau8821_clock_check(nau8821, substream->stream,
nau8821->fs, osr)) {
return -EINVAL;
}
regmap_update_bits(nau8821->regmap, NAU8821_R03_CLK_DIVIDER, regmap_update_bits(nau8821->regmap, NAU8821_R03_CLK_DIVIDER,
NAU8821_CLK_ADC_SRC_MASK, NAU8821_CLK_ADC_SRC_MASK,
osr_adc_sel[osr].clk_src << NAU8821_CLK_ADC_SRC_SFT); osr->clk_src << NAU8821_CLK_ADC_SRC_SFT);
}
/* make BCLK and LRC divde configuration if the codec as master. */ /* make BCLK and LRC divde configuration if the codec as master. */
regmap_read(nau8821->regmap, NAU8821_R1D_I2S_PCM_CTRL2, &ctrl_val); regmap_read(nau8821->regmap, NAU8821_R1D_I2S_PCM_CTRL2, &ctrl_val);
@ -843,6 +848,7 @@ static int nau8821_digital_mute(struct snd_soc_dai *dai, int mute,
} }
static const struct snd_soc_dai_ops nau8821_dai_ops = { static const struct snd_soc_dai_ops nau8821_dai_ops = {
.startup = nau8821_dai_startup,
.hw_params = nau8821_hw_params, .hw_params = nau8821_hw_params,
.set_fmt = nau8821_set_dai_fmt, .set_fmt = nau8821_set_dai_fmt,
.mute_stream = nau8821_digital_mute, .mute_stream = nau8821_digital_mute,

View File

@ -1014,27 +1014,42 @@ static irqreturn_t nau8824_interrupt(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int nau8824_clock_check(struct nau8824 *nau8824, static const struct nau8824_osr_attr *
int stream, int rate, int osr) nau8824_get_osr(struct nau8824 *nau8824, int stream)
{ {
int osrate; unsigned int osr;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
regmap_read(nau8824->regmap,
NAU8824_REG_DAC_FILTER_CTRL_1, &osr);
osr &= NAU8824_DAC_OVERSAMPLE_MASK;
if (osr >= ARRAY_SIZE(osr_dac_sel)) if (osr >= ARRAY_SIZE(osr_dac_sel))
return -EINVAL; return NULL;
osrate = osr_dac_sel[osr].osr; return &osr_dac_sel[osr];
} else { } else {
regmap_read(nau8824->regmap,
NAU8824_REG_ADC_FILTER_CTRL, &osr);
osr &= NAU8824_ADC_SYNC_DOWN_MASK;
if (osr >= ARRAY_SIZE(osr_adc_sel)) if (osr >= ARRAY_SIZE(osr_adc_sel))
return -EINVAL; return NULL;
osrate = osr_adc_sel[osr].osr; return &osr_adc_sel[osr];
} }
}
if (!osrate || rate * osr > CLK_DA_AD_MAX) { static int nau8824_dai_startup(struct snd_pcm_substream *substream,
dev_err(nau8824->dev, "exceed the maximum frequency of CLK_ADC or CLK_DAC\n"); struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
const struct nau8824_osr_attr *osr;
osr = nau8824_get_osr(nau8824, substream->stream);
if (!osr || !osr->osr)
return -EINVAL; return -EINVAL;
}
return 0; return snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
0, CLK_DA_AD_MAX / osr->osr);
} }
static int nau8824_hw_params(struct snd_pcm_substream *substream, static int nau8824_hw_params(struct snd_pcm_substream *substream,
@ -1042,7 +1057,9 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div; unsigned int val_len = 0, ctrl_val, bclk_fs, bclk_div;
const struct nau8824_osr_attr *osr;
int err = -EINVAL;
nau8824_sema_acquire(nau8824, HZ); nau8824_sema_acquire(nau8824, HZ);
@ -1053,27 +1070,19 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
* than 6.144 MHz. * than 6.144 MHz.
*/ */
nau8824->fs = params_rate(params); nau8824->fs = params_rate(params);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { osr = nau8824_get_osr(nau8824, substream->stream);
regmap_read(nau8824->regmap, if (!osr || !osr->osr)
NAU8824_REG_DAC_FILTER_CTRL_1, &osr); goto error;
osr &= NAU8824_DAC_OVERSAMPLE_MASK; if (nau8824->fs * osr->osr > CLK_DA_AD_MAX)
if (nau8824_clock_check(nau8824, substream->stream, goto error;
nau8824->fs, osr)) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
return -EINVAL;
regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER,
NAU8824_CLK_DAC_SRC_MASK, NAU8824_CLK_DAC_SRC_MASK,
osr_dac_sel[osr].clk_src << NAU8824_CLK_DAC_SRC_SFT); osr->clk_src << NAU8824_CLK_DAC_SRC_SFT);
} else { else
regmap_read(nau8824->regmap,
NAU8824_REG_ADC_FILTER_CTRL, &osr);
osr &= NAU8824_ADC_SYNC_DOWN_MASK;
if (nau8824_clock_check(nau8824, substream->stream,
nau8824->fs, osr))
return -EINVAL;
regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER,
NAU8824_CLK_ADC_SRC_MASK, NAU8824_CLK_ADC_SRC_MASK,
osr_adc_sel[osr].clk_src << NAU8824_CLK_ADC_SRC_SFT); osr->clk_src << NAU8824_CLK_ADC_SRC_SFT);
}
/* make BCLK and LRC divde configuration if the codec as master. */ /* make BCLK and LRC divde configuration if the codec as master. */
regmap_read(nau8824->regmap, regmap_read(nau8824->regmap,
@ -1090,7 +1099,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
else if (bclk_fs <= 256) else if (bclk_fs <= 256)
bclk_div = 0; bclk_div = 0;
else else
return -EINVAL; goto error;
regmap_update_bits(nau8824->regmap, regmap_update_bits(nau8824->regmap,
NAU8824_REG_PORT0_I2S_PCM_CTRL_2, NAU8824_REG_PORT0_I2S_PCM_CTRL_2,
NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK, NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK,
@ -1111,15 +1120,17 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
val_len |= NAU8824_I2S_DL_32; val_len |= NAU8824_I2S_DL_32;
break; break;
default: default:
return -EINVAL; goto error;
} }
regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1,
NAU8824_I2S_DL_MASK, val_len); NAU8824_I2S_DL_MASK, val_len);
err = 0;
error:
nau8824_sema_release(nau8824); nau8824_sema_release(nau8824);
return 0; return err;
} }
static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
@ -1128,8 +1139,6 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
unsigned int ctrl1_val = 0, ctrl2_val = 0; unsigned int ctrl1_val = 0, ctrl2_val = 0;
nau8824_sema_acquire(nau8824, HZ);
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM: case SND_SOC_DAIFMT_CBM_CFM:
ctrl2_val |= NAU8824_I2S_MS_MASTER; ctrl2_val |= NAU8824_I2S_MS_MASTER;
@ -1171,6 +1180,8 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return -EINVAL; return -EINVAL;
} }
nau8824_sema_acquire(nau8824, HZ);
regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1,
NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK | NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK |
NAU8824_I2S_PCMB_EN, ctrl1_val); NAU8824_I2S_PCMB_EN, ctrl1_val);
@ -1547,6 +1558,7 @@ static const struct snd_soc_component_driver nau8824_component_driver = {
}; };
static const struct snd_soc_dai_ops nau8824_dai_ops = { static const struct snd_soc_dai_ops nau8824_dai_ops = {
.startup = nau8824_dai_startup,
.hw_params = nau8824_hw_params, .hw_params = nau8824_hw_params,
.set_fmt = nau8824_set_fmt, .set_fmt = nau8824_set_fmt,
.set_tdm_slot = nau8824_set_tdm_slot, .set_tdm_slot = nau8824_set_tdm_slot,

View File

@ -1247,27 +1247,42 @@ static const struct snd_soc_dapm_route nau8825_dapm_routes[] = {
{"HPOR", NULL, "Class G"}, {"HPOR", NULL, "Class G"},
}; };
static int nau8825_clock_check(struct nau8825 *nau8825, static const struct nau8825_osr_attr *
int stream, int rate, int osr) nau8825_get_osr(struct nau8825 *nau8825, int stream)
{ {
int osrate; unsigned int osr;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
regmap_read(nau8825->regmap,
NAU8825_REG_DAC_CTRL1, &osr);
osr &= NAU8825_DAC_OVERSAMPLE_MASK;
if (osr >= ARRAY_SIZE(osr_dac_sel)) if (osr >= ARRAY_SIZE(osr_dac_sel))
return -EINVAL; return NULL;
osrate = osr_dac_sel[osr].osr; return &osr_dac_sel[osr];
} else { } else {
regmap_read(nau8825->regmap,
NAU8825_REG_ADC_RATE, &osr);
osr &= NAU8825_ADC_SYNC_DOWN_MASK;
if (osr >= ARRAY_SIZE(osr_adc_sel)) if (osr >= ARRAY_SIZE(osr_adc_sel))
return -EINVAL; return NULL;
osrate = osr_adc_sel[osr].osr; return &osr_adc_sel[osr];
} }
}
if (!osrate || rate * osr > CLK_DA_AD_MAX) { static int nau8825_dai_startup(struct snd_pcm_substream *substream,
dev_err(nau8825->dev, "exceed the maximum frequency of CLK_ADC or CLK_DAC\n"); struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
const struct nau8825_osr_attr *osr;
osr = nau8825_get_osr(nau8825, substream->stream);
if (!osr || !osr->osr)
return -EINVAL; return -EINVAL;
}
return 0; return snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
0, CLK_DA_AD_MAX / osr->osr);
} }
static int nau8825_hw_params(struct snd_pcm_substream *substream, static int nau8825_hw_params(struct snd_pcm_substream *substream,
@ -1276,7 +1291,9 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component); struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div; unsigned int val_len = 0, ctrl_val, bclk_fs, bclk_div;
const struct nau8825_osr_attr *osr;
int err = -EINVAL;
nau8825_sema_acquire(nau8825, 3 * HZ); nau8825_sema_acquire(nau8825, 3 * HZ);
@ -1286,29 +1303,19 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
* values must be selected such that the maximum frequency is less * values must be selected such that the maximum frequency is less
* than 6.144 MHz. * than 6.144 MHz.
*/ */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { osr = nau8825_get_osr(nau8825, substream->stream);
regmap_read(nau8825->regmap, NAU8825_REG_DAC_CTRL1, &osr); if (!osr || !osr->osr)
osr &= NAU8825_DAC_OVERSAMPLE_MASK; goto error;
if (nau8825_clock_check(nau8825, substream->stream, if (params_rate(params) * osr->osr > CLK_DA_AD_MAX)
params_rate(params), osr)) { goto error;
nau8825_sema_release(nau8825); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
return -EINVAL;
}
regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER, regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
NAU8825_CLK_DAC_SRC_MASK, NAU8825_CLK_DAC_SRC_MASK,
osr_dac_sel[osr].clk_src << NAU8825_CLK_DAC_SRC_SFT); osr->clk_src << NAU8825_CLK_DAC_SRC_SFT);
} else { else
regmap_read(nau8825->regmap, NAU8825_REG_ADC_RATE, &osr);
osr &= NAU8825_ADC_SYNC_DOWN_MASK;
if (nau8825_clock_check(nau8825, substream->stream,
params_rate(params), osr)) {
nau8825_sema_release(nau8825);
return -EINVAL;
}
regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER, regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
NAU8825_CLK_ADC_SRC_MASK, NAU8825_CLK_ADC_SRC_MASK,
osr_adc_sel[osr].clk_src << NAU8825_CLK_ADC_SRC_SFT); osr->clk_src << NAU8825_CLK_ADC_SRC_SFT);
}
/* make BCLK and LRC divde configuration if the codec as master. */ /* make BCLK and LRC divde configuration if the codec as master. */
regmap_read(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, &ctrl_val); regmap_read(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, &ctrl_val);
@ -1321,10 +1328,8 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
bclk_div = 1; bclk_div = 1;
else if (bclk_fs <= 128) else if (bclk_fs <= 128)
bclk_div = 0; bclk_div = 0;
else { else
nau8825_sema_release(nau8825); goto error;
return -EINVAL;
}
regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
NAU8825_I2S_LRC_DIV_MASK | NAU8825_I2S_BLK_DIV_MASK, NAU8825_I2S_LRC_DIV_MASK | NAU8825_I2S_BLK_DIV_MASK,
((bclk_div + 1) << NAU8825_I2S_LRC_DIV_SFT) | bclk_div); ((bclk_div + 1) << NAU8825_I2S_LRC_DIV_SFT) | bclk_div);
@ -1344,17 +1349,18 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
val_len |= NAU8825_I2S_DL_32; val_len |= NAU8825_I2S_DL_32;
break; break;
default: default:
nau8825_sema_release(nau8825); goto error;
return -EINVAL;
} }
regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1, regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1,
NAU8825_I2S_DL_MASK, val_len); NAU8825_I2S_DL_MASK, val_len);
err = 0;
error:
/* Release the semaphore. */ /* Release the semaphore. */
nau8825_sema_release(nau8825); nau8825_sema_release(nau8825);
return 0; return err;
} }
static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
@ -1420,6 +1426,7 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
} }
static const struct snd_soc_dai_ops nau8825_dai_ops = { static const struct snd_soc_dai_ops nau8825_dai_ops = {
.startup = nau8825_dai_startup,
.hw_params = nau8825_hw_params, .hw_params = nau8825_hw_params,
.set_fmt = nau8825_set_dai_fmt, .set_fmt = nau8825_set_dai_fmt,
}; };

View File

@ -234,18 +234,26 @@ static int fsl_aud2htx_probe(struct platform_device *pdev)
regcache_cache_only(aud2htx->regmap, true); regcache_cache_only(aud2htx->regmap, true);
/*
* Register platform component before registering cpu dai for there
* is not defer probe for platform component in snd_soc_add_pcm_runtime().
*/
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
if (ret) {
dev_err(&pdev->dev, "failed to pcm register\n");
pm_runtime_disable(&pdev->dev);
return ret;
}
ret = devm_snd_soc_register_component(&pdev->dev, ret = devm_snd_soc_register_component(&pdev->dev,
&fsl_aud2htx_component, &fsl_aud2htx_component,
&fsl_aud2htx_dai, 1); &fsl_aud2htx_dai, 1);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register ASoC DAI\n"); dev_err(&pdev->dev, "failed to register ASoC DAI\n");
pm_runtime_disable(&pdev->dev);
return ret; return ret;
} }
ret = imx_pcm_dma_init(pdev);
if (ret)
dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
return ret; return ret;
} }

View File

@ -122,7 +122,7 @@ static int fsl_mqs_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
} }
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
case SND_SOC_DAIFMT_BP_FP: case SND_SOC_DAIFMT_CBC_CFC:
break; break;
default: default:
return -EINVAL; return -EINVAL;

View File

@ -1306,7 +1306,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
sai->mclk_clk[i] = devm_clk_get(dev, tmp); sai->mclk_clk[i] = devm_clk_get(dev, tmp);
if (IS_ERR(sai->mclk_clk[i])) { if (IS_ERR(sai->mclk_clk[i])) {
dev_err(dev, "failed to get mclk%d clock: %ld\n", dev_err(dev, "failed to get mclk%d clock: %ld\n",
i + 1, PTR_ERR(sai->mclk_clk[i])); i, PTR_ERR(sai->mclk_clk[i]));
sai->mclk_clk[i] = NULL; sai->mclk_clk[i] = NULL;
} }
} }

View File

@ -271,9 +271,6 @@ static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
/* should delayed 1/fs(smallest is 8k) = 125us before afe off */ /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
usleep_range(125, 135); usleep_range(125, 135);
mt8186_afe_gpio_request(afe->dev, false, MT8186_DAI_ADDA, 1); mt8186_afe_gpio_request(afe->dev, false, MT8186_DAI_ADDA, 1);
/* reset dmic */
afe_priv->mtkaif_dmic = 0;
break; break;
default: default:
break; break;

View File

@ -270,6 +270,7 @@ static int sm8250_platform_probe(struct platform_device *pdev)
if (!card) if (!card)
return -ENOMEM; return -ENOMEM;
card->owner = THIS_MODULE;
/* Allocate the private data */ /* Allocate the private data */
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data) if (!data)

View File

@ -196,6 +196,7 @@ config SND_SOC_SOF_DEBUG_ENABLE_FIRMWARE_TRACE
config SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST config SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST
tristate "SOF enable IPC flood test" tristate "SOF enable IPC flood test"
depends on SND_SOC_SOF
select SND_SOC_SOF_CLIENT select SND_SOC_SOF_CLIENT
help help
This option enables a separate client device for IPC flood test This option enables a separate client device for IPC flood test
@ -214,6 +215,7 @@ config SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST_NUM
config SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR config SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR
tristate "SOF enable IPC message injector" tristate "SOF enable IPC message injector"
depends on SND_SOC_SOF
select SND_SOC_SOF_CLIENT select SND_SOC_SOF_CLIENT
help help
This option enables the IPC message injector which can be used to send This option enables the IPC message injector which can be used to send

View File

@ -771,7 +771,7 @@ static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget)
goto err; goto err;
ret = sof_update_ipc_object(scomp, src, SOF_SRC_TOKENS, swidget->tuples, ret = sof_update_ipc_object(scomp, src, SOF_SRC_TOKENS, swidget->tuples,
swidget->num_tuples, sizeof(src), 1); swidget->num_tuples, sizeof(*src), 1);
if (ret) { if (ret) {
dev_err(scomp->dev, "Parsing SRC tokens failed\n"); dev_err(scomp->dev, "Parsing SRC tokens failed\n");
goto err; goto err;
@ -1251,7 +1251,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
if (blob->alh_cfg.count > 1) { if (blob->alh_cfg.count > 1) {
int group_id; int group_id;
group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT, group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT - 1,
GFP_KERNEL); GFP_KERNEL);
if (group_id < 0) if (group_id < 0)