ALSA: hda - Split snd_hda_build_pcms()
authorTakashi Iwai <tiwai@suse.de>
Tue, 24 Feb 2015 10:50:11 +0000 (11:50 +0100)
committerTakashi Iwai <tiwai@suse.de>
Tue, 3 Mar 2015 10:25:15 +0000 (11:25 +0100)
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>
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h

index db86b446743c9173fba0dfcc1927e7b288730740..40300fcc5308912108e840b57503352149a00b9b 100644 (file)
@@ -4569,71 +4569,87 @@ 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 (snd_BUG_ON(!pcm->name))
-               return -EINVAL;
-       for (stream = 0; stream < 2; stream++) {
-               info = &pcm->stream[stream];
-               if (info->substreams) {
+       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;
+
+               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);
-                       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 (err < 0) {
-                               codec_err(codec,
-                                         "cannot revert codec\n");
-                               return err;
-                       }
-               }
+       if (snd_BUG_ON(!bus->ops.attach_pcm))
+               return -EINVAL;
+
+       err = snd_hda_codec_parse_pcms(codec);
+       if (err < 0) {
+               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);
-                       if (dev < 0)
-                               continue; /* no fatal error */
-                       cpcm->device = dev;
-                       err = snd_hda_attach_pcm(codec, cpcm);
-                       if (err < 0) {
-                               codec_err(codec,
-                                         "cannot attach PCM stream %d for codec #%d\n",
-                                         dev, codec->addr);
-                               continue; /* no fatal error */
-                       }
+               dev = get_empty_pcm_device(bus, cpcm->pcm_type);
+               if (dev < 0)
+                       continue; /* no fatal error */
+               cpcm->device = dev;
+               err =  bus->ops.attach_pcm(bus, codec, cpcm);
+               if (err < 0) {
+                       codec_err(codec,
+                                 "cannot attach PCM stream %d for codec #%d\n",
+                                 dev, codec->addr);
+                       continue; /* no fatal error */
                }
        }
+
        return 0;
 }
 
index 457fc589eb469d5f5c07d8176491697daa2ab0ff..8cf70369cd101625261e44819ba75bb37b11b371 100644 (file)
@@ -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,