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