source: cmedia/trunk/Cmpci/cmpci.c@ 354

Last change on this file since 354 was 354, checked in by stevenhl, 17 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: 126.2 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 * Based on the PCI drivers by Thomas Sailer (sailer@ife.ee.ethz.ch)
10 *
11 * For update, visit:
12 * http://members.home.net/puresoft/cmedia.html
13 * http://www.cmedia.com.tw
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 * Special thanks to David C. Niemi, Jan Pfeifer
30 *
31 *
32 * Module command line parameters:
33 * none so far
34 *
35 *
36 * Supported devices:
37 * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible
38 * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible
39 * /dev/midi simple MIDI UART interface, no ioctl
40 *
41 * The card has both an FM and a Wavetable synth, but I have to figure
42 * out first how to drive them...
43 *
44 * Revision history
45 * 06.05.98 0.1 Initial release
46 * 10.05.98 0.2 Fixed many bugs, esp. ADC rate calculation
47 * First stab at a simple midi interface (no bells&whistles)
48 * 13.05.98 0.3 Fix stupid cut&paste error: set_adc_rate was called instead of
49 * set_dac_rate in the FMODE_WRITE case in cm_open
50 * Fix hwptr out of bounds (now mpg123 works)
51 * 14.05.98 0.4 Don't allow excessive interrupt rates
52 * 08.06.98 0.5 First release using Alan Cox' soundcore instead of miscdevice
53 * 03.08.98 0.6 Do not include modversions.h
54 * Now mixer behaviour can basically be selected between
55 * "OSS documented" and "OSS actual" behaviour
56 * 31.08.98 0.7 Fix realplayer problems - dac.count issues
57 * 10.12.98 0.8 Fix drain_dac trying to wait on not yet initialized DMA
58 * 16.12.98 0.9 Fix a few f_file & FMODE_ bugs
59 * 06.01.99 0.10 remove the silly SA_INTERRUPT flag.
60 * hopefully killed the egcs section type conflict
61 * 12.03.99 0.11 cinfo.blocks should be reset after GETxPTR ioctl.
62 * reported by Johan Maes <joma@telindus.be>
63 * 22.03.99 0.12 return EAGAIN instead of EBUSY when O_NONBLOCK
64 * read/write cannot be executed
65 * 18.08.99 1.5 Only deallocate DMA buffer when unloading.
66 * 02.09.99 1.6 Enable SPDIF LOOP
67 * Change the mixer read back
68 * 21.09.99 2.33 Use RCS version as driver version.
69 * Add support for modem, S/PDIF loop and 4 channels.
70 * (8738 only)
71 * Fix bug cause x11amp cannot play.
72 *
73 */
74
75/*****************************************************************************/
76
77#define EXPORT_SYMTAB
78#include <linux/version.h>
79#ifndef TARGET_OS2
80 #include <linux/config.h>
81#endif
82#include <linux/kernel.h>
83#include <linux/types.h>
84#include <linux/list.h>
85#include <linux/module.h>
86#ifndef TARGET_OS2
87 #include <linux/string.h>
88#endif
89#include <linux/ioport.h>
90#include <linux/sched.h>
91#include <linux/delay.h>
92#include <linux/sound.h>
93#include <linux/malloc.h>
94#include <linux/soundcard.h>
95#include <linux/pci.h>
96#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
97 #include <linux/wrapper.h>
98#endif
99#include <asm/io.h>
100#include <asm/dma.h>
101#include <linux/init.h>
102#include <linux/poll.h>
103
104#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
105 #include <linux/spinlock.h>
106
107 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
108 #include <linux/smp_lock.h>
109 #endif
110
111 #ifdef TARGET_OS2
112 #include <linux/delay.h>
113 #include "cmpcios2.h"
114 #endif
115
116#else
117 #include <asm/spinlock.h>
118 #define AFMT_AC3 0x00000400 /* Dolby Digital AC3 */
119 #define DSP_CAP_BIND 0x00008000 /* channel binding to front/rear/cneter/lfe */
120 #define SNDCTL_DSP_GETCHANNELMASK _SIOWR('P', 64, int)
121 #define SNDCTL_DSP_BIND_CHANNEL _SIOWR('P', 65, int)
122 #define DSP_BIND_QUERY 0x00000000
123 #define DSP_BIND_FRONT 0x00000001
124 #define DSP_BIND_SURR 0x00000002
125 #define DSP_BIND_CENTER_LFE 0x00000004
126 #define DSP_BIND_HANDSET 0x00000008
127 #define DSP_BIND_MIC 0x00000010
128 #define DSP_BIND_MODEM1 0x00000020
129 #define DSP_BIND_MODEM2 0x00000040
130 #define DSP_BIND_I2S 0x00000080
131 #define DSP_BIND_SPDIF 0x00000100
132
133#endif
134
135#include <asm/uaccess.h>
136#include <asm/hardirq.h>
137
138
139// Rudi: allow multiple open requests on OS/2
140#ifdef TARGET_OS2
141 #define AUDIO_DEV_PTR(a) (*(struct cm_state **)(a))
142#else
143 #define AUDIO_DEV_PTR(a) ((struct cm_state *)(a))
144 #include "dm.h"
145#endif
146
147
148/* --------------------------------------------------------------------- */
149
150#undef OSS_DOCUMENTED_MIXER_SEMANTICS
151
152/* --------------------------------------------------------------------- */
153
154#ifndef PCI_VENDOR_ID_CMEDIA
155#define PCI_VENDOR_ID_CMEDIA 0x13F6
156#endif
157#ifndef PCI_DEVICE_ID_CMEDIA_CM8338A
158#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100
159#endif
160#ifndef PCI_DEVICE_ID_CMEDIA_CM8338B
161#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101
162#endif
163#ifndef PCI_DEVICE_ID_CMEDIA_CM8738
164#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
165#endif
166#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B
167#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
168#endif
169
170#define CM_MAGIC ((PCI_VENDOR_ID_CMEDIA<<16)|PCI_DEVICE_ID_CMEDIA_CM8338A)
171
172/*
173 * CM8338 registers definition
174 */
175
176#define CODEC_CMI_FUNCTRL0 (0x00)
177#define CODEC_CMI_FUNCTRL1 (0x04)
178#define CODEC_CMI_CHFORMAT (0x08)
179#define CODEC_CMI_INT_HLDCLR (0x0C)
180#define CODEC_CMI_INT_STATUS (0x10)
181#define CODEC_CMI_LEGACY_CTRL (0x14)
182#define CODEC_CMI_MISC_CTRL (0x18)
183#define CODEC_CMI_TDMA_POS (0x1C)
184#define CODEC_CMI_MIXER (0x20)
185#define CODEC_SB16_DATA (0x22)
186#define CODEC_SB16_ADDR (0x23)
187#define CODEC_CMI_MIXER1 (0x24)
188#define CODEC_CMI_MIXER2 (0x25)
189#define CODEC_CMI_AUX_VOL (0x26)
190#define CODEC_CMI_MISC (0x27)
191#define CODEC_CMI_AC97 (0x28)
192
193#define CODEC_CMI_CH0_FRAME1 (0x80)
194#define CODEC_CMI_CH0_FRAME2 (0x84)
195#define CODEC_CMI_CH1_FRAME1 (0x88)
196#define CODEC_CMI_CH1_FRAME2 (0x8C)
197
198#define CODEC_CMI_EXT_REG (0xF0) // ???
199
200
201/*
202** Mixer registers for SB16
203*/
204
205#define UCHAR unsigned char
206
207#define DSP_MIX_DATARESETIDX ((UCHAR)(0x00))
208
209#define DSP_MIX_MASTERVOLIDX_L ((UCHAR)(0x30))
210#define DSP_MIX_MASTERVOLIDX_R ((UCHAR)(0x31))
211#define DSP_MIX_VOICEVOLIDX_L ((UCHAR)(0x32))
212#define DSP_MIX_VOICEVOLIDX_R ((UCHAR)(0x33))
213#define DSP_MIX_FMVOLIDX_L ((UCHAR)(0x34))
214#define DSP_MIX_FMVOLIDX_R ((UCHAR)(0x35))
215#define DSP_MIX_CDVOLIDX_L ((UCHAR)(0x36))
216#define DSP_MIX_CDVOLIDX_R ((UCHAR)(0x37))
217#define DSP_MIX_LINEVOLIDX_L ((UCHAR)(0x38))
218#define DSP_MIX_LINEVOLIDX_R ((UCHAR)(0x39))
219
220#define DSP_MIX_MICVOLIDX ((UCHAR)(0x3A))
221#define DSP_MIX_SPKRVOLIDX ((UCHAR)(0x3B))
222
223#define DSP_MIX_OUTMIXIDX ((UCHAR)(0x3C))
224
225#define DSP_MIX_ADCMIXIDX_L ((UCHAR)(0x3D))
226#define DSP_MIX_ADCMIXIDX_R ((UCHAR)(0x3E))
227
228#define DSP_MIX_INGAINIDX_L ((UCHAR)(0x3F)) // not present
229#define DSP_MIX_INGAINIDX_R ((UCHAR)(0x40)) // not present
230#define DSP_MIX_OUTGAINIDX_L ((UCHAR)(0x41)) // not present
231#define DSP_MIX_OUTGAINIDX_R ((UCHAR)(0x42)) // not present
232
233#define DSP_MIX_AGCIDX ((UCHAR)(0x43)) // not present
234
235#define DSP_MIX_TREBLEIDX_L ((UCHAR)(0x44)) // not present
236#define DSP_MIX_TREBLEIDX_R ((UCHAR)(0x45)) // not present
237#define DSP_MIX_BASSIDX_L ((UCHAR)(0x46)) // not present
238#define DSP_MIX_BASSIDX_R ((UCHAR)(0x47)) // not present
239
240#define DSP_MIX_EXTENSIONIDX ((UCHAR)(0xf0))
241
242
243#define CM_RESET_CH0 0x04
244#define CM_RESET_CH1 0x08
245
246#define CM_EXTENT_CODEC 0x100
247#define CM_EXTENT_MIDI 0x2
248#define CM_EXTENT_SYNTH 0x4
249
250#define CM_INT_CH0 0x1
251#define CM_INT_CH1 0x2
252
253#define CM_INTR 0x80000000
254#define CM_UARTINT 0x00010000
255#define CM_LTDMAINT 0x00008000
256#define CM_HTDMAINT 0x00004000
257#define CM_CH1BUSY 0x00000008
258#define CM_CH0BUSY 0x00000004
259#define CM_CHINT1 0x00000002
260#define CM_CHINT0 0x00000001
261
262
263#define CM_CFMT_STEREO 0x01
264#define CM_CFMT_16BIT 0x02
265#define CM_CFMT_MASK 0x03
266#define CM_CFMT_SHIFT_CH0 0
267#define CM_CFMT_SHIFT_CH1 2
268
269static const unsigned sample_size[] = { 1, 2, 2, 4 };
270static const unsigned sample_shift[] = { 0, 1, 1, 2 };
271static const unsigned sample_mask[] = { ~0, ~1, ~1, ~3 };
272
273#define CM_ENABLE_CH0 0x1
274#define CM_ENABLE_CH1 0x2
275#define CM_PAUSE_CH0 0x4
276#define CM_PAUSE_CH1 0x8
277
278
279
280/* MIDI buffer sizes */
281
282#define MIDIINBUF 256
283#define MIDIOUTBUF 256
284
285#define FMODE_MIDI_SHIFT 2
286#define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT)
287#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
288
289#define FMODE_DMFM 0x10
290
291#define SND_DEV_DSP16 5
292
293#define set_dac1_rate set_adc_rate
294#define stop_dac1 stop_adc
295#define get_dmadac1 get_dmaadc
296
297
298// hardware multichannel seems to work exclusively on channel B
299#define FORCE_DUAL_DAC
300
301
302/* --------------------------------------------------------------------- */
303
304struct cm_state {
305 /* magic */
306 unsigned int magic;
307
308 /* we keep cm cards in a linked list */
309 struct cm_state *next;
310
311 /* soundcore stuff */
312 int dev_audio;
313 int dev_mixer;
314 int dev_midi;
315 int dev_dmfm;
316
317 /* hardware resources */
318 unsigned int iosb, iobase, iosynth, iomidi, iogame, irq;
319 unsigned short deviceid;
320
321 /* mixer stuff */
322 struct {
323 unsigned int modcnt;
324#ifndef OSS_DOCUMENTED_MIXER_SEMANTICS
325//Rudi: unsigned short vol[13];
326 unsigned short vol[SOUND_MIXER_NRDEVICES];
327#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
328 } mix;
329
330 /* wave stuff */
331 unsigned int rateadc, ratedac;
332 unsigned char fmt, enable;
333
334 spinlock_t lock;
335 struct semaphore open_sem;
336 mode_t open_mode;
337#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
338 wait_queue_head_t open_wait;
339#else
340 struct wait_queue *open_wait;
341#endif
342
343 struct dmabuf {
344 void *rawbuf;
345 unsigned rawphys;
346 unsigned buforder;
347 unsigned numfrag;
348 unsigned fragshift;
349 unsigned hwptr, swptr;
350 unsigned total_bytes;
351 int count;
352 unsigned error; /* over/underrun */
353#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
354 wait_queue_head_t wait;
355#else
356 struct wait_queue *wait;
357#endif
358 /* redundant, but makes calculations easier */
359 unsigned fragsize;
360 unsigned dmasize;
361 unsigned fragsamples;
362 unsigned dmasamples;
363 /* OSS stuff */
364 unsigned mapped:1;
365 unsigned ready:1;
366 unsigned endcleared:1;
367 unsigned ossfragshift;
368 int ossmaxfrags;
369 unsigned subdivision;
370 } dma_dac, dma_adc;
371
372 /* midi stuff */
373 struct {
374 unsigned ird, iwr, icnt;
375 unsigned ord, owr, ocnt;
376#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
377 wait_queue_head_t iwait;
378 wait_queue_head_t owait;
379#else
380 struct wait_queue *iwait;
381 struct wait_queue *owait;
382#endif
383#ifdef CONFIG_SOUND_CMPCI_MIDI
384 struct timer_list timer;
385#endif
386 unsigned char ibuf[MIDIINBUF];
387 unsigned char obuf[MIDIOUTBUF];
388 } midi;
389
390 /* misc stuff */
391 int modem;
392 int chip_version;
393 int max_channels;
394 int curr_channels;
395 int speakers; // number of speakers
396 int capability; // HW capability, various for chip versions
397 int status; // HW or SW state
398
399 /* spdif frame counter */
400 int spdif_counter;
401
402#ifdef TARGET_OS2
403 int audio_open_count[2]; // [0]: read, [1]: write
404 void *curr_streamid[2]; // [0]: read, [1]: write
405#endif
406};
407
408/* flags used for capability */
409#define CAN_AC3_HW 0x00000001 // 037 or later
410#define CAN_AC3_SW 0x00000002 // 033 or later
411#define CAN_AC3 (CAN_AC3_HW | CAN_AC3_SW)
412#define CAN_DUAL_DAC 0x00000004 // 033 or later
413#define CAN_MULTI_CH_HW 0x00000008 // 039 or later
414#define CAN_MULTI_CH (CAN_MULTI_CH_HW | CAN_DUAL_DAC)
415#define CAN_LINE_AS_REAR 0x00000010 // 033 or later
416#define CAN_LINE_AS_BASS 0x00000020 // 039 or later
417#define CAN_MIC_AS_BASS 0x00000040 // 039 or later
418
419/* flags used for status */
420#define DO_AC3_HW 0x00000001
421#define DO_AC3_SW 0x00000002
422#define DO_AC3 (DO_AC3_HW | DO_AC3_SW)
423#define DO_DUAL_DAC 0x00000004
424#define DO_MULTI_CH_HW 0x00000008
425#define DO_MULTI_CH (DO_MULTI_CH_HW | DO_DUAL_DAC)
426#define DO_LINE_AS_REAR 0x00000010 // 033 or later
427#define DO_LINE_AS_BASS 0x00000020 // 039 or later
428#define DO_MIC_AS_BASS 0x00000040 // 039 or later
429#define DO_SPDIF_OUT 0x00000100
430#define DO_SPDIF_IN 0x00000200
431#define DO_SPDIF_LOOP 0x00000400
432
433/* Rudi's additional status info */
434#define DO_SPDIF_MONITOR 0x00010000
435#define DO_SPDIF_COPYRIGHT 0x00020000
436#define DO_SPDIF_OUT_5V 0x00040000
437#define DO_SPDIF_INPUT2 0x00080000
438#define DO_SPDIF_INVERSE 0x00100000
439#define DO_SPDIF_OUT_ENABLE 0x00200000
440#define DO_POWER_DOWN 0x00400000
441#define DO_MIC_BOOST 0x00800000
442
443
444/* --------------------------------------------------------------------- */
445
446static struct cm_state *devs = NULL;
447static struct cm_state *devaudio = NULL;
448
449#if CONFIG_WAVETABLE
450static unsigned long wavetable_mem = 0;
451#endif
452
453int prog_dmabuf(struct cm_state *s, unsigned rec);
454void update_mixer(struct cm_state *s);
455
456
457/* --------------------------------------------------------------------- */
458
459#ifndef TARGET_OS2
460 extern __inline__ unsigned ld2(unsigned int x)
461 {
462 unsigned r = 0;
463 if (x >= 0x10000) {
464 x >>= 16;
465 r += 16;
466 }
467 if (x >= 0x100) {
468 x >>= 8;
469 r += 8;
470 }
471 if (x >= 0x10) {
472 x >>= 4;
473 r += 4;
474 }
475 if (x >= 4) {
476 x >>= 2;
477 r += 2;
478 }
479 if (x >= 2)
480 r++;
481 return r;
482 }
483
484
485 /*
486 * hweightN: returns the hamming weight (i.e. the number
487 * of bits set) of a N-bit word
488 */
489
490 #ifdef hweight32
491 #undef hweight32
492 #endif
493
494 extern __inline__ unsigned int hweight32(unsigned int w)
495 {
496 unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
497 res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
498 res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
499 res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
500 return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
501 }
502
503 /* --------------------------------------------------------------------- */
504
505 /*
506 * Why use byte IO? Nobody knows, but S3 does it also in their Windows driver.
507 */
508
509 #undef DMABYTEIO
510
511 extern __inline__ void maskb(unsigned int addr, unsigned int mask, unsigned int value)
512 {
513 outb((inb(addr) & mask) | value, addr);
514 }
515
516 extern __inline__ void maskw(unsigned int addr, unsigned int mask, unsigned int value)
517 {
518 outw((inw(addr) & mask) | value, addr);
519 }
520
521 extern __inline__ void maskl(unsigned int addr, unsigned int mask, unsigned int value)
522 {
523 outl((inl(addr) & mask) | value, addr);
524 }
525
526#else
527 unsigned ld2(unsigned x);
528 #pragma aux ld2 = \
529 "xor ecx, ecx" \
530 "bsr ecx, eax" \
531 parm nomemory [eax] \
532 modify exact nomemory [ecx] \
533 value [ecx];
534
535 void maskb(unsigned short addr, unsigned char mask, unsigned char value);
536 #pragma aux maskb = \
537 "in al, dx" \
538 "and al, cl" \
539 "or al, ch" \
540 "out dx, al" \
541 parm nomemory [dx] [cl] [ch] \
542 modify exact nomemory [al];
543
544 void maskw(unsigned short addr, unsigned mask, unsigned value);
545 #pragma aux maskw = \
546 "in ax, dx" \
547 "and eax, ecx" \
548 "or eax, ebx" \
549 "out dx, ax" \
550 parm nomemory [edx] [ecx] [ebx] \
551 modify exact nomemory [eax];
552
553 void maskl(unsigned short addr, unsigned long mask, unsigned long value);
554 #pragma aux maskl = \
555 "in eax, dx" \
556 "and eax, ecx" \
557 "or eax, ebx" \
558 "out dx, eax" \
559 parm nomemory [edx] [ecx] [ebx] \
560 modify exact nomemory [eax];
561
562 unsigned char parity(unsigned value, unsigned mask);
563 #pragma aux parity = \
564 "test eax, ecx" \
565 "setpo cl" \
566 parm nomemory [eax] [ecx] \
567 modify exact nomemory [ecx] \
568 value [cl];
569
570#endif
571
572
573extern __inline__ void set_dmadac1(struct cm_state *s, unsigned int addr, unsigned int count)
574{
575 if (addr) outl(addr, s->iobase + CODEC_CMI_CH1_FRAME1);
576 outw(count - 1, s->iobase + CODEC_CMI_CH1_FRAME2);
577 maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~2, 0); // CH1 = play
578}
579
580extern __inline__ void set_dmaadc(struct cm_state *s, unsigned int addr, unsigned int count)
581{
582 outl(addr, s->iobase + CODEC_CMI_CH1_FRAME1);
583 outw(count - 1, s->iobase + CODEC_CMI_CH1_FRAME2);
584 maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, 2); // CH1 = rec
585}
586
587extern __inline__ void set_dmadac(struct cm_state *s, unsigned int addr, unsigned int count)
588{
589 outl(addr, s->iobase + CODEC_CMI_CH0_FRAME1);
590 outw(count - 1, s->iobase + CODEC_CMI_CH0_FRAME2);
591 maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~1, 0); // CH0 = play
592 if (s->status & DO_DUAL_DAC) set_dmadac1(s, 0, count);
593}
594
595extern __inline__ void set_countadc(struct cm_state *s, unsigned count)
596{
597 outw(count - 1, s->iobase + CODEC_CMI_CH1_FRAME2 + 2);
598}
599
600extern __inline__ void set_countdac(struct cm_state *s, unsigned count)
601{
602 outw(count - 1, s->iobase + CODEC_CMI_CH0_FRAME2 + 2);
603 if (s->status & DO_DUAL_DAC) set_countadc(s, count);
604}
605
606extern __inline__ unsigned get_dmadac(struct cm_state *s)
607{
608 unsigned int curr_addr, last_addr;
609
610 curr_addr = inw(s->iobase + CODEC_CMI_CH0_FRAME2);
611 last_addr = ~curr_addr;
612 while( curr_addr != last_addr ) {
613 iodelay32(1);
614 last_addr = curr_addr;
615 curr_addr = inw(s->iobase + CODEC_CMI_CH0_FRAME2);
616 }
617
618 curr_addr = (curr_addr + 1) <<
619 sample_shift[(s->fmt >> CM_CFMT_SHIFT_CH0) & CM_CFMT_MASK];
620 return s->dma_dac.dmasize - curr_addr;
621}
622
623extern __inline__ unsigned get_dmaadc(struct cm_state *s)
624{
625 unsigned int curr_addr, last_addr;
626
627 curr_addr = inw(s->iobase + CODEC_CMI_CH1_FRAME2);
628 last_addr = ~curr_addr;
629 while( curr_addr != last_addr ) {
630 iodelay32(1);
631 last_addr = curr_addr;
632 curr_addr = inw(s->iobase + CODEC_CMI_CH1_FRAME2);
633 }
634
635 curr_addr = (curr_addr + 1) <<
636 sample_shift[(s->fmt >> CM_CFMT_SHIFT_CH1) & CM_CFMT_MASK];
637 return s->dma_adc.dmasize - curr_addr;
638}
639
640extern __inline__ void wrmixer(struct cm_state *s, unsigned char idx, unsigned char data)
641{
642 outb(idx, s->iobase + CODEC_SB16_ADDR);
643 outb(data, s->iobase + CODEC_SB16_DATA);
644}
645
646extern __inline__ unsigned char rdmixer(struct cm_state *s, unsigned char idx)
647{
648 outb(idx, s->iobase + CODEC_SB16_ADDR);
649 return inb(s->iobase + CODEC_SB16_DATA);
650}
651
652extern __inline__ void enable_aux(struct cm_state *s, int enable, int record)
653{
654 unsigned char v = ( record ) ? 0xc0 : 0x30;
655 maskb(s->iobase + CODEC_CMI_MIXER2, ~v, ( enable ) ? v : 0);
656}
657
658extern __inline__ void enable_digital(struct cm_state *s, int enable, int record)
659{
660 unsigned char v = ( record ) ? 0x0c : 0x01;
661 maskb(s->iobase + CODEC_CMI_MIXER1, ~v, ( enable ) ? v : 0);
662
663 if (record) {
664 // SPDF_1
665 maskb(s->iobase + CODEC_CMI_FUNCTRL1+1, ~0x02, ( enable ) ? 0x02 : 0);
666
667// // select input pin
668// maskb(s->iobase + CODEC_CMI_MISC_CTRL+1, ~1, (record >> 1) & 1);
669 }
670}
671
672extern __inline__ void set_fmt(struct cm_state *s,
673 unsigned char mask, unsigned char data)
674{
675 unsigned long flags;
676
677 spin_lock_irqsave(&s->lock, flags);
678 if (mask)
679 s->fmt = inb(s->iobase + CODEC_CMI_CHFORMAT);
680 s->fmt = (s->fmt & mask) | data;
681 outb(s->fmt, s->iobase + CODEC_CMI_CHFORMAT);
682 spin_unlock_irqrestore(&s->lock, flags);
683}
684
685extern __inline__ void frobindir(struct cm_state *s, unsigned char idx,
686 unsigned char mask, unsigned char data)
687{
688 outb(idx, s->iobase + CODEC_SB16_ADDR);
689 maskb(s->iobase + CODEC_SB16_DATA, mask, data);
690}
691
692
693
694__static__ unsigned char match_rate(unsigned *rate)
695{
696 static struct {
697 unsigned rate;
698 unsigned lower;
699 unsigned upper;
700 unsigned char freq;
701 } rate_lookup[] =
702 {
703 { 5512, (0 + 5512) / 2, (5512 + 8000) / 2, 0 },
704 { 8000, (5512 + 8000) / 2, (8000 + 11025) / 2, 4 },
705 { 11025, (8000 + 11025) / 2, (11025 + 16000) / 2, 1 },
706 { 16000, (11025 + 16000) / 2, (16000 + 22050) / 2, 5 },
707 { 22050, (16000 + 22050) / 2, (22050 + 32000) / 2, 2 },
708 { 32000, (22050 + 32000) / 2, (32000 + 44100) / 2, 6 },
709 { 44100, (32000 + 44100) / 2, (44100 + 48000) / 2, 3 },
710 { 48000, (44100 + 48000) / 2, 48000, 7 }
711 };
712
713 int i;
714 unsigned r = *rate;
715
716 if( r > 48000 ) r = 48000;
717 else if( r < 8000 ) r = 8000;
718
719 for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
720 if (r > rate_lookup[i].lower && r <= rate_lookup[i].upper) {
721 *rate = rate_lookup[i].rate;
722 return rate_lookup[i].freq;
723 }
724 }
725
726 return 0; // impossible to get here ...
727}
728
729
730__static__ void set_spdifout(struct cm_state *s, unsigned rate)
731{
732 unsigned long flags;
733
734 spin_lock_irqsave(&s->lock, flags);
735 if (rate >= 44100 && (s->status & DO_SPDIF_OUT_ENABLE)) {
736 // SPDIFI48K SPDF_ACc97
737 maskl(s->iobase + CODEC_CMI_MISC_CTRL,
738 ~0x01008000, rate == 48000 ? 0x01008000 : 0);
739#if 1
740 // ENSPDOUT
741 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~0, 0x80);
742 // SPDF_0 SPDO2DAC
743 maskw(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x0140);
744
745 // CDPLAY (SPDIF-in monitor)
746 if (s->chip_version >= 39) {
747 maskb(s->iobase + CODEC_CMI_MIXER1, ~0, 0x01);
748 }
749
750 s->status |= DO_SPDIF_OUT;
751
752 } else {
753 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~0x80, 0);
754 maskw(s->iobase + CODEC_CMI_FUNCTRL1, ~0x0140, 0);
755
756 if (s->chip_version >= 39 && !(s->status & DO_SPDIF_MONITOR)) {
757 maskb(s->iobase + CODEC_CMI_MIXER1, ~0x01, 0);
758 }
759
760 s->status &= ~DO_SPDIF_OUT;
761 }
762#else
763 if ( s->chip_version >= 39) {
764 // ENSPDOUT DAC2SPDO
765 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~0, 0xa0);
766 } else {
767 // ENSPDOUT
768 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~0, 0x80);
769 // SPDF_1 SPDO2DAC
770 // maskw(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x0240);
771 // SPDF_0 SPDO2DAC
772 maskw(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x0140);
773 }
774
775 s->status |= DO_SPDIF_OUT;
776
777 } else {
778 if (s->chip_version >= 39) {
779 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~0xa0, 0);
780 } else {
781 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~0x80, 0);
782// maskw(s->iobase + CODEC_CMI_FUNCTRL1, ~0x0240, 0);
783 maskw(s->iobase + CODEC_CMI_FUNCTRL1, ~0x0140, 0);
784 }
785
786 s->status &= ~DO_SPDIF_OUT;
787 }
788#endif
789 spin_unlock_irqrestore(&s->lock, flags);
790}
791
792
793#ifndef TARGET_OS2
794 #if 0
795 /* find parity for bit 4~30 */
796 __static__ unsigned _parity(unsigned data)
797 {
798 unsigned parity = 0;
799 int counter = 4;
800
801 data >>= 4; // start from bit 4
802 while (counter <= 30) {
803 if (data & 1)
804 parity++;
805 data >>= 1;
806 counter++;
807 }
808 return parity & 1;
809 }
810
811 #define parity(val, mask) _parity(val)
812 #else
813 #define parity(val, mask) (hweight32((val) & (mask)) & 1)
814 #endif
815#endif
816
817
818__static__ void set_ac3(struct cm_state *s, unsigned rate)
819{
820 unsigned long flags;
821
822 spin_lock_irqsave(&s->lock, flags);
823//Rudi: set_ac3 should NOT include spdif_out
824// set_spdifout(s, rate);
825
826 /* enable AC3 */
827 if (rate >= 44100 && (s->status & DO_SPDIF_OUT)) {
828
829 // mute DAC
830 maskb(s->iobase + CODEC_CMI_MIXER1, ~0, 0x40);
831 // AC3EN for 037, 0x10
832 maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 0x10);
833 // AC3EN for 039, 0x04
834 maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, 0x04);
835
836 if (s->capability & CAN_AC3_HW) {
837 // SPD24SEL for 037, 0x02
838 // SPD24SEL for 039, 0x20, but cannot be set
839 maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 0x02);
840 s->status |= DO_AC3_HW;
841
842/*Rudi: don't touch CDPLAY here */
843// if (s->chip_version >= 39)
844// maskb(s->iobase + CODEC_CMI_MIXER1, ~1, 0);
845 } else {
846 // SPD32SEL for 037 & 039, 0x20
847 maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, 0x20);
848 // set 176K sample rate to fix 033 HW bug
849 if (s->chip_version == 33) {
850 maskb(s->iobase + CODEC_CMI_CHFORMAT + 1,
851 ~0x08, ( rate == 48000 ) ? 0x08 : 0);
852/*
853 if (rate == 48000)
854 maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0, 0x08);
855 else
856 maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0);
857*/
858 }
859
860 s->status |= DO_AC3_SW;
861 }
862 } else {
863 maskb(s->iobase + CODEC_CMI_MIXER1, ~0x40, 0);
864// Bug ? maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0x32, 0);
865 maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0x12, 0);
866 maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0x24, 0);
867 maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0);
868
869// Rudi: if (s->chip_version == 33)
870// Why twice ? maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0);
871
872/*Rudi: don't touch CDPLAY here */
873// if (s->chip_version >= 39)
874// maskb(s->iobase + CODEC_CMI_MIXER1, ~0, 1);
875
876 s->status &= ~DO_AC3;
877 }
878 s->spdif_counter = 0;
879 spin_unlock_irqrestore(&s->lock, flags);
880}
881
882
883/*
884 * compose 32bit iec958 subframe with non-audio data.
885 * bit 0-3 = preamble
886 * 4-7 = aux (=0)
887 * 8-27 = data (12-27 for 16bit)
888 * 28 = validity (=0)
889 * 29 = user data (=0)
890 * 30 = channel status
891 * 31 = parity
892 *
893 * channel status is assumed as consumer, non-audio
894 * thus all 0 except bit 1
895 */
896
897
898__static__ void trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
899{
900 int i = size / 2;
901 unsigned long data;
902 unsigned long *dst = (unsigned long *) dest;
903 unsigned short *src = (unsigned short *)source;
904
905 while (i--) {
906 data = (unsigned long) *src++;
907 data <<= 12; // ok for 16-bit data
908
909 if (s->spdif_counter == 2 || s->spdif_counter == 3)
910 data |= 0x40000000; // indicate AC-3 raw data
911
912 if (parity(data, 0x7ffffff0))
913 data |= 0x80000000; // parity
914
915 if (s->spdif_counter == 0)
916 data |= 3; // preamble 'B'
917 else if (s->spdif_counter & 1)
918 data |= 5; // odd, 'W'
919 else
920 data |= 9; // even, 'M'
921 *dst++ = data;
922
923 if (++s->spdif_counter == 384) s->spdif_counter = 0;
924 }
925}
926
927__static__ void set_adc_rate(struct cm_state *s, unsigned rate)
928{
929 unsigned long flags;
930 unsigned char freq;
931
932 freq = match_rate(&rate);
933 s->rateadc = rate;
934
935 spin_lock_irqsave(&s->lock, flags);
936 maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0xe0, freq << 5);
937 spin_unlock_irqrestore(&s->lock, flags);
938}
939
940__static__ void set_dac_rate(struct cm_state *s, unsigned rate)
941{
942 unsigned long flags;
943 unsigned char freq;
944
945 freq = match_rate(&rate);
946 s->ratedac = rate;
947
948 spin_lock_irqsave(&s->lock, flags);
949 maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0x1c, freq << 2);
950 spin_unlock_irqrestore(&s->lock, flags);
951
952 if (s->curr_channels <= 2) set_spdifout(s, rate);
953 if (s->status & DO_DUAL_DAC) set_dac1_rate(s, rate);
954}
955
956/* --------------------------------------------------------------------- */
957
958extern __inline__ void pause_adc(struct cm_state *s)
959{
960 maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, CM_PAUSE_CH1);
961}
962
963extern __inline__ void pause_dac(struct cm_state *s)
964{
965 maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, CM_PAUSE_CH0);
966 if (s->status & DO_DUAL_DAC) pause_adc(s);
967}
968
969extern __inline__ void disable_adc(struct cm_state *s)
970{
971 /* disable channel */
972 s->enable &= ~CM_ENABLE_CH1;
973// outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
974
975 /* reset bus master */
976 outb(s->enable | CM_RESET_CH1, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
977 outb(s->enable & ~CM_RESET_CH1, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
978}
979
980extern __inline__ void disable_dac(struct cm_state *s)
981{
982 /* disable channel */
983 s->enable &= ~CM_ENABLE_CH0;
984// outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
985
986 /* reset bus master */
987 outb(s->enable | CM_RESET_CH0, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
988 outb(s->enable & ~CM_RESET_CH0, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
989
990 if (s->status & DO_DUAL_DAC) disable_adc(s);
991}
992
993extern __inline__ void enable_adc(struct cm_state *s)
994{
995 if (!(s->enable & CM_ENABLE_CH1)) {
996 /* enable channel */
997 s->enable |= CM_ENABLE_CH1;
998 outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
999 }
1000 maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CM_PAUSE_CH1, 0);
1001}
1002
1003extern __inline__ void enable_dac(struct cm_state *s)
1004{
1005 if (!(s->enable & CM_ENABLE_CH0)) {
1006 /* enable channel */
1007 s->enable |= CM_ENABLE_CH0;
1008 outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
1009 }
1010 maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CM_PAUSE_CH0, 0);
1011
1012 if (s->status & DO_DUAL_DAC) enable_adc(s);
1013}
1014
1015extern __inline__ void stop_adc(struct cm_state *s)
1016{
1017 unsigned long flags;
1018
1019 spin_lock_irqsave(&s->lock, flags);
1020 if (s->enable & CM_ENABLE_CH1) {
1021 /* disable interrupt */
1022 maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~CM_INT_CH1, 0);
1023 disable_adc(s);
1024 }
1025 spin_unlock_irqrestore(&s->lock, flags);
1026}
1027
1028extern __inline__ void stop_dac(struct cm_state *s)
1029{
1030 unsigned long flags;
1031
1032 spin_lock_irqsave(&s->lock, flags);
1033 if (s->enable & CM_ENABLE_CH0) {
1034 /* disable interrupt */
1035 maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~CM_INT_CH0, 0);
1036 disable_dac(s);
1037 }
1038 spin_unlock_irqrestore(&s->lock, flags);
1039
1040// Rudi: disable_dac() already does this !
1041// if (s->status & DO_DUAL_DAC) stop_dac1(s);
1042}
1043
1044extern __inline__ void start_adc(struct cm_state *s)
1045{
1046 unsigned long flags;
1047
1048 spin_lock_irqsave(&s->lock, flags);
1049 if( !(s->enable & CM_ENABLE_CH1) ) {
1050 if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
1051 && s->dma_adc.ready) {
1052 /* enable interrupt */
1053 maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, CM_INT_CH1);
1054 enable_adc(s);
1055 }
1056 }
1057 spin_unlock_irqrestore(&s->lock, flags);
1058}
1059
1060extern __inline__ void start_dac(struct cm_state *s)
1061{
1062 unsigned long flags;
1063
1064 spin_lock_irqsave(&s->lock, flags);
1065 if( !(s->enable & CM_ENABLE_CH0) ) {
1066 if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
1067 /* enable interrupt */
1068 maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, CM_INT_CH0);
1069 enable_dac(s);
1070 }
1071 }
1072 spin_unlock_irqrestore(&s->lock, flags);
1073
1074// Rudi: enable_dac() already does this !
1075// if (s->status & DO_DUAL_DAC) start_dac1(s);
1076}
1077
1078
1079
1080__static__ int set_dac_channels(struct cm_state *s, int channels)
1081{
1082 unsigned long flags;
1083 ssize_t ret;
1084
1085 spin_lock_irqsave(&s->lock, flags);
1086 if ((channels > 2) && (channels <= s->max_channels)) {
1087// Rudi: && (((s->fmt >> CM_CFMT_SHIFT_CH0) & CM_CFMT_MASK) == (CM_CFMT_STEREO | CM_CFMT_16BIT))) {
1088 set_spdifout(s, 0);
1089 if (s->capability & CAN_MULTI_CH_HW) {
1090 // NXCHG
1091 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0, 0x80);
1092
1093 // CHB3D or CHB3D5C
1094 maskb(s->iobase + CODEC_CMI_CHFORMAT + 3, ~0xa0, channels > 4 ? 0x80 : 0x20);
1095 // CHB3D6C
1096 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~0x80, channels == 6 ? 0x80 : 0);
1097 // ENCENTER
1098 maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~0x80, channels == 6 ? 0x80 : 0);
1099
1100 s->status |= DO_MULTI_CH_HW;
1101 } else if (s->capability & CAN_DUAL_DAC) {
1102 // Rudi: turn off SPDF_0 and SPDF_1
1103 maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0x03, 0);
1104
1105 // ENDBDAC, turn on double DAC mode
1106 // XCHGDAC, CH0 -> back, CH1->front
1107 maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, 0xC0);
1108// Rudi: XCHGDAC seems to be neccessary ...
1109
1110 s->status |= DO_DUAL_DAC;
1111
1112 // prepare secondary buffer
1113 if (ret = prog_dmabuf(s, 1)) {
1114 maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0xC0, 0);
1115 s->status &= ~DO_DUAL_DAC;
1116 spin_unlock_irqrestore(&s->lock, flags);
1117 return ret;
1118 }
1119
1120 // the HW only support 16-bit stereo
1121 set_fmt(s, ~0,
1122 ((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_SHIFT_CH0) |
1123 ((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_SHIFT_CH1));
1124
1125 set_dac1_rate(s, s->ratedac);
1126 }
1127
1128 s->curr_channels = channels;
1129
1130 if (s->speakers > 2) {
1131 // N4SPK3D, disable 4 speaker mode (analog duplicate)
1132 maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~0x04, 0);
1133 update_mixer(s);
1134 }
1135
1136 } else {
1137 if (s->status & DO_MULTI_CH_HW) {
1138 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x80, 0);
1139 maskb(s->iobase + CODEC_CMI_CHFORMAT + 3, ~0xa0, 0);
1140 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~0x80, 0);
1141 } else if (s->status & DO_DUAL_DAC) {
1142 maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0xC0, 0);
1143 }
1144
1145 s->status &= ~(DO_MULTI_CH | DO_DUAL_DAC);
1146 s->curr_channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_SHIFT_CH0) ? 2 : 1;
1147
1148 if (s->speakers > 2) {
1149 // N4SPK3D, enable 4 speaker mode (analog duplicate)
1150 maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~0, 0x04);
1151 update_mixer(s);
1152 }
1153
1154 }
1155 spin_unlock_irqrestore(&s->lock, flags);
1156 return s->curr_channels;
1157}
1158
1159/* --------------------------------------------------------------------- */
1160
1161#ifndef TARGET_OS2
1162 #define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
1163#else
1164 #define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
1165#endif
1166
1167#define DMABUF_MINORDER 1
1168
1169__static__ void dealloc_dmabuf(struct dmabuf *db)
1170{
1171#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1172 struct page *pstart, *pend;
1173#else
1174 unsigned long map, mapend;
1175#endif
1176
1177 if (db->rawbuf) {
1178#ifndef TARGET_OS2
1179 /* undo marking the pages as reserved */
1180 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1181 pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
1182 for (pstart = virt_to_page(db->rawbuf); pstart <= pend; pstart++)
1183 mem_map_unreserve(pstart);
1184 #else
1185 mapend = MAP_NR((char *)db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
1186 for (map = MAP_NR(db->rawbuf); map <= mapend; map++)
1187 clear_bit(PG_reserved, &mem_map[map].flags);
1188 #endif
1189#endif
1190
1191 free_pages((unsigned long)db->rawbuf, db->buforder);
1192 }
1193 db->rawbuf = NULL;
1194 db->mapped = db->ready = 0;
1195}
1196
1197
1198/* Ch0 is used for playback, Ch1 is used for recording */
1199
1200__static__ int prog_dmabuf(struct cm_state *s, unsigned rec)
1201{
1202 struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
1203 unsigned rate = rec ? s->rateadc : s->ratedac;
1204 int order;
1205 unsigned bytepersec;
1206 unsigned bufs;
1207#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1208 struct page *pstart, *pend;
1209#else
1210 unsigned long map, mapend;
1211#endif
1212 unsigned char fmt;
1213 unsigned long flags;
1214
1215 spin_lock_irqsave(&s->lock, flags);
1216 fmt = s->fmt;
1217 if (rec) {
1218 stop_adc(s);
1219 fmt >>= CM_CFMT_SHIFT_CH1;
1220 } else {
1221 stop_dac(s);
1222 fmt >>= CM_CFMT_SHIFT_CH0;
1223 }
1224 spin_unlock_irqrestore(&s->lock, flags);
1225 fmt &= CM_CFMT_MASK;
1226 db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
1227 if (!db->rawbuf) {
1228 db->ready = db->mapped = 0;
1229#ifndef TARGET_OS2
1230 for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
1231 if ((db->rawbuf = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, order)))
1232 break;
1233#else
1234 order = DMABUF_DEFAULTORDER;
1235 db->rawbuf = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, order);
1236#endif
1237 if (!db->rawbuf)
1238 return -ENOMEM;
1239 db->buforder = order;
1240 db->rawphys = virt_to_bus(db->rawbuf);
1241
1242#ifndef TARGET_OS2
1243 if ((db->rawphys ^ (db->rawphys + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff)
1244 printk(KERN_DEBUG "cm: DMA buffer crosses 64k boundary: busaddr 0x%lx size %ld\n",
1245 (long) db->rawphys, PAGE_SIZE << db->buforder);
1246 if ((db->rawphys + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff)
1247 printk(KERN_DEBUG "cm: DMA buffer beyond 16MB: busaddr 0x%lx size %ld\n",
1248 (long) db->rawphys, PAGE_SIZE << db->buforder);
1249
1250 /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
1251 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1252 pend = virt_to_page((char *)db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
1253 for (pstart = virt_to_page(db->rawbuf); pstart <= pend; pstart++)
1254 mem_map_reserve(pstart);
1255 #else
1256 mapend = MAP_NR((char *)db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
1257 for (map = MAP_NR(db->rawbuf); map <= mapend; map++)
1258 set_bit(PG_reserved, &mem_map[map].flags);
1259 #endif
1260#endif
1261
1262 }
1263 bytepersec = rate << sample_shift[fmt];
1264 bufs = PAGE_SIZE << db->buforder;
1265 if (db->ossfragshift) {
1266 if ((1000 << db->ossfragshift) < bytepersec)
1267 db->fragshift = ld2(bytepersec/1000);
1268 else
1269 db->fragshift = db->ossfragshift;
1270 } else {
1271 db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
1272 if (db->fragshift < 3)
1273 db->fragshift = 3;
1274 }
1275 db->numfrag = bufs >> db->fragshift;
1276 while (db->numfrag < 4 && db->fragshift > 3) {
1277 db->fragshift--;
1278 db->numfrag = bufs >> db->fragshift;
1279 }
1280 db->fragsize = 1 << db->fragshift;
1281 if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
1282 db->numfrag = db->ossmaxfrags;
1283 /* to make fragsize >= 4096 */
1284 if (s->modem) {
1285 while (db->fragsize < 4096 && db->numfrag >= 4) {
1286 db->fragsize *= 2;
1287 db->fragshift++;
1288 db->numfrag /= 2;
1289 }
1290 }
1291
1292 db->fragsamples = db->fragsize >> sample_shift[fmt];
1293 db->dmasize = db->numfrag << db->fragshift;
1294 db->dmasamples = db->dmasize >> sample_shift[fmt];
1295 memset(db->rawbuf, (fmt & CM_CFMT_16BIT) ? 0 : 0x80, db->dmasize);
1296
1297 spin_lock_irqsave(&s->lock, flags);
1298 if (rec) {
1299 if (s->status & DO_DUAL_DAC)
1300 set_dmadac1(s, db->rawphys, db->dmasamples);
1301 else
1302 set_dmaadc(s, db->rawphys, db->dmasamples);
1303 /* program sample counts */
1304// Rudi: Bug set_countdac(s, db->fragsamples);
1305 set_countadc(s, db->fragsamples);
1306
1307 } else {
1308 set_dmadac(s, db->rawphys, db->dmasamples);
1309 /* program sample counts */
1310 set_countdac(s, db->fragsamples);
1311 }
1312 spin_unlock_irqrestore(&s->lock, flags);
1313 db->ready = 1;
1314
1315dprintf(("prog_dmabuf(%d): dmasize: %d, fragsize: %d, numfrag: %d",
1316 rec, db->dmasize, db->fragsize, db->numfrag));
1317
1318 return 0;
1319}
1320
1321extern __inline__ void clear_advance(struct cm_state *s)
1322{
1323 unsigned char c = (s->fmt & (CM_CFMT_16BIT << CM_CFMT_SHIFT_CH0)) ? 0 : 0x80;
1324 unsigned char *buf = s->dma_dac.rawbuf;
1325 unsigned char *buf1 = s->dma_adc.rawbuf;
1326 unsigned bsize = s->dma_dac.dmasize;
1327 unsigned bptr = s->dma_dac.swptr;
1328 unsigned len = s->dma_dac.fragsize;
1329
1330 if (bptr + len > bsize) {
1331 unsigned x = bsize - bptr;
1332 memset(buf + bptr, c, x);
1333 if (s->status & DO_DUAL_DAC)
1334 memset(buf1 + bptr, c, x);
1335 bptr = 0;
1336 len -= x;
1337 }
1338 memset(buf + bptr, c, len);
1339 if (s->status & DO_DUAL_DAC)
1340 memset(buf1 + bptr, c, len);
1341}
1342
1343/* call with spinlock held! */
1344__static__ void cm_update_ptr(struct cm_state *s)
1345{
1346 unsigned hwptr;
1347 int diff;
1348
1349 /* update ADC pointer */
1350 if ((s->dma_adc.ready) && !(s->status & DO_DUAL_DAC)) {
1351 hwptr = get_dmaadc(s);
1352 diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
1353 s->dma_adc.hwptr = hwptr;
1354 s->dma_adc.total_bytes += diff;
1355 s->dma_adc.count += diff;
1356 if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
1357 wake_up(&s->dma_adc.wait);
1358 if (!s->dma_adc.mapped) {
1359 if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
1360//dprintf(("dma_adc.count: %d, dmasz: %d, fragsz: %d", s->dma_adc.count, s->dma_adc.dmasize, s->dma_adc.fragsize));
1361#ifndef TARGET_OS2
1362 pause_adc(s);
1363#endif
1364 s->dma_adc.error++;
1365 }
1366 }
1367 }
1368
1369
1370 /* update DAC pointer */
1371 if (s->dma_dac.ready) {
1372 hwptr = get_dmadac(s);
1373 diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
1374 s->dma_dac.hwptr = hwptr;
1375 s->dma_dac.total_bytes += diff;
1376 if (s->dma_dac.mapped) {
1377 s->dma_dac.count += diff;
1378 if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
1379 wake_up(&s->dma_dac.wait);
1380 } else {
1381 s->dma_dac.count -= diff;
1382 if (s->dma_dac.count <= 0) {
1383#ifndef TARGET_OS2
1384 pause_dac(s);
1385#endif
1386 s->dma_dac.error++;
1387 } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
1388 clear_advance(s);
1389 s->dma_dac.endcleared = 1;
1390 }
1391 if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
1392 wake_up(&s->dma_dac.wait);
1393 }
1394 }
1395}
1396
1397#ifdef CONFIG_SOUND_CMPCI_MIDI
1398/* hold spinlock for the following! */
1399__static__ void cm_handle_midi(struct cm_state *s)
1400{
1401 unsigned char ch;
1402 int wake;
1403
1404 wake = 0;
1405 while (!(inb(s->iomidi+1) & 0x80)) {
1406 ch = inb(s->iomidi);
1407 if (s->midi.icnt < MIDIINBUF) {
1408 s->midi.ibuf[s->midi.iwr] = ch;
1409 s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
1410 s->midi.icnt++;
1411 }
1412 wake = 1;
1413 }
1414 if (wake)
1415 wake_up(&s->midi.iwait);
1416 wake = 0;
1417 while (!(inb(s->iomidi+1) & 0x40) && s->midi.ocnt > 0) {
1418 outb(s->midi.obuf[s->midi.ord], s->iomidi);
1419 s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
1420 s->midi.ocnt--;
1421 if (s->midi.ocnt < MIDIOUTBUF-16)
1422 wake = 1;
1423 }
1424 if (wake)
1425 wake_up(&s->midi.owait);
1426}
1427#endif
1428
1429__static__ void cm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1430{
1431 struct cm_state *s = (struct cm_state *)dev_id;
1432 unsigned char intstat, mask;
1433 unsigned int intsrc;
1434
1435 /* fastpath out, to ease interrupt sharing */
1436 intsrc = inl(s->iobase + CODEC_CMI_INT_STATUS);
1437 if( !(intsrc & 0x80000000) ) return;
1438
1439#ifndef TARGET_OS2
1440 spin_lock(&s->lock);
1441 /* acknowledge interrupt */
1442 if (intsrc & CM_INT_CH0)
1443 mask |= 1;
1444 if (intsrc & CM_INT_CH1)
1445 mask |= 2;
1446 outb(intstat & ~mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
1447 outb(intstat | mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
1448 cm_update_ptr(s);
1449 #ifdef CONFIG_SOUND_CMPCI_MIDI
1450 cm_handle_midi(s);
1451 #endif
1452 spin_unlock(&s->lock);
1453#else
1454 // midi uart
1455 if( intsrc & 0x00010000 ) {
1456 OSS32_ProcessIRQ(OSS_STREAM_MIDIIN, (unsigned long)s);
1457 }
1458
1459 if( (mask = (unsigned char)intsrc & (CM_INT_CH0 | CM_INT_CH1)) != 0 ) {
1460 intstat = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2);
1461 outb(intstat & ~mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
1462 outb(intstat | mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
1463 }
1464
1465 // playback
1466 if( (mask & CM_INT_CH0) && s->curr_streamid[1] )
1467 OSS32_ProcessIRQ(OSS_STREAM_WAVEOUT, (unsigned long)s->curr_streamid[1]);
1468
1469 // record
1470 if( (mask & CM_INT_CH1) && s->curr_streamid[0] )
1471 OSS32_ProcessIRQ(OSS_STREAM_WAVEIN, (unsigned long)s->curr_streamid[0]);
1472
1473 eoi_irq(irq);
1474#endif
1475}
1476
1477
1478#ifdef CONFIG_SOUND_CMPCI_MIDI
1479__static__ void cm_midi_timer(unsigned long data)
1480{
1481 struct cm_state *s = (struct cm_state *)data;
1482 unsigned long flags;
1483
1484 spin_lock_irqsave(&s->lock, flags);
1485 cm_handle_midi(s);
1486 spin_unlock_irqrestore(&s->lock, flags);
1487 s->midi.timer.expires = jiffies+1;
1488 add_timer(&s->midi.timer);
1489}
1490#endif
1491
1492/* --------------------------------------------------------------------- */
1493
1494#ifdef CONFIG_SOUND_CMPCI /* support multiple chips */
1495 #define VALIDATE_STATE(s)
1496#else
1497 static const char invalid_magic[] = KERN_CRIT "cm: invalid magic value\n";
1498
1499 #define VALIDATE_STATE(s) \
1500 ({ \
1501 if (!(s) || (s)->magic != CM_MAGIC) { \
1502 printk(invalid_magic); \
1503 return -ENXIO; \
1504 } \
1505 })
1506#endif
1507
1508/* --------------------------------------------------------------------- */
1509
1510#define MT_2 0x01
1511//#define MT_4 0x02
1512#define MT_4AUX 0x03
1513#define MT_5 0x04
1514//#define MT_6 0x05
1515#define MT_MONO 0x40
1516#define MT_MUTE 0x80
1517
1518#define MT_2MONO (MT_2 | MT_MONO)
1519//#define MT_4MUTEMONO (MT_4 | MT_MONO | MT_MUTE)
1520#define MT_5MUTEMONO (MT_5 | MT_MONO | MT_MUTE)
1521
1522
1523static const struct {
1524 unsigned char left; // SB mixer volume index (left channel)
1525 unsigned char right; // SB mixer volume index (right channel)
1526 unsigned char type; // MT_xxx
1527 unsigned char play; // SB register 3c
1528 unsigned short rec; // SB register 3d (left channel only)
1529 // register 3e is derived from 3d
1530} mixtable[SOUND_MIXER_NRDEVICES] = {
1531
1532#ifndef TARGET_OS2
1533 [SOUND_MIXER_CD] = { DSP_MIX_CDVOLIDX_L, DSP_MIX_CDVOLIDX_R, MT_5, 0x02, 0x0004 },
1534 [SOUND_MIXER_LINE] = { DSP_MIX_LINEVOLIDX_L, DSP_MIX_LINEVOLIDX_R, MT_5, 0x08, 0x0010 },
1535 [SOUND_MIXER_MIC] = { DSP_MIX_MICVOLIDX, 0, MT_5MUTEMONO, 0x01, 0x0001 },
1536 [SOUND_MIXER_SYNTH] = { DSP_MIX_FMVOLIDX_L, DSP_MIX_FMVOLIDX_R, MT_5, 0x00, 0x0040 },
1537 [SOUND_MIXER_VOLUME] = { DSP_MIX_MASTERVOLIDX_L, DSP_MIX_MASTERVOLIDX_R, MT_5, 0x00, 0x0000 },
1538 [SOUND_MIXER_PCM] = { DSP_MIX_VOICEVOLIDX_L, DSP_MIX_VOICEVOLIDX_R, MT_5, 0x00, 0x0000 },
1539 [SOUND_MIXER_IGAIN] = { DSP_MIX_INGAINIDX_L, DSP_MIX_INGAINIDX_R, MT_2, 0x00, 0x0000 },
1540 [SOUND_MIXER_OGAIN] = { DSP_MIX_OUTGAINIDX_L, DSP_MIX_OUTGAINIDX_R, MT_2, 0x00, 0x0000 },
1541 [SOUND_MIXER_SPEAKER] = { DSP_MIX_SPKRVOLIDX, 0, MT_2MONO, 0x40, 0x0000 },
1542 // Rudi: AUX and SPDIF/IN support
1543 [SOUND_MIXER_LINE1] = { 0, 0, MT_4AUX, 0x20, 0x0080 },
1544 [SOUND_MIXER_DIGITAL1] = { 0, 0, MT_MUTE, 0x00, 0x0100 }
1545
1546#else
1547
1548/*SOUND_MIXER_VOLUME*/ { DSP_MIX_MASTERVOLIDX_L, DSP_MIX_MASTERVOLIDX_R, MT_5, 0x00, 0x0000 },
1549/*SOUND_MIXER_BASS*/ { 0, 0, 0, 0, 0 },
1550/*SOUND_MIXER_TREBLE*/ { 0, 0, 0, 0, 0 },
1551/*SOUND_MIXER_SYNTH*/ { DSP_MIX_FMVOLIDX_L, DSP_MIX_FMVOLIDX_R, MT_5, 0x00, 0x0040 },
1552/*SOUND_MIXER_PCM*/ { DSP_MIX_VOICEVOLIDX_L, DSP_MIX_VOICEVOLIDX_R, MT_5, 0x00, 0x0000 },
1553/*SOUND_MIXER_SPEAKER*/ { DSP_MIX_SPKRVOLIDX, 0, MT_2MONO, 0x40, 0x0000 },
1554/*SOUND_MIXER_LINE*/ { DSP_MIX_LINEVOLIDX_L, DSP_MIX_LINEVOLIDX_R, MT_5, 0x18, 0x0010 },
1555/*SOUND_MIXER_MIC*/ { DSP_MIX_MICVOLIDX, 0, MT_5MUTEMONO, 0x01, 0x0001 },
1556/*SOUND_MIXER_CD*/ { DSP_MIX_CDVOLIDX_L, DSP_MIX_CDVOLIDX_R, MT_5, 0x06, 0x0004 },
1557/*SOUND_MIXER_IMIX*/ { 0, 0, 0, 0, 0 },
1558/*SOUND_MIXER_ALTPCM*/ { 0, 0, 0, 0, 0 },
1559/*SOUND_MIXER_RECLEV*/ { 0, 0, 0, 0, 0 },
1560/*SOUND_MIXER_IGAIN*/ { DSP_MIX_INGAINIDX_L, DSP_MIX_INGAINIDX_R, MT_2, 0x00, 0x0000 },
1561/*SOUND_MIXER_OGAIN*/ { DSP_MIX_OUTGAINIDX_L, DSP_MIX_OUTGAINIDX_R, MT_2, 0x00, 0x0000 },
1562/*SOUND_MIXER_LINE1*/ { 0, 0, MT_4AUX, 0x20, 0x0080 },
1563/*SOUND_MIXER_LINE2*/ { 0, 0, 0, 0, 0 },
1564/*SOUND_MIXER_LINE3*/ { 0, 0, 0, 0, 0 },
1565/*SOUND_MIXER_DIGITAL1*/{ 0, 0, MT_MUTE, 0x00, 0x0100 }
1566
1567#endif
1568};
1569
1570#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
1571
1572__static__ int return_mixval(struct cm_state *s, unsigned i, int *arg)
1573{
1574 unsigned long flags;
1575 unsigned char l, r, rl, rr;
1576
1577 spin_lock_irqsave(&s->lock, flags);
1578 if( mixtable[i].type == MT_4AUX )
1579 {
1580 l = inb(s->iobase + CODEC_CMI_AUX_VOL);
1581 r = l >> 4;
1582 l &= 0xf;
1583 }
1584 else
1585 {
1586 l = rdmixer(s, mixtable[i].left);
1587 r = rdmixer(s, mixtable[i].right);
1588 }
1589 spin_unlock_irqrestore(&s->lock, flags);
1590
1591 switch (mixtable[i].type) {
1592 case MT_2:
1593 case MT_2MONO:
1594 l >>= 6;
1595 r >>= 6;
1596 rl = (l * 33) + (l != 0);
1597 rr = (r * 33) + (r != 0);
1598 break;
1599
1600 case MT_4:
1601 rl = 10 + 6 * (l & 15);
1602 rr = 10 + 6 * (r & 15);
1603 break;
1604
1605 case MT_4AUX:
1606 rl = 10 + 6 * (l & 15);
1607 rr = 10 + 6 * (r & 15);
1608 break;
1609
1610 case MT_4MUTEMONO:
1611 rl = 55 - 3 * (l & 15);
1612 if (r & 0x10)
1613 rl += 45;
1614 rr = rl;
1615 break;
1616
1617 case MT_5:
1618 rl = 100 - 3 * ((l >> 3) & 31);
1619 rr = 100 - 3 * ((r >> 3) & 31);
1620 break;
1621
1622 case MT_5MUTEMONO:
1623 rl = 100 - 3 * ((l >> 3) & 31);
1624 rr = rl;
1625 break;
1626
1627 case MT_6:
1628 rl = 100 - 3 * (l & 63) / 2;
1629 rr = 100 - 3 * (r & 63) / 2;
1630 break;
1631 }
1632
1633// if (l & 0x80) rl = 0;
1634// if (r & 0x80) rr = 0;
1635
1636 return put_user((rr << 8) | rl, arg);
1637}
1638
1639#else
1640 #define return_mixval(s, v, a) put_user((v), (a))
1641
1642#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
1643
1644
1645
1646__static__ void set_mixval(struct cm_state *s, unsigned i, int val)
1647{
1648 unsigned long flags;
1649 unsigned char l, r, rl, rr, mix, enable;
1650
1651 l = (unsigned char)val;
1652 r = (unsigned char)(val >> 8);
1653 if( l > 100 ) l = 100;
1654 if( r > 100 ) r = 100;
1655
1656// Rudi: master volume always set to max, when running in 4 channel mode
1657 if( s->curr_channels > 2 &&
1658 i != SOUND_MIXER_VOLUME && i != SOUND_MIXER_PCM ) {
1659 rl = (unsigned char)s->mix.vol[SOUND_MIXER_VOLUME];
1660 rr = (unsigned char)(s->mix.vol[SOUND_MIXER_VOLUME] >> 8);
1661 if( rl > 100 ) rl = 100;
1662 if( rr > 100 ) rr = 100;
1663 l = (l * rl) / 100;
1664 r = (r * rr) / 100;
1665 }
1666
1667
1668 spin_lock_irqsave(&s->lock, flags);
1669
1670 switch (mixtable[i].type) {
1671#ifdef MT_2
1672 case MT_2:
1673 wrmixer(s, mixtable[i].right, (r >> 5) << 6);
1674 case MT_2MONO:
1675 wrmixer(s, mixtable[i].left, (l >> 5) << 6);
1676 break;
1677#endif
1678
1679#ifdef MT_4
1680 case MT_4:
1681 rl = (l * 40) >> 8;
1682 rr = (r * 40) >> 8;
1683 frobindir(s, mixtable[i].left, ~0xf0, rl << 4);
1684 frobindir(s, mixtable[i].right, ~0xf0, rr << 4);
1685 break;
1686#endif
1687
1688#ifdef MT_4MUTEMONO
1689 case MT_4MUTEMONO:
1690 rl = (l * 40) >> 8;
1691 rr = (rl >> 1) & 7;
1692 wrmixer(s, mixtable[i].left, rl<<4);
1693 maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, rr<<1);
1694 break;
1695#endif
1696
1697#ifdef MT_4AUX
1698 case MT_4AUX:
1699 rl = (l * 40) >> 8;
1700 rr = (r * 40) >> 8;
1701 outb((rr << 4) | rl, s->iobase + CODEC_CMI_AUX_VOL);
1702 break;
1703#endif
1704
1705#ifdef MT_5
1706 case MT_5:
1707 rl = (l * 80) >> 8;
1708 rr = (r * 80) >> 8;
1709 wrmixer(s, mixtable[i].left, rl<<3);
1710 wrmixer(s, mixtable[i].right, rr<<3);
1711 break;
1712#endif
1713
1714#ifdef MT_5MUTEMONO
1715 case MT_5MUTEMONO:
1716 rl = (l * 80) >> 8;
1717 rr = (rl >> 2) & 7;
1718 wrmixer(s, mixtable[i].left, rl<<3);
1719 maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, rr<<1);
1720 break;
1721#endif
1722
1723#ifdef MT_6
1724 case MT_6:
1725 rl = (l * 160) >> 8;
1726 rr = (r * 160) >> 8;
1727 wrmixer(s, mixtable[i].left, rl);
1728 wrmixer(s, mixtable[i].right, rr);
1729 break;
1730#endif
1731 }
1732
1733#ifdef TARGET_OS2
1734 mix = mixtable[i].play;
1735 enable = l | r;
1736 switch( mix )
1737 {
1738 case 0x20 :
1739 enable_aux(s, enable, 0);
1740 break;
1741
1742 case 0x40 :
1743 frobindir(s, DSP_MIX_EXTENSIONIDX, ~8, ( enable ) ? 8 : 0);
1744 break;
1745
1746 case 0x80 :
1747 case 0x00 :
1748 break;
1749
1750 default :
1751 frobindir(s, DSP_MIX_OUTMIXIDX, ~mix, ( enable ) ? mix : 0);
1752 }
1753#endif
1754
1755 spin_unlock_irqrestore(&s->lock, flags);
1756}
1757
1758
1759__static__ void update_mixer(struct cm_state *s)
1760{
1761 int i;
1762
1763 if( s->curr_channels > 2 ) {
1764 set_mixval(s, SOUND_MIXER_PCM, s->mix.vol[SOUND_MIXER_VOLUME]);
1765 set_mixval(s, SOUND_MIXER_VOLUME, 0x6464);
1766 } else {
1767 set_mixval(s, SOUND_MIXER_PCM, s->mix.vol[SOUND_MIXER_PCM]);
1768 set_mixval(s, SOUND_MIXER_VOLUME, s->mix.vol[SOUND_MIXER_VOLUME]);
1769 }
1770
1771 // emulate master volume control: CD, Line, Aux, Mic, Rear
1772 for( i = 0; i < SOUND_MIXER_NRDEVICES; i++ )
1773 if( mixtable[i].play ) set_mixval(s, i, s->mix.vol[i]);
1774}
1775
1776
1777
1778__static__ unsigned mixer_recmask(struct cm_state *s)
1779{
1780 unsigned long flags;
1781 int i, j, k;
1782
1783 spin_lock_irqsave(&s->lock, flags);
1784 j = rdmixer(s, DSP_MIX_ADCMIXIDX_L);
1785 spin_unlock_irqrestore(&s->lock, flags);
1786 j &= 0x7f;
1787 for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1788 if (j & mixtable[i].rec)
1789 k |= 1 << i;
1790 return k;
1791}
1792
1793__static__ int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
1794{
1795 unsigned long flags;
1796 int i, val, j;
1797
1798 VALIDATE_STATE(s);
1799 if (cmd == SOUND_MIXER_INFO) {
1800 mixer_info info;
1801 strncpy(info.id, "cmpci", sizeof(info.id));
1802 strncpy(info.name, "C-Media PCI", sizeof(info.name));
1803 info.modify_counter = s->mix.modcnt;
1804 if (copy_to_user((void *)arg, &info, sizeof(info)))
1805 return -EFAULT;
1806 return 0;
1807 }
1808 if (cmd == SOUND_OLD_MIXER_INFO) {
1809 _old_mixer_info info;
1810 strncpy(info.id, "cmpci", sizeof(info.id));
1811 strncpy(info.name, "C-Media cmpci", sizeof(info.name));
1812 if (copy_to_user((void *)arg, &info, sizeof(info)))
1813 return -EFAULT;
1814 return 0;
1815 }
1816 if (cmd == OSS_GETVERSION)
1817 return put_user(SOUND_VERSION, (int *)arg);
1818 if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
1819 return -EINVAL;
1820 if (_IOC_DIR(cmd) == _IOC_READ) {
1821 switch (_IOC_NR(cmd)) {
1822 case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
1823// Rudi: AUX and SPDIF/IN support
1824 val = ( inb(s->iobase + CODEC_CMI_MIXER2) & 0xc0 ) ?
1825 SOUND_MASK_LINE1 : 0;
1826 if( inb(s->iobase + CODEC_CMI_MIXER1) & 0x0c )
1827 val |= SOUND_MASK_DIGITAL1;
1828
1829 return put_user(val | mixer_recmask(s), (int *)arg);
1830
1831 case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each output source */
1832// Rudi: AUX and SPDIF/IN support @@@
1833 val = ( inb(s->iobase + CODEC_CMI_MIXER2) & 0x30 ) ?
1834 SOUND_MASK_LINE1 : 0;
1835 if ( inb(s->iobase + CODEC_CMI_MIXER1) & 0x01 )
1836 val |= SOUND_MASK_DIGITAL1;
1837
1838 return put_user(val | mixer_recmask(s), (int *)arg);//need fix
1839
1840 case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
1841 for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1842 if (mixtable[i].type)
1843 val |= 1 << i;
1844 return put_user(val, (int *)arg);
1845
1846 case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
1847 for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1848 if (mixtable[i].rec)
1849 val |= 1 << i;
1850 return put_user(val, (int *)arg);
1851
1852 case SOUND_MIXER_OUTMASK: /* Arg contains a bit for each supported recording source */
1853 for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1854 if (mixtable[i].play)
1855 val |= 1 << i;
1856 return put_user(val, (int *)arg);
1857
1858 case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
1859 for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
1860 if (mixtable[i].type && !(mixtable[i].type & MT_MONO))
1861 val |= 1 << i;
1862 return put_user(val, (int *)arg);
1863
1864 case SOUND_MIXER_CAPS:
1865 return put_user(0, (int *)arg);
1866
1867 default:
1868 i = _IOC_NR(cmd);
1869 if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
1870 return -EINVAL;
1871 return return_mixval(s, i, (int *)arg);
1872 }
1873 }
1874
1875
1876 if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE))
1877 return -EINVAL;
1878 s->mix.modcnt++;
1879 switch (_IOC_NR(cmd)) {
1880 case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
1881#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1882 if (get_user(val, (int *)arg))
1883 return -EFAULT;
1884#else
1885 get_user_ret(val, (int *)arg, -EFAULT);
1886#endif
1887// Rudi: why ? i = hweight32(val);
1888 for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
1889 if (!(val & (1 << i)))
1890 continue;
1891 if (!mixtable[i].rec) {
1892 val &= ~(1 << i);
1893 continue;
1894 }
1895 j |= mixtable[i].rec;
1896 }
1897
1898// Rudi: AUX and SPDIF/IN support
1899 spin_lock_irqsave(&s->lock, flags);
1900 enable_aux(s, j & 0x80, 1);
1901 enable_digital(s, j & 0x0100, 1);
1902 // left -> left, right->right, MIC is mono
1903 j &= 0x7f;
1904 wrmixer(s, DSP_MIX_ADCMIXIDX_L, j);
1905 wrmixer(s, DSP_MIX_ADCMIXIDX_R, (j & 1) | (j>>1));
1906 spin_unlock_irqrestore(&s->lock, flags);
1907 return 0;
1908
1909 case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each output source */
1910#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1911 if (get_user(val, (int *)arg))
1912 return -EFAULT;
1913#else
1914 get_user_ret(val, (int *)arg, -EFAULT);
1915#endif
1916 for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
1917 if (!(val & (1 << i)))
1918 continue;
1919 if (!mixtable[i].play) {
1920 val &= ~(1 << i);
1921 continue;
1922 }
1923 j |= mixtable[i].play;
1924 }
1925
1926// Rudi: AUX and SPDIF/IN support
1927 spin_lock_irqsave(&s->lock, flags);
1928 enable_aux(s, j & 0x20, 0);
1929// enable_digital(s, j & 0x40, 0);
1930
1931// @@@ ist das wirklich korrekt ???
1932 frobindir(s, DSP_MIX_OUTMIXIDX, 0x1f, j & 0x1f);
1933 spin_unlock_irqrestore(&s->lock, flags);
1934 return 0;
1935
1936 default:
1937 i = _IOC_NR(cmd);
1938 if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
1939 return -EINVAL;
1940#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1941 if (get_user(val, (int *)arg))
1942 return -EFAULT;
1943#else
1944 get_user_ret(val, (int *)arg, -EFAULT);
1945#endif
1946
1947// Rudi: 4 channels (seems to work only on Rev39+)
1948// In this mode, master volume is always set to max.
1949// Wave volume is controlled via SOUND_MIXER_PCM.
1950// For all other sources, master volume is emulated
1951 if( /*s->chip_version >= 39 &&*/ s->curr_channels > 2 ) {
1952 if( i == SOUND_MIXER_PCM )
1953 return put_user(val, (int *)arg);
1954
1955 if( i == SOUND_MIXER_VOLUME ) {
1956 s->mix.vol[SOUND_MIXER_VOLUME] = val;
1957 update_mixer(s);
1958 return put_user(val, (int *)arg);
1959 }
1960 }
1961
1962 set_mixval(s, i, val);
1963
1964#ifndef OSS_DOCUMENTED_MIXER_SEMANTICS
1965 s->mix.vol[i] = val;
1966 return put_user(val, (int *)arg);
1967#else
1968 return return_mixval(s, i, (int *)arg);
1969#endif
1970 }
1971}
1972
1973/* --------------------------------------------------------------------- */
1974
1975__static__ loff_t cm_llseek(struct file *file, loff_t offset, int origin)
1976{
1977dprintf(("cm_llseek"));
1978
1979 return -ESPIPE;
1980}
1981
1982/* --------------------------------------------------------------------- */
1983
1984__static__ int cm_open_mixdev(struct inode *inode, struct file *file)
1985{
1986 int minor = MINOR(inode->i_rdev);
1987 struct cm_state *s = devs;
1988
1989dprintf(("cm_open_mixdev"));
1990
1991 while (s && s->dev_mixer != minor)
1992 s = s->next;
1993 if (!s)
1994 return -ENODEV;
1995 VALIDATE_STATE(s);
1996 file->private_data = s;
1997#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
1998 MOD_INC_USE_COUNT;
1999#endif
2000 return 0;
2001}
2002
2003__static__ int cm_release_mixdev(struct inode *inode, struct file *file)
2004{
2005 struct cm_state *s = (struct cm_state *)file->private_data;
2006
2007dprintf(("cm_release_mixdev"));
2008
2009 VALIDATE_STATE(s);
2010#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
2011 MOD_DEC_USE_COUNT;
2012#endif
2013 return 0;
2014}
2015
2016__static__ int cm_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
2017{
2018dprintf(("cm_ioctl_mixdev: %x", cmd));
2019
2020 return mixer_ioctl((struct cm_state *)file->private_data, cmd, arg);
2021}
2022
2023
2024#ifndef TARGET_OS2
2025 static /*const*/ struct file_operations cm_mixer_fops = {
2026 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2027 owner: THIS_MODULE,
2028 #endif
2029 llseek: cm_llseek,
2030 ioctl: cm_ioctl_mixdev,
2031 open: cm_open_mixdev,
2032 release: cm_release_mixdev,
2033 };
2034
2035#else
2036 static /*const*/ struct file_operations cm_mixer_fops = {
2037 cm_llseek, // llseek
2038 NULL, // read
2039 NULL, // write
2040 NULL, // readdir
2041 NULL, // poll
2042 cm_ioctl_mixdev, // ioctl
2043 NULL, // mmap
2044 cm_open_mixdev, // open
2045 NULL, // flush
2046 cm_release_mixdev // release
2047 };
2048
2049#endif
2050
2051
2052
2053/* --------------------------------------------------------------------- */
2054
2055#ifndef TARGET_OS2
2056int IntrOpen(void)
2057{
2058 struct cm_state *s = devs;
2059 unsigned char fmtm = ~0, fmts = 0;
2060
2061 /* Locate the /dev/dsp file descriptor */
2062 while (s && ((s->dev_audio ^ 3) & ~0xf))
2063 s = s->next;
2064
2065 devaudio = s;
2066 down(&s->open_sem);
2067 if (s->open_mode & FMODE_WRITE) {
2068 up(&s->open_sem);
2069 devaudio = NULL;
2070 return -EBUSY;
2071 }
2072
2073 if (!s->dma_dac.ready) {
2074 set_dac_rate(s, 8000);
2075 fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_SHIFT_CH0);
2076 set_fmt(s, fmtm, fmts);
2077 s->modem = 1;
2078 }
2079
2080 s->open_mode |= FMODE_WRITE;
2081 up(&s->open_sem);
2082 MOD_INC_USE_COUNT;
2083 return 0;
2084}
2085EXPORT_SYMBOL(IntrOpen);
2086
2087int IntrClose(void)
2088{
2089 struct cm_state *s = devaudio;
2090
2091 if (!s)
2092 return -ENODEV;
2093 down(&s->open_sem);
2094 stop_dac(s);
2095#ifndef FIXEDDMA
2096 dealloc_dmabuf(&s->dma_dac);
2097#endif
2098
2099 s->open_mode &= ~FMODE_WRITE;
2100 s->modem = 0;
2101 up(&s->open_sem);
2102 wake_up(&s->open_wait);
2103#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
2104 MOD_DEC_USE_COUNT;
2105#endif
2106 devaudio = NULL;
2107 return 0;
2108}
2109EXPORT_SYMBOL(IntrClose);
2110
2111int IntrWrite(const char *buffer, int count)
2112{
2113 struct cm_state *s = devaudio;
2114 ssize_t ret = 0;
2115 unsigned long flags;
2116 unsigned swptr;
2117 int cnt;
2118
2119 if (!s)
2120 return -ENODEV;
2121 VALIDATE_STATE(s);
2122 if (s->dma_dac.mapped)
2123 return -ENXIO;
2124
2125 if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
2126 return ret;
2127
2128 s->dma_dac.ossfragshift = 8;
2129 s->dma_dac.ossmaxfrags = 16;
2130 s->dma_dac.subdivision = 0;
2131
2132 while (count > 0) {
2133 spin_lock_irqsave(&s->lock, flags);
2134 if (s->dma_dac.count < 0) {
2135 s->dma_dac.count = 0;
2136 s->dma_dac.swptr = s->dma_dac.hwptr;
2137 }
2138 swptr = s->dma_dac.swptr;
2139 cnt = s->dma_dac.dmasize-swptr;
2140 if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
2141 cnt = s->dma_dac.dmasize - s->dma_dac.count;
2142 spin_unlock_irqrestore(&s->lock, flags);
2143 if (cnt > count)
2144 cnt = count;
2145 if (cnt <= 0) {
2146 start_dac(s);
2147 return ret;
2148 }
2149 if (__copy_from_user((char *)s->dma_dac.rawbuf + swptr, buffer, cnt))
2150 return ret ? ret : -EFAULT;
2151 swptr = (swptr + cnt) % s->dma_dac.dmasize;
2152 spin_lock_irqsave(&s->lock, flags);
2153 s->dma_dac.swptr = swptr;
2154 s->dma_dac.count += cnt;
2155 s->dma_dac.endcleared = 0;
2156 spin_unlock_irqrestore(&s->lock, flags);
2157 count -= cnt;
2158 buffer += cnt;
2159 ret += cnt;
2160 start_dac(s);
2161 }
2162 return ret;
2163}
2164EXPORT_SYMBOL(IntrWrite);
2165#endif
2166
2167
2168
2169/* --------------------------------------------------------------------- */
2170
2171
2172#ifndef TARGET_OS2
2173 __static__ int drain_dac(struct cm_state *s, int nonblock)
2174 {
2175 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2176 DECLARE_WAITQUEUE(wait, current);
2177 #else
2178 struct wait_queue wait = { current, NULL };
2179 #endif
2180 unsigned long flags;
2181 int count, tmo;
2182
2183 if (s->dma_dac.mapped || !s->dma_dac.ready)
2184 return 0;
2185 current->state = TASK_INTERRUPTIBLE;
2186 add_wait_queue(&s->dma_dac.wait, &wait);
2187 for (;;) {
2188 spin_lock_irqsave(&s->lock, flags);
2189 count = s->dma_dac.count;
2190 spin_unlock_irqrestore(&s->lock, flags);
2191 if (count <= 0)
2192 break;
2193 if (signal_pending(current))
2194 break;
2195 if (nonblock) {
2196 remove_wait_queue(&s->dma_dac.wait, &wait);
2197 current->state = TASK_RUNNING;
2198 return -EBUSY;
2199 }
2200 tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
2201 tmo >>= sample_shift[(s->fmt >> CM_CFMT_SHIFT_CH0) & CM_CFMT_MASK];
2202
2203 if (!schedule_timeout(tmo + 1))
2204 printk(KERN_DEBUG "cm: dma timed out??\n");
2205 }
2206 remove_wait_queue(&s->dma_dac.wait, &wait);
2207 current->state = TASK_RUNNING;
2208 if (signal_pending(current))
2209 return -ERESTARTSYS;
2210 return 0;
2211 }
2212#endif
2213
2214
2215/* --------------------------------------------------------------------- */
2216
2217__static__ ssize_t cm_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
2218{
2219 struct cm_state *s = AUDIO_DEV_PTR(file->private_data);
2220 ssize_t ret;
2221 unsigned long flags;
2222 unsigned swptr;
2223 int cnt;
2224
2225//dprintf(("cm_read"));
2226
2227 VALIDATE_STATE(s);
2228 if (ppos != &file->f_pos)
2229 return -ESPIPE;
2230 if (s->dma_adc.mapped)
2231 return -ENXIO;
2232 if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
2233 return ret;
2234 if (!access_ok(VERIFY_WRITE, buffer, count))
2235 return -EFAULT;
2236 ret = 0;
2237#if 0
2238 spin_lock_irqsave(&s->lock, flags);
2239 cm_update_ptr(s);
2240 spin_unlock_irqrestore(&s->lock, flags);
2241#endif
2242
2243#ifdef TARGET_OS2
2244 if( s->curr_streamid[0] != file->private_data ) {
2245 dprintf(("cm_read: wrong streamid: %x", file->private_data));
2246 return -EAGAIN;
2247 }
2248#endif
2249
2250 while (count > 0) {
2251 spin_lock_irqsave(&s->lock, flags);
2252 swptr = s->dma_adc.swptr;
2253 cnt = s->dma_adc.dmasize-swptr;
2254 if (s->dma_adc.count < cnt)
2255 cnt = s->dma_adc.count;
2256 spin_unlock_irqrestore(&s->lock, flags);
2257 if (cnt > count)
2258 cnt = count;
2259#ifdef TARGET_OS2
2260 if (cnt <= 0) { start_adc(s); return ret; };
2261#else
2262 if (cnt <= 0) {
2263 start_adc(s);
2264 if (file->f_flags & O_NONBLOCK)
2265 return ret ? ret : -EAGAIN;
2266
2267 if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
2268 printk(KERN_DEBUG "cm: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
2269 s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count,
2270 s->dma_adc.hwptr, s->dma_adc.swptr);
2271 stop_adc(s);
2272 spin_lock_irqsave(&s->lock, flags);
2273 set_dmaadc(s, s->dma_adc.rawphys, s->dma_adc.dmasamples);
2274 /* program sample counts */
2275 set_countadc(s, s->dma_adc.fragsamples);
2276 s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
2277 spin_unlock_irqrestore(&s->lock, flags);
2278 }
2279
2280 if (signal_pending(current))
2281 return ret ? ret : -ERESTARTSYS;
2282 continue;
2283 }
2284#endif
2285
2286 if (copy_to_user(buffer, (char *)s->dma_adc.rawbuf + swptr, cnt))
2287 return ret ? ret : -EFAULT;
2288 swptr = (swptr + cnt) % s->dma_adc.dmasize;
2289 spin_lock_irqsave(&s->lock, flags);
2290 s->dma_adc.swptr = swptr;
2291 s->dma_adc.count -= cnt;
2292 spin_unlock_irqrestore(&s->lock, flags);
2293 count -= cnt;
2294 buffer += cnt;
2295 ret += cnt;
2296 start_adc(s);
2297 }
2298 return ret;
2299}
2300
2301__static__ ssize_t cm_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
2302{
2303 struct cm_state *s = AUDIO_DEV_PTR(file->private_data);
2304 ssize_t ret;
2305 unsigned long flags;
2306 unsigned swptr;
2307 int cnt, dualshift;
2308
2309//dprintf(("cm_write: %d %d", count, 1));
2310
2311 VALIDATE_STATE(s);
2312 if (ppos != &file->f_pos)
2313 return -ESPIPE;
2314 if (s->dma_dac.mapped)
2315 return -ENXIO;
2316 if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
2317 return ret;
2318 if (!access_ok(VERIFY_READ, buffer, count))
2319 return -EFAULT;
2320 if (s->status & DO_DUAL_DAC) {
2321 if (s->dma_adc.mapped)
2322 return -ENXIO;
2323 if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
2324 return ret;
2325 if (!access_ok(VERIFY_READ, buffer, count))
2326 return -EFAULT;
2327 }
2328 ret = 0;
2329#if 0
2330 spin_lock_irqsave(&s->lock, flags);
2331 cm_update_ptr(s);
2332 spin_unlock_irqrestore(&s->lock, flags);
2333#endif
2334
2335#ifdef TARGET_OS2
2336 if( s->curr_streamid[1] != file->private_data ) {
2337 dprintf(("cm_write: wrong streamid: %x", file->private_data));
2338 return -EAGAIN;
2339 }
2340#endif
2341
2342 dualshift = ( s->status & DO_DUAL_DAC ) != 0;
2343
2344 while (count > 0) {
2345 spin_lock_irqsave(&s->lock, flags);
2346 if (s->dma_dac.count < 0) {
2347 s->dma_dac.count = 0;
2348 s->dma_dac.swptr = s->dma_dac.hwptr;
2349 }
2350 if( dualshift ) {
2351 s->dma_adc.swptr = s->dma_dac.swptr;
2352 s->dma_adc.count = s->dma_dac.count;
2353 s->dma_adc.endcleared = s->dma_dac.endcleared;
2354 }
2355 swptr = s->dma_dac.swptr;
2356 cnt = s->dma_dac.dmasize-swptr;
2357 if (s->status & DO_AC3_SW) {
2358 if (s->dma_dac.count + 2 * cnt > s->dma_dac.dmasize)
2359 cnt = (s->dma_dac.dmasize - s->dma_dac.count) / 2;
2360 } else {
2361 if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
2362 cnt = s->dma_dac.dmasize - s->dma_dac.count;
2363 }
2364 spin_unlock_irqrestore(&s->lock, flags);
2365
2366 cnt <<= dualshift;
2367 if (cnt > count) cnt = count;
2368
2369#ifdef TARGET_OS2
2370 if (cnt <= 0) { start_dac(s); return ret; }
2371#else
2372 if (cnt <= 0) {
2373 start_dac(s);
2374 if (file->f_flags & O_NONBLOCK)
2375 return ret ? ret : -EAGAIN;
2376
2377 if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
2378 printk(KERN_DEBUG "cm: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
2379 s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
2380 s->dma_dac.hwptr, s->dma_dac.swptr);
2381 stop_dac(s);
2382 spin_lock_irqsave(&s->lock, flags);
2383 set_dmadac(s, s->dma_dac.rawphys, s->dma_dac.dmasamples);
2384 /* program sample counts */
2385 set_countdac(s, s->dma_dac.fragsamples);
2386 s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
2387 if (s->status & DO_DUAL_DAC) {
2388 set_dmadac1(s, s->dma_adc.rawphys, s->dma_adc.dmasamples);
2389 s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
2390 }
2391 spin_unlock_irqrestore(&s->lock, flags);
2392 }
2393
2394 if (signal_pending(current))
2395 return ret ? ret : -ERESTARTSYS;
2396 continue;
2397 }
2398#endif
2399 if (s->status & DO_AC3_SW) {
2400 // clip exceeded data, caught by 033 and 037
2401 if (swptr + 2 * cnt > s->dma_dac.dmasize)
2402 cnt = (s->dma_dac.dmasize - swptr) / 2;
2403 trans_ac3(s, (char *)s->dma_dac.rawbuf + swptr, buffer, cnt);
2404 swptr = (swptr + 2 * cnt) % s->dma_dac.dmasize;
2405 } else if (s->status & DO_DUAL_DAC) {
2406 int i;
2407 unsigned long *src, *dst0, *dst1;
2408
2409 src = (unsigned long *) buffer;
2410 dst0 = (unsigned long *) ((char *)s->dma_dac.rawbuf + swptr);
2411 dst1 = (unsigned long *) ((char *)s->dma_adc.rawbuf + swptr);
2412
2413 // copy left/right sample at one time
2414 cnt >>= 3;
2415 for (i = 0; i < cnt; i++) {
2416// Rudi: exchange front <-> rear
2417 *dst1++ = *src++;
2418 *dst0++ = *src++;
2419 }
2420 cnt <<= 3;
2421 swptr = (swptr + (cnt >> 1)) % s->dma_dac.dmasize;
2422
2423 } else {
2424 if (copy_from_user((char *)s->dma_dac.rawbuf + swptr, buffer, cnt))
2425 return ret ? ret : -EFAULT;
2426 swptr = (swptr + cnt) % s->dma_dac.dmasize;
2427 }
2428
2429 spin_lock_irqsave(&s->lock, flags);
2430 s->dma_dac.swptr = swptr;
2431 s->dma_dac.count += cnt >> dualshift;
2432 if (s->status & DO_AC3_SW) s->dma_dac.count += cnt;
2433 s->dma_dac.endcleared = 0;
2434 spin_unlock_irqrestore(&s->lock, flags);
2435
2436 count -= cnt;
2437 buffer += cnt;
2438 ret += cnt;
2439 if( dualshift && (count < 8) ) count = 0;
2440
2441 start_dac(s);
2442 }
2443 return ret;
2444}
2445
2446__static__ unsigned int cm_poll(struct file *file, struct poll_table_struct *wait)
2447{
2448 struct cm_state *s = AUDIO_DEV_PTR(file->private_data);
2449 unsigned long flags;
2450 unsigned int mask = 0;
2451
2452dprintf(("cm_poll"));
2453
2454 VALIDATE_STATE(s);
2455 if (file->f_mode & FMODE_WRITE)
2456 poll_wait(file, &s->dma_dac.wait, wait);
2457 if (file->f_mode & FMODE_READ)
2458 poll_wait(file, &s->dma_adc.wait, wait);
2459 spin_lock_irqsave(&s->lock, flags);
2460 cm_update_ptr(s);
2461 if (file->f_mode & FMODE_READ) {
2462 if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
2463 mask |= POLLIN | POLLRDNORM;
2464 }
2465 if (file->f_mode & FMODE_WRITE) {
2466 if (s->dma_dac.mapped) {
2467 if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
2468 mask |= POLLOUT | POLLWRNORM;
2469 } else {
2470 if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
2471 mask |= POLLOUT | POLLWRNORM;
2472 }
2473 }
2474 spin_unlock_irqrestore(&s->lock, flags);
2475
2476 return mask;
2477}
2478
2479__static__ int cm_mmap(struct file *file, struct vm_area_struct *vma)
2480{
2481 struct cm_state *s = AUDIO_DEV_PTR(file->private_data);
2482 struct dmabuf *db;
2483 int ret = -EINVAL;
2484 unsigned long size;
2485
2486dprintf(("cm_mmap"));
2487
2488 VALIDATE_STATE(s);
2489#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2490 lock_kernel();
2491#endif
2492 if (vma->vm_flags & VM_WRITE) {
2493 if ((ret = prog_dmabuf(s, 0)) != 0)
2494 goto out;
2495 db = &s->dma_dac;
2496 } else if (vma->vm_flags & VM_READ) {
2497 if ((ret = prog_dmabuf(s, 1)) != 0)
2498 goto out;
2499 db = &s->dma_adc;
2500 } else
2501 goto out;
2502 ret = -EINVAL;
2503#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2504 if (vma->vm_pgoff != 0)
2505#else
2506 if (vma->vm_offset != 0)
2507#endif
2508 goto out;
2509 size = vma->vm_end - vma->vm_start;
2510 if (size > (PAGE_SIZE << db->buforder))
2511 goto out;
2512 ret = -EINVAL;
2513 if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
2514 goto out;
2515 db->mapped = 1;
2516 ret = 0;
2517out:
2518#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2519 unlock_kernel();
2520#endif
2521 return ret;
2522}
2523
2524__static__ int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
2525{
2526 struct cm_state *s = AUDIO_DEV_PTR(file->private_data);
2527 unsigned long flags;
2528 audio_buf_info abinfo;
2529 count_info cinfo;
2530 int val, mapped, ret, temp;
2531 unsigned char fmtm, fmtd;
2532
2533//dprintf(("cm_ioctl: %x, %x", cmd, s));
2534
2535 VALIDATE_STATE(s);
2536 mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
2537 ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
2538 switch (cmd) {
2539 case OSS_GETVERSION:
2540 return put_user(SOUND_VERSION, (int *)arg);
2541
2542#ifndef TARGET_OS2
2543 case SNDCTL_DSP_SYNC:
2544 if (file->f_mode & FMODE_WRITE)
2545 return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
2546 return 0;
2547
2548 case SNDCTL_DSP_SETDUPLEX:
2549 return 0;
2550
2551 case SNDCTL_DSP_GETCAPS:
2552 return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
2553 DSP_CAP_TRIGGER | DSP_CAP_MMAP |
2554 DSP_CAP_BIND, (int *)arg);
2555#endif
2556
2557 case SNDCTL_DSP_RESET:
2558dprintf(("IOCTL: SNDCTL_DSP_RESET: %x (%x)", file->private_data, s->curr_streamid[1]));
2559
2560 if (file->f_mode & FMODE_WRITE) {
2561#ifdef TARGET_OS2
2562 if( s->curr_streamid[1] == file->private_data ) {
2563#endif
2564 stop_dac(s);
2565 synchronize_irq();
2566
2567 spin_lock_irqsave(&s->lock, flags);
2568 s->dma_dac.ready = 0;
2569 s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
2570 if (s->status & DO_DUAL_DAC) {
2571//Rudi: clear adc.ready as well
2572 s->dma_adc.ready = 0;
2573 s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
2574 }
2575 spin_unlock_irqrestore(&s->lock, flags);
2576#ifdef TARGET_OS2
2577 }
2578#endif
2579 }
2580 if (file->f_mode & FMODE_READ) {
2581#ifdef TARGET_OS2
2582 if( s->curr_streamid[0] == file->private_data ) {
2583#endif
2584 stop_adc(s);
2585 synchronize_irq();
2586
2587 spin_lock_irqsave(&s->lock, flags);
2588 s->dma_adc.ready = 0;
2589 s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
2590 spin_unlock_irqrestore(&s->lock, flags);
2591#ifdef TARGET_OS2
2592 }
2593#endif
2594 }
2595 return 0;
2596
2597 case SNDCTL_DSP_SPEED:
2598dprintf(("IOCTL: SNDCTL_DSP_SPEED: %x (%x)", file->private_data, s->curr_streamid[1]));
2599
2600#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2601 if (get_user(val, (int *)arg))
2602 return -EFAULT;
2603#else
2604 get_user_ret(val, (int *)arg, -EFAULT);
2605#endif
2606 if (val >= 0) {
2607 if (file->f_mode & FMODE_READ) {
2608 stop_adc(s);
2609 s->dma_adc.ready = 0;
2610 set_adc_rate(s, val);
2611#ifdef TARGET_OS2
2612 s->curr_streamid[0] = file->private_data;
2613#endif
2614 }
2615 if (file->f_mode & FMODE_WRITE) {
2616 stop_dac(s);
2617 s->dma_dac.ready = 0;
2618 if (s->status & DO_DUAL_DAC)
2619 s->dma_adc.ready = 0;
2620 set_dac_rate(s, val);
2621#ifdef TARGET_OS2
2622 s->curr_streamid[1] = file->private_data;
2623#endif
2624 }
2625 }
2626 return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
2627
2628 case SNDCTL_DSP_STEREO:
2629#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2630 if (get_user(val, (int *)arg))
2631 return -EFAULT;
2632#else
2633 get_user_ret(val, (int *)arg, -EFAULT);
2634#endif
2635 fmtd = 0;
2636 fmtm = ~0;
2637 if (file->f_mode & FMODE_READ) {
2638 stop_adc(s);
2639 s->dma_adc.ready = 0;
2640 if (val)
2641 fmtd |= CM_CFMT_STEREO << CM_CFMT_SHIFT_CH1;
2642 else
2643 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_SHIFT_CH1);
2644 }
2645 if (file->f_mode & FMODE_WRITE) {
2646 stop_dac(s);
2647 s->dma_dac.ready = 0;
2648 if (val)
2649 fmtd |= CM_CFMT_STEREO << CM_CFMT_SHIFT_CH0;
2650 else
2651 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_SHIFT_CH0);
2652 if (s->status & DO_DUAL_DAC) {
2653 s->dma_adc.ready = 0;
2654 if (val)
2655 fmtd |= CM_CFMT_STEREO << CM_CFMT_SHIFT_CH1;
2656 else
2657 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_SHIFT_CH1);
2658 }
2659 }
2660 set_fmt(s, fmtm, fmtd);
2661 return 0;
2662
2663 case SNDCTL_DSP_CHANNELS:
2664dprintf(("IOCTL: SNDCTL_DSP_CHANNELS: %x (%x)", file->private_data, s->curr_streamid[1]));
2665
2666#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2667 if (get_user(val, (int *)arg))
2668 return -EFAULT;
2669#else
2670 get_user_ret(val, (int *)arg, -EFAULT);
2671#endif
2672 if (val != 0) {
2673 fmtd = 0;
2674 fmtm = ~0;
2675 if (file->f_mode & FMODE_READ) {
2676 stop_adc(s);
2677 s->dma_adc.ready = 0;
2678 if (val >= 2)
2679 fmtd |= CM_CFMT_STEREO << CM_CFMT_SHIFT_CH1;
2680 else
2681 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_SHIFT_CH1);
2682 }
2683 if (file->f_mode & FMODE_WRITE) {
2684 stop_dac(s);
2685 s->dma_dac.ready = 0;
2686 if (val >= 2)
2687 fmtd |= CM_CFMT_STEREO << CM_CFMT_SHIFT_CH0;
2688 else
2689 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_SHIFT_CH0);
2690 if (s->status & DO_DUAL_DAC) {
2691 s->dma_adc.ready = 0;
2692 if (val >= 2)
2693 fmtd |= CM_CFMT_STEREO << CM_CFMT_SHIFT_CH1;
2694 else
2695 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_SHIFT_CH1);
2696 }
2697 }
2698 set_fmt(s, fmtm, fmtd);
2699 if ((s->capability & CAN_MULTI_CH)
2700 && (file->f_mode & FMODE_WRITE)) {
2701 val = set_dac_channels(s, val);
2702 return put_user(val, (int *)arg);
2703 }
2704 }
2705 return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_SHIFT_CH1)
2706 : (CM_CFMT_STEREO << CM_CFMT_SHIFT_CH0))) ? 2 : 1, (int *)arg);
2707
2708 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
2709 return put_user(AFMT_S16_LE|AFMT_U8|AFMT_AC3, (int *)arg);
2710
2711 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
2712dprintf(("IOCTL: SNDCTL_DSP_SETFMT: %x (%x)", file->private_data, s->curr_streamid[1]));
2713
2714#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2715 if (get_user(val, (int *)arg))
2716 return -EFAULT;
2717#else
2718 get_user_ret(val, (int *)arg, -EFAULT);
2719#endif
2720 if (val != AFMT_QUERY) {
2721 fmtd = 0;
2722 fmtm = ~0;
2723 if (file->f_mode & FMODE_READ) {
2724 stop_adc(s);
2725 s->dma_adc.ready = 0;
2726 if (val == AFMT_S16_LE)
2727 fmtd |= CM_CFMT_16BIT << CM_CFMT_SHIFT_CH1;
2728 else
2729 fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_SHIFT_CH1);
2730 }
2731 if (file->f_mode & FMODE_WRITE) {
2732 stop_dac(s);
2733 s->dma_dac.ready = 0;
2734 if (val == AFMT_S16_LE || val == AFMT_AC3)
2735 fmtd |= CM_CFMT_16BIT << CM_CFMT_SHIFT_CH0;
2736 else
2737 fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_SHIFT_CH0);
2738
2739 if (val == AFMT_AC3) {
2740 fmtd |= CM_CFMT_STEREO << CM_CFMT_SHIFT_CH0;
2741// Rudi: enable set_spdifout separately
2742
2743 // AC3HACK
2744 temp = s->status & DO_SPDIF_OUT_ENABLE;
2745 s->status |= DO_SPDIF_OUT_ENABLE;
2746 set_spdifout(s, s->ratedac);
2747 set_ac3(s, s->ratedac);
2748 s->status &= ~temp ^ DO_SPDIF_OUT_ENABLE;
2749
2750 } else {
2751 set_ac3(s, 0);
2752 set_spdifout(s, (s->curr_channels <= 2) ? s->ratedac : 0);
2753 }
2754
2755 if (s->status & DO_DUAL_DAC) {
2756 s->dma_adc.ready = 0;
2757 if (val == AFMT_S16_LE)
2758 fmtd |= CM_CFMT_STEREO << CM_CFMT_SHIFT_CH1;
2759 else
2760 fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_SHIFT_CH1);
2761 }
2762 }
2763 set_fmt(s, fmtm, fmtd);
2764 }
2765 if (s->status & DO_AC3) return put_user(AFMT_AC3, (int *)arg);
2766 return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_SHIFT_CH1)
2767 : (CM_CFMT_16BIT << CM_CFMT_SHIFT_CH0))) ? AFMT_S16_LE : AFMT_U8, (int *)arg);
2768
2769 case SNDCTL_DSP_POST:
2770 return 0;
2771
2772 case SNDCTL_DSP_GETTRIGGER:
2773 val = 0;
2774 if (s->status & DO_DUAL_DAC) {
2775 if (file->f_mode & FMODE_WRITE &&
2776 (s->enable & CM_ENABLE_CH1) &&
2777 (s->enable & CM_ENABLE_CH0))
2778 val |= PCM_ENABLE_OUTPUT;
2779 return put_user(val, (int *)arg);
2780 }
2781 if (file->f_mode & FMODE_READ && s->enable & CM_ENABLE_CH0)
2782 val |= PCM_ENABLE_INPUT;
2783 if (file->f_mode & FMODE_WRITE && s->enable & CM_ENABLE_CH1)
2784 val |= PCM_ENABLE_OUTPUT;
2785 return put_user(val, (int *)arg);
2786
2787 case SNDCTL_DSP_SETTRIGGER:
2788
2789#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2790 if (get_user(val, (int *)arg))
2791 return -EFAULT;
2792#else
2793 get_user_ret(val, (int *)arg, -EFAULT);
2794#endif
2795
2796dprintf(("IOCTL: SNDCTL_DSP_SETTRIGGER(%d): %x (%x)", val, file->private_data, s->curr_streamid[1]));
2797
2798 if (file->f_mode & FMODE_READ) {
2799 if (val & PCM_ENABLE_INPUT) {
2800 if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
2801 return ret;
2802#ifdef TARGET_OS2
2803 s->curr_streamid[0] = file->private_data;
2804#endif
2805 start_adc(s);
2806 } else {
2807#ifdef TARGET_OS2
2808 if( s->curr_streamid[0] == file->private_data )
2809#endif
2810 stop_adc(s);
2811 }
2812 }
2813 if (file->f_mode & FMODE_WRITE) {
2814 if (val & PCM_ENABLE_OUTPUT) {
2815 if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
2816 return ret;
2817 if (s->status & DO_DUAL_DAC) {
2818 if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
2819 return ret;
2820 }
2821#ifdef TARGET_OS2
2822 s->curr_streamid[1] = file->private_data;
2823#endif
2824 start_dac(s);
2825 } else {
2826#ifdef TARGET_OS2
2827 if( s->curr_streamid[1] == file->private_data )
2828#endif
2829 stop_dac(s);
2830 }
2831 }
2832 return 0;
2833
2834 case SNDCTL_DSP_GETOSPACE:
2835 if (!(file->f_mode & FMODE_WRITE))
2836 return -EINVAL;
2837#ifdef TARGET_OS2
2838 if( s->curr_streamid[1] != file->private_data ) return -EINVAL;
2839#endif
2840// if (!(s->enable & CM_ENABLE_CH1) && (val = prog_dmabuf(s, 0)))
2841 if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)))
2842 return val;
2843 spin_lock_irqsave(&s->lock, flags);
2844 cm_update_ptr(s);
2845 abinfo.fragsize = s->dma_dac.fragsize;
2846//Rudi: round down to full sample size
2847 abinfo.bytes = (s->dma_dac.dmasize - s->dma_dac.count) &
2848 sample_mask[(s->fmt >> CM_CFMT_SHIFT_CH0) & CM_CFMT_MASK];
2849//Rudi: 4 channels
2850 if( s->status & DO_DUAL_DAC ) abinfo.bytes <<= 1;
2851 abinfo.fragstotal = s->dma_dac.numfrag;
2852 abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
2853 spin_unlock_irqrestore(&s->lock, flags);
2854 return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
2855
2856 case SNDCTL_DSP_GETISPACE:
2857 if (!(file->f_mode & FMODE_READ))
2858 return -EINVAL;
2859#ifdef TARGET_OS2
2860 if( s->curr_streamid[0] != file->private_data ) return -EINVAL;
2861#endif
2862// if (!(s->enable & CM_ENABLE_CH0) && (val = prog_dmabuf(s, 1)) != 0)
2863 if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)))
2864 return val;
2865 spin_lock_irqsave(&s->lock, flags);
2866 cm_update_ptr(s);
2867 abinfo.fragsize = s->dma_adc.fragsize;
2868//Rudi: round down to full sample size
2869 abinfo.bytes = s->dma_adc.count &
2870 sample_mask[(s->fmt >> CM_CFMT_SHIFT_CH1) & CM_CFMT_MASK];
2871 abinfo.fragstotal = s->dma_adc.numfrag;
2872 abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
2873 spin_unlock_irqrestore(&s->lock, flags);
2874 return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
2875
2876 case SNDCTL_DSP_NONBLOCK:
2877 file->f_flags |= O_NONBLOCK;
2878 return 0;
2879
2880 case SNDCTL_DSP_GETODELAY:
2881 if (!(file->f_mode & FMODE_WRITE))
2882 return -EINVAL;
2883 spin_lock_irqsave(&s->lock, flags);
2884 cm_update_ptr(s);
2885 val = s->dma_dac.count;
2886 spin_unlock_irqrestore(&s->lock, flags);
2887 return put_user(val, (int *)arg);
2888
2889 case SNDCTL_DSP_GETIPTR:
2890 if (!(file->f_mode & FMODE_READ))
2891 return -EINVAL;
2892#ifdef TARGET_OS2
2893 if( s->curr_streamid[0] != file->private_data ) return -EINVAL;
2894#endif
2895 spin_lock_irqsave(&s->lock, flags);
2896 cm_update_ptr(s);
2897 cinfo.bytes = s->dma_adc.total_bytes;
2898 cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
2899 cinfo.ptr = s->dma_adc.hwptr;
2900 if (s->dma_adc.mapped)
2901 s->dma_adc.count &= s->dma_adc.fragsize-1;
2902 spin_unlock_irqrestore(&s->lock, flags);
2903 return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
2904
2905 case SNDCTL_DSP_GETOPTR:
2906 if (!(file->f_mode & FMODE_WRITE))
2907 return -EINVAL;
2908#ifdef TARGET_OS2
2909 if( s->curr_streamid[1] != file->private_data ) return -EINVAL;
2910#endif
2911 spin_lock_irqsave(&s->lock, flags);
2912 cm_update_ptr(s);
2913 cinfo.bytes = s->dma_dac.total_bytes;
2914//Rudi: 4 channels
2915 if( s->status & DO_DUAL_DAC ) cinfo.bytes <<= 1;
2916
2917 cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
2918
2919//Rudi: SW_AC3 uses 32bits
2920 if( s->status & DO_AC3_SW ) {
2921 cinfo.bytes >>= 1; cinfo.blocks >>= 1;
2922 }
2923
2924 cinfo.ptr = s->dma_dac.hwptr;
2925 if (s->dma_dac.mapped)
2926 s->dma_dac.count &= s->dma_dac.fragsize-1;
2927 if (s->status & DO_DUAL_DAC) {
2928 if (s->dma_adc.mapped)
2929 s->dma_adc.count &= s->dma_adc.fragsize-1;
2930 }
2931 spin_unlock_irqrestore(&s->lock, flags);
2932 return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
2933
2934 case SNDCTL_DSP_GETBLKSIZE:
2935 if (file->f_mode & FMODE_WRITE) {
2936 if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)))
2937 return val;
2938 if (s->status & DO_DUAL_DAC) {
2939 if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)))
2940 return val;
2941 return put_user(2 * s->dma_dac.fragsize, (int *)arg);
2942 }
2943 return put_user(s->dma_dac.fragsize, (int *)arg);
2944 }
2945
2946 if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)))
2947 return val;
2948 return put_user(s->dma_adc.fragsize, (int *)arg);
2949
2950 case SNDCTL_DSP_SETFRAGMENT:
2951dprintf(("IOCTL: SNDCTL_DSP_SETFRAGMENT:: %x (%x)", file->private_data, s->curr_streamid[1]));
2952
2953#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2954 if (get_user(val, (int *)arg))
2955 return -EFAULT;
2956#else
2957 get_user_ret(val, (int *)arg, -EFAULT);
2958#endif
2959 if (file->f_mode & FMODE_READ) {
2960 s->dma_adc.ossfragshift = val & 0xffff;
2961 s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
2962 if (s->dma_adc.ossfragshift < 4)
2963 s->dma_adc.ossfragshift = 4;
2964 if (s->dma_adc.ossfragshift > 15)
2965 s->dma_adc.ossfragshift = 15;
2966 if (s->dma_adc.ossmaxfrags < 4)
2967 s->dma_adc.ossmaxfrags = 4;
2968 }
2969 if (file->f_mode & FMODE_WRITE) {
2970 s->dma_dac.ossfragshift = val & 0xffff;
2971 s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
2972 if (s->dma_dac.ossfragshift < 4)
2973 s->dma_dac.ossfragshift = 4;
2974 if (s->dma_dac.ossfragshift > 15)
2975 s->dma_dac.ossfragshift = 15;
2976 if (s->dma_dac.ossmaxfrags < 4)
2977 s->dma_dac.ossmaxfrags = 4;
2978 if (s->status & DO_DUAL_DAC) {
2979 s->dma_adc.ossfragshift = s->dma_dac.ossfragshift;
2980 s->dma_adc.ossmaxfrags = s->dma_dac.ossmaxfrags;
2981 }
2982 }
2983 return 0;
2984
2985 case SNDCTL_DSP_SUBDIVIDE:
2986 if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
2987 (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
2988 return -EINVAL;
2989#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2990 if (get_user(val, (int *)arg))
2991 return -EFAULT;
2992#else
2993 get_user_ret(val, (int *)arg, -EFAULT);
2994#endif
2995 if (val != 1 && val != 2 && val != 4)
2996 return -EINVAL;
2997 if (file->f_mode & FMODE_READ)
2998 s->dma_adc.subdivision = val;
2999 if (file->f_mode & FMODE_WRITE) {
3000 s->dma_dac.subdivision = val;
3001 if (s->status & DO_DUAL_DAC)
3002 s->dma_adc.subdivision = val;
3003 }
3004 return 0;
3005
3006 case SOUND_PCM_READ_RATE:
3007 return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
3008
3009 case SOUND_PCM_READ_CHANNELS:
3010 return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_SHIFT_CH1) : (CM_CFMT_STEREO << CM_CFMT_SHIFT_CH0))) ? 2 : 1, (int *)arg);
3011
3012 case SOUND_PCM_READ_BITS:
3013 return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_SHIFT_CH1) : (CM_CFMT_16BIT << CM_CFMT_SHIFT_CH0))) ? 16 : 8, (int *)arg);
3014
3015 case SOUND_PCM_READ_FILTER:
3016 return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
3017
3018 case SNDCTL_DSP_GETCHANNELMASK:
3019 return put_user(DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE|DSP_BIND_SPDIF, (int *)arg);
3020
3021 case SNDCTL_DSP_BIND_CHANNEL:
3022#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3023 if (get_user(val, (int *)arg))
3024 return -EFAULT;
3025#else
3026 get_user_ret(val, (int *)arg, -EFAULT);
3027#endif
3028 if (val == DSP_BIND_QUERY) {
3029 val = DSP_BIND_FRONT;
3030 if (s->status & DO_SPDIF_OUT)
3031 val |= DSP_BIND_SPDIF;
3032 else {
3033 if (s->curr_channels == 4)
3034 val |= DSP_BIND_SURR;
3035 if (s->curr_channels > 4)
3036 val |= DSP_BIND_CENTER_LFE;
3037 }
3038 } else {
3039 if (file->f_mode & FMODE_READ) {
3040 stop_adc(s);
3041 s->dma_adc.ready = 0;
3042 }
3043 if (file->f_mode & FMODE_WRITE) {
3044 stop_dac(s);
3045 s->dma_dac.ready = 0;
3046 if (val & DSP_BIND_SPDIF) {
3047 set_spdifout(s, s->ratedac);
3048 set_dac_channels(s, s->fmt & (CM_CFMT_STEREO << CM_CFMT_SHIFT_CH0) ? 2 : 1);
3049 if (!(s->status & DO_SPDIF_OUT))
3050 val &= ~DSP_BIND_SPDIF;
3051 } else {
3052 int channels;
3053 int mask;
3054
3055 mask = val & (DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE);
3056 switch (mask) {
3057 case DSP_BIND_FRONT:
3058 channels = 2;
3059 break;
3060 case DSP_BIND_FRONT|DSP_BIND_SURR:
3061 channels = 4;
3062 break;
3063 case DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE:
3064 channels = 6;
3065 break;
3066 default:
3067 channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_SHIFT_CH0) ? 2 : 1;
3068 break;
3069 }
3070 set_dac_channels(s, channels);
3071 }
3072 }
3073 }
3074 return put_user(val, (int *)arg);
3075
3076 case SOUND_PCM_WRITE_FILTER:
3077 case SNDCTL_DSP_MAPINBUF:
3078 case SNDCTL_DSP_MAPOUTBUF:
3079 case SNDCTL_DSP_SETSYNCRO:
3080 return -EINVAL;
3081
3082 }
3083 return mixer_ioctl(s, cmd, arg);
3084}
3085
3086__static__ int cm_open(struct inode *inode, struct file *file)
3087{
3088 unsigned long flags;
3089 int minor = MINOR(inode->i_rdev);
3090 struct cm_state *s = devs;
3091 unsigned char fmtm = ~0, fmts = 0;
3092
3093 while (s && ((s->dev_audio ^ minor) & ~0xf))
3094 s = s->next;
3095 if (!s)
3096 return -ENODEV;
3097
3098dprintf(("cm_open(%d, %d): capability=%x, status=%x",
3099 s->audio_open_count[0], s->audio_open_count[1], s->capability, s->status));
3100
3101 VALIDATE_STATE(s);
3102
3103#ifdef TARGET_OS2
3104 down(&s->open_sem);
3105 file->private_data = kmalloc(sizeof(struct cm_state *), GFP_KERNEL);
3106 AUDIO_DEV_PTR(file->private_data) = s;
3107
3108 if( file->f_mode & FMODE_READ ) {
3109 if( s->open_mode & file->f_mode ) stop_adc(s);
3110
3111 spin_lock_irqsave(&s->lock, flags);
3112 s->curr_streamid[0] = file->private_data;
3113 s->audio_open_count[0]++;
3114 spin_unlock_irqrestore(&s->lock, flags);
3115 }
3116
3117 if( file->f_mode & FMODE_WRITE ) {
3118 if( s->open_mode & file->f_mode ) stop_dac(s);
3119
3120 spin_lock_irqsave(&s->lock, flags);
3121 s->curr_streamid[1] = file->private_data;
3122 s->audio_open_count[1]++;
3123 spin_unlock_irqrestore(&s->lock, flags);
3124 }
3125
3126#else
3127 file->private_data = s;
3128
3129 /* wait for device to become free */
3130 down(&s->open_sem);
3131 while (s->open_mode & file->f_mode) {
3132 if (file->f_flags & O_NONBLOCK) {
3133 up(&s->open_sem);
3134 return -EBUSY;
3135 }
3136 up(&s->open_sem);
3137 interruptible_sleep_on(&s->open_wait);
3138 if (signal_pending(current))
3139 return -ERESTARTSYS;
3140 down(&s->open_sem);
3141 }
3142#endif
3143
3144 if (file->f_mode & FMODE_READ) {
3145 fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_SHIFT_CH1);
3146 if ((minor & 0xf) == SND_DEV_DSP16)
3147 fmts |= CM_CFMT_16BIT << CM_CFMT_SHIFT_CH1;
3148 s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
3149 set_adc_rate(s, 8000);
3150 }
3151
3152 if (file->f_mode & FMODE_WRITE) {
3153 fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_SHIFT_CH0);
3154 if ((minor & 0xf) == SND_DEV_DSP16)
3155 fmts |= CM_CFMT_16BIT << CM_CFMT_SHIFT_CH0;
3156 s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
3157
3158 // clear previous multichannel, spdif, ac3 state
3159 set_spdifout(s, 0);
3160 if (s->deviceid >= PCI_DEVICE_ID_CMEDIA_CM8738) {
3161 set_ac3(s, 0);
3162 set_dac_channels(s, 1);
3163 }
3164 set_dac_rate(s, 8000);
3165 }
3166 set_fmt(s, fmtm, fmts);
3167 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
3168 up(&s->open_sem);
3169#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
3170 MOD_INC_USE_COUNT;
3171#endif
3172 return 0;
3173}
3174
3175__static__ int cm_release(struct inode *inode, struct file *file)
3176{
3177 unsigned long flags;
3178 struct cm_state *s = AUDIO_DEV_PTR(file->private_data);
3179
3180dprintf(("cm_release(%d, %d)", s->audio_open_count[0], s->audio_open_count[1]));
3181
3182 VALIDATE_STATE(s);
3183#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3184 lock_kernel();
3185#endif
3186
3187
3188#ifdef TARGET_OS2
3189dprintf(("RELEASE(%d): %x (%x)", s->audio_open_count[1], file->private_data, s->curr_streamid[1]));
3190
3191 kfree(file->private_data);
3192 file->private_data = NULL;
3193
3194 spin_lock_irqsave(&s->lock, flags);
3195
3196 if( file->f_mode & FMODE_READ ) {
3197 if( --s->audio_open_count[0] ) {
3198 spin_unlock_irqrestore(&s->lock, flags); return 0;
3199 }
3200
3201 s->curr_streamid[0] = NULL;
3202 }
3203
3204 if( file->f_mode & FMODE_WRITE ) {
3205 if( --s->audio_open_count[1] ) {
3206 spin_unlock_irqrestore(&s->lock, flags); return 0;
3207 }
3208
3209 s->curr_streamid[1] = NULL;
3210 }
3211
3212 spin_unlock_irqrestore(&s->lock, flags);
3213#else
3214 if (file->f_mode & FMODE_WRITE)
3215 drain_dac(s, file->f_flags & O_NONBLOCK);
3216#endif
3217
3218dprintf(("RELEASE: SHUTDOWN"));
3219
3220 down(&s->open_sem);
3221 if (file->f_mode & FMODE_WRITE) {
3222 stop_dac(s);
3223#ifndef FIXEDDMA
3224 dealloc_dmabuf(&s->dma_dac);
3225 if (s->status & DO_DUAL_DAC)
3226 dealloc_dmabuf(&s->dma_adc);
3227#endif
3228 if (s->status & DO_MULTI_CH)
3229 set_dac_channels(s, 0);
3230 if (s->status & DO_AC3)
3231 set_ac3(s, 0);
3232 if (s->status & DO_SPDIF_OUT)
3233 set_spdifout(s, 0);
3234
3235 s->ratedac = 0;
3236 }
3237 if (file->f_mode & FMODE_READ) {
3238 stop_adc(s);
3239#ifndef FIXEDDMA
3240 dealloc_dmabuf(&s->dma_adc);
3241#endif
3242
3243 s->rateadc = 0;
3244 }
3245 s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
3246 up(&s->open_sem);
3247 wake_up(&s->open_wait);
3248#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3249 unlock_kernel();
3250#else
3251 MOD_DEC_USE_COUNT;
3252#endif
3253 return 0;
3254}
3255
3256#ifndef TARGET_OS2
3257 static /*const*/ struct file_operations cm_audio_fops = {
3258 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3259 owner: THIS_MODULE,
3260 #endif
3261 llseek: cm_llseek,
3262 read: cm_read,
3263 write: cm_write,
3264 poll: cm_poll,
3265 ioctl: cm_ioctl,
3266 mmap: cm_mmap,
3267 open: cm_open,
3268 release: cm_release,
3269 };
3270#else
3271 static /*const*/ struct file_operations cm_audio_fops = {
3272 cm_llseek, // llseek
3273 cm_read, // read
3274 cm_write, // write
3275 NULL, // readdir
3276 cm_poll, // poll
3277 cm_ioctl, // ioctl
3278 cm_mmap, // mmap
3279 cm_open, // open
3280 NULL, // flush
3281 cm_release // release
3282 };
3283
3284#endif
3285
3286
3287#ifdef CONFIG_SOUND_CMPCI_MIDI
3288/* --------------------------------------------------------------------- */
3289
3290__static__ ssize_t cm_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
3291{
3292 struct cm_state *s = (struct cm_state *)file->private_data;
3293#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3294 DECLARE_WAITQUEUE(wait, current);
3295#endif
3296 ssize_t ret;
3297 unsigned long flags;
3298 unsigned ptr;
3299 int cnt;
3300
3301dprintf(("cm_midi_read"));
3302
3303 VALIDATE_STATE(s);
3304 if (ppos != &file->f_pos)
3305 return -ESPIPE;
3306 if (!access_ok(VERIFY_WRITE, buffer, count))
3307 return -EFAULT;
3308 ret = 0;
3309#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3310 add_wait_queue(&s->midi.iwait, &wait);
3311#endif
3312 while (count > 0) {
3313 spin_lock_irqsave(&s->lock, flags);
3314 ptr = s->midi.ird;
3315 cnt = MIDIINBUF - ptr;
3316 if (s->midi.icnt < cnt)
3317 cnt = s->midi.icnt;
3318 spin_unlock_irqrestore(&s->lock, flags);
3319 if (cnt > count)
3320 cnt = count;
3321 if (cnt <= 0) {
3322 if (file->f_flags & O_NONBLOCK)
3323#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3324 {
3325 if (!ret)
3326 ret = -EAGAIN;
3327 break;
3328 }
3329 __set_current_state(TASK_INTERRUPTIBLE);
3330 schedule();
3331 if (signal_pending(current))
3332 {
3333 if (!ret)
3334 ret = -ERESTARTSYS;
3335 break;
3336 }
3337#else
3338 return ret ? ret : -EAGAIN;
3339 interruptible_sleep_on(&s->midi.iwait);
3340 if (signal_pending(current))
3341 return ret ? ret : -ERESTARTSYS;
3342#endif
3343 continue;
3344 }
3345 if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt))
3346#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3347 {
3348 if (!ret)
3349 ret = -EFAULT;
3350 break;
3351 }
3352#else
3353 return ret ? ret : -EFAULT;
3354#endif
3355 ptr = (ptr + cnt) % MIDIINBUF;
3356 spin_lock_irqsave(&s->lock, flags);
3357 s->midi.ird = ptr;
3358 s->midi.icnt -= cnt;
3359 spin_unlock_irqrestore(&s->lock, flags);
3360 count -= cnt;
3361 buffer += cnt;
3362 ret += cnt;
3363#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3364 break;
3365#endif
3366 }
3367#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3368 __set_current_state(TASK_RUNNING);
3369 remove_wait_queue(&s->midi.iwait, &wait);
3370#endif
3371 return ret;
3372}
3373
3374__static__ ssize_t cm_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
3375{
3376 struct cm_state *s = (struct cm_state *)file->private_data;
3377#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3378 DECLARE_WAITQUEUE(wait, current);
3379#endif
3380 ssize_t ret;
3381 unsigned long flags;
3382 unsigned ptr;
3383 int cnt;
3384
3385dprintf(("cm_midi_write"));
3386
3387 VALIDATE_STATE(s);
3388 if (ppos != &file->f_pos)
3389 return -ESPIPE;
3390 if (!access_ok(VERIFY_READ, buffer, count))
3391 return -EFAULT;
3392#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3393 if (count == 0)
3394 return 0;
3395#endif
3396 ret = 0;
3397#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3398 add_wait_queue(&s->midi.owait, &wait);
3399#endif
3400 while (count > 0) {
3401 spin_lock_irqsave(&s->lock, flags);
3402 ptr = s->midi.owr;
3403 cnt = MIDIOUTBUF - ptr;
3404 if (s->midi.ocnt + cnt > MIDIOUTBUF)
3405 cnt = MIDIOUTBUF - s->midi.ocnt;
3406 if (cnt <= 0)
3407 cm_handle_midi(s);
3408 spin_unlock_irqrestore(&s->lock, flags);
3409 if (cnt > count)
3410 cnt = count;
3411 if (cnt <= 0) {
3412 if (file->f_flags & O_NONBLOCK)
3413#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3414 {
3415 if (!ret)
3416 ret = -EAGAIN;
3417 break;
3418 }
3419 __set_current_state(TASK_INTERRUPTIBLE);
3420 schedule();
3421 if (signal_pending(current)) {
3422 if (!ret)
3423 ret = -ERESTARTSYS;
3424 break;
3425 }
3426#else
3427 return ret ? ret : -EAGAIN;
3428 interruptible_sleep_on(&s->midi.owait);
3429 if (signal_pending(current))
3430 return ret ? ret : -ERESTARTSYS;
3431#endif
3432 continue;
3433 }
3434 if (copy_from_user(s->midi.obuf + ptr, buffer, cnt))
3435#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3436 {
3437 if (!ret)
3438 ret = -EFAULT;
3439 break;
3440 }
3441#else
3442 return ret ? ret : -EFAULT;
3443#endif
3444 ptr = (ptr + cnt) % MIDIOUTBUF;
3445 spin_lock_irqsave(&s->lock, flags);
3446 s->midi.owr = ptr;
3447 s->midi.ocnt += cnt;
3448 spin_unlock_irqrestore(&s->lock, flags);
3449 count -= cnt;
3450 buffer += cnt;
3451 ret += cnt;
3452 spin_lock_irqsave(&s->lock, flags);
3453 cm_handle_midi(s);
3454 spin_unlock_irqrestore(&s->lock, flags);
3455 }
3456#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3457 __set_current_state(TASK_RUNNING);
3458 remove_wait_queue(&s->midi.owait, &wait);
3459#endif
3460 return ret;
3461}
3462
3463__static__ unsigned int cm_midi_poll(struct file *file, struct poll_table_struct *wait)
3464{
3465 struct cm_state *s = (struct cm_state *)file->private_data;
3466 unsigned long flags;
3467 unsigned int mask = 0;
3468
3469dprintf(("cm_midi_poll"));
3470
3471 VALIDATE_STATE(s);
3472 if (file->f_mode & FMODE_WRITE)
3473 poll_wait(file, &s->midi.owait, wait);
3474 if (file->f_mode & FMODE_READ)
3475 poll_wait(file, &s->midi.iwait, wait);
3476 spin_lock_irqsave(&s->lock, flags);
3477 if (file->f_mode & FMODE_READ) {
3478 if (s->midi.icnt > 0)
3479 mask |= POLLIN | POLLRDNORM;
3480 }
3481 if (file->f_mode & FMODE_WRITE) {
3482 if (s->midi.ocnt < MIDIOUTBUF)
3483 mask |= POLLOUT | POLLWRNORM;
3484 }
3485 spin_unlock_irqrestore(&s->lock, flags);
3486 return mask;
3487}
3488
3489__static__ int cm_midi_open(struct inode *inode, struct file *file)
3490{
3491 int minor = MINOR(inode->i_rdev);
3492 struct cm_state *s = devs;
3493 unsigned long flags;
3494
3495dprintf(("cm_midi_open"));
3496
3497 while (s && s->dev_midi != minor)
3498 s = s->next;
3499 if (!s)
3500 return -ENODEV;
3501 VALIDATE_STATE(s);
3502 file->private_data = s;
3503 /* wait for device to become free */
3504 down(&s->open_sem);
3505 while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
3506 if (file->f_flags & O_NONBLOCK) {
3507 up(&s->open_sem);
3508 return -EBUSY;
3509 }
3510 up(&s->open_sem);
3511 interruptible_sleep_on(&s->open_wait);
3512 if (signal_pending(current))
3513 return -ERESTARTSYS;
3514 down(&s->open_sem);
3515 }
3516 spin_lock_irqsave(&s->lock, flags);
3517 if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
3518 s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
3519 s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
3520 /* enable MPU-401 */
3521 maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 4);
3522 outb(0xff, s->iomidi+1); /* reset command */
3523 if (!(inb(s->iomidi+1) & 0x80))
3524 inb(s->iomidi);
3525 outb(0x3f, s->iomidi+1); /* uart command */
3526 if (!(inb(s->iomidi+1) & 0x80))
3527 inb(s->iomidi);
3528 s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
3529 init_timer(&s->midi.timer);
3530 s->midi.timer.expires = jiffies+1;
3531 s->midi.timer.data = (unsigned long)s;
3532 s->midi.timer.function = cm_midi_timer;
3533 add_timer(&s->midi.timer);
3534 }
3535 if (file->f_mode & FMODE_READ) {
3536 s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
3537 }
3538 if (file->f_mode & FMODE_WRITE) {
3539 s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
3540 }
3541 spin_unlock_irqrestore(&s->lock, flags);
3542 s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
3543 up(&s->open_sem);
3544 MOD_INC_USE_COUNT;
3545 return 0;
3546}
3547
3548__static__ int cm_midi_release(struct inode *inode, struct file *file)
3549{
3550 struct cm_state *s = (struct cm_state *)file->private_data;
3551#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3552 DECLARE_WAITQUEUE(wait, current);
3553#else
3554 struct wait_queue wait = { current, NULL };
3555#endif
3556 unsigned long flags;
3557 unsigned count, tmo;
3558
3559dprintf(("cm_midi_release"));
3560
3561 VALIDATE_STATE(s);
3562#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3563 lock_kernel();
3564#endif
3565
3566 if (file->f_mode & FMODE_WRITE) {
3567#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3568 __set_current_state(TASK_INTERRUPTIBLE);
3569#else
3570 current->state = TASK_INTERRUPTIBLE;
3571#endif
3572 add_wait_queue(&s->midi.owait, &wait);
3573 for (;;) {
3574 spin_lock_irqsave(&s->lock, flags);
3575 count = s->midi.ocnt;
3576 spin_unlock_irqrestore(&s->lock, flags);
3577 if (count <= 0)
3578 break;
3579 if (signal_pending(current))
3580 break;
3581 if (file->f_flags & O_NONBLOCK) {
3582 remove_wait_queue(&s->midi.owait, &wait);
3583#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3584 __set_current_state(TASK_RUNNING);
3585#else
3586 current->state = TASK_RUNNING;
3587#endif
3588 return -EBUSY;
3589 }
3590 tmo = (count * HZ) / 3100;
3591
3592 if (!schedule_timeout(tmo ? : 1) && tmo)
3593 printk(KERN_DEBUG "cm: midi timed out??\n");
3594 }
3595 remove_wait_queue(&s->midi.owait, &wait);
3596#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3597 __set_current_state(TASK_RUNNING);
3598#else
3599 current->state = TASK_RUNNING;
3600#endif
3601 }
3602 down(&s->open_sem);
3603 s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE);
3604 spin_lock_irqsave(&s->lock, flags);
3605 if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
3606 del_timer(&s->midi.timer);
3607 outb(0xff, s->iomidi+1); /* reset command */
3608 if (!(inb(s->iomidi+1) & 0x80))
3609 inb(s->iomidi);
3610 /* disable MPU-401 */
3611 maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~4, 0);
3612 }
3613 spin_unlock_irqrestore(&s->lock, flags);
3614 up(&s->open_sem);
3615 wake_up(&s->open_wait);
3616#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3617 unlock_kernel();
3618#else
3619 MOD_DEC_USE_COUNT;
3620#endif
3621 return 0;
3622}
3623
3624#ifndef TARGET_OS2
3625 static /*const*/ struct file_operations cm_midi_fops = {
3626 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3627 owner: THIS_MODULE,
3628 #endif
3629 llseek: cm_llseek,
3630 read: cm_midi_read,
3631 write: cm_midi_write,
3632 poll: cm_midi_poll,
3633 open: cm_midi_open,
3634 release: cm_midi_release,
3635 };
3636#else
3637 static /*const*/ struct file_operations cm_midi_fops = {
3638 cm_llseek, // llseek
3639 cm_midi_read, // read
3640 cm_midi_write, // write
3641 NULL, // readdir
3642 cm_midi_poll, // poll
3643 NULL, // ioctl
3644 NULL, // mmap
3645 cm_midi_open, // open
3646 NULL, // flush
3647 cm_midi_release // release
3648 };
3649#endif
3650
3651#endif
3652
3653/* --------------------------------------------------------------------- */
3654
3655#ifdef CONFIG_SOUND_CMPCI_FM
3656__static__ int cm_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
3657{
3658 static const unsigned char op_offset[18] = {
3659 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
3660 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
3661 0x10, 0x11, 0x12, 0x13, 0x14, 0x15
3662 };
3663 struct cm_state *s = (struct cm_state *)file->private_data;
3664 struct dm_fm_voice v;
3665 struct dm_fm_note n;
3666 struct dm_fm_params p;
3667 unsigned int io;
3668 unsigned int regb;
3669
3670dprintf(("cm_dmfm_ioctl: %x", cmd));
3671
3672 switch (cmd) {
3673 case FM_IOCTL_RESET:
3674 for (regb = 0xb0; regb < 0xb9; regb++) {
3675 outb(regb, s->iosynth);
3676 outb(0, s->iosynth+1);
3677 outb(regb, s->iosynth+2);
3678 outb(0, s->iosynth+3);
3679 }
3680 return 0;
3681
3682 case FM_IOCTL_PLAY_NOTE:
3683 if (copy_from_user(&n, (void *)arg, sizeof(n)))
3684 return -EFAULT;
3685 if (n.voice >= 18)
3686 return -EINVAL;
3687 if (n.voice >= 9) {
3688 regb = n.voice - 9;
3689 io = s->iosynth+2;
3690 } else {
3691 regb = n.voice;
3692 io = s->iosynth;
3693 }
3694 outb(0xa0 + regb, io);
3695 outb(n.fnum & 0xff, io+1);
3696 outb(0xb0 + regb, io);
3697 outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1);
3698 return 0;
3699
3700 case FM_IOCTL_SET_VOICE:
3701 if (copy_from_user(&v, (void *)arg, sizeof(v)))
3702 return -EFAULT;
3703 if (v.voice >= 18)
3704 return -EINVAL;
3705 regb = op_offset[v.voice];
3706 io = s->iosynth + ((v.op & 1) << 1);
3707 outb(0x20 + regb, io);
3708 outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) |
3709 ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1);
3710 outb(0x40 + regb, io);
3711 outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1);
3712 outb(0x60 + regb, io);
3713 outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1);
3714 outb(0x80 + regb, io);
3715 outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1);
3716 outb(0xe0 + regb, io);
3717 outb(v.waveform & 0x7, io+1);
3718 if (n.voice >= 9) {
3719 regb = n.voice - 9;
3720 io = s->iosynth+2;
3721 } else {
3722 regb = n.voice;
3723 io = s->iosynth;
3724 }
3725 outb(0xc0 + regb, io);
3726 outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) |
3727 (v.connection & 1), io+1);
3728 return 0;
3729
3730 case FM_IOCTL_SET_PARAMS:
3731 if (copy_from_user(&p, (void *)arg, sizeof(p)))
3732 return -EFAULT;
3733 outb(0x08, s->iosynth);
3734 outb((p.kbd_split & 1) << 6, s->iosynth+1);
3735 outb(0xbd, s->iosynth);
3736 outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) |
3737 ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->iosynth+1);
3738 return 0;
3739
3740 case FM_IOCTL_SET_OPL:
3741 outb(4, s->iosynth+2);
3742 outb(arg, s->iosynth+3);
3743 return 0;
3744
3745 case FM_IOCTL_SET_MODE:
3746 outb(5, s->iosynth+2);
3747 outb(arg & 1, s->iosynth+3);
3748 return 0;
3749
3750 default:
3751 return -EINVAL;
3752 }
3753}
3754
3755__static__ int cm_dmfm_open(struct inode *inode, struct file *file)
3756{
3757 int minor = MINOR(inode->i_rdev);
3758 struct cm_state *s = devs;
3759
3760dprintf(("cm_dmfm_open"));
3761
3762 while (s && s->dev_dmfm != minor)
3763 s = s->next;
3764 if (!s)
3765 return -ENODEV;
3766 VALIDATE_STATE(s);
3767 file->private_data = s;
3768 /* wait for device to become free */
3769 down(&s->open_sem);
3770 while (s->open_mode & FMODE_DMFM) {
3771 if (file->f_flags & O_NONBLOCK) {
3772 up(&s->open_sem);
3773 return -EBUSY;
3774 }
3775 up(&s->open_sem);
3776 interruptible_sleep_on(&s->open_wait);
3777 if (signal_pending(current))
3778 return -ERESTARTSYS;
3779 down(&s->open_sem);
3780 }
3781 /* init the stuff */
3782 outb(1, s->iosynth);
3783 outb(0x20, s->iosynth+1); /* enable waveforms */
3784 outb(4, s->iosynth+2);
3785 outb(0, s->iosynth+3); /* no 4op enabled */
3786 outb(5, s->iosynth+2);
3787 outb(1, s->iosynth+3); /* enable OPL3 */
3788 s->open_mode |= FMODE_DMFM;
3789 up(&s->open_sem);
3790 MOD_INC_USE_COUNT;
3791 return 0;
3792}
3793
3794__static__ int cm_dmfm_release(struct inode *inode, struct file *file)
3795{
3796 struct cm_state *s = (struct cm_state *)file->private_data;
3797 unsigned int regb;
3798
3799dprintf(("cm_dmfm_release"));
3800
3801 VALIDATE_STATE(s);
3802#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3803 lock_kernel();
3804#endif
3805 down(&s->open_sem);
3806 s->open_mode &= ~FMODE_DMFM;
3807 for (regb = 0xb0; regb < 0xb9; regb++) {
3808 outb(regb, s->iosynth);
3809 outb(0, s->iosynth+1);
3810 outb(regb, s->iosynth+2);
3811 outb(0, s->iosynth+3);
3812 }
3813 up(&s->open_sem);
3814 wake_up(&s->open_wait);
3815#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3816 unlock_kernel();
3817#else
3818 MOD_DEC_USE_COUNT;
3819#endif
3820 return 0;
3821}
3822
3823#ifndef TARGET_OS2
3824 static /*const*/ struct file_operations cm_dmfm_fops = {
3825 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3826 owner: THIS_MODULE,
3827 #endif
3828 llseek: cm_llseek,
3829 ioctl: cm_dmfm_ioctl,
3830 open: cm_dmfm_open,
3831 release: cm_dmfm_release,
3832 };
3833
3834#else
3835 static /*const*/ struct file_operations cm_mixer_fops = {
3836 cm_llseek, // llseek
3837 NULL, // read
3838 NULL, // write
3839 NULL, // readdir
3840 NULL, // poll
3841 cm_dmfm_ioctl, // ioctl
3842 NULL, // mmap
3843 cm_dmfm_open, // open
3844 NULL, // flush
3845 cm_dmfm_release // release
3846 };
3847
3848#endif
3849
3850#endif /* CONFIG_SOUND_CMPCI_FM */
3851
3852/* --------------------------------------------------------------------- */
3853
3854/* maximum number of devices */
3855
3856//Rudi:
3857//#define NR_DEVICE 5
3858
3859#define NR_DEVICE 1
3860
3861
3862#if 0
3863static int reverb[NR_DEVICE] = { 0, };
3864
3865static int wavetable[NR_DEVICE] = { 0, };
3866#endif
3867
3868/* --------------------------------------------------------------------- */
3869
3870static struct initvol {
3871 int mixch;
3872 int vol;
3873} initvol[] __initdata = {
3874 { SOUND_MIXER_WRITE_CD, 0x0000 },
3875 { SOUND_MIXER_WRITE_LINE, 0x0000 },
3876 { SOUND_MIXER_WRITE_MIC, 0x0000 },
3877 { SOUND_MIXER_WRITE_LINE1, 0x0000 },
3878 { SOUND_MIXER_WRITE_SYNTH, 0x0000 },
3879 { SOUND_MIXER_WRITE_VOLUME, 0x4f4f },
3880 { SOUND_MIXER_WRITE_PCM, 0x0000 },
3881 { SOUND_MIXER_WRITE_SPEAKER, 0x0000 }
3882};
3883
3884/* check chip version and capability */
3885__static__ int query_chip(struct cm_state *s)
3886{
3887 int ChipVersion = -1;
3888 unsigned char RegValue;
3889
3890 // check reg 0Ch, bit 24-31
3891 RegValue = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 3);
3892 if (RegValue == 0) {
3893 // check reg 08h, bit 24-28
3894 RegValue = inb(s->iobase + CODEC_CMI_CHFORMAT + 3) & 0x1f;
3895 if (RegValue == 0) {
3896 ChipVersion = 33;
3897 s->capability |= CAN_DUAL_DAC | CAN_AC3_SW;
3898 } else {
3899 ChipVersion = 37;
3900 s->capability |= CAN_DUAL_DAC | CAN_AC3_HW;
3901 }
3902
3903 s->max_channels = 4;
3904 } else {
3905 // check reg 0Ch, bit 26
3906 if (RegValue & (1 << (26-24))) {
3907 ChipVersion = 39; // 4 or 6 channels
3908 s->max_channels = ( RegValue & (1 << (24-24)) ) ? 6 : 4;
3909 } else {
3910 ChipVersion = 55; // 5 channels
3911 s->max_channels = 6;
3912 }
3913
3914 s->capability |= CAN_DUAL_DAC |
3915#ifndef FORCE_DUAL_DAC
3916 CAN_MULTI_CH_HW |
3917#endif
3918 CAN_AC3_HW;
3919 }
3920
3921
3922// AC3HACK
3923s->capability = (s->capability & ~CAN_AC3_HW) | CAN_AC3_SW;
3924
3925
3926
3927 // still limited to number of speakers
3928 if (s->max_channels > s->speakers)
3929 s->max_channels = s->speakers;
3930
3931 return ChipVersion;
3932}
3933
3934#if defined(CONFIG_SOUND_CMPCI_MIDI) || defined(TARGET_OS2)
3935static int mpu_io = CONFIG_SOUND_CMPCI_MPUIO;
3936#else
3937static int mpu_io = 0;
3938#endif
3939
3940#ifdef CONFIG_SOUND_CMPCI_FM
3941static int fm_io = CONFIG_SOUND_CMPCI_FMIO;
3942#else
3943 #ifdef TARGET_OS2
3944 static int fm_io = CONFIG_SOUND_CMPCI_FMIO;
3945 #else
3946 static int fm_io = 0;
3947 #endif
3948#endif
3949
3950#ifdef CONFIG_SOUND_CMPCI_SPDIFINVERSE
3951/*static*/ int spdif_inverse = 1;
3952#else
3953/*static*/ int spdif_inverse = 0;
3954#endif
3955
3956#ifdef CONFIG_SOUND_CMPCI_SPDIFLOOP
3957/*static*/ int spdif_loop = 1;
3958#else
3959/*static*/ int spdif_loop = 0;
3960#endif
3961
3962#ifdef CONFIG_SOUND_CMPCI_SPEAKERS
3963static int speakers = CONFIG_SOUND_CMPCI_SPEAKERS;
3964#else
3965static int speakers = 2;
3966#endif
3967
3968#ifdef CONFIG_SOUND_CMPCI_LINE_REAR
3969/*static*/ int use_line_as_rear = 1;
3970#else
3971/*static*/ int use_line_as_rear = 0;
3972#endif
3973
3974#ifdef CONFIG_SOUND_CMPCI_LINE_BASS
3975/*static*/ int use_line_as_bass = 1;
3976#else
3977/*static*/ int use_line_as_bass = 0;
3978#endif
3979
3980#ifdef CONFIG_SOUND_CMPCI_PCTEL
3981static int modem = 1;
3982#else
3983static int modem = 0;
3984#endif
3985
3986#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
3987/*static*/ int joystick = 1;
3988#else
3989/*static*/ int joystick = 0;
3990#endif
3991
3992#ifdef CONFIG_SOUND_CMPCI_SPDIF5V
3993/*static*/ int spdif_5v = 1;
3994/*static*/ int spdif_src = 0;
3995#else
3996/*static*/ int spdif_5v = 0;
3997/*static*/ int spdif_src = 1;
3998#endif
3999
4000int spdif_copyright = 0;
4001int spdif_enable = 0;
4002int mic_boost = 0;
4003
4004
4005MODULE_PARM(mpu_io, "i");
4006MODULE_PARM(fm_io, "i");
4007MODULE_PARM(spdif_inverse, "i");
4008MODULE_PARM(spdif_loop, "i");
4009MODULE_PARM(speakers, "i");
4010MODULE_PARM(use_line_as_rear, "i");
4011MODULE_PARM(use_line_as_bass, "i");
4012MODULE_PARM(modem, "i");
4013MODULE_PARM(joystick, "i");
4014MODULE_PARM_DESC(mpu_io, "(0x330, 0x320, 0x310, 0x300) Base of MPU-401, 0 to disable");
4015MODULE_PARM_DESC(fm_io, "(0x388, 0x3C8, 0x3E0) Base of OPL3, 0 to disable");
4016MODULE_PARM_DESC(spdif_inverse, "(1/0) Invert S/PDIF-in signal");
4017MODULE_PARM_DESC(spdif_loop, "(1/0) Route S/PDIF-in to S/PDIF-out directly");
4018MODULE_PARM_DESC(speakers, "(2-6) Number of speakers you connect");
4019MODULE_PARM_DESC(use_line_as_rear, "(1/0) Use line-in jack as rear-out");
4020MODULE_PARM_DESC(use_line_as_bass, "(1/0) Use line-in jack as bass/center");
4021MODULE_PARM_DESC(modem, "(1/0) Use HSP modem, still need PCTel modem driver");
4022MODULE_PARM_DESC(joystick, "(1/0) Enable joystick interface, still need joystick driver");
4023
4024
4025void initialize_chip(struct pci_dev *pcidev)
4026{
4027 struct cm_state *s;
4028 int i, val;
4029#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
4030 mm_segment_t fs;
4031#endif
4032#if defined(CONFIG_SOUND_CMPCI_MIDI) || defined(TARGET_OS2)
4033 unsigned char reg_mask = 0;
4034#endif
4035 struct {
4036 unsigned short deviceid;
4037 char *devicename;
4038 } devicetable[] =
4039 {
4040 { PCI_DEVICE_ID_CMEDIA_CM8338A, "CM8338A" },
4041 { PCI_DEVICE_ID_CMEDIA_CM8338B, "CM8338B" },
4042 { PCI_DEVICE_ID_CMEDIA_CM8738, "CM8738" },
4043 { PCI_DEVICE_ID_CMEDIA_CM8738B, "CM8738B" },
4044 };
4045 char *devicename = "unknown";
4046 {
4047#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4048 if (pci_enable_device(pcidev))
4049 return;
4050#endif
4051 if (pcidev->irq == 0)
4052 return;
4053 if (!(s = kmalloc(sizeof(struct cm_state), GFP_KERNEL))) {
4054 printk(KERN_WARNING "cm: out of memory\n");
4055 return;
4056 }
4057 /* search device name */
4058 for (i = 0; i < sizeof(devicetable) / sizeof(devicetable[0]); i++) {
4059 if (devicetable[i].deviceid == pcidev->device)
4060 {
4061 devicename = devicetable[i].devicename;
4062 break;
4063 }
4064 }
4065
4066 memset(s, 0, sizeof(struct cm_state));
4067
4068#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
4069 init_waitqueue_head(&s->dma_adc.wait);
4070 init_waitqueue_head(&s->dma_dac.wait);
4071 init_waitqueue_head(&s->open_wait);
4072 init_waitqueue_head(&s->midi.iwait);
4073 init_waitqueue_head(&s->midi.owait);
4074 init_MUTEX(&s->open_sem);
4075#else
4076 init_waitqueue(&s->dma_adc.wait);
4077 init_waitqueue(&s->dma_dac.wait);
4078 init_waitqueue(&s->open_wait);
4079 init_waitqueue(&s->midi.iwait);
4080 init_waitqueue(&s->midi.owait);
4081 s->open_sem = MUTEX;
4082#endif
4083 spin_lock_init(&s->lock);
4084 s->magic = CM_MAGIC;
4085#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4086 s->iobase = pci_resource_start(pcidev, 0);
4087#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
4088 s->iobase = pcidev->resource[0].start;
4089#else
4090 s->iobase = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
4091#endif
4092
4093#ifndef TARGET_OS2
4094 /* range check */
4095 if (s->iobase == 0)
4096 return;
4097 if (speakers < 2)
4098 speakers = 2;
4099 else if (speakers > 6)
4100 speakers = 6;
4101#endif
4102
4103 s->iosynth = fm_io;
4104 s->iomidi = mpu_io;
4105 s->speakers = speakers;
4106 s->irq = pcidev->irq;
4107
4108#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4109 if (!request_region(s->iobase, CM_EXTENT_CODEC, "cmpci")) {
4110#else
4111 if (check_region(s->iobase, CM_EXTENT_CODEC)) {
4112#endif
4113 printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
4114 goto err_region5;
4115 }
4116#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
4117 request_region(s->iobase, CM_EXTENT_CODEC, "cmpci");
4118#endif
4119
4120
4121#if defined(CONFIG_SOUND_CMPCI_MIDI) || defined(TARGET_OS2)
4122 /* disable MPU-401 */
4123 maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0);
4124 if (s->iomidi) {
4125#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4126 if (!request_region(s->iomidi, CM_EXTENT_MIDI, "cmpci Midi")) {
4127#else
4128 if (check_region(s->iomidi, CM_EXTENT_MIDI)) {
4129#endif
4130 printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
4131 s->iomidi = 0;
4132 } else {
4133 /* set IO based at 0x330 */
4134 switch (s->iomidi) {
4135 case 0x330:
4136 reg_mask = 0x00;
4137 break;
4138 case 0x320:
4139 reg_mask = 0x20;
4140 break;
4141 case 0x310:
4142 reg_mask = 0x40;
4143 break;
4144 case 0x300:
4145 reg_mask = 0x60;
4146 break;
4147 default:
4148 s->iomidi = 0;
4149 break;
4150 }
4151
4152 /* enable MPU-401 */
4153 if (s->iomidi) {
4154 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x60, reg_mask);
4155//Rudi: enable on open ! maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x04);
4156
4157#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
4158 request_region(s->iomidi, CM_EXTENT_MIDI, "cmpci MPU");
4159#endif
4160 }
4161 }
4162 }
4163#endif
4164
4165
4166#if definded(CONFIG_SOUND_CMPCI_FM) || defined(TARGET_OS2)
4167 /* disable FM */
4168 maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
4169 if (s->iosynth) {
4170#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4171 if (!request_region(s->iosynth, CM_EXTENT_SYNTH, "cmpci FM")) {
4172#else
4173 if (check_region(s->iosynth, CM_EXTENT_SYNTH)) {
4174#endif
4175 printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
4176 s->iosynth = 0;
4177 } else {
4178 /* set IO based at 0x388 */
4179 switch (s->iosynth) {
4180 case 0x388:
4181 reg_mask = 0;
4182 break;
4183 case 0x3C8:
4184 reg_mask = 0x01;
4185 break;
4186 case 0x3E0:
4187 reg_mask = 0x02;
4188 break;
4189 case 0x3E8:
4190 reg_mask = 0x03;
4191 break;
4192 default:
4193 s->iosynth = 0;
4194 break;
4195 }
4196 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x03, reg_mask);
4197 /* enable FM */
4198 if (s->iosynth) {
4199 maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, 8);
4200#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
4201 request_region(s->iosynth, CM_EXTENT_SYNTH, "cmpci FM");
4202#endif
4203 }
4204 }
4205 }
4206#endif
4207 /* enable joystick */
4208 maskb(s->iobase + CODEC_CMI_FUNCTRL1,
4209 ~0x02, ( joystick ) ? 0x02 : 0x00);
4210
4211 /* initialize codec registers */
4212 outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2); /* disable ints */
4213 outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
4214
4215 /* reset mixer */
4216 wrmixer(s, DSP_MIX_DATARESETIDX, 0);
4217
4218 /* request irq */
4219 if (request_irq(s->irq, cm_interrupt, SA_SHIRQ, "cmpci", s)) {
4220 printk(KERN_ERR "cm: irq %u in use\n", s->irq);
4221 goto err_irq;
4222 }
4223 printk(KERN_INFO "cm: found %s adapter at io %#06x irq %u\n",
4224 devicename, s->iobase, s->irq);
4225 /* register devices */
4226 if ((s->dev_audio = register_sound_dsp(&cm_audio_fops, -1)) < 0)
4227 goto err_dev1;
4228 if ((s->dev_mixer = register_sound_mixer(&cm_mixer_fops, -1)) < 0)
4229 goto err_dev2;
4230#ifdef CONFIG_SOUND_CMPCI_MIDI
4231 if ((s->dev_midi = register_sound_midi(&cm_midi_fops, -1)) < 0)
4232 goto err_dev3;
4233#endif
4234#ifdef CONFIG_SOUND_CMPCI_FM
4235 if ((s->dev_dmfm = register_sound_special(&cm_dmfm_fops, 15 /* ?? */)) < 0)
4236 goto err_dev4;
4237#endif
4238
4239 pci_set_master(pcidev); /* enable bus mastering */
4240
4241 /* set mixer output */
4242 frobindir(s, DSP_MIX_OUTMIXIDX, 0x1f, 0x1f);
4243 enable_aux(s, 1, 0); // Rudi: enable aux in
4244 enable_aux(s, 0, 1); // Rudi: disable aux record
4245 enable_digital(s, 0, 0); // Rudi: disable SPDIF in (monitor)
4246 enable_digital(s, 0, 1); // Rudi: disable SPDIF record
4247
4248
4249#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
4250 fs = get_fs();
4251 set_fs(KERNEL_DS);
4252#endif
4253 /* set mixer input */
4254 val = SOUND_MASK_LINE | SOUND_MASK_SYNTH |// SOUND_MASK_PCM |
4255 SOUND_MASK_CD | SOUND_MASK_MIC | SOUND_MASK_LINE1;
4256
4257#if !defined(TARGET_OS2) || defined(KEE)
4258 mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
4259#else
4260 mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC,
4261 (unsigned long)__StackToFlat((unsigned long)&val));
4262#endif
4263 for (i = 0; i < sizeof(initvol) / sizeof(initvol[0]); i++) {
4264 val = initvol[i].vol;
4265#if !defined(TARGET_OS2) || defined(KEE)
4266 mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
4267#else
4268 mixer_ioctl(s, initvol[i].mixch,
4269 (unsigned long)__StackToFlat((unsigned long)&val));
4270#endif
4271 }
4272#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
4273 set_fs(fs);
4274#endif
4275
4276 /* use channel 0 for playback, channel 1 for record */
4277 maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0x01, 0x02);
4278
4279 s->deviceid = pcidev->device;
4280 if (pcidev->device >= PCI_DEVICE_ID_CMEDIA_CM8738) {
4281 /* chip version and hw capability check */
4282 s->chip_version = query_chip(s);
4283 printk(KERN_INFO "cm: chip version = 0%d\n", s->chip_version);
4284
4285#ifdef TARGET_OS2
4286 if( spdif_5v ) s->status |= DO_SPDIF_OUT_5V;
4287 if( spdif_src ) s->status |= DO_SPDIF_INPUT2;
4288 if( spdif_inverse ) s->status |= DO_SPDIF_INVERSE;
4289 if( spdif_copyright ) s->status |= DO_SPDIF_COPYRIGHT;
4290 if( spdif_loop ) s->status |= DO_SPDIF_LOOP;
4291 else if( spdif_enable ) s->status |= DO_SPDIF_OUT_ENABLE;
4292 if( mic_boost ) s->status |= DO_MIC_BOOST;
4293
4294 if( use_line_as_rear ) {
4295 s->capability |= CAN_LINE_AS_REAR;
4296 s->status |= DO_LINE_AS_REAR;
4297 }
4298
4299 if( use_line_as_bass && s->chip_version >= 39 ) {
4300 s->capability |= CAN_LINE_AS_BASS;
4301 s->status |= DO_LINE_AS_BASS;
4302 }
4303
4304 set_device_state(s);
4305
4306#else
4307 s->modem = modem;
4308 if (modem) {
4309 /* enable FLINKON and disable FLINKOFF */
4310 maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~0x40, 0x80);
4311 printk(KERN_INFO "cm: modem function supported\n");
4312 }
4313
4314 /* set SPDIF-in inverse before enable SPDIF loop */
4315 if (spdif_inverse) {
4316 /* turn on spdif-in inverse */
4317 maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 1);
4318 printk(KERN_INFO "cm: Inverse SPDIF-in\n");
4319 } else {
4320 /* turn off spdif-in inverse */
4321 maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~1, 0);
4322 }
4323
4324 /* enable SPDIF loop */
4325 if (spdif_loop) {
4326 s->status |= DO_SPDIF_LOOP;
4327 /* turn on spdif-in to spdif-out */
4328 maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x80);
4329 printk(KERN_INFO "cm: Enable SPDIF loop\n");
4330 } else {
4331 s->status &= ~DO_SPDIF_LOOP;
4332 /* turn off spdif-in to spdif-out */
4333 maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x80, 0);
4334 }
4335
4336 if (use_line_as_rear) {
4337 s->capability |= CAN_LINE_AS_REAR;
4338 s->status |= DO_LINE_AS_REAR;
4339 maskb(s->iobase + CODEC_CMI_MIXER1, ~0, 0x20);
4340 } else
4341 maskb(s->iobase + CODEC_CMI_MIXER1, ~0x20, 0);
4342
4343 if (s->chip_version >= 39) {
4344 if (use_line_as_bass) {
4345 s->capability |= CAN_LINE_AS_BASS;
4346 s->status |= DO_LINE_AS_BASS;
4347 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~0, 0x60);
4348 } else
4349 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~0x60, 0);
4350 }
4351#endif
4352
4353 // Rudi: enable 4 speaker mode (analog duplicate)
4354 if (s->speakers > 2)
4355 maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~0, 0x04);
4356 } else {
4357 /* 8338 will fall here */
4358 s->max_channels = 2;
4359 }
4360
4361 /* queue it for later freeing */
4362 s->next = devs;
4363 devs = s;
4364 return;
4365
4366#ifdef CONFIG_SOUND_CMPCI_FM
4367 unregister_sound_special(s->dev_dmfm);
4368 err_dev4:
4369#endif
4370#ifdef CONFIG_SOUND_CMPCI_MIDI
4371 unregister_sound_midi(s->dev_midi);
4372 err_dev3:
4373#endif
4374#if defined(CONFIG_SOUND_CMPCI_MIDI) || defined(CONFIG_SOUND_CMPCI_FM)
4375 unregister_sound_mixer(s->dev_mixer);
4376#endif
4377
4378 err_dev2:
4379 unregister_sound_dsp(s->dev_audio);
4380 err_dev1:
4381 printk(KERN_ERR "cm: cannot register misc device\n");
4382 free_irq(s->irq, s);
4383 err_irq:
4384#ifdef CONFIG_SOUND_CMPCI_FM
4385 if (s->iosynth) release_region(s->iosynth, CM_EXTENT_SYNTH);
4386#endif
4387#ifdef CONFIG_SOUND_CMPCI_MIDI
4388 if (s->iomidi) release_region(s->iomidi, CM_EXTENT_MIDI);
4389#endif
4390 release_region(s->iobase, CM_EXTENT_CODEC);
4391 err_region5:
4392#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4393 kfree(s);
4394#else
4395 kfree_s(s, sizeof(struct cm_state));
4396#endif
4397 }
4398
4399#if CONFIG_WAVETABLE
4400 if (!devs) {
4401 if (wavetable_mem)
4402 free_pages(wavetable_mem, 20-PAGE_SHIFT);
4403 return;
4404 }
4405#endif
4406 return;
4407}
4408
4409#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4410__static__ int __init init_cmpci(void)
4411#else
4412#ifdef MODULE
4413int __init init_module(void)
4414#else
4415int __init init_cmpci(void)
4416#endif
4417#endif
4418{
4419 struct pci_dev *pcidev = NULL;
4420 int index = 0;
4421
4422#ifdef CONFIG_PCI
4423 if (!pci_present()) /* No PCI bus in this machine! */
4424#endif
4425 return -ENODEV;
4426 printk(KERN_INFO "cm: version $Revision: 5.64 $ time " __TIME__ " " __DATE__ "\n");
4427#if CONFIG_WAVETABLE
4428 if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
4429 printk(KERN_INFO "cm: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
4430#endif
4431 while (index < NR_DEVICE && (
4432 (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B, pcidev)))) {
4433 initialize_chip(pcidev);
4434 index++;
4435 }
4436 while (index < NR_DEVICE && (
4437 (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, pcidev)))) {
4438 initialize_chip(pcidev);
4439 index++;
4440 }
4441 while (index < NR_DEVICE && (
4442 (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, pcidev)))) {
4443 initialize_chip(pcidev);
4444 index++;
4445 }
4446 while (index < NR_DEVICE && (
4447 (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, pcidev)))) {
4448 initialize_chip(pcidev);
4449 index++;
4450 }
4451 return 0;
4452}
4453
4454/* --------------------------------------------------------------------- */
4455
4456MODULE_AUTHOR("ChenLi Tien, cltien@cmedia.com.tw");
4457MODULE_DESCRIPTION("CM8x38 Audio Driver");
4458
4459#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4460__static__ void __exit cleanup_cmpci(void)
4461#else
4462void cleanup_module(void)
4463#endif
4464{
4465 struct cm_state *s;
4466
4467 while ((s = devs)) {
4468 devs = devs->next;
4469 outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2); /* disable ints */
4470 synchronize_irq();
4471 outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
4472 free_irq(s->irq, s);
4473#ifdef FIXEDDMA
4474 dealloc_dmabuf(&s->dma_dac);
4475 dealloc_dmabuf(&s->dma_adc);
4476#endif
4477
4478 /* reset mixer */
4479 wrmixer(s, DSP_MIX_DATARESETIDX, 0);
4480
4481 release_region(s->iobase, CM_EXTENT_CODEC);
4482#ifdef CONFIG_SOUND_CMPCI_MIDI
4483 if (s->iomidi) release_region(s->iomidi, CM_EXTENT_MIDI);
4484#endif
4485#ifdef CONFIG_SOUND_CMPCI_FM
4486 if (s->iosynth) release_region(s->iosynth, CM_EXTENT_SYNTH);
4487#endif
4488 unregister_sound_dsp(s->dev_audio);
4489 unregister_sound_mixer(s->dev_mixer);
4490#ifdef CONFIG_SOUND_CMPCI_MIDI
4491 unregister_sound_midi(s->dev_midi);
4492#endif
4493#ifdef CONFIG_SOUND_CMPCI_FM
4494 unregister_sound_special(s->dev_dmfm);
4495#endif
4496#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4497 kfree(s);
4498#else
4499 kfree_s(s, sizeof(struct cm_state));
4500#endif
4501 }
4502#if CONFIG_WAVETABLE
4503 if (wavetable_mem)
4504 free_pages(wavetable_mem, 20-PAGE_SHIFT);
4505#endif
4506 printk(KERN_INFO "cm: unloading\n");
4507}
4508
4509#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4510module_init(init_cmpci);
4511module_exit(cleanup_cmpci);
4512#endif
4513
4514
4515
4516#ifdef TARGET_OS2
4517
4518void set_device_state(struct cm_state *s)
4519{
4520 unsigned long val, flags;
4521
4522 spin_lock_irqsave(&s->lock, flags);
4523
4524 // line as rear
4525 if( s->capability & CAN_LINE_AS_REAR ) {
4526 maskb(s->iobase + CODEC_CMI_MIXER1,
4527 ~0x20, ( s->status & DO_LINE_AS_REAR ) ? 0x20 : 0x00);
4528 }
4529
4530 // line as bass
4531 if( s->capability & CAN_LINE_AS_BASS ) {
4532 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1,
4533 ~0x60, ( s->status & DO_LINE_AS_BASS ) ? 0x60 : 0x00);
4534 }
4535
4536 // S/P DIF inverse
4537 if (s->chip_version >= 39) {
4538 maskb(s->iobase + CODEC_CMI_CHFORMAT,
4539 ~0x80, ( s->status & DO_SPDIF_INVERSE ) ? 0x80 : 0x00);
4540 } else {
4541 maskb(s->iobase + CODEC_CMI_CHFORMAT + 2,
4542 ~0x01, ( s->status & DO_SPDIF_INVERSE ) ? 0x00 : 0x01);
4543 }
4544
4545 // S/P DIF copyright
4546 maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2,
4547 ~0x40, ( s->status & DO_SPDIF_COPYRIGHT ) ? 0x40 : 0x00);
4548
4549 // S/P DIF loop (external)
4550 maskb(s->iobase + CODEC_CMI_FUNCTRL1,
4551 ~0x80, ( s->status & DO_SPDIF_LOOP ) ? 0x80 : 0x00);
4552
4553 // S/P DIF output level and input source
4554 val = 0;
4555 if( s->status & DO_POWER_DOWN ) val |= 0x80000000;
4556 if( s->status & DO_SPDIF_INPUT2 ) val |= 0x00000100;
4557 if( !(s->status & DO_SPDIF_OUT_5V) ) val |= 0x02000000;
4558 maskl(s->iobase + CODEC_CMI_MISC_CTRL, ~0x82000100, val);
4559
4560 // S/P DIF monitor
4561 if( !(s->status & DO_SPDIF_OUT) ) {
4562 enable_digital(s, s->status & DO_SPDIF_MONITOR, 0);
4563 }
4564
4565 // Mic boost
4566 maskb(s->iobase + CODEC_CMI_MIXER2,
4567 ~0x01, ( s->status & DO_MIC_BOOST ) ? 0x00 : 0x01);
4568 // Mic record boost
4569 frobindir(s, CODEC_CMI_EXT_REG,
4570 ~0x01, ( s->status & DO_MIC_BOOST ) ? 0x01 : 0x00);
4571
4572
4573 spin_unlock_irqrestore(&s->lock, flags);
4574
4575 if( !(s->status & DO_DUAL_DAC) ) set_spdifout(s, s->ratedac);
4576}
4577
4578
4579unsigned long OSS32_DevEscape(unsigned long uChipNo, unsigned long uCommand,
4580 unsigned long uParam1, unsigned long uParam2)
4581{
4582 struct cm_state *s = devs;
4583
4584 while( s ) {
4585 if( uChipNo-- == 0 )
4586 switch( uCommand ) {
4587 case 0x00: return s->deviceid | (PCI_VENDOR_ID_CMEDIA << 16);
4588 case 0x01: return s->iobase;
4589 case 0x02: return s->irq;
4590 case 0x03: return s->chip_version;
4591 case 0x04: return s->capability;
4592 case 0xff: if( uParam1 | uParam2 ) {
4593 s->status = (s->status & ~uParam2) | uParam1;
4594 set_device_state(s);
4595 }
4596 return s->status;
4597
4598 default: return -1;
4599 }
4600 s = s->next;
4601 }
4602
4603 return -1;
4604}
4605
4606unsigned long OSS32_StreamMidiWrite(unsigned long streamid,
4607 unsigned long midiByte)
4608{
4609 struct cm_state *s = (struct cm_state *)streamid;
4610
4611 if( !(inb(s->iomidi+1) & 0x40) )
4612 {
4613 outb((unsigned char)midiByte, s->iomidi); return 1;
4614 }
4615
4616 return 0;
4617}
4618
4619unsigned long OSS32_StreamMidiRead(unsigned long streamid,
4620 char near *buffer, unsigned long bufsize)
4621{
4622 struct cm_state *s = (struct cm_state *)streamid;
4623 unsigned long count = 0;
4624
4625 while( !(inb(s->iomidi+1) & 0x80) && count < bufsize )
4626 {
4627 buffer[count++] = inb(s->iomidi);
4628 }
4629
4630 return count;
4631}
4632
4633//void init_timer(struct timer_list *t) {};
4634
4635//void add_timer(struct timer_list *t) {};
4636
4637//void del_timer(struct timer_list *t) {};
4638
4639#endif
4640
4641
Note: See TracBrowser for help on using the repository browser.