mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-29 23:53:32 +00:00
ASoC: Fixes for v6.5
A fairly large collection of fixes here, mostly SOF and Intel related. The one core fix is Hans' change which reduces the log spam when working out new use cases for DPCM. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmTbq9kACgkQJNaLcl1U h9DjOwf+LH6skuS33cgeXKBEWdu5xP1WJ82y7Xjfr+kzecSZSSQEBI1NJgEBHNbk yd4ZnCnTy2/WKdj/IxsuifK8WrqT8jIpWXw25SUeYw+VavgLDXfDZvzmQaO0oigR ACIwhgtJJshlYzNIYvwyL2CMjZPliGEr6LGLA2Da4lxFivo9JFN2imRzS/k5aQ2o YdsVg0xH/TytNUZ//gJh1HaRfOzu1hsqAawzcWnTAEX1EadViZSAFHsdn02VA2Yg gLONXU+w1WrsKkTgUnrnAgnFDvda06KIO17M+bNXkiDZa+wVMJ2Zh8p89j4psHBN d+JpY9PQHcyx0BEufvtCYHsdfAh7cg== =zEhY -----END PGP SIGNATURE----- Merge tag 'asoc-fix-v6.5-rc6' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus ASoC: Fixes for v6.5 A fairly large collection of fixes here, mostly SOF and Intel related. The one core fix is Hans' change which reduces the log spam when working out new use cases for DPCM.
This commit is contained in:
commit
220c8f6713
12 changed files with 73 additions and 35 deletions
|
@ -185,10 +185,10 @@ static int max98363_io_init(struct sdw_slave *slave)
|
||||||
pm_runtime_get_noresume(dev);
|
pm_runtime_get_noresume(dev);
|
||||||
|
|
||||||
ret = regmap_read(max98363->regmap, MAX98363_R21FF_REV_ID, ®);
|
ret = regmap_read(max98363->regmap, MAX98363_R21FF_REV_ID, ®);
|
||||||
if (!ret) {
|
if (!ret)
|
||||||
dev_info(dev, "Revision ID: %X\n", reg);
|
dev_info(dev, "Revision ID: %X\n", reg);
|
||||||
return ret;
|
else
|
||||||
}
|
goto out;
|
||||||
|
|
||||||
if (max98363->first_hw_init) {
|
if (max98363->first_hw_init) {
|
||||||
regcache_cache_bypass(max98363->regmap, false);
|
regcache_cache_bypass(max98363->regmap, false);
|
||||||
|
@ -198,10 +198,11 @@ static int max98363_io_init(struct sdw_slave *slave)
|
||||||
max98363->first_hw_init = true;
|
max98363->first_hw_init = true;
|
||||||
max98363->hw_init = true;
|
max98363->hw_init = true;
|
||||||
|
|
||||||
|
out:
|
||||||
pm_runtime_mark_last_busy(dev);
|
pm_runtime_mark_last_busy(dev);
|
||||||
pm_runtime_put_autosuspend(dev);
|
pm_runtime_put_autosuspend(dev);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX98363_RATES SNDRV_PCM_RATE_8000_192000
|
#define MAX98363_RATES SNDRV_PCM_RATE_8000_192000
|
||||||
|
|
|
@ -52,6 +52,7 @@ static bool rt1308_volatile_register(struct device *dev, unsigned int reg)
|
||||||
case 0x300a:
|
case 0x300a:
|
||||||
case 0xc000:
|
case 0xc000:
|
||||||
case 0xc710:
|
case 0xc710:
|
||||||
|
case 0xcf01:
|
||||||
case 0xc860 ... 0xc863:
|
case 0xc860 ... 0xc863:
|
||||||
case 0xc870 ... 0xc873:
|
case 0xc870 ... 0xc873:
|
||||||
return true;
|
return true;
|
||||||
|
@ -213,7 +214,7 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
|
||||||
{
|
{
|
||||||
struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev);
|
struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned int tmp;
|
unsigned int tmp, hibernation_flag;
|
||||||
|
|
||||||
if (rt1308->hw_init)
|
if (rt1308->hw_init)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -242,6 +243,10 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
|
||||||
|
|
||||||
pm_runtime_get_noresume(&slave->dev);
|
pm_runtime_get_noresume(&slave->dev);
|
||||||
|
|
||||||
|
regmap_read(rt1308->regmap, 0xcf01, &hibernation_flag);
|
||||||
|
if ((hibernation_flag != 0x00) && rt1308->first_hw_init)
|
||||||
|
goto _preset_ready_;
|
||||||
|
|
||||||
/* sw reset */
|
/* sw reset */
|
||||||
regmap_write(rt1308->regmap, RT1308_SDW_RESET, 0);
|
regmap_write(rt1308->regmap, RT1308_SDW_RESET, 0);
|
||||||
|
|
||||||
|
@ -282,6 +287,12 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
|
||||||
regmap_write(rt1308->regmap, 0xc100, 0xd7);
|
regmap_write(rt1308->regmap, 0xc100, 0xd7);
|
||||||
regmap_write(rt1308->regmap, 0xc101, 0xd7);
|
regmap_write(rt1308->regmap, 0xc101, 0xd7);
|
||||||
|
|
||||||
|
/* apply BQ params */
|
||||||
|
rt1308_apply_bq_params(rt1308);
|
||||||
|
|
||||||
|
regmap_write(rt1308->regmap, 0xcf01, 0x01);
|
||||||
|
|
||||||
|
_preset_ready_:
|
||||||
if (rt1308->first_hw_init) {
|
if (rt1308->first_hw_init) {
|
||||||
regcache_cache_bypass(rt1308->regmap, false);
|
regcache_cache_bypass(rt1308->regmap, false);
|
||||||
regcache_mark_dirty(rt1308->regmap);
|
regcache_mark_dirty(rt1308->regmap);
|
||||||
|
|
|
@ -4472,6 +4472,8 @@ static void rt5665_remove(struct snd_soc_component *component)
|
||||||
struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
|
struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
regmap_write(rt5665->regmap, RT5665_RESET, 0);
|
regmap_write(rt5665->regmap, RT5665_RESET, 0);
|
||||||
|
|
||||||
|
regulator_bulk_disable(ARRAY_SIZE(rt5665->supplies), rt5665->supplies);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
|
@ -476,7 +476,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
|
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Lunar Lake Client Platform"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "Lunar Lake Client Platform"),
|
||||||
},
|
},
|
||||||
.driver_data = (void *)(RT711_JD2_100K),
|
.driver_data = (void *)(RT711_JD2),
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
|
@ -99,9 +99,9 @@ static int cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
jack = &ctx->sdw_headset;
|
jack = &ctx->sdw_headset;
|
||||||
|
|
||||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
|
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
|
||||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
|
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
|
||||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
|
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
|
||||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
|
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
|
||||||
|
|
||||||
ret = snd_soc_component_set_jack(component, jack, NULL);
|
ret = snd_soc_component_set_jack(component, jack, NULL);
|
||||||
|
|
||||||
|
|
|
@ -30,27 +30,32 @@ int axg_tdm_formatter_set_channel_masks(struct regmap *map,
|
||||||
struct axg_tdm_stream *ts,
|
struct axg_tdm_stream *ts,
|
||||||
unsigned int offset)
|
unsigned int offset)
|
||||||
{
|
{
|
||||||
unsigned int val, ch = ts->channels;
|
unsigned int ch = ts->channels;
|
||||||
unsigned long mask;
|
u32 val[AXG_TDM_NUM_LANES];
|
||||||
int i, j;
|
int i, j, k;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to mimick the slot distribution used by the HW to keep the
|
||||||
|
* channel placement consistent regardless of the number of channel
|
||||||
|
* in the stream. This is why the odd algorithm below is used.
|
||||||
|
*/
|
||||||
|
memset(val, 0, sizeof(*val) * AXG_TDM_NUM_LANES);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Distribute the channels of the stream over the available slots
|
* Distribute the channels of the stream over the available slots
|
||||||
* of each TDM lane
|
* of each TDM lane. We need to go over the 32 slots ...
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < AXG_TDM_NUM_LANES; i++) {
|
for (i = 0; (i < 32) && ch; i += 2) {
|
||||||
val = 0;
|
/* ... of all the lanes ... */
|
||||||
mask = ts->mask[i];
|
for (j = 0; j < AXG_TDM_NUM_LANES; j++) {
|
||||||
|
/* ... then distribute the channels in pairs */
|
||||||
for (j = find_first_bit(&mask, 32);
|
for (k = 0; k < 2; k++) {
|
||||||
(j < 32) && ch;
|
if ((BIT(i + k) & ts->mask[j]) && ch) {
|
||||||
j = find_next_bit(&mask, 32, j + 1)) {
|
val[j] |= BIT(i + k);
|
||||||
val |= 1 << j;
|
ch -= 1;
|
||||||
ch -= 1;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
regmap_write(map, offset, val);
|
|
||||||
offset += regmap_get_reg_stride(map);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -63,6 +68,11 @@ int axg_tdm_formatter_set_channel_masks(struct regmap *map,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < AXG_TDM_NUM_LANES; i++) {
|
||||||
|
regmap_write(map, offset, val[i]);
|
||||||
|
offset += regmap_get_reg_stride(map);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(axg_tdm_formatter_set_channel_masks);
|
EXPORT_SYMBOL_GPL(axg_tdm_formatter_set_channel_masks);
|
||||||
|
|
|
@ -38,6 +38,7 @@ static inline int _soc_pcm_ret(struct snd_soc_pcm_runtime *rtd,
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case -EPROBE_DEFER:
|
case -EPROBE_DEFER:
|
||||||
case -ENOTSUPP:
|
case -ENOTSUPP:
|
||||||
|
case -EINVAL:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(rtd->dev,
|
dev_err(rtd->dev,
|
||||||
|
@ -2466,8 +2467,11 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream)
|
||||||
|
|
||||||
/* there is no point preparing this FE if there are no BEs */
|
/* there is no point preparing this FE if there are no BEs */
|
||||||
if (list_empty(&fe->dpcm[stream].be_clients)) {
|
if (list_empty(&fe->dpcm[stream].be_clients)) {
|
||||||
dev_err(fe->dev, "ASoC: no backend DAIs enabled for %s\n",
|
/* dev_err_once() for visibility, dev_dbg() for debugging UCM profiles */
|
||||||
fe->dai_link->name);
|
dev_err_once(fe->dev, "ASoC: no backend DAIs enabled for %s, possibly missing ALSA mixer-based routing or UCM profile\n",
|
||||||
|
fe->dai_link->name);
|
||||||
|
dev_dbg(fe->dev, "ASoC: no backend DAIs enabled for %s\n",
|
||||||
|
fe->dai_link->name);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -372,6 +372,7 @@ static const struct hda_dai_widget_dma_ops hda_ipc4_chain_dma_ops = {
|
||||||
static int hda_ipc3_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai,
|
static int hda_ipc3_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai,
|
||||||
struct snd_pcm_substream *substream, int cmd)
|
struct snd_pcm_substream *substream, int cmd)
|
||||||
{
|
{
|
||||||
|
struct hdac_ext_stream *hext_stream = hda_get_hext_stream(sdev, cpu_dai, substream);
|
||||||
struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream);
|
struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream);
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
@ -379,9 +380,17 @@ static int hda_ipc3_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *c
|
||||||
case SNDRV_PCM_TRIGGER_STOP:
|
case SNDRV_PCM_TRIGGER_STOP:
|
||||||
{
|
{
|
||||||
struct snd_sof_dai_config_data data = { 0 };
|
struct snd_sof_dai_config_data data = { 0 };
|
||||||
|
int ret;
|
||||||
|
|
||||||
data.dai_data = DMA_CHAN_INVALID;
|
data.dai_data = DMA_CHAN_INVALID;
|
||||||
return hda_dai_config(w, SOF_DAI_CONFIG_FLAGS_HW_FREE, &data);
|
ret = hda_dai_config(w, SOF_DAI_CONFIG_FLAGS_HW_FREE, &data);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (cmd == SNDRV_PCM_TRIGGER_STOP)
|
||||||
|
return hda_link_dma_cleanup(substream, hext_stream, cpu_dai);
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||||
return hda_dai_config(w, SOF_DAI_CONFIG_FLAGS_PAUSE, NULL);
|
return hda_dai_config(w, SOF_DAI_CONFIG_FLAGS_PAUSE, NULL);
|
||||||
|
|
|
@ -107,9 +107,8 @@ hda_dai_get_ops(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai
|
||||||
return sdai->platform_private;
|
return sdai->platform_private;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hda_link_dma_cleanup(struct snd_pcm_substream *substream,
|
int hda_link_dma_cleanup(struct snd_pcm_substream *substream, struct hdac_ext_stream *hext_stream,
|
||||||
struct hdac_ext_stream *hext_stream,
|
struct snd_soc_dai *cpu_dai)
|
||||||
struct snd_soc_dai *cpu_dai)
|
|
||||||
{
|
{
|
||||||
const struct hda_dai_widget_dma_ops *ops = hda_dai_get_ops(substream, cpu_dai);
|
const struct hda_dai_widget_dma_ops *ops = hda_dai_get_ops(substream, cpu_dai);
|
||||||
struct sof_intel_hda_stream *hda_stream;
|
struct sof_intel_hda_stream *hda_stream;
|
||||||
|
|
|
@ -963,5 +963,7 @@ const struct hda_dai_widget_dma_ops *
|
||||||
hda_select_dai_widget_ops(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget);
|
hda_select_dai_widget_ops(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget);
|
||||||
int hda_dai_config(struct snd_soc_dapm_widget *w, unsigned int flags,
|
int hda_dai_config(struct snd_soc_dapm_widget *w, unsigned int flags,
|
||||||
struct snd_sof_dai_config_data *data);
|
struct snd_sof_dai_config_data *data);
|
||||||
|
int hda_link_dma_cleanup(struct snd_pcm_substream *substream, struct hdac_ext_stream *hext_stream,
|
||||||
|
struct snd_soc_dai *cpu_dai);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1001,7 +1001,7 @@ void sof_ipc3_do_rx_work(struct snd_sof_dev *sdev, struct sof_ipc_cmd_hdr *hdr,
|
||||||
|
|
||||||
ipc3_log_header(sdev->dev, "ipc rx", hdr->cmd);
|
ipc3_log_header(sdev->dev, "ipc rx", hdr->cmd);
|
||||||
|
|
||||||
if (hdr->size < sizeof(hdr) || hdr->size > SOF_IPC_MSG_MAX_SIZE) {
|
if (hdr->size < sizeof(*hdr) || hdr->size > SOF_IPC_MSG_MAX_SIZE) {
|
||||||
dev_err(sdev->dev, "The received message size is invalid: %u\n",
|
dev_err(sdev->dev, "The received message size is invalid: %u\n",
|
||||||
hdr->size);
|
hdr->size);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1731,6 +1731,9 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
|
||||||
|
|
||||||
*ipc_config_size = ipc_size;
|
*ipc_config_size = ipc_size;
|
||||||
|
|
||||||
|
/* update pipeline memory usage */
|
||||||
|
sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config);
|
||||||
|
|
||||||
/* copy IPC data */
|
/* copy IPC data */
|
||||||
memcpy(*ipc_config_data, (void *)copier_data, sizeof(*copier_data));
|
memcpy(*ipc_config_data, (void *)copier_data, sizeof(*copier_data));
|
||||||
if (gtw_cfg_config_length)
|
if (gtw_cfg_config_length)
|
||||||
|
@ -1743,9 +1746,6 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
|
||||||
gtw_cfg_config_length,
|
gtw_cfg_config_length,
|
||||||
&ipc4_copier->dma_config_tlv, dma_config_tlv_size);
|
&ipc4_copier->dma_config_tlv, dma_config_tlv_size);
|
||||||
|
|
||||||
/* update pipeline memory usage */
|
|
||||||
sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue