Skip to content

Commit 2d744ec

Browse files
Mateusz Gorskibroonie
authored andcommitted
ASoC: Intel: Skylake: Automatic DMIC format configuration according to information from NHLT
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>
1 parent 1b45079 commit 2d744ec

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

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)