Update of /cvsroot/alsa/alsa-kernel/pci
In directory sc8-pr-cvs1:/tmp/cvs-serv2213

Modified Files:
        cmipci.c 
Log Message:
- fixed multi-channel playback.  now channel B is used for that.
- check the devices for multi-channel playback.  both channels are
  necessary.
- fixed the configuration of period size.



Index: cmipci.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/cmipci.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -r1.41 -r1.42
--- cmipci.c    24 Jan 2003 11:19:51 -0000      1.41
+++ cmipci.c    29 Jan 2003 17:01:43 -0000      1.42
@@ -372,8 +372,10 @@
 #define CM_OPEN_DAC    0x10
 #define CM_OPEN_ADC    0x20
 #define CM_OPEN_SPDIF  0x40
+#define CM_OPEN_MCHAN  0x80
 #define CM_OPEN_PLAYBACK       (CM_CH_PLAY | CM_OPEN_DAC)
 #define CM_OPEN_PLAYBACK2      (CM_CH_CAPT | CM_OPEN_DAC)
+#define CM_OPEN_PLAYBACK_MULTI (CM_CH_PLAY | CM_OPEN_DAC | CM_OPEN_MCHAN)
 #define CM_OPEN_CAPTURE                (CM_CH_CAPT | CM_OPEN_ADC)
 #define CM_OPEN_SPDIF_PLAYBACK (CM_CH_PLAY | CM_OPEN_DAC | CM_OPEN_SPDIF)
 #define CM_OPEN_SPDIF_CAPTURE  (CM_CH_CAPT | CM_OPEN_ADC | CM_OPEN_SPDIF)
@@ -425,7 +427,7 @@
        // {"IEC958 Out To DAC", 1}, // no longer used
        {"IEC958 Loop", 0},
 };
-#define CM_SAVED_MIXERS                
(sizeof(cm_saved_mixer)/sizeof(cm_saved_mixer[0]))
+#define CM_SAVED_MIXERS                ARRAY_SIZE(cm_saved_mixer)
 
 struct snd_stru_cmipci {
        snd_card_t *card;
@@ -559,12 +561,11 @@
  */
 
 static int rates[] = { 5512, 11025, 22050, 44100, 8000, 16000, 32000, 48000 };
-#define RATES (sizeof(rates) / sizeof(rates[0]))
 
 static unsigned int snd_cmipci_rate_freq(unsigned int rate)
 {
        int i;
-       for (i = 0; i < RATES; i++) {
+       for (i = 0; i < ARRAY_SIZE(rates); i++) {
                if (rates[i] == rate)
                        return i;
        }
@@ -644,6 +645,23 @@
        return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
+static int snd_cmipci_playback2_hw_params(snd_pcm_substream_t * substream,
+                                         snd_pcm_hw_params_t * hw_params)
+{
+       cmipci_t *cm = snd_pcm_substream_chip(substream);
+       if (params_channels(hw_params) > 2) {
+               down(&cm->open_mutex);
+               if (cm->opened[CM_CH_PLAY]) {
+                       up(&cm->open_mutex);
+                       return -EBUSY;
+               }
+               /* reserve the channel A */
+               cm->opened[CM_CH_PLAY] = CM_OPEN_PLAYBACK_MULTI;
+               up(&cm->open_mutex);
+       }
+       return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+}
+
 static void snd_cmipci_ch_reset(cmipci_t *cm, int ch)
 {
        int reset = CM_RST_CH0 << (cm->channel[ch].ch);
@@ -747,6 +765,11 @@
        rec->period_size = runtime->period_size << rec->shift;
        rec->dma_size <<= rec->ac3_shift;
        rec->period_size <<= rec->ac3_shift;
+       if (runtime->channels > 2) {
+               /* multi-channels */
+               rec->dma_size = (rec->dma_size * runtime->channels) / 2;
+               rec->period_size = (rec->period_size * runtime->channels) / 2;
+       }
 
        spin_lock_irqsave(&cm->reg_lock, flags);
 
@@ -756,7 +779,7 @@
        /* program sample counts */
        reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
        snd_cmipci_write_w(cm, reg, rec->dma_size - 1);
-       snd_cmipci_write_w(cm, reg + 2, rec->period_size); /* FIXME: or period_size-1 
?? */
+       snd_cmipci_write_w(cm, reg + 2, rec->period_size - 1);
 
        /* set adc/dac flag */
        val = rec->ch ? CM_CHADC1 : CM_CHADC0;
@@ -868,6 +891,8 @@
        ptr = bytes_to_frames(substream->runtime, ptr);
 #endif
        ptr >>= rec->ac3_shift;
+       if (substream->runtime->channels > 2)
+               ptr = (ptr * 2) / substream->runtime->channels;
        return ptr;
 }
 
@@ -1787,9 +1812,11 @@
 
        down(&cm->open_mutex);
        if (cm->opened[ch] == mode) {
-               snd_cmipci_ch_reset(cm, ch);
-               cm->channel[ch].running = 0;
-               cm->channel[ch].substream = NULL;
+               if (cm->channel[ch].substream) {
+                       snd_cmipci_ch_reset(cm, ch);
+                       cm->channel[ch].running = 0;
+                       cm->channel[ch].substream = NULL;
+               }
                cm->opened[ch] = 0;
                if (! cm->channel[ch].is_dac) {
                        /* enable dual DAC mode again */
@@ -1814,13 +1841,6 @@
        if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0)
                return err;
        runtime->hw = snd_cmipci_playback;
-       if (cm->can_multi_ch) {
-               runtime->hw.channels_max = cm->max_channels;
-               if (cm->max_channels == 4)
-                       snd_pcm_hw_constraint_list(runtime, 0, 
SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_4);
-               else
-                       snd_pcm_hw_constraint_list(runtime, 0, 
SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_6);
-       }
        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 
0x10000);
        return 0;
 }
@@ -1847,7 +1867,18 @@
        if ((err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream)) < 0) /* use 
channel B */
                return err;
        runtime->hw = snd_cmipci_playback2;
-       snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 
0x10000);
+       down(&cm->open_mutex);
+       if (! cm->opened[CM_CH_PLAY]) {
+               if (cm->can_multi_ch) {
+                       runtime->hw.channels_max = cm->max_channels;
+                       if (cm->max_channels == 4)
+                               snd_pcm_hw_constraint_list(runtime, 0, 
+SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_4);
+                       else
+                               snd_pcm_hw_constraint_list(runtime, 0, 
+SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_6);
+               }
+               snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 
+0, 0x10000);
+       }
+       up(&cm->open_mutex);
        return 0;
 }
 
@@ -1904,6 +1935,7 @@
 {
        cmipci_t *cm = snd_pcm_substream_chip(substream);
        close_device_check(cm, CM_OPEN_PLAYBACK2);
+       close_device_check(cm, CM_OPEN_PLAYBACK_MULTI);
        return 0;
 }
 
@@ -1951,7 +1983,7 @@
        .open =         snd_cmipci_playback2_open,
        .close =        snd_cmipci_playback2_close,
        .ioctl =        snd_pcm_lib_ioctl,
-       .hw_params =    snd_cmipci_hw_params,
+       .hw_params =    snd_cmipci_playback2_hw_params,
        .hw_free =      snd_cmipci_hw_free,
        .prepare =      snd_cmipci_capture_prepare,     /* channel B */
        .trigger =      snd_cmipci_capture_trigger,     /* channel B */
@@ -3053,7 +3085,7 @@
                return err;
        }
 #ifdef USE_VAR48KRATE
-       for (val = 0; val < RATES; val++)
+       for (val = 0; val < ARRAY_SIZE(rates); val++)
                snd_cmipci_set_pll(cm, rates[val], val);
 
        /*



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to