1 /*********************************************************************
3 * Turtle Beach MultiSound Sound Card Driver for Linux
4 * Linux 2.0/2.2 Version
6 * msnd_pinnacle.c / msnd_classic.c
8 * -- If MSND_CLASSIC is defined:
10 * -> driver for Turtle Beach Classic/Monterey/Tahiti
14 * -> driver for Turtle Beach Pinnacle/Fiji
16 * Copyright (C) 1998 Andrew Veliath
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 * $Id: msnd_pinnacle.c,v 1.8 1998/08/06 21:06:14 andrewtv Exp $
34 ********************************************************************/
36 #include <linux/config.h>
37 #include <linux/version.h>
38 #if LINUX_VERSION_CODE < 0x020101
41 #include <linux/module.h>
42 #include <linux/malloc.h>
43 #include <linux/types.h>
44 #include <linux/delay.h>
46 # include <linux/init.h>
48 #include "sound_config.h"
49 #include "sound_firmware.h"
55 # include "msnd_classic.h"
56 # define LOGNAME "msnd_classic"
58 # include "msnd_pinnacle.h"
59 # define LOGNAME "msnd_pinnacle"
62 #define DEVNAME dev.name
63 #define MIXERMINOR dev.mixer_minor
64 #define DSPMINOR dev.dsp_minor
69 static char *dspini
, *permini
;
70 static int sizeof_dspini
, sizeof_permini
;
73 static void reset_play_queue(void)
78 msnd_fifo_make_empty(&dev
.DAPF
);
80 dev
.DAPQ
->wTail
= PCTODSP_OFFSET(2 * DAPQ_STRUCT_SIZE
);
81 dev
.CurDAQD
= (LPDAQD
)(dev
.base
+ 1 * DAPQ_DATA_BUFF
);
82 outb(HPBLKSEL_0
, dev
.io
+ HP_BLKS
);
83 memset_io(dev
.base
, 0, DAP_BUFF_SIZE
* 3);
85 for (n
= 0, lpDAQ
= dev
.CurDAQD
; n
< 3; ++n
, ++lpDAQ
) {
87 writew(PCTODSP_BASED((DWORD
)(DAP_BUFF_SIZE
* n
)), &lpDAQ
->wStart
);
88 writew(DAP_BUFF_SIZE
, &lpDAQ
->wSize
);
89 writew(1, &lpDAQ
->wFormat
);
90 writew(dev
.sample_size
, &lpDAQ
->wSampleSize
);
91 writew(dev
.channels
, &lpDAQ
->wChannels
);
92 writew(dev
.sample_rate
, &lpDAQ
->wSampleRate
);
93 writew(HIMT_PLAY_DONE
* 0x100 + n
, &lpDAQ
->wIntMsg
);
94 writew(n
+ 1, &lpDAQ
->wFlags
);
101 static void reset_record_queue(void)
106 msnd_fifo_make_empty(&dev
.DARF
);
108 dev
.DARQ
->wTail
= PCTODSP_OFFSET(2 * DARQ_STRUCT_SIZE
);
109 dev
.CurDARQD
= (LPDAQD
)(dev
.base
+ 1 * DARQ_DATA_BUFF
);
110 outb(HPBLKSEL_1
, dev
.io
+ HP_BLKS
);
111 memset_io(dev
.base
, 0, DAR_BUFF_SIZE
* 3);
112 outb(HPBLKSEL_0
, dev
.io
+ HP_BLKS
);
114 for (n
= 0, lpDAQ
= dev
.CurDARQD
; n
< 3; ++n
, ++lpDAQ
) {
116 writew(PCTODSP_BASED((DWORD
)(DAR_BUFF_SIZE
* n
)) + 0x4000, &lpDAQ
->wStart
);
117 writew(DAR_BUFF_SIZE
, &lpDAQ
->wSize
);
118 writew(1, &lpDAQ
->wFormat
);
119 writew(dev
.sample_size
, &lpDAQ
->wSampleSize
);
120 writew(dev
.channels
, &lpDAQ
->wChannels
);
121 writew(dev
.sample_rate
, &lpDAQ
->wSampleRate
);
122 writew(HIMT_RECORD_DONE
* 0x100 + n
, &lpDAQ
->wIntMsg
);
123 writew(n
+ 1, &lpDAQ
->wFlags
);
128 static void reset_queues(void)
130 dev
.DSPQ
->wHead
= dev
.DSPQ
->wTail
= 0;
132 reset_record_queue();
135 static int dsp_ioctl(unsigned int cmd
, unsigned long arg
)
137 int val
, i
, data
, tmp
;
138 LPDAQD lpDAQ
, lpDARQ
;
140 lpDAQ
= (LPDAQD
)(dev
.base
+ DAPQ_DATA_BUFF
);
141 lpDARQ
= (LPDAQD
)(dev
.base
+ DARQ_DATA_BUFF
);
144 case SNDCTL_DSP_SUBDIVIDE
:
145 case SNDCTL_DSP_SETFRAGMENT
:
146 case SNDCTL_DSP_SETDUPLEX
:
149 case SNDCTL_DSP_GETIPTR
:
150 case SNDCTL_DSP_GETOPTR
:
151 case SNDCTL_DSP_MAPINBUF
:
152 case SNDCTL_DSP_MAPOUTBUF
:
155 case SNDCTL_DSP_SYNC
:
156 case SNDCTL_DSP_RESET
:
159 reset_record_queue();
163 case SNDCTL_DSP_GETBLKSIZE
:
165 tmp
= dev
.fifosize
/ 4;
166 if (put_user(tmp
, (int *)arg
))
171 case SNDCTL_DSP_NONBLOCK
:
173 dev
.mode
|= O_NONBLOCK
;
177 case SNDCTL_DSP_GETCAPS
:
179 val
= DSP_CAP_DUPLEX
| DSP_CAP_BATCH
;
180 if (put_user(val
, (int *)arg
))
185 case SNDCTL_DSP_SAMPLESIZE
:
187 if (get_user(val
, (int *)arg
))
196 data
= DEFSAMPLESIZE
;
200 for (i
= 0; i
< 3; ++i
, ++lpDAQ
, ++lpDARQ
) {
202 lpDAQ
->wSampleSize
= data
;
203 lpDARQ
->wSampleSize
= data
;
206 dev
.sample_size
= data
;
208 if (put_user(data
, (int *)arg
))
213 case SNDCTL_DSP_SPEED
:
215 if (get_user(val
, (int *)arg
))
226 for (i
= 0; i
< 3; ++i
, ++lpDAQ
, ++lpDARQ
) {
228 lpDAQ
->wSampleRate
= data
;
229 lpDARQ
->wSampleRate
= data
;
232 dev
.sample_rate
= data
;
234 if (put_user(data
, (int *)arg
))
239 case SNDCTL_DSP_CHANNELS
:
241 if (get_user(val
, (int *)arg
))
254 for (i
= 0; i
< 3; ++i
, ++lpDAQ
, ++lpDARQ
) {
256 lpDAQ
->wChannels
= data
;
257 lpDARQ
->wChannels
= data
;
262 if (put_user(val
, (int *)arg
))
267 case SNDCTL_DSP_STEREO
:
269 if (get_user(val
, (int *)arg
))
283 for (i
= 0; i
< 3; ++i
, ++lpDAQ
, ++lpDARQ
) {
285 lpDAQ
->wChannels
= data
;
286 lpDARQ
->wChannels
= data
;
291 if (put_user(val
, (int *)arg
))
300 static int mixer_get(int d
)
306 case SOUND_MIXER_VOLUME
:
307 case SOUND_MIXER_SYNTH
:
308 case SOUND_MIXER_PCM
:
309 case SOUND_MIXER_LINE
:
311 case SOUND_MIXER_MIC
:
313 case SOUND_MIXER_IMIX
:
314 case SOUND_MIXER_LINE1
:
315 return (dev
.left_levels
[d
] >> 8) * 100 / 0xff |
316 (((dev
.right_levels
[d
] >> 8) * 100 / 0xff) << 8);
322 #define update_vol(a,b,s) \
323 writew(dev.left_levels[a] * readw(&dev.SMA->wCurrMastVolLeft) / 0xffff / s, \
324 &dev.SMA->b##Left); \
325 writew(dev.right_levels[a] * readw(&dev.SMA->wCurrMastVolRight) / 0xffff / s, \
328 static int mixer_set(int d
, int value
)
330 int left
= value
& 0x000000ff;
331 int right
= (value
& 0x0000ff00) >> 8;
338 bLeft
= left
* 0xff / 100;
339 wLeft
= left
* 0xffff / 100;
341 bRight
= right
* 0xff / 100;
342 wRight
= right
* 0xffff / 100;
344 dev
.left_levels
[d
] = wLeft
;
345 dev
.right_levels
[d
] = wRight
;
348 case SOUND_MIXER_VOLUME
: /* master volume */
349 writew(wLeft
/ 2, &dev
.SMA
->wCurrMastVolLeft
);
350 writew(wRight
/ 2, &dev
.SMA
->wCurrMastVolRight
);
354 case SOUND_MIXER_LINE
: /* aux pot control */
355 writeb(bLeft
, &dev
.SMA
->bInPotPosLeft
);
356 writeb(bRight
, &dev
.SMA
->bInPotPosRight
);
357 if (msnd_send_word(&dev
, 0, 0, HDEXAR_IN_SET_POTS
) == 0)
358 msnd_send_dsp_cmd(&dev
, HDEX_AUX_REQ
);
362 case SOUND_MIXER_MIC
: /* mic pot control */
363 writeb(bLeft
, &dev
.SMA
->bMicPotPosLeft
);
364 writeb(bRight
, &dev
.SMA
->bMicPotPosRight
);
365 if (msnd_send_word(&dev
, 0, 0, HDEXAR_MIC_SET_POTS
) == 0)
366 msnd_send_dsp_cmd(&dev
, HDEX_AUX_REQ
);
370 case SOUND_MIXER_LINE1
: /* line pot control */
371 writeb(bLeft
, &dev
.SMA
->bAuxPotPosLeft
);
372 writeb(bRight
, &dev
.SMA
->bAuxPotPosRight
);
373 if (msnd_send_word(&dev
, 0, 0, HDEXAR_AUX_SET_POTS
) == 0)
374 msnd_send_dsp_cmd(&dev
, HDEX_AUX_REQ
);
377 /* digital controls */
378 case SOUND_MIXER_SYNTH
: /* synth vol (dsp mix) */
379 case SOUND_MIXER_PCM
: /* pcm vol (dsp mix) */
380 case SOUND_MIXER_IMIX
: /* input monitor (dsp mix) */
387 /* update digital controls for master volume */
388 update_vol(SOUND_MIXER_PCM
, wCurrPlayVol
, 1);
389 update_vol(SOUND_MIXER_IMIX
, wCurrInVol
, 1);
391 update_vol(SOUND_MIXER_SYNTH
, wCurrMHdrVol
, 1);
397 static unsigned long set_recsrc(unsigned long recsrc
)
399 if (dev
.recsrc
== recsrc
)
402 else if (recsrc
== 0)
406 dev
.recsrc
^= recsrc
;
409 if (dev
.recsrc
& SOUND_MASK_LINE
) {
411 if (msnd_send_word(&dev
, 0, 0, HDEXAR_SET_ANA_IN
) == 0)
412 msnd_send_dsp_cmd(&dev
, HDEX_AUX_REQ
);
415 else if (dev
.recsrc
& SOUND_MASK_SYNTH
) {
417 if (msnd_send_word(&dev
, 0, 0, HDEXAR_SET_SYNTH_IN
) == 0)
418 msnd_send_dsp_cmd(&dev
, HDEX_AUX_REQ
);
421 else if ((dev
.recsrc
& SOUND_MASK_DIGITAL1
) && test_bit(F_HAVEDIGITAL
, &dev
.flags
)) {
423 if (msnd_send_word(&dev
, 0, 0, HDEXAR_SET_DAT_IN
) == 0) {
425 msnd_send_dsp_cmd(&dev
, HDEX_AUX_REQ
);
430 /* Select no input (?) */
433 dev
.recsrc
= SOUND_MASK_LINE
;
434 if (msnd_send_word(&dev
, 0, 0, HDEXAR_SET_ANA_IN
) == 0)
435 msnd_send_dsp_cmd(&dev
, HDEX_AUX_REQ
);
438 #endif /* MSND_CLASSIC */
443 #define set_mixer_info() \
444 strncpy(info.id, "MSNDMIXER", sizeof(info.id)); \
445 strncpy(info.name, "MultiSound Mixer", sizeof(info.name));
447 static int mixer_ioctl(unsigned int cmd
, unsigned long arg
)
449 if (cmd
== SOUND_MIXER_INFO
) {
452 info
.modify_counter
= dev
.mixer_mod_count
;
453 return copy_to_user((void *)arg
, &info
, sizeof(info
));
455 else if (cmd
== SOUND_OLD_MIXER_INFO
) {
456 _old_mixer_info info
;
458 return copy_to_user((void *)arg
, &info
, sizeof(info
));
460 else if (cmd
== OSS_GETVERSION
)
461 return put_user(SOUND_VERSION
, (int *)arg
);
462 else if (((cmd
>> 8) & 0xff) == 'M') {
465 if (_SIOC_DIR(cmd
) & _SIOC_WRITE
) {
467 switch (cmd
& 0xff) {
468 case SOUND_MIXER_RECSRC
:
469 if (get_user(val
, (int *)arg
))
471 val
= set_recsrc(val
);
475 if (get_user(val
, (int *)arg
))
477 val
= mixer_set(cmd
& 0xff, val
);
481 ++dev
.mixer_mod_count
;
483 return put_user(val
, (int *)arg
);
486 switch (cmd
& 0xff) {
487 case SOUND_MIXER_RECSRC
:
491 case SOUND_MIXER_DEVMASK
:
492 case SOUND_MIXER_STEREODEVS
:
493 val
= SOUND_MASK_VOLUME
|
503 case SOUND_MIXER_RECMASK
:
507 val
= SOUND_MASK_LINE
|
509 if (test_bit(F_HAVEDIGITAL
, &dev
.flags
))
510 val
|= SOUND_MASK_DIGITAL1
;
514 case SOUND_MIXER_CAPS
:
515 val
= SOUND_CAP_EXCL_INPUT
;
519 if ((val
= mixer_get(cmd
& 0xff)) < 0)
525 return put_user(val
, (int *)arg
);
531 static int dev_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
533 int minor
= MINOR(inode
->i_rdev
);
535 if (minor
== DSPMINOR
)
536 return dsp_ioctl(cmd
, arg
);
537 else if (minor
== MIXERMINOR
)
538 return mixer_ioctl(cmd
, arg
);
543 static void dsp_halt(void)
547 if (test_bit(F_READING
, &dev
.flags
)) {
548 clear_bit(F_READING
, &dev
.flags
);
550 if (test_and_clear_bit(F_READING
, &dev
.flags
)) {
552 msnd_send_dsp_cmd(&dev
, HDEX_RECORD_STOP
);
553 msnd_disable_irq(&dev
);
558 if (test_bit(F_WRITING
, &dev
.flags
)) {
559 clear_bit(F_WRITING
, &dev
.flags
);
561 if (test_and_clear_bit(F_WRITING
, &dev
.flags
)) {
563 set_bit(F_WRITEFLUSH
, &dev
.flags
);
564 interruptible_sleep_on(&dev
.writeflush
);
565 current
->state
= TASK_INTERRUPTIBLE
;
567 jiffies
+ DAP_BUFF_SIZE
/ 2 * HZ
/
568 dev
.sample_rate
/ dev
.channels
;
570 current
->timeout
= 0;
571 msnd_send_dsp_cmd(&dev
, HDEX_PLAY_STOP
);
572 msnd_disable_irq(&dev
);
573 memset_io(dev
.base
, 0, DAP_BUFF_SIZE
* 3);
580 static int dsp_open(struct file
*file
)
582 dev
.mode
= file
->f_mode
;
583 set_bit(F_AUDIO_INUSE
, &dev
.flags
);
588 static int dsp_close(void)
591 clear_bit(F_AUDIO_INUSE
, &dev
.flags
);
595 static int dev_open(struct inode
*inode
, struct file
*file
)
597 int minor
= MINOR(inode
->i_rdev
);
600 if (minor
== DSPMINOR
) {
602 if (test_bit(F_AUDIO_INUSE
, &dev
.flags
))
605 err
= dsp_open(file
);
607 else if (minor
== MIXERMINOR
) {
619 static void dev_close(struct inode
*inode
, struct file
*file
)
621 static int dev_close(struct inode
*inode
, struct file
*file
)
624 int minor
= MINOR(inode
->i_rdev
);
629 if (minor
== DSPMINOR
) {
635 else if (minor
== MIXERMINOR
) {
651 static int DAPF_to_bank(int bank
)
653 return msnd_fifo_read(&dev
.DAPF
, dev
.base
+ bank
* DAP_BUFF_SIZE
, DAP_BUFF_SIZE
, 0);
656 static int bank_to_DARF(int bank
)
658 return msnd_fifo_write(&dev
.DARF
, dev
.base
+ bank
* DAR_BUFF_SIZE
, DAR_BUFF_SIZE
, 0);
661 static int dsp_read(char *buf
, size_t len
)
670 if ((n
= msnd_fifo_read(&dev
.DARF
, buf
, count
, 1)) < 0) {
672 printk(KERN_WARNING LOGNAME
": FIFO read error\n");
680 if (!test_bit(F_READING
, &dev
.flags
) && (dev
.mode
& FMODE_READ
)) {
681 set_bit(F_READING
, &dev
.flags
);
683 if (!test_and_set_bit(F_READING
, &dev
.flags
) && (dev
.mode
& FMODE_READ
)) {
685 reset_record_queue();
686 msnd_enable_irq(&dev
);
687 msnd_send_dsp_cmd(&dev
, HDEX_RECORD_START
);
691 if (dev
.mode
& O_NONBLOCK
)
692 return count
== len
? -EAGAIN
: len
- count
;
696 set_bit(F_READBLOCK
, &dev
.flags
);
697 interruptible_sleep_on(&dev
.readblock
);
698 clear_bit(F_READBLOCK
, &dev
.flags
);
700 if (signal_pending(current
))
712 static int dsp_write(const char *buf
, size_t len
)
721 if ((n
= msnd_fifo_write(&dev
.DAPF
, buf
, count
, 1)) < 0) {
723 printk(KERN_WARNING LOGNAME
": FIFO write error\n");
731 if (!test_bit(F_WRITING
, &dev
.flags
) && (dev
.mode
& FMODE_WRITE
)) {
732 set_bit(F_WRITING
, &dev
.flags
);
734 if (!test_and_set_bit(F_WRITING
, &dev
.flags
) && (dev
.mode
& FMODE_WRITE
)) {
737 msnd_enable_irq(&dev
);
738 msnd_send_dsp_cmd(&dev
, HDEX_PLAY_START
);
742 if (dev
.mode
& O_NONBLOCK
)
743 return count
== len
? -EAGAIN
: len
- count
;
747 set_bit(F_WRITEBLOCK
, &dev
.flags
);
748 interruptible_sleep_on(&dev
.writeblock
);
749 clear_bit(F_WRITEBLOCK
, &dev
.flags
);
751 if (signal_pending(current
))
764 static int dev_read(struct inode
*inode
, struct file
*file
, char *buf
, int count
)
766 int minor
= MINOR(inode
->i_rdev
);
768 static ssize_t
dev_read(struct file
*file
, char *buf
, size_t count
, loff_t
*off
)
770 int minor
= MINOR(file
->f_dentry
->d_inode
->i_rdev
);
773 if (minor
== DSPMINOR
) {
775 return dsp_read(buf
, count
);
782 static int dev_write(struct inode
*inode
, struct file
*file
, const char *buf
, int count
)
784 int minor
= MINOR(inode
->i_rdev
);
786 static ssize_t
dev_write(struct file
*file
, const char *buf
, size_t count
, loff_t
*off
)
788 int minor
= MINOR(file
->f_dentry
->d_inode
->i_rdev
);
791 if (minor
== DSPMINOR
) {
793 return dsp_write(buf
, count
);
799 static void eval_dsp_msg(WORD wMessage
)
801 switch (HIBYTE(wMessage
)) {
804 if (dev
.lastbank
== LOBYTE(wMessage
))
807 dev
.lastbank
= LOBYTE(wMessage
);
809 dev
.CurDAQD
->wSize
= DAP_BUFF_SIZE
;
811 if ((dev
.DAPQ
->wTail
+= PCTODSP_OFFSET(DAPQ_STRUCT_SIZE
)) > dev
.DAPQ
->wSize
)
814 if (++dev
.CurDAQD
> (LPDAQD
)(dev
.base
+ DAPQ_DATA_BUFF
+ 2 * DAPQ_STRUCT_SIZE
))
815 dev
.CurDAQD
= (LPDAQD
)(dev
.base
+ DAPQ_DATA_BUFF
);
817 if (dev
.lastbank
< 3) {
819 if (DAPF_to_bank(dev
.lastbank
) > 0) {
822 msnd_send_dsp_cmd(&dev
, HDEX_PLAY_START
);
825 else if (!test_bit(F_WRITEBLOCK
, &dev
.flags
)) {
827 clear_bit(F_WRITING
, &dev
.flags
);
829 if (test_bit(F_WRITEFLUSH
, &dev
.flags
)) {
830 clear_bit(F_WRITEFLUSH
, &dev
.flags
);
831 wake_up_interruptible(&dev
.writeflush
);
834 if (test_and_clear_bit(F_WRITEFLUSH
, &dev
.flags
))
835 wake_up_interruptible(&dev
.writeflush
);
837 msnd_disable_irq(&dev
);
842 if (test_bit(F_WRITEBLOCK
, &dev
.flags
))
843 wake_up_interruptible(&dev
.writeblock
);
847 case HIMT_RECORD_DONE
: {
851 wTemp
= dev
.DARQ
->wTail
+ (DARQ_STRUCT_SIZE
/ 2);
853 if (wTemp
> dev
.DARQ
->wSize
)
856 while (wTemp
== dev
.DARQ
->wHead
);
858 dev
.DARQ
->wTail
= wTemp
;
860 outb(HPBLKSEL_1
, dev
.io
+ HP_BLKS
);
861 if (bank_to_DARF(LOBYTE(wMessage
)) == 0 &&
862 !test_bit(F_READBLOCK
, &dev
.flags
)) {
864 memset_io(dev
.base
, 0, DAR_BUFF_SIZE
* 3);
865 clear_bit(F_READING
, &dev
.flags
);
866 msnd_disable_irq(&dev
);
869 outb(HPBLKSEL_0
, dev
.io
+ HP_BLKS
);
871 if (test_bit(F_READBLOCK
, &dev
.flags
))
872 wake_up_interruptible(&dev
.readblock
);
877 switch (LOBYTE(wMessage
)) {
879 case HIDSP_PLAY_UNDER
:
881 case HIDSP_INT_PLAY_UNDER
:
882 printk(KERN_INFO LOGNAME
": Write underflow\n");
886 case HIDSP_INT_RECORD_OVER
:
887 printk(KERN_INFO LOGNAME
": Read overflow\n");
888 reset_record_queue();
892 printk(KERN_DEBUG LOGNAME
": DSP message %u\n", LOBYTE(wMessage
));
897 case HIMT_MIDI_IN_UCHAR
:
898 if (dev
.midi_in_interrupt
)
899 (*dev
.midi_in_interrupt
)(&dev
);
903 printk(KERN_DEBUG LOGNAME
": MIDI out event\n");
907 printk(KERN_DEBUG LOGNAME
": HIMT message %u\n", HIBYTE(wMessage
));
912 static void intr(int irq
, void *dev_id
, struct pt_regs
*regs
)
914 if (test_bit(F_INTERRUPT
, &dev
.flags
))
917 set_bit(F_INTERRUPT
, &dev
.flags
);
919 if (test_bit(F_BANKONE
, &dev
.flags
))
920 outb(HPBLKSEL_0
, dev
.io
+ HP_BLKS
);
922 inb(dev
.io
+ HP_RXL
);
924 while (dev
.DSPQ
->wTail
!= dev
.DSPQ
->wHead
) {
926 eval_dsp_msg(*(dev
.pwDSPQData
+ dev
.DSPQ
->wHead
));
928 if (++dev
.DSPQ
->wHead
> dev
.DSPQ
->wSize
)
932 if (test_bit(F_BANKONE
, &dev
.flags
))
933 outb(HPBLKSEL_1
, dev
.io
+ HP_BLKS
);
935 clear_bit(F_INTERRUPT
, &dev
.flags
);
938 static struct file_operations dev_fileops
= {
951 __initfunc(static int reset_dsp(void))
955 outb(HPDSPRESET_ON
, dev
.io
+ HP_DSPR
);
959 dev
.info
= inb(dev
.io
+ HP_INFO
);
961 outb(HPDSPRESET_OFF
, dev
.io
+ HP_DSPR
);
965 while (timeout
-- > 0) {
967 if (inb(dev
.io
+ HP_CVR
) == HP_CVR_DEF
)
973 printk(KERN_ERR LOGNAME
": Cannot reset DSP\n");
978 __initfunc(static int probe_multisound(void))
981 char *xv
, *rev
= NULL
;
982 char *pin
= "Pinnacle", *fiji
= "Fiji";
983 char *pinfiji
= "Pinnacle/Fiji";
986 if (check_region(dev
.io
, dev
.numio
)) {
988 printk(KERN_ERR LOGNAME
": I/O port conflict\n");
992 request_region(dev
.io
, dev
.numio
, "probing");
994 if (reset_dsp() < 0) {
996 release_region(dev
.io
, dev
.numio
);
1000 printk(KERN_INFO LOGNAME
": DSP reset successful\n");
1003 dev
.name
= "Classic/Tahiti/Monterey";
1004 printk(KERN_INFO LOGNAME
": Turtle Beach %s, "
1006 switch (dev
.info
>> 4) {
1007 case 0xf: xv
= "<= 1.15"; break;
1008 case 0x1: xv
= "1.18/1.2"; break;
1009 case 0x2: xv
= "1.3"; break;
1010 case 0x3: xv
= "1.4"; break;
1011 default: xv
= "unknown"; break;
1014 switch (dev
.info
& 0x7) {
1015 case 0x0: rev
= "I"; dev
.name
= pin
; break;
1016 case 0x1: rev
= "F"; dev
.name
= pin
; break;
1017 case 0x2: rev
= "G"; dev
.name
= pin
; break;
1018 case 0x3: rev
= "H"; dev
.name
= pin
; break;
1019 case 0x4: rev
= "E"; dev
.name
= fiji
; break;
1020 case 0x5: rev
= "C"; dev
.name
= fiji
; break;
1021 case 0x6: rev
= "D"; dev
.name
= fiji
; break;
1023 rev
= "A-B (Fiji) or A-E (Pinnacle)";
1027 printk(KERN_INFO LOGNAME
": Turtle Beach %s revision %s, Xilinx version %s, "
1028 #endif /* MSND_CLASSIC */
1029 "I/O 0x%x-0x%x, IRQ %d, memory mapped to 0x%p-0x%p\n",
1031 #ifndef MSND_CLASSIC
1034 dev
.io
, dev
.io
+ dev
.numio
- 1,
1036 dev
.base
, dev
.base
+ 0x7fff);
1038 release_region(dev
.io
, dev
.numio
);
1043 __initfunc(static int init_sma(void))
1049 outb(dev
.memid
, dev
.io
+ HP_MEMM
);
1051 outb(HPBLKSEL_0
, dev
.io
+ HP_BLKS
);
1052 memset_io(dev
.base
, 0, 0x8000);
1054 outb(HPBLKSEL_1
, dev
.io
+ HP_BLKS
);
1055 memset_io(dev
.base
, 0, 0x8000);
1057 outb(HPBLKSEL_0
, dev
.io
+ HP_BLKS
);
1059 dev
.DAPQ
= (struct JobQueueStruct
*)(dev
.base
+ DAPQ_OFFSET
);
1060 dev
.DARQ
= (struct JobQueueStruct
*)(dev
.base
+ DARQ_OFFSET
);
1061 dev
.MODQ
= (struct JobQueueStruct
*)(dev
.base
+ MODQ_OFFSET
);
1062 dev
.MIDQ
= (struct JobQueueStruct
*)(dev
.base
+ MIDQ_OFFSET
);
1063 dev
.DSPQ
= (struct JobQueueStruct
*)(dev
.base
+ DSPQ_OFFSET
);
1065 dev
.SMA
= (struct SMA0_CommonData
*)(dev
.base
+ SMA_STRUCT_START
);
1067 dev
.CurDAQD
= (LPDAQD
)(dev
.base
+ DAPQ_DATA_BUFF
);
1068 dev
.CurDARQD
= (LPDAQD
)(dev
.base
+ DARQ_DATA_BUFF
);
1070 dev
.sample_size
= DEFSAMPLESIZE
;
1071 dev
.sample_rate
= DEFSAMPLERATE
;
1072 dev
.channels
= DEFCHANNELS
;
1074 for (n
= 0, lpDAQ
= dev
.CurDAQD
; n
< 3; ++n
, ++lpDAQ
) {
1076 writew(PCTODSP_BASED((DWORD
)(DAP_BUFF_SIZE
* n
)), &lpDAQ
->wStart
);
1077 writew(DAP_BUFF_SIZE
, &lpDAQ
->wSize
);
1078 writew(1, &lpDAQ
->wFormat
);
1079 writew(dev
.sample_size
, &lpDAQ
->wSampleSize
);
1080 writew(dev
.channels
, &lpDAQ
->wChannels
);
1081 writew(dev
.sample_rate
, &lpDAQ
->wSampleRate
);
1082 writew(HIMT_PLAY_DONE
* 0x100 + n
, &lpDAQ
->wIntMsg
);
1083 writew(n
+ 1, &lpDAQ
->wFlags
);
1086 for (n
= 0, lpDAQ
= dev
.CurDARQD
; n
< 3; ++n
, ++lpDAQ
) {
1088 writew(PCTODSP_BASED((DWORD
)(DAR_BUFF_SIZE
* n
)) + 0x4000, &lpDAQ
->wStart
);
1089 writew(DAR_BUFF_SIZE
, &lpDAQ
->wSize
);
1090 writew(1, &lpDAQ
->wFormat
);
1091 writew(dev
.sample_size
, &lpDAQ
->wSampleSize
);
1092 writew(dev
.channels
, &lpDAQ
->wChannels
);
1093 writew(dev
.sample_rate
, &lpDAQ
->wSampleRate
);
1094 writew(HIMT_RECORD_DONE
* 0x100 + n
, &lpDAQ
->wIntMsg
);
1095 writew(n
+ 1, &lpDAQ
->wFlags
);
1099 dev
.pwDSPQData
= (WORD
*)(dev
.base
+ DSPQ_DATA_BUFF
);
1100 dev
.pwMODQData
= (WORD
*)(dev
.base
+ MODQ_DATA_BUFF
);
1101 dev
.pwMIDQData
= (WORD
*)(dev
.base
+ MIDQ_DATA_BUFF
);
1103 writew(PCTODSP_BASED(MIDQ_DATA_BUFF
), &dev
.MIDQ
->wStart
);
1104 writew(PCTODSP_OFFSET(MIDQ_BUFF_SIZE
) - 1, &dev
.MIDQ
->wSize
);
1105 writew(0, &dev
.MIDQ
->wHead
);
1106 writew(0, &dev
.MIDQ
->wTail
);
1108 writew(PCTODSP_BASED(MODQ_DATA_BUFF
), &dev
.MODQ
->wStart
);
1109 writew(PCTODSP_OFFSET(MODQ_BUFF_SIZE
) - 1, &dev
.MODQ
->wSize
);
1110 writew(0, &dev
.MODQ
->wHead
);
1111 writew(0, &dev
.MODQ
->wTail
);
1113 writew(PCTODSP_BASED(DAPQ_DATA_BUFF
), &dev
.DAPQ
->wStart
);
1114 writew(PCTODSP_OFFSET(DAPQ_BUFF_SIZE
) - 1, &dev
.DAPQ
->wSize
);
1115 writew(0, &dev
.DAPQ
->wHead
);
1116 writew(0, &dev
.DAPQ
->wTail
);
1118 writew(PCTODSP_BASED(DARQ_DATA_BUFF
), &dev
.DARQ
->wStart
);
1119 writew(PCTODSP_OFFSET(DARQ_BUFF_SIZE
) - 1, &dev
.DARQ
->wSize
);
1120 writew(0, &dev
.DARQ
->wHead
);
1121 writew(0, &dev
.DARQ
->wTail
);
1123 writew(PCTODSP_BASED(DSPQ_DATA_BUFF
), &dev
.DSPQ
->wStart
);
1124 writew(PCTODSP_OFFSET(DSPQ_BUFF_SIZE
) - 1, &dev
.DSPQ
->wSize
);
1125 writew(0, &dev
.DSPQ
->wHead
);
1126 writew(0, &dev
.DSPQ
->wTail
);
1128 writew(0, &dev
.SMA
->wCurrPlayBytes
);
1129 writew(0, &dev
.SMA
->wCurrRecordBytes
);
1131 writew(0, &dev
.SMA
->wCurrPlayVolLeft
);
1132 writew(0, &dev
.SMA
->wCurrPlayVolRight
);
1134 writew(0, &dev
.SMA
->wCurrInVolLeft
);
1135 writew(0, &dev
.SMA
->wCurrInVolRight
);
1137 writew(0, &dev
.SMA
->wCurrMastVolLeft
);
1138 writew(0, &dev
.SMA
->wCurrMastVolRight
);
1140 #ifndef MSND_CLASSIC
1141 writel(0x00010000, &dev
.SMA
->dwCurrPlayPitch
);
1142 writel(0x00000001, &dev
.SMA
->dwCurrPlayRate
);
1145 writew(0x0000, &dev
.SMA
->wCurrDSPStatusFlags
);
1146 writew(0x0000, &dev
.SMA
->wCurrHostStatusFlags
);
1148 writew(0x303, &dev
.SMA
->wCurrInputTagBits
);
1149 writew(0, &dev
.SMA
->wCurrLeftPeak
);
1150 writew(0, &dev
.SMA
->wCurrRightPeak
);
1152 writeb(0, &dev
.SMA
->bInPotPosRight
);
1153 writeb(0, &dev
.SMA
->bInPotPosLeft
);
1155 writeb(0, &dev
.SMA
->bAuxPotPosRight
);
1156 writeb(0, &dev
.SMA
->bAuxPotPosLeft
);
1158 #ifndef MSND_CLASSIC
1159 writew(1, &dev
.SMA
->wCurrPlayFormat
);
1160 writew(dev
.sample_size
, &dev
.SMA
->wCurrPlaySampleSize
);
1161 writew(dev
.channels
, &dev
.SMA
->wCurrPlayChannels
);
1162 writew(dev
.sample_rate
, &dev
.SMA
->wCurrPlaySampleRate
);
1164 writew(dev
.sample_rate
, &dev
.SMA
->wCalFreqAtoD
);
1169 __initfunc(static int calibrate_adc(WORD srate
))
1171 if (!dev
.calibrate_signal
) {
1173 printk(KERN_INFO LOGNAME
": ADC calibration to board ground ");
1174 writew(readw(&dev
.SMA
->wCurrHostStatusFlags
)
1175 | 0x0001, &dev
.SMA
->wCurrHostStatusFlags
);
1179 printk(KERN_INFO LOGNAME
": ADC calibration to signal ground ");
1180 writew(readw(&dev
.SMA
->wCurrHostStatusFlags
)
1181 & ~0x0001, &dev
.SMA
->wCurrHostStatusFlags
);
1184 writew(srate
, &dev
.SMA
->wCalFreqAtoD
);
1186 if (msnd_send_word(&dev
, 0, 0, HDEXAR_CAL_A_TO_D
) == 0 &&
1187 msnd_send_dsp_cmd(&dev
, HDEX_AUX_REQ
) == 0) {
1189 current
->state
= TASK_INTERRUPTIBLE
;
1190 current
->timeout
= jiffies
+ HZ
;
1192 current
->timeout
= 0;
1193 printk("successful\n");
1202 __initfunc(static int upload_dsp_code(void))
1204 outb(HPBLKSEL_0
, dev
.io
+ HP_BLKS
);
1206 #ifdef HAVE_DSPCODEH
1207 printk(KERN_INFO LOGNAME
": Using resident Turtle Beach DSP code\n");
1209 printk(KERN_INFO LOGNAME
": Loading Turtle Beach DSP code\n");
1210 INITCODESIZE
= mod_firmware_load(INITCODEFILE
, &INITCODE
);
1212 printk(KERN_ERR LOGNAME
": Error loading " INITCODEFILE
);
1216 PERMCODESIZE
= mod_firmware_load(PERMCODEFILE
, &PERMCODE
);
1218 printk(KERN_ERR LOGNAME
": Error loading " PERMCODEFILE
);
1223 memcpy_toio(dev
.base
, PERMCODE
, PERMCODESIZE
);
1225 if (msnd_upload_host(&dev
, INITCODE
, INITCODESIZE
) < 0) {
1227 printk(KERN_WARNING LOGNAME
": Error uploading to DSP\n");
1231 #ifndef HAVE_DSPCODEH
1240 __initfunc(static void reset_proteus(void))
1242 outb(HPPRORESET_ON
, dev
.io
+ HP_PROR
);
1243 mdelay(TIME_PRO_RESET
);
1244 outb(HPPRORESET_OFF
, dev
.io
+ HP_PROR
);
1245 mdelay(TIME_PRO_RESET_DONE
);
1249 __initfunc(static int initialize(void))
1254 outb(HPWAITSTATE_0
, dev
.io
+ HP_WAIT
);
1255 outb(HPBITMODE_16
, dev
.io
+ HP_BITM
);
1260 if ((err
= init_sma()) < 0) {
1262 printk(KERN_WARNING LOGNAME
": Cannot initialize SMA\n");
1266 if ((err
= reset_dsp()) < 0)
1269 if ((err
= upload_dsp_code()) < 0) {
1271 printk(KERN_WARNING LOGNAME
": Cannot upload DSP code\n");
1275 printk(KERN_INFO LOGNAME
": DSP upload successful\n");
1279 while (readw(dev
.base
)) {
1289 __initfunc(static int attach_multisound(void))
1293 printk(KERN_DEBUG LOGNAME
": Intializing DSP\n");
1295 if ((err
= request_irq(dev
.irq
, intr
, SA_SHIRQ
, DEVNAME
, &dev
)) < 0) {
1297 printk(KERN_ERR LOGNAME
": Couldn't grab IRQ %d\n", dev
.irq
);
1302 request_region(dev
.io
, dev
.numio
, DEVNAME
);
1304 if ((err
= initialize()) < 0) {
1306 printk(KERN_WARNING LOGNAME
": Initialization failure\n");
1307 release_region(dev
.io
, dev
.numio
);
1308 free_irq(dev
.irq
, &dev
);
1313 if ((err
= msnd_register(&dev
)) < 0) {
1315 printk(KERN_ERR LOGNAME
": Unable to register MultiSound\n");
1316 release_region(dev
.io
, dev
.numio
);
1317 free_irq(dev
.irq
, &dev
);
1321 if ((DSPMINOR
= register_sound_dsp(&dev_fileops
)) < 0) {
1323 printk(KERN_ERR LOGNAME
": Unable to register DSP operations\n");
1324 msnd_unregister(&dev
);
1325 release_region(dev
.io
, dev
.numio
);
1326 free_irq(dev
.irq
, &dev
);
1330 if ((MIXERMINOR
= register_sound_mixer(&dev_fileops
)) < 0) {
1332 printk(KERN_ERR LOGNAME
": Unable to register mixer operations\n");
1333 unregister_sound_mixer(MIXERMINOR
);
1334 msnd_unregister(&dev
);
1335 release_region(dev
.io
, dev
.numio
);
1336 free_irq(dev
.irq
, &dev
);
1339 printk(KERN_INFO LOGNAME
": Using DSP minor %d, mixer minor %d\n", MIXERMINOR
, DSPMINOR
);
1341 calibrate_adc(dev
.sample_rate
);
1342 #ifndef MSND_CLASSIC
1343 printk(KERN_INFO LOGNAME
": Setting recording source to Line In\n");
1344 if (msnd_send_word(&dev
, 0, 0, HDEXAR_SET_ANA_IN
) != 0 ||
1345 msnd_send_dsp_cmd(&dev
, HDEX_AUX_REQ
) != 0) {
1346 printk(KERN_DEBUG LOGNAME
": Error setting Line In as recording source\n");
1348 dev
.recsrc
= SOUND_MASK_LINE
;
1354 static void unload_multisound(void)
1356 release_region(dev
.io
, dev
.numio
);
1357 free_irq(dev
.irq
, &dev
);
1358 unregister_sound_mixer(MIXERMINOR
);
1359 unregister_sound_dsp(DSPMINOR
);
1360 msnd_unregister(&dev
);
1363 static void mod_inc_ref(void)
1368 static void mod_dec_ref(void)
1374 MODULE_AUTHOR ("Andrew Veliath <andrewtv@usa.net>");
1375 MODULE_DESCRIPTION ("Turtle Beach " LONGNAME
" Linux Driver");
1376 MODULE_PARM (io
, "i");
1377 MODULE_PARM (irq
, "i");
1378 MODULE_PARM (mem
, "i");
1379 MODULE_PARM (major
, "i");
1380 MODULE_PARM (fifosize
, "i");
1381 MODULE_PARM (calibrate_signal
, "i");
1382 #ifndef MSND_CLASSIC
1383 MODULE_PARM (digital
, "i");
1386 static int io __initdata
= -1;
1387 static int irq __initdata
= -1;
1388 static int mem __initdata
= -1;
1389 #ifndef MSND_CLASSIC
1390 static int digital __initdata
;
1392 static int fifosize __initdata
= DEFFIFOSIZE
;
1393 static int calibrate_signal __initdata
;
1395 int init_module(void)
1396 #else /* not a module */
1398 static int io __initdata
= CONFIG_MSNDCLAS_IO
;
1399 static int irq __initdata
= CONFIG_MSNDCLAS_IRQ
;
1400 static int mem __initdata
= CONFIG_MSNDCLAS_MEM
;
1401 #else /* Pinnacle/Fiji */
1402 static int io __initdata
= CONFIG_MSNDPIN_IO
;
1403 static int irq __initdata
= CONFIG_MSNDPIN_IRQ
;
1404 static int mem __initdata
= CONFIG_MSNDPIN_MEM
;
1405 #ifndef CONFIG_MSNDPIN_DIGITAL
1406 # define CONFIG_MSNDPIN_DIGITAL 0
1408 static int digital __initdata
= CONFIG_MSNDPIN_DIGITAL
;
1409 #endif /* MSND_CLASSIC */
1410 #ifndef CONFIG_MSND_FIFOSIZE
1411 # define CONFIG_MSND_FIFOSIZE DEFFIFOSIZE
1412 #endif /* CONFIG_MSND_FIFOSIZE */
1413 static int fifosize __initdata
= CONFIG_MSND_FIFOSIZE
;
1414 #ifndef CONFIG_MSND_CALSIGNAL
1415 # define CONFIG_MSND_CALSIGNAL 0
1416 #endif /* CONFIG_MSND_CALSIGNAL */
1418 calibrate_signal __initdata
= CONFIG_MSND_CALSIGNAL
;
1421 __initfunc(int msnd_classic_init(void))
1423 __initfunc(int msnd_pinnacle_init(void))
1424 #endif /* MSND_CLASSIC */
1429 printk(KERN_INFO LOGNAME
": Turtle Beach " LONGNAME
" Linux Driver Version "
1430 VERSION
", Copyright (C) 1998 Andrew Veliath\n");
1432 if (io
== -1 || irq
== -1 || mem
== -1) {
1434 printk(KERN_WARNING LOGNAME
": io, irq and mem must be set\n");
1447 printk(KERN_ERR LOGNAME
": \"io\" - DSP I/O base must be set\n");
1459 printk(KERN_ERR LOGNAME
": \"irq\" - must be set to 5, 7, 9, 10, 11 or 12\n");
1471 printk(KERN_ERR LOGNAME
": \"mem\" - must be set to "
1472 "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n");
1478 case 5: dev
.irqid
= HPIRQ_5
; break;
1479 case 7: dev
.irqid
= HPIRQ_7
; break;
1480 case 9: dev
.irqid
= HPIRQ_9
; break;
1481 case 10: dev
.irqid
= HPIRQ_10
; break;
1482 case 11: dev
.irqid
= HPIRQ_11
; break;
1483 case 12: dev
.irqid
= HPIRQ_12
; break;
1487 case 0xb0000: dev
.memid
= HPMEM_B000
; break;
1488 case 0xc8000: dev
.memid
= HPMEM_C800
; break;
1489 case 0xd0000: dev
.memid
= HPMEM_D000
; break;
1490 case 0xd8000: dev
.memid
= HPMEM_D800
; break;
1491 case 0xe0000: dev
.memid
= HPMEM_E000
; break;
1492 case 0xe8000: dev
.memid
= HPMEM_E800
; break;
1494 #endif /* MSND_CLASSIC */
1503 dev
.type
= msndClassic
;
1505 dev
.type
= msndPinnacle
;
1508 dev
.numio
= DSP_NUMIO
;
1510 dev
.base
= phys_to_virt(mem
);
1511 dev
.fifosize
= fifosize
* 1024;
1512 dev
.calibrate_signal
= calibrate_signal
? 1 : 0;
1514 dev
.inc_ref
= mod_inc_ref
;
1515 dev
.dec_ref
= mod_dec_ref
;
1517 #ifndef MSND_CLASSIC
1519 set_bit(F_HAVEDIGITAL
, &dev
.flags
);
1520 printk(KERN_INFO LOGNAME
": Digital I/O access enabled\n");
1524 init_waitqueue(&dev
.writeblock
);
1525 init_waitqueue(&dev
.readblock
);
1526 init_waitqueue(&dev
.writeflush
);
1527 msnd_fifo_init(&dev
.DAPF
);
1528 msnd_fifo_init(&dev
.DARF
);
1530 spin_lock_init(&dev
.lock
);
1533 printk(KERN_INFO LOGNAME
": Using %u byte digital audio FIFOs (x2)\n", dev
.fifosize
);
1535 if ((err
= msnd_fifo_alloc(&dev
.DAPF
, dev
.fifosize
)) < 0) {
1537 printk(KERN_ERR LOGNAME
": Couldn't allocate write FIFO\n");
1541 if ((err
= msnd_fifo_alloc(&dev
.DARF
, dev
.fifosize
)) < 0) {
1543 printk(KERN_ERR LOGNAME
": Couldn't allocate read FIFO\n");
1544 msnd_fifo_free(&dev
.DAPF
);
1548 if ((err
= probe_multisound()) < 0) {
1550 printk(KERN_ERR LOGNAME
": Probe failed\n");
1551 msnd_fifo_free(&dev
.DAPF
);
1552 msnd_fifo_free(&dev
.DARF
);
1557 if ((err
= attach_multisound()) < 0) {
1559 printk(KERN_ERR LOGNAME
": Attach failed\n");
1560 msnd_fifo_free(&dev
.DAPF
);
1561 msnd_fifo_free(&dev
.DARF
);
1570 void cleanup_module(void)
1572 printk(KERN_INFO LOGNAME
": Unloading\n");
1574 unload_multisound();
1576 msnd_fifo_free(&dev
.DAPF
);
1577 msnd_fifo_free(&dev
.DARF
);