Import 2.3.18pre1
[davej-history.git] / drivers / sound / cmpci.c
blobefca048dc1e1bc2c203f4ceb45021c73ede1c0b4
1 /*****************************************************************************/
3 /*
4 * cmpci.c -- C-Media PCI audio driver.
6 * Copyright (C) 1999 ChenLi Tien (cltien@home.com)
8 * Based on the PCI drivers by Thomas Sailer (sailer@ife.ee.ethz.ch)
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * Special thanks to David C. Niemi
27 * Module command line parameters:
28 * none so far
31 * Supported devices:
32 * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible
33 * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible
34 * /dev/midi simple MIDI UART interface, no ioctl
36 * The card has both an FM and a Wavetable synth, but I have to figure
37 * out first how to drive them...
39 * Revision history
40 * 06.05.98 0.1 Initial release
41 * 10.05.98 0.2 Fixed many bugs, esp. ADC rate calculation
42 * First stab at a simple midi interface (no bells&whistles)
43 * 13.05.98 0.3 Fix stupid cut&paste error: set_adc_rate was called instead of
44 * set_dac_rate in the FMODE_WRITE case in cm_open
45 * Fix hwptr out of bounds (now mpg123 works)
46 * 14.05.98 0.4 Don't allow excessive interrupt rates
47 * 08.06.98 0.5 First release using Alan Cox' soundcore instead of miscdevice
48 * 03.08.98 0.6 Do not include modversions.h
49 * Now mixer behaviour can basically be selected between
50 * "OSS documented" and "OSS actual" behaviour
51 * 31.08.98 0.7 Fix realplayer problems - dac.count issues
52 * 10.12.98 0.8 Fix drain_dac trying to wait on not yet initialized DMA
53 * 16.12.98 0.9 Fix a few f_file & FMODE_ bugs
54 * 06.01.99 0.10 remove the silly SA_INTERRUPT flag.
55 * hopefully killed the egcs section type conflict
56 * 12.03.99 0.11 cinfo.blocks should be reset after GETxPTR ioctl.
57 * reported by Johan Maes <joma@telindus.be>
58 * 22.03.99 0.12 return EAGAIN instead of EBUSY when O_NONBLOCK
59 * read/write cannot be executed
63 /*****************************************************************************/
65 #include <linux/config.h>
66 #include <linux/version.h>
67 #include <linux/module.h>
68 #include <linux/string.h>
69 #include <linux/ioport.h>
70 #include <linux/sched.h>
71 #include <linux/delay.h>
72 #include <linux/sound.h>
73 #include <linux/malloc.h>
74 #include <linux/soundcard.h>
75 #include <linux/pci.h>
76 #include <asm/io.h>
77 #include <asm/dma.h>
78 #include <linux/init.h>
79 #include <linux/poll.h>
80 #include <linux/spinlock.h>
81 #include <asm/uaccess.h>
82 #include <asm/hardirq.h>
84 #include"dm.h"
86 /* --------------------------------------------------------------------- */
88 #undef OSS_DOCUMENTED_MIXER_SEMANTICS
90 /* --------------------------------------------------------------------- */
92 #ifndef PCI_VENDOR_ID_CMEDIA
93 #define PCI_VENDOR_ID_CMEDIA 0x13F6
94 #endif
95 #ifndef PCI_DEVICE_ID_CMEDIA_CM8338A
96 #define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100
97 #endif
98 #ifndef PCI_DEVICE_ID_CMEDIA_CM8338B
99 #define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101
100 #endif
101 #ifndef PCI_DEVICE_ID_CMEDIA_CM8738
102 #define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
103 #endif
105 #define CM_MAGIC ((PCI_VENDOR_ID_CMEDIA<<16)|PCI_DEVICE_ID_CMEDIA_CM8338A)
108 * CM8338 registers definition
111 #define CODEC_CMI_FUNCTRL0 (0x00)
112 #define CODEC_CMI_FUNCTRL1 (0x04)
113 #define CODEC_CMI_CHFORMAT (0x08)
114 #define CODEC_CMI_INT_HLDCLR (0x0C)
115 #define CODEC_CMI_INT_STATUS (0x10)
116 #define CODEC_CMI_LEGACY_CTRL (0x14)
117 #define CODEC_CMI_MISC_CTRL (0x18)
118 #define CODEC_CMI_TDMA_POS (0x1C)
119 #define CODEC_CMI_MIXER (0x20)
120 #define CODEC_SB16_DATA (0x22)
121 #define CODEC_SB16_ADDR (0x23)
122 #define CODEC_CMI_MIXER1 (0x24)
123 #define CODEC_CMI_MIXER2 (0x25)
124 #define CODEC_CMI_AUX_VOL (0x26)
125 #define CODEC_CMI_MISC (0x27)
126 #define CODEC_CMI_AC97 (0x28)
128 #define CODEC_CMI_CH0_FRAME1 (0x80)
129 #define CODEC_CMI_CH0_FRAME2 (0x84)
130 #define CODEC_CMI_CH1_FRAME1 (0x88)
131 #define CODEC_CMI_CH1_FRAME2 (0x8C)
133 #define CODEC_CMI_EXT_REG (0xF0)
134 #define UCHAR unsigned char
136 ** Mixer registers for SB16
139 #define DSP_MIX_DATARESETIDX ((UCHAR)(0x00))
141 #define DSP_MIX_MASTERVOLIDX_L ((UCHAR)(0x30))
142 #define DSP_MIX_MASTERVOLIDX_R ((UCHAR)(0x31))
143 #define DSP_MIX_VOICEVOLIDX_L ((UCHAR)(0x32))
144 #define DSP_MIX_VOICEVOLIDX_R ((UCHAR)(0x33))
145 #define DSP_MIX_FMVOLIDX_L ((UCHAR)(0x34))
146 #define DSP_MIX_FMVOLIDX_R ((UCHAR)(0x35))
147 #define DSP_MIX_CDVOLIDX_L ((UCHAR)(0x36))
148 #define DSP_MIX_CDVOLIDX_R ((UCHAR)(0x37))
149 #define DSP_MIX_LINEVOLIDX_L ((UCHAR)(0x38))
150 #define DSP_MIX_LINEVOLIDX_R ((UCHAR)(0x39))
152 #define DSP_MIX_MICVOLIDX ((UCHAR)(0x3A))
153 #define DSP_MIX_SPKRVOLIDX ((UCHAR)(0x3B))
155 #define DSP_MIX_OUTMIXIDX ((UCHAR)(0x3C))
157 #define DSP_MIX_ADCMIXIDX_L ((UCHAR)(0x3D))
158 #define DSP_MIX_ADCMIXIDX_R ((UCHAR)(0x3E))
160 #define DSP_MIX_INGAINIDX_L ((UCHAR)(0x3F))
161 #define DSP_MIX_INGAINIDX_R ((UCHAR)(0x40))
162 #define DSP_MIX_OUTGAINIDX_L ((UCHAR)(0x41))
163 #define DSP_MIX_OUTGAINIDX_R ((UCHAR)(0x42))
165 #define DSP_MIX_AGCIDX ((UCHAR)(0x43))
167 #define DSP_MIX_TREBLEIDX_L ((UCHAR)(0x44))
168 #define DSP_MIX_TREBLEIDX_R ((UCHAR)(0x45))
169 #define DSP_MIX_BASSIDX_L ((UCHAR)(0x46))
170 #define DSP_MIX_BASSIDX_R ((UCHAR)(0x47))
171 #define CM_CH0_RESET 0x04
172 #define CM_CH1_RESET 0x08
173 #define CM_EXTENT_CODEC 0x100
174 #define CM_EXTENT_MIDI 0x2
175 #define CM_EXTENT_SYNTH 0x4
176 #define CM_INT_CH0 1
177 #define CM_INT_CH1 2
179 #define CM_CFMT_STEREO 0x01
180 #define CM_CFMT_16BIT 0x02
181 #define CM_CFMT_MASK 0x03
182 #define CM_CFMT_DACSHIFT 0
183 #define CM_CFMT_ADCSHIFT 2
185 static const unsigned sample_size[] = {1,2,2,4};
186 static const unsigned sample_shift[] = {0,1,1,2};
188 #define CM_CENABLE_RE 0x2
189 #define CM_CENABLE_PE 0x1
192 /* MIDI buffer sizes */
194 #define MIDIINBUF 256
195 #define MIDIOUTBUF 256
197 #define FMODE_MIDI_SHIFT 2
198 #define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT)
199 #define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
201 #define FMODE_DMFM 0x10
203 #define SND_DEV_DSP16 5
205 /* --------------------------------------------------------------------- */
207 struct cm_state {
208 /* magic */
209 unsigned int magic;
211 /* we keep cm cards in a linked list */
212 struct cm_state *next;
214 /* soundcore stuff */
215 int dev_audio;
216 int dev_mixer;
217 int dev_midi;
218 int dev_dmfm;
220 /* hardware resources */
221 unsigned int iosb, iobase, iosynth, iomidi, iogame, irq;
223 /* mixer stuff */
224 struct{
225 unsigned int modcnt;
226 #ifndef OSS_DOCUMENTED_MIXER_SEMANTICS
227 unsigned short vol[13];
228 #endif/* OSS_DOCUMENTED_MIXER_SEMANTICS */
229 } mix;
231 /* wave stuff */
232 unsigned int rateadc, ratedac;
233 unsigned char fmt, enable;
235 spinlock_t lock;
236 struct semaphore open_sem;
237 mode_t open_mode;
238 wait_queue_head_t open_wait;
240 struct dmabuf {
241 void*rawbuf;
242 unsigned buforder;
243 unsigned numfrag;
244 unsigned fragshift;
245 unsigned hwptr, swptr;
246 unsigned total_bytes;
247 int count;
248 unsigned error;/* over/underrun */
249 wait_queue_head_t wait;
250 /* redundant, but makes calculations easier */
251 unsigned fragsize;
252 unsigned dmasize;
253 unsigned fragsamples;
254 /* OSS stuff */
255 unsigned mapped:1;
256 unsigned ready:1;
257 unsigned endcleared:1;
258 unsigned ossfragshift;
259 int ossmaxfrags;
260 unsigned subdivision;
261 } dma_dac, dma_adc;
263 /* midi stuff */
264 struct{
265 unsigned ird, iwr, icnt;
266 unsigned ord, owr, ocnt;
267 wait_queue_head_t iwait;
268 wait_queue_head_t owait;
269 struct timer_list timer;
270 unsigned char ibuf[MIDIINBUF];
271 unsigned char obuf[MIDIOUTBUF];
272 } midi;
275 /* --------------------------------------------------------------------- */
277 static struct cm_state *devs = NULL;
278 static unsigned long wavetable_mem =0;
280 /* --------------------------------------------------------------------- */
282 extern __inline__ unsignedld2(unsigned int x)
284 unsigned r =0;
286 if(x >=0x10000) {
287 x >>=16;
288 r +=16;
290 if(x >=0x100) {
291 x >>=8;
292 r +=8;
294 if(x >=0x10) {
295 x >>=4;
296 r +=4;
298 if(x >=4) {
299 x >>=2;
300 r +=2;
302 if(x >=2)
303 r++;
304 return r;
308 * hweightN: returns the hamming weight (i.e. the number
309 * of bits set) of a N-bit word
312 #ifdef hweight32
313 #undef hweight32
314 #endif
316 extern __inline__ unsigned inthweight32(unsigned int w)
318 unsigned int res = (w &0x55555555) + ((w >>1) &0x55555555);
319 res = (res &0x33333333) + ((res >>2) &0x33333333);
320 res = (res &0x0F0F0F0F) + ((res >>4) &0x0F0F0F0F);
321 res = (res &0x00FF00FF) + ((res >>8) &0x00FF00FF);
322 return(res &0x0000FFFF) + ((res >>16) &0x0000FFFF);
325 /* --------------------------------------------------------------------- */
327 static voidset_dmadac(struct cm_state *s,unsigned int addr,unsigned int count)
329 count--;
330 outl(addr, s->iobase + CODEC_CMI_CH0_FRAME1);
331 outw(count, s->iobase + CODEC_CMI_CH0_FRAME2);
332 outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) & ~1, s->iobase + CODEC_CMI_FUNCTRL0);
333 outb(inb(s->iobase + CODEC_CMI_FUNCTRL0 +2) |1, s->iobase + CODEC_CMI_FUNCTRL0 +2);
336 static voidset_dmaadc(struct cm_state *s,unsigned int addr,unsigned int count)
338 count--;
339 outl(addr, s->iobase + CODEC_CMI_CH1_FRAME1);
340 outw(count, s->iobase + CODEC_CMI_CH1_FRAME2);
341 outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) |2, s->iobase + CODEC_CMI_FUNCTRL0);
342 outb(inb(s->iobase + CODEC_CMI_FUNCTRL0 +2) |2, s->iobase + CODEC_CMI_FUNCTRL0 +2);
345 extern __inline__ unsignedget_dmadac(struct cm_state *s)
347 unsigned int curr_addr;
349 curr_addr =inl(s->iobase + CODEC_CMI_CH0_FRAME1);
350 curr_addr -=virt_to_bus(s->dma_dac.rawbuf);
351 curr_addr = s->dma_dac.dmasize - curr_addr;
352 curr_addr &= ~(sample_size[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK]-1);
353 return curr_addr;
356 extern __inline__ unsignedget_dmaadc(struct cm_state *s)
358 unsigned int curr_addr;
360 curr_addr =inl(s->iobase + CODEC_CMI_CH1_FRAME1);
361 curr_addr -=virt_to_bus(s->dma_adc.rawbuf);
362 curr_addr = s->dma_adc.dmasize - curr_addr;
363 curr_addr &= ~(sample_size[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK]-1);
364 return curr_addr;
367 static voidwrmixer(struct cm_state *s,unsigned char idx,unsigned char data)
369 outb(idx, s->iobase + CODEC_SB16_ADDR);
370 udelay(10);
371 outb(data, s->iobase + CODEC_SB16_DATA);
372 udelay(10);
375 static unsigned charrdmixer(struct cm_state *s,unsigned char idx)
377 unsigned char v;
379 outb(idx, s->iobase + CODEC_SB16_ADDR);
380 udelay(10);
381 v =inb(s->iobase + CODEC_SB16_DATA);
382 udelay(10);
383 return v;
386 static voidset_fmt(struct cm_state *s,unsigned char mask,unsigned char data)
388 unsigned long flags;
390 spin_lock_irqsave(&s->lock, flags);
391 if(mask) {
392 s->fmt =inb(s->iobase + CODEC_CMI_CHFORMAT);
393 udelay(10);
395 s->fmt = (s->fmt & mask) | data;
396 outb(s->fmt, s->iobase + CODEC_CMI_CHFORMAT);
397 spin_unlock_irqrestore(&s->lock, flags);
398 udelay(10);
401 static voidfrobindir(struct cm_state *s,unsigned char idx,unsigned char mask,unsigned char data)
403 outb(idx, s->iobase + CODEC_SB16_ADDR);
404 udelay(10);
405 outb((inb(s->iobase + CODEC_SB16_DATA) & mask) | data, s->iobase + CODEC_SB16_DATA);
406 udelay(10);
409 static struct{
410 unsigned rate;
411 unsigned lower;
412 unsigned upper;
413 unsigned char freq;
414 } rate_lookup[] =
416 {5512, (0+5512) /2, (5512+8000) /2,0},
417 {8000, (5512+8000) /2, (8000+11025) /2,4},
418 {11025, (8000+11025) /2, (11025+16000) /2,1},
419 {16000, (11025+16000) /2, (16000+22050) /2,5},
420 {22050, (16000+22050) /2, (22050+32000) /2,2},
421 {32000, (22050+32000) /2, (32000+44100) /2,6},
422 {44100, (32000+44100) /2, (44100+48000) /2,3},
423 {48000,48000,48000,7}
426 static voidset_dac_rate(struct cm_state *s,unsigned rate)
428 unsigned long flags;
429 unsigned char freq =4, val;
430 int i;
432 if(rate >48000)
433 rate =48000;
434 if(rate <5512)
435 rate =5512;
436 for(i =0; i <sizeof(rate_lookup) /sizeof(rate_lookup[0]); i++)
438 if(rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper)
440 rate = rate_lookup[i].rate;
441 freq = rate_lookup[i].freq;
442 break;
445 s->ratedac = rate;
446 freq <<=2;
447 spin_lock_irqsave(&s->lock, flags);
448 val =inb(s->iobase + CODEC_CMI_FUNCTRL1 +1) & ~0x1c;
449 outb(val | freq, s->iobase + CODEC_CMI_FUNCTRL1 +1);
450 spin_unlock_irqrestore(&s->lock, flags);
453 static voidset_adc_rate(struct cm_state *s,unsigned rate)
455 unsigned long flags;
456 unsigned char freq =4, val;
457 int i;
459 if(rate >48000)
460 rate =48000;
461 if(rate <5512)
462 rate =5512;
463 for(i =0; i <sizeof(rate_lookup) /sizeof(rate_lookup[0]); i++)
465 if(rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper)
467 rate = rate_lookup[i].rate;
468 freq = rate_lookup[i].freq;
469 break;
472 s->rateadc = rate;
473 freq <<=5;
474 spin_lock_irqsave(&s->lock, flags);
475 val =inb(s->iobase + CODEC_CMI_FUNCTRL1 +1) & ~0xe0;
476 outb(val | freq, s->iobase + CODEC_CMI_FUNCTRL1 +1);
477 spin_unlock_irqrestore(&s->lock, flags);
480 /* --------------------------------------------------------------------- */
482 extern inlinevoidstop_adc(struct cm_state *s)
484 unsigned long flags;
486 spin_lock_irqsave(&s->lock, flags);
487 s->enable &= ~CM_CENABLE_RE;
488 /* disable interrupt */
489 outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR +2) & ~2, s->iobase + CODEC_CMI_INT_HLDCLR +2);
490 /* disable channel and reset */
491 outb(s->enable | CM_CH1_RESET, s->iobase + CODEC_CMI_FUNCTRL0 +2);
492 udelay(10);
493 outb(s->enable & ~CM_CH1_RESET, s->iobase + CODEC_CMI_FUNCTRL0 +2);
494 spin_unlock_irqrestore(&s->lock, flags);
497 extern inlinevoidstop_dac(struct cm_state *s)
499 unsigned long flags;
501 spin_lock_irqsave(&s->lock, flags);
502 s->enable &= ~CM_CENABLE_PE;
503 /* disable interrupt */
504 outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR +2) & ~1, s->iobase + CODEC_CMI_INT_HLDCLR +2);
505 /* disable channel and reset */
506 outb(s->enable | CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 +2);
507 udelay(10);
508 outb(s->enable & ~CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 +2);
509 spin_unlock_irqrestore(&s->lock, flags);
512 static voidstart_dac(struct cm_state *s)
514 unsigned long flags;
516 spin_lock_irqsave(&s->lock, flags);
517 if((s->dma_dac.mapped || s->dma_dac.count >0) && s->dma_dac.ready) {
518 s->enable |= CM_CENABLE_PE;
519 outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 +2);
521 outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR +2) |1, s->iobase + CODEC_CMI_INT_HLDCLR +2);
522 spin_unlock_irqrestore(&s->lock, flags);
525 static voidstart_adc(struct cm_state *s)
527 unsigned long flags;
529 spin_lock_irqsave(&s->lock, flags);
530 if((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize -2*s->dma_adc.fragsize))
531 && s->dma_adc.ready) {
532 s->enable |= CM_CENABLE_RE;
533 outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 +2);
535 outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR +2) |2, s->iobase + CODEC_CMI_INT_HLDCLR +2);
536 spin_unlock_irqrestore(&s->lock, flags);
539 /* --------------------------------------------------------------------- */
541 #define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
542 #define DMABUF_MINORDER 1
544 static voiddealloc_dmabuf(struct dmabuf *db)
546 unsigned long map, mapend;
548 if(db->rawbuf) {
549 /* undo marking the pages as reserved */
550 mapend =MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) -1);
551 for(map =MAP_NR(db->rawbuf); map <= mapend; map++)
552 clear_bit(PG_reserved, &mem_map[map].flags);
553 free_pages((unsigned long)db->rawbuf, db->buforder);
555 db->rawbuf = NULL;
556 db->mapped = db->ready =0;
560 /* Ch0 is used for playback, Ch1 is used for recording */
562 static intprog_dmabuf(struct cm_state *s,unsigned rec)
564 struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
565 unsigned rate = rec ? s->rateadc : s->ratedac;
566 int order;
567 unsigned bytepersec;
568 unsigned bufs;
569 unsigned long map, mapend;
570 unsigned char fmt;
571 unsigned long flags;
573 spin_lock_irqsave(&s->lock, flags);
574 fmt = s->fmt;
575 if(rec) {
576 s->enable &= ~CM_CENABLE_RE;
577 fmt >>= CM_CFMT_ADCSHIFT;
578 }else{
579 s->enable &= ~CM_CENABLE_PE;
580 fmt >>= CM_CFMT_DACSHIFT;
582 outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 +2);
583 spin_unlock_irqrestore(&s->lock, flags);
584 fmt &= CM_CFMT_MASK;
585 db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared =0;
586 if(!db->rawbuf) {
587 db->ready = db->mapped =0;
588 for(order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER && !db->rawbuf; order--)
589 db->rawbuf = (void*)__get_free_pages(GFP_KERNEL | GFP_DMA, order);
590 if(!db->rawbuf)
591 return-ENOMEM;
592 db->buforder = order;
593 if((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) -1)) & ~0xffff)
594 printk(KERN_DEBUG "cm: DMA buffer crosses 64k boundary: busaddr 0x%lx size %ld\n",
595 virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
596 if((virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) -1) & ~0xffffff)
597 printk(KERN_DEBUG "cm: DMA buffer beyond 16MB: busaddr 0x%lx size %ld\n",
598 virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
599 /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
600 mapend =MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) -1);
601 for(map =MAP_NR(db->rawbuf); map <= mapend; map++)
602 set_bit(PG_reserved, &mem_map[map].flags);
604 bytepersec = rate << sample_shift[fmt];
605 bufs = PAGE_SIZE << db->buforder;
606 if(db->ossfragshift) {
607 if((1000<< db->ossfragshift) < bytepersec)
608 db->fragshift =ld2(bytepersec/1000);
609 else
610 db->fragshift = db->ossfragshift;
611 }else{
612 db->fragshift =ld2(bytepersec/100/(db->subdivision ? db->subdivision :1));
613 if(db->fragshift <3)
614 db->fragshift =3;
616 db->numfrag = bufs >> db->fragshift;
617 while(db->numfrag <4&& db->fragshift >3) {
618 db->fragshift--;
619 db->numfrag = bufs >> db->fragshift;
621 db->fragsize =1<< db->fragshift;
622 if(db->ossmaxfrags >=4&& db->ossmaxfrags < db->numfrag)
623 db->numfrag = db->ossmaxfrags;
624 #if 1
625 /* to make fragsize >= 4096 */
626 while(db->fragsize <4096&& db->numfrag >=4)
628 db->fragsize *=2;
629 db->fragshift++;
630 db->numfrag /=2;
632 #endif
633 db->fragsamples = db->fragsize >> sample_shift[fmt];
634 db->dmasize = db->numfrag << db->fragshift;
635 memset(db->rawbuf, (fmt & CM_CFMT_16BIT) ?0:0x80, db->dmasize);
636 spin_lock_irqsave(&s->lock, flags);
637 if(rec) {
638 set_dmaadc(s,virt_to_bus(db->rawbuf), db->dmasize >> sample_shift[fmt]);
639 /* program sample counts */
640 outw(db->fragsamples-1, s->iobase + CODEC_CMI_CH1_FRAME2 +2);
641 }else{
642 set_dmadac(s,virt_to_bus(db->rawbuf), db->dmasize >> sample_shift[fmt]);
643 /* program sample counts */
644 outw(db->fragsamples-1, s->iobase + CODEC_CMI_CH0_FRAME2 +2);
646 spin_unlock_irqrestore(&s->lock, flags);
647 db->ready =1;
648 return0;
651 extern __inline__ voidclear_advance(struct cm_state *s)
653 unsigned char c = (s->fmt & (CM_CFMT_16BIT << CM_CFMT_DACSHIFT)) ?0:0x80;
654 unsigned char*buf = s->dma_dac.rawbuf;
655 unsigned bsize = s->dma_dac.dmasize;
656 unsigned bptr = s->dma_dac.swptr;
657 unsigned len = s->dma_dac.fragsize;
659 if(bptr + len > bsize) {
660 unsigned x = bsize - bptr;
661 memset(buf + bptr, c, x);
662 bptr =0;
663 len -= x;
665 memset(buf + bptr, c, len);
668 /* call with spinlock held! */
669 static voidcm_update_ptr(struct cm_state *s)
671 unsigned hwptr;
672 int diff;
674 /* update ADC pointer */
675 if(s->dma_adc.ready) {
676 hwptr = (s->dma_adc.dmasize -get_dmaadc(s)) % s->dma_adc.dmasize;
677 diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
678 s->dma_adc.hwptr = hwptr;
679 s->dma_adc.total_bytes += diff;
680 s->dma_adc.count += diff;
681 if(s->dma_adc.count >= (signed)s->dma_adc.fragsize)
682 wake_up(&s->dma_adc.wait);
683 if(!s->dma_adc.mapped) {
684 if(s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3* s->dma_adc.fragsize) >>1))) {
685 s->enable &= ~CM_CENABLE_RE;
686 outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 +2);
687 s->dma_adc.error++;
691 /* update DAC pointer */
692 if(s->dma_dac.ready) {
693 hwptr = (s->dma_dac.dmasize -get_dmadac(s)) % s->dma_dac.dmasize;
694 diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
695 s->dma_dac.hwptr = hwptr;
696 s->dma_dac.total_bytes += diff;
697 if(s->dma_dac.mapped) {
698 s->dma_dac.count += diff;
699 if(s->dma_dac.count >= (signed)s->dma_dac.fragsize)
700 wake_up(&s->dma_dac.wait);
701 }else{
702 s->dma_dac.count -= diff;
703 if(s->dma_dac.count <=0) {
704 s->enable &= ~CM_CENABLE_PE;
705 outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 +2);
706 s->dma_dac.error++;
707 }else if(s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
708 clear_advance(s);
709 s->dma_dac.endcleared =1;
711 if(s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
712 wake_up(&s->dma_dac.wait);
717 /* hold spinlock for the following! */
718 static voidcm_handle_midi(struct cm_state *s)
720 unsigned char ch;
721 int wake;
723 wake =0;
724 while(!(inb(s->iomidi+1) &0x80)) {
725 ch =inb(s->iomidi);
726 if(s->midi.icnt < MIDIINBUF) {
727 s->midi.ibuf[s->midi.iwr] = ch;
728 s->midi.iwr = (s->midi.iwr +1) % MIDIINBUF;
729 s->midi.icnt++;
731 wake =1;
733 if(wake)
734 wake_up(&s->midi.iwait);
735 wake =0;
736 while(!(inb(s->iomidi+1) &0x40) && s->midi.ocnt >0) {
737 outb(s->midi.obuf[s->midi.ord], s->iomidi);
738 s->midi.ord = (s->midi.ord +1) % MIDIOUTBUF;
739 s->midi.ocnt--;
740 if(s->midi.ocnt < MIDIOUTBUF-16)
741 wake =1;
743 if(wake)
744 wake_up(&s->midi.owait);
747 static voidcm_interrupt(int irq,void*dev_id,struct pt_regs *regs)
749 struct cm_state *s = (struct cm_state *)dev_id;
750 unsigned int intsrc, intstat;
752 /* fastpath out, to ease interrupt sharing */
753 intsrc =inb(s->iobase + CODEC_CMI_INT_STATUS);
754 if(!(intsrc & (CM_INT_CH0 | CM_INT_CH1)))
755 return;
756 spin_lock(&s->lock);
757 intstat =inb(s->iobase + CODEC_CMI_INT_HLDCLR +2);
758 /* disable interrupt */
759 if(intsrc & CM_INT_CH0)
760 outb(intstat & ~1, s->iobase + CODEC_CMI_INT_HLDCLR +2);
761 if(intsrc & CM_INT_CH1)
762 outb(intstat & ~2, s->iobase + CODEC_CMI_INT_HLDCLR +2);
763 cm_update_ptr(s);
764 #ifdef SOUND_CONFIG_CMPCI_MIDI
765 cm_handle_midi(s);
766 #endif
767 /* enable interrupt */
768 if(intsrc & CM_INT_CH0)
769 outb(intstat |1, s->iobase + CODEC_CMI_INT_HLDCLR +2);
770 if(intsrc & CM_INT_CH1)
771 outb(intstat |2, s->iobase + CODEC_CMI_INT_HLDCLR +2);
772 spin_unlock(&s->lock);
775 static voidcm_midi_timer(unsigned long data)
777 struct cm_state *s = (struct cm_state *)data;
778 unsigned long flags;
780 spin_lock_irqsave(&s->lock, flags);
781 cm_handle_midi(s);
782 spin_unlock_irqrestore(&s->lock, flags);
783 s->midi.timer.expires = jiffies+1;
784 add_timer(&s->midi.timer);
787 /* --------------------------------------------------------------------- */
789 static const char invalid_magic[] = KERN_CRIT "cm: invalid magic value\n";
791 #ifdef CONFIG_SOUND_CMPCI/* support multiple chips */
792 #define VALIDATE_STATE(s)
793 #else
794 #define VALIDATE_STATE(s) \
795 ({ \
796 if (!(s) || (s)->magic != CM_MAGIC) { \
797 printk(invalid_magic); \
798 return -ENXIO; \
801 #endif
803 /* --------------------------------------------------------------------- */
805 #define MT_4 1
806 #define MT_5MUTE 2
807 #define MT_4MUTEMONO 3
808 #define MT_6MUTE 4
810 static const struct{
811 unsigned left;
812 unsigned right;
813 unsigned type;
814 unsigned rec;
815 unsigned play;
816 } mixtable[SOUND_MIXER_NRDEVICES] = {
817 [SOUND_MIXER_CD] = { DSP_MIX_CDVOLIDX_L, DSP_MIX_CDVOLIDX_R, MT_5MUTE,0x04,0x02},
818 [SOUND_MIXER_LINE] = { DSP_MIX_LINEVOLIDX_L, DSP_MIX_LINEVOLIDX_R, MT_5MUTE,0x10,0x08},
819 [SOUND_MIXER_MIC] = { DSP_MIX_MICVOLIDX, CODEC_CMI_MIXER2, MT_4MUTEMONO,0x01,0x01},
820 [SOUND_MIXER_SYNTH] = { DSP_MIX_FMVOLIDX_L, DSP_MIX_FMVOLIDX_R, MT_5MUTE,0x40,0x00},
821 [SOUND_MIXER_VOLUME] = { DSP_MIX_MASTERVOLIDX_L, DSP_MIX_MASTERVOLIDX_R, MT_5MUTE,0x00,0x00},
822 [SOUND_MIXER_PCM] = { DSP_MIX_VOICEVOLIDX_L, DSP_MIX_VOICEVOLIDX_R, MT_5MUTE,0x00,0x00}
825 #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
827 static intreturn_mixval(struct cm_state *s,unsigned i,int*arg)
829 unsigned long flags;
830 unsigned char l, r, rl, rr;
832 spin_lock_irqsave(&s->lock, flags);
833 l =rdmixer(s, mixtable[i].left);
834 r =rdmixer(s, mixtable[i].right);
835 spin_unlock_irqrestore(&s->lock, flags);
836 switch(mixtable[i].type) {
837 case MT_4:
838 r &=0xf;
839 l &=0xf;
840 rl =10+6* (l &15);
841 rr =10+6* (r &15);
842 break;
844 case MT_4MUTEMONO:
845 rl =55-3* (l &15);
846 if(r &0x10)
847 rl +=45;
848 rr = rl;
849 r = l;
850 break;
852 case MT_5MUTE:
853 default:
854 rl =100-3* (l &31);
855 rr =100-3* (r &31);
856 break;
858 case MT_6MUTE:
859 rl =100-3* (l &63) /2;
860 rr =100-3* (r &63) /2;
861 break;
863 if(l &0x80)
864 rl =0;
865 if(r &0x80)
866 rr =0;
867 returnput_user((rr <<8) | rl, arg);
870 #else/* OSS_DOCUMENTED_MIXER_SEMANTICS */
872 static const unsigned char volidx[SOUND_MIXER_NRDEVICES] =
874 [SOUND_MIXER_CD] =1,
875 [SOUND_MIXER_LINE] =2,
876 [SOUND_MIXER_MIC] =3,
877 [SOUND_MIXER_SYNTH] =4,
878 [SOUND_MIXER_VOLUME] =5,
879 [SOUND_MIXER_PCM] =6
882 #endif/* OSS_DOCUMENTED_MIXER_SEMANTICS */
884 static unsignedmixer_recmask(struct cm_state *s)
886 unsigned long flags;
887 int i, j, k;
889 spin_lock_irqsave(&s->lock, flags);
890 j =rdmixer(s, DSP_MIX_ADCMIXIDX_L);
891 spin_unlock_irqrestore(&s->lock, flags);
892 j &=0x7f;
893 for(k = i =0; i < SOUND_MIXER_NRDEVICES; i++)
894 if(j & mixtable[i].rec)
895 k |=1<< i;
896 return k;
899 static intmixer_ioctl(struct cm_state *s,unsigned int cmd,unsigned long arg)
901 unsigned long flags;
902 int i, val, j;
903 unsigned char l, r, rl, rr;
905 VALIDATE_STATE(s);
906 if(cmd == SOUND_MIXER_INFO) {
907 mixer_info info;
908 strncpy(info.id,"cmpci",sizeof(info.id));
909 strncpy(info.name,"C-Media PCI",sizeof(info.name));
910 info.modify_counter = s->mix.modcnt;
911 if(copy_to_user((void*)arg, &info,sizeof(info)))
912 return-EFAULT;
913 return0;
915 if(cmd == SOUND_OLD_MIXER_INFO) {
916 _old_mixer_info info;
917 strncpy(info.id,"cmpci",sizeof(info.id));
918 strncpy(info.name,"C-Media cmpci",sizeof(info.name));
919 if(copy_to_user((void*)arg, &info,sizeof(info)))
920 return-EFAULT;
921 return0;
923 if(cmd == OSS_GETVERSION)
924 returnput_user(SOUND_VERSION, (int*)arg);
925 if(_IOC_TYPE(cmd) !='M'||_IOC_SIZE(cmd) !=sizeof(int))
926 return-EINVAL;
927 if(_IOC_DIR(cmd) == _IOC_READ) {
928 switch(_IOC_NR(cmd)) {
929 case SOUND_MIXER_RECSRC:/* Arg contains a bit for each recording source */
930 returnput_user(mixer_recmask(s), (int*)arg);
932 case SOUND_MIXER_OUTSRC:/* Arg contains a bit for each recording source */
933 returnput_user(mixer_recmask(s), (int*)arg);//need fix
935 case SOUND_MIXER_DEVMASK:/* Arg contains a bit for each supported device */
936 for(val = i =0; i < SOUND_MIXER_NRDEVICES; i++)
937 if(mixtable[i].type)
938 val |=1<< i;
939 returnput_user(val, (int*)arg);
941 case SOUND_MIXER_RECMASK:/* Arg contains a bit for each supported recording source */
942 for(val = i =0; i < SOUND_MIXER_NRDEVICES; i++)
943 if(mixtable[i].rec)
944 val |=1<< i;
945 returnput_user(val, (int*)arg);
947 case SOUND_MIXER_OUTMASK:/* Arg contains a bit for each supported recording source */
948 for(val = i =0; i < SOUND_MIXER_NRDEVICES; i++)
949 if(mixtable[i].play)
950 val |=1<< i;
951 returnput_user(val, (int*)arg);
953 case SOUND_MIXER_STEREODEVS:/* Mixer channels supporting stereo */
954 for(val = i =0; i < SOUND_MIXER_NRDEVICES; i++)
955 if(mixtable[i].type && mixtable[i].type != MT_4MUTEMONO)
956 val |=1<< i;
957 returnput_user(val, (int*)arg);
959 case SOUND_MIXER_CAPS:
960 returnput_user(0, (int*)arg);
962 default:
963 i =_IOC_NR(cmd);
964 if(i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
965 return-EINVAL;
966 #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
967 returnreturn_mixval(s, i, (int*)arg);
968 #else/* OSS_DOCUMENTED_MIXER_SEMANTICS */
969 if(!volidx[i])
970 return-EINVAL;
971 returnput_user(s->mix.vol[volidx[i]-1], (int*)arg);
972 #endif/* OSS_DOCUMENTED_MIXER_SEMANTICS */
975 if(_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE))
976 return-EINVAL;
977 s->mix.modcnt++;
978 switch(_IOC_NR(cmd)) {
979 case SOUND_MIXER_RECSRC:/* Arg contains a bit for each recording source */
980 get_user_ret(val, (int*)arg, -EFAULT);
981 i =hweight32(val);
982 for(j = i =0; i < SOUND_MIXER_NRDEVICES; i++) {
983 if(!(val & (1<< i)))
984 continue;
985 if(!mixtable[i].rec) {
986 val &= ~(1<< i);
987 continue;
989 j |= mixtable[i].rec;
991 spin_lock_irqsave(&s->lock, flags);
992 wrmixer(s, DSP_MIX_ADCMIXIDX_L, j);
993 wrmixer(s, DSP_MIX_ADCMIXIDX_R, (j &1) | j>>1);
994 spin_unlock_irqrestore(&s->lock, flags);
995 return0;
997 case SOUND_MIXER_OUTSRC:/* Arg contains a bit for each recording source */
998 get_user_ret(val, (int*)arg, -EFAULT);
999 for(j = i =0; i < SOUND_MIXER_NRDEVICES; i++) {
1000 if(!(val & (1<< i)))
1001 continue;
1002 if(!mixtable[i].play) {
1003 val &= ~(1<< i);
1004 continue;
1006 j |= mixtable[i].play;
1008 spin_lock_irqsave(&s->lock, flags);
1009 frobindir(s, DSP_MIX_OUTMIXIDX,0x1f, j);
1010 spin_unlock_irqrestore(&s->lock, flags);
1011 return0;
1013 default:
1014 i =_IOC_NR(cmd);
1015 if(i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
1016 return-EINVAL;
1017 get_user_ret(val, (int*)arg, -EFAULT);
1018 l = val &0xff;
1019 r = (val >>8) &0xff;
1020 if(l >100)
1021 l =100;
1022 if(r >100)
1023 r =100;
1024 spin_lock_irqsave(&s->lock, flags);
1025 switch(mixtable[i].type) {
1026 case MT_4:
1027 if(l >=10)
1028 l -=10;
1029 if(r >=10)
1030 r -=10;
1031 frobindir(s, mixtable[i].left,0xf0, l /6);
1032 frobindir(s, mixtable[i].right,0xf0, l /6);
1033 break;
1035 case MT_4MUTEMONO:
1036 rl = (l <4?0: (l -5) /3) &31;
1037 rr = (rl >>2) &7;
1038 wrmixer(s, mixtable[i].left, rl<<3);
1039 outb((inb(s->iobase + CODEC_CMI_MIXER2) & ~0x0e) | rr<<1, s->iobase + CODEC_CMI_MIXER2);
1040 break;
1042 case MT_5MUTE:
1043 rl = l <4?0: (l -5) /3;
1044 rr = r <4?0: (r -5) /3;
1045 wrmixer(s, mixtable[i].left, rl<<3);
1046 wrmixer(s, mixtable[i].right, rr<<3);
1047 break;
1049 case MT_6MUTE:
1050 if(l <6)
1051 rl =0x00;
1052 else
1053 rl = l *2/3;
1054 if(r <6)
1055 rr =0x00;
1056 else
1057 rr = r *2/3;
1058 wrmixer(s, mixtable[i].left, rl);
1059 wrmixer(s, mixtable[i].right, rr);
1060 break;
1062 spin_unlock_irqrestore(&s->lock, flags);
1063 #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
1064 returnreturn_mixval(s, i, (int*)arg);
1065 #else/* OSS_DOCUMENTED_MIXER_SEMANTICS */
1066 if(!volidx[i])
1067 return-EINVAL;
1068 s->mix.vol[volidx[i]-1] = val;
1069 returnput_user(s->mix.vol[volidx[i]-1], (int*)arg);
1070 #endif/* OSS_DOCUMENTED_MIXER_SEMANTICS */
1074 /* --------------------------------------------------------------------- */
1076 static loff_t cm_llseek(struct file *file, loff_t offset,int origin)
1078 return-ESPIPE;
1081 /* --------------------------------------------------------------------- */
1083 static intcm_open_mixdev(struct inode *inode,struct file *file)
1085 int minor =MINOR(inode->i_rdev);
1086 struct cm_state *s = devs;
1088 while(s && s->dev_mixer != minor)
1089 s = s->next;
1090 if(!s)
1091 return-ENODEV;
1092 VALIDATE_STATE(s);
1093 file->private_data = s;
1094 MOD_INC_USE_COUNT;
1095 return0;
1098 static intcm_release_mixdev(struct inode *inode,struct file *file)
1100 struct cm_state *s = (struct cm_state *)file->private_data;
1102 VALIDATE_STATE(s);
1103 MOD_DEC_USE_COUNT;
1104 return0;
1107 static intcm_ioctl_mixdev(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
1109 returnmixer_ioctl((struct cm_state *)file->private_data, cmd, arg);
1112 static/*const*/struct file_operations cm_mixer_fops = {
1113 &cm_llseek,
1114 NULL,/* read */
1115 NULL,/* write */
1116 NULL,/* readdir */
1117 NULL,/* poll */
1118 &cm_ioctl_mixdev,
1119 NULL,/* mmap */
1120 &cm_open_mixdev,
1121 NULL,/* flush */
1122 &cm_release_mixdev,
1123 NULL,/* fsync */
1124 NULL,/* fasync */
1125 NULL,/* check_media_change */
1126 NULL,/* revalidate */
1127 NULL,/* lock */
1130 /* --------------------------------------------------------------------- */
1132 static intdrain_dac(struct cm_state *s,int nonblock)
1134 DECLARE_WAITQUEUE(wait, current);
1135 unsigned long flags;
1136 int count, tmo;
1138 if(s->dma_dac.mapped || !s->dma_dac.ready)
1139 return0;
1140 current->state = TASK_INTERRUPTIBLE;
1141 add_wait_queue(&s->dma_dac.wait, &wait);
1142 for(;;) {
1143 spin_lock_irqsave(&s->lock, flags);
1144 count = s->dma_dac.count;
1145 spin_unlock_irqrestore(&s->lock, flags);
1146 if(count <=0)
1147 break;
1148 if(signal_pending(current))
1149 break;
1150 if(nonblock) {
1151 remove_wait_queue(&s->dma_dac.wait, &wait);
1152 current->state = TASK_RUNNING;
1153 return-EBUSY;
1155 tmo = (count * HZ) / s->ratedac;
1156 tmo >>= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
1157 if(!schedule_timeout(tmo ? :1) && tmo)
1158 printk(KERN_DEBUG "cm: dma timed out??\n");
1160 remove_wait_queue(&s->dma_dac.wait, &wait);
1161 current->state = TASK_RUNNING;
1162 if(signal_pending(current))
1163 return-ERESTARTSYS;
1164 return0;
1167 /* --------------------------------------------------------------------- */
1169 static ssize_t cm_read(struct file *file,char*buffer,size_t count, loff_t *ppos)
1171 struct cm_state *s = (struct cm_state *)file->private_data;
1172 ssize_t ret;
1173 unsigned long flags;
1174 unsigned swptr;
1175 int cnt;
1177 VALIDATE_STATE(s);
1178 if(ppos != &file->f_pos)
1179 return-ESPIPE;
1180 if(s->dma_adc.mapped)
1181 return-ENXIO;
1182 if(!s->dma_adc.ready && (ret =prog_dmabuf(s,1)))
1183 return ret;
1184 if(!access_ok(VERIFY_WRITE, buffer, count))
1185 return-EFAULT;
1186 ret =0;
1187 #if 0
1188 spin_lock_irqsave(&s->lock, flags);
1189 cm_update_ptr(s);
1190 spin_unlock_irqrestore(&s->lock, flags);
1191 #endif
1192 while(count >0) {
1193 spin_lock_irqsave(&s->lock, flags);
1194 swptr = s->dma_adc.swptr;
1195 cnt = s->dma_adc.dmasize-swptr;
1196 if(s->dma_adc.count < cnt)
1197 cnt = s->dma_adc.count;
1198 spin_unlock_irqrestore(&s->lock, flags);
1199 if(cnt > count)
1200 cnt = count;
1201 if(cnt <=0) {
1202 start_adc(s);
1203 if(file->f_flags & O_NONBLOCK)
1204 return ret ? ret : -EAGAIN;
1205 interruptible_sleep_on(&s->dma_adc.wait);
1206 if(signal_pending(current))
1207 return ret ? ret : -ERESTARTSYS;
1208 continue;
1210 if(copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt))
1211 return ret ? ret : -EFAULT;
1212 swptr = (swptr + cnt) % s->dma_adc.dmasize;
1213 spin_lock_irqsave(&s->lock, flags);
1214 s->dma_adc.swptr = swptr;
1215 s->dma_adc.count -= cnt;
1216 spin_unlock_irqrestore(&s->lock, flags);
1217 count -= cnt;
1218 buffer += cnt;
1219 ret += cnt;
1220 start_adc(s);
1222 return ret;
1225 static ssize_t cm_write(struct file *file,const char*buffer,size_t count, loff_t *ppos)
1227 struct cm_state *s = (struct cm_state *)file->private_data;
1228 ssize_t ret;
1229 unsigned long flags;
1230 unsigned swptr;
1231 int cnt;
1233 VALIDATE_STATE(s);
1234 if(ppos != &file->f_pos)
1235 return-ESPIPE;
1236 if(s->dma_dac.mapped)
1237 return-ENXIO;
1238 if(!s->dma_dac.ready && (ret =prog_dmabuf(s,0)))
1239 return ret;
1240 if(!access_ok(VERIFY_READ, buffer, count))
1241 return-EFAULT;
1242 ret =0;
1243 #if 0
1244 spin_lock_irqsave(&s->lock, flags);
1245 cm_update_ptr(s);
1246 spin_unlock_irqrestore(&s->lock, flags);
1247 #endif
1248 while(count >0) {
1249 spin_lock_irqsave(&s->lock, flags);
1250 if(s->dma_dac.count <0) {
1251 s->dma_dac.count =0;
1252 s->dma_dac.swptr = s->dma_dac.hwptr;
1254 swptr = s->dma_dac.swptr;
1255 cnt = s->dma_dac.dmasize-swptr;
1256 if(s->dma_dac.count + cnt > s->dma_dac.dmasize)
1257 cnt = s->dma_dac.dmasize - s->dma_dac.count;
1258 spin_unlock_irqrestore(&s->lock, flags);
1259 if(cnt > count)
1260 cnt = count;
1261 if(cnt <=0) {
1262 start_dac(s);
1263 if(file->f_flags & O_NONBLOCK)
1264 return ret ? ret : -EAGAIN;
1265 interruptible_sleep_on(&s->dma_dac.wait);
1266 if(signal_pending(current))
1267 return ret ? ret : -ERESTARTSYS;
1268 continue;
1270 if(copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
1271 return ret ? ret : -EFAULT;
1272 swptr = (swptr + cnt) % s->dma_dac.dmasize;
1273 spin_lock_irqsave(&s->lock, flags);
1274 s->dma_dac.swptr = swptr;
1275 s->dma_dac.count += cnt;
1276 s->dma_dac.endcleared =0;
1277 spin_unlock_irqrestore(&s->lock, flags);
1278 count -= cnt;
1279 buffer += cnt;
1280 ret += cnt;
1281 start_dac(s);
1283 return ret;
1286 static unsigned intcm_poll(struct file *file,struct poll_table_struct *wait)
1288 struct cm_state *s = (struct cm_state *)file->private_data;
1289 unsigned long flags;
1290 unsigned int mask =0;
1292 VALIDATE_STATE(s);
1293 if(file->f_mode & FMODE_WRITE)
1294 poll_wait(file, &s->dma_dac.wait, wait);
1295 if(file->f_mode & FMODE_READ)
1296 poll_wait(file, &s->dma_adc.wait, wait);
1297 spin_lock_irqsave(&s->lock, flags);
1298 cm_update_ptr(s);
1299 if(file->f_mode & FMODE_READ) {
1300 if(s->dma_adc.count >= (signed)s->dma_adc.fragsize)
1301 mask |= POLLIN | POLLRDNORM;
1303 if(file->f_mode & FMODE_WRITE) {
1304 if(s->dma_dac.mapped) {
1305 if(s->dma_dac.count >= (signed)s->dma_dac.fragsize)
1306 mask |= POLLOUT | POLLWRNORM;
1307 }else{
1308 if((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
1309 mask |= POLLOUT | POLLWRNORM;
1312 spin_unlock_irqrestore(&s->lock, flags);
1313 return mask;
1316 static intcm_mmap(struct file *file,struct vm_area_struct *vma)
1318 struct cm_state *s = (struct cm_state *)file->private_data;
1319 struct dmabuf *db;
1320 int ret;
1321 unsigned long size;
1323 VALIDATE_STATE(s);
1324 if(vma->vm_flags & VM_WRITE) {
1325 if((ret =prog_dmabuf(s,1)) !=0)
1326 return ret;
1327 db = &s->dma_dac;
1328 }else if(vma->vm_flags & VM_READ) {
1329 if((ret =prog_dmabuf(s,0)) !=0)
1330 return ret;
1331 db = &s->dma_adc;
1332 }else
1333 return-EINVAL;
1334 if(vma->vm_offset !=0)
1335 return-EINVAL;
1336 size = vma->vm_end - vma->vm_start;
1337 if(size > (PAGE_SIZE << db->buforder))
1338 return-EINVAL;
1339 if(remap_page_range(vma->vm_start,virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
1340 return-EAGAIN;
1341 db->mapped =1;
1342 return0;
1345 static intcm_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
1347 struct cm_state *s = (struct cm_state *)file->private_data;
1348 unsigned long flags;
1349 audio_buf_info abinfo;
1350 count_info cinfo;
1351 int val, mapped, ret;
1352 unsigned char fmtm, fmtd;
1354 VALIDATE_STATE(s);
1355 mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
1356 ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
1357 switch(cmd) {
1358 case OSS_GETVERSION:
1359 returnput_user(SOUND_VERSION, (int*)arg);
1361 case SNDCTL_DSP_SYNC:
1362 if(file->f_mode & FMODE_WRITE)
1363 returndrain_dac(s,0/*file->f_flags & O_NONBLOCK*/);
1364 return0;
1366 case SNDCTL_DSP_SETDUPLEX:
1367 return0;
1369 case SNDCTL_DSP_GETCAPS:
1370 returnput_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int*)arg);
1372 case SNDCTL_DSP_RESET:
1373 if(file->f_mode & FMODE_WRITE) {
1374 stop_dac(s);
1375 synchronize_irq();
1376 s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes =0;
1378 if(file->f_mode & FMODE_READ) {
1379 stop_adc(s);
1380 synchronize_irq();
1381 s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes =0;
1383 return0;
1385 case SNDCTL_DSP_SPEED:
1386 get_user_ret(val, (int*)arg, -EFAULT);
1387 if(val >=0) {
1388 if(file->f_mode & FMODE_READ) {
1389 stop_adc(s);
1390 s->dma_adc.ready =0;
1391 set_adc_rate(s, val);
1393 if(file->f_mode & FMODE_WRITE) {
1394 stop_dac(s);
1395 s->dma_dac.ready =0;
1396 set_dac_rate(s, val);
1399 returnput_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int*)arg);
1401 case SNDCTL_DSP_STEREO:
1402 get_user_ret(val, (int*)arg, -EFAULT);
1403 fmtd =0;
1404 fmtm = ~0;
1405 if(file->f_mode & FMODE_READ) {
1406 stop_adc(s);
1407 s->dma_adc.ready =0;
1408 if(val)
1409 fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
1410 else
1411 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
1413 if(file->f_mode & FMODE_WRITE) {
1414 stop_dac(s);
1415 s->dma_dac.ready =0;
1416 if(val)
1417 fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
1418 else
1419 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
1421 set_fmt(s, fmtm, fmtd);
1422 return0;
1424 case SNDCTL_DSP_CHANNELS:
1425 get_user_ret(val, (int*)arg, -EFAULT);
1426 if(val !=0) {
1427 fmtd =0;
1428 fmtm = ~0;
1429 if(file->f_mode & FMODE_READ) {
1430 stop_adc(s);
1431 s->dma_adc.ready =0;
1432 if(val >=2)
1433 fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
1434 else
1435 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
1437 if(file->f_mode & FMODE_WRITE) {
1438 stop_dac(s);
1439 s->dma_dac.ready =0;
1440 if(val >=2)
1441 fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
1442 else
1443 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
1445 set_fmt(s, fmtm, fmtd);
1447 returnput_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT)
1448 : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ?2:1, (int*)arg);
1450 case SNDCTL_DSP_GETFMTS:/* Returns a mask */
1451 returnput_user(AFMT_S16_LE|AFMT_U8, (int*)arg);
1453 case SNDCTL_DSP_SETFMT:/* Selects ONE fmt*/
1454 get_user_ret(val, (int*)arg, -EFAULT);
1455 if(val != AFMT_QUERY) {
1456 fmtd =0;
1457 fmtm = ~0;
1458 if(file->f_mode & FMODE_READ) {
1459 stop_adc(s);
1460 s->dma_adc.ready =0;
1461 if(val == AFMT_S16_LE)
1462 fmtd |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
1463 else
1464 fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_ADCSHIFT);
1466 if(file->f_mode & FMODE_WRITE) {
1467 stop_dac(s);
1468 s->dma_dac.ready =0;
1469 if(val == AFMT_S16_LE)
1470 fmtd |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
1471 else
1472 fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_DACSHIFT);
1474 set_fmt(s, fmtm, fmtd);
1476 returnput_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT)
1477 : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? AFMT_S16_LE : AFMT_U8, (int*)arg);
1479 case SNDCTL_DSP_POST:
1480 return0;
1482 case SNDCTL_DSP_GETTRIGGER:
1483 val =0;
1484 if(file->f_mode & FMODE_READ && s->enable & CM_CENABLE_RE)
1485 val |= PCM_ENABLE_INPUT;
1486 if(file->f_mode & FMODE_WRITE && s->enable & CM_CENABLE_PE)
1487 val |= PCM_ENABLE_OUTPUT;
1488 returnput_user(val, (int*)arg);
1490 case SNDCTL_DSP_SETTRIGGER:
1491 get_user_ret(val, (int*)arg, -EFAULT);
1492 if(file->f_mode & FMODE_READ) {
1493 if(val & PCM_ENABLE_INPUT) {
1494 if(!s->dma_adc.ready && (ret =prog_dmabuf(s,1)))
1495 return ret;
1496 start_adc(s);
1497 }else
1498 stop_adc(s);
1500 if(file->f_mode & FMODE_WRITE) {
1501 if(val & PCM_ENABLE_OUTPUT) {
1502 if(!s->dma_dac.ready && (ret =prog_dmabuf(s,0)))
1503 return ret;
1504 start_dac(s);
1505 }else
1506 stop_dac(s);
1508 return0;
1510 case SNDCTL_DSP_GETOSPACE:
1511 if(!(file->f_mode & FMODE_WRITE))
1512 return-EINVAL;
1513 if(!(s->enable & CM_CENABLE_PE) && (val =prog_dmabuf(s,0)) !=0)
1514 return val;
1515 spin_lock_irqsave(&s->lock, flags);
1516 cm_update_ptr(s);
1517 abinfo.fragsize = s->dma_dac.fragsize;
1518 abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
1519 abinfo.fragstotal = s->dma_dac.numfrag;
1520 abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
1521 spin_unlock_irqrestore(&s->lock, flags);
1522 returncopy_to_user((void*)arg, &abinfo,sizeof(abinfo)) ? -EFAULT :0;
1524 case SNDCTL_DSP_GETISPACE:
1525 if(!(file->f_mode & FMODE_READ))
1526 return-EINVAL;
1527 if(!(s->enable & CM_CENABLE_RE) && (val =prog_dmabuf(s,1)) !=0)
1528 return val;
1529 spin_lock_irqsave(&s->lock, flags);
1530 cm_update_ptr(s);
1531 abinfo.fragsize = s->dma_adc.fragsize;
1532 abinfo.bytes = s->dma_adc.count;
1533 abinfo.fragstotal = s->dma_adc.numfrag;
1534 abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
1535 spin_unlock_irqrestore(&s->lock, flags);
1536 returncopy_to_user((void*)arg, &abinfo,sizeof(abinfo)) ? -EFAULT :0;
1538 case SNDCTL_DSP_NONBLOCK:
1539 file->f_flags |= O_NONBLOCK;
1540 return0;
1542 case SNDCTL_DSP_GETODELAY:
1543 if(!(file->f_mode & FMODE_WRITE))
1544 return-EINVAL;
1545 spin_lock_irqsave(&s->lock, flags);
1546 cm_update_ptr(s);
1547 val = s->dma_dac.count;
1548 spin_unlock_irqrestore(&s->lock, flags);
1549 returnput_user(val, (int*)arg);
1551 case SNDCTL_DSP_GETIPTR:
1552 if(!(file->f_mode & FMODE_READ))
1553 return-EINVAL;
1554 spin_lock_irqsave(&s->lock, flags);
1555 cm_update_ptr(s);
1556 cinfo.bytes = s->dma_adc.total_bytes;
1557 cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
1558 cinfo.ptr = s->dma_adc.hwptr;
1559 if(s->dma_adc.mapped)
1560 s->dma_adc.count &= s->dma_adc.fragsize-1;
1561 spin_unlock_irqrestore(&s->lock, flags);
1562 returncopy_to_user((void*)arg, &cinfo,sizeof(cinfo));
1564 case SNDCTL_DSP_GETOPTR:
1565 if(!(file->f_mode & FMODE_WRITE))
1566 return-EINVAL;
1567 spin_lock_irqsave(&s->lock, flags);
1568 cm_update_ptr(s);
1569 cinfo.bytes = s->dma_dac.total_bytes;
1570 cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
1571 cinfo.ptr = s->dma_dac.hwptr;
1572 if(s->dma_dac.mapped)
1573 s->dma_dac.count &= s->dma_dac.fragsize-1;
1574 spin_unlock_irqrestore(&s->lock, flags);
1575 returncopy_to_user((void*)arg, &cinfo,sizeof(cinfo));
1577 case SNDCTL_DSP_GETBLKSIZE:
1578 if(file->f_mode & FMODE_WRITE) {
1579 if((val =prog_dmabuf(s,0)))
1580 return val;
1581 returnput_user(s->dma_dac.fragsize, (int*)arg);
1583 if((val =prog_dmabuf(s,1)))
1584 return val;
1585 returnput_user(s->dma_adc.fragsize, (int*)arg);
1587 case SNDCTL_DSP_SETFRAGMENT:
1588 get_user_ret(val, (int*)arg, -EFAULT);
1589 if(file->f_mode & FMODE_READ) {
1590 s->dma_adc.ossfragshift = val &0xffff;
1591 s->dma_adc.ossmaxfrags = (val >>16) &0xffff;
1592 if(s->dma_adc.ossfragshift <4)
1593 s->dma_adc.ossfragshift =4;
1594 if(s->dma_adc.ossfragshift >15)
1595 s->dma_adc.ossfragshift =15;
1596 if(s->dma_adc.ossmaxfrags <4)
1597 s->dma_adc.ossmaxfrags =4;
1599 if(file->f_mode & FMODE_WRITE) {
1600 s->dma_dac.ossfragshift = val &0xffff;
1601 s->dma_dac.ossmaxfrags = (val >>16) &0xffff;
1602 if(s->dma_dac.ossfragshift <4)
1603 s->dma_dac.ossfragshift =4;
1604 if(s->dma_dac.ossfragshift >15)
1605 s->dma_dac.ossfragshift =15;
1606 if(s->dma_dac.ossmaxfrags <4)
1607 s->dma_dac.ossmaxfrags =4;
1609 return0;
1611 case SNDCTL_DSP_SUBDIVIDE:
1612 if((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
1613 (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
1614 return-EINVAL;
1615 get_user_ret(val, (int*)arg, -EFAULT);
1616 if(val !=1&& val !=2&& val !=4)
1617 return-EINVAL;
1618 if(file->f_mode & FMODE_READ)
1619 s->dma_adc.subdivision = val;
1620 if(file->f_mode & FMODE_WRITE)
1621 s->dma_dac.subdivision = val;
1622 return0;
1624 case SOUND_PCM_READ_RATE:
1625 returnput_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int*)arg);
1627 case SOUND_PCM_READ_CHANNELS:
1628 returnput_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ?2:1, (int*)arg);
1630 case SOUND_PCM_READ_BITS:
1631 returnput_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ?16:8, (int*)arg);
1633 case SOUND_PCM_WRITE_FILTER:
1634 case SNDCTL_DSP_SETSYNCRO:
1635 case SOUND_PCM_READ_FILTER:
1636 return-EINVAL;
1639 returnmixer_ioctl(s, cmd, arg);
1642 static intcm_open(struct inode *inode,struct file *file)
1644 int minor =MINOR(inode->i_rdev);
1645 struct cm_state *s = devs;
1646 unsigned char fmtm = ~0, fmts =0;
1648 while(s && ((s->dev_audio ^ minor) & ~0xf))
1649 s = s->next;
1650 if(!s)
1651 return-ENODEV;
1652 VALIDATE_STATE(s);
1653 file->private_data = s;
1654 /* wait for device to become free */
1655 down(&s->open_sem);
1656 while(s->open_mode & file->f_mode) {
1657 if(file->f_flags & O_NONBLOCK) {
1658 up(&s->open_sem);
1659 return-EBUSY;
1661 up(&s->open_sem);
1662 interruptible_sleep_on(&s->open_wait);
1663 if(signal_pending(current))
1664 return-ERESTARTSYS;
1665 down(&s->open_sem);
1667 if(file->f_mode & FMODE_READ) {
1668 fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT);
1669 if((minor &0xf) == SND_DEV_DSP16)
1670 fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
1671 s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision =0;
1672 set_adc_rate(s,8000);
1674 if(file->f_mode & FMODE_WRITE) {
1675 fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT);
1676 if((minor &0xf) == SND_DEV_DSP16)
1677 fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
1678 s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision =0;
1679 set_dac_rate(s,8000);
1681 set_fmt(s, fmtm, fmts);
1682 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
1683 up(&s->open_sem);
1684 MOD_INC_USE_COUNT;
1685 return0;
1688 static intcm_release(struct inode *inode,struct file *file)
1690 struct cm_state *s = (struct cm_state *)file->private_data;
1692 VALIDATE_STATE(s);
1693 if(file->f_mode & FMODE_WRITE)
1694 drain_dac(s, file->f_flags & O_NONBLOCK);
1695 down(&s->open_sem);
1696 if(file->f_mode & FMODE_WRITE) {
1697 stop_dac(s);
1698 dealloc_dmabuf(&s->dma_dac);
1700 if(file->f_mode & FMODE_READ) {
1701 stop_adc(s);
1702 dealloc_dmabuf(&s->dma_adc);
1704 s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
1705 up(&s->open_sem);
1706 wake_up(&s->open_wait);
1707 MOD_DEC_USE_COUNT;
1708 return0;
1711 static/*const*/struct file_operations cm_audio_fops = {
1712 &cm_llseek,
1713 &cm_read,
1714 &cm_write,
1715 NULL,/* readdir */
1716 &cm_poll,
1717 &cm_ioctl,
1718 &cm_mmap,
1719 &cm_open,
1720 NULL,/* flush */
1721 &cm_release,
1722 NULL,/* fsync */
1723 NULL,/* fasync */
1724 NULL,/* check_media_change */
1725 NULL,/* revalidate */
1726 NULL,/* lock */
1729 #ifdef CONFIG_SOUND_CMPCI_MIDI
1730 /* --------------------------------------------------------------------- */
1732 static ssize_t cm_midi_read(struct file *file,char*buffer,size_t count, loff_t *ppos)
1734 struct cm_state *s = (struct cm_state *)file->private_data;
1735 ssize_t ret;
1736 unsigned long flags;
1737 unsigned ptr;
1738 int cnt;
1740 VALIDATE_STATE(s);
1741 if(ppos != &file->f_pos)
1742 return-ESPIPE;
1743 if(!access_ok(VERIFY_WRITE, buffer, count))
1744 return-EFAULT;
1745 ret =0;
1746 while(count >0) {
1747 spin_lock_irqsave(&s->lock, flags);
1748 ptr = s->midi.ird;
1749 cnt = MIDIINBUF - ptr;
1750 if(s->midi.icnt < cnt)
1751 cnt = s->midi.icnt;
1752 spin_unlock_irqrestore(&s->lock, flags);
1753 if(cnt > count)
1754 cnt = count;
1755 if(cnt <=0) {
1756 if(file->f_flags & O_NONBLOCK)
1757 return ret ? ret : -EAGAIN;
1758 interruptible_sleep_on(&s->midi.iwait);
1759 if(signal_pending(current))
1760 return ret ? ret : -ERESTARTSYS;
1761 continue;
1763 if(copy_to_user(buffer, s->midi.ibuf + ptr, cnt))
1764 return ret ? ret : -EFAULT;
1765 ptr = (ptr + cnt) % MIDIINBUF;
1766 spin_lock_irqsave(&s->lock, flags);
1767 s->midi.ird = ptr;
1768 s->midi.icnt -= cnt;
1769 spin_unlock_irqrestore(&s->lock, flags);
1770 count -= cnt;
1771 buffer += cnt;
1772 ret += cnt;
1774 return ret;
1777 static ssize_t cm_midi_write(struct file *file,const char*buffer,size_t count, loff_t *ppos)
1779 struct cm_state *s = (struct cm_state *)file->private_data;
1780 ssize_t ret;
1781 unsigned long flags;
1782 unsigned ptr;
1783 int cnt;
1785 VALIDATE_STATE(s);
1786 if(ppos != &file->f_pos)
1787 return-ESPIPE;
1788 if(!access_ok(VERIFY_READ, buffer, count))
1789 return-EFAULT;
1790 ret =0;
1791 while(count >0) {
1792 spin_lock_irqsave(&s->lock, flags);
1793 ptr = s->midi.owr;
1794 cnt = MIDIOUTBUF - ptr;
1795 if(s->midi.ocnt + cnt > MIDIOUTBUF)
1796 cnt = MIDIOUTBUF - s->midi.ocnt;
1797 if(cnt <=0)
1798 cm_handle_midi(s);
1799 spin_unlock_irqrestore(&s->lock, flags);
1800 if(cnt > count)
1801 cnt = count;
1802 if(cnt <=0) {
1803 if(file->f_flags & O_NONBLOCK)
1804 return ret ? ret : -EAGAIN;
1805 interruptible_sleep_on(&s->midi.owait);
1806 if(signal_pending(current))
1807 return ret ? ret : -ERESTARTSYS;
1808 continue;
1810 if(copy_from_user(s->midi.obuf + ptr, buffer, cnt))
1811 return ret ? ret : -EFAULT;
1812 ptr = (ptr + cnt) % MIDIOUTBUF;
1813 spin_lock_irqsave(&s->lock, flags);
1814 s->midi.owr = ptr;
1815 s->midi.ocnt += cnt;
1816 spin_unlock_irqrestore(&s->lock, flags);
1817 count -= cnt;
1818 buffer += cnt;
1819 ret += cnt;
1820 spin_lock_irqsave(&s->lock, flags);
1821 cm_handle_midi(s);
1822 spin_unlock_irqrestore(&s->lock, flags);
1824 return ret;
1827 static unsigned intcm_midi_poll(struct file *file,struct poll_table_struct *wait)
1829 struct cm_state *s = (struct cm_state *)file->private_data;
1830 unsigned long flags;
1831 unsigned int mask =0;
1833 VALIDATE_STATE(s);
1834 if(file->f_mode & FMODE_WRITE)
1835 poll_wait(file, &s->midi.owait, wait);
1836 if(file->f_mode & FMODE_READ)
1837 poll_wait(file, &s->midi.iwait, wait);
1838 spin_lock_irqsave(&s->lock, flags);
1839 if(file->f_mode & FMODE_READ) {
1840 if(s->midi.icnt >0)
1841 mask |= POLLIN | POLLRDNORM;
1843 if(file->f_mode & FMODE_WRITE) {
1844 if(s->midi.ocnt < MIDIOUTBUF)
1845 mask |= POLLOUT | POLLWRNORM;
1847 spin_unlock_irqrestore(&s->lock, flags);
1848 return mask;
1851 static intcm_midi_open(struct inode *inode,struct file *file)
1853 int minor =MINOR(inode->i_rdev);
1854 struct cm_state *s = devs;
1855 unsigned long flags;
1857 while(s && s->dev_midi != minor)
1858 s = s->next;
1859 if(!s)
1860 return-ENODEV;
1861 VALIDATE_STATE(s);
1862 file->private_data = s;
1863 /* wait for device to become free */
1864 down(&s->open_sem);
1865 while(s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
1866 if(file->f_flags & O_NONBLOCK) {
1867 up(&s->open_sem);
1868 return-EBUSY;
1870 up(&s->open_sem);
1871 interruptible_sleep_on(&s->open_wait);
1872 if(signal_pending(current))
1873 return-ERESTARTSYS;
1874 down(&s->open_sem);
1876 spin_lock_irqsave(&s->lock, flags);
1877 if(!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
1878 s->midi.ird = s->midi.iwr = s->midi.icnt =0;
1879 s->midi.ord = s->midi.owr = s->midi.ocnt =0;
1880 /* enable MPU-401 */
1881 outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) |4, s->iobase + CODEC_CMI_FUNCTRL1);
1882 outb(0xff, s->iomidi+1);/* reset command */
1883 if(!(inb(s->iomidi+1) &0x80))
1884 inb(s->iomidi);
1885 outb(0x3f, s->iomidi+1);/* uart command */
1886 if(!(inb(s->iomidi+1) &0x80))
1887 inb(s->iomidi);
1888 s->midi.ird = s->midi.iwr = s->midi.icnt =0;
1889 init_timer(&s->midi.timer);
1890 s->midi.timer.expires = jiffies+1;
1891 s->midi.timer.data = (unsigned long)s;
1892 s->midi.timer.function = cm_midi_timer;
1893 add_timer(&s->midi.timer);
1895 if(file->f_mode & FMODE_READ) {
1896 s->midi.ird = s->midi.iwr = s->midi.icnt =0;
1898 if(file->f_mode & FMODE_WRITE) {
1899 s->midi.ord = s->midi.owr = s->midi.ocnt =0;
1901 spin_unlock_irqrestore(&s->lock, flags);
1902 s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
1903 up(&s->open_sem);
1904 MOD_INC_USE_COUNT;
1905 return0;
1908 static intcm_midi_release(struct inode *inode,struct file *file)
1910 struct cm_state *s = (struct cm_state *)file->private_data;
1911 DECLARE_WAITQUEUE(wait, current);
1912 unsigned long flags;
1913 unsigned count, tmo;
1915 VALIDATE_STATE(s);
1917 if(file->f_mode & FMODE_WRITE) {
1918 current->state = TASK_INTERRUPTIBLE;
1919 add_wait_queue(&s->midi.owait, &wait);
1920 for(;;) {
1921 spin_lock_irqsave(&s->lock, flags);
1922 count = s->midi.ocnt;
1923 spin_unlock_irqrestore(&s->lock, flags);
1924 if(count <=0)
1925 break;
1926 if(signal_pending(current))
1927 break;
1928 if(file->f_flags & O_NONBLOCK) {
1929 remove_wait_queue(&s->midi.owait, &wait);
1930 current->state = TASK_RUNNING;
1931 return-EBUSY;
1933 tmo = (count * HZ) /3100;
1934 if(!schedule_timeout(tmo ? :1) && tmo)
1935 printk(KERN_DEBUG "cm: midi timed out??\n");
1937 remove_wait_queue(&s->midi.owait, &wait);
1938 current->state = TASK_RUNNING;
1940 down(&s->open_sem);
1941 s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE);
1942 spin_lock_irqsave(&s->lock, flags);
1943 if(!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
1944 del_timer(&s->midi.timer);
1945 outb(0xff, s->iomidi+1);/* reset command */
1946 if(!(inb(s->iomidi+1) &0x80))
1947 inb(s->iomidi);
1948 /* disable MPU-401 */
1949 outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) & ~4, s->iobase + CODEC_CMI_FUNCTRL1);
1951 spin_unlock_irqrestore(&s->lock, flags);
1952 up(&s->open_sem);
1953 wake_up(&s->open_wait);
1954 MOD_DEC_USE_COUNT;
1955 return0;
1958 static/*const*/struct file_operations cm_midi_fops = {
1959 &cm_llseek,
1960 &cm_midi_read,
1961 &cm_midi_write,
1962 NULL,/* readdir */
1963 &cm_midi_poll,
1964 NULL,/* ioctl */
1965 NULL,/* mmap */
1966 &cm_midi_open,
1967 NULL,/* flush */
1968 &cm_midi_release,
1969 NULL,/* fsync */
1970 NULL,/* fasync */
1971 NULL,/* check_media_change */
1972 NULL,/* revalidate */
1973 NULL,/* lock */
1975 #endif
1977 /* --------------------------------------------------------------------- */
1979 #ifdef CONFIG_SOUND_CMPCI_FM
1980 static intcm_dmfm_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
1982 static const unsigned char op_offset[18] = {
1983 0x00,0x01,0x02,0x03,0x04,0x05,
1984 0x08,0x09,0x0A,0x0B,0x0C,0x0D,
1985 0x10,0x11,0x12,0x13,0x14,0x15
1987 struct cm_state *s = (struct cm_state *)file->private_data;
1988 struct dm_fm_voice v;
1989 struct dm_fm_note n;
1990 struct dm_fm_params p;
1991 unsigned int io;
1992 unsigned int regb;
1994 switch(cmd) {
1995 case FM_IOCTL_RESET:
1996 for(regb =0xb0; regb <0xb9; regb++) {
1997 outb(regb, s->iosynth);
1998 outb(0, s->iosynth+1);
1999 outb(regb, s->iosynth+2);
2000 outb(0, s->iosynth+3);
2002 return0;
2004 case FM_IOCTL_PLAY_NOTE:
2005 if(copy_from_user(&n, (void*)arg,sizeof(n)))
2006 return-EFAULT;
2007 if(n.voice >=18)
2008 return-EINVAL;
2009 if(n.voice >=9) {
2010 regb = n.voice -9;
2011 io = s->iosynth+2;
2012 }else{
2013 regb = n.voice;
2014 io = s->iosynth;
2016 outb(0xa0+ regb, io);
2017 outb(n.fnum &0xff, io+1);
2018 outb(0xb0+ regb, io);
2019 outb(((n.fnum >>8) &3) | ((n.octave &7) <<2) | ((n.key_on &1) <<5), io+1);
2020 return0;
2022 case FM_IOCTL_SET_VOICE:
2023 if(copy_from_user(&v, (void*)arg,sizeof(v)))
2024 return-EFAULT;
2025 if(v.voice >=18)
2026 return-EINVAL;
2027 regb = op_offset[v.voice];
2028 io = s->iosynth + ((v.op &1) <<1);
2029 outb(0x20+ regb, io);
2030 outb(((v.am &1) <<7) | ((v.vibrato &1) <<6) | ((v.do_sustain &1) <<5) |
2031 ((v.kbd_scale &1) <<4) | (v.harmonic &0xf), io+1);
2032 outb(0x40+ regb, io);
2033 outb(((v.scale_level &0x3) <<6) | (v.volume &0x3f), io+1);
2034 outb(0x60+ regb, io);
2035 outb(((v.attack &0xf) <<4) | (v.decay &0xf), io+1);
2036 outb(0x80+ regb, io);
2037 outb(((v.sustain &0xf) <<4) | (v.release &0xf), io+1);
2038 outb(0xe0+ regb, io);
2039 outb(v.waveform &0x7, io+1);
2040 if(n.voice >=9) {
2041 regb = n.voice -9;
2042 io = s->iosynth+2;
2043 }else{
2044 regb = n.voice;
2045 io = s->iosynth;
2047 outb(0xc0+ regb, io);
2048 outb(((v.right &1) <<5) | ((v.left &1) <<4) | ((v.feedback &7) <<1) |
2049 (v.connection &1), io+1);
2050 return0;
2052 case FM_IOCTL_SET_PARAMS:
2053 if(copy_from_user(&p, (void*)arg,sizeof(p)))
2054 return-EFAULT;
2055 outb(0x08, s->iosynth);
2056 outb((p.kbd_split &1) <<6, s->iosynth+1);
2057 outb(0xbd, s->iosynth);
2058 outb(((p.am_depth &1) <<7) | ((p.vib_depth &1) <<6) | ((p.rhythm &1) <<5) | ((p.bass &1) <<4) |
2059 ((p.snare &1) <<3) | ((p.tomtom &1) <<2) | ((p.cymbal &1) <<1) | (p.hihat &1), s->iosynth+1);
2060 return0;
2062 case FM_IOCTL_SET_OPL:
2063 outb(4, s->iosynth+2);
2064 outb(arg, s->iosynth+3);
2065 return0;
2067 case FM_IOCTL_SET_MODE:
2068 outb(5, s->iosynth+2);
2069 outb(arg &1, s->iosynth+3);
2070 return0;
2072 default:
2073 return-EINVAL;
2077 static intcm_dmfm_open(struct inode *inode,struct file *file)
2079 int minor =MINOR(inode->i_rdev);
2080 struct cm_state *s = devs;
2082 while(s && s->dev_dmfm != minor)
2083 s = s->next;
2084 if(!s)
2085 return-ENODEV;
2086 VALIDATE_STATE(s);
2087 file->private_data = s;
2088 /* wait for device to become free */
2089 down(&s->open_sem);
2090 while(s->open_mode & FMODE_DMFM) {
2091 if(file->f_flags & O_NONBLOCK) {
2092 up(&s->open_sem);
2093 return-EBUSY;
2095 up(&s->open_sem);
2096 interruptible_sleep_on(&s->open_wait);
2097 if(signal_pending(current))
2098 return-ERESTARTSYS;
2099 down(&s->open_sem);
2101 /* init the stuff */
2102 outb(1, s->iosynth);
2103 outb(0x20, s->iosynth+1);/* enable waveforms */
2104 outb(4, s->iosynth+2);
2105 outb(0, s->iosynth+3);/* no 4op enabled */
2106 outb(5, s->iosynth+2);
2107 outb(1, s->iosynth+3);/* enable OPL3 */
2108 s->open_mode |= FMODE_DMFM;
2109 up(&s->open_sem);
2110 MOD_INC_USE_COUNT;
2111 return0;
2114 static intcm_dmfm_release(struct inode *inode,struct file *file)
2116 struct cm_state *s = (struct cm_state *)file->private_data;
2117 unsigned int regb;
2119 VALIDATE_STATE(s);
2120 down(&s->open_sem);
2121 s->open_mode &= ~FMODE_DMFM;
2122 for(regb =0xb0; regb <0xb9; regb++) {
2123 outb(regb, s->iosynth);
2124 outb(0, s->iosynth+1);
2125 outb(regb, s->iosynth+2);
2126 outb(0, s->iosynth+3);
2128 up(&s->open_sem);
2129 wake_up(&s->open_wait);
2130 MOD_DEC_USE_COUNT;
2131 return0;
2134 static/*const*/struct file_operations cm_dmfm_fops = {
2135 &cm_llseek,
2136 NULL,/* read */
2137 NULL,/* write */
2138 NULL,/* readdir */
2139 NULL,/* poll */
2140 &cm_dmfm_ioctl,
2141 NULL,/* mmap */
2142 &cm_dmfm_open,
2143 NULL,/* flush */
2144 &cm_dmfm_release,
2145 NULL,/* fsync */
2146 NULL,/* fasync */
2147 NULL,/* check_media_change */
2148 NULL,/* revalidate */
2149 NULL,/* lock */
2151 #endif/* CONFIG_SOUND_CMPCI_FM */
2153 /* --------------------------------------------------------------------- */
2155 /* maximum number of devices */
2156 #define NR_DEVICE 5
2158 #if 0
2159 static int reverb[NR_DEVICE] = {0, };
2161 static int wavetable[NR_DEVICE] = {0, };
2162 #endif
2164 /* --------------------------------------------------------------------- */
2166 static struct initvol {
2167 int mixch;
2168 int vol;
2169 } initvol[] __initdata = {
2170 { SOUND_MIXER_WRITE_CD,0x4040},
2171 { SOUND_MIXER_WRITE_LINE,0x4040},
2172 { SOUND_MIXER_WRITE_MIC,0x4040},
2173 { SOUND_MIXER_WRITE_SYNTH,0x4040},
2174 { SOUND_MIXER_WRITE_VOLUME,0x4040},
2175 { SOUND_MIXER_WRITE_PCM,0x4040}
2178 #ifdef MODULE
2179 int __init init_module(void)
2180 #else
2181 int __init init_cmpci(void)
2182 #endif
2184 struct cm_state *s;
2185 struct pci_dev *pcidev = NULL;
2186 mm_segment_t fs;
2187 int i, val, index =0;
2188 struct{
2189 unsigned short deviceid;
2190 char*devicename;
2191 } devicetable[] =
2193 { PCI_DEVICE_ID_CMEDIA_CM8338A,"CM8338A"},
2194 { PCI_DEVICE_ID_CMEDIA_CM8338B,"CM8338B"},
2195 { PCI_DEVICE_ID_CMEDIA_CM8738,"CM8738"},
2197 char*devicename ="unknown";
2199 #ifdef CONFIG_PCI
2200 if(!pci_present())/* No PCI bus in this machine! */
2201 #endif
2202 return-ENODEV;
2203 printk(KERN_INFO "cm: version v1.1 time " __TIME__ " " __DATE__ "\n");
2204 #if 0
2205 if(!(wavetable_mem =__get_free_pages(GFP_KERNEL,20-PAGE_SHIFT)))
2206 printk(KERN_INFO "cm: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
2207 #endif
2208 while(index < NR_DEVICE && pcidev == NULL && (
2209 (pcidev =pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, pcidev)) ||
2210 (pcidev =pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, pcidev)) ||
2211 (pcidev =pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, pcidev)))) {
2212 if(pcidev->irq ==0)
2213 continue;
2214 if(!(s =kmalloc(sizeof(struct cm_state), GFP_KERNEL))) {
2215 printk(KERN_WARNING "cm: out of memory\n");
2216 continue;
2218 /* search device name */
2219 for(i =0; i <sizeof(devicetable) /sizeof(devicetable[0]); i++)
2221 if(devicetable[i].deviceid == pcidev->device)
2223 devicename = devicetable[i].devicename;
2224 break;
2227 memset(s,0,sizeof(struct cm_state));
2228 init_waitqueue_head(&s->dma_adc.wait);
2229 init_waitqueue_head(&s->dma_dac.wait);
2230 init_waitqueue_head(&s->open_wait);
2231 init_waitqueue_head(&s->midi.iwait);
2232 init_waitqueue_head(&s->midi.owait);
2233 init_MUTEX(&s->open_sem);
2234 s->magic = CM_MAGIC;
2235 s->iobase = pcidev->resource[0].start;
2236 #ifdef CONFIG_SOUND_CMPCI_FM
2237 s->iosynth =0x388;
2238 #endif
2239 #ifdef CONFIG_SOUND_CMPCI_MIDI
2240 s->iomidi =0x330;
2241 #endif
2242 if(s->iobase ==0)
2243 continue;
2244 s->irq = pcidev->irq;
2246 if(check_region(s->iobase, CM_EXTENT_CODEC)) {
2247 printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
2248 goto err_region5;
2250 request_region(s->iobase, CM_EXTENT_CODEC,"cmpci");
2251 #ifdef CONFIG_SOUND_CMPCI_MIDI
2252 if(check_region(s->iomidi, CM_EXTENT_MIDI)) {
2253 printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
2254 goto err_region4;
2256 request_region(s->iomidi, CM_EXTENT_MIDI,"cmpci Midi");
2257 /* set IO based at 0x330 */
2258 outb(inb(s->iobase + CODEC_CMI_LEGACY_CTRL +3) & ~0x60, s->iobase + CODEC_CMI_LEGACY_CTRL +3);
2259 #endif
2260 #ifdef CONFIG_SOUND_CMPCI_FM
2261 if(check_region(s->iosynth, CM_EXTENT_SYNTH)) {
2262 printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
2263 goto err_region1;
2265 request_region(s->iosynth, CM_EXTENT_SYNTH,"cmpci FM");
2266 /* enable FM */
2267 outb(inb(s->iobase + CODEC_CMI_MISC_CTRL +2) |8, s->iobase + CODEC_CMI_MISC_CTRL);
2268 #endif
2269 /* initialize codec registers */
2270 outb(0, s->iobase + CODEC_CMI_INT_HLDCLR +2);/* disable ints */
2271 outb(0, s->iobase + CODEC_CMI_FUNCTRL0 +2);/* reset channels */
2272 /* reset mixer */
2273 wrmixer(s, DSP_MIX_DATARESETIDX,0);
2275 /* request irq */
2276 if(request_irq(s->irq, cm_interrupt, SA_SHIRQ,"cmpci", s)) {
2277 printk(KERN_ERR "cm: irq %u in use\n", s->irq);
2278 goto err_irq;
2280 printk(KERN_INFO "cm: found %s adapter at io %#06x irq %u\n",
2281 devicename, s->iobase, s->irq);
2282 /* register devices */
2283 if((s->dev_audio =register_sound_dsp(&cm_audio_fops, -1)) <0)
2284 goto err_dev1;
2285 if((s->dev_mixer =register_sound_mixer(&cm_mixer_fops, -1)) <0)
2286 goto err_dev2;
2287 #ifdef CONFIG_SOUND_CMPCI_MIDI
2288 if((s->dev_midi =register_sound_midi(&cm_midi_fops, -1)) <0)
2289 goto err_dev3;
2290 #endif
2291 #ifdef CONFIG_SOUND_CMPCI_FM
2292 if((s->dev_dmfm =register_sound_special(&cm_dmfm_fops,15/* ?? */)) <0)
2293 goto err_dev4;
2294 #endif
2295 /* initialize the chips */
2296 fs =get_fs();
2297 set_fs(KERNEL_DS);
2298 /* set mixer output */
2299 frobindir(s, DSP_MIX_OUTMIXIDX,0x1f,0x1f);
2300 /* set mixer input */
2301 val = SOUND_MASK_LINE|SOUND_MASK_SYNTH|SOUND_MASK_CD|SOUND_MASK_MIC;
2302 mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
2303 for(i =0; i <sizeof(initvol)/sizeof(initvol[0]); i++) {
2304 val = initvol[i].vol;
2305 mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
2307 set_fs(fs);
2308 /* queue it for later freeing */
2309 s->next = devs;
2310 devs = s;
2311 index++;
2312 continue;
2314 err_dev4:
2315 unregister_sound_midi(s->dev_midi);
2316 err_dev3:
2317 unregister_sound_mixer(s->dev_mixer);
2318 err_dev2:
2319 unregister_sound_dsp(s->dev_audio);
2320 err_dev1:
2321 printk(KERN_ERR "cm: cannot register misc device\n");
2322 free_irq(s->irq, s);
2323 err_irq:
2324 #ifdef CONFIG_SOUND_CMPCI_FM
2325 release_region(s->iosynth, CM_EXTENT_SYNTH);
2326 err_region1:
2327 #endif
2328 #ifdef CONFIG_SOUND_CMPCI_MIDI
2329 release_region(s->iomidi, CM_EXTENT_MIDI);
2330 #endif
2331 err_region4:
2332 release_region(s->iobase, CM_EXTENT_CODEC);
2333 err_region5:
2334 kfree_s(s,sizeof(struct cm_state));
2336 if(!devs) {
2337 if(wavetable_mem)
2338 free_pages(wavetable_mem,20-PAGE_SHIFT);
2339 return-ENODEV;
2341 return0;
2344 /* --------------------------------------------------------------------- */
2346 #ifdef MODULE
2348 #if 0
2349 MODULE_PARM(wavetable,"1-"__MODULE_STRING(NR_DEVICE)"i");
2350 MODULE_PARM_DESC(wavetable,"if 1 the wavetable synth is enabled");
2351 #endif
2353 MODULE_AUTHOR("ChenLi Tien, cltien@home.com");
2354 MODULE_DESCRIPTION("CMPCI Audio Driver");
2356 voidcleanup_module(void)
2358 struct cm_state *s;
2360 while((s = devs)) {
2361 devs = devs->next;
2362 outb(0, s->iobase + CODEC_CMI_INT_HLDCLR +2);/* disable ints */
2363 synchronize_irq();
2364 outb(0, s->iobase + CODEC_CMI_FUNCTRL0 +2);/* reset channels */
2365 free_irq(s->irq, s);
2367 /* reset mixer */
2368 wrmixer(s, DSP_MIX_DATARESETIDX,0);
2370 release_region(s->iobase, CM_EXTENT_CODEC);
2371 #ifdef CONFIG_SOUND_CMPCI_MIDI
2372 release_region(s->iomidi, CM_EXTENT_MIDI);
2373 #endif
2374 #ifdef CONFIG_SOUND_CMPCI_FM
2375 release_region(s->iosynth, CM_EXTENT_SYNTH);
2376 #endif
2377 unregister_sound_dsp(s->dev_audio);
2378 unregister_sound_mixer(s->dev_mixer);
2379 #ifdef CONFIG_SOUND_CMPCI_MIDI
2380 unregister_sound_midi(s->dev_midi);
2381 #endif
2382 #ifdef CONFIG_SOUND_CMPCI_FM
2383 unregister_sound_special(s->dev_dmfm);
2384 #endif
2385 kfree_s(s,sizeof(struct cm_state));
2387 if(wavetable_mem)
2388 free_pages(wavetable_mem,20-PAGE_SHIFT);
2389 printk(KERN_INFO "cm: unloading\n");
2392 #endif/* MODULE */
close