Skip to content

Commit cd73439

Browse files
Mateusz Gorskigregkh
authored andcommitted
ASoC: Intel: Skylake: Automatic DMIC format configuration according to information from NHLT
commit 2d744ec upstream. Automatically choose DMIC pipeline format configuration depending on information included in NHLT. Change the access rights of appropriate kcontrols to read-only in order to prevent user interference. Signed-off-by: Mateusz Gorski <mateusz.gorski@linux.intel.com> Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20200427132727.24942-4-mateusz.gorski@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> Cc: <stable@vger.kernel.org> # 5.4.x Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 6ebb6af commit cd73439

2 files changed

Lines changed: 62 additions & 3 deletions

File tree

include/uapi/sound/skl-tplg-interface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define SKL_CONTROL_TYPE_BYTE_TLV 0x100
2020
#define SKL_CONTROL_TYPE_MIC_SELECT 0x102
2121
#define SKL_CONTROL_TYPE_MULTI_IO_SELECT 0x103
22+
#define SKL_CONTROL_TYPE_MULTI_IO_SELECT_DMIC 0x104
2223

2324
#define HDA_SST_CFG_MAX 900 /* size of copier cfg*/
2425
#define MAX_IN_QUEUE 8

sound/soc/intel/skylake/skl-topology.c

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,6 +1405,18 @@ static int skl_tplg_multi_config_set(struct snd_kcontrol *kcontrol,
14051405
return skl_tplg_multi_config_set_get(kcontrol, ucontrol, true);
14061406
}
14071407

1408+
static int skl_tplg_multi_config_get_dmic(struct snd_kcontrol *kcontrol,
1409+
struct snd_ctl_elem_value *ucontrol)
1410+
{
1411+
return skl_tplg_multi_config_set_get(kcontrol, ucontrol, false);
1412+
}
1413+
1414+
static int skl_tplg_multi_config_set_dmic(struct snd_kcontrol *kcontrol,
1415+
struct snd_ctl_elem_value *ucontrol)
1416+
{
1417+
return skl_tplg_multi_config_set_get(kcontrol, ucontrol, true);
1418+
}
1419+
14081420
static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol,
14091421
unsigned int __user *data, unsigned int size)
14101422
{
@@ -1949,6 +1961,11 @@ static const struct snd_soc_tplg_kcontrol_ops skl_tplg_kcontrol_ops[] = {
19491961
.get = skl_tplg_multi_config_get,
19501962
.put = skl_tplg_multi_config_set,
19511963
},
1964+
{
1965+
.id = SKL_CONTROL_TYPE_MULTI_IO_SELECT_DMIC,
1966+
.get = skl_tplg_multi_config_get_dmic,
1967+
.put = skl_tplg_multi_config_set_dmic,
1968+
}
19521969
};
19531970

19541971
static int skl_tplg_fill_pipe_cfg(struct device *dev,
@@ -3109,12 +3126,21 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
31093126
case SND_SOC_TPLG_CTL_ENUM:
31103127
tplg_ec = container_of(hdr,
31113128
struct snd_soc_tplg_enum_control, hdr);
3112-
if (kctl->access & SNDRV_CTL_ELEM_ACCESS_READWRITE) {
3129+
if (kctl->access & SNDRV_CTL_ELEM_ACCESS_READ) {
31133130
se = (struct soc_enum *)kctl->private_value;
31143131
if (tplg_ec->priv.size)
3115-
return skl_init_enum_data(bus->dev, se,
3116-
tplg_ec);
3132+
skl_init_enum_data(bus->dev, se, tplg_ec);
31173133
}
3134+
3135+
/*
3136+
* now that the control initializations are done, remove
3137+
* write permission for the DMIC configuration enums to
3138+
* avoid conflicts between NHLT settings and user interaction
3139+
*/
3140+
3141+
if (hdr->ops.get == SKL_CONTROL_TYPE_MULTI_IO_SELECT_DMIC)
3142+
kctl->access = SNDRV_CTL_ELEM_ACCESS_READ;
3143+
31183144
break;
31193145

31203146
default:
@@ -3584,6 +3610,37 @@ static int skl_manifest_load(struct snd_soc_component *cmpnt, int index,
35843610
return 0;
35853611
}
35863612

3613+
static void skl_tplg_complete(struct snd_soc_component *component)
3614+
{
3615+
struct snd_soc_dobj *dobj;
3616+
struct snd_soc_acpi_mach *mach =
3617+
dev_get_platdata(component->card->dev);
3618+
int i;
3619+
3620+
list_for_each_entry(dobj, &component->dobj_list, list) {
3621+
struct snd_kcontrol *kcontrol = dobj->control.kcontrol;
3622+
struct soc_enum *se =
3623+
(struct soc_enum *)kcontrol->private_value;
3624+
char **texts = dobj->control.dtexts;
3625+
char chan_text[4];
3626+
3627+
if (dobj->type != SND_SOC_DOBJ_ENUM ||
3628+
dobj->control.kcontrol->put !=
3629+
skl_tplg_multi_config_set_dmic)
3630+
continue;
3631+
sprintf(chan_text, "c%d", mach->mach_params.dmic_num);
3632+
3633+
for (i = 0; i < se->items; i++) {
3634+
struct snd_ctl_elem_value val;
3635+
3636+
if (strstr(texts[i], chan_text)) {
3637+
val.value.enumerated.item[0] = i;
3638+
kcontrol->put(kcontrol, &val);
3639+
}
3640+
}
3641+
}
3642+
}
3643+
35873644
static struct snd_soc_tplg_ops skl_tplg_ops = {
35883645
.widget_load = skl_tplg_widget_load,
35893646
.control_load = skl_tplg_control_load,
@@ -3593,6 +3650,7 @@ static struct snd_soc_tplg_ops skl_tplg_ops = {
35933650
.io_ops_count = ARRAY_SIZE(skl_tplg_kcontrol_ops),
35943651
.manifest = skl_manifest_load,
35953652
.dai_load = skl_dai_load,
3653+
.complete = skl_tplg_complete,
35963654
};
35973655

35983656
/*

0 commit comments

Comments
 (0)