diff options
Diffstat (limited to 'sound/soc/soc-topology.c')
-rw-r--r-- | sound/soc/soc-topology.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 5b60379237bf..c5ef432a023b 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -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++) { @@ -603,10 +614,11 @@ static int soc_tplg_kcontrol_bind_io(struct snd_soc_tplg_ctl_hdr *hdr, sbe->get = ext_ops[i].get; } - if (sbe->put && sbe->get) - return 0; - else + if ((k->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) && !sbe->get) + return -EINVAL; + if ((k->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) && !sbe->put) return -EINVAL; + return 0; } /* try and map vendor specific kcontrol handlers first */ |