ALSA: hda - Build PCMs and controls at codec driver probe
authorTakashi Iwai <tiwai@suse.de>
Fri, 27 Feb 2015 19:44:54 +0000 (20:44 +0100)
committerTakashi Iwai <tiwai@suse.de>
Tue, 3 Mar 2015 10:28:36 +0000 (11:28 +0100)
This makes the code flow easier -- instead of the controller driver
calling snd_hda_build_pcms() and snd_hda_build_controls() explicitly,
the codec driver itself builds PCMs and controls at probe time.  Then
the controller driver only needs to call snd_card_register().

Also, this allows us the full bind/unbind control, too.  Even when a
codec driver is bound later, it automatically registers the new PCM
and controls by itself.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/hda_bind.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_tegra.c

index 311896a..a49bc45 100644 (file)
@@ -106,16 +106,28 @@ static int hda_codec_driver_probe(struct device *dev)
        }
 
        err = codec->preset->patch(codec);
-       if (err < 0) {
-               module_put(owner);
-               goto error;
+       if (err < 0)
+               goto error_module;
+
+       err = snd_hda_codec_build_pcms(codec);
+       if (err < 0)
+               goto error_module;
+       err = snd_hda_codec_build_controls(codec);
+       if (err < 0)
+               goto error_module;
+       if (codec->card->registered) {
+               err = snd_card_register(codec->card);
+               if (err < 0)
+                       goto error_module;
        }
 
        return 0;
 
+ error_module:
+       module_put(owner);
+
  error:
-       codec->preset = NULL;
-       memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
+       snd_hda_codec_cleanup_for_unbind(codec);
        return err;
 }
 
index 2c7e481..7085d37 100644 (file)
@@ -4031,36 +4031,6 @@ const struct dev_pm_ops hda_codec_driver_pm = {
                           NULL)
 };
 
-/**
- * snd_hda_build_controls - build mixer controls
- * @bus: the BUS
- *
- * Creates mixer controls for each codec included in the bus.
- *
- * Returns 0 if successful, otherwise a negative error code.
- */
-int snd_hda_build_controls(struct hda_bus *bus)
-{
-       struct hda_codec *codec;
-
-       list_for_each_entry(codec, &bus->codec_list, list) {
-               int err = snd_hda_codec_build_controls(codec);
-               if (err < 0) {
-                       codec_err(codec,
-                                 "cannot build controls for #%d (error %d)\n",
-                                 codec->addr, err);
-                       err = snd_hda_codec_reset(codec);
-                       if (err < 0) {
-                               codec_err(codec,
-                                         "cannot revert codec\n");
-                               return err;
-                       }
-               }
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(snd_hda_build_controls);
-
 /*
  * add standard channel maps if not specified
  */
@@ -4693,43 +4663,6 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
 }
 
 /**
- * snd_hda_build_pcms - build PCM information
- * @bus: the BUS
- *
- * Create PCM information for each codec included in the bus.
- *
- * The build_pcms codec patch is requested to create and assign new
- * hda_pcm objects.  The codec is responsible to call snd_hda_codec_pcm_new()
- * and fills the fields.  Later they are instantiated by this function.
- *
- * At least, substreams, channels_min and channels_max must be filled for
- * each stream.  substreams = 0 indicates that the stream doesn't exist.
- * When rates and/or formats are zero, the supported values are queried
- * from the given nid.  The nid is used also by the default ops.prepare
- * and ops.cleanup callbacks.
- *
- * The driver needs to call ops.open in its open callback.  Similarly,
- * ops.close is supposed to be called in the close callback.
- * ops.prepare should be called in the prepare or hw_params callback
- * with the proper parameters for set up.
- * ops.cleanup should be called in hw_free for clean up of streams.
- *
- * This function returns 0 if successful, or a negative error code.
- */
-int snd_hda_build_pcms(struct hda_bus *bus)
-{
-       struct hda_codec *codec;
-
-       list_for_each_entry(codec, &bus->codec_list, list) {
-               int err = snd_hda_codec_build_pcms(codec);
-               if (err < 0)
-                       return err;
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(snd_hda_build_pcms);
-
-/**
  * snd_hda_add_new_ctls - create controls from the array
  * @codec: the HDA codec
  * @knew: the array of struct snd_kcontrol_new
index fc62ca5..46d253e 100644 (file)
@@ -516,13 +516,11 @@ void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid);
 /*
  * Mixer
  */
-int snd_hda_build_controls(struct hda_bus *bus);
 int snd_hda_codec_build_controls(struct hda_codec *codec);
 
 /*
  * PCM
  */
-int snd_hda_build_pcms(struct hda_bus *bus);
 int snd_hda_codec_parse_pcms(struct hda_codec *codec);
 int snd_hda_codec_build_pcms(struct hda_codec *codec);
 
index f7fb1b5..e81461a 100644 (file)
@@ -1895,16 +1895,6 @@ static int azx_probe_continue(struct azx *chip)
                        goto out_free;
        }
 
-       /* create PCM streams */
-       err = snd_hda_build_pcms(chip->bus);
-       if (err < 0)
-               goto out_free;
-
-       /* create mixer controls */
-       err = snd_hda_build_controls(chip->bus);
-       if (err < 0)
-               goto out_free;
-
        err = snd_card_register(chip->card);
        if (err < 0)
                goto out_free;
index 1359fdd..7586abe 100644 (file)
@@ -497,16 +497,6 @@ static int hda_tegra_probe(struct platform_device *pdev)
        if (err < 0)
                goto out_free;
 
-       /* create PCM streams */
-       err = snd_hda_build_pcms(chip->bus);
-       if (err < 0)
-               goto out_free;
-
-       /* create mixer controls */
-       err = snd_hda_build_controls(chip->bus);
-       if (err < 0)
-               goto out_free;
-
        err = snd_card_register(chip->card);
        if (err < 0)
                goto out_free;