summaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-02-27 20:44:54 +0100
committerTakashi Iwai <tiwai@suse.de>2015-03-03 11:28:36 +0100
commitbcd96557bd0ab1129fcdde073d5700aed8fcb942 (patch)
tree8f246b3fc0b986ba9d105f632aa7cef485123825 /sound/pci
parentALSA: hda - Implement unbind more safely (diff)
downloadlinux-bcd96557bd0ab1129fcdde073d5700aed8fcb942.tar.xz
linux-bcd96557bd0ab1129fcdde073d5700aed8fcb942.zip
ALSA: hda - Build PCMs and controls at codec driver probe
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>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_bind.c22
-rw-r--r--sound/pci/hda/hda_codec.c67
-rw-r--r--sound/pci/hda/hda_codec.h2
-rw-r--r--sound/pci/hda/hda_intel.c10
-rw-r--r--sound/pci/hda/hda_tegra.c10
5 files changed, 17 insertions, 94 deletions
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c
index 311896a23cd1..a49bc45c2ea5 100644
--- a/sound/pci/hda/hda_bind.c
+++ b/sound/pci/hda/hda_bind.c
@@ -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;
}
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 2c7e481a9171..7085d3733d0d 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -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
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index fc62ca51fd35..46d253e2f266 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -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);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index f7fb1b51d446..e81461a413b8 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -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;
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index 1359fdd20f02..7586abe91dfb 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -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;