ALSA: ctxfi - Clear PCM resources at hw_params and hw_free
authorTakashi Iwai <tiwai@suse.de>
Tue, 9 Jun 2009 06:19:02 +0000 (08:19 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 9 Jun 2009 06:19:02 +0000 (08:19 +0200)
Currently the PCM resources are allocated only once and ever in prepare
callback, assuming that the PCM parameters are never changed.  But it's
not true.

This patch adds the call of atc->pcm_release_resources() at hw_params
and hw_free callbacks to assure that the PCM setup is done correctly
for each h/w parameter changes.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/ctxfi/ctatc.c
sound/pci/ctxfi/ctpcm.c

index e54006ef83cf2c743265ce356f744b5c67e40285..80fb2baed7a72c52ea9330336039bfe0835c621a 100644 (file)
@@ -523,7 +523,7 @@ atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
        struct src_node_conf_t src_node_conf[2] = {{0} };
 
        /* first release old resources */
        struct src_node_conf_t src_node_conf[2] = {{0} };
 
        /* first release old resources */
-       atc->pcm_release_resources(atc, apcm);
+       atc_pcm_release_resources(atc, apcm);
 
        /* The numbers of converting SRCs and SRCIMPs should be determined
         * by pitch value. */
 
        /* The numbers of converting SRCs and SRCIMPs should be determined
         * by pitch value. */
@@ -802,7 +802,7 @@ static int spdif_passthru_playback_get_resources(struct ct_atc *atc,
        unsigned int pitch, rsr = atc->pll_rate;
 
        /* first release old resources */
        unsigned int pitch, rsr = atc->pll_rate;
 
        /* first release old resources */
-       atc->pcm_release_resources(atc, apcm);
+       atc_pcm_release_resources(atc, apcm);
 
        /* Get SRC resource */
        desc.multi = apcm->substream->runtime->channels;
 
        /* Get SRC resource */
        desc.multi = apcm->substream->runtime->channels;
index 870fa170f046ab632abe9cd2ee40562f87b69b43..9e5c0c4da7261166faa9659bbef57fd35f90c678 100644 (file)
@@ -176,12 +176,26 @@ static int ct_pcm_playback_close(struct snd_pcm_substream *substream)
 static int ct_pcm_hw_params(struct snd_pcm_substream *substream,
                                     struct snd_pcm_hw_params *hw_params)
 {
 static int ct_pcm_hw_params(struct snd_pcm_substream *substream,
                                     struct snd_pcm_hw_params *hw_params)
 {
-       return snd_pcm_lib_malloc_pages(substream,
+       struct ct_atc *atc = snd_pcm_substream_chip(substream);
+       struct ct_atc_pcm *apcm = substream->runtime->private_data;
+       int err;
+
+       err = snd_pcm_lib_malloc_pages(substream,
                                        params_buffer_bytes(hw_params));
                                        params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
+       /* clear previous resources */
+       atc->pcm_release_resources(atc, apcm);
+       return err;
 }
 
 static int ct_pcm_hw_free(struct snd_pcm_substream *substream)
 {
 }
 
 static int ct_pcm_hw_free(struct snd_pcm_substream *substream)
 {
+       struct ct_atc *atc = snd_pcm_substream_chip(substream);
+       struct ct_atc_pcm *apcm = substream->runtime->private_data;
+
+       /* clear previous resources */
+       atc->pcm_release_resources(atc, apcm);
        /* Free snd-allocated pages */
        return snd_pcm_lib_free_pages(substream);
 }
        /* Free snd-allocated pages */
        return snd_pcm_lib_free_pages(substream);
 }