Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bcd96557 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

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: default avatarTakashi Iwai <tiwai@suse.de>
parent 9a6246ff
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -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;
}

+0 −67
Original line number Diff line number Diff line
@@ -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
 */
@@ -4692,43 +4662,6 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
	return 0;
}

/**
 * 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
+0 −2
Original line number Diff line number Diff line
@@ -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);

+0 −10
Original line number Diff line number Diff line
@@ -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;
+0 −10
Original line number Diff line number Diff line
@@ -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;