source: cmedia/trunk/Cmpci/Linux/cmpci.403@ 577

Last change on this file since 577 was 354, checked in by stevenhl, 18 years ago

Import untested baseline cmedia sources, work products and binaries
Binaries and work products should be deleted from repository.
once new builds are verified to work.

File size: 97.1 KB
Line 
1/*****************************************************************************/
2
3/*
4 * cmpci.c -- C-Media PCI audio driver.
5 *
6 * Copyright (C) 1999 ChenLi Tien (cltien@home.com)
7 * C-media support (support@cmedia.com.tw)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * Special thanks to David C. Niemi, Jan Pfeifer
24 *
25 *
26 * Module command line parameters:
27 * none so far
28 *
29 *
30 * Supported devices:
31 * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible
32 * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible
33 * /dev/midi simple MIDI UART interface, no ioctl
34 *
35 * The card has both an FM and a Wavetable synth, but I have to figure
36 * out first how to drive them...
37 *
38 * Revision history
39 * 06.05.98 0.1 Initial release
40 * 10.05.98 0.2 Fixed many bugs, esp. ADC rate calculation
41 * First stab at a simple midi interface (no bells&whistles)
42 * 13.05.98 0.3 Fix stupid cut&paste error: set_adc_rate was called instead of
43 * set_dac_rate in the FMODE_WRITE case in cm_open
44 * Fix hwptr out of bounds (now mpg123 works)
45 * 14.05.98 0.4 Don't allow excessive interrupt rates
46 * 08.06.98 0.5 First release using Alan Cox' soundcore instead of miscdevice
47 * 03.08.98 0.6 Do not include modversions.h
48 * Now mixer behaviour can basically be selected between
49 * "OSS documented" and "OSS actual" behaviour
50 * 31.08.98 0.7 Fix realplayer problems - dac.count issues
51 * 10.12.98 0.8 Fix drain_dac trying to wait on not yet initialized DMA
52 * 16.12.98 0.9 Fix a few f_file & FMODE_ bugs
53 * 06.01.99 0.10 remove the silly SA_INTERRUPT flag.
54 * hopefully killed the egcs section type conflict
55 * 12.03.99 0.11 cinfo.blocks should be reset after GETxPTR ioctl.
56 * reported by Johan Maes <joma@telindus.be>
57 * 22.03.99 0.12 return EAGAIN instead of EBUSY when O_NONBLOCK
58 * read/write cannot be executed
59 * 18.08.99 1.5 Only deallocate DMA buffer when unloading.
60 * 02.09.99 1.6 Enable SPDIF LOOP
61 * Change the mixer read back
62 * 21.09.99 2.33 Use RCS version as driver version.
63 * Add support for modem, S/PDIF loop and 4 channels.
64 * (8738 only)
65 * Fix bug cause x11amp cannot play.
66 *
67 */
68
69/*****************************************************************************/
70
71#define EXPORT_SYMTAB
72#include <linux/version.h>
73#include <linux/config.h>
74#include <linux/module.h>
75#include <linux/string.h>
76#include <linux/ioport.h>
77#include <linux/sched.h>
78#include <linux/delay.h>
79#include <linux/sound.h>
80#include <linux/malloc.h>
81#include <linux/soundcard.h>
82#include <linux/pci.h>
83#include <asm/io.h>
84#include <asm/dma.h>
85#include <linux/init.h>
86#include <linux/poll.h>
87#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
88#include <linux/spinlock.h>
89#else
90#include <asm/spinlock.h>
91#endif
92#include <asm/uaccess.h>
93#include <asm/hardirq.h>
94
95#include "dm.h"
96
97/* --------------------------------------------------------------------- */
98
99#undef OSS_DOCUMENTED_MIXER_SEMANTICS
100
101/* --------------------------------------------------------------------- */
102
103#ifndef PCI_VENDOR_ID_CMEDIA
104#define PCI_VENDOR_ID_CMEDIA 0x13F6
105#endif
106#ifndef PCI_DEVICE_ID_CMEDIA_CM8338A
107#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100
108#endif
109#ifndef PCI_DEVICE_ID_CMEDIA_CM8338B
110#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101
111#endif
112#ifndef PCI_DEVICE_ID_CMEDIA_CM8738
113#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
114#endif
115#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B
116#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
117#endif
118
119#define CM_MAGIC ((PCI_VENDOR_ID_CMEDIA<<16)|PCI_DEVICE_ID_CMEDIA_CM8338A)
120
121/*
122 * CM8338 registers definition
123 */
124
125#define CODEC_CMI_FUNCTRL0 (0x00)
126#define CODEC_CMI_FUNCTRL1 (0x04)
127#define CODEC_CMI_CHFORMAT (0x08)
128#define CODEC_CMI_INT_HLDCLR (0x0C)
129#define CODEC_CMI_INT_STATUS (0x10)
130#define CODEC_CMI_LEGACY_CTRL (0x14)
131#define CODEC_CMI_MISC_CTRL (0x18)
132#define CODEC_CMI_TDMA_POS (0x1C)
133#define CODEC_CMI_MIXER (0x20)
134#define CODEC_SB16_DATA (0x22)
135#define CODEC_SB16_ADDR (0x23)
136#define CODEC_CMI_MIXER1 (0x24)
137#define CODEC_CMI_MIXER2 (0x25)
138#define CODEC_CMI_AUX_VOL (0x26)
139#define CODEC_CMI_MISC (0x27)
140#define CODEC_CMI_AC97 (0x28)
141
142#define CODEC_CMI_CH0_FRAME1 (0x80)
143#define CODEC_CMI_CH0_FRAME2 (0x84)
144#define CODEC_CMI_CH1_FRAME1 (0x88)
145#define CODEC_CMI_CH1_FRAME2 (0x8C)
146
147#define CODEC_CMI_EXT_REG (0xF0)
148#define UCHAR unsigned char
149/*
150** Mixer registers for SB16
151*/
152
153#define DSP_MIX_DATARESETIDX ((UCHAR)(0x00))
154
155#define DSP_MIX_MASTERVOLIDX_L ((UCHAR)(0x30))
156#define DSP_MIX_MASTERVOLIDX_R ((UCHAR)(0x31))
157#define DSP_MIX_VOICEVOLIDX_L ((UCHAR)(0x32))
158#define DSP_MIX_VOICEVOLIDX_R ((UCHAR)(0x33))
159#define DSP_MIX_FMVOLIDX_L ((UCHAR)(0x34))
160#define DSP_MIX_FMVOLIDX_R ((UCHAR)(0x35))
161#define DSP_MIX_CDVOLIDX_L ((UCHAR)(0x36))
162#define DSP_MIX_CDVOLIDX_R ((UCHAR)(0x37))
163#define DSP_MIX_LINEVOLIDX_L ((UCHAR)(0x38))
164#define DSP_MIX_LINEVOLIDX_R ((UCHAR)(0x39))
165
166#define DSP_MIX_MICVOLIDX ((UCHAR)(0x3A))
167#define DSP_MIX_SPKRVOLIDX ((UCHAR)(0x3B))
168
169#define DSP_MIX_OUTMIXIDX ((UCHAR)(0x3C))
170
171#define DSP_MIX_ADCMIXIDX_L ((UCHAR)(0x3D))
172#define DSP_MIX_ADCMIXIDX_R ((UCHAR)(0x3E))
173
174#define DSP_MIX_INGAINIDX_L ((UCHAR)(0x3F))
175#define DSP_MIX_INGAINIDX_R ((UCHAR)(0x40))
176#define DSP_MIX_OUTGAINIDX_L ((UCHAR)(0x41))
177#define DSP_MIX_OUTGAINIDX_R ((UCHAR)(0x42))
178
179#define DSP_MIX_AGCIDX ((UCHAR)(0x43))
180
181#define DSP_MIX_TREBLEIDX_L ((UCHAR)(0x44))
182#define DSP_MIX_TREBLEIDX_R ((UCHAR)(0x45))
183#define DSP_MIX_BASSIDX_L ((UCHAR)(0x46))
184#define DSP_MIX_BASSIDX_R ((UCHAR)(0x47))
185#define CM_CH0_RESET 0x04
186#define CM_CH1_RESET 0x08
187#define CM_EXTENT_CODEC 0x100
188#define CM_EXTENT_MIDI 0x2
189#define CM_EXTENT_SYNTH 0x4
190#define CM_INT_CH0 1
191#define CM_INT_CH1 2
192
193#define CM_CFMT_STEREO 0x01
194#define CM_CFMT_16BIT 0x02
195#define CM_CFMT_MASK 0x03
196#define CM_CFMT_DACSHIFT 0
197#define CM_CFMT_ADCSHIFT 2
198
199static const unsigned sample_size[] = { 1, 2, 2, 4 };
200static const unsigned sample_shift[] = { 0, 1, 1, 2 };
201
202#define CM_CENABLE_RE 0x2
203#define CM_CENABLE_PE 0x1
204
205
206/* MIDI buffer sizes */
207
208#define MIDIINBUF 256
209#define MIDIOUTBUF 256
210
211#define FMODE_MIDI_SHIFT 2
212#define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT)
213#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
214
215#define FMODE_DMFM 0x10
216
217#define SND_DEV_DSP16 5
218
219#ifdef CONFIG_SOUND_CMPCI_4CH
220#define DUAL_DAC
221#endif
222#ifdef DUAL_DAC
223#define set_dac1_rate set_adc_rate
224#define stop_dac1 stop_adc
225#define get_dmadac1 get_dmaadc
226#endif
227
228/* --------------------------------------------------------------------- */
229
230struct cm_state {
231 /* magic */
232 unsigned int magic;
233
234 /* we keep cm cards in a linked list */
235 struct cm_state *next;
236
237 /* soundcore stuff */
238 int dev_audio;
239 int dev_mixer;
240#ifdef DUAL_DAC
241 int dev_dsp;
242 int dual_mode;
243 int hw_dual_dac;
244#endif
245 int four_ch;
246 int dev_midi;
247 int dev_dmfm;
248
249 /* hardware resources */
250 unsigned int iosb, iobase, iosynth, iomidi, iogame, irq;
251
252 /* mixer stuff */
253 struct {
254 unsigned int modcnt;
255#ifndef OSS_DOCUMENTED_MIXER_SEMANTICS
256 unsigned short vol[13];
257#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
258 } mix;
259
260 /* wave stuff */
261 unsigned int rateadc, ratedac;
262 unsigned char fmt, enable;
263
264 spinlock_t lock;
265 struct semaphore open_sem;
266 mode_t open_mode;
267#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
268 wait_queue_head_t open_wait;
269#else
270 struct wait_queue *open_wait;
271#endif
272
273 struct dmabuf {
274 void *rawbuf;
275 unsigned rawphys;
276 unsigned buforder;
277 unsigned numfrag;
278 unsigned fragshift;
279 unsigned hwptr, swptr;
280 unsigned total_bytes;
281 int count;
282 unsigned error; /* over/underrun */
283#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
284 wait_queue_head_t wait;
285#else
286 struct wait_queue *wait;
287#endif
288 /* redundant, but makes calculations easier */
289 unsigned fragsize;
290 unsigned dmasize;
291 unsigned fragsamples;
292 unsigned dmasamples;
293 /* OSS stuff */
294 unsigned mapped:1;
295 unsigned ready:1;
296 unsigned endcleared:1;
297 unsigned ossfragshift;
298 int ossmaxfrags;
299 unsigned subdivision;
300 } dma_dac, dma_adc;
301
302 /* midi stuff */
303 struct {
304 unsigned ird, iwr, icnt;
305 unsigned ord, owr, ocnt;
306#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
307 wait_queue_head_t iwait;
308 wait_queue_head_t owait;
309#else
310 struct wait_queue *iwait;
311 struct wait_queue *owait;
312#endif
313 struct timer_list timer;
314 unsigned char ibuf[MIDIINBUF];
315 unsigned char obuf[MIDIOUTBUF];
316 } midi;
317
318 /* misc stuff */
319 int modem;
320};
321
322/* --------------------------------------------------------------------- */
323
324static struct cm_state *devs = NULL;
325static struct cm_state *devaudio = NULL;
326static unsigned long wavetable_mem = 0;
327
328/* --------------------------------------------------------------------- */
329
330extern __inline__ unsigned ld2(unsigned int x)
331{
332 unsigned r = 0;
333
334 if (x >= 0x10000) {
335 x >>= 16;
336 r += 16;
337 }
338 if (x >= 0x100) {
339 x >>= 8;
340 r += 8;
341 }
342 if (x >= 0x10) {
343 x >>= 4;
344 r += 4;
345 }
346 if (x >= 4) {
347 x >>= 2;
348 r += 2;
349 }
350 if (x >= 2)
351 r++;
352 return r;
353}
354
355/*
356 * hweightN: returns the hamming weight (i.e. the number
357 * of bits set) of a N-bit word
358 */
359
360#ifdef hweight32
361#undef hweight32
362#endif
363
364extern __inline__ unsigned int hweight32(unsigned int w)
365{
366 unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
367 res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
368 res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
369 res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
370 return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
371}
372
373/* --------------------------------------------------------------------- */
374
375/*
376 * Why use byte IO? Nobody knows, but S3 does it also in their Windows driver.
377 */
378
379#undef DMABYTEIO
380
381static void set_dmadac(struct cm_state *s, unsigned int addr, unsigned int count)
382{
383 count--;
384 outl(addr, s->iobase + CODEC_CMI_CH0_FRAME1);
385 outw(count, s->iobase + CODEC_CMI_CH0_FRAME2);
386 outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) & ~1, s->iobase + CODEC_CMI_FUNCTRL0);
387}
388
389static void set_dmadac1(struct cm_state *s, unsigned int addr, unsigned int count)
390{
391 count--;
392 outl(addr, s->iobase + CODEC_CMI_CH1_FRAME1);
393 outw(count, s->iobase + CODEC_CMI_CH1_FRAME2);
394 outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) & ~2, s->iobase + CODEC_CMI_FUNCTRL0);
395}
396
397static void set_dmaadc(struct cm_state *s, unsigned int addr, unsigned int count)
398{
399 count--;
400 outl(addr, s->iobase + CODEC_CMI_CH1_FRAME1);
401 outw(count, s->iobase + CODEC_CMI_CH1_FRAME2);
402 outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) | 2, s->iobase + CODEC_CMI_FUNCTRL0);
403}
404
405extern __inline__ unsigned get_dmadac(struct cm_state *s)
406{
407 unsigned int curr_addr;
408
409#if 1
410 curr_addr = inw(s->iobase + CODEC_CMI_CH0_FRAME2) + 1;
411 curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
412 curr_addr = s->dma_dac.dmasize - curr_addr;
413#else
414 curr_addr = inl(s->iobase + CODEC_CMI_CH0_FRAME1);
415 curr_addr &= ~(sample_size[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK]-1);
416 curr_addr -= s->dma_dac.rawphys;
417#endif
418 return curr_addr;
419}
420
421extern __inline__ unsigned get_dmaadc(struct cm_state *s)
422{
423 unsigned int curr_addr;
424
425#if 1
426 curr_addr = inw(s->iobase + CODEC_CMI_CH1_FRAME2) + 1;
427 curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK];
428 curr_addr = s->dma_adc.dmasize - curr_addr;
429#else
430 curr_addr = inl(s->iobase + CODEC_CMI_CH1_FRAME1);
431 curr_addr &= ~(sample_size[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK]-1);
432 curr_addr -= s->dma_adc.rawphys;
433#endif
434 return curr_addr;
435}
436
437static void wrmixer(struct cm_state *s, unsigned char idx, unsigned char data)
438{
439 outb(idx, s->iobase + CODEC_SB16_ADDR);
440 outb(data, s->iobase + CODEC_SB16_DATA);
441}
442
443static unsigned char rdmixer(struct cm_state *s, unsigned char idx)
444{
445 unsigned char v;
446
447 outb(idx, s->iobase + CODEC_SB16_ADDR);
448 v = inb(s->iobase + CODEC_SB16_DATA);
449 return v;
450}
451
452static void set_fmt(struct cm_state *s, unsigned char mask, unsigned char data)
453{
454 unsigned long flags;
455
456 spin_lock_irqsave(&s->lock, flags);
457 if (mask)
458 s->fmt = inb(s->iobase + CODEC_CMI_CHFORMAT);
459 s->fmt = (s->fmt & mask) | data;
460 outb(s->fmt, s->iobase + CODEC_CMI_CHFORMAT);
461 spin_unlock_irqrestore(&s->lock, flags);
462}
463
464static void frobindir(struct cm_state *s, unsigned char idx, unsigned char mask, unsigned char data)
465{
466 outb(idx, s->iobase + CODEC_SB16_ADDR);
467 outb((inb(s->iobase + CODEC_SB16_DATA) & mask) | data, s->iobase + CODEC_SB16_DATA);
468}
469
470static struct {
471 unsigned rate;
472 unsigned lower;
473 unsigned upper;
474 unsigned char freq;
475} rate_lookup[] =
476{
477 { 5512, (0 + 5512) / 2, (5512 + 8000) / 2, 0 },
478 { 8000, (5512 + 8000) / 2, (8000 + 11025) / 2, 4 },
479 { 11025, (8000 + 11025) / 2, (11025 + 16000) / 2, 1 },
480 { 16000, (11025 + 16000) / 2, (16000 + 22050) / 2, 5 },
481 { 22050, (16000 + 22050) / 2, (22050 + 32000) / 2, 2 },
482 { 32000, (22050 + 32000) / 2, (32000 + 44100) / 2, 6 },
483 { 44100, (32000 + 44100) / 2, (44100 + 48000) / 2, 3 },
484 { 48000, (44100 + 48000) / 2, 48000, 7 }
485};
486
487static void set_dac_rate(struct cm_state *s, unsigned rate)
488{
489 unsigned long flags;
490 unsigned char freq = 4, val;
491 int i;
492
493 if (rate > 48000)
494 rate = 48000;
495 if (rate < 5512)
496 rate = 5512;
497 for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++)
498 {
499 if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper)
500 {
501 rate = rate_lookup[i].rate;
502 freq = rate_lookup[i].freq;
503 break;
504 }
505 }
506 s->ratedac = rate;
507 freq <<= 2;
508 spin_lock_irqsave(&s->lock, flags);
509 val = inb(s->iobase + CODEC_CMI_FUNCTRL1 + 1) & ~0x1c;
510 outb(val | freq, s->iobase + CODEC_CMI_FUNCTRL1 + 1);
511 spin_unlock_irqrestore(&s->lock, flags);
512}
513
514static void set_adc_rate(struct cm_state *s, unsigned rate)
515{
516 unsigned long flags;
517 unsigned char freq = 4, val;
518 int i;
519
520 if (rate > 48000)
521 rate = 48000;
522 if (rate < 5512)
523 rate = 5512;
524 for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++)
525 {
526 if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper)
527 {
528 rate = rate_lookup[i].rate;
529 freq = rate_lookup[i].freq;
530 break;
531 }
532 }
533 s->rateadc = rate;
534 freq <<= 5;
535 spin_lock_irqsave(&s->lock, flags);
536 val = inb(s->iobase + CODEC_CMI_FUNCTRL1 + 1) & ~0xe0;
537 outb(val | freq, s->iobase + CODEC_CMI_FUNCTRL1 + 1);
538 spin_unlock_irqrestore(&s->lock, flags);
539}
540
541/* --------------------------------------------------------------------- */
542static inline void reset_adc(struct cm_state *s)
543{
544 /* reset bus master */
545 outb(s->enable | CM_CH1_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
546 outb(s->enable & ~CM_CH1_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
547}
548
549static inline void reset_dac(struct cm_state *s)
550{
551 /* reset bus master */
552 outb(s->enable | CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
553 outb(s->enable & ~CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
554}
555
556static inline void pause_adc(struct cm_state *s)
557{
558 outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) | 8, s->iobase + CODEC_CMI_FUNCTRL0);
559}
560
561static inline void pause_dac(struct cm_state *s)
562{
563 outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) | 4, s->iobase + CODEC_CMI_FUNCTRL0);
564}
565
566extern inline void disable_adc(struct cm_state *s)
567{
568 /* disable channel */
569 s->enable &= ~CM_CENABLE_RE;
570 outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
571 reset_adc(s);
572}
573
574extern inline void disable_dac(struct cm_state *s)
575{
576 /* disable channel */
577 s->enable &= ~CM_CENABLE_PE;
578 outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
579 reset_dac(s);
580}
581
582extern inline void enable_adc(struct cm_state *s)
583{
584 if (!(s->enable & CM_CENABLE_RE))
585 {
586 /* enable channel */
587 s->enable |= CM_CENABLE_RE;
588 outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
589 }
590 else
591 {
592 outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) & ~8, s->iobase + CODEC_CMI_FUNCTRL0);
593 }
594}
595
596extern inline void enable_dac(struct cm_state *s)
597{
598 if (!(s->enable & CM_CENABLE_PE))
599 {
600 /* enable channel */
601 s->enable |= CM_CENABLE_PE;
602 outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
603 }
604 else
605 {
606 outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) & ~4, s->iobase + CODEC_CMI_FUNCTRL0);
607 }
608}
609
610extern inline void stop_adc(struct cm_state *s)
611{
612 unsigned long flags;
613
614 spin_lock_irqsave(&s->lock, flags);
615 if (s->enable & CM_CENABLE_RE)
616 {
617 /* disable interrupt */
618 outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) & ~2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
619 disable_adc(s);
620 }
621 spin_unlock_irqrestore(&s->lock, flags);
622}
623
624extern inline void stop_dac(struct cm_state *s)
625{
626 unsigned long flags;
627
628 spin_lock_irqsave(&s->lock, flags);
629 if (s->enable & CM_CENABLE_PE)
630 {
631 /* disable interrupt */
632 outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) & ~1, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
633 disable_dac(s);
634 }
635 spin_unlock_irqrestore(&s->lock, flags);
636}
637
638static void start_dac(struct cm_state *s)
639{
640 unsigned long flags;
641
642 spin_lock_irqsave(&s->lock, flags);
643 if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
644 /* enable interrupt */
645 outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) | 1, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
646 enable_dac(s);
647 }
648 spin_unlock_irqrestore(&s->lock, flags);
649}
650
651static void start_dac1(struct cm_state *s)
652{
653 unsigned long flags;
654
655 spin_lock_irqsave(&s->lock, flags);
656 if ((s->dma_adc.mapped || s->dma_adc.count > 0) && s->dma_adc.ready) {
657 /* enable interrupt */
658 outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) | 2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
659 enable_adc(s);
660 }
661 spin_unlock_irqrestore(&s->lock, flags);
662}
663
664static void start_adc(struct cm_state *s)
665{
666 unsigned long flags;
667
668 spin_lock_irqsave(&s->lock, flags);
669 if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
670 && s->dma_adc.ready) {
671 /* enable interrupt */
672 outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) | 2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
673 enable_adc(s);
674 }
675 spin_unlock_irqrestore(&s->lock, flags);
676}
677
678/* --------------------------------------------------------------------- */
679
680#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
681#define DMABUF_MINORDER 1
682
683static void dealloc_dmabuf(struct dmabuf *db)
684{
685 unsigned long map, mapend;
686
687 if (db->rawbuf) {
688 /* undo marking the pages as reserved */
689 mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
690 for (map = MAP_NR(db->rawbuf); map <= mapend; map++)
691 clear_bit(PG_reserved, &mem_map[map].flags);
692 free_pages((unsigned long)db->rawbuf, db->buforder);
693 }
694 db->rawbuf = NULL;
695 db->mapped = db->ready = 0;
696}
697
698
699/* Ch0 is used for playback, Ch1 is used for recording */
700
701static int prog_dmabuf(struct cm_state *s, unsigned rec)
702{
703 struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
704 unsigned rate = rec ? s->rateadc : s->ratedac;
705 int order;
706 unsigned bytepersec;
707 unsigned bufs;
708 unsigned long map, mapend;
709 unsigned char fmt;
710 unsigned long flags;
711
712 spin_lock_irqsave(&s->lock, flags);
713 fmt = s->fmt;
714 if (rec) {
715 stop_adc(s);
716 fmt >>= CM_CFMT_ADCSHIFT;
717 } else {
718 stop_dac(s);
719 fmt >>= CM_CFMT_DACSHIFT;
720 }
721 spin_unlock_irqrestore(&s->lock, flags);
722 fmt &= CM_CFMT_MASK;
723 db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
724 if (!db->rawbuf) {
725 db->ready = db->mapped = 0;
726 for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
727 if ((db->rawbuf = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, order)))
728 break;
729 if (!db->rawbuf)
730 return -ENOMEM;
731 db->buforder = order;
732 db->rawphys = virt_to_bus(db->rawbuf);
733 if ((db->rawphys ^ (db->rawphys + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff)
734 printk(KERN_DEBUG "cm: DMA buffer crosses 64k boundary: busaddr 0x%lx size %ld\n",
735 (long) db->rawphys, PAGE_SIZE << db->buforder);
736 if ((db->rawphys + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff)
737 printk(KERN_DEBUG "cm: DMA buffer beyond 16MB: busaddr 0x%lx size %ld\n",
738 (long) db->rawphys, PAGE_SIZE << db->buforder);
739 /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
740 mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
741 for (map = MAP_NR(db->rawbuf); map <= mapend; map++)
742 set_bit(PG_reserved, &mem_map[map].flags);
743 }
744 bytepersec = rate << sample_shift[fmt];
745 bufs = PAGE_SIZE << db->buforder;
746 if (db->ossfragshift) {
747 if ((1000 << db->ossfragshift) < bytepersec)
748 db->fragshift = ld2(bytepersec/1000);
749 else
750 db->fragshift = db->ossfragshift;
751 } else {
752 db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
753 if (db->fragshift < 3)
754 db->fragshift = 3;
755 }
756 db->numfrag = bufs >> db->fragshift;
757 while (db->numfrag < 4 && db->fragshift > 3) {
758 db->fragshift--;
759 db->numfrag = bufs >> db->fragshift;
760 }
761 db->fragsize = 1 << db->fragshift;
762 if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
763 db->numfrag = db->ossmaxfrags;
764 /* to make fragsize >= 4096 */
765 if (s->modem)
766 {
767 while (db->fragsize < 4096 && db->numfrag >= 4)
768 {
769 db->fragsize *= 2;
770 db->fragshift++;
771 db->numfrag /= 2;
772 }
773 }
774 db->fragsamples = db->fragsize >> sample_shift[fmt];
775 db->dmasize = db->numfrag << db->fragshift;
776 db->dmasamples = db->dmasize >> sample_shift[fmt];
777 memset(db->rawbuf, (fmt & CM_CFMT_16BIT) ? 0 : 0x80, db->dmasize);
778 spin_lock_irqsave(&s->lock, flags);
779 if (rec) {
780#ifdef DUAL_DAC
781 if (s->dual_mode)
782 set_dmadac1(s, db->rawphys, db->dmasize >> sample_shift[fmt]);
783 else
784#endif
785 set_dmaadc(s, db->rawphys, db->dmasize >> sample_shift[fmt]);
786 /* program sample counts */
787 outw(db->fragsamples-1, s->iobase + CODEC_CMI_CH1_FRAME2 + 2);
788 } else {
789 set_dmadac(s, db->rawphys, db->dmasize >> sample_shift[fmt]);
790 /* program sample counts */
791 outw(db->fragsamples-1, s->iobase + CODEC_CMI_CH0_FRAME2 + 2);
792 }
793 spin_unlock_irqrestore(&s->lock, flags);
794 db->ready = 1;
795 return 0;
796}
797
798extern __inline__ void clear_advance(struct cm_state *s)
799{
800 unsigned char c = (s->fmt & (CM_CFMT_16BIT << CM_CFMT_DACSHIFT)) ? 0 : 0x80;
801 unsigned char *buf = s->dma_dac.rawbuf;
802#ifdef DUAL_DAC
803 unsigned char *buf1 = s->dma_adc.rawbuf;
804#endif
805 unsigned bsize = s->dma_dac.dmasize;
806 unsigned bptr = s->dma_dac.swptr;
807 unsigned len = s->dma_dac.fragsize;
808
809 if (bptr + len > bsize) {
810 unsigned x = bsize - bptr;
811 memset(buf + bptr, c, x);
812#ifdef DUAL_DAC
813 if (s->dual_mode)
814 memset(buf1 + bptr, c, x);
815#endif
816 bptr = 0;
817 len -= x;
818 }
819 memset(buf + bptr, c, len);
820#ifdef DUAL_DAC
821 if (s->dual_mode)
822 memset(buf1 + bptr, c, len);
823#endif
824}
825
826/* call with spinlock held! */
827static void cm_update_ptr(struct cm_state *s)
828{
829 unsigned hwptr;
830 int diff;
831
832 /* update ADC pointer */
833 if (s->dma_adc.ready) {
834#ifdef DUAL_DAC
835 if (s->dual_mode)
836 {
837 hwptr = get_dmaadc(s) % s->dma_adc.dmasize;
838 diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
839 s->dma_adc.hwptr = hwptr;
840 s->dma_adc.total_bytes += diff;
841 if (s->dma_adc.mapped) {
842 s->dma_adc.count += diff;
843 if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
844 wake_up(&s->dma_adc.wait);
845 } else {
846 s->dma_adc.count -= diff;
847 if (s->dma_adc.count <= 0) {
848 pause_adc(s);
849 s->dma_adc.error++;
850 } else if (s->dma_adc.count <= (signed)s->dma_adc.fragsize && !s->dma_adc.endcleared) {
851 clear_advance(s);
852 s->dma_adc.endcleared = 1;
853 }
854 if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
855 wake_up(&s->dma_adc.wait);
856 }
857 }
858 else
859 {
860#endif
861 hwptr = get_dmaadc(s) % s->dma_adc.dmasize;
862 diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
863 s->dma_adc.hwptr = hwptr;
864 s->dma_adc.total_bytes += diff;
865 s->dma_adc.count += diff;
866 if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
867 wake_up(&s->dma_adc.wait);
868 if (!s->dma_adc.mapped) {
869 if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
870 pause_adc(s);
871 s->dma_adc.error++;
872 }
873 }
874#ifdef DUAL_DAC
875 }
876#endif
877 }
878 /* update DAC pointer */
879 if (s->dma_dac.ready) {
880 hwptr = get_dmadac(s) % s->dma_dac.dmasize;
881 diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
882 s->dma_dac.hwptr = hwptr;
883 s->dma_dac.total_bytes += diff;
884 if (s->dma_dac.mapped) {
885 s->dma_dac.count += diff;
886 if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
887 wake_up(&s->dma_dac.wait);
888 } else {
889 s->dma_dac.count -= diff;
890 if (s->dma_dac.count <= 0) {
891 pause_dac(s);
892 s->dma_dac.error++;
893 } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
894 clear_advance(s);
895 s->dma_dac.endcleared = 1;
896 }
897 if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
898 wake_up(&s->dma_dac.wait);
899 }
900 }
901}
902
903#ifdef CONFIG_SOUND_CMPCI_MIDI
904/* hold spinlock for the following! */
905static void cm_handle_midi(struct cm_state *s)
906{
907 unsigned char ch;
908 int wake;
909
910 wake = 0;
911 while (!(inb(s->iomidi+1) & 0x80)) {
912 ch = inb(s->iomidi);
913 if (s->midi.icnt < MIDIINBUF) {
914 s->midi.ibuf[s->midi.iwr] = ch;
915 s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
916 s->midi.icnt++;
917 }
918 wake = 1;
919 }
920 if (wake)
921 wake_up(&s->midi.iwait);
922 wake = 0;
923 while (!(inb(s->iomidi+1) & 0x40) && s->midi.ocnt > 0) {
924 outb(s->midi.obuf[s->midi.ord], s->iomidi);
925 s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
926 s->midi.ocnt--;
927 if (s->midi.ocnt < MIDIOUTBUF-16)
928 wake = 1;
929 }
930 if (wake)
931 wake_up(&s->midi.owait);
932}
933#endif
934
935static void cm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
936{
937 struct cm_state *s = (struct cm_state *)dev_id;
938 unsigned int intsrc, intstat;
939 unsigned char mask = 0;
940
941 /* fastpath out, to ease interrupt sharing */
942 intsrc = inl(s->iobase + CODEC_CMI_INT_STATUS);
943 if (!(intsrc & 0x80000000))
944 return;
945 spin_lock(&s->lock);
946 intstat = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2);
947 /* acknowledge interrupt */
948 if (intsrc & CM_INT_CH0)
949 mask |= 1;
950 if (intsrc & CM_INT_CH1)
951 mask |= 2;
952 outb(intstat & ~mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
953 outb(intstat | mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
954 cm_update_ptr(s);
955#ifdef CONFIG_SOUND_CMPCI_MIDI
956 cm_handle_midi(s);
957#endif
958 spin_unlock(&s->lock);
959}
960
961#ifdef CONFIG_SOUND_CMPCI_MIDI
962static void cm_midi_timer(unsigned long data)
963{
964 struct cm_state *s = (struct cm_state *)data;
965 unsigned long flags;
966
967 spin_lock_irqsave(&s->lock, flags);
968 cm_handle_midi(s);
969 spin_unlock_irqrestore(&s->lock, flags);
970 s->midi.timer.expires = jiffies+1;
971 add_timer(&s->midi.timer);
972}
973#endif
974
975/* --------------------------------------------------------------------- */
976
977static const char invalid_magic[] = KERN_CRIT "cm: invalid magic value\n";
978
979#ifdef CONFIG_SOUND_CMPCI /* support multiple chips */
980#define VALIDATE_STATE(s)
981#else
982#define VALIDATE_STATE(s) \
983({ \
984 if (!(s) || (s)->magic != CM_MAGIC) { \
985 printk(invalid_magic); \
986 return -ENXIO; \
987 } \
988})
989#endif
990
991/* --------------------------------------------------------------------- */
992
993#define MT_4 1
994#define MT_5MUTE 2
995#define MT_4MUTEMONO 3
996#define MT_6MUTE 4
997#define MT_5MUTEMONO 5
998
999static const struct {
1000 unsigned left;
1001 unsigned right;
1002 unsigned type;
1003 unsigned rec;
1004 unsigned play;
1005} mixtable[SOUND_MIXER_NRDEVICES] = {
1006 [SOUND_MIXER_CD] = { DSP_MIX_CDVOLIDX_L, DSP_MIX_CDVOLIDX_R, MT_5MUTE, 0x04, 0x02 },
1007 [SOUND_MIXER_LINE] = { DSP_MIX_LINEVOLIDX_L, DSP_MIX_LINEVOLIDX_R, MT_5MUTE, 0x10, 0x08 },
1008 [SOUND_MIXER_MIC] = { DSP_MIX_MICVOLIDX, DSP_MIX_MICVOLIDX, MT_5MUTEMONO, 0x01, 0x01 },
1009 [SOUND_MIXER_SYNTH] = { DSP_MIX_FMVOLIDX_L, DSP_MIX_FMVOLIDX_R, MT_5MUTE, 0x40, 0x00 },
1010 [SOUND_MIXER_VOLUME] = { DSP_MIX_MASTERVOLIDX_L, DSP_MIX_MASTERVOLIDX_R, MT_5MUTE, 0x00, 0x00 },
1011 [SOUND_MIXER_PCM] = { DSP_MIX_VOICEVOLIDX_L, DSP_MIX_VOICEVOLIDX_R, MT_5MUTE, 0x00, 0x00 }
1012};
1013
1014#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
1015
1016static int return_mixval(struct cm_state *s, unsigned i, int *arg)
1017{
1018 unsigned long flags;
1019 unsigned char l, r, rl, rr;
1020
1021 spin_lock_irqsave(&s->lock, flags);
1022 l = rdmixer(s, mixtable[i].left);
1023 r = rdmixer(s, mixtable[i].right);
1024 spin_unlock_irqrestore(&s->lock, flags);
1025 switch (mixtable[i].type) {
1026 case MT_4:
1027 r &= 0xf;
1028 l &= 0xf;
1029 rl = 10 + 6 * (l & 15);
1030 rr = 10 + 6 * (r & 15);
1031 break;
1032
1033 case MT_4MUTEMONO:
1034 rl = 55 - 3 * (l & 15);
1035 if (r & 0x10)
1036 rl += 45;
1037 rr = rl;
1038 r = l;
1039 break;
1040
1041 case MT_5MUTEMONO:
1042 r = l;
1043 rl = 100 - 3 * ((l >> 3) & 31);
1044 rr = rl;
1045 break;
1046
1047 case MT_5MUTE:
1048 default:
1049 rl = 100 - 3 * ((l >> 3) & 31);
1050 rr = 100 - 3 * ((r >> 3) & 31);
1051 break;
1052
1053 case MT_6MUTE:
1054 rl = 100 - 3 * (l & 63) / 2;
1055 rr = 100 - 3 * (r & 63) / 2;
1056 break;
1057 }
1058 if (l & 0x80)
1059 rl = 0;
1060 if (r & 0x80)
1061 rr = 0;
1062 return put_user((rr << 8) | rl, arg);
1063}
1064
1065#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1066
1067static const unsigned char volidx[SOUND_MIXER_NRDEVICES] =
1068{
1069 [SOUND_MIXER_CD] = 1,
1070 [SOUND_MIXER_LINE] = 2,
1071 [SOUND_MIXER_MIC] = 3,
1072 [SOUND_MIXER_SYNTH] = 4,
1073 [SOUND_MIXER_VOLUME] = 5,
1074 [SOUND_MIXER_PCM] = 6
1075};
1076
1077#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1078
1079static unsigned mixer_recmask(struct cm_state *s)
1080{
1081 unsigned long flags;
1082 int i, j, k;
1083
1084 spin_lock_irqsave(&s->lock, flags);
1085 j = rdmixer(s, DSP_MIX_ADCMIXIDX_L);
1086 spin_unlock_irqrestore(&s->lock, flags);
1087 j &= 0x7f;
1088 for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1089 if (j & mixtable[i].rec)
1090 k |= 1 << i;
1091 return k;
1092}
1093
1094static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
1095{
1096 unsigned long flags;
1097 int i, val, j;
1098 unsigned char l, r, rl, rr;
1099
1100 VALIDATE_STATE(s);
1101 if (cmd == SOUND_MIXER_INFO) {
1102 mixer_info info;
1103 strncpy(info.id, "cmpci", sizeof(info.id));
1104 strncpy(info.name, "C-Media PCI", sizeof(info.name));
1105 info.modify_counter = s->mix.modcnt;
1106 if (copy_to_user((void *)arg, &info, sizeof(info)))
1107 return -EFAULT;
1108 return 0;
1109 }
1110 if (cmd == SOUND_OLD_MIXER_INFO) {
1111 _old_mixer_info info;
1112 strncpy(info.id, "cmpci", sizeof(info.id));
1113 strncpy(info.name, "C-Media cmpci", sizeof(info.name));
1114 if (copy_to_user((void *)arg, &info, sizeof(info)))
1115 return -EFAULT;
1116 return 0;
1117 }
1118 if (cmd == OSS_GETVERSION)
1119 return put_user(SOUND_VERSION, (int *)arg);
1120 if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
1121 return -EINVAL;
1122 if (_IOC_DIR(cmd) == _IOC_READ) {
1123 switch (_IOC_NR(cmd)) {
1124 case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
1125 return put_user(mixer_recmask(s), (int *)arg);
1126
1127 case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */
1128 return put_user(mixer_recmask(s), (int *)arg);//need fix
1129
1130 case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
1131 for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1132 if (mixtable[i].type)
1133 val |= 1 << i;
1134 return put_user(val, (int *)arg);
1135
1136 case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
1137 for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1138 if (mixtable[i].rec)
1139 val |= 1 << i;
1140 return put_user(val, (int *)arg);
1141
1142 case SOUND_MIXER_OUTMASK: /* Arg contains a bit for each supported recording source */
1143 for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1144 if (mixtable[i].play)
1145 val |= 1 << i;
1146 return put_user(val, (int *)arg);
1147
1148 case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
1149 for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1150 if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO)
1151 val |= 1 << i;
1152 return put_user(val, (int *)arg);
1153
1154 case SOUND_MIXER_CAPS:
1155 return put_user(0, (int *)arg);
1156
1157 default:
1158 i = _IOC_NR(cmd);
1159 if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
1160 return -EINVAL;
1161#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
1162 return return_mixval(s, i, (int *)arg);
1163#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1164 if (!volidx[i])
1165 return -EINVAL;
1166 return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
1167#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1168 }
1169 }
1170 if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE))
1171 return -EINVAL;
1172 s->mix.modcnt++;
1173 switch (_IOC_NR(cmd)) {
1174 case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
1175 get_user_ret(val, (int *)arg, -EFAULT);
1176 i = hweight32(val);
1177 for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
1178 if (!(val & (1 << i)))
1179 continue;
1180 if (!mixtable[i].rec) {
1181 val &= ~(1 << i);
1182 continue;
1183 }
1184 j |= mixtable[i].rec;
1185 }
1186 spin_lock_irqsave(&s->lock, flags);
1187 wrmixer(s, DSP_MIX_ADCMIXIDX_L, j);
1188 wrmixer(s, DSP_MIX_ADCMIXIDX_R, (j & 1) | (j>>1));
1189 spin_unlock_irqrestore(&s->lock, flags);
1190 return 0;
1191
1192 case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */
1193 get_user_ret(val, (int *)arg, -EFAULT);
1194 for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
1195 if (!(val & (1 << i)))
1196 continue;
1197 if (!mixtable[i].play) {
1198 val &= ~(1 << i);
1199 continue;
1200 }
1201 j |= mixtable[i].play;
1202 }
1203 spin_lock_irqsave(&s->lock, flags);
1204 frobindir(s, DSP_MIX_OUTMIXIDX, 0x1f, j);
1205 spin_unlock_irqrestore(&s->lock, flags);
1206 return 0;
1207
1208 default:
1209 i = _IOC_NR(cmd);
1210 if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
1211 return -EINVAL;
1212 get_user_ret(val, (int *)arg, -EFAULT);
1213 l = val & 0xff;
1214 r = (val >> 8) & 0xff;
1215 if (l > 100)
1216 l = 100;
1217 if (r > 100)
1218 r = 100;
1219 spin_lock_irqsave(&s->lock, flags);
1220 switch (mixtable[i].type) {
1221 case MT_4:
1222 if (l >= 10)
1223 l -= 10;
1224 if (r >= 10)
1225 r -= 10;
1226 frobindir(s, mixtable[i].left, 0xf0, l / 6);
1227 frobindir(s, mixtable[i].right, 0xf0, l / 6);
1228 break;
1229
1230 case MT_4MUTEMONO:
1231 rl = (l < 4 ? 0 : (l - 5) / 3) & 31;
1232 rr = (rl >> 2) & 7;
1233 wrmixer(s, mixtable[i].left, rl<<3);
1234 outb((inb(s->iobase + CODEC_CMI_MIXER2) & ~0x0e) | rr<<1, s->iobase + CODEC_CMI_MIXER2);
1235 break;
1236
1237 case MT_5MUTEMONO:
1238 r = l;
1239 rl = l < 4 ? 0 : (l - 5) / 3;
1240 rr = rl >> 2;
1241 wrmixer(s, mixtable[i].left, rl<<3);
1242 outb((inb(s->iobase + CODEC_CMI_MIXER2) & ~0x0e) | rr<<1, s->iobase + CODEC_CMI_MIXER2);
1243 break;
1244
1245 case MT_5MUTE:
1246 rl = l < 4 ? 0 : (l - 5) / 3;
1247 rr = r < 4 ? 0 : (r - 5) / 3;
1248 wrmixer(s, mixtable[i].left, rl<<3);
1249 wrmixer(s, mixtable[i].right, rr<<3);
1250 break;
1251
1252 case MT_6MUTE:
1253 if (l < 6)
1254 rl = 0x00;
1255 else
1256 rl = l * 2 / 3;
1257 if (r < 6)
1258 rr = 0x00;
1259 else
1260 rr = r * 2 / 3;
1261 wrmixer(s, mixtable[i].left, rl);
1262 wrmixer(s, mixtable[i].right, rr);
1263 break;
1264 }
1265 spin_unlock_irqrestore(&s->lock, flags);
1266#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
1267 return return_mixval(s, i, (int *)arg);
1268#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1269 if (!volidx[i])
1270 return -EINVAL;
1271 s->mix.vol[volidx[i]-1] = val;
1272 return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
1273#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1274 }
1275}
1276
1277/* --------------------------------------------------------------------- */
1278
1279static loff_t cm_llseek(struct file *file, loff_t offset, int origin)
1280{
1281 return -ESPIPE;
1282}
1283
1284/* --------------------------------------------------------------------- */
1285
1286static int cm_open_mixdev(struct inode *inode, struct file *file)
1287{
1288 int minor = MINOR(inode->i_rdev);
1289 struct cm_state *s = devs;
1290
1291 while (s && s->dev_mixer != minor)
1292 s = s->next;
1293 if (!s)
1294 return -ENODEV;
1295 VALIDATE_STATE(s);
1296 file->private_data = s;
1297 MOD_INC_USE_COUNT;
1298 return 0;
1299}
1300
1301static int cm_release_mixdev(struct inode *inode, struct file *file)
1302{
1303 struct cm_state *s = (struct cm_state *)file->private_data;
1304
1305 VALIDATE_STATE(s);
1306 MOD_DEC_USE_COUNT;
1307 return 0;
1308}
1309
1310static int cm_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
1311{
1312 return mixer_ioctl((struct cm_state *)file->private_data, cmd, arg);
1313}
1314
1315static /*const*/ struct file_operations cm_mixer_fops = {
1316#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
1317 llseek: cm_llseek,
1318 ioctl: cm_ioctl_mixdev,
1319 open: cm_open_mixdev,
1320 release: cm_release_mixdev,
1321#else
1322 &cm_llseek,
1323 NULL, /* read */
1324 NULL, /* write */
1325 NULL, /* readdir */
1326 NULL, /* poll */
1327 &cm_ioctl_mixdev,
1328 NULL, /* mmap */
1329 &cm_open_mixdev,
1330 NULL, /* flush */
1331 &cm_release_mixdev,
1332 NULL, /* fsync */
1333 NULL, /* fasync */
1334 NULL, /* check_media_change */
1335 NULL, /* revalidate */
1336 NULL, /* lock */
1337#endif
1338};
1339
1340int IntrOpen(void)
1341{
1342 struct cm_state *s = devs;
1343 unsigned char fmtm = ~0, fmts = 0;
1344
1345 /* Locate the /dev/dsp file descriptor */
1346 while (s && ((s->dev_audio ^ 3) & ~0xf))
1347 s = s->next;
1348
1349 devaudio = s;
1350 down(&s->open_sem);
1351 if (s->open_mode & FMODE_WRITE)
1352 {
1353 up(&s->open_sem);
1354 devaudio = NULL;
1355 return -EBUSY;
1356 }
1357
1358 if (!s->dma_dac.ready)
1359 {
1360 set_dac_rate(s, 8000);
1361 fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT);
1362 set_fmt(s, fmtm, fmts);
1363 s->modem = 1;
1364 }
1365
1366 s->open_mode |= FMODE_WRITE;
1367 up(&s->open_sem);
1368 MOD_INC_USE_COUNT;
1369 return 0;
1370}
1371EXPORT_SYMBOL(IntrOpen);
1372
1373int IntrClose(void)
1374{
1375 struct cm_state *s = devaudio;
1376
1377 if (!s)
1378 return -ENODEV;
1379 down(&s->open_sem);
1380 stop_dac(s);
1381#ifndef FIXEDDMA
1382 dealloc_dmabuf(&s->dma_dac);
1383#endif
1384
1385 s->open_mode &= ~FMODE_WRITE;
1386 s->modem = 0;
1387 up(&s->open_sem);
1388 wake_up(&s->open_wait);
1389 MOD_DEC_USE_COUNT;
1390 devaudio = NULL;
1391 return 0;
1392}
1393EXPORT_SYMBOL(IntrClose);
1394
1395int IntrWrite(const char *buffer, int count)
1396{
1397 struct cm_state *s = devaudio;
1398 ssize_t ret = 0;
1399 unsigned long flags;
1400 unsigned swptr;
1401 int cnt;
1402
1403 if (!s)
1404 return -ENODEV;
1405 VALIDATE_STATE(s);
1406 if (s->dma_dac.mapped)
1407 return -ENXIO;
1408
1409 if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
1410 return ret;
1411
1412 s->dma_dac.ossfragshift = 8;
1413 s->dma_dac.ossmaxfrags = 16;
1414 s->dma_dac.subdivision = 0;
1415
1416 while (count > 0) {
1417 spin_lock_irqsave(&s->lock, flags);
1418 if (s->dma_dac.count < 0) {
1419 s->dma_dac.count = 0;
1420 s->dma_dac.swptr = s->dma_dac.hwptr;
1421 }
1422 swptr = s->dma_dac.swptr;
1423 cnt = s->dma_dac.dmasize-swptr;
1424 if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
1425 cnt = s->dma_dac.dmasize - s->dma_dac.count;
1426 spin_unlock_irqrestore(&s->lock, flags);
1427 if (cnt > count)
1428 cnt = count;
1429 if (cnt <= 0) {
1430 start_dac(s);
1431 return ret;
1432 }
1433 if (__copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
1434 return ret ? ret : -EFAULT;
1435 swptr = (swptr + cnt) % s->dma_dac.dmasize;
1436 spin_lock_irqsave(&s->lock, flags);
1437 s->dma_dac.swptr = swptr;
1438 s->dma_dac.count += cnt;
1439 s->dma_dac.endcleared = 0;
1440 spin_unlock_irqrestore(&s->lock, flags);
1441 count -= cnt;
1442 buffer += cnt;
1443 ret += cnt;
1444 start_dac(s);
1445 }
1446 return ret;
1447}
1448EXPORT_SYMBOL(IntrWrite);
1449
1450/* --------------------------------------------------------------------- */
1451
1452static int drain_dac(struct cm_state *s, int nonblock)
1453{
1454#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
1455 DECLARE_WAITQUEUE(wait, current);
1456#else
1457 struct wait_queue wait = { current, NULL };
1458#endif
1459 unsigned long flags;
1460 int count, tmo;
1461
1462 if (s->dma_dac.mapped || !s->dma_dac.ready)
1463 return 0;
1464 current->state = TASK_INTERRUPTIBLE;
1465 add_wait_queue(&s->dma_dac.wait, &wait);
1466 for (;;) {
1467 spin_lock_irqsave(&s->lock, flags);
1468 count = s->dma_dac.count;
1469 spin_unlock_irqrestore(&s->lock, flags);
1470 if (count <= 0)
1471 break;
1472 if (signal_pending(current))
1473 break;
1474 if (nonblock) {
1475 remove_wait_queue(&s->dma_dac.wait, &wait);
1476 current->state = TASK_RUNNING;
1477 return -EBUSY;
1478 }
1479 tmo = (count * HZ) / s->ratedac;
1480 tmo >>= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
1481 if (!schedule_timeout(tmo ? : 1) && tmo)
1482 printk(KERN_DEBUG "cm: dma timed out??\n");
1483 }
1484 remove_wait_queue(&s->dma_dac.wait, &wait);
1485 current->state = TASK_RUNNING;
1486 if (signal_pending(current))
1487 return -ERESTARTSYS;
1488 return 0;
1489}
1490
1491/* --------------------------------------------------------------------- */
1492
1493static ssize_t cm_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
1494{
1495 struct cm_state *s = (struct cm_state *)file->private_data;
1496 ssize_t ret;
1497 unsigned long flags;
1498 unsigned swptr;
1499 int cnt;
1500
1501 VALIDATE_STATE(s);
1502 if (ppos != &file->f_pos)
1503 return -ESPIPE;
1504 if (s->dma_adc.mapped)
1505 return -ENXIO;
1506 if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
1507 return ret;
1508 if (!access_ok(VERIFY_WRITE, buffer, count))
1509 return -EFAULT;
1510 ret = 0;
1511#if 0
1512 spin_lock_irqsave(&s->lock, flags);
1513 cm_update_ptr(s);
1514 spin_unlock_irqrestore(&s->lock, flags);
1515#endif
1516 while (count > 0) {
1517 spin_lock_irqsave(&s->lock, flags);
1518 swptr = s->dma_adc.swptr;
1519 cnt = s->dma_adc.dmasize-swptr;
1520 if (s->dma_adc.count < cnt)
1521 cnt = s->dma_adc.count;
1522 spin_unlock_irqrestore(&s->lock, flags);
1523 if (cnt > count)
1524 cnt = count;
1525 if (cnt <= 0) {
1526 start_adc(s);
1527 if (file->f_flags & O_NONBLOCK)
1528 return ret ? ret : -EAGAIN;
1529 if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
1530 printk(KERN_DEBUG "cm: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
1531 s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count,
1532 s->dma_adc.hwptr, s->dma_adc.swptr);
1533 stop_adc(s);
1534 spin_lock_irqsave(&s->lock, flags);
1535 set_dmaadc(s, s->dma_adc.rawphys, s->dma_adc.dmasamples);
1536 /* program sample counts */
1537 outw(s->dma_adc.fragsamples-1, s->iobase + CODEC_CMI_CH1_FRAME2 + 2);
1538 s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
1539 spin_unlock_irqrestore(&s->lock, flags);
1540 }
1541 if (signal_pending(current))
1542 return ret ? ret : -ERESTARTSYS;
1543 continue;
1544 }
1545 if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt))
1546 return ret ? ret : -EFAULT;
1547 swptr = (swptr + cnt) % s->dma_adc.dmasize;
1548 spin_lock_irqsave(&s->lock, flags);
1549 s->dma_adc.swptr = swptr;
1550 s->dma_adc.count -= cnt;
1551 spin_unlock_irqrestore(&s->lock, flags);
1552 count -= cnt;
1553 buffer += cnt;
1554 ret += cnt;
1555 start_adc(s);
1556 }
1557 return ret;
1558}
1559
1560static ssize_t cm_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
1561{
1562 struct cm_state *s = (struct cm_state *)file->private_data;
1563 ssize_t ret;
1564 unsigned long flags;
1565 unsigned swptr;
1566 int cnt;
1567
1568 VALIDATE_STATE(s);
1569 if (ppos != &file->f_pos)
1570 return -ESPIPE;
1571 if (s->dma_dac.mapped)
1572 return -ENXIO;
1573 if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
1574 return ret;
1575 if (!access_ok(VERIFY_READ, buffer, count))
1576 return -EFAULT;
1577 ret = 0;
1578#if 0
1579 spin_lock_irqsave(&s->lock, flags);
1580 cm_update_ptr(s);
1581 spin_unlock_irqrestore(&s->lock, flags);
1582#endif
1583 while (count > 0) {
1584 spin_lock_irqsave(&s->lock, flags);
1585 if (s->dma_dac.count < 0) {
1586 s->dma_dac.count = 0;
1587 s->dma_dac.swptr = s->dma_dac.hwptr;
1588 }
1589 swptr = s->dma_dac.swptr;
1590 cnt = s->dma_dac.dmasize-swptr;
1591 if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
1592 cnt = s->dma_dac.dmasize - s->dma_dac.count;
1593 spin_unlock_irqrestore(&s->lock, flags);
1594 if (cnt > count)
1595 cnt = count;
1596 if (cnt <= 0) {
1597 start_dac(s);
1598 if (file->f_flags & O_NONBLOCK)
1599 return ret ? ret : -EAGAIN;
1600 if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
1601 printk(KERN_DEBUG "cm: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
1602 s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
1603 s->dma_dac.hwptr, s->dma_dac.swptr);
1604 stop_dac(s);
1605 spin_lock_irqsave(&s->lock, flags);
1606 set_dmadac(s, s->dma_dac.rawphys, s->dma_dac.dmasamples);
1607 /* program sample counts */
1608 outw(s->dma_dac.fragsamples-1, s->iobase + CODEC_CMI_CH0_FRAME2 + 2);
1609 s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
1610 spin_unlock_irqrestore(&s->lock, flags);
1611 }
1612 if (signal_pending(current))
1613 return ret ? ret : -ERESTARTSYS;
1614 continue;
1615 }
1616 if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
1617 return ret ? ret : -EFAULT;
1618 swptr = (swptr + cnt) % s->dma_dac.dmasize;
1619 spin_lock_irqsave(&s->lock, flags);
1620 s->dma_dac.swptr = swptr;
1621 s->dma_dac.count += cnt;
1622 s->dma_dac.endcleared = 0;
1623 spin_unlock_irqrestore(&s->lock, flags);
1624 count -= cnt;
1625 buffer += cnt;
1626 ret += cnt;
1627 start_dac(s);
1628 }
1629 return ret;
1630}
1631
1632static unsigned int cm_poll(struct file *file, struct poll_table_struct *wait)
1633{
1634 struct cm_state *s = (struct cm_state *)file->private_data;
1635 unsigned long flags;
1636 unsigned int mask = 0;
1637
1638 VALIDATE_STATE(s);
1639 if (file->f_mode & FMODE_WRITE)
1640 poll_wait(file, &s->dma_dac.wait, wait);
1641 if (file->f_mode & FMODE_READ)
1642 poll_wait(file, &s->dma_adc.wait, wait);
1643 spin_lock_irqsave(&s->lock, flags);
1644 cm_update_ptr(s);
1645 if (file->f_mode & FMODE_READ) {
1646 if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
1647 mask |= POLLIN | POLLRDNORM;
1648 }
1649 if (file->f_mode & FMODE_WRITE) {
1650 if (s->dma_dac.mapped) {
1651 if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
1652 mask |= POLLOUT | POLLWRNORM;
1653 } else {
1654 if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
1655 mask |= POLLOUT | POLLWRNORM;
1656 }
1657 }
1658 spin_unlock_irqrestore(&s->lock, flags);
1659 return mask;
1660}
1661
1662static int cm_mmap(struct file *file, struct vm_area_struct *vma)
1663{
1664 struct cm_state *s = (struct cm_state *)file->private_data;
1665 struct dmabuf *db;
1666 int ret;
1667 unsigned long size;
1668
1669 VALIDATE_STATE(s);
1670 if (vma->vm_flags & VM_WRITE) {
1671 if ((ret = prog_dmabuf(s, 1)) != 0)
1672 return ret;
1673 db = &s->dma_dac;
1674 } else if (vma->vm_flags & VM_READ) {
1675 if ((ret = prog_dmabuf(s, 0)) != 0)
1676 return ret;
1677 db = &s->dma_adc;
1678 } else
1679 return -EINVAL;
1680#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
1681 if (vma->vm_pgoff != 0)
1682#else
1683 if (vma->vm_offset != 0)
1684#endif
1685 return -EINVAL;
1686 size = vma->vm_end - vma->vm_start;
1687 if (size > (PAGE_SIZE << db->buforder))
1688 return -EINVAL;
1689 if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
1690 return -EAGAIN;
1691 db->mapped = 1;
1692 return 0;
1693}
1694
1695static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
1696{
1697 struct cm_state *s = (struct cm_state *)file->private_data;
1698 unsigned long flags;
1699 audio_buf_info abinfo;
1700 count_info cinfo;
1701 int val, mapped, ret;
1702 unsigned char fmtm, fmtd;
1703
1704 VALIDATE_STATE(s);
1705 mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
1706 ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
1707 switch (cmd) {
1708 case OSS_GETVERSION:
1709 return put_user(SOUND_VERSION, (int *)arg);
1710
1711 case SNDCTL_DSP_SYNC:
1712 if (file->f_mode & FMODE_WRITE)
1713 return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
1714 return 0;
1715
1716 case SNDCTL_DSP_SETDUPLEX:
1717 return 0;
1718
1719 case SNDCTL_DSP_GETCAPS:
1720 return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
1721
1722 case SNDCTL_DSP_RESET:
1723 if (file->f_mode & FMODE_WRITE) {
1724 stop_dac(s);
1725 synchronize_irq();
1726 s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
1727 }
1728 if (file->f_mode & FMODE_READ) {
1729 stop_adc(s);
1730 synchronize_irq();
1731 s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
1732 }
1733 return 0;
1734
1735 case SNDCTL_DSP_SPEED:
1736 get_user_ret(val, (int *)arg, -EFAULT);
1737 if (val >= 0) {
1738 if (file->f_mode & FMODE_READ) {
1739 stop_adc(s);
1740 s->dma_adc.ready = 0;
1741 set_adc_rate(s, val);
1742 }
1743 if (file->f_mode & FMODE_WRITE) {
1744 stop_dac(s);
1745 s->dma_dac.ready = 0;
1746 set_dac_rate(s, val);
1747 }
1748 }
1749 return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
1750
1751 case SNDCTL_DSP_STEREO:
1752 get_user_ret(val, (int *)arg, -EFAULT);
1753 fmtd = 0;
1754 fmtm = ~0;
1755 if (file->f_mode & FMODE_READ) {
1756 stop_adc(s);
1757 s->dma_adc.ready = 0;
1758 if (val)
1759 fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
1760 else
1761 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
1762 }
1763 if (file->f_mode & FMODE_WRITE) {
1764 stop_dac(s);
1765 s->dma_dac.ready = 0;
1766 if (val)
1767 fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
1768 else
1769 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
1770 }
1771 set_fmt(s, fmtm, fmtd);
1772 return 0;
1773
1774 case SNDCTL_DSP_CHANNELS:
1775 get_user_ret(val, (int *)arg, -EFAULT);
1776 if (val != 0) {
1777 fmtd = 0;
1778 fmtm = ~0;
1779 if (file->f_mode & FMODE_READ) {
1780 stop_adc(s);
1781 s->dma_adc.ready = 0;
1782 if (val >= 2)
1783 fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
1784 else
1785 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
1786 }
1787 if (file->f_mode & FMODE_WRITE) {
1788 stop_dac(s);
1789 s->dma_dac.ready = 0;
1790 if (val >= 2)
1791 fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
1792 else
1793 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
1794 }
1795 set_fmt(s, fmtm, fmtd);
1796 }
1797 return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT)
1798 : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, (int *)arg);
1799
1800 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
1801 return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
1802
1803 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
1804 get_user_ret(val, (int *)arg, -EFAULT);
1805 if (val != AFMT_QUERY) {
1806 fmtd = 0;
1807 fmtm = ~0;
1808 if (file->f_mode & FMODE_READ) {
1809 stop_adc(s);
1810 s->dma_adc.ready = 0;
1811 if (val == AFMT_S16_LE)
1812 fmtd |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
1813 else
1814 fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_ADCSHIFT);
1815 }
1816 if (file->f_mode & FMODE_WRITE) {
1817 stop_dac(s);
1818 s->dma_dac.ready = 0;
1819 if (val == AFMT_S16_LE)
1820 fmtd |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
1821 else
1822 fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_DACSHIFT);
1823 }
1824 set_fmt(s, fmtm, fmtd);
1825 }
1826 return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT)
1827 : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? AFMT_S16_LE : AFMT_U8, (int *)arg);
1828
1829 case SNDCTL_DSP_POST:
1830 return 0;
1831
1832 case SNDCTL_DSP_GETTRIGGER:
1833 val = 0;
1834 if (file->f_mode & FMODE_READ && s->enable & CM_CENABLE_RE)
1835 val |= PCM_ENABLE_INPUT;
1836 if (file->f_mode & FMODE_WRITE && s->enable & CM_CENABLE_PE)
1837 val |= PCM_ENABLE_OUTPUT;
1838 return put_user(val, (int *)arg);
1839
1840 case SNDCTL_DSP_SETTRIGGER:
1841 get_user_ret(val, (int *)arg, -EFAULT);
1842 if (file->f_mode & FMODE_READ) {
1843 if (val & PCM_ENABLE_INPUT) {
1844 if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
1845 return ret;
1846 start_adc(s);
1847 } else
1848 stop_adc(s);
1849 }
1850 if (file->f_mode & FMODE_WRITE) {
1851 if (val & PCM_ENABLE_OUTPUT) {
1852 if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
1853 return ret;
1854 start_dac(s);
1855 } else
1856 stop_dac(s);
1857 }
1858 return 0;
1859
1860 case SNDCTL_DSP_GETOSPACE:
1861 if (!(file->f_mode & FMODE_WRITE))
1862 return -EINVAL;
1863 if (!(s->enable & CM_CENABLE_PE) && (val = prog_dmabuf(s, 0)) != 0)
1864 return val;
1865 spin_lock_irqsave(&s->lock, flags);
1866 cm_update_ptr(s);
1867 abinfo.fragsize = s->dma_dac.fragsize;
1868 abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
1869 abinfo.fragstotal = s->dma_dac.numfrag;
1870 abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
1871 spin_unlock_irqrestore(&s->lock, flags);
1872 return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
1873
1874 case SNDCTL_DSP_GETISPACE:
1875 if (!(file->f_mode & FMODE_READ))
1876 return -EINVAL;
1877 if (!(s->enable & CM_CENABLE_RE) && (val = prog_dmabuf(s, 1)) != 0)
1878 return val;
1879 spin_lock_irqsave(&s->lock, flags);
1880 cm_update_ptr(s);
1881 abinfo.fragsize = s->dma_adc.fragsize;
1882 abinfo.bytes = s->dma_adc.count;
1883 abinfo.fragstotal = s->dma_adc.numfrag;
1884 abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
1885 spin_unlock_irqrestore(&s->lock, flags);
1886 return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
1887
1888 case SNDCTL_DSP_NONBLOCK:
1889 file->f_flags |= O_NONBLOCK;
1890 return 0;
1891
1892 case SNDCTL_DSP_GETODELAY:
1893 if (!(file->f_mode & FMODE_WRITE))
1894 return -EINVAL;
1895 spin_lock_irqsave(&s->lock, flags);
1896 cm_update_ptr(s);
1897 val = s->dma_dac.count;
1898 spin_unlock_irqrestore(&s->lock, flags);
1899 return put_user(val, (int *)arg);
1900
1901 case SNDCTL_DSP_GETIPTR:
1902 if (!(file->f_mode & FMODE_READ))
1903 return -EINVAL;
1904 spin_lock_irqsave(&s->lock, flags);
1905 cm_update_ptr(s);
1906 cinfo.bytes = s->dma_adc.total_bytes;
1907 cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
1908 cinfo.ptr = s->dma_adc.hwptr;
1909 if (s->dma_adc.mapped)
1910 s->dma_adc.count &= s->dma_adc.fragsize-1;
1911 spin_unlock_irqrestore(&s->lock, flags);
1912 return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
1913
1914 case SNDCTL_DSP_GETOPTR:
1915 if (!(file->f_mode & FMODE_WRITE))
1916 return -EINVAL;
1917 spin_lock_irqsave(&s->lock, flags);
1918 cm_update_ptr(s);
1919 cinfo.bytes = s->dma_dac.total_bytes;
1920 cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
1921 cinfo.ptr = s->dma_dac.hwptr;
1922 if (s->dma_dac.mapped)
1923 s->dma_dac.count &= s->dma_dac.fragsize-1;
1924 spin_unlock_irqrestore(&s->lock, flags);
1925 return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
1926
1927 case SNDCTL_DSP_GETBLKSIZE:
1928 if (file->f_mode & FMODE_WRITE) {
1929 if ((val = prog_dmabuf(s, 0)))
1930 return val;
1931 return put_user(s->dma_dac.fragsize, (int *)arg);
1932 }
1933 if ((val = prog_dmabuf(s, 1)))
1934 return val;
1935 return put_user(s->dma_adc.fragsize, (int *)arg);
1936
1937 case SNDCTL_DSP_SETFRAGMENT:
1938 get_user_ret(val, (int *)arg, -EFAULT);
1939 if (file->f_mode & FMODE_READ) {
1940 s->dma_adc.ossfragshift = val & 0xffff;
1941 s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
1942 if (s->dma_adc.ossfragshift < 4)
1943 s->dma_adc.ossfragshift = 4;
1944 if (s->dma_adc.ossfragshift > 15)
1945 s->dma_adc.ossfragshift = 15;
1946 if (s->dma_adc.ossmaxfrags < 4)
1947 s->dma_adc.ossmaxfrags = 4;
1948 }
1949 if (file->f_mode & FMODE_WRITE) {
1950 s->dma_dac.ossfragshift = val & 0xffff;
1951 s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
1952 if (s->dma_dac.ossfragshift < 4)
1953 s->dma_dac.ossfragshift = 4;
1954 if (s->dma_dac.ossfragshift > 15)
1955 s->dma_dac.ossfragshift = 15;
1956 if (s->dma_dac.ossmaxfrags < 4)
1957 s->dma_dac.ossmaxfrags = 4;
1958 }
1959 return 0;
1960
1961 case SNDCTL_DSP_SUBDIVIDE:
1962 if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
1963 (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
1964 return -EINVAL;
1965 get_user_ret(val, (int *)arg, -EFAULT);
1966 if (val != 1 && val != 2 && val != 4)
1967 return -EINVAL;
1968 if (file->f_mode & FMODE_READ)
1969 s->dma_adc.subdivision = val;
1970 if (file->f_mode & FMODE_WRITE)
1971 s->dma_dac.subdivision = val;
1972 return 0;
1973
1974 case SOUND_PCM_READ_RATE:
1975 return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
1976
1977 case SOUND_PCM_READ_CHANNELS:
1978 return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, (int *)arg);
1979
1980 case SOUND_PCM_READ_BITS:
1981 return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? 16 : 8, (int *)arg);
1982
1983 case SOUND_PCM_READ_FILTER:
1984 return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
1985 case SOUND_PCM_WRITE_FILTER:
1986 case SNDCTL_DSP_SETSYNCRO:
1987 return -EINVAL;
1988
1989 }
1990 return mixer_ioctl(s, cmd, arg);
1991}
1992
1993static int cm_open(struct inode *inode, struct file *file)
1994{
1995 int minor = MINOR(inode->i_rdev);
1996 struct cm_state *s = devs;
1997 unsigned char fmtm = ~0, fmts = 0;
1998
1999 while (s && ((s->dev_audio ^ minor) & ~0xf))
2000 s = s->next;
2001 if (!s)
2002 return -ENODEV;
2003 VALIDATE_STATE(s);
2004 file->private_data = s;
2005 /* wait for device to become free */
2006 down(&s->open_sem);
2007 while (s->open_mode & file->f_mode) {
2008 if (file->f_flags & O_NONBLOCK) {
2009 up(&s->open_sem);
2010 return -EBUSY;
2011 }
2012 up(&s->open_sem);
2013 interruptible_sleep_on(&s->open_wait);
2014 if (signal_pending(current))
2015 return -ERESTARTSYS;
2016 down(&s->open_sem);
2017 }
2018 if (file->f_mode & FMODE_READ) {
2019 fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT);
2020 if ((minor & 0xf) == SND_DEV_DSP16)
2021 fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
2022 s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
2023 set_adc_rate(s, 8000);
2024 }
2025 if (file->f_mode & FMODE_WRITE) {
2026 fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT);
2027 if ((minor & 0xf) == SND_DEV_DSP16)
2028 fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
2029 s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
2030 set_dac_rate(s, 8000);
2031 }
2032 set_fmt(s, fmtm, fmts);
2033 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
2034 up(&s->open_sem);
2035 MOD_INC_USE_COUNT;
2036 return 0;
2037}
2038
2039static int cm_release(struct inode *inode, struct file *file)
2040{
2041 struct cm_state *s = (struct cm_state *)file->private_data;
2042
2043 VALIDATE_STATE(s);
2044 if (file->f_mode & FMODE_WRITE)
2045 drain_dac(s, file->f_flags & O_NONBLOCK);
2046 down(&s->open_sem);
2047 if (file->f_mode & FMODE_WRITE) {
2048 stop_dac(s);
2049#ifndef FIXEDDMA
2050 dealloc_dmabuf(&s->dma_dac);
2051#endif
2052 }
2053 if (file->f_mode & FMODE_READ) {
2054 stop_adc(s);
2055#ifndef FIXEDDMA
2056 dealloc_dmabuf(&s->dma_adc);
2057#endif
2058 }
2059 s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
2060 up(&s->open_sem);
2061 wake_up(&s->open_wait);
2062 MOD_DEC_USE_COUNT;
2063 return 0;
2064}
2065
2066static /*const*/ struct file_operations cm_audio_fops = {
2067#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2068 llseek: cm_llseek,
2069 read: cm_read,
2070 write: cm_write,
2071 poll: cm_poll,
2072 ioctl: cm_ioctl,
2073 mmap: cm_mmap,
2074 open: cm_open,
2075 release: cm_release,
2076#else
2077 &cm_llseek,
2078 &cm_read,
2079 &cm_write,
2080 NULL, /* readdir */
2081 &cm_poll,
2082 &cm_ioctl,
2083 &cm_mmap,
2084 &cm_open,
2085 NULL, /* flush */
2086 &cm_release,
2087 NULL, /* fsync */
2088 NULL, /* fasync */
2089 NULL, /* check_media_change */
2090 NULL, /* revalidate */
2091 NULL, /* lock */
2092#endif
2093};
2094
2095#ifdef DUAL_DAC
2096static ssize_t cm_write_dual(struct file *file, const char *buffer, size_t count, loff_t *ppos)
2097{
2098 struct cm_state *s = (struct cm_state *)file->private_data;
2099 ssize_t ret;
2100 unsigned long flags;
2101 unsigned swptr;
2102 int cnt;
2103
2104 VALIDATE_STATE(s);
2105 if (ppos != &file->f_pos)
2106 return -ESPIPE;
2107 if (s->dma_dac.mapped)
2108 return -ENXIO;
2109 if (s->dma_adc.mapped)
2110 return -ENXIO;
2111 if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
2112 return ret;
2113 if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
2114 return ret;
2115 if (!access_ok(VERIFY_READ, buffer, count))
2116 return -EFAULT;
2117 ret = 0;
2118#if 0
2119 spin_lock_irqsave(&s->lock, flags);
2120 cm_update_ptr(s);
2121 spin_unlock_irqrestore(&s->lock, flags);
2122#endif
2123 while (count > 0) {
2124 spin_lock_irqsave(&s->lock, flags);
2125 if (s->dma_dac.count < 0) {
2126 s->dma_dac.count = 0;
2127 s->dma_dac.swptr = s->dma_dac.hwptr;
2128 }
2129 if (s->dma_adc.count < 0) {
2130 s->dma_adc.count = 0;
2131 s->dma_adc.swptr = s->dma_adc.hwptr;
2132 }
2133 swptr = s->dma_dac.swptr;
2134 cnt = s->dma_dac.dmasize-swptr;
2135 if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
2136 cnt = s->dma_dac.dmasize - s->dma_dac.count;
2137 spin_unlock_irqrestore(&s->lock, flags);
2138 if (cnt > count / 2)
2139 cnt = count / 2;
2140 if (cnt <= 0) {
2141 start_dac(s);
2142 start_dac1(s);
2143 if (file->f_flags & O_NONBLOCK)
2144 return ret ? ret : -EAGAIN;
2145 if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
2146 printk(KERN_DEBUG "cm: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
2147 s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
2148 s->dma_dac.hwptr, s->dma_dac.swptr);
2149 stop_dac(s);
2150 stop_dac1(s);
2151 spin_lock_irqsave(&s->lock, flags);
2152 set_dmadac(s, s->dma_dac.rawphys, s->dma_dac.dmasamples);
2153 set_dmadac1(s, s->dma_adc.rawphys, s->dma_adc.dmasamples);
2154 /* program sample counts */
2155 outw(s->dma_dac.fragsamples-1, s->iobase + CODEC_CMI_CH0_FRAME2 + 2);
2156 outw(s->dma_adc.fragsamples-1, s->iobase + CODEC_CMI_CH1_FRAME2 + 2);
2157 s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
2158 s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
2159 spin_unlock_irqrestore(&s->lock, flags);
2160 }
2161 if (signal_pending(current))
2162 return ret ? ret : -ERESTARTSYS;
2163 continue;
2164 }
2165#if 1
2166 {
2167 int i;
2168 unsigned long *src, *dst0, *dst1;
2169
2170 src = (unsigned long *) buffer;
2171 dst0 = (unsigned long *) (s->dma_dac.rawbuf + swptr);
2172 dst1 = (unsigned long *) (s->dma_adc.rawbuf + swptr);
2173 // copy left/right sample at one time
2174 for (i = 0; i <= cnt / 4; i++)
2175 {
2176 *dst0++ = *src++;
2177 *dst1++ = *src++;
2178 }
2179 }
2180#else
2181 if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
2182 return ret ? ret : -EFAULT;
2183 if (copy_from_user(s->dma_adc.rawbuf + swptr, buffer, cnt))
2184 return ret ? ret : -EFAULT;
2185#endif
2186 swptr = (swptr + cnt) % s->dma_dac.dmasize;
2187 spin_lock_irqsave(&s->lock, flags);
2188 s->dma_adc.swptr =
2189 s->dma_dac.swptr = swptr;
2190 s->dma_adc.count += cnt;
2191 s->dma_dac.count += cnt;
2192 s->dma_adc.endcleared =
2193 s->dma_dac.endcleared = 0;
2194 spin_unlock_irqrestore(&s->lock, flags);
2195 count -= cnt * 2;
2196 buffer += cnt * 2;
2197 ret += cnt * 2;
2198 start_dac(s);
2199 start_dac1(s);
2200 }
2201 return ret;
2202}
2203
2204static unsigned int cm_poll_dual(struct file *file, struct poll_table_struct *wait)
2205{
2206 struct cm_state *s = (struct cm_state *)file->private_data;
2207 unsigned long flags;
2208 unsigned int mask = 0;
2209
2210 VALIDATE_STATE(s);
2211 if (file->f_mode & FMODE_WRITE)
2212 poll_wait(file, &s->dma_dac.wait, wait);
2213 if (file->f_mode & FMODE_READ)
2214 poll_wait(file, &s->dma_adc.wait, wait);
2215 spin_lock_irqsave(&s->lock, flags);
2216 cm_update_ptr(s);
2217 if (file->f_mode & FMODE_READ) {
2218 if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
2219 mask |= POLLIN | POLLRDNORM;
2220 }
2221 if (file->f_mode & FMODE_WRITE) {
2222 if (s->dma_dac.mapped) {
2223 if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
2224 mask |= POLLOUT | POLLWRNORM;
2225 } else {
2226 if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
2227 mask |= POLLOUT | POLLWRNORM;
2228 }
2229 }
2230 spin_unlock_irqrestore(&s->lock, flags);
2231 return mask;
2232}
2233
2234static int cm_mmap_dual(struct file *file, struct vm_area_struct *vma)
2235{
2236 struct cm_state *s = (struct cm_state *)file->private_data;
2237 struct dmabuf *db;
2238 int ret;
2239 unsigned long size;
2240
2241 VALIDATE_STATE(s);
2242 if (vma->vm_flags & VM_WRITE) {
2243 if ((ret = prog_dmabuf(s, 1)) != 0)
2244 return ret;
2245 db = &s->dma_dac;
2246 } else if (vma->vm_flags & VM_READ) {
2247 if ((ret = prog_dmabuf(s, 0)) != 0)
2248 return ret;
2249 db = &s->dma_adc;
2250 } else
2251 return -EINVAL;
2252#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2253 if (vma->vm_pgoff != 0)
2254#else
2255 if (vma->vm_offset != 0)
2256#endif
2257 return -EINVAL;
2258 size = vma->vm_end - vma->vm_start;
2259 if (size > (PAGE_SIZE << db->buforder))
2260 return -EINVAL;
2261 if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
2262 return -EAGAIN;
2263 db->mapped = 1;
2264 return 0;
2265}
2266
2267static int cm_ioctl_dual(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
2268{
2269 struct cm_state *s = (struct cm_state *)file->private_data;
2270 unsigned long flags;
2271 audio_buf_info abinfo;
2272 count_info cinfo;
2273 int val, mapped, ret;
2274 unsigned char fmtm, fmtd;
2275
2276 VALIDATE_STATE(s);
2277 mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
2278 ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
2279 switch (cmd) {
2280 case OSS_GETVERSION:
2281 return put_user(SOUND_VERSION, (int *)arg);
2282
2283 case SNDCTL_DSP_SYNC:
2284 if (file->f_mode & FMODE_WRITE)
2285 return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
2286 return 0;
2287
2288 case SNDCTL_DSP_SETDUPLEX:
2289 return 0;
2290
2291 case SNDCTL_DSP_GETCAPS:
2292 return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
2293
2294 case SNDCTL_DSP_RESET:
2295 if (file->f_mode & FMODE_WRITE) {
2296 stop_dac(s);
2297 stop_dac1(s);
2298 synchronize_irq();
2299 s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
2300 s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
2301 }
2302 return 0;
2303
2304 case SNDCTL_DSP_SPEED:
2305 get_user_ret(val, (int *)arg, -EFAULT);
2306 if (val >= 0) {
2307 if (file->f_mode & FMODE_WRITE) {
2308 stop_dac(s);
2309 stop_dac1(s);
2310 s->dma_dac.ready = 0;
2311 s->dma_adc.ready = 0;
2312 set_dac_rate(s, val);
2313 set_dac1_rate(s, val);
2314 }
2315 }
2316 return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
2317
2318 case SNDCTL_DSP_STEREO:
2319 get_user_ret(val, (int *)arg, -EFAULT);
2320 fmtd = 0;
2321 fmtm = ~0;
2322 if (file->f_mode & FMODE_WRITE) {
2323 stop_dac(s);
2324 stop_dac1(s);
2325 s->dma_dac.ready = 0;
2326 s->dma_adc.ready = 0;
2327 if (val) {
2328 fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
2329 fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
2330 } else {
2331 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
2332 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
2333 }
2334 }
2335 set_fmt(s, fmtm, fmtd);
2336 return 0;
2337
2338 case SNDCTL_DSP_CHANNELS:
2339 get_user_ret(val, (int *)arg, -EFAULT);
2340 if (val != 0) {
2341 fmtd = 0;
2342 fmtm = ~0;
2343 if (file->f_mode & FMODE_WRITE) {
2344 stop_dac(s);
2345 stop_dac1(s);
2346 s->dma_dac.ready = 0;
2347 s->dma_adc.ready = 0;
2348 if (val >= 2) {
2349 fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
2350 fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
2351 } else {
2352 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
2353 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
2354 }
2355 }
2356 set_fmt(s, fmtm, fmtd);
2357 }
2358 return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT)
2359 : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, (int *)arg);
2360
2361 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
2362 return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
2363
2364 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
2365 get_user_ret(val, (int *)arg, -EFAULT);
2366 if (val != AFMT_QUERY) {
2367 fmtd = 0;
2368 fmtm = ~0;
2369 if (file->f_mode & FMODE_WRITE) {
2370 stop_dac(s);
2371 stop_dac1(s);
2372 s->dma_dac.ready = 0;
2373 s->dma_adc.ready = 0;
2374 if (val == AFMT_S16_LE) {
2375 fmtd |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
2376 fmtd |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
2377 } else {
2378 fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_DACSHIFT);
2379 fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_ADCSHIFT);
2380 }
2381 }
2382 set_fmt(s, fmtm, fmtd);
2383 }
2384 return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT)
2385 : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? AFMT_S16_LE : AFMT_U8, (int *)arg);
2386
2387 case SNDCTL_DSP_POST:
2388 return 0;
2389
2390 case SNDCTL_DSP_GETTRIGGER:
2391 val = 0;
2392 if (file->f_mode & FMODE_WRITE && s->enable & CM_CENABLE_PE)
2393 val |= PCM_ENABLE_OUTPUT;
2394 return put_user(val, (int *)arg);
2395
2396 case SNDCTL_DSP_SETTRIGGER:
2397 get_user_ret(val, (int *)arg, -EFAULT);
2398 if (file->f_mode & FMODE_WRITE) {
2399 if (val & PCM_ENABLE_OUTPUT) {
2400 if ((!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) || (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))))
2401 return ret;
2402 start_dac(s);
2403 start_dac1(s);
2404 } else {
2405 stop_dac(s);
2406 stop_dac1(s);
2407 }
2408 }
2409 return 0;
2410
2411 case SNDCTL_DSP_GETOSPACE:
2412 if (!(file->f_mode & FMODE_WRITE))
2413 return -EINVAL;
2414 if (!(s->enable & CM_CENABLE_PE) && (val = prog_dmabuf(s, 0) | prog_dmabuf(s, 1)) != 0)
2415 return val;
2416 spin_lock_irqsave(&s->lock, flags);
2417 cm_update_ptr(s);
2418 abinfo.fragsize = s->dma_dac.fragsize;
2419 abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
2420 abinfo.fragstotal = s->dma_dac.numfrag;
2421 abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
2422 abinfo.fragsize *= 2;
2423 abinfo.bytes *= 2;
2424 spin_unlock_irqrestore(&s->lock, flags);
2425 return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
2426
2427 case SNDCTL_DSP_NONBLOCK:
2428 file->f_flags |= O_NONBLOCK;
2429 return 0;
2430
2431 case SNDCTL_DSP_GETODELAY:
2432 if (!(file->f_mode & FMODE_WRITE))
2433 return -EINVAL;
2434 spin_lock_irqsave(&s->lock, flags);
2435 cm_update_ptr(s);
2436 val = s->dma_dac.count;
2437 val *= 2;
2438 spin_unlock_irqrestore(&s->lock, flags);
2439 return put_user(val, (int *)arg);
2440
2441 case SNDCTL_DSP_GETOPTR:
2442 if (!(file->f_mode & FMODE_WRITE))
2443 return -EINVAL;
2444 spin_lock_irqsave(&s->lock, flags);
2445 cm_update_ptr(s);
2446 cinfo.bytes = s->dma_dac.total_bytes;
2447 cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
2448 cinfo.ptr = s->dma_dac.hwptr;
2449 cinfo.bytes *= 2;
2450 cinfo.ptr *= 2;
2451 if (s->dma_dac.mapped)
2452 s->dma_dac.count &= s->dma_dac.fragsize-1;
2453 spin_unlock_irqrestore(&s->lock, flags);
2454 return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
2455
2456 case SNDCTL_DSP_GETBLKSIZE:
2457 if (file->f_mode & FMODE_WRITE) {
2458 if ((val = prog_dmabuf(s, 0) | prog_dmabuf(s, 1)))
2459 return val;
2460 return put_user(2 * s->dma_dac.fragsize, (int *)arg);
2461 }
2462 if ((val = prog_dmabuf(s, 1)))
2463 return val;
2464 return put_user(2 * s->dma_adc.fragsize, (int *)arg);
2465
2466 case SNDCTL_DSP_SETFRAGMENT:
2467 get_user_ret(val, (int *)arg, -EFAULT);
2468 if (file->f_mode & FMODE_WRITE) {
2469 s->dma_adc.ossfragshift =
2470 s->dma_dac.ossfragshift = val & 0xffff;
2471 s->dma_adc.ossmaxfrags =
2472 s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
2473 if (s->dma_dac.ossfragshift < 4)
2474 s->dma_adc.ossfragshift =
2475 s->dma_dac.ossfragshift = 4;
2476 if (s->dma_dac.ossfragshift > 15)
2477 s->dma_adc.ossfragshift =
2478 s->dma_dac.ossfragshift = 15;
2479 if (s->dma_dac.ossmaxfrags < 4)
2480 s->dma_adc.ossmaxfrags =
2481 s->dma_dac.ossmaxfrags = 4;
2482 }
2483 return 0;
2484
2485 case SNDCTL_DSP_SUBDIVIDE:
2486 if (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision)
2487 return -EINVAL;
2488 get_user_ret(val, (int *)arg, -EFAULT);
2489 if (val != 1 && val != 2 && val != 4)
2490 return -EINVAL;
2491 if (file->f_mode & FMODE_WRITE)
2492 s->dma_adc.subdivision =
2493 s->dma_dac.subdivision = val;
2494 return 0;
2495
2496 case SOUND_PCM_READ_RATE:
2497 return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
2498
2499 case SOUND_PCM_READ_CHANNELS:
2500 return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, (int *)arg);
2501
2502 case SOUND_PCM_READ_BITS:
2503 return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? 16 : 8, (int *)arg);
2504
2505 case SOUND_PCM_READ_FILTER:
2506 return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
2507 case SOUND_PCM_WRITE_FILTER:
2508 case SNDCTL_DSP_SETSYNCRO:
2509 return -EINVAL;
2510
2511 }
2512 return mixer_ioctl(s, cmd, arg);
2513}
2514
2515static int cm_open_dual(struct inode *inode, struct file *file)
2516{
2517 int minor = MINOR(inode->i_rdev);
2518 struct cm_state *s = devs;
2519 unsigned char fmtm = ~0, fmts = 0;
2520
2521 while (s && ((s->dev_dsp ^ minor) & ~0xf))
2522 s = s->next;
2523 if (!s)
2524 return -ENODEV;
2525 VALIDATE_STATE(s);
2526 if (!(file->f_mode & FMODE_WRITE))
2527 return -EINVAL;
2528 file->private_data = s;
2529 /* wait for device to become free */
2530 down(&s->open_sem);
2531 while (s->open_mode & file->f_mode) {
2532 if (file->f_flags & O_NONBLOCK) {
2533 up(&s->open_sem);
2534 return -EBUSY;
2535 }
2536 up(&s->open_sem);
2537 interruptible_sleep_on(&s->open_wait);
2538 if (signal_pending(current))
2539 return -ERESTARTSYS;
2540 down(&s->open_sem);
2541 }
2542 if (file->f_mode & FMODE_WRITE) {
2543 fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT);
2544 fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT);
2545 // the HW only support 16-bit stereo
2546 fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
2547 fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
2548 fmts |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
2549 fmts |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
2550 s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
2551 s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
2552 set_dac_rate(s, 8000);
2553 set_dac1_rate(s, 8000);
2554 }
2555 set_fmt(s, fmtm, fmts);
2556 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
2557 s->dual_mode = 1;
2558 /* disable 4 channel mode (analog duplicate) */
2559 if (s->four_ch)
2560 outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 3) & ~0x04, s->iobase + CODEC_CMI_MISC_CTRL + 3);
2561 /* turn on double DAC mode */
2562 outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 2) | 0x80, s->iobase + CODEC_CMI_MISC_CTRL + 2);
2563 up(&s->open_sem);
2564 MOD_INC_USE_COUNT;
2565 return 0;
2566}
2567
2568static int cm_release_dual(struct inode *inode, struct file *file)
2569{
2570 struct cm_state *s = (struct cm_state *)file->private_data;
2571
2572 VALIDATE_STATE(s);
2573 if (file->f_mode & FMODE_WRITE)
2574 drain_dac(s, file->f_flags & O_NONBLOCK);
2575 down(&s->open_sem);
2576 if (file->f_mode & FMODE_WRITE) {
2577 stop_dac(s);
2578 stop_dac1(s);
2579#ifndef FIXEDDMA
2580 dealloc_dmabuf(&s->dma_dac);
2581 dealloc_dmabuf(&s->dma_adc);
2582#endif
2583 }
2584 s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
2585 s->dual_mode = 0;
2586 /* enable 4 channel mode (analog duplicate) */
2587 if (s->four_ch)
2588 outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 3) | 0x04, s->iobase + CODEC_CMI_MISC_CTRL + 3);
2589 /* turn off double DAC mode */
2590 outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 2) & ~0x80, s->iobase + CODEC_CMI_MISC_CTRL + 2);
2591 up(&s->open_sem);
2592 wake_up(&s->open_wait);
2593 MOD_DEC_USE_COUNT;
2594 return 0;
2595}
2596
2597static /*const*/ struct file_operations cm_dsp_fops = {
2598#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2599 llseek: cm_llseek,
2600 write: cm_write_dual,
2601 poll: cm_poll_dual,
2602 ioctl: cm_ioctl_dual,
2603 mmap: cm_mmap_dual,
2604 open: cm_open_dual,
2605 release: cm_release_dual,
2606#else
2607 &cm_llseek,
2608 NULL,
2609 &cm_write_dual,
2610 NULL, /* readdir */
2611 &cm_poll_dual,
2612 &cm_ioctl_dual,
2613 &cm_mmap_dual,
2614 &cm_open_dual,
2615 NULL, /* flush */
2616 &cm_release_dual,
2617 NULL, /* fsync */
2618 NULL, /* fasync */
2619 NULL, /* check_media_change */
2620 NULL, /* revalidate */
2621 NULL, /* lock */
2622#endif
2623};
2624#endif
2625
2626#ifdef CONFIG_SOUND_CMPCI_MIDI
2627/* --------------------------------------------------------------------- */
2628
2629static ssize_t cm_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
2630{
2631 struct cm_state *s = (struct cm_state *)file->private_data;
2632#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2633 DECLARE_WAITQUEUE(wait, current);
2634#endif
2635 ssize_t ret;
2636 unsigned long flags;
2637 unsigned ptr;
2638 int cnt;
2639
2640 VALIDATE_STATE(s);
2641 if (ppos != &file->f_pos)
2642 return -ESPIPE;
2643 if (!access_ok(VERIFY_WRITE, buffer, count))
2644 return -EFAULT;
2645 ret = 0;
2646#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2647 add_wait_queue(&s->midi.iwait, &wait);
2648#endif
2649 while (count > 0) {
2650 spin_lock_irqsave(&s->lock, flags);
2651 ptr = s->midi.ird;
2652 cnt = MIDIINBUF - ptr;
2653 if (s->midi.icnt < cnt)
2654 cnt = s->midi.icnt;
2655 spin_unlock_irqrestore(&s->lock, flags);
2656 if (cnt > count)
2657 cnt = count;
2658 if (cnt <= 0) {
2659 if (file->f_flags & O_NONBLOCK)
2660#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2661 {
2662 if (!ret)
2663 ret = -EAGAIN;
2664 break;
2665 }
2666 __set_current_state(TASK_INTERRUPTIBLE);
2667 schedule();
2668 if (signal_pending(current))
2669 {
2670 if (!ret)
2671 ret = -ERESTARTSYS;
2672 break;
2673 }
2674#else
2675 return ret ? ret : -EAGAIN;
2676 interruptible_sleep_on(&s->midi.iwait);
2677 if (signal_pending(current))
2678 return ret ? ret : -ERESTARTSYS;
2679#endif
2680 continue;
2681 }
2682 if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt))
2683#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2684 {
2685 if (!ret)
2686 ret = -EFAULT;
2687 break;
2688 }
2689#else
2690 return ret ? ret : -EFAULT;
2691#endif
2692 ptr = (ptr + cnt) % MIDIINBUF;
2693 spin_lock_irqsave(&s->lock, flags);
2694 s->midi.ird = ptr;
2695 s->midi.icnt -= cnt;
2696 spin_unlock_irqrestore(&s->lock, flags);
2697 count -= cnt;
2698 buffer += cnt;
2699 ret += cnt;
2700#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2701 break;
2702#endif
2703 }
2704#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2705 __set_current_state(TASK_RUNNING);
2706 remove_wait_queue(&s->midi.iwait, &wait);
2707#endif
2708 return ret;
2709}
2710
2711static ssize_t cm_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
2712{
2713 struct cm_state *s = (struct cm_state *)file->private_data;
2714#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2715 DECLARE_WAITQUEUE(wait, current);
2716#endif
2717 ssize_t ret;
2718 unsigned long flags;
2719 unsigned ptr;
2720 int cnt;
2721
2722 VALIDATE_STATE(s);
2723 if (ppos != &file->f_pos)
2724 return -ESPIPE;
2725 if (!access_ok(VERIFY_READ, buffer, count))
2726 return -EFAULT;
2727#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2728 if (count == 0)
2729 return 0;
2730#endif
2731 ret = 0;
2732#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2733 add_wait_queue(&s->midi.owait, &wait);
2734#endif
2735 while (count > 0) {
2736 spin_lock_irqsave(&s->lock, flags);
2737 ptr = s->midi.owr;
2738 cnt = MIDIOUTBUF - ptr;
2739 if (s->midi.ocnt + cnt > MIDIOUTBUF)
2740 cnt = MIDIOUTBUF - s->midi.ocnt;
2741 if (cnt <= 0)
2742 cm_handle_midi(s);
2743 spin_unlock_irqrestore(&s->lock, flags);
2744 if (cnt > count)
2745 cnt = count;
2746 if (cnt <= 0) {
2747 if (file->f_flags & O_NONBLOCK)
2748#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2749 {
2750 if (!ret)
2751 ret = -EAGAIN;
2752 break;
2753 }
2754 __set_current_state(TASK_INTERRUPTIBLE);
2755 schedule();
2756 if (signal_pending(current)) {
2757 if (!ret)
2758 ret = -ERESTARTSYS;
2759 break;
2760 }
2761#else
2762 return ret ? ret : -EAGAIN;
2763 interruptible_sleep_on(&s->midi.owait);
2764 if (signal_pending(current))
2765 return ret ? ret : -ERESTARTSYS;
2766#endif
2767 continue;
2768 }
2769 if (copy_from_user(s->midi.obuf + ptr, buffer, cnt))
2770#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2771 {
2772 if (!ret)
2773 ret = -EFAULT;
2774 break;
2775 }
2776#else
2777 return ret ? ret : -EFAULT;
2778#endif
2779 ptr = (ptr + cnt) % MIDIOUTBUF;
2780 spin_lock_irqsave(&s->lock, flags);
2781 s->midi.owr = ptr;
2782 s->midi.ocnt += cnt;
2783 spin_unlock_irqrestore(&s->lock, flags);
2784 count -= cnt;
2785 buffer += cnt;
2786 ret += cnt;
2787 spin_lock_irqsave(&s->lock, flags);
2788 cm_handle_midi(s);
2789 spin_unlock_irqrestore(&s->lock, flags);
2790 }
2791#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2792 __set_current_state(TASK_RUNNING);
2793 remove_wait_queue(&s->midi.owait, &wait);
2794#endif
2795 return ret;
2796}
2797
2798static unsigned int cm_midi_poll(struct file *file, struct poll_table_struct *wait)
2799{
2800 struct cm_state *s = (struct cm_state *)file->private_data;
2801 unsigned long flags;
2802 unsigned int mask = 0;
2803
2804 VALIDATE_STATE(s);
2805 if (file->f_mode & FMODE_WRITE)
2806 poll_wait(file, &s->midi.owait, wait);
2807 if (file->f_mode & FMODE_READ)
2808 poll_wait(file, &s->midi.iwait, wait);
2809 spin_lock_irqsave(&s->lock, flags);
2810 if (file->f_mode & FMODE_READ) {
2811 if (s->midi.icnt > 0)
2812 mask |= POLLIN | POLLRDNORM;
2813 }
2814 if (file->f_mode & FMODE_WRITE) {
2815 if (s->midi.ocnt < MIDIOUTBUF)
2816 mask |= POLLOUT | POLLWRNORM;
2817 }
2818 spin_unlock_irqrestore(&s->lock, flags);
2819 return mask;
2820}
2821
2822static int cm_midi_open(struct inode *inode, struct file *file)
2823{
2824 int minor = MINOR(inode->i_rdev);
2825 struct cm_state *s = devs;
2826 unsigned long flags;
2827
2828 while (s && s->dev_midi != minor)
2829 s = s->next;
2830 if (!s)
2831 return -ENODEV;
2832 VALIDATE_STATE(s);
2833 file->private_data = s;
2834 /* wait for device to become free */
2835 down(&s->open_sem);
2836 while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
2837 if (file->f_flags & O_NONBLOCK) {
2838 up(&s->open_sem);
2839 return -EBUSY;
2840 }
2841 up(&s->open_sem);
2842 interruptible_sleep_on(&s->open_wait);
2843 if (signal_pending(current))
2844 return -ERESTARTSYS;
2845 down(&s->open_sem);
2846 }
2847 spin_lock_irqsave(&s->lock, flags);
2848 if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
2849 s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
2850 s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
2851 /* enable MPU-401 */
2852 outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) | 4, s->iobase + CODEC_CMI_FUNCTRL1);
2853 outb(0xff, s->iomidi+1); /* reset command */
2854 if (!(inb(s->iomidi+1) & 0x80))
2855 inb(s->iomidi);
2856 outb(0x3f, s->iomidi+1); /* uart command */
2857 if (!(inb(s->iomidi+1) & 0x80))
2858 inb(s->iomidi);
2859 s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
2860 init_timer(&s->midi.timer);
2861 s->midi.timer.expires = jiffies+1;
2862 s->midi.timer.data = (unsigned long)s;
2863 s->midi.timer.function = cm_midi_timer;
2864 add_timer(&s->midi.timer);
2865 }
2866 if (file->f_mode & FMODE_READ) {
2867 s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
2868 }
2869 if (file->f_mode & FMODE_WRITE) {
2870 s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
2871 }
2872 spin_unlock_irqrestore(&s->lock, flags);
2873 s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
2874 up(&s->open_sem);
2875 MOD_INC_USE_COUNT;
2876 return 0;
2877}
2878
2879static int cm_midi_release(struct inode *inode, struct file *file)
2880{
2881 struct cm_state *s = (struct cm_state *)file->private_data;
2882#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2883 DECLARE_WAITQUEUE(wait, current);
2884#else
2885 struct wait_queue wait = { current, NULL };
2886#endif
2887 unsigned long flags;
2888 unsigned count, tmo;
2889
2890 VALIDATE_STATE(s);
2891
2892 if (file->f_mode & FMODE_WRITE) {
2893#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2894 __set_current_state(TASK_INTERRUPTIBLE);
2895#else
2896 current->state = TASK_INTERRUPTIBLE;
2897#endif
2898 add_wait_queue(&s->midi.owait, &wait);
2899 for (;;) {
2900 spin_lock_irqsave(&s->lock, flags);
2901 count = s->midi.ocnt;
2902 spin_unlock_irqrestore(&s->lock, flags);
2903 if (count <= 0)
2904 break;
2905 if (signal_pending(current))
2906 break;
2907 if (file->f_flags & O_NONBLOCK) {
2908 remove_wait_queue(&s->midi.owait, &wait);
2909#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2910 set_current_state(TASK_RUNNING);
2911#else
2912 current->state = TASK_RUNNING;
2913#endif
2914 return -EBUSY;
2915 }
2916 tmo = (count * HZ) / 3100;
2917 if (!schedule_timeout(tmo ? : 1) && tmo)
2918 printk(KERN_DEBUG "cm: midi timed out??\n");
2919 }
2920 remove_wait_queue(&s->midi.owait, &wait);
2921#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2922 set_current_state(TASK_RUNNING);
2923#else
2924 current->state = TASK_RUNNING;
2925#endif
2926 }
2927 down(&s->open_sem);
2928 s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE);
2929 spin_lock_irqsave(&s->lock, flags);
2930 if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
2931 del_timer(&s->midi.timer);
2932 outb(0xff, s->iomidi+1); /* reset command */
2933 if (!(inb(s->iomidi+1) & 0x80))
2934 inb(s->iomidi);
2935 /* disable MPU-401 */
2936 outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) & ~4, s->iobase + CODEC_CMI_FUNCTRL1);
2937 }
2938 spin_unlock_irqrestore(&s->lock, flags);
2939 up(&s->open_sem);
2940 wake_up(&s->open_wait);
2941 MOD_DEC_USE_COUNT;
2942 return 0;
2943}
2944
2945static /*const*/ struct file_operations cm_midi_fops = {
2946#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2947 llseek: cm_llseek,
2948 read: cm_midi_read,
2949 write: cm_midi_write,
2950 poll: cm_midi_poll,
2951 open: cm_midi_open,
2952 release: cm_midi_release,
2953#else
2954 &cm_llseek,
2955 &cm_midi_read,
2956 &cm_midi_write,
2957 NULL, /* readdir */
2958 &cm_midi_poll,
2959 NULL, /* ioctl */
2960 NULL, /* mmap */
2961 &cm_midi_open,
2962 NULL, /* flush */
2963 &cm_midi_release,
2964 NULL, /* fsync */
2965 NULL, /* fasync */
2966 NULL, /* check_media_change */
2967 NULL, /* revalidate */
2968 NULL, /* lock */
2969#endif
2970};
2971#endif
2972
2973/* --------------------------------------------------------------------- */
2974
2975#ifdef CONFIG_SOUND_CMPCI_FM
2976static int cm_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
2977{
2978 static const unsigned char op_offset[18] = {
2979 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
2980 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
2981 0x10, 0x11, 0x12, 0x13, 0x14, 0x15
2982 };
2983 struct cm_state *s = (struct cm_state *)file->private_data;
2984 struct dm_fm_voice v;
2985 struct dm_fm_note n;
2986 struct dm_fm_params p;
2987 unsigned int io;
2988 unsigned int regb;
2989
2990 switch (cmd) {
2991 case FM_IOCTL_RESET:
2992 for (regb = 0xb0; regb < 0xb9; regb++) {
2993 outb(regb, s->iosynth);
2994 outb(0, s->iosynth+1);
2995 outb(regb, s->iosynth+2);
2996 outb(0, s->iosynth+3);
2997 }
2998 return 0;
2999
3000 case FM_IOCTL_PLAY_NOTE:
3001 if (copy_from_user(&n, (void *)arg, sizeof(n)))
3002 return -EFAULT;
3003 if (n.voice >= 18)
3004 return -EINVAL;
3005 if (n.voice >= 9) {
3006 regb = n.voice - 9;
3007 io = s->iosynth+2;
3008 } else {
3009 regb = n.voice;
3010 io = s->iosynth;
3011 }
3012 outb(0xa0 + regb, io);
3013 outb(n.fnum & 0xff, io+1);
3014 outb(0xb0 + regb, io);
3015 outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1);
3016 return 0;
3017
3018 case FM_IOCTL_SET_VOICE:
3019 if (copy_from_user(&v, (void *)arg, sizeof(v)))
3020 return -EFAULT;
3021 if (v.voice >= 18)
3022 return -EINVAL;
3023 regb = op_offset[v.voice];
3024 io = s->iosynth + ((v.op & 1) << 1);
3025 outb(0x20 + regb, io);
3026 outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) |
3027 ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1);
3028 outb(0x40 + regb, io);
3029 outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1);
3030 outb(0x60 + regb, io);
3031 outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1);
3032 outb(0x80 + regb, io);
3033 outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1);
3034 outb(0xe0 + regb, io);
3035 outb(v.waveform & 0x7, io+1);
3036 if (n.voice >= 9) {
3037 regb = n.voice - 9;
3038 io = s->iosynth+2;
3039 } else {
3040 regb = n.voice;
3041 io = s->iosynth;
3042 }
3043 outb(0xc0 + regb, io);
3044 outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) |
3045 (v.connection & 1), io+1);
3046 return 0;
3047
3048 case FM_IOCTL_SET_PARAMS:
3049 if (copy_from_user(&p, (void *)arg, sizeof(p)))
3050 return -EFAULT;
3051 outb(0x08, s->iosynth);
3052 outb((p.kbd_split & 1) << 6, s->iosynth+1);
3053 outb(0xbd, s->iosynth);
3054 outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) |
3055 ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->iosynth+1);
3056 return 0;
3057
3058 case FM_IOCTL_SET_OPL:
3059 outb(4, s->iosynth+2);
3060 outb(arg, s->iosynth+3);
3061 return 0;
3062
3063 case FM_IOCTL_SET_MODE:
3064 outb(5, s->iosynth+2);
3065 outb(arg & 1, s->iosynth+3);
3066 return 0;
3067
3068 default:
3069 return -EINVAL;
3070 }
3071}
3072
3073static int cm_dmfm_open(struct inode *inode, struct file *file)
3074{
3075 int minor = MINOR(inode->i_rdev);
3076 struct cm_state *s = devs;
3077
3078 while (s && s->dev_dmfm != minor)
3079 s = s->next;
3080 if (!s)
3081 return -ENODEV;
3082 VALIDATE_STATE(s);
3083 file->private_data = s;
3084 /* wait for device to become free */
3085 down(&s->open_sem);
3086 while (s->open_mode & FMODE_DMFM) {
3087 if (file->f_flags & O_NONBLOCK) {
3088 up(&s->open_sem);
3089 return -EBUSY;
3090 }
3091 up(&s->open_sem);
3092 interruptible_sleep_on(&s->open_wait);
3093 if (signal_pending(current))
3094 return -ERESTARTSYS;
3095 down(&s->open_sem);
3096 }
3097 /* init the stuff */
3098 outb(1, s->iosynth);
3099 outb(0x20, s->iosynth+1); /* enable waveforms */
3100 outb(4, s->iosynth+2);
3101 outb(0, s->iosynth+3); /* no 4op enabled */
3102 outb(5, s->iosynth+2);
3103 outb(1, s->iosynth+3); /* enable OPL3 */
3104 s->open_mode |= FMODE_DMFM;
3105 up(&s->open_sem);
3106 MOD_INC_USE_COUNT;
3107 return 0;
3108}
3109
3110static int cm_dmfm_release(struct inode *inode, struct file *file)
3111{
3112 struct cm_state *s = (struct cm_state *)file->private_data;
3113 unsigned int regb;
3114
3115 VALIDATE_STATE(s);
3116 down(&s->open_sem);
3117 s->open_mode &= ~FMODE_DMFM;
3118 for (regb = 0xb0; regb < 0xb9; regb++) {
3119 outb(regb, s->iosynth);
3120 outb(0, s->iosynth+1);
3121 outb(regb, s->iosynth+2);
3122 outb(0, s->iosynth+3);
3123 }
3124 up(&s->open_sem);
3125 wake_up(&s->open_wait);
3126 MOD_DEC_USE_COUNT;
3127 return 0;
3128}
3129
3130static /*const*/ struct file_operations cm_dmfm_fops = {
3131#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3132 llseek: cm_llseek,
3133 ioctl: cm_dmfm_ioctl,
3134 open: cm_dmfm_open,
3135 release: cm_dmfm_release,
3136#else
3137 &cm_llseek,
3138 NULL, /* read */
3139 NULL, /* write */
3140 NULL, /* readdir */
3141 NULL, /* poll */
3142 &cm_dmfm_ioctl,
3143 NULL, /* mmap */
3144 &cm_dmfm_open,
3145 NULL, /* flush */
3146 &cm_dmfm_release,
3147 NULL, /* fsync */
3148 NULL, /* fasync */
3149 NULL, /* check_media_change */
3150 NULL, /* revalidate */
3151 NULL, /* lock */
3152#endif
3153};
3154#endif /* CONFIG_SOUND_CMPCI_FM */
3155
3156/* --------------------------------------------------------------------- */
3157
3158/* maximum number of devices */
3159#define NR_DEVICE 5
3160
3161#if 0
3162static int reverb[NR_DEVICE] = { 0, };
3163
3164static int wavetable[NR_DEVICE] = { 0, };
3165#endif
3166
3167/* --------------------------------------------------------------------- */
3168
3169static struct initvol {
3170 int mixch;
3171 int vol;
3172} initvol[] __initdata = {
3173 { SOUND_MIXER_WRITE_CD, 0x4040 },
3174 { SOUND_MIXER_WRITE_LINE, 0x4040 },
3175 { SOUND_MIXER_WRITE_MIC, 0x4040 },
3176 { SOUND_MIXER_WRITE_SYNTH, 0x4040 },
3177 { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
3178 { SOUND_MIXER_WRITE_PCM, 0x4040 }
3179};
3180
3181#ifdef CONFIG_SOUND_CMPCI_MIDI
3182static int mpu_io = CONFIG_SOUND_CMPCI_MPUIO;
3183#endif
3184#ifdef CONFIG_SOUND_CMPCI_FM
3185static int fm_io = CONFIG_SOUND_CMPCI_FMIO;
3186#endif
3187#ifdef CONFIG_SOUND_CMPCI_SPDIFLOOP
3188static int spdif_loop = 1;
3189#else
3190static int spdif_loop = 0;
3191#endif
3192#ifdef CONFIG_SOUND_CMPCI_4CH
3193static int four_ch = 1;
3194#else
3195static int four_ch = 0;
3196#endif
3197#ifdef CONFIG_SOUND_CMPCI_REAR
3198static int rear_out = 1;
3199#else
3200static int rear_out = 0;
3201#endif
3202#ifdef CONFIG_SOUND_CMPCI_PCTEL
3203static int modem = 1;
3204#else
3205static int modem = 0;
3206#endif
3207#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
3208static int joystick = 1;
3209#else
3210static int joystick = 0;
3211#endif
3212#ifdef MODULE
3213MODULE_PARM(mpu_io, "i");
3214MODULE_PARM(fm_io, "i");
3215MODULE_PARM(spdif_loop, "i");
3216MODULE_PARM(four_ch, "i");
3217MODULE_PARM(rear_out, "i");
3218MODULE_PARM(modem, "i");
3219MODULE_PARM(joystick, "i");
3220#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3221int __init init_module(void)
3222#else
3223__initfunc(int init_module(void))
3224#endif
3225#else
3226#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3227int __init init_cmpci(void)
3228#else
3229__initfunc(int init_cmpci(void))
3230#endif
3231#endif
3232{
3233 struct cm_state *s;
3234 struct pci_dev *pcidev = NULL;
3235 mm_segment_t fs;
3236 int i, val, index = 0;
3237#ifdef CONFIG_SOUND_CMPCI_MIDI
3238 unsigned char reg_mask = 0;
3239#endif
3240 struct {
3241 unsigned short deviceid;
3242 char *devicename;
3243 } devicetable[] =
3244 {
3245 { PCI_DEVICE_ID_CMEDIA_CM8338A, "CM8338A" },
3246 { PCI_DEVICE_ID_CMEDIA_CM8338B, "CM8338B" },
3247 { PCI_DEVICE_ID_CMEDIA_CM8738, "CM8738" },
3248 { PCI_DEVICE_ID_CMEDIA_CM8738B, "CM8738B" },
3249 };
3250 char *devicename = "unknown";
3251
3252#ifdef CONFIG_PCI
3253 if (!pci_present()) /* No PCI bus in this machine! */
3254#endif
3255 return -ENODEV;
3256 printk(KERN_INFO "cm: version $Revision: 4.3 $ time " __TIME__ " " __DATE__ "\n");
3257#if 0
3258 if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
3259 printk(KERN_INFO "cm: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
3260#endif
3261 while (index < NR_DEVICE && pcidev == NULL && (
3262 (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, pcidev)) ||
3263 (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, pcidev)) ||
3264 (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, pcidev)))) {
3265 if (pcidev->irq == 0)
3266 continue;
3267 if (!(s = kmalloc(sizeof(struct cm_state), GFP_KERNEL))) {
3268 printk(KERN_WARNING "cm: out of memory\n");
3269 continue;
3270 }
3271 /* search device name */
3272 for (i = 0; i < sizeof(devicetable) / sizeof(devicetable[0]); i++)
3273 {
3274 if (devicetable[i].deviceid == pcidev->device)
3275 {
3276 devicename = devicetable[i].devicename;
3277 break;
3278 }
3279 }
3280 memset(s, 0, sizeof(struct cm_state));
3281#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3282 init_waitqueue_head(&s->dma_adc.wait);
3283 init_waitqueue_head(&s->dma_dac.wait);
3284 init_waitqueue_head(&s->open_wait);
3285 init_waitqueue_head(&s->midi.iwait);
3286 init_waitqueue_head(&s->midi.owait);
3287 init_MUTEX(&s->open_sem);
3288#else
3289 init_waitqueue(&s->dma_adc.wait);
3290 init_waitqueue(&s->dma_dac.wait);
3291 init_waitqueue(&s->open_wait);
3292 init_waitqueue(&s->midi.iwait);
3293 init_waitqueue(&s->midi.owait);
3294 s->open_sem = MUTEX;
3295#endif
3296 spin_lock_init(&s->lock);
3297 s->magic = CM_MAGIC;
3298#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3299 s->iobase = pcidev->resource[0].start;
3300#else
3301 s->iobase = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
3302#endif
3303#ifdef CONFIG_SOUND_CMPCI_FM
3304 s->iosynth = fm_io;
3305#endif
3306#ifdef CONFIG_SOUND_CMPCI_MIDI
3307 s->iomidi = mpu_io;
3308#endif
3309#ifdef DUAL_DAC
3310 s->dual_mode = 0;
3311 s->hw_dual_dac = (pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738B);
3312#endif
3313 s->four_ch = four_ch;
3314 if (s->iobase == 0)
3315 continue;
3316 s->irq = pcidev->irq;
3317
3318 if (check_region(s->iobase, CM_EXTENT_CODEC)) {
3319 printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
3320 goto err_region5;
3321 }
3322 request_region(s->iobase, CM_EXTENT_CODEC, "cmpci");
3323#ifdef CONFIG_SOUND_CMPCI_MIDI
3324 if (s->iomidi)
3325 {
3326 if (check_region(s->iomidi, CM_EXTENT_MIDI)) {
3327 printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
3328 goto err_region4;
3329 }
3330 request_region(s->iomidi, CM_EXTENT_MIDI, "cmpci Midi");
3331 /* set IO based at 0x330 */
3332 switch (s->iomidi)
3333 {
3334 case 0x330:
3335 reg_mask = 0;
3336 break;
3337 case 0x320:
3338 reg_mask = 0x20;
3339 break;
3340 case 0x310:
3341 reg_mask = 0x40;
3342 break;
3343 case 0x300:
3344 reg_mask = 0x60;
3345 break;
3346 }
3347 outb((inb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3) & ~0x60) | reg_mask, s->iobase + CODEC_CMI_LEGACY_CTRL + 3);
3348 }
3349#endif
3350#ifdef CONFIG_SOUND_CMPCI_FM
3351 if (s->iosynth)
3352 {
3353 if (check_region(s->iosynth, CM_EXTENT_SYNTH)) {
3354 printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
3355 goto err_region1;
3356 }
3357 request_region(s->iosynth, CM_EXTENT_SYNTH, "cmpci FM");
3358 /* enable FM */
3359 outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 2) | 8, s->iobase + CODEC_CMI_MISC_CTRL);
3360 }
3361#endif
3362 /* initialize codec registers */
3363 outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2); /* disable ints */
3364 outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
3365 /* reset mixer */
3366 wrmixer(s, DSP_MIX_DATARESETIDX, 0);
3367
3368 /* request irq */
3369 if (request_irq(s->irq, cm_interrupt, SA_SHIRQ, "cmpci", s)) {
3370 printk(KERN_ERR "cm: irq %u in use\n", s->irq);
3371 goto err_irq;
3372 }
3373 printk(KERN_INFO "cm: found %s adapter at io %#06x irq %u\n",
3374 devicename, s->iobase, s->irq);
3375 /* register devices */
3376 if ((s->dev_audio = register_sound_dsp(&cm_audio_fops, -1)) < 0)
3377 goto err_dev1;
3378 if ((s->dev_mixer = register_sound_mixer(&cm_mixer_fops, -1)) < 0)
3379 goto err_dev2;
3380#ifdef CONFIG_SOUND_CMPCI_MIDI
3381 if ((s->dev_midi = register_sound_midi(&cm_midi_fops, -1)) < 0)
3382 goto err_dev3;
3383#endif
3384#ifdef CONFIG_SOUND_CMPCI_FM
3385 if ((s->dev_dmfm = register_sound_special(&cm_dmfm_fops, 15 /* ?? */)) < 0)
3386 goto err_dev4;
3387#endif
3388#ifdef DUAL_DAC
3389 if ((s->dev_dsp = register_sound_special(&cm_dsp_fops, 14)) < 0)
3390 goto err_dev5;
3391#endif
3392 pci_set_master(pcidev); /* enable bus mastering */
3393 /* initialize the chips */
3394 fs = get_fs();
3395 set_fs(KERNEL_DS);
3396 /* set mixer output */
3397 frobindir(s, DSP_MIX_OUTMIXIDX, 0x1f, 0x1f);
3398 /* set mixer input */
3399 val = SOUND_MASK_LINE|SOUND_MASK_SYNTH|SOUND_MASK_CD|SOUND_MASK_MIC;
3400 mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
3401 for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
3402 val = initvol[i].vol;
3403 mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
3404 }
3405#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
3406 set_fs(fs);
3407#endif
3408 if (pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738)
3409 {
3410 s->modem = modem;
3411 if (modem)
3412 {
3413 /* enable FLINKON and disable FLINKOFF */
3414 outb(inb((s->iobase + CODEC_CMI_MISC_CTRL) | 0x80) & ~0x40, s->iobase + CODEC_CMI_MISC_CTRL);
3415 printk(KERN_INFO "cm: modem function supported\n");
3416 }
3417 /* enable SPDIF loop */
3418 if (spdif_loop)
3419 {
3420 /* turn on spdif-in to spdif-out */
3421 outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) | 0x80, s->iobase + CODEC_CMI_FUNCTRL1);
3422 printk(KERN_INFO "cm: Enable SPDIF loop\n");
3423 }
3424 else
3425 outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) & ~0x80, s->iobase + CODEC_CMI_FUNCTRL1);
3426 /* enable 4 channels mode */
3427 if (four_ch)
3428 {
3429 /* 4 channel mode (analog duplicate) */
3430 outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 3) | 0x04, s->iobase + CODEC_CMI_MISC_CTRL + 3);
3431 printk(KERN_INFO "cm: Enable 4 channels mode\n");
3432 /* has separate rear-out jack ? */
3433 if (rear_out)
3434 {
3435 /* has separate rear out jack */
3436 outb(inb(s->iobase + CODEC_CMI_MIXER1) & ~0x20, s->iobase + CODEC_CMI_MIXER1);
3437 }
3438 else
3439 {
3440 outb(inb(s->iobase + CODEC_CMI_MIXER1) | 0x20, s->iobase + CODEC_CMI_MIXER1);
3441 printk(KERN_INFO "cm: line-in routed as rear-out\n");
3442 }
3443 }
3444 else
3445 outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 3) & ~0x04, s->iobase + CODEC_CMI_MISC_CTRL + 3);
3446 }
3447 /* enable joystick */
3448 if (joystick)
3449 outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) | 0x02, s->iobase + CODEC_CMI_FUNCTRL1);
3450 else
3451 outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) & ~0x02, s->iobase + CODEC_CMI_FUNCTRL1);
3452#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
3453 set_fs(fs);
3454#endif
3455 /* queue it for later freeing */
3456 s->next = devs;
3457 devs = s;
3458 index++;
3459 continue;
3460
3461#ifdef DUAL_DAC
3462 err_dev5:
3463#endif
3464#ifdef CONFIG_SOUND_CMPCI_FM
3465 unregister_sound_special(s->dev_dmfm);
3466 err_dev4:
3467#endif
3468#ifdef CONFIG_SOUND_CMPCI_MIDI
3469 unregister_sound_midi(s->dev_midi);
3470 err_dev3:
3471#endif
3472 unregister_sound_mixer(s->dev_mixer);
3473 err_dev2:
3474 unregister_sound_dsp(s->dev_audio);
3475 err_dev1:
3476 printk(KERN_ERR "cm: cannot register misc device\n");
3477 free_irq(s->irq, s);
3478 err_irq:
3479#ifdef CONFIG_SOUND_CMPCI_FM
3480 if (s->iosynth) release_region(s->iosynth, CM_EXTENT_SYNTH);
3481 err_region1:
3482#endif
3483#ifdef CONFIG_SOUND_CMPCI_MIDI
3484 if (s->iomidi) release_region(s->iomidi, CM_EXTENT_MIDI);
3485 err_region4:
3486#endif
3487 release_region(s->iobase, CM_EXTENT_CODEC);
3488 err_region5:
3489 kfree_s(s, sizeof(struct cm_state));
3490 }
3491 if (!devs) {
3492 if (wavetable_mem)
3493 free_pages(wavetable_mem, 20-PAGE_SHIFT);
3494 return -ENODEV;
3495 }
3496 return 0;
3497}
3498
3499/* --------------------------------------------------------------------- */
3500
3501#ifdef MODULE
3502
3503#if 0
3504MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i");
3505MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled");
3506#endif
3507
3508MODULE_AUTHOR("ChenLi Tien, cltien@home.com");
3509MODULE_DESCRIPTION("CMPCI Audio Driver");
3510
3511void cleanup_module(void)
3512{
3513 struct cm_state *s;
3514
3515 while ((s = devs)) {
3516 devs = devs->next;
3517 outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2); /* disable ints */
3518 synchronize_irq();
3519 outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
3520 free_irq(s->irq, s);
3521#ifdef FIXEDDMA
3522 dealloc_dmabuf(&s->dma_dac);
3523 dealloc_dmabuf(&s->dma_adc);
3524#endif
3525
3526 /* reset mixer */
3527 wrmixer(s, DSP_MIX_DATARESETIDX, 0);
3528
3529 release_region(s->iobase, CM_EXTENT_CODEC);
3530#ifdef CONFIG_SOUND_CMPCI_MIDI
3531 if (s->iomidi) release_region(s->iomidi, CM_EXTENT_MIDI);
3532#endif
3533#ifdef CONFIG_SOUND_CMPCI_FM
3534 if (s->iosynth) release_region(s->iosynth, CM_EXTENT_SYNTH);
3535#endif
3536 unregister_sound_dsp(s->dev_audio);
3537 unregister_sound_mixer(s->dev_mixer);
3538#ifdef CONFIG_SOUND_CMPCI_MIDI
3539 unregister_sound_midi(s->dev_midi);
3540#endif
3541#ifdef CONFIG_SOUND_CMPCI_FM
3542 unregister_sound_special(s->dev_dmfm);
3543#endif
3544#ifdef DUAL_DAC
3545 unregister_sound_special(s->dev_dsp);
3546#endif
3547 kfree_s(s, sizeof(struct cm_state));
3548 }
3549 if (wavetable_mem)
3550 free_pages(wavetable_mem, 20-PAGE_SHIFT);
3551 printk(KERN_INFO "cm: unloading\n");
3552}
3553
3554#endif /* MODULE */
Note: See TracBrowser for help on using the repository browser.