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: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2015-02-24 11:50:11 +01:00
parent 820cc6cf2c
commit 1a4ba30cce
2 changed files with 60 additions and 43 deletions

View File

@ -4569,71 +4569,87 @@ static int get_empty_pcm_device(struct hda_bus *bus, unsigned int type)
return -EAGAIN; return -EAGAIN;
} }
/* /* call build_pcms ops of the given codec and set up the default parameters */
* attach a new PCM stream int snd_hda_codec_parse_pcms(struct hda_codec *codec)
*/
static int snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
{ {
struct hda_bus *bus = codec->bus; unsigned int pcm;
struct hda_pcm_stream *info; int err;
int stream, err;
if (snd_BUG_ON(!pcm->name)) if (codec->num_pcms)
return -EINVAL; return 0; /* already parsed */
for (stream = 0; stream < 2; stream++) {
info = &pcm->stream[stream]; if (!codec->patch_ops.build_pcms)
if (info->substreams) { 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;
for (stream = 0; stream < 2; stream++) {
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); 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 err;
}
} }
} }
return bus->ops.attach_pcm(bus, codec, pcm);
return 0;
} }
/* assign all PCMs of the given codec */ /* assign all PCMs of the given codec */
int snd_hda_codec_build_pcms(struct hda_codec *codec) int snd_hda_codec_build_pcms(struct hda_codec *codec)
{ {
struct hda_bus *bus = codec->bus;
unsigned int pcm; unsigned int pcm;
int err; int dev, err;
if (!codec->num_pcms) { if (snd_BUG_ON(!bus->ops.attach_pcm))
if (!codec->patch_ops.build_pcms) return -EINVAL;
return 0;
err = codec->patch_ops.build_pcms(codec); err = snd_hda_codec_parse_pcms(codec);
if (err < 0) { if (err < 0) {
codec_err(codec, snd_hda_codec_reset(codec);
"cannot build PCMs for #%d (error %d)\n", return err;
codec->addr, err);
err = snd_hda_codec_reset(codec);
if (err < 0) {
codec_err(codec,
"cannot revert codec\n");
return err;
}
}
} }
/* attach a new PCM streams */
for (pcm = 0; pcm < codec->num_pcms; pcm++) { for (pcm = 0; pcm < codec->num_pcms; pcm++) {
struct hda_pcm *cpcm = &codec->pcm_info[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) if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
continue; /* no substreams assigned */ continue; /* no substreams assigned */
if (!cpcm->pcm) { dev = get_empty_pcm_device(bus, cpcm->pcm_type);
dev = get_empty_pcm_device(codec->bus, cpcm->pcm_type); if (dev < 0)
if (dev < 0) continue; /* no fatal error */
continue; /* no fatal error */ cpcm->device = dev;
cpcm->device = dev; err = bus->ops.attach_pcm(bus, codec, cpcm);
err = snd_hda_attach_pcm(codec, cpcm); if (err < 0) {
if (err < 0) { codec_err(codec,
codec_err(codec, "cannot attach PCM stream %d for codec #%d\n",
"cannot attach PCM stream %d for codec #%d\n", dev, codec->addr);
dev, codec->addr); continue; /* no fatal error */
continue; /* no fatal error */
}
} }
} }
return 0; return 0;
} }

View File

@ -517,6 +517,7 @@ int snd_hda_codec_build_controls(struct hda_codec *codec);
* PCM * PCM
*/ */
int snd_hda_build_pcms(struct hda_bus *bus); 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_build_pcms(struct hda_codec *codec);
int snd_hda_codec_prepare(struct hda_codec *codec, int snd_hda_codec_prepare(struct hda_codec *codec,