aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ca0106
diff options
context:
space:
mode:
authorJames Courtier-Dutton <James@superbug.co.uk>2005-05-28 07:28:21 -0400
committerJaroslav Kysela <perex@suse.cz>2005-06-22 06:27:12 -0400
commit883130b476e7f8baa608dabe52c455ac351f7c39 (patch)
treebd252f2384b7ed8565512c77fa6f0734581b12f0 /sound/pci/ca0106
parented144f3cdcf8f9b9280e04ca1a831c85a8fbb488 (diff)
[ALSA] Implement S32_LE(24bit) and 96000 capture rates etc.
CA0106 driver Signed-off-by: James Courtier-Dutton <James@superbug.co.uk>
Diffstat (limited to 'sound/pci/ca0106')
-rw-r--r--sound/pci/ca0106/ca0106_main.c63
1 files changed, 59 insertions, 4 deletions
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 58d9026c8ca6..1c26206b4fb9 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -216,10 +216,10 @@ static snd_pcm_hardware_t snd_ca0106_capture_hw = {
216 SNDRV_PCM_INFO_INTERLEAVED | 216 SNDRV_PCM_INFO_INTERLEAVED |
217 SNDRV_PCM_INFO_BLOCK_TRANSFER | 217 SNDRV_PCM_INFO_BLOCK_TRANSFER |
218 SNDRV_PCM_INFO_MMAP_VALID), 218 SNDRV_PCM_INFO_MMAP_VALID),
219 .formats = SNDRV_PCM_FMTBIT_S16_LE, 219 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
220 .rates = SNDRV_PCM_RATE_48000, 220 .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
221 .rate_min = 48000, 221 .rate_min = 44100,
222 .rate_max = 48000, 222 .rate_max = 192000,
223 .channels_min = 2, 223 .channels_min = 2,
224 .channels_max = 2, 224 .channels_max = 2,
225 .buffer_bytes_max = ((65536 - 64) * 8), 225 .buffer_bytes_max = ((65536 - 64) * 8),
@@ -607,6 +607,61 @@ static int snd_ca0106_pcm_prepare_capture(snd_pcm_substream_t *substream)
607 snd_pcm_runtime_t *runtime = substream->runtime; 607 snd_pcm_runtime_t *runtime = substream->runtime;
608 ca0106_pcm_t *epcm = runtime->private_data; 608 ca0106_pcm_t *epcm = runtime->private_data;
609 int channel = epcm->channel_id; 609 int channel = epcm->channel_id;
610 u32 hcfg_mask = HCFG_CAPTURE_S32_LE;
611 u32 hcfg_set = 0x00000000;
612 u32 hcfg;
613 u32 over_sampling=0x2;
614 u32 reg71_mask = 0x0000c000 ; /* Global. Set ADC rate. */
615 u32 reg71_set = 0;
616 u32 reg71;
617
618 //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1));
619 //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base);
620 //snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->buffer.addr, emu->buffer.area, emu->buffer.bytes);
621 /* reg71 controls ADC rate. */
622 switch (runtime->rate) {
623 case 44100:
624 reg71_set = 0x00004000;
625 break;
626 case 48000:
627 reg71_set = 0;
628 break;
629 case 96000:
630 reg71_set = 0x00008000;
631 over_sampling=0xa;
632 break;
633 case 192000:
634 reg71_set = 0x0000c000;
635 over_sampling=0xa;
636 break;
637 default:
638 reg71_set = 0;
639 break;
640 }
641 /* Format is a global setting */
642 /* FIXME: Only let the first channel accessed set this. */
643 switch (runtime->format) {
644 case SNDRV_PCM_FORMAT_S16_LE:
645 hcfg_set = 0;
646 break;
647 case SNDRV_PCM_FORMAT_S32_LE:
648 hcfg_set = HCFG_CAPTURE_S32_LE;
649 break;
650 default:
651 hcfg_set = 0;
652 break;
653 }
654 hcfg = inl(emu->port + HCFG) ;
655 hcfg = (hcfg & ~hcfg_mask) | hcfg_set;
656 outl(hcfg, emu->port + HCFG);
657 reg71 = snd_ca0106_ptr_read(emu, 0x71, 0);
658 reg71 = (reg71 & ~reg71_mask) | reg71_set;
659 snd_ca0106_ptr_write(emu, 0x71, 0, reg71);
660 if (emu->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */
661 snd_ca0106_i2c_write(emu, ADC_MASTER, over_sampling); /* Adjust the over sampler to better suit the capture rate. */
662 }
663
664
610 //printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, frames_to_bytes(runtime, 1)); 665 //printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, frames_to_bytes(runtime, 1));
611 snd_ca0106_ptr_write(emu, 0x13, channel, 0); 666 snd_ca0106_ptr_write(emu, 0x13, channel, 0);
612 snd_ca0106_ptr_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr); 667 snd_ca0106_ptr_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);