1 /*****************************************************************************/ 4 * sonicvibes.c -- S3 Sonic Vibes audio driver. 6 * Copyright (C) 1998-2000 Thomas Sailer (sailer@ife.ee.ethz.ch) 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 * Special thanks to David C. Niemi 25 * Module command line parameters: 30 * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible 31 * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible 32 * /dev/midi simple MIDI UART interface, no ioctl 34 * The card has both an FM and a Wavetable synth, but I have to figure 35 * out first how to drive them... 38 * 06.05.1998 0.1 Initial release 39 * 10.05.1998 0.2 Fixed many bugs, esp. ADC rate calculation 40 * First stab at a simple midi interface (no bells&whistles) 41 * 13.05.1998 0.3 Fix stupid cut&paste error: set_adc_rate was called instead of 42 * set_dac_rate in the FMODE_WRITE case in sv_open 43 * Fix hwptr out of bounds (now mpg123 works) 44 * 14.05.1998 0.4 Don't allow excessive interrupt rates 45 * 08.06.1998 0.5 First release using Alan Cox' soundcore instead of miscdevice 46 * 03.08.1998 0.6 Do not include modversions.h 47 * Now mixer behaviour can basically be selected between 48 * "OSS documented" and "OSS actual" behaviour 49 * 31.08.1998 0.7 Fix realplayer problems - dac.count issues 50 * 10.12.1998 0.8 Fix drain_dac trying to wait on not yet initialized DMA 51 * 16.12.1998 0.9 Fix a few f_file & FMODE_ bugs 52 * 06.01.1999 0.10 remove the silly SA_INTERRUPT flag. 53 * hopefully killed the egcs section type conflict 54 * 12.03.1999 0.11 cinfo.blocks should be reset after GETxPTR ioctl. 55 * reported by Johan Maes <joma@telindus.be> 56 * 22.03.1999 0.12 return EAGAIN instead of EBUSY when O_NONBLOCK 57 * read/write cannot be executed 58 * 05.04.1999 0.13 added code to sv_read and sv_write which should detect 59 * lockups of the sound chip and revive it. This is basically 60 * an ugly hack, but at least applications using this driver 61 * won't hang forever. I don't know why these lockups happen, 62 * it might well be the motherboard chipset (an early 486 PCI 63 * board with ALI chipset), since every busmastering 100MB 64 * ethernet card I've tried (Realtek 8139 and Macronix tulip clone) 65 * exhibit similar behaviour (they work for a couple of packets 66 * and then lock up and can be revived by ifconfig down/up). 67 * 07.04.1999 0.14 implemented the following ioctl's: SOUND_PCM_READ_RATE, 68 * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 69 * Alpha fixes reported by Peter Jones <pjones@redhat.com> 70 * Note: dmaio hack might still be wrong on archs other than i386 71 * 15.06.1999 0.15 Fix bad allocation bug. 72 * Thanks to Deti Fliegl <fliegl@in.tum.de> 73 * 28.06.1999 0.16 Add pci_set_master 74 * 03.08.1999 0.17 adapt to Linus' new __setup/__initcall 75 * added kernel command line options "sonicvibes=reverb" and "sonicvibesdmaio=dmaioaddr" 76 * 12.08.1999 0.18 module_init/__setup fixes 77 * 24.08.1999 0.19 get rid of the dmaio kludge, replace with allocate_resource 78 * 31.08.1999 0.20 add spin_lock_init 79 * use new resource allocation to allocate DDMA IO space 80 * replaced current->state = x with set_current_state(x) 81 * 03.09.1999 0.21 change read semantics for MIDI to match 82 * OSS more closely; remove possible wakeup race 83 * 28.10.1999 0.22 More waitqueue races fixed 84 * 01.12.1999 0.23 New argument to allocate_resource 85 * 07.12.1999 0.24 More allocate_resource semantics change 86 * 08.01.2000 0.25 Prevent some ioctl's from returning bad count values on underrun/overrun; 87 * Tim Janik's BSE (Bedevilled Sound Engine) found this 88 * use Martin Mares' pci_assign_resource 89 * 07.02.2000 0.26 Use pci_alloc_consistent and pci_register_driver 90 * 21.11.2000 0.27 Initialize dma buffers in poll, otherwise poll may return a bogus mask 94 /*****************************************************************************/ 96 #include <linux/version.h> 97 #include <linux/module.h> 98 #include <linux/string.h> 99 #include <linux/ioport.h> 100 #include <linux/sched.h> 101 #include <linux/delay.h> 102 #include <linux/sound.h> 103 #include <linux/malloc.h> 104 #include <linux/soundcard.h> 105 #include <linux/pci.h> 108 #include <linux/init.h> 109 #include <linux/poll.h> 110 #include <linux/spinlock.h> 111 #include <linux/smp_lock.h> 112 #include <linux/wrapper.h> 113 #include <asm/uaccess.h> 114 #include <asm/hardirq.h> 118 /* --------------------------------------------------------------------- */ 120 #undef OSS_DOCUMENTED_MIXER_SEMANTICS 122 /* --------------------------------------------------------------------- */ 124 #ifndef PCI_VENDOR_ID_S3 125 #define PCI_VENDOR_ID_S3 0x5333 127 #ifndef PCI_DEVICE_ID_S3_SONICVIBES 128 #define PCI_DEVICE_ID_S3_SONICVIBES 0xca00 131 #define SV_MAGIC ((PCI_VENDOR_ID_S3<<16)|PCI_DEVICE_ID_S3_SONICVIBES) 133 #define SV_EXTENT_SB 0x10 134 #define SV_EXTENT_ENH 0x10 135 #define SV_EXTENT_SYNTH 0x4 136 #define SV_EXTENT_MIDI 0x4 137 #define SV_EXTENT_GAME 0x8 138 #define SV_EXTENT_DMA 0x10 141 * we are not a bridge and thus use a resource for DDMA that is used for bridges but 142 * left empty for normal devices 144 #define RESOURCE_SB 0 145 #define RESOURCE_ENH 1 146 #define RESOURCE_SYNTH 2 147 #define RESOURCE_MIDI 3 148 #define RESOURCE_GAME 4 149 #define RESOURCE_DDMA 7 151 #define SV_MIDI_DATA 0 152 #define SV_MIDI_COMMAND 1 153 #define SV_MIDI_STATUS 1 155 #define SV_DMA_ADDR0 0 156 #define SV_DMA_ADDR1 1 157 #define SV_DMA_ADDR2 2 158 #define SV_DMA_ADDR3 3 159 #define SV_DMA_COUNT0 4 160 #define SV_DMA_COUNT1 5 161 #define SV_DMA_COUNT2 6 162 #define SV_DMA_MODE 0xb 163 #define SV_DMA_RESET 0xd 164 #define SV_DMA_MASK 0xf 167 * DONT reset the DMA controllers unless you understand 168 * the reset semantics. Assuming reset semantics as in 169 * the 8237 does not work. 172 #define DMA_MODE_AUTOINIT 0x10 173 #define DMA_MODE_READ 0x44/* I/O to memory, no autoinit, increment, single mode */ 174 #define DMA_MODE_WRITE 0x48/* memory to I/O, no autoinit, increment, single mode */ 176 #define SV_CODEC_CONTROL 0 177 #define SV_CODEC_INTMASK 1 178 #define SV_CODEC_STATUS 2 179 #define SV_CODEC_IADDR 4 180 #define SV_CODEC_IDATA 5 182 #define SV_CCTRL_RESET 0x80 183 #define SV_CCTRL_INTADRIVE 0x20 184 #define SV_CCTRL_WAVETABLE 0x08 185 #define SV_CCTRL_REVERB 0x04 186 #define SV_CCTRL_ENHANCED 0x01 188 #define SV_CINTMASK_DMAA 0x01 189 #define SV_CINTMASK_DMAC 0x04 190 #define SV_CINTMASK_SPECIAL 0x08 191 #define SV_CINTMASK_UPDOWN 0x40 192 #define SV_CINTMASK_MIDI 0x80 194 #define SV_CSTAT_DMAA 0x01 195 #define SV_CSTAT_DMAC 0x04 196 #define SV_CSTAT_SPECIAL 0x08 197 #define SV_CSTAT_UPDOWN 0x40 198 #define SV_CSTAT_MIDI 0x80 200 #define SV_CIADDR_TRD 0x80 201 #define SV_CIADDR_MCE 0x40 203 /* codec indirect registers */ 204 #define SV_CIMIX_ADCINL 0x00 205 #define SV_CIMIX_ADCINR 0x01 206 #define SV_CIMIX_AUX1INL 0x02 207 #define SV_CIMIX_AUX1INR 0x03 208 #define SV_CIMIX_CDINL 0x04 209 #define SV_CIMIX_CDINR 0x05 210 #define SV_CIMIX_LINEINL 0x06 211 #define SV_CIMIX_LINEINR 0x07 212 #define SV_CIMIX_MICIN 0x08 213 #define SV_CIMIX_SYNTHINL 0x0A 214 #define SV_CIMIX_SYNTHINR 0x0B 215 #define SV_CIMIX_AUX2INL 0x0C 216 #define SV_CIMIX_AUX2INR 0x0D 217 #define SV_CIMIX_ANALOGINL 0x0E 218 #define SV_CIMIX_ANALOGINR 0x0F 219 #define SV_CIMIX_PCMINL 0x10 220 #define SV_CIMIX_PCMINR 0x11 222 #define SV_CIGAMECONTROL 0x09 223 #define SV_CIDATAFMT 0x12 224 #define SV_CIENABLE 0x13 225 #define SV_CIUPDOWN 0x14 226 #define SV_CIREVISION 0x15 227 #define SV_CIADCOUTPUT 0x16 228 #define SV_CIDMAABASECOUNT1 0x18 229 #define SV_CIDMAABASECOUNT0 0x19 230 #define SV_CIDMACBASECOUNT1 0x1c 231 #define SV_CIDMACBASECOUNT0 0x1d 232 #define SV_CIPCMSR0 0x1e 233 #define SV_CIPCMSR1 0x1f 234 #define SV_CISYNTHSR0 0x20 235 #define SV_CISYNTHSR1 0x21 236 #define SV_CIADCCLKSOURCE 0x22 237 #define SV_CIADCALTSR 0x23 238 #define SV_CIADCPLLM 0x24 239 #define SV_CIADCPLLN 0x25 240 #define SV_CISYNTHPLLM 0x26 241 #define SV_CISYNTHPLLN 0x27 242 #define SV_CIUARTCONTROL 0x2a 243 #define SV_CIDRIVECONTROL 0x2b 244 #define SV_CISRSSPACE 0x2c 245 #define SV_CISRSCENTER 0x2d 246 #define SV_CIWAVETABLESRC 0x2e 247 #define SV_CIANALOGPWRDOWN 0x30 248 #define SV_CIDIGITALPWRDOWN 0x31 251 #define SV_CIMIX_ADCSRC_CD 0x20 252 #define SV_CIMIX_ADCSRC_DAC 0x40 253 #define SV_CIMIX_ADCSRC_AUX2 0x60 254 #define SV_CIMIX_ADCSRC_LINE 0x80 255 #define SV_CIMIX_ADCSRC_AUX1 0xa0 256 #define SV_CIMIX_ADCSRC_MIC 0xc0 257 #define SV_CIMIX_ADCSRC_MIXOUT 0xe0 258 #define SV_CIMIX_ADCSRC_MASK 0xe0 260 #define SV_CFMT_STEREO 0x01 261 #define SV_CFMT_16BIT 0x02 262 #define SV_CFMT_MASK 0x03 263 #define SV_CFMT_ASHIFT 0 264 #define SV_CFMT_CSHIFT 4 266 static const unsigned sample_size
[] = {1,2,2,4}; 267 static const unsigned sample_shift
[] = {0,1,1,2}; 269 #define SV_CENABLE_PPE 0x4 270 #define SV_CENABLE_RE 0x2 271 #define SV_CENABLE_PE 0x1 274 /* MIDI buffer sizes */ 276 #define MIDIINBUF 256 277 #define MIDIOUTBUF 256 279 #define FMODE_MIDI_SHIFT 2 280 #define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT) 281 #define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT) 283 #define FMODE_DMFM 0x10 285 /* --------------------------------------------------------------------- */ 291 /* list of sonicvibes devices */ 292 struct list_head devs
; 294 /* the corresponding pci_dev structure */ 297 /* soundcore stuff */ 303 /* hardware resources */ 304 unsigned long iosb
, ioenh
, iosynth
, iomidi
, iogame
;/* long for SPARC */ 305 unsigned int iodmaa
, iodmac
, irq
; 310 #ifndef OSS_DOCUMENTED_MIXER_SEMANTICS 311 unsigned short vol
[13]; 312 #endif/* OSS_DOCUMENTED_MIXER_SEMANTICS */ 316 unsigned int rateadc
, ratedac
; 317 unsigned char fmt
, enable
; 320 struct semaphore open_sem
; 322 wait_queue_head_t open_wait
; 330 unsigned hwptr
, swptr
; 331 unsigned total_bytes
; 333 unsigned error
;/* over/underrun */ 334 wait_queue_head_t wait
; 335 /* redundant, but makes calculations easier */ 338 unsigned fragsamples
; 342 unsigned endcleared
:1; 343 unsigned ossfragshift
; 345 unsigned subdivision
; 350 unsigned ird
, iwr
, icnt
; 351 unsigned ord
, owr
, ocnt
; 352 wait_queue_head_t iwait
; 353 wait_queue_head_t owait
; 354 struct timer_list timer
; 355 unsigned char ibuf
[MIDIINBUF
]; 356 unsigned char obuf
[MIDIOUTBUF
]; 360 /* --------------------------------------------------------------------- */ 362 staticLIST_HEAD(devs
); 363 static unsigned long wavetable_mem
=0; 365 /* --------------------------------------------------------------------- */ 367 extern __inline__
unsignedld2(unsigned int x
) 393 * hweightN: returns the hamming weight (i.e. the number 394 * of bits set) of a N-bit word 401 extern __inline__
unsigned inthweight32(unsigned int w
) 403 unsigned int res
= (w
&0x55555555) + ((w
>>1) &0x55555555); 404 res
= (res
&0x33333333) + ((res
>>2) &0x33333333); 405 res
= (res
&0x0F0F0F0F) + ((res
>>4) &0x0F0F0F0F); 406 res
= (res
&0x00FF00FF) + ((res
>>8) &0x00FF00FF); 407 return(res
&0x0000FFFF) + ((res
>>16) &0x0000FFFF); 410 /* --------------------------------------------------------------------- */ 413 * Why use byte IO? Nobody knows, but S3 does it also in their Windows driver. 418 static voidset_dmaa(struct sv_state
*s
,unsigned int addr
,unsigned int count
) 421 unsigned io
= s
->iodmaa
, u
; 424 for(u
=4; u
>0; u
--, addr
>>=8, io
++) 425 outb(addr
&0xff, io
); 426 for(u
=3; u
>0; u
--, count
>>=8, io
++) 427 outb(count
&0xff, io
); 430 outl(addr
, s
->iodmaa
+ SV_DMA_ADDR0
); 431 outl(count
, s
->iodmaa
+ SV_DMA_COUNT0
); 432 #endif/* DMABYTEIO */ 433 outb(0x18, s
->iodmaa
+ SV_DMA_MODE
); 436 static voidset_dmac(struct sv_state
*s
,unsigned int addr
,unsigned int count
) 439 unsigned io
= s
->iodmac
, u
; 443 for(u
=4; u
>0; u
--, addr
>>=8, io
++) 444 outb(addr
&0xff, io
); 445 for(u
=3; u
>0; u
--, count
>>=8, io
++) 446 outb(count
&0xff, io
); 450 outl(addr
, s
->iodmac
+ SV_DMA_ADDR0
); 451 outl(count
, s
->iodmac
+ SV_DMA_COUNT0
); 452 #endif/* DMABYTEIO */ 453 outb(0x14, s
->iodmac
+ SV_DMA_MODE
); 456 extern __inline__
unsignedget_dmaa(struct sv_state
*s
) 459 unsigned io
= s
->iodmaa
+6, v
=0, u
; 461 for(u
=3; u
>0; u
--, io
--) { 467 return(inl(s
->iodmaa
+ SV_DMA_COUNT0
) &0xffffff) +1; 468 #endif/* DMABYTEIO */ 471 extern __inline__
unsignedget_dmac(struct sv_state
*s
) 474 unsigned io
= s
->iodmac
+6, v
=0, u
; 476 for(u
=3; u
>0; u
--, io
--) { 482 return((inl(s
->iodmac
+ SV_DMA_COUNT0
) &0xffffff) +1) <<1; 483 #endif/* DMABYTEIO */ 486 static voidwrindir(struct sv_state
*s
,unsigned char idx
,unsigned char data
) 488 outb(idx
&0x3f, s
->ioenh
+ SV_CODEC_IADDR
); 490 outb(data
, s
->ioenh
+ SV_CODEC_IDATA
); 494 static unsigned charrdindir(struct sv_state
*s
,unsigned char idx
) 498 outb(idx
&0x3f, s
->ioenh
+ SV_CODEC_IADDR
); 500 v
=inb(s
->ioenh
+ SV_CODEC_IDATA
); 505 static voidset_fmt(struct sv_state
*s
,unsigned char mask
,unsigned char data
) 509 spin_lock_irqsave(&s
->lock
, flags
); 510 outb(SV_CIDATAFMT
| SV_CIADDR_MCE
, s
->ioenh
+ SV_CODEC_IADDR
); 512 s
->fmt
=inb(s
->ioenh
+ SV_CODEC_IDATA
); 515 s
->fmt
= (s
->fmt
& mask
) | data
; 516 outb(s
->fmt
, s
->ioenh
+ SV_CODEC_IDATA
); 518 outb(0, s
->ioenh
+ SV_CODEC_IADDR
); 519 spin_unlock_irqrestore(&s
->lock
, flags
); 523 static voidfrobindir(struct sv_state
*s
,unsigned char idx
,unsigned char mask
,unsigned char data
) 525 outb(idx
&0x3f, s
->ioenh
+ SV_CODEC_IADDR
); 527 outb((inb(s
->ioenh
+ SV_CODEC_IDATA
) & mask
) ^ data
, s
->ioenh
+ SV_CODEC_IDATA
); 531 #define REFFREQUENCY 24576000 533 #define FULLRATE 48000 535 static unsignedsetpll(struct sv_state
*s
,unsigned char reg
,unsigned rate
) 538 unsigned char r
, m
=0, n
=0; 539 unsigned xm
, xn
, xr
, xd
, metric
= ~0U; 540 /* the warnings about m and n used uninitialized are bogus and may safely be ignored */ 542 if(rate
<625000/ADCMULT
) 543 rate
=625000/ADCMULT
; 544 if(rate
>150000000/ADCMULT
) 545 rate
=150000000/ADCMULT
; 546 /* slight violation of specs, needed for continuous sampling rates */ 547 for(r
=0; rate
<75000000/ADCMULT
; r
+=0x20, rate
<<=1); 548 for(xn
=3; xn
<35; xn
++) 549 for(xm
=3; xm
<130; xm
++) { 550 xr
= REFFREQUENCY
/ADCMULT
* xm
/ xn
; 551 xd
=abs((signed)(xr
- rate
)); 559 spin_lock_irqsave(&s
->lock
, flags
); 560 outb(reg
, s
->ioenh
+ SV_CODEC_IADDR
); 562 outb(m
, s
->ioenh
+ SV_CODEC_IDATA
); 564 outb(reg
+1, s
->ioenh
+ SV_CODEC_IADDR
); 566 outb(r
| n
, s
->ioenh
+ SV_CODEC_IDATA
); 567 spin_unlock_irqrestore(&s
->lock
, flags
); 569 return(REFFREQUENCY
/ADCMULT
* (m
+2) / (n
+2)) >> ((r
>>5) &7); 574 static unsignedgetpll(struct sv_state
*s
,unsigned char reg
) 580 spin_lock_irqsave(&s
->lock
, flags
); 581 outb(reg
, s
->ioenh
+ SV_CODEC_IADDR
); 583 m
=inb(s
->ioenh
+ SV_CODEC_IDATA
); 585 outb(reg
+1, s
->ioenh
+ SV_CODEC_IADDR
); 587 n
=inb(s
->ioenh
+ SV_CODEC_IDATA
); 588 spin_unlock_irqrestore(&s
->lock
, flags
); 590 return(REFFREQUENCY
/ADCMULT
* (m
+2) / ((n
&0x1f) +2)) >> ((n
>>5) &7); 595 static voidset_dac_rate(struct sv_state
*s
,unsigned rate
) 604 div
= (rate
*65536+ FULLRATE
/2) / FULLRATE
; 607 spin_lock_irqsave(&s
->lock
, flags
); 608 wrindir(s
, SV_CIPCMSR1
, div
>>8); 609 wrindir(s
, SV_CIPCMSR0
, div
); 610 spin_unlock_irqrestore(&s
->lock
, flags
); 611 s
->ratedac
= (div
* FULLRATE
+32768) /65536; 614 static voidset_adc_rate(struct sv_state
*s
,unsigned rate
) 617 unsigned rate1
, rate2
, div
; 623 rate1
=setpll(s
, SV_CIADCPLLM
, rate
); 624 div
= (48000+ rate
/2) / rate
; 627 rate2
= (48000+ div
/2) / div
; 628 spin_lock_irqsave(&s
->lock
, flags
); 629 wrindir(s
, SV_CIADCALTSR
, (div
-1) <<4); 630 if(abs((signed)(rate
-rate2
)) <=abs((signed)(rate
-rate1
))) { 631 wrindir(s
, SV_CIADCCLKSOURCE
,0x10); 634 wrindir(s
, SV_CIADCCLKSOURCE
,0x00); 637 spin_unlock_irqrestore(&s
->lock
, flags
); 640 /* --------------------------------------------------------------------- */ 642 extern inlinevoidstop_adc(struct sv_state
*s
) 646 spin_lock_irqsave(&s
->lock
, flags
); 647 s
->enable
&= ~SV_CENABLE_RE
; 648 wrindir(s
, SV_CIENABLE
, s
->enable
); 649 spin_unlock_irqrestore(&s
->lock
, flags
); 652 extern inlinevoidstop_dac(struct sv_state
*s
) 656 spin_lock_irqsave(&s
->lock
, flags
); 657 s
->enable
&= ~(SV_CENABLE_PPE
| SV_CENABLE_PE
); 658 wrindir(s
, SV_CIENABLE
, s
->enable
); 659 spin_unlock_irqrestore(&s
->lock
, flags
); 662 static voidstart_dac(struct sv_state
*s
) 666 spin_lock_irqsave(&s
->lock
, flags
); 667 if((s
->dma_dac
.mapped
|| s
->dma_dac
.count
>0) && s
->dma_dac
.ready
) { 668 s
->enable
= (s
->enable
& ~SV_CENABLE_PPE
) | SV_CENABLE_PE
; 669 wrindir(s
, SV_CIENABLE
, s
->enable
); 671 spin_unlock_irqrestore(&s
->lock
, flags
); 674 static voidstart_adc(struct sv_state
*s
) 678 spin_lock_irqsave(&s
->lock
, flags
); 679 if((s
->dma_adc
.mapped
|| s
->dma_adc
.count
< (signed)(s
->dma_adc
.dmasize
-2*s
->dma_adc
.fragsize
)) 680 && s
->dma_adc
.ready
) { 681 s
->enable
|= SV_CENABLE_RE
; 682 wrindir(s
, SV_CIENABLE
, s
->enable
); 684 spin_unlock_irqrestore(&s
->lock
, flags
); 687 /* --------------------------------------------------------------------- */ 689 #define DMABUF_DEFAULTORDER (17-PAGE_SHIFT) 690 #define DMABUF_MINORDER 1 692 static voiddealloc_dmabuf(struct sv_state
*s
,struct dmabuf
*db
) 694 struct page
*page
, *pend
; 697 /* undo marking the pages as reserved */ 698 pend
=virt_to_page(db
->rawbuf
+ (PAGE_SIZE
<< db
->buforder
) -1); 699 for(page
=virt_to_page(db
->rawbuf
); page
<= pend
; page
++) 700 mem_map_unreserve(page
); 701 pci_free_consistent(s
->dev
, PAGE_SIZE
<< db
->buforder
, db
->rawbuf
, db
->dmaaddr
); 704 db
->mapped
= db
->ready
=0; 708 /* DMAA is used for playback, DMAC is used for recording */ 710 static intprog_dmabuf(struct sv_state
*s
,unsigned rec
) 712 struct dmabuf
*db
= rec
? &s
->dma_adc
: &s
->dma_dac
; 713 unsigned rate
= rec
? s
->rateadc
: s
->ratedac
; 717 struct page
*page
, *pend
; 721 spin_lock_irqsave(&s
->lock
, flags
); 724 s
->enable
&= ~SV_CENABLE_RE
; 725 fmt
>>= SV_CFMT_CSHIFT
; 727 s
->enable
&= ~SV_CENABLE_PE
; 728 fmt
>>= SV_CFMT_ASHIFT
; 730 wrindir(s
, SV_CIENABLE
, s
->enable
); 731 spin_unlock_irqrestore(&s
->lock
, flags
); 733 db
->hwptr
= db
->swptr
= db
->total_bytes
= db
->count
= db
->error
= db
->endcleared
=0; 735 db
->ready
= db
->mapped
=0; 736 for(order
= DMABUF_DEFAULTORDER
; order
>= DMABUF_MINORDER
; order
--) 737 if((db
->rawbuf
=pci_alloc_consistent(s
->dev
, PAGE_SIZE
<< order
, &db
->dmaaddr
))) 741 db
->buforder
= order
; 742 if((virt_to_bus(db
->rawbuf
) ^ (virt_to_bus(db
->rawbuf
) + (PAGE_SIZE
<< db
->buforder
) -1)) & ~0xffff) 743 printk(KERN_DEBUG
"sv: DMA buffer crosses 64k boundary: busaddr 0x%lx size %ld\n", 744 virt_to_bus(db
->rawbuf
), PAGE_SIZE
<< db
->buforder
); 745 if((virt_to_bus(db
->rawbuf
) + (PAGE_SIZE
<< db
->buforder
) -1) & ~0xffffff) 746 printk(KERN_DEBUG
"sv: DMA buffer beyond 16MB: busaddr 0x%lx size %ld\n", 747 virt_to_bus(db
->rawbuf
), PAGE_SIZE
<< db
->buforder
); 748 /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */ 749 pend
=virt_to_page(db
->rawbuf
+ (PAGE_SIZE
<< db
->buforder
) -1); 750 for(page
=virt_to_page(db
->rawbuf
); page
<= pend
; page
++) 751 mem_map_reserve(page
); 753 bytepersec
= rate
<< sample_shift
[fmt
]; 754 bufs
= PAGE_SIZE
<< db
->buforder
; 755 if(db
->ossfragshift
) { 756 if((1000<< db
->ossfragshift
) < bytepersec
) 757 db
->fragshift
=ld2(bytepersec
/1000); 759 db
->fragshift
= db
->ossfragshift
; 761 db
->fragshift
=ld2(bytepersec
/100/(db
->subdivision
? db
->subdivision
:1)); 765 db
->numfrag
= bufs
>> db
->fragshift
; 766 while(db
->numfrag
<4&& db
->fragshift
>3) { 768 db
->numfrag
= bufs
>> db
->fragshift
; 770 db
->fragsize
=1<< db
->fragshift
; 771 if(db
->ossmaxfrags
>=4&& db
->ossmaxfrags
< db
->numfrag
) 772 db
->numfrag
= db
->ossmaxfrags
; 773 db
->fragsamples
= db
->fragsize
>> sample_shift
[fmt
]; 774 db
->dmasize
= db
->numfrag
<< db
->fragshift
; 775 memset(db
->rawbuf
, (fmt
& SV_CFMT_16BIT
) ?0:0x80, db
->dmasize
); 776 spin_lock_irqsave(&s
->lock
, flags
); 778 set_dmac(s
, db
->dmaaddr
, db
->numfrag
<< db
->fragshift
); 779 /* program enhanced mode registers */ 780 wrindir(s
, SV_CIDMACBASECOUNT1
, (db
->fragsamples
-1) >>8); 781 wrindir(s
, SV_CIDMACBASECOUNT0
, db
->fragsamples
-1); 783 set_dmaa(s
, db
->dmaaddr
, db
->numfrag
<< db
->fragshift
); 784 /* program enhanced mode registers */ 785 wrindir(s
, SV_CIDMAABASECOUNT1
, (db
->fragsamples
-1) >>8); 786 wrindir(s
, SV_CIDMAABASECOUNT0
, db
->fragsamples
-1); 788 spin_unlock_irqrestore(&s
->lock
, flags
); 793 extern __inline__
voidclear_advance(struct sv_state
*s
) 795 unsigned char c
= (s
->fmt
& (SV_CFMT_16BIT
<< SV_CFMT_ASHIFT
)) ?0:0x80; 796 unsigned char*buf
= s
->dma_dac
.rawbuf
; 797 unsigned bsize
= s
->dma_dac
.dmasize
; 798 unsigned bptr
= s
->dma_dac
.swptr
; 799 unsigned len
= s
->dma_dac
.fragsize
; 801 if(bptr
+ len
> bsize
) { 802 unsigned x
= bsize
- bptr
; 803 memset(buf
+ bptr
, c
, x
); 807 memset(buf
+ bptr
, c
, len
); 810 /* call with spinlock held! */ 811 static voidsv_update_ptr(struct sv_state
*s
) 816 /* update ADC pointer */ 817 if(s
->dma_adc
.ready
) { 818 hwptr
= (s
->dma_adc
.dmasize
-get_dmac(s
)) % s
->dma_adc
.dmasize
; 819 diff
= (s
->dma_adc
.dmasize
+ hwptr
- s
->dma_adc
.hwptr
) % s
->dma_adc
.dmasize
; 820 s
->dma_adc
.hwptr
= hwptr
; 821 s
->dma_adc
.total_bytes
+= diff
; 822 s
->dma_adc
.count
+= diff
; 823 if(s
->dma_adc
.count
>= (signed)s
->dma_adc
.fragsize
) 824 wake_up(&s
->dma_adc
.wait
); 825 if(!s
->dma_adc
.mapped
) { 826 if(s
->dma_adc
.count
> (signed)(s
->dma_adc
.dmasize
- ((3* s
->dma_adc
.fragsize
) >>1))) { 827 s
->enable
&= ~SV_CENABLE_RE
; 828 wrindir(s
, SV_CIENABLE
, s
->enable
); 833 /* update DAC pointer */ 834 if(s
->dma_dac
.ready
) { 835 hwptr
= (s
->dma_dac
.dmasize
-get_dmaa(s
)) % s
->dma_dac
.dmasize
; 836 diff
= (s
->dma_dac
.dmasize
+ hwptr
- s
->dma_dac
.hwptr
) % s
->dma_dac
.dmasize
; 837 s
->dma_dac
.hwptr
= hwptr
; 838 s
->dma_dac
.total_bytes
+= diff
; 839 if(s
->dma_dac
.mapped
) { 840 s
->dma_dac
.count
+= diff
; 841 if(s
->dma_dac
.count
>= (signed)s
->dma_dac
.fragsize
) 842 wake_up(&s
->dma_dac
.wait
); 844 s
->dma_dac
.count
-= diff
; 845 if(s
->dma_dac
.count
<=0) { 846 s
->enable
&= ~SV_CENABLE_PE
; 847 wrindir(s
, SV_CIENABLE
, s
->enable
); 849 }else if(s
->dma_dac
.count
<= (signed)s
->dma_dac
.fragsize
&& !s
->dma_dac
.endcleared
) { 851 s
->dma_dac
.endcleared
=1; 853 if(s
->dma_dac
.count
+ (signed)s
->dma_dac
.fragsize
<= (signed)s
->dma_dac
.dmasize
) 854 wake_up(&s
->dma_dac
.wait
); 859 /* hold spinlock for the following! */ 860 static voidsv_handle_midi(struct sv_state
*s
) 866 while(!(inb(s
->iomidi
+1) &0x80)) { 868 if(s
->midi
.icnt
< MIDIINBUF
) { 869 s
->midi
.ibuf
[s
->midi
.iwr
] = ch
; 870 s
->midi
.iwr
= (s
->midi
.iwr
+1) % MIDIINBUF
; 876 wake_up(&s
->midi
.iwait
); 878 while(!(inb(s
->iomidi
+1) &0x40) && s
->midi
.ocnt
>0) { 879 outb(s
->midi
.obuf
[s
->midi
.ord
], s
->iomidi
); 880 s
->midi
.ord
= (s
->midi
.ord
+1) % MIDIOUTBUF
; 882 if(s
->midi
.ocnt
< MIDIOUTBUF
-16) 886 wake_up(&s
->midi
.owait
); 889 static voidsv_interrupt(int irq
,void*dev_id
,struct pt_regs
*regs
) 891 struct sv_state
*s
= (struct sv_state
*)dev_id
; 894 /* fastpath out, to ease interrupt sharing */ 895 intsrc
=inb(s
->ioenh
+ SV_CODEC_STATUS
); 896 if(!(intsrc
& (SV_CSTAT_DMAA
| SV_CSTAT_DMAC
| SV_CSTAT_MIDI
))) 901 spin_unlock(&s
->lock
); 904 static voidsv_midi_timer(unsigned long data
) 906 struct sv_state
*s
= (struct sv_state
*)data
; 909 spin_lock_irqsave(&s
->lock
, flags
); 911 spin_unlock_irqrestore(&s
->lock
, flags
); 912 s
->midi
.timer
.expires
= jiffies
+1; 913 add_timer(&s
->midi
.timer
); 916 /* --------------------------------------------------------------------- */ 918 static const char invalid_magic
[] = KERN_CRIT
"sv: invalid magic value\n"; 920 #define VALIDATE_STATE(s) \ 922 if (!(s) || (s)->magic != SV_MAGIC) { \ 923 printk(invalid_magic); \ 928 /* --------------------------------------------------------------------- */ 932 #define MT_4MUTEMONO 3 940 } mixtable
[SOUND_MIXER_NRDEVICES
] = { 941 [SOUND_MIXER_RECLEV
] = { SV_CIMIX_ADCINL
, SV_CIMIX_ADCINR
, MT_4
,0}, 942 [SOUND_MIXER_LINE1
] = { SV_CIMIX_AUX1INL
, SV_CIMIX_AUX1INR
, MT_5MUTE
,5}, 943 [SOUND_MIXER_CD
] = { SV_CIMIX_CDINL
, SV_CIMIX_CDINR
, MT_5MUTE
,1}, 944 [SOUND_MIXER_LINE
] = { SV_CIMIX_LINEINL
, SV_CIMIX_LINEINR
, MT_5MUTE
,4}, 945 [SOUND_MIXER_MIC
] = { SV_CIMIX_MICIN
, SV_CIMIX_ADCINL
, MT_4MUTEMONO
,6}, 946 [SOUND_MIXER_SYNTH
] = { SV_CIMIX_SYNTHINL
, SV_CIMIX_SYNTHINR
, MT_5MUTE
,2}, 947 [SOUND_MIXER_LINE2
] = { SV_CIMIX_AUX2INL
, SV_CIMIX_AUX2INR
, MT_5MUTE
,3}, 948 [SOUND_MIXER_VOLUME
] = { SV_CIMIX_ANALOGINL
, SV_CIMIX_ANALOGINR
, MT_5MUTE
,7}, 949 [SOUND_MIXER_PCM
] = { SV_CIMIX_PCMINL
, SV_CIMIX_PCMINR
, MT_6MUTE
,0} 952 #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS 954 static intreturn_mixval(struct sv_state
*s
,unsigned i
,int*arg
) 957 unsigned char l
, r
, rl
, rr
; 959 spin_lock_irqsave(&s
->lock
, flags
); 960 l
=rdindir(s
, mixtable
[i
].left
); 961 r
=rdindir(s
, mixtable
[i
].right
); 962 spin_unlock_irqrestore(&s
->lock
, flags
); 963 switch(mixtable
[i
].type
) { 986 rl
=100-3* (l
&63) /2; 987 rr
=100-3* (r
&63) /2; 994 returnput_user((rr
<<8) | rl
, arg
); 997 #else/* OSS_DOCUMENTED_MIXER_SEMANTICS */ 999 static const unsigned char volidx
[SOUND_MIXER_NRDEVICES
] = 1001 [SOUND_MIXER_RECLEV
] =1, 1002 [SOUND_MIXER_LINE1
] =2, 1003 [SOUND_MIXER_CD
] =3, 1004 [SOUND_MIXER_LINE
] =4, 1005 [SOUND_MIXER_MIC
] =5, 1006 [SOUND_MIXER_SYNTH
] =6, 1007 [SOUND_MIXER_LINE2
] =7, 1008 [SOUND_MIXER_VOLUME
] =8, 1009 [SOUND_MIXER_PCM
] =9 1012 #endif/* OSS_DOCUMENTED_MIXER_SEMANTICS */ 1014 static unsignedmixer_recmask(struct sv_state
*s
) 1016 unsigned long flags
; 1019 spin_lock_irqsave(&s
->lock
, flags
); 1020 j
=rdindir(s
, SV_CIMIX_ADCINL
) >>5; 1021 spin_unlock_irqrestore(&s
->lock
, flags
); 1023 for(i
=0; i
< SOUND_MIXER_NRDEVICES
&& mixtable
[i
].rec
!= j
; i
++); 1027 static intmixer_ioctl(struct sv_state
*s
,unsigned int cmd
,unsigned long arg
) 1029 unsigned long flags
; 1031 unsigned char l
, r
, rl
, rr
; 1034 if(cmd
== SOUND_MIXER_INFO
) { 1036 strncpy(info
.id
,"SonicVibes",sizeof(info
.id
)); 1037 strncpy(info
.name
,"S3 SonicVibes",sizeof(info
.name
)); 1038 info
.modify_counter
= s
->mix
.modcnt
; 1039 if(copy_to_user((void*)arg
, &info
,sizeof(info
))) 1043 if(cmd
== SOUND_OLD_MIXER_INFO
) { 1044 _old_mixer_info info
; 1045 strncpy(info
.id
,"SonicVibes",sizeof(info
.id
)); 1046 strncpy(info
.name
,"S3 SonicVibes",sizeof(info
.name
)); 1047 if(copy_to_user((void*)arg
, &info
,sizeof(info
))) 1051 if(cmd
== OSS_GETVERSION
) 1052 returnput_user(SOUND_VERSION
, (int*)arg
); 1053 if(cmd
== SOUND_MIXER_PRIVATE1
) {/* SRS settings */ 1054 if(get_user(val
, (int*)arg
)) 1056 spin_lock_irqsave(&s
->lock
, flags
); 1059 l
=4- ((val
>>2) &7); 1062 r
=4- ((val
>>5) &7); 1065 wrindir(s
, SV_CISRSSPACE
, l
); 1066 wrindir(s
, SV_CISRSCENTER
, r
); 1068 wrindir(s
, SV_CISRSSPACE
,0x80); 1070 l
=rdindir(s
, SV_CISRSSPACE
); 1071 r
=rdindir(s
, SV_CISRSCENTER
); 1072 spin_unlock_irqrestore(&s
->lock
, flags
); 1074 returnput_user(0, (int*)arg
); 1075 returnput_user(((4- (l
&7)) <<2) | ((4- (r
&7)) <<5) |2, (int*)arg
); 1077 if(_IOC_TYPE(cmd
) !='M'||_SIOC_SIZE(cmd
) !=sizeof(int)) 1079 if(_SIOC_DIR(cmd
) == _SIOC_READ
) { 1080 switch(_IOC_NR(cmd
)) { 1081 case SOUND_MIXER_RECSRC
:/* Arg contains a bit for each recording source */ 1082 returnput_user(mixer_recmask(s
), (int*)arg
); 1084 case SOUND_MIXER_DEVMASK
:/* Arg contains a bit for each supported device */ 1085 for(val
= i
=0; i
< SOUND_MIXER_NRDEVICES
; i
++) 1086 if(mixtable
[i
].type
) 1088 returnput_user(val
, (int*)arg
); 1090 case SOUND_MIXER_RECMASK
:/* Arg contains a bit for each supported recording source */ 1091 for(val
= i
=0; i
< SOUND_MIXER_NRDEVICES
; i
++) 1094 returnput_user(val
, (int*)arg
); 1096 case SOUND_MIXER_STEREODEVS
:/* Mixer channels supporting stereo */ 1097 for(val
= i
=0; i
< SOUND_MIXER_NRDEVICES
; i
++) 1098 if(mixtable
[i
].type
&& mixtable
[i
].type
!= MT_4MUTEMONO
) 1100 returnput_user(val
, (int*)arg
); 1102 case SOUND_MIXER_CAPS
: 1103 returnput_user(SOUND_CAP_EXCL_INPUT
, (int*)arg
); 1107 if(i
>= SOUND_MIXER_NRDEVICES
|| !mixtable
[i
].type
) 1109 #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS 1110 returnreturn_mixval(s
, i
, (int*)arg
); 1111 #else/* OSS_DOCUMENTED_MIXER_SEMANTICS */ 1114 returnput_user(s
->mix
.vol
[volidx
[i
]-1], (int*)arg
); 1115 #endif/* OSS_DOCUMENTED_MIXER_SEMANTICS */ 1118 if(_SIOC_DIR(cmd
) != (_SIOC_READ
|_SIOC_WRITE
)) 1121 switch(_IOC_NR(cmd
)) { 1122 case SOUND_MIXER_RECSRC
:/* Arg contains a bit for each recording source */ 1123 if(get_user(val
, (int*)arg
)) 1127 return0;/*val = mixer_recmask(s);*/ 1129 val
&= ~mixer_recmask(s
); 1130 for(i
=0; i
< SOUND_MIXER_NRDEVICES
; i
++) { 1131 if(!(val
& (1<< i
))) 1136 if(!mixtable
[i
].rec
) 1138 spin_lock_irqsave(&s
->lock
, flags
); 1139 frobindir(s
, SV_CIMIX_ADCINL
,0x1f, mixtable
[i
].rec
<<5); 1140 frobindir(s
, SV_CIMIX_ADCINR
,0x1f, mixtable
[i
].rec
<<5); 1141 spin_unlock_irqrestore(&s
->lock
, flags
); 1146 if(i
>= SOUND_MIXER_NRDEVICES
|| !mixtable
[i
].type
) 1148 if(get_user(val
, (int*)arg
)) 1151 r
= (val
>>8) &0xff; 1152 if(mixtable
[i
].type
== MT_4MUTEMONO
) 1158 spin_lock_irqsave(&s
->lock
, flags
); 1159 switch(mixtable
[i
].type
) { 1165 frobindir(s
, mixtable
[i
].left
,0xf0, l
/6); 1166 frobindir(s
, mixtable
[i
].right
,0xf0, l
/6); 1180 wrindir(s
, mixtable
[i
].left
, rl
); 1181 frobindir(s
, mixtable
[i
].right
, ~0x10, rr
); 1193 wrindir(s
, mixtable
[i
].left
, rl
); 1194 wrindir(s
, mixtable
[i
].right
, rr
); 1206 wrindir(s
, mixtable
[i
].left
, rl
); 1207 wrindir(s
, mixtable
[i
].right
, rr
); 1210 spin_unlock_irqrestore(&s
->lock
, flags
); 1211 #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS 1212 returnreturn_mixval(s
, i
, (int*)arg
); 1213 #else/* OSS_DOCUMENTED_MIXER_SEMANTICS */ 1216 s
->mix
.vol
[volidx
[i
]-1] = val
; 1217 returnput_user(s
->mix
.vol
[volidx
[i
]-1], (int*)arg
); 1218 #endif/* OSS_DOCUMENTED_MIXER_SEMANTICS */ 1222 /* --------------------------------------------------------------------- */ 1224 static loff_t
sv_llseek(struct file
*file
, loff_t offset
,int origin
) 1229 /* --------------------------------------------------------------------- */ 1231 static intsv_open_mixdev(struct inode
*inode
,struct file
*file
) 1233 int minor
=MINOR(inode
->i_rdev
); 1234 struct list_head
*list
; 1237 for(list
= devs
.next
; ; list
= list
->next
) { 1240 s
=list_entry(list
,struct sv_state
, devs
); 1241 if(s
->dev_mixer
== minor
) 1245 file
->private_data
= s
; 1249 static intsv_release_mixdev(struct inode
*inode
,struct file
*file
) 1251 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 1257 static intsv_ioctl_mixdev(struct inode
*inode
,struct file
*file
,unsigned int cmd
,unsigned long arg
) 1259 returnmixer_ioctl((struct sv_state
*)file
->private_data
, cmd
, arg
); 1262 static/*const*/struct file_operations sv_mixer_fops
= { 1265 ioctl
: sv_ioctl_mixdev
, 1266 open
: sv_open_mixdev
, 1267 release
: sv_release_mixdev
, 1270 /* --------------------------------------------------------------------- */ 1272 static intdrain_dac(struct sv_state
*s
,int nonblock
) 1274 DECLARE_WAITQUEUE(wait
, current
); 1275 unsigned long flags
; 1278 if(s
->dma_dac
.mapped
|| !s
->dma_dac
.ready
) 1280 add_wait_queue(&s
->dma_dac
.wait
, &wait
); 1282 __set_current_state(TASK_INTERRUPTIBLE
); 1283 spin_lock_irqsave(&s
->lock
, flags
); 1284 count
= s
->dma_dac
.count
; 1285 spin_unlock_irqrestore(&s
->lock
, flags
); 1288 if(signal_pending(current
)) 1291 remove_wait_queue(&s
->dma_dac
.wait
, &wait
); 1292 set_current_state(TASK_RUNNING
); 1295 tmo
=3* HZ
* (count
+ s
->dma_dac
.fragsize
) /2/ s
->ratedac
; 1296 tmo
>>= sample_shift
[(s
->fmt
>> SV_CFMT_ASHIFT
) & SV_CFMT_MASK
]; 1297 if(!schedule_timeout(tmo
+1)) 1298 printk(KERN_DEBUG
"sv: dma timed out??\n"); 1300 remove_wait_queue(&s
->dma_dac
.wait
, &wait
); 1301 set_current_state(TASK_RUNNING
); 1302 if(signal_pending(current
)) 1307 /* --------------------------------------------------------------------- */ 1309 static ssize_t
sv_read(struct file
*file
,char*buffer
,size_t count
, loff_t
*ppos
) 1311 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 1312 DECLARE_WAITQUEUE(wait
, current
); 1314 unsigned long flags
; 1319 if(ppos
!= &file
->f_pos
) 1321 if(s
->dma_adc
.mapped
) 1323 if(!s
->dma_adc
.ready
&& (ret
=prog_dmabuf(s
,1))) 1325 if(!access_ok(VERIFY_WRITE
, buffer
, count
)) 1329 spin_lock_irqsave(&s
->lock
, flags
); 1331 spin_unlock_irqrestore(&s
->lock
, flags
); 1333 add_wait_queue(&s
->dma_adc
.wait
, &wait
); 1335 spin_lock_irqsave(&s
->lock
, flags
); 1336 swptr
= s
->dma_adc
.swptr
; 1337 cnt
= s
->dma_adc
.dmasize
-swptr
; 1338 if(s
->dma_adc
.count
< cnt
) 1339 cnt
= s
->dma_adc
.count
; 1341 __set_current_state(TASK_INTERRUPTIBLE
); 1342 spin_unlock_irqrestore(&s
->lock
, flags
); 1347 if(file
->f_flags
& O_NONBLOCK
) { 1352 if(!schedule_timeout(HZ
)) { 1353 printk(KERN_DEBUG
"sv: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", 1354 s
->dma_adc
.dmasize
, s
->dma_adc
.fragsize
, s
->dma_adc
.count
, 1355 s
->dma_adc
.hwptr
, s
->dma_adc
.swptr
); 1357 spin_lock_irqsave(&s
->lock
, flags
); 1358 set_dmac(s
,virt_to_bus(s
->dma_adc
.rawbuf
), s
->dma_adc
.numfrag
<< s
->dma_adc
.fragshift
); 1359 /* program enhanced mode registers */ 1360 wrindir(s
, SV_CIDMACBASECOUNT1
, (s
->dma_adc
.fragsamples
-1) >>8); 1361 wrindir(s
, SV_CIDMACBASECOUNT0
, s
->dma_adc
.fragsamples
-1); 1362 s
->dma_adc
.count
= s
->dma_adc
.hwptr
= s
->dma_adc
.swptr
=0; 1363 spin_unlock_irqrestore(&s
->lock
, flags
); 1365 if(signal_pending(current
)) { 1372 if(copy_to_user(buffer
, s
->dma_adc
.rawbuf
+ swptr
, cnt
)) { 1377 swptr
= (swptr
+ cnt
) % s
->dma_adc
.dmasize
; 1378 spin_lock_irqsave(&s
->lock
, flags
); 1379 s
->dma_adc
.swptr
= swptr
; 1380 s
->dma_adc
.count
-= cnt
; 1381 spin_unlock_irqrestore(&s
->lock
, flags
); 1387 remove_wait_queue(&s
->dma_adc
.wait
, &wait
); 1388 set_current_state(TASK_RUNNING
); 1392 static ssize_t
sv_write(struct file
*file
,const char*buffer
,size_t count
, loff_t
*ppos
) 1394 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 1395 DECLARE_WAITQUEUE(wait
, current
); 1397 unsigned long flags
; 1402 if(ppos
!= &file
->f_pos
) 1404 if(s
->dma_dac
.mapped
) 1406 if(!s
->dma_dac
.ready
&& (ret
=prog_dmabuf(s
,0))) 1408 if(!access_ok(VERIFY_READ
, buffer
, count
)) 1412 spin_lock_irqsave(&s
->lock
, flags
); 1414 spin_unlock_irqrestore(&s
->lock
, flags
); 1416 add_wait_queue(&s
->dma_dac
.wait
, &wait
); 1418 spin_lock_irqsave(&s
->lock
, flags
); 1419 if(s
->dma_dac
.count
<0) { 1420 s
->dma_dac
.count
=0; 1421 s
->dma_dac
.swptr
= s
->dma_dac
.hwptr
; 1423 swptr
= s
->dma_dac
.swptr
; 1424 cnt
= s
->dma_dac
.dmasize
-swptr
; 1425 if(s
->dma_dac
.count
+ cnt
> s
->dma_dac
.dmasize
) 1426 cnt
= s
->dma_dac
.dmasize
- s
->dma_dac
.count
; 1428 __set_current_state(TASK_INTERRUPTIBLE
); 1429 spin_unlock_irqrestore(&s
->lock
, flags
); 1434 if(file
->f_flags
& O_NONBLOCK
) { 1439 if(!schedule_timeout(HZ
)) { 1440 printk(KERN_DEBUG
"sv: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", 1441 s
->dma_dac
.dmasize
, s
->dma_dac
.fragsize
, s
->dma_dac
.count
, 1442 s
->dma_dac
.hwptr
, s
->dma_dac
.swptr
); 1444 spin_lock_irqsave(&s
->lock
, flags
); 1445 set_dmaa(s
,virt_to_bus(s
->dma_dac
.rawbuf
), s
->dma_dac
.numfrag
<< s
->dma_dac
.fragshift
); 1446 /* program enhanced mode registers */ 1447 wrindir(s
, SV_CIDMAABASECOUNT1
, (s
->dma_dac
.fragsamples
-1) >>8); 1448 wrindir(s
, SV_CIDMAABASECOUNT0
, s
->dma_dac
.fragsamples
-1); 1449 s
->dma_dac
.count
= s
->dma_dac
.hwptr
= s
->dma_dac
.swptr
=0; 1450 spin_unlock_irqrestore(&s
->lock
, flags
); 1452 if(signal_pending(current
)) { 1459 if(copy_from_user(s
->dma_dac
.rawbuf
+ swptr
, buffer
, cnt
)) { 1464 swptr
= (swptr
+ cnt
) % s
->dma_dac
.dmasize
; 1465 spin_lock_irqsave(&s
->lock
, flags
); 1466 s
->dma_dac
.swptr
= swptr
; 1467 s
->dma_dac
.count
+= cnt
; 1468 s
->dma_dac
.endcleared
=0; 1469 spin_unlock_irqrestore(&s
->lock
, flags
); 1475 remove_wait_queue(&s
->dma_dac
.wait
, &wait
); 1476 set_current_state(TASK_RUNNING
); 1480 /* No kernel lock - we have our own spinlock */ 1481 static unsigned intsv_poll(struct file
*file
,struct poll_table_struct
*wait
) 1483 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 1484 unsigned long flags
; 1485 unsigned int mask
=0; 1488 if(file
->f_mode
& FMODE_WRITE
) { 1489 if(!s
->dma_dac
.ready
&&prog_dmabuf(s
,1)) 1491 poll_wait(file
, &s
->dma_dac
.wait
, wait
); 1493 if(file
->f_mode
& FMODE_READ
) { 1494 if(!s
->dma_adc
.ready
&&prog_dmabuf(s
,0)) 1496 poll_wait(file
, &s
->dma_adc
.wait
, wait
); 1498 spin_lock_irqsave(&s
->lock
, flags
); 1500 if(file
->f_mode
& FMODE_READ
) { 1501 if(s
->dma_adc
.count
>= (signed)s
->dma_adc
.fragsize
) 1502 mask
|= POLLIN
| POLLRDNORM
; 1504 if(file
->f_mode
& FMODE_WRITE
) { 1505 if(s
->dma_dac
.mapped
) { 1506 if(s
->dma_dac
.count
>= (signed)s
->dma_dac
.fragsize
) 1507 mask
|= POLLOUT
| POLLWRNORM
; 1509 if((signed)s
->dma_dac
.dmasize
>= s
->dma_dac
.count
+ (signed)s
->dma_dac
.fragsize
) 1510 mask
|= POLLOUT
| POLLWRNORM
; 1513 spin_unlock_irqrestore(&s
->lock
, flags
); 1517 static intsv_mmap(struct file
*file
,struct vm_area_struct
*vma
) 1519 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 1526 if(vma
->vm_flags
& VM_WRITE
) { 1527 if((ret
=prog_dmabuf(s
,1)) !=0) 1530 }else if(vma
->vm_flags
& VM_READ
) { 1531 if((ret
=prog_dmabuf(s
,0)) !=0) 1537 if(vma
->vm_pgoff
!=0) 1539 size
= vma
->vm_end
- vma
->vm_start
; 1540 if(size
> (PAGE_SIZE
<< db
->buforder
)) 1543 if(remap_page_range(vma
->vm_start
,virt_to_phys(db
->rawbuf
), size
, vma
->vm_page_prot
)) 1552 static intsv_ioctl(struct inode
*inode
,struct file
*file
,unsigned int cmd
,unsigned long arg
) 1554 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 1555 unsigned long flags
; 1556 audio_buf_info abinfo
; 1559 int val
, mapped
, ret
; 1560 unsigned char fmtm
, fmtd
; 1563 mapped
= ((file
->f_mode
& FMODE_WRITE
) && s
->dma_dac
.mapped
) || 1564 ((file
->f_mode
& FMODE_READ
) && s
->dma_adc
.mapped
); 1566 case OSS_GETVERSION
: 1567 returnput_user(SOUND_VERSION
, (int*)arg
); 1569 case SNDCTL_DSP_SYNC
: 1570 if(file
->f_mode
& FMODE_WRITE
) 1571 returndrain_dac(s
,0/*file->f_flags & O_NONBLOCK*/); 1574 case SNDCTL_DSP_SETDUPLEX
: 1577 case SNDCTL_DSP_GETCAPS
: 1578 returnput_user(DSP_CAP_DUPLEX
| DSP_CAP_REALTIME
| DSP_CAP_TRIGGER
| DSP_CAP_MMAP
, (int*)arg
); 1580 case SNDCTL_DSP_RESET
: 1581 if(file
->f_mode
& FMODE_WRITE
) { 1584 s
->dma_dac
.swptr
= s
->dma_dac
.hwptr
= s
->dma_dac
.count
= s
->dma_dac
.total_bytes
=0; 1586 if(file
->f_mode
& FMODE_READ
) { 1589 s
->dma_adc
.swptr
= s
->dma_adc
.hwptr
= s
->dma_adc
.count
= s
->dma_adc
.total_bytes
=0; 1593 case SNDCTL_DSP_SPEED
: 1594 if(get_user(val
, (int*)arg
)) 1597 if(file
->f_mode
& FMODE_READ
) { 1599 s
->dma_adc
.ready
=0; 1600 set_adc_rate(s
, val
); 1602 if(file
->f_mode
& FMODE_WRITE
) { 1604 s
->dma_dac
.ready
=0; 1605 set_dac_rate(s
, val
); 1608 returnput_user((file
->f_mode
& FMODE_READ
) ? s
->rateadc
: s
->ratedac
, (int*)arg
); 1610 case SNDCTL_DSP_STEREO
: 1611 if(get_user(val
, (int*)arg
)) 1615 if(file
->f_mode
& FMODE_READ
) { 1617 s
->dma_adc
.ready
=0; 1619 fmtd
|= SV_CFMT_STEREO
<< SV_CFMT_CSHIFT
; 1621 fmtm
&= ~(SV_CFMT_STEREO
<< SV_CFMT_CSHIFT
); 1623 if(file
->f_mode
& FMODE_WRITE
) { 1625 s
->dma_dac
.ready
=0; 1627 fmtd
|= SV_CFMT_STEREO
<< SV_CFMT_ASHIFT
; 1629 fmtm
&= ~(SV_CFMT_STEREO
<< SV_CFMT_ASHIFT
); 1631 set_fmt(s
, fmtm
, fmtd
); 1634 case SNDCTL_DSP_CHANNELS
: 1635 if(get_user(val
, (int*)arg
)) 1640 if(file
->f_mode
& FMODE_READ
) { 1642 s
->dma_adc
.ready
=0; 1644 fmtd
|= SV_CFMT_STEREO
<< SV_CFMT_CSHIFT
; 1646 fmtm
&= ~(SV_CFMT_STEREO
<< SV_CFMT_CSHIFT
); 1648 if(file
->f_mode
& FMODE_WRITE
) { 1650 s
->dma_dac
.ready
=0; 1652 fmtd
|= SV_CFMT_STEREO
<< SV_CFMT_ASHIFT
; 1654 fmtm
&= ~(SV_CFMT_STEREO
<< SV_CFMT_ASHIFT
); 1656 set_fmt(s
, fmtm
, fmtd
); 1658 returnput_user((s
->fmt
& ((file
->f_mode
& FMODE_READ
) ? (SV_CFMT_STEREO
<< SV_CFMT_CSHIFT
) 1659 : (SV_CFMT_STEREO
<< SV_CFMT_ASHIFT
))) ?2:1, (int*)arg
); 1661 case SNDCTL_DSP_GETFMTS
:/* Returns a mask */ 1662 returnput_user(AFMT_S16_LE
|AFMT_U8
, (int*)arg
); 1664 case SNDCTL_DSP_SETFMT
:/* Selects ONE fmt*/ 1665 if(get_user(val
, (int*)arg
)) 1667 if(val
!= AFMT_QUERY
) { 1670 if(file
->f_mode
& FMODE_READ
) { 1672 s
->dma_adc
.ready
=0; 1673 if(val
== AFMT_S16_LE
) 1674 fmtd
|= SV_CFMT_16BIT
<< SV_CFMT_CSHIFT
; 1676 fmtm
&= ~(SV_CFMT_16BIT
<< SV_CFMT_CSHIFT
); 1678 if(file
->f_mode
& FMODE_WRITE
) { 1680 s
->dma_dac
.ready
=0; 1681 if(val
== AFMT_S16_LE
) 1682 fmtd
|= SV_CFMT_16BIT
<< SV_CFMT_ASHIFT
; 1684 fmtm
&= ~(SV_CFMT_16BIT
<< SV_CFMT_ASHIFT
); 1686 set_fmt(s
, fmtm
, fmtd
); 1688 returnput_user((s
->fmt
& ((file
->f_mode
& FMODE_READ
) ? (SV_CFMT_16BIT
<< SV_CFMT_CSHIFT
) 1689 : (SV_CFMT_16BIT
<< SV_CFMT_ASHIFT
))) ? AFMT_S16_LE
: AFMT_U8
, (int*)arg
); 1691 case SNDCTL_DSP_POST
: 1694 case SNDCTL_DSP_GETTRIGGER
: 1696 if(file
->f_mode
& FMODE_READ
&& s
->enable
& SV_CENABLE_RE
) 1697 val
|= PCM_ENABLE_INPUT
; 1698 if(file
->f_mode
& FMODE_WRITE
&& s
->enable
& SV_CENABLE_PE
) 1699 val
|= PCM_ENABLE_OUTPUT
; 1700 returnput_user(val
, (int*)arg
); 1702 case SNDCTL_DSP_SETTRIGGER
: 1703 if(get_user(val
, (int*)arg
)) 1705 if(file
->f_mode
& FMODE_READ
) { 1706 if(val
& PCM_ENABLE_INPUT
) { 1707 if(!s
->dma_adc
.ready
&& (ret
=prog_dmabuf(s
,1))) 1713 if(file
->f_mode
& FMODE_WRITE
) { 1714 if(val
& PCM_ENABLE_OUTPUT
) { 1715 if(!s
->dma_dac
.ready
&& (ret
=prog_dmabuf(s
,0))) 1723 case SNDCTL_DSP_GETOSPACE
: 1724 if(!(file
->f_mode
& FMODE_WRITE
)) 1726 if(!s
->dma_dac
.ready
&& (ret
=prog_dmabuf(s
,0))) 1728 spin_lock_irqsave(&s
->lock
, flags
); 1730 abinfo
.fragsize
= s
->dma_dac
.fragsize
; 1731 count
= s
->dma_dac
.count
; 1734 abinfo
.bytes
= s
->dma_dac
.dmasize
- count
; 1735 abinfo
.fragstotal
= s
->dma_dac
.numfrag
; 1736 abinfo
.fragments
= abinfo
.bytes
>> s
->dma_dac
.fragshift
; 1737 spin_unlock_irqrestore(&s
->lock
, flags
); 1738 returncopy_to_user((void*)arg
, &abinfo
,sizeof(abinfo
)) ? -EFAULT
:0; 1740 case SNDCTL_DSP_GETISPACE
: 1741 if(!(file
->f_mode
& FMODE_READ
)) 1743 if(!s
->dma_adc
.ready
&& (ret
=prog_dmabuf(s
,1))) 1745 spin_lock_irqsave(&s
->lock
, flags
); 1747 abinfo
.fragsize
= s
->dma_adc
.fragsize
; 1748 count
= s
->dma_adc
.count
; 1751 abinfo
.bytes
= count
; 1752 abinfo
.fragstotal
= s
->dma_adc
.numfrag
; 1753 abinfo
.fragments
= abinfo
.bytes
>> s
->dma_adc
.fragshift
; 1754 spin_unlock_irqrestore(&s
->lock
, flags
); 1755 returncopy_to_user((void*)arg
, &abinfo
,sizeof(abinfo
)) ? -EFAULT
:0; 1757 case SNDCTL_DSP_NONBLOCK
: 1758 file
->f_flags
|= O_NONBLOCK
; 1761 case SNDCTL_DSP_GETODELAY
: 1762 if(!(file
->f_mode
& FMODE_WRITE
)) 1764 if(!s
->dma_dac
.ready
&& (ret
=prog_dmabuf(s
,0))) 1766 spin_lock_irqsave(&s
->lock
, flags
); 1768 count
= s
->dma_dac
.count
; 1769 spin_unlock_irqrestore(&s
->lock
, flags
); 1772 returnput_user(count
, (int*)arg
); 1774 case SNDCTL_DSP_GETIPTR
: 1775 if(!(file
->f_mode
& FMODE_READ
)) 1777 if(!s
->dma_adc
.ready
&& (ret
=prog_dmabuf(s
,1))) 1779 spin_lock_irqsave(&s
->lock
, flags
); 1781 cinfo
.bytes
= s
->dma_adc
.total_bytes
; 1782 count
= s
->dma_adc
.count
; 1785 cinfo
.blocks
= count
>> s
->dma_adc
.fragshift
; 1786 cinfo
.ptr
= s
->dma_adc
.hwptr
; 1787 if(s
->dma_adc
.mapped
) 1788 s
->dma_adc
.count
&= s
->dma_adc
.fragsize
-1; 1789 spin_unlock_irqrestore(&s
->lock
, flags
); 1790 returncopy_to_user((void*)arg
, &cinfo
,sizeof(cinfo
)); 1792 case SNDCTL_DSP_GETOPTR
: 1793 if(!(file
->f_mode
& FMODE_WRITE
)) 1795 if(!s
->dma_dac
.ready
&& (ret
=prog_dmabuf(s
,0))) 1797 spin_lock_irqsave(&s
->lock
, flags
); 1799 cinfo
.bytes
= s
->dma_dac
.total_bytes
; 1800 count
= s
->dma_dac
.count
; 1803 cinfo
.blocks
= count
>> s
->dma_dac
.fragshift
; 1804 cinfo
.ptr
= s
->dma_dac
.hwptr
; 1805 if(s
->dma_dac
.mapped
) 1806 s
->dma_dac
.count
&= s
->dma_dac
.fragsize
-1; 1807 spin_unlock_irqrestore(&s
->lock
, flags
); 1808 returncopy_to_user((void*)arg
, &cinfo
,sizeof(cinfo
)); 1810 case SNDCTL_DSP_GETBLKSIZE
: 1811 if(file
->f_mode
& FMODE_WRITE
) { 1812 if((val
=prog_dmabuf(s
,0))) 1814 returnput_user(s
->dma_dac
.fragsize
, (int*)arg
); 1816 if((val
=prog_dmabuf(s
,1))) 1818 returnput_user(s
->dma_adc
.fragsize
, (int*)arg
); 1820 case SNDCTL_DSP_SETFRAGMENT
: 1821 if(get_user(val
, (int*)arg
)) 1823 if(file
->f_mode
& FMODE_READ
) { 1824 s
->dma_adc
.ossfragshift
= val
&0xffff; 1825 s
->dma_adc
.ossmaxfrags
= (val
>>16) &0xffff; 1826 if(s
->dma_adc
.ossfragshift
<4) 1827 s
->dma_adc
.ossfragshift
=4; 1828 if(s
->dma_adc
.ossfragshift
>15) 1829 s
->dma_adc
.ossfragshift
=15; 1830 if(s
->dma_adc
.ossmaxfrags
<4) 1831 s
->dma_adc
.ossmaxfrags
=4; 1833 if(file
->f_mode
& FMODE_WRITE
) { 1834 s
->dma_dac
.ossfragshift
= val
&0xffff; 1835 s
->dma_dac
.ossmaxfrags
= (val
>>16) &0xffff; 1836 if(s
->dma_dac
.ossfragshift
<4) 1837 s
->dma_dac
.ossfragshift
=4; 1838 if(s
->dma_dac
.ossfragshift
>15) 1839 s
->dma_dac
.ossfragshift
=15; 1840 if(s
->dma_dac
.ossmaxfrags
<4) 1841 s
->dma_dac
.ossmaxfrags
=4; 1845 case SNDCTL_DSP_SUBDIVIDE
: 1846 if((file
->f_mode
& FMODE_READ
&& s
->dma_adc
.subdivision
) || 1847 (file
->f_mode
& FMODE_WRITE
&& s
->dma_dac
.subdivision
)) 1849 if(get_user(val
, (int*)arg
)) 1851 if(val
!=1&& val
!=2&& val
!=4) 1853 if(file
->f_mode
& FMODE_READ
) 1854 s
->dma_adc
.subdivision
= val
; 1855 if(file
->f_mode
& FMODE_WRITE
) 1856 s
->dma_dac
.subdivision
= val
; 1859 case SOUND_PCM_READ_RATE
: 1860 returnput_user((file
->f_mode
& FMODE_READ
) ? s
->rateadc
: s
->ratedac
, (int*)arg
); 1862 case SOUND_PCM_READ_CHANNELS
: 1863 returnput_user((s
->fmt
& ((file
->f_mode
& FMODE_READ
) ? (SV_CFMT_STEREO
<< SV_CFMT_CSHIFT
) 1864 : (SV_CFMT_STEREO
<< SV_CFMT_ASHIFT
))) ?2:1, (int*)arg
); 1866 case SOUND_PCM_READ_BITS
: 1867 returnput_user((s
->fmt
& ((file
->f_mode
& FMODE_READ
) ? (SV_CFMT_16BIT
<< SV_CFMT_CSHIFT
) 1868 : (SV_CFMT_16BIT
<< SV_CFMT_ASHIFT
))) ?16:8, (int*)arg
); 1870 case SOUND_PCM_WRITE_FILTER
: 1871 case SNDCTL_DSP_SETSYNCRO
: 1872 case SOUND_PCM_READ_FILTER
: 1876 returnmixer_ioctl(s
, cmd
, arg
); 1879 static intsv_open(struct inode
*inode
,struct file
*file
) 1881 int minor
=MINOR(inode
->i_rdev
); 1882 DECLARE_WAITQUEUE(wait
, current
); 1883 unsigned char fmtm
= ~0, fmts
=0; 1884 struct list_head
*list
; 1887 for(list
= devs
.next
; ; list
= list
->next
) { 1890 s
=list_entry(list
,struct sv_state
, devs
); 1891 if(!((s
->dev_audio
^ minor
) & ~0xf)) 1895 file
->private_data
= s
; 1896 /* wait for device to become free */ 1898 while(s
->open_mode
& file
->f_mode
) { 1899 if(file
->f_flags
& O_NONBLOCK
) { 1903 add_wait_queue(&s
->open_wait
, &wait
); 1904 __set_current_state(TASK_INTERRUPTIBLE
); 1907 remove_wait_queue(&s
->open_wait
, &wait
); 1908 set_current_state(TASK_RUNNING
); 1909 if(signal_pending(current
)) 1913 if(file
->f_mode
& FMODE_READ
) { 1914 fmtm
&= ~((SV_CFMT_STEREO
| SV_CFMT_16BIT
) << SV_CFMT_CSHIFT
); 1915 if((minor
&0xf) == SND_DEV_DSP16
) 1916 fmts
|= SV_CFMT_16BIT
<< SV_CFMT_CSHIFT
; 1917 s
->dma_adc
.ossfragshift
= s
->dma_adc
.ossmaxfrags
= s
->dma_adc
.subdivision
=0; 1918 set_adc_rate(s
,8000); 1920 if(file
->f_mode
& FMODE_WRITE
) { 1921 fmtm
&= ~((SV_CFMT_STEREO
| SV_CFMT_16BIT
) << SV_CFMT_ASHIFT
); 1922 if((minor
&0xf) == SND_DEV_DSP16
) 1923 fmts
|= SV_CFMT_16BIT
<< SV_CFMT_ASHIFT
; 1924 s
->dma_dac
.ossfragshift
= s
->dma_dac
.ossmaxfrags
= s
->dma_dac
.subdivision
=0; 1925 set_dac_rate(s
,8000); 1927 set_fmt(s
, fmtm
, fmts
); 1928 s
->open_mode
|= file
->f_mode
& (FMODE_READ
| FMODE_WRITE
); 1933 static intsv_release(struct inode
*inode
,struct file
*file
) 1935 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 1939 if(file
->f_mode
& FMODE_WRITE
) 1940 drain_dac(s
, file
->f_flags
& O_NONBLOCK
); 1942 if(file
->f_mode
& FMODE_WRITE
) { 1944 dealloc_dmabuf(s
, &s
->dma_dac
); 1946 if(file
->f_mode
& FMODE_READ
) { 1948 dealloc_dmabuf(s
, &s
->dma_adc
); 1950 s
->open_mode
&= (~file
->f_mode
) & (FMODE_READ
|FMODE_WRITE
); 1951 wake_up(&s
->open_wait
); 1957 static/*const*/struct file_operations sv_audio_fops
= { 1966 release
: sv_release
, 1969 /* --------------------------------------------------------------------- */ 1971 static ssize_t
sv_midi_read(struct file
*file
,char*buffer
,size_t count
, loff_t
*ppos
) 1973 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 1974 DECLARE_WAITQUEUE(wait
, current
); 1976 unsigned long flags
; 1981 if(ppos
!= &file
->f_pos
) 1983 if(!access_ok(VERIFY_WRITE
, buffer
, count
)) 1988 add_wait_queue(&s
->midi
.iwait
, &wait
); 1990 spin_lock_irqsave(&s
->lock
, flags
); 1992 cnt
= MIDIINBUF
- ptr
; 1993 if(s
->midi
.icnt
< cnt
) 1996 __set_current_state(TASK_INTERRUPTIBLE
); 1997 spin_unlock_irqrestore(&s
->lock
, flags
); 2001 if(file
->f_flags
& O_NONBLOCK
) { 2007 if(signal_pending(current
)) { 2014 if(copy_to_user(buffer
, s
->midi
.ibuf
+ ptr
, cnt
)) { 2019 ptr
= (ptr
+ cnt
) % MIDIINBUF
; 2020 spin_lock_irqsave(&s
->lock
, flags
); 2022 s
->midi
.icnt
-= cnt
; 2023 spin_unlock_irqrestore(&s
->lock
, flags
); 2029 __set_current_state(TASK_RUNNING
); 2030 remove_wait_queue(&s
->midi
.iwait
, &wait
); 2034 static ssize_t
sv_midi_write(struct file
*file
,const char*buffer
,size_t count
, loff_t
*ppos
) 2036 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 2037 DECLARE_WAITQUEUE(wait
, current
); 2039 unsigned long flags
; 2044 if(ppos
!= &file
->f_pos
) 2046 if(!access_ok(VERIFY_READ
, buffer
, count
)) 2051 add_wait_queue(&s
->midi
.owait
, &wait
); 2053 spin_lock_irqsave(&s
->lock
, flags
); 2055 cnt
= MIDIOUTBUF
- ptr
; 2056 if(s
->midi
.ocnt
+ cnt
> MIDIOUTBUF
) 2057 cnt
= MIDIOUTBUF
- s
->midi
.ocnt
; 2059 __set_current_state(TASK_INTERRUPTIBLE
); 2062 spin_unlock_irqrestore(&s
->lock
, flags
); 2066 if(file
->f_flags
& O_NONBLOCK
) { 2072 if(signal_pending(current
)) { 2079 if(copy_from_user(s
->midi
.obuf
+ ptr
, buffer
, cnt
)) { 2084 ptr
= (ptr
+ cnt
) % MIDIOUTBUF
; 2085 spin_lock_irqsave(&s
->lock
, flags
); 2087 s
->midi
.ocnt
+= cnt
; 2088 spin_unlock_irqrestore(&s
->lock
, flags
); 2092 spin_lock_irqsave(&s
->lock
, flags
); 2094 spin_unlock_irqrestore(&s
->lock
, flags
); 2096 __set_current_state(TASK_RUNNING
); 2097 remove_wait_queue(&s
->midi
.owait
, &wait
); 2101 /* No kernel lock - we have our own spinlock */ 2102 static unsigned intsv_midi_poll(struct file
*file
,struct poll_table_struct
*wait
) 2104 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 2105 unsigned long flags
; 2106 unsigned int mask
=0; 2109 if(file
->f_mode
& FMODE_WRITE
) 2110 poll_wait(file
, &s
->midi
.owait
, wait
); 2111 if(file
->f_mode
& FMODE_READ
) 2112 poll_wait(file
, &s
->midi
.iwait
, wait
); 2113 spin_lock_irqsave(&s
->lock
, flags
); 2114 if(file
->f_mode
& FMODE_READ
) { 2116 mask
|= POLLIN
| POLLRDNORM
; 2118 if(file
->f_mode
& FMODE_WRITE
) { 2119 if(s
->midi
.ocnt
< MIDIOUTBUF
) 2120 mask
|= POLLOUT
| POLLWRNORM
; 2122 spin_unlock_irqrestore(&s
->lock
, flags
); 2126 static intsv_midi_open(struct inode
*inode
,struct file
*file
) 2128 int minor
=MINOR(inode
->i_rdev
); 2129 DECLARE_WAITQUEUE(wait
, current
); 2130 unsigned long flags
; 2131 struct list_head
*list
; 2134 for(list
= devs
.next
; ; list
= list
->next
) { 2137 s
=list_entry(list
,struct sv_state
, devs
); 2138 if(s
->dev_midi
== minor
) 2142 file
->private_data
= s
; 2143 /* wait for device to become free */ 2145 while(s
->open_mode
& (file
->f_mode
<< FMODE_MIDI_SHIFT
)) { 2146 if(file
->f_flags
& O_NONBLOCK
) { 2150 add_wait_queue(&s
->open_wait
, &wait
); 2151 __set_current_state(TASK_INTERRUPTIBLE
); 2154 remove_wait_queue(&s
->open_wait
, &wait
); 2155 set_current_state(TASK_RUNNING
); 2156 if(signal_pending(current
)) 2160 spin_lock_irqsave(&s
->lock
, flags
); 2161 if(!(s
->open_mode
& (FMODE_MIDI_READ
| FMODE_MIDI_WRITE
))) { 2162 s
->midi
.ird
= s
->midi
.iwr
= s
->midi
.icnt
=0; 2163 s
->midi
.ord
= s
->midi
.owr
= s
->midi
.ocnt
=0; 2164 //outb(inb(s->ioenh + SV_CODEC_CONTROL) | SV_CCTRL_WAVETABLE, s->ioenh + SV_CODEC_CONTROL); 2165 outb(inb(s
->ioenh
+ SV_CODEC_INTMASK
) | SV_CINTMASK_MIDI
, s
->ioenh
+ SV_CODEC_INTMASK
); 2166 wrindir(s
, SV_CIUARTCONTROL
,5);/* output MIDI data to external and internal synth */ 2167 wrindir(s
, SV_CIWAVETABLESRC
,1);/* Wavetable in PC RAM */ 2168 outb(0xff, s
->iomidi
+1);/* reset command */ 2169 outb(0x3f, s
->iomidi
+1);/* uart command */ 2170 if(!(inb(s
->iomidi
+1) &0x80)) 2172 s
->midi
.ird
= s
->midi
.iwr
= s
->midi
.icnt
=0; 2173 init_timer(&s
->midi
.timer
); 2174 s
->midi
.timer
.expires
= jiffies
+1; 2175 s
->midi
.timer
.data
= (unsigned long)s
; 2176 s
->midi
.timer
.function
= sv_midi_timer
; 2177 add_timer(&s
->midi
.timer
); 2179 if(file
->f_mode
& FMODE_READ
) { 2180 s
->midi
.ird
= s
->midi
.iwr
= s
->midi
.icnt
=0; 2182 if(file
->f_mode
& FMODE_WRITE
) { 2183 s
->midi
.ord
= s
->midi
.owr
= s
->midi
.ocnt
=0; 2185 spin_unlock_irqrestore(&s
->lock
, flags
); 2186 s
->open_mode
|= (file
->f_mode
<< FMODE_MIDI_SHIFT
) & (FMODE_MIDI_READ
| FMODE_MIDI_WRITE
); 2191 static intsv_midi_release(struct inode
*inode
,struct file
*file
) 2193 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 2194 DECLARE_WAITQUEUE(wait
, current
); 2195 unsigned long flags
; 2196 unsigned count
, tmo
; 2201 if(file
->f_mode
& FMODE_WRITE
) { 2202 add_wait_queue(&s
->midi
.owait
, &wait
); 2204 __set_current_state(TASK_INTERRUPTIBLE
); 2205 spin_lock_irqsave(&s
->lock
, flags
); 2206 count
= s
->midi
.ocnt
; 2207 spin_unlock_irqrestore(&s
->lock
, flags
); 2210 if(signal_pending(current
)) 2212 if(file
->f_flags
& O_NONBLOCK
) { 2213 remove_wait_queue(&s
->midi
.owait
, &wait
); 2214 set_current_state(TASK_RUNNING
); 2217 tmo
= (count
* HZ
) /3100; 2218 if(!schedule_timeout(tmo
? :1) && tmo
) 2219 printk(KERN_DEBUG
"sv: midi timed out??\n"); 2221 remove_wait_queue(&s
->midi
.owait
, &wait
); 2222 set_current_state(TASK_RUNNING
); 2225 s
->open_mode
&= (~(file
->f_mode
<< FMODE_MIDI_SHIFT
)) & (FMODE_MIDI_READ
|FMODE_MIDI_WRITE
); 2226 spin_lock_irqsave(&s
->lock
, flags
); 2227 if(!(s
->open_mode
& (FMODE_MIDI_READ
| FMODE_MIDI_WRITE
))) { 2228 outb(inb(s
->ioenh
+ SV_CODEC_INTMASK
) & ~SV_CINTMASK_MIDI
, s
->ioenh
+ SV_CODEC_INTMASK
); 2229 del_timer(&s
->midi
.timer
); 2231 spin_unlock_irqrestore(&s
->lock
, flags
); 2232 wake_up(&s
->open_wait
); 2238 static/*const*/struct file_operations sv_midi_fops
= { 2242 write
: sv_midi_write
, 2245 release
: sv_midi_release
, 2248 /* --------------------------------------------------------------------- */ 2250 static intsv_dmfm_ioctl(struct inode
*inode
,struct file
*file
,unsigned int cmd
,unsigned long arg
) 2252 static const unsigned char op_offset
[18] = { 2253 0x00,0x01,0x02,0x03,0x04,0x05, 2254 0x08,0x09,0x0A,0x0B,0x0C,0x0D, 2255 0x10,0x11,0x12,0x13,0x14,0x15 2257 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 2258 struct dm_fm_voice v
; 2259 struct dm_fm_note n
; 2260 struct dm_fm_params p
; 2265 case FM_IOCTL_RESET
: 2266 for(regb
=0xb0; regb
<0xb9; regb
++) { 2267 outb(regb
, s
->iosynth
); 2268 outb(0, s
->iosynth
+1); 2269 outb(regb
, s
->iosynth
+2); 2270 outb(0, s
->iosynth
+3); 2274 case FM_IOCTL_PLAY_NOTE
: 2275 if(copy_from_user(&n
, (void*)arg
,sizeof(n
))) 2286 outb(0xa0+ regb
, io
); 2287 outb(n
.fnum
&0xff, io
+1); 2288 outb(0xb0+ regb
, io
); 2289 outb(((n
.fnum
>>8) &3) | ((n
.octave
&7) <<2) | ((n
.key_on
&1) <<5), io
+1); 2292 case FM_IOCTL_SET_VOICE
: 2293 if(copy_from_user(&v
, (void*)arg
,sizeof(v
))) 2297 regb
= op_offset
[v
.voice
]; 2298 io
= s
->iosynth
+ ((v
.op
&1) <<1); 2299 outb(0x20+ regb
, io
); 2300 outb(((v
.am
&1) <<7) | ((v
.vibrato
&1) <<6) | ((v
.do_sustain
&1) <<5) | 2301 ((v
.kbd_scale
&1) <<4) | (v
.harmonic
&0xf), io
+1); 2302 outb(0x40+ regb
, io
); 2303 outb(((v
.scale_level
&0x3) <<6) | (v
.volume
&0x3f), io
+1); 2304 outb(0x60+ regb
, io
); 2305 outb(((v
.attack
&0xf) <<4) | (v
.decay
&0xf), io
+1); 2306 outb(0x80+ regb
, io
); 2307 outb(((v
.sustain
&0xf) <<4) | (v
.release
&0xf), io
+1); 2308 outb(0xe0+ regb
, io
); 2309 outb(v
.waveform
&0x7, io
+1); 2317 outb(0xc0+ regb
, io
); 2318 outb(((v
.right
&1) <<5) | ((v
.left
&1) <<4) | ((v
.feedback
&7) <<1) | 2319 (v
.connection
&1), io
+1); 2322 case FM_IOCTL_SET_PARAMS
: 2323 if(copy_from_user(&p
, (void*)arg
,sizeof(p
))) 2325 outb(0x08, s
->iosynth
); 2326 outb((p
.kbd_split
&1) <<6, s
->iosynth
+1); 2327 outb(0xbd, s
->iosynth
); 2328 outb(((p
.am_depth
&1) <<7) | ((p
.vib_depth
&1) <<6) | ((p
.rhythm
&1) <<5) | ((p
.bass
&1) <<4) | 2329 ((p
.snare
&1) <<3) | ((p
.tomtom
&1) <<2) | ((p
.cymbal
&1) <<1) | (p
.hihat
&1), s
->iosynth
+1); 2332 case FM_IOCTL_SET_OPL
: 2333 outb(4, s
->iosynth
+2); 2334 outb(arg
, s
->iosynth
+3); 2337 case FM_IOCTL_SET_MODE
: 2338 outb(5, s
->iosynth
+2); 2339 outb(arg
&1, s
->iosynth
+3); 2347 static intsv_dmfm_open(struct inode
*inode
,struct file
*file
) 2349 int minor
=MINOR(inode
->i_rdev
); 2350 DECLARE_WAITQUEUE(wait
, current
); 2351 struct list_head
*list
; 2354 for(list
= devs
.next
; ; list
= list
->next
) { 2357 s
=list_entry(list
,struct sv_state
, devs
); 2358 if(s
->dev_dmfm
== minor
) 2362 file
->private_data
= s
; 2363 /* wait for device to become free */ 2365 while(s
->open_mode
& FMODE_DMFM
) { 2366 if(file
->f_flags
& O_NONBLOCK
) { 2370 add_wait_queue(&s
->open_wait
, &wait
); 2371 __set_current_state(TASK_INTERRUPTIBLE
); 2374 remove_wait_queue(&s
->open_wait
, &wait
); 2375 set_current_state(TASK_RUNNING
); 2376 if(signal_pending(current
)) 2380 /* init the stuff */ 2381 outb(1, s
->iosynth
); 2382 outb(0x20, s
->iosynth
+1);/* enable waveforms */ 2383 outb(4, s
->iosynth
+2); 2384 outb(0, s
->iosynth
+3);/* no 4op enabled */ 2385 outb(5, s
->iosynth
+2); 2386 outb(1, s
->iosynth
+3);/* enable OPL3 */ 2387 s
->open_mode
|= FMODE_DMFM
; 2392 static intsv_dmfm_release(struct inode
*inode
,struct file
*file
) 2394 struct sv_state
*s
= (struct sv_state
*)file
->private_data
; 2400 s
->open_mode
&= ~FMODE_DMFM
; 2401 for(regb
=0xb0; regb
<0xb9; regb
++) { 2402 outb(regb
, s
->iosynth
); 2403 outb(0, s
->iosynth
+1); 2404 outb(regb
, s
->iosynth
+2); 2405 outb(0, s
->iosynth
+3); 2407 wake_up(&s
->open_wait
); 2413 static/*const*/struct file_operations sv_dmfm_fops
= { 2416 ioctl
: sv_dmfm_ioctl
, 2418 release
: sv_dmfm_release
, 2421 /* --------------------------------------------------------------------- */ 2423 /* maximum number of devices; only used for command line params */ 2426 static int reverb
[NR_DEVICE
] = {0, }; 2429 static int wavetable
[NR_DEVICE
] = {0, }; 2432 static unsigned int devindex
=0; 2434 MODULE_PARM(reverb
,"1-"__MODULE_STRING(NR_DEVICE
)"i"); 2435 MODULE_PARM_DESC(reverb
,"if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM"); 2437 MODULE_PARM(wavetable
,"1-"__MODULE_STRING(NR_DEVICE
)"i"); 2438 MODULE_PARM_DESC(wavetable
,"if 1 the wavetable synth is enabled"); 2441 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); 2442 MODULE_DESCRIPTION("S3 SonicVibes Driver"); 2444 /* --------------------------------------------------------------------- */ 2446 static struct initvol
{ 2449 } initvol
[] __initdata
= { 2450 { SOUND_MIXER_WRITE_RECLEV
,0x4040}, 2451 { SOUND_MIXER_WRITE_LINE1
,0x4040}, 2452 { SOUND_MIXER_WRITE_CD
,0x4040}, 2453 { SOUND_MIXER_WRITE_LINE
,0x4040}, 2454 { SOUND_MIXER_WRITE_MIC
,0x4040}, 2455 { SOUND_MIXER_WRITE_SYNTH
,0x4040}, 2456 { SOUND_MIXER_WRITE_LINE2
,0x4040}, 2457 { SOUND_MIXER_WRITE_VOLUME
,0x4040}, 2458 { SOUND_MIXER_WRITE_PCM
,0x4040} 2461 #define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \ 2462 (pci_resource_flags((dev), (num)) & IORESOURCE_IO)) 2464 static int __devinit
sv_probe(struct pci_dev
*pcidev
,const struct pci_device_id
*pciid
) 2466 static const char __initdata sv_ddma_name
[] ="S3 Inc. SonicVibes DDMA Controller"; 2471 unsigned ddmanamelen
; 2473 if(!RSRCISIOREGION(pcidev
, RESOURCE_SB
) || 2474 !RSRCISIOREGION(pcidev
, RESOURCE_ENH
) || 2475 !RSRCISIOREGION(pcidev
, RESOURCE_SYNTH
) || 2476 !RSRCISIOREGION(pcidev
, RESOURCE_MIDI
) || 2477 !RSRCISIOREGION(pcidev
, RESOURCE_GAME
)) 2481 if(!pci_dma_supported(pcidev
,0x00ffffff)) { 2482 printk(KERN_WARNING
"sonicvibes: architecture does not support 24bit PCI busmaster DMA\n"); 2485 /* try to allocate a DDMA resource if not already available */ 2486 if(!RSRCISIOREGION(pcidev
, RESOURCE_DDMA
)) { 2487 pcidev
->resource
[RESOURCE_DDMA
].start
=0; 2488 pcidev
->resource
[RESOURCE_DDMA
].end
=2*SV_EXTENT_DMA
-1; 2489 pcidev
->resource
[RESOURCE_DDMA
].flags
= PCI_BASE_ADDRESS_SPACE_IO
| IORESOURCE_IO
; 2490 ddmanamelen
=strlen(sv_ddma_name
)+1; 2491 if(!(ddmaname
=kmalloc(ddmanamelen
, GFP_KERNEL
))) 2493 memcpy(ddmaname
, sv_ddma_name
, ddmanamelen
); 2494 pcidev
->resource
[RESOURCE_DDMA
].name
= ddmaname
; 2495 if(pci_assign_resource(pcidev
, RESOURCE_DDMA
)) { 2496 pcidev
->resource
[RESOURCE_DDMA
].name
= NULL
; 2498 printk(KERN_ERR
"sv: cannot allocate DDMA controller io ports\n"); 2502 if(!(s
=kmalloc(sizeof(struct sv_state
), GFP_KERNEL
))) { 2503 printk(KERN_WARNING
"sv: out of memory\n"); 2506 memset(s
,0,sizeof(struct sv_state
)); 2507 init_waitqueue_head(&s
->dma_adc
.wait
); 2508 init_waitqueue_head(&s
->dma_dac
.wait
); 2509 init_waitqueue_head(&s
->open_wait
); 2510 init_waitqueue_head(&s
->midi
.iwait
); 2511 init_waitqueue_head(&s
->midi
.owait
); 2512 init_MUTEX(&s
->open_sem
); 2513 spin_lock_init(&s
->lock
); 2514 s
->magic
= SV_MAGIC
; 2516 s
->iosb
=pci_resource_start(pcidev
, RESOURCE_SB
); 2517 s
->ioenh
=pci_resource_start(pcidev
, RESOURCE_ENH
); 2518 s
->iosynth
=pci_resource_start(pcidev
, RESOURCE_SYNTH
); 2519 s
->iomidi
=pci_resource_start(pcidev
, RESOURCE_MIDI
); 2520 s
->iogame
=pci_resource_start(pcidev
, RESOURCE_GAME
); 2521 s
->iodmaa
=pci_resource_start(pcidev
, RESOURCE_DDMA
); 2522 s
->iodmac
=pci_resource_start(pcidev
, RESOURCE_DDMA
) + SV_EXTENT_DMA
; 2523 pci_write_config_dword(pcidev
,0x40, s
->iodmaa
|9);/* enable and use extended mode */ 2524 pci_write_config_dword(pcidev
,0x48, s
->iodmac
|9);/* enable */ 2525 printk(KERN_DEBUG
"sv: io ports: %#lx %#lx %#lx %#lx %#lx %#x %#x\n", 2526 s
->iosb
, s
->ioenh
, s
->iosynth
, s
->iomidi
, s
->iogame
, s
->iodmaa
, s
->iodmac
); 2527 s
->irq
= pcidev
->irq
; 2530 pci_write_config_dword(pcidev
,0x60, wavetable_mem
>>12);/* wavetable base address */ 2532 if(!request_region(s
->ioenh
, SV_EXTENT_ENH
,"S3 SonicVibes PCM")) { 2533 printk(KERN_ERR
"sv: io ports %#lx-%#lx in use\n", s
->ioenh
, s
->ioenh
+SV_EXTENT_ENH
-1); 2536 if(!request_region(s
->iodmaa
, SV_EXTENT_DMA
,"S3 SonicVibes DMAA")) { 2537 printk(KERN_ERR
"sv: io ports %#x-%#x in use\n", s
->iodmaa
, s
->iodmaa
+SV_EXTENT_DMA
-1); 2540 if(!request_region(s
->iodmac
, SV_EXTENT_DMA
,"S3 SonicVibes DMAC")) { 2541 printk(KERN_ERR
"sv: io ports %#x-%#x in use\n", s
->iodmac
, s
->iodmac
+SV_EXTENT_DMA
-1); 2544 if(!request_region(s
->iomidi
, SV_EXTENT_MIDI
,"S3 SonicVibes Midi")) { 2545 printk(KERN_ERR
"sv: io ports %#lx-%#lx in use\n", s
->iomidi
, s
->iomidi
+SV_EXTENT_MIDI
-1); 2548 if(!request_region(s
->iosynth
, SV_EXTENT_SYNTH
,"S3 SonicVibes Synth")) { 2549 printk(KERN_ERR
"sv: io ports %#lx-%#lx in use\n", s
->iosynth
, s
->iosynth
+SV_EXTENT_SYNTH
-1); 2552 if(pci_enable_device(pcidev
)) 2554 /* initialize codec registers */ 2555 outb(0x80, s
->ioenh
+ SV_CODEC_CONTROL
);/* assert reset */ 2557 outb(0x00, s
->ioenh
+ SV_CODEC_CONTROL
);/* deassert reset */ 2559 outb(SV_CCTRL_INTADRIVE
| SV_CCTRL_ENHANCED
/*| SV_CCTRL_WAVETABLE */ 2560 | (reverb
[devindex
] ? SV_CCTRL_REVERB
:0), s
->ioenh
+ SV_CODEC_CONTROL
); 2561 inb(s
->ioenh
+ SV_CODEC_STATUS
);/* clear ints */ 2562 wrindir(s
, SV_CIDRIVECONTROL
,0);/* drive current 16mA */ 2563 wrindir(s
, SV_CIENABLE
, s
->enable
=0);/* disable DMAA and DMAC */ 2564 outb(~(SV_CINTMASK_DMAA
| SV_CINTMASK_DMAC
), s
->ioenh
+ SV_CODEC_INTMASK
); 2565 /* outb(0xff, s->iodmaa + SV_DMA_RESET); */ 2566 /* outb(0xff, s->iodmac + SV_DMA_RESET); */ 2567 inb(s
->ioenh
+ SV_CODEC_STATUS
);/* ack interrupts */ 2568 wrindir(s
, SV_CIADCCLKSOURCE
,0);/* use pll as ADC clock source */ 2569 wrindir(s
, SV_CIANALOGPWRDOWN
,0);/* power up the analog parts of the device */ 2570 wrindir(s
, SV_CIDIGITALPWRDOWN
,0);/* power up the digital parts of the device */ 2571 setpll(s
, SV_CIADCPLLM
,8000); 2572 wrindir(s
, SV_CISRSSPACE
,0x80);/* SRS off */ 2573 wrindir(s
, SV_CIPCMSR0
, (8000*65536/ FULLRATE
) &0xff); 2574 wrindir(s
, SV_CIPCMSR1
, ((8000*65536/ FULLRATE
) >>8) &0xff); 2575 wrindir(s
, SV_CIADCOUTPUT
,0); 2577 if(request_irq(s
->irq
, sv_interrupt
, SA_SHIRQ
,"S3 SonicVibes", s
)) { 2578 printk(KERN_ERR
"sv: irq %u in use\n", s
->irq
); 2581 printk(KERN_INFO
"sv: found adapter at io %#lx irq %u dmaa %#06x dmac %#06x revision %u\n", 2582 s
->ioenh
, s
->irq
, s
->iodmaa
, s
->iodmac
,rdindir(s
, SV_CIREVISION
)); 2583 /* register devices */ 2584 if((s
->dev_audio
=register_sound_dsp(&sv_audio_fops
, -1)) <0) 2586 if((s
->dev_mixer
=register_sound_mixer(&sv_mixer_fops
, -1)) <0) 2588 if((s
->dev_midi
=register_sound_midi(&sv_midi_fops
, -1)) <0) 2590 if((s
->dev_dmfm
=register_sound_special(&sv_dmfm_fops
,15/* ?? */)) <0) 2592 pci_set_master(pcidev
);/* enable bus mastering */ 2593 /* initialize the chips */ 2596 val
= SOUND_MASK_LINE
|SOUND_MASK_SYNTH
; 2597 mixer_ioctl(s
, SOUND_MIXER_WRITE_RECSRC
, (unsigned long)&val
); 2598 for(i
=0; i
<sizeof(initvol
)/sizeof(initvol
[0]); i
++) { 2599 val
= initvol
[i
].vol
; 2600 mixer_ioctl(s
, initvol
[i
].mixch
, (unsigned long)&val
); 2603 /* store it in the driver field */ 2604 pci_set_drvdata(pcidev
, s
); 2605 pcidev
->dma_mask
=0x00ffffff; 2606 /* put it into driver list */ 2607 list_add_tail(&s
->devs
, &devs
); 2608 /* increment devindex */ 2609 if(devindex
< NR_DEVICE
-1) 2614 unregister_sound_midi(s
->dev_midi
); 2616 unregister_sound_mixer(s
->dev_mixer
); 2618 unregister_sound_dsp(s
->dev_audio
); 2620 printk(KERN_ERR
"sv: cannot register misc device\n"); 2621 free_irq(s
->irq
, s
); 2623 release_region(s
->iosynth
, SV_EXTENT_SYNTH
); 2625 release_region(s
->iomidi
, SV_EXTENT_MIDI
); 2627 release_region(s
->iodmac
, SV_EXTENT_DMA
); 2629 release_region(s
->iodmaa
, SV_EXTENT_DMA
); 2631 release_region(s
->ioenh
, SV_EXTENT_ENH
); 2637 static void __devinit
sv_remove(struct pci_dev
*dev
) 2639 struct sv_state
*s
=pci_get_drvdata(dev
); 2644 outb(~0, s
->ioenh
+ SV_CODEC_INTMASK
);/* disable ints */ 2646 inb(s
->ioenh
+ SV_CODEC_STATUS
);/* ack interrupts */ 2647 wrindir(s
, SV_CIENABLE
,0);/* disable DMAA and DMAC */ 2648 /*outb(0, s->iodmaa + SV_DMA_RESET);*/ 2649 /*outb(0, s->iodmac + SV_DMA_RESET);*/ 2650 free_irq(s
->irq
, s
); 2651 release_region(s
->iodmac
, SV_EXTENT_DMA
); 2652 release_region(s
->iodmaa
, SV_EXTENT_DMA
); 2653 release_region(s
->ioenh
, SV_EXTENT_ENH
); 2654 release_region(s
->iomidi
, SV_EXTENT_MIDI
); 2655 release_region(s
->iosynth
, SV_EXTENT_SYNTH
); 2656 unregister_sound_dsp(s
->dev_audio
); 2657 unregister_sound_mixer(s
->dev_mixer
); 2658 unregister_sound_midi(s
->dev_midi
); 2659 unregister_sound_special(s
->dev_dmfm
); 2661 pci_set_drvdata(dev
, NULL
); 2664 static struct pci_device_id id_table
[] __devinitdata
= { 2665 { PCI_VENDOR_ID_S3
, PCI_DEVICE_ID_S3_SONICVIBES
, PCI_ANY_ID
, PCI_ANY_ID
,0,0}, 2669 MODULE_DEVICE_TABLE(pci
, id_table
); 2671 static struct pci_driver sv_driver
= { 2678 static int __init
init_sonicvibes(void) 2680 if(!pci_present())/* No PCI bus in this machine! */ 2682 printk(KERN_INFO
"sv: version v0.27 time " __TIME__
" " __DATE__
"\n"); 2684 if(!(wavetable_mem
=__get_free_pages(GFP_KERNEL
,20-PAGE_SHIFT
))) 2685 printk(KERN_INFO
"sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n"); 2687 returnpci_module_init(&sv_driver
); 2690 static void __exit
cleanup_sonicvibes(void) 2692 printk(KERN_INFO
"sv: unloading\n"); 2693 pci_unregister_driver(&sv_driver
); 2695 free_pages(wavetable_mem
,20-PAGE_SHIFT
); 2698 module_init(init_sonicvibes
); 2699 module_exit(cleanup_sonicvibes
); 2701 /* --------------------------------------------------------------------- */ 2705 /* format is: sonicvibes=[reverb] sonicvibesdmaio=dmaioaddr */ 2707 static int __init
sonicvibes_setup(char*str
) 2709 static unsigned __initdata nr_dev
=0; 2711 if(nr_dev
>= NR_DEVICE
) 2714 if(get_option(&str
, &reverb
[nr_dev
]) ==2) 2715 (void)get_option(&str
, &wavetable
[nr_dev
]); 2717 (void)get_option(&str
, &reverb
[nr_dev
]); 2724 __setup("sonicvibes=", sonicvibes_setup
);