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