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.
Unified · Split
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #define SKL_CONTROL_TYPE_BYTE_TLV 0x100 | 19 | #define SKL_CONTROL_TYPE_BYTE_TLV 0x100 |
| 20 | #define SKL_CONTROL_TYPE_MIC_SELECT 0x102 | 20 | #define SKL_CONTROL_TYPE_MIC_SELECT 0x102 |
| 21 | #define SKL_CONTROL_TYPE_MULTI_IO_SELECT 0x103 | 21 | #define SKL_CONTROL_TYPE_MULTI_IO_SELECT 0x103 |
| 22 | #define SKL_CONTROL_TYPE_MULTI_IO_SELECT_DMIC 0x104 | ||
| 22 | 23 | ||
| 23 | #define HDA_SST_CFG_MAX 900 /* size of copier cfg*/ | 24 | #define HDA_SST_CFG_MAX 900 /* size of copier cfg*/ |
| 24 | #define MAX_IN_QUEUE 8 | 25 | #define MAX_IN_QUEUE 8 |
| @@ -1405,6 +1405,18 @@ static int skl_tplg_multi_config_set(struct snd_kcontrol *kcontrol, · 1404 unmodified lines | |||
| 1405 | return skl_tplg_multi_config_set_get(kcontrol, ucontrol, true); | 1405 | return skl_tplg_multi_config_set_get(kcontrol, ucontrol, true); |
| 1406 | } | 1406 | } |
| 1407 | 1407 | ||
| 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 | |||
| 1408 | static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol, | 1420 | static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol, |
| 1409 | unsigned int __user *data, unsigned int size) | 1421 | unsigned int __user *data, unsigned int size) |
| 1410 | { | 1422 | { |
| @@ -1949,6 +1961,11 @@ static const struct snd_soc_tplg_kcontrol_ops skl_tplg_kcontrol_ops[] = { · 538 unmodified lines | |||
| 1949 | .get = skl_tplg_multi_config_get, | 1961 | .get = skl_tplg_multi_config_get, |
| 1950 | .put = skl_tplg_multi_config_set, | 1962 | .put = skl_tplg_multi_config_set, |
| 1951 | }, | 1963 | }, |
| 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 | } | ||
| 1952 | }; | 1969 | }; |
| 1953 | 1970 | ||
| 1954 | static int skl_tplg_fill_pipe_cfg(struct device *dev, | 1971 | 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, · 1154 unmodified lines | |||
| 3109 | case SND_SOC_TPLG_CTL_ENUM: | 3126 | case SND_SOC_TPLG_CTL_ENUM: |
| 3110 | tplg_ec = container_of(hdr, | 3127 | tplg_ec = container_of(hdr, |
| 3111 | struct snd_soc_tplg_enum_control, hdr); | 3128 | 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) { |
| 3113 | se = (struct soc_enum *)kctl->private_value; | 3130 | se = (struct soc_enum *)kctl->private_value; |
| 3114 | if (tplg_ec->priv.size) | 3131 | if (tplg_ec->priv.size) |
| 3115 | return skl_init_enum_data(bus->dev, se, | 3132 | skl_init_enum_data(bus->dev, se, tplg_ec); |
| 3116 | tplg_ec); | ||
| 3117 | } | 3133 | } |
| 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 | |||
| 3118 | break; | 3144 | break; |
| 3119 | 3145 | ||
| 3120 | default: | 3146 | default: |
| @@ -3584,6 +3610,37 @@ static int skl_manifest_load(struct snd_soc_component *cmpnt, int index, · 463 unmodified lines | |||
| 3584 | return 0; | 3610 | return 0; |
| 3585 | } | 3611 | } |
| 3586 | 3612 | ||
| 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 | |||
| 3587 | static struct snd_soc_tplg_ops skl_tplg_ops = { | 3644 | static struct snd_soc_tplg_ops skl_tplg_ops = { |
| 3588 | .widget_load = skl_tplg_widget_load, | 3645 | .widget_load = skl_tplg_widget_load, |
| 3589 | .control_load = skl_tplg_control_load, | 3646 | .control_load = skl_tplg_control_load, |
| @@ -3593,6 +3650,7 @@ static struct snd_soc_tplg_ops skl_tplg_ops = { · 3 unmodified lines | |||
| 3593 | .io_ops_count = ARRAY_SIZE(skl_tplg_kcontrol_ops), | 3650 | .io_ops_count = ARRAY_SIZE(skl_tplg_kcontrol_ops), |
| 3594 | .manifest = skl_manifest_load, | 3651 | .manifest = skl_manifest_load, |
| 3595 | .dai_load = skl_dai_load, | 3652 | .dai_load = skl_dai_load, |
| 3653 | .complete = skl_tplg_complete, | ||
| 3596 | }; | 3654 | }; |
| 3597 | 3655 | ||
| 3598 | /* | 3656 | /* |