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

Commit 1a4ba30c authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: hda - Split snd_hda_build_pcms()



snd_hda_build_pcms() does actually three things: let the codec driver
build up hda_pcm list, set the PCM default values, and call the
attach_pcm bus ops for each hda_pcm instance.  The former two are
basically independent from the bus implementation, so it'd make the
code a bit more readable.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 820cc6cf
Loading
Loading
Loading
Loading
+59 −43
Original line number Diff line number Diff line
@@ -4569,63 +4569,79 @@ static int get_empty_pcm_device(struct hda_bus *bus, unsigned int type)
	return -EAGAIN;
}

/*
 * attach a new PCM stream
 */
static int snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
/* call build_pcms ops of the given codec and set up the default parameters */
int snd_hda_codec_parse_pcms(struct hda_codec *codec)
{
	struct hda_bus *bus = codec->bus;
	struct hda_pcm_stream *info;
	int stream, err;
	unsigned int pcm;
	int err;

	if (codec->num_pcms)
		return 0; /* already parsed */

	if (!codec->patch_ops.build_pcms)
		return 0;

	err = codec->patch_ops.build_pcms(codec);
	if (err < 0) {
		codec_err(codec, "cannot build PCMs for #%d (error %d)\n",
			  codec->addr, err);
		return err;
	}

	for (pcm = 0; pcm < codec->num_pcms; pcm++) {
		struct hda_pcm *cpcm = &codec->pcm_info[pcm];
		int stream;

	if (snd_BUG_ON(!pcm->name))
		return -EINVAL;
		for (stream = 0; stream < 2; stream++) {
		info = &pcm->stream[stream];
		if (info->substreams) {
			struct hda_pcm_stream *info = &cpcm->stream[stream];

			if (!info->substreams)
				continue;
			if (snd_BUG_ON(!cpcm->name))
				return -EINVAL;
			err = set_pcm_default_values(codec, info);
			if (err < 0)
			if (err < 0) {
				codec_warn(codec,
					   "fail to setup default for PCM %s\n",
					   cpcm->name);
				return err;
			}
		}
	return bus->ops.attach_pcm(bus, codec, pcm);
	}

	return 0;
}

/* assign all PCMs of the given codec */
int snd_hda_codec_build_pcms(struct hda_codec *codec)
{
	struct hda_bus *bus = codec->bus;
	unsigned int pcm;
	int err;
	int dev, err;

	if (!codec->num_pcms) {
		if (!codec->patch_ops.build_pcms)
			return 0;
		err = codec->patch_ops.build_pcms(codec);
		if (err < 0) {
			codec_err(codec,
				  "cannot build PCMs for #%d (error %d)\n",
				  codec->addr, err);
			err = snd_hda_codec_reset(codec);
	if (snd_BUG_ON(!bus->ops.attach_pcm))
		return -EINVAL;

	err = snd_hda_codec_parse_pcms(codec);
	if (err < 0) {
				codec_err(codec,
					  "cannot revert codec\n");
		snd_hda_codec_reset(codec);
		return err;
	}
		}
	}

	/* attach a new PCM streams */
	for (pcm = 0; pcm < codec->num_pcms; pcm++) {
		struct hda_pcm *cpcm = &codec->pcm_info[pcm];
		int dev;

		if (cpcm->pcm)
			continue; /* already attached */
		if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
			continue; /* no substreams assigned */

		if (!cpcm->pcm) {
			dev = get_empty_pcm_device(codec->bus, cpcm->pcm_type);
		dev = get_empty_pcm_device(bus, cpcm->pcm_type);
		if (dev < 0)
			continue; /* no fatal error */
		cpcm->device = dev;
			err = snd_hda_attach_pcm(codec, cpcm);
		err =  bus->ops.attach_pcm(bus, codec, cpcm);
		if (err < 0) {
			codec_err(codec,
				  "cannot attach PCM stream %d for codec #%d\n",
@@ -4633,7 +4649,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
			continue; /* no fatal error */
		}
	}
	}

	return 0;
}

+1 −0
Original line number Diff line number Diff line
@@ -517,6 +517,7 @@ 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);

int snd_hda_codec_prepare(struct hda_codec *codec,