>>>>  static const struct snd_kcontrol_new hdmi_controls[] = {
>>>>    {
>>>>            .access = SNDRV_CTL_ELEM_ACCESS_READ |
>>>> @@ -79,6 +400,17 @@ static const struct snd_kcontrol_new hdmi_controls[] = 
>>>> {
>>>>            .info = hdmi_eld_ctl_info,
>>>>            .get = hdmi_eld_ctl_get,
>>>>    },
>>>> +  {
>>>> +          .access = SNDRV_CTL_ELEM_ACCESS_READ |
>>>> +                    SNDRV_CTL_ELEM_ACCESS_TLV_READ |
>>>> +                    SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK |
>>>> +                    SNDRV_CTL_ELEM_ACCESS_VOLATILE,
>>>> +          .iface = SNDRV_CTL_ELEM_IFACE_PCM,
>>>> +          .name = "Playback Channel Map",
>>>> +          .info = hdmi_codec_chmap_ctl_info,
>>>> +          .get = hdmi_codec_chmap_ctl_get,
>>>> +          .tlv.c = hdmi_codec_chmap_ctl_tlv,
>>>> +  },
>>>>  };
>>>
>>> If you can keep the same interface for applications as
>>> 'snd_pcm_add_chmap_ctls()' have, it's better to integrate the function
>>> to have different tables/callbacks depending on drivers.
>>>
>> I had a look before define it. Unfortunately i cannot use
>> snd_pcm_add_chmap_ctls. snd_pcm_add_chmap_ctls requests "snd_pcm"
>> structure as input param. ASoC codec not aware of it.
>> i could add an helper for ASoC, but hdmi-codec should be used for HDMI
>> drivers and i'm not sure that there is another need in ASoC.
> 
> For example, splitting the function to two parts; one gets the parameter 
> for pcm instance, another deal with adding control element sets. Symbols 
> of both functions are going to be exported and your code can reuse the 
> latter.
> 
> My motivation for this idea is to use the same code for control element 
> sets with the same name of 'Playback Channel Map'. In this case, usage 
> of the same code brings us an merit. We can produce the consist way for 
> applications to handle the control element sets, even if long term 
> development brings much code changes. It has an advantage to reduce 
> maintaining effort.
> 
> This is merely my initial idea. If it's impossible, your idea is preferable.
> 
I checked you proposal. I see 2 blocking points:
- ASoC core set the control private_data field to snd_soc_component so
it is not possible to reuse pcm_chmap_ctl_get/set/tlv that request
snd_pcm_chmap type for the private_data

- The control is a PCM control, so for multi instances it could have to
migrate to the pcm_controls field if following patch is accepted:
[PATCH v5 0/2] ALSA controls management using index/device/sub-devices
fields (http://www.spinics.net/lists/alsa-devel/msg57639.html)
in this case it must be created by the ASoC core and not the driver itself

Alternative could be to treat the control in soc-core:
In soc_link_dai_pcm_controls that is created in patch-set mentioned above.

I have to improve and test it(dirty code for concept...) but this would
be something like that :

static int soc_link_dai_pcm_controls(struct snd_soc_dai **dais, int
num_dais,
                                     struct snd_soc_pcm_runtime *rtd)
{
        struct snd_kcontrol_new kctl;
        int i, j, ret;

        for (i = 0; i < num_dais; ++i) {
                for (j = 0; j < dais[i]->driver->num_pcm_controls; j++) {
                        kctl = dais[i]->driver->pcm_controls[j];

+                       /* TODO test also capture */
+                       if(!strcmp(kctl->name, "Playback Channel Map") {
+                               ret = snd_pcm_add_chmap_ctls(rtd->pcm,
+                                 SNDRV_PCM_STREAM_PLAYBACK,
+                                 /* Not very clean: chmap pointer is stored in 
private_value */
+                                 (const struct snd_pcm_chmap_elem *) 
kctl.private_value,
+                                 dai->driver->playback.max_channels,
+                                 0, NULL);
+                               continue;
+                       }
                        if (kctl.iface != SNDRV_CTL_ELEM_IFACE_PCM ||
                            rtd->dai_link->no_pcm) {
                                dev_err(dais[i]->dev,
                                        "ASoC: Failed to bind %s control: %s\n",
                                        dais[i]->name, kctl.name);
                                return -EINVAL;
                        }
Regards
Arnaud

Reply via email to