[alsa-devel] [RFC v2 00/11] Enable HDA Codec support on Intel Platforms (Series2)

Takashi Iwai tiwai at suse.de
Tue Dec 12 17:50:59 CET 2017


On Tue, 12 Dec 2017 17:37:56 +0100,
Ughreja, Rakesh A wrote:
> 
> 
> 
> >-----Original Message-----
> >From: Takashi Iwai [mailto:tiwai at suse.de]
> >Sent: Tuesday, December 12, 2017 12:19 AM
> >To: Ughreja, Rakesh A <rakesh.a.ughreja at intel.com>
> >Cc: alsa-devel at alsa-project.org; broonie at kernel.org;
> >liam.r.girdwood at linux.intel.com; pierre-louis.bossart at linux.intel.com; Koul,
> >Vinod <vinod.koul at intel.com>; Patches Audio <patches.audio at intel.com>
> >Subject: Re: [RFC v2 00/11] Enable HDA Codec support on Intel Platforms
> >(Series2)
> 
> >
> >The registration should be triggered from the top-level, i.e. the
> >controller driver, once after all codecs get probed.  Otherwise, it
> >becomes racy.  The user-space will start poking the device before all
> >the stuff becomes ready.
> 
> Thank you very much, I understand now.
> 
> >
> >That said, at the point when the codec is probed, the card shouldn't
> >be registered yet.  The card gets registered after the all components
> >are bound and become ready -- which is done a single
> >snd_card_register() call.  At this point, the access points to
> >user-space are provided.
> 
> So based on your suggestion when I relooked at the code, I could
> remove the new function that I added. I could completely reuse the 
> existing function with little change.
> 
> Does it look okay ?

Lesser, better :)


> Following is the patch, which I tested and it works for me.
> I will include this in next series but for now it's only for quick reference.
> 
> I am calling this API from the hdac_hda codec driver with argument
> HDA_DEV_ASOC to make sure that it does not register with the bus
> again. I am not able to call this API from ASoC Platform driver because
> I don't have snd_card pointer at the time of machine driver probe.
> 
> Following is the patch. 
> ---------------------------
> Modify snd_hda_codec_new API so that it can work for legacy as well as
> ASoC codec drivers. The API takes an additional argument dev_type as
> HDA_DEV_LEGACY or HDA_DEV_ASOC to distinguish the caller.

The idea looks good, but I'd prefer different functions instead of
mutating the behavior depending on the flag.  i.e. keep
snd_hda_codec_new(), and introduce another API (snd_hda_codec_init()
or whatever).  ASoC driver can call the latter while the legacy driver
keeps calling the former.

This would factor out the allocation and snd_hdac_device_init() calls
from the old snd_hda_codec_new() to a new snd_hda_codec_new().
snd_hda_codec_init() would do the rest.  snd_hda_codec_new() calls
snd_hda_codec_init() at the end of the function.

Does this sound good for you?


thanks,

Takashi

> 
> Signed-off-by: Rakesh Ughreja <rakesh.a.ughreja at intel.com>
> ---
>  sound/pci/hda/hda_codec.c      | 30 +++++++++++++++++++-----------
>  sound/pci/hda/hda_codec.h      |  3 ++-
>  sound/pci/hda/hda_controller.c |  2 +-
>  3 files changed, 22 insertions(+), 13 deletions(-)
> 
> diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
> index 085fd9e..252779c 100644
> --- a/sound/pci/hda/hda_codec.c
> +++ b/sound/pci/hda/hda_codec.c
> @@ -865,7 +865,8 @@ static void snd_hda_codec_dev_release(struct device *dev)
>   * Returns 0 if successful, or a negative error code.
>   */
>  int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
> -		      unsigned int codec_addr, struct hda_codec **codecp)
> +		      unsigned int codec_addr, struct hda_codec **codecp,
> +			unsigned int dev_type)
>  {
>  	struct hda_codec *codec;
>  	char component[31];
> @@ -882,20 +883,27 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
>  	if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
>  		return -EINVAL;
>  
> -	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
> -	if (!codec)
> -		return -ENOMEM;
> +	if (dev_type == HDA_DEV_LEGACY) {
>  
> -	sprintf(component, "hdaudioC%dD%d", card->number, codec_addr);
> -	err = snd_hdac_device_init(&codec->core, &bus->core, component,
> -				   codec_addr);
> -	if (err < 0) {
> -		kfree(codec);
> -		return err;
> +		codec = kzalloc(sizeof(*codec), GFP_KERNEL);
> +		if (!codec)
> +			return -ENOMEM;
> +
> +		sprintf(component, "hdaudioC%dD%d", card->number, codec_addr);
> +		err = snd_hdac_device_init(&codec->core, &bus->core, component,
> +						codec_addr);
> +		if (err < 0) {
> +			kfree(codec);
> +			return err;
> +		}
> +
> +		codec->core.type = HDA_DEV_LEGACY;
> +
> +	} else {
> +		codec = *codecp;
>  	}
>  
>  	codec->core.dev.release = snd_hda_codec_dev_release;
> -	codec->core.type = HDA_DEV_LEGACY;
>  	codec->core.exec_verb = codec_exec_verb;
>  
>  	codec->bus = bus;
> diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
> index d3099db..92815b7 100644
> --- a/sound/pci/hda/hda_codec.h
> +++ b/sound/pci/hda/hda_codec.h
> @@ -306,7 +306,8 @@ struct hda_codec {
>   * constructors
>   */
>  int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
> -		      unsigned int codec_addr, struct hda_codec **codecp);
> +			unsigned int codec_addr, struct hda_codec **codecp,
> +			unsigned int dev_type);
>  int snd_hda_codec_configure(struct hda_codec *codec);
>  int snd_hda_codec_update_widgets(struct hda_codec *codec);
>  
> diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
> index d1eb148..ec887d7 100644
> --- a/sound/pci/hda/hda_controller.c
> +++ b/sound/pci/hda/hda_controller.c
> @@ -1318,7 +1318,7 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots)
>  	for (c = 0; c < max_slots; c++) {
>  		if ((bus->codec_mask & (1 << c)) & chip->codec_probe_mask) {
>  			struct hda_codec *codec;
> -			err = snd_hda_codec_new(&chip->bus, chip->card, c, &codec);
> +			err = snd_hda_codec_new(&chip->bus, chip->card, c, &codec, HDA_DEV_LEGACY);
>  			if (err < 0)
>  				continue;
>  			codec->jackpoll_interval = get_jackpoll_interval(chip);
> -- 
> 2.7.4
> 


More information about the Alsa-devel mailing list