1 /*****************************************************************************/ 4 * esssolo1.c -- ESS Technology Solo1 (ES1946) 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 * Module command line parameters: 26 * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible 27 * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible 28 * /dev/midi simple MIDI UART interface, no ioctl 31 * 10.11.1998 0.1 Initial release (without any hardware) 32 * 22.03.1999 0.2 cinfo.blocks should be reset after GETxPTR ioctl. 33 * reported by Johan Maes <joma@telindus.be> 34 * return EAGAIN instead of EBUSY when O_NONBLOCK 35 * read/write cannot be executed 36 * 07.04.1999 0.3 implemented the following ioctl's: SOUND_PCM_READ_RATE, 37 * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 38 * Alpha fixes reported by Peter Jones <pjones@redhat.com> 39 * 15.06.1999 0.4 Fix bad allocation bug. 40 * Thanks to Deti Fliegl <fliegl@in.tum.de> 41 * 28.06.1999 0.5 Add pci_set_master 42 * 12.08.1999 0.6 Fix MIDI UART crashing the driver 43 * Changed mixer semantics from OSS documented 44 * behaviour to OSS "code behaviour". 45 * Recording might actually work now. 46 * The real DDMA controller address register is at PCI config 47 * 0x60, while the register at 0x18 is used as a placeholder 48 * register for BIOS address allocation. This register 49 * is supposed to be copied into 0x60, according 50 * to the Solo1 datasheet. When I do that, I can access 51 * the DDMA registers except the mask bit, which 52 * is stuck at 1. When I copy the contents of 0x18 +0x10 53 * to the DDMA base register, everything seems to work. 54 * The fun part is that the Windows Solo1 driver doesn't 55 * seem to do these tricks. 56 * Bugs remaining: plops and clicks when starting/stopping playback 57 * 31.08.1999 0.7 add spin_lock_init 58 * replaced current->state = x with set_current_state(x) 59 * 03.09.1999 0.8 change read semantics for MIDI to match 60 * OSS more closely; remove possible wakeup race 61 * 07.10.1999 0.9 Fix initialization; complain if sequencer writes time out 62 * Revised resource grabbing for the FM synthesizer 63 * 28.10.1999 0.10 More waitqueue races fixed 64 * 09.12.1999 0.11 Work around stupid Alpha port issue (virt_to_bus(kmalloc(GFP_DMA)) > 16M) 65 * Disabling recording on Alpha 66 * 12.01.2000 0.12 Prevent some ioctl's from returning bad count values on underrun/overrun; 67 * Tim Janik's BSE (Bedevilled Sound Engine) found this 68 * Integrated (aka redid 8-)) APM support patch by Zach Brown 69 * 07.02.2000 0.13 Use pci_alloc_consistent and pci_register_driver 70 * 19.02.2000 0.14 Use pci_dma_supported to determine if recording should be disabled 71 * 13.03.2000 0.15 Reintroduce initialization of a couple of PCI config space registers 72 * 21.11.2000 0.16 Initialize dma buffers in poll, otherwise poll may return a bogus mask 75 /*****************************************************************************/ 77 #include <linux/version.h> 78 #include <linux/module.h> 79 #include <linux/string.h> 80 #include <linux/ioport.h> 81 #include <linux/sched.h> 82 #include <linux/delay.h> 83 #include <linux/sound.h> 84 #include <linux/malloc.h> 85 #include <linux/soundcard.h> 86 #include <linux/pci.h> 87 #include <linux/bitops.h> 91 #include <linux/init.h> 92 #include <linux/poll.h> 93 #include <linux/spinlock.h> 94 #include <linux/smp_lock.h> 95 #include <linux/wrapper.h> 96 #include <asm/uaccess.h> 97 #include <asm/hardirq.h> 101 /* --------------------------------------------------------------------- */ 103 #undef OSS_DOCUMENTED_MIXER_SEMANTICS 105 /* --------------------------------------------------------------------- */ 107 #ifndef PCI_VENDOR_ID_ESS 108 #define PCI_VENDOR_ID_ESS 0x125d 110 #ifndef PCI_DEVICE_ID_ESS_SOLO1 111 #define PCI_DEVICE_ID_ESS_SOLO1 0x1969 114 #define SOLO1_MAGIC ((PCI_VENDOR_ID_ESS<<16)|PCI_DEVICE_ID_ESS_SOLO1) 116 #define DDMABASE_OFFSET 0/* chip bug workaround kludge */ 117 #define DDMABASE_EXTENT 16 119 #define IOBASE_EXTENT 16 120 #define SBBASE_EXTENT 16 121 #define VCBASE_EXTENT (DDMABASE_EXTENT+DDMABASE_OFFSET) 122 #define MPUBASE_EXTENT 4 123 #define GPBASE_EXTENT 4 125 #define FMSYNTH_EXTENT 4 127 /* MIDI buffer sizes */ 129 #define MIDIINBUF 256 130 #define MIDIOUTBUF 256 132 #define FMODE_MIDI_SHIFT 3 133 #define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT) 134 #define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT) 136 #define FMODE_DMFM 0x10 138 /* --------------------------------------------------------------------- */ 144 /* list of esssolo1 devices */ 145 struct list_head devs
; 147 /* the corresponding pci_dev structure */ 150 /* soundcore stuff */ 156 /* hardware resources */ 157 unsigned long iobase
, sbbase
, vcbase
, ddmabase
, mpubase
, gpbase
;/* long for SPARC */ 160 /* mixer registers */ 162 unsigned short vol
[10]; 165 unsigned short micpreamp
; 172 unsigned char clkdiv
; 176 struct semaphore open_sem
; 178 wait_queue_head_t open_wait
; 186 unsigned hwptr
, swptr
; 187 unsigned total_bytes
; 189 unsigned error
;/* over/underrun */ 190 wait_queue_head_t wait
; 191 /* redundant, but makes calculations easier */ 194 unsigned fragsamples
; 198 unsigned endcleared
:1; 199 unsigned ossfragshift
; 201 unsigned subdivision
; 206 unsigned ird
, iwr
, icnt
; 207 unsigned ord
, owr
, ocnt
; 208 wait_queue_head_t iwait
; 209 wait_queue_head_t owait
; 210 struct timer_list timer
; 211 unsigned char ibuf
[MIDIINBUF
]; 212 unsigned char obuf
[MIDIOUTBUF
]; 216 /* --------------------------------------------------------------------- */ 218 staticLIST_HEAD(devs
); 220 /* --------------------------------------------------------------------- */ 222 extern inlinevoidwrite_seq(struct solo1_state
*s
,unsigned char data
) 227 /* the __cli stunt is to send the data within the command window */ 228 for(i
=0; i
<0xffff; i
++) { 231 if(!(inb(s
->sbbase
+0xc) &0x80)) { 232 outb(data
, s
->sbbase
+0xc); 233 __restore_flags(flags
); 236 __restore_flags(flags
); 238 printk(KERN_ERR
"esssolo1: write_seq timeout\n"); 239 outb(data
, s
->sbbase
+0xc); 242 extern inlineintread_seq(struct solo1_state
*s
,unsigned char*data
) 248 for(i
=0; i
<0xffff; i
++) 249 if(inb(s
->sbbase
+0xe) &0x80) { 250 *data
=inb(s
->sbbase
+0xa); 253 printk(KERN_ERR
"esssolo1: read_seq timeout\n"); 257 static intinlinereset_ctrl(struct solo1_state
*s
) 261 outb(3, s
->sbbase
+6);/* clear sequencer and FIFO */ 263 outb(0, s
->sbbase
+6); 264 for(i
=0; i
<0xffff; i
++) 265 if(inb(s
->sbbase
+0xe) &0x80) 266 if(inb(s
->sbbase
+0xa) ==0xaa) { 267 write_seq(s
,0xc6);/* enter enhanced mode */ 273 static voidwrite_ctrl(struct solo1_state
*s
,unsigned char reg
,unsigned char data
) 280 static unsigned charread_ctrl(struct solo1_state
*s
,unsigned char reg
) 291 static voidwrite_mixer(struct solo1_state
*s
,unsigned char reg
,unsigned char data
) 293 outb(reg
, s
->sbbase
+4); 294 outb(data
, s
->sbbase
+5); 297 static unsigned charread_mixer(struct solo1_state
*s
,unsigned char reg
) 299 outb(reg
, s
->sbbase
+4); 300 returninb(s
->sbbase
+5); 303 /* --------------------------------------------------------------------- */ 305 extern inlineunsignedld2(unsigned int x
) 330 /* --------------------------------------------------------------------- */ 332 extern inlinevoidstop_dac(struct solo1_state
*s
) 336 spin_lock_irqsave(&s
->lock
, flags
); 337 s
->ena
&= ~FMODE_WRITE
; 338 write_mixer(s
,0x78,0x10); 339 spin_unlock_irqrestore(&s
->lock
, flags
); 342 static voidstart_dac(struct solo1_state
*s
) 346 spin_lock_irqsave(&s
->lock
, flags
); 347 if(!(s
->ena
& FMODE_WRITE
) && (s
->dma_dac
.mapped
|| s
->dma_dac
.count
>0) && s
->dma_dac
.ready
) { 348 s
->ena
|= FMODE_WRITE
; 349 write_mixer(s
,0x78,0x12); 351 write_mixer(s
,0x78,0x13); 353 spin_unlock_irqrestore(&s
->lock
, flags
); 356 extern inlinevoidstop_adc(struct solo1_state
*s
) 360 spin_lock_irqsave(&s
->lock
, flags
); 361 s
->ena
&= ~FMODE_READ
; 362 write_ctrl(s
,0xb8,0xe); 363 spin_unlock_irqrestore(&s
->lock
, flags
); 366 static voidstart_adc(struct solo1_state
*s
) 370 spin_lock_irqsave(&s
->lock
, flags
); 371 if(!(s
->ena
& FMODE_READ
) && (s
->dma_adc
.mapped
|| s
->dma_adc
.count
< (signed)(s
->dma_adc
.dmasize
-2*s
->dma_adc
.fragsize
)) 372 && s
->dma_adc
.ready
) { 373 s
->ena
|= FMODE_READ
; 374 write_ctrl(s
,0xb8,0xf); 376 printk(KERN_DEBUG
"solo1: DMAbuffer: 0x%08lx\n", (long)s
->dma_adc
.rawbuf
); 377 printk(KERN_DEBUG
"solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x\n", 378 inb(s
->ddmabase
+0xf),inw(s
->ddmabase
+4),inl(s
->ddmabase
),inb(s
->ddmabase
+8)); 380 outb(0, s
->ddmabase
+0xd);/* master reset */ 381 outb(1, s
->ddmabase
+0xf);/* mask */ 382 outb(0x54/*0x14*/, s
->ddmabase
+0xb);/* DMA_MODE_READ | DMA_MODE_AUTOINIT */ 383 outl(virt_to_bus(s
->dma_adc
.rawbuf
), s
->ddmabase
); 384 outw(s
->dma_adc
.dmasize
-1, s
->ddmabase
+4); 385 outb(0, s
->ddmabase
+0xf); 387 spin_unlock_irqrestore(&s
->lock
, flags
); 389 printk(KERN_DEBUG
"solo1: start DMA: reg B8: 0x%02x SBstat: 0x%02x\n" 390 KERN_DEBUG
"solo1: DMA: stat: 0x%02x cnt: 0x%04x mask: 0x%02x\n", 391 read_ctrl(s
,0xb8),inb(s
->sbbase
+0xc), 392 inb(s
->ddmabase
+8),inw(s
->ddmabase
+4),inb(s
->ddmabase
+0xf)); 393 printk(KERN_DEBUG
"solo1: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8: 0x%02x\n" 394 KERN_DEBUG
"solo1: B1: 0x%02x B2: 0x%02x B4: 0x%02x B7: 0x%02x B8: 0x%02x B9: 0x%02x\n", 395 read_ctrl(s
,0xa1),read_ctrl(s
,0xa2),read_ctrl(s
,0xa4),read_ctrl(s
,0xa5),read_ctrl(s
,0xa8), 396 read_ctrl(s
,0xb1),read_ctrl(s
,0xb2),read_ctrl(s
,0xb4),read_ctrl(s
,0xb7),read_ctrl(s
,0xb8), 401 /* --------------------------------------------------------------------- */ 403 #define DMABUF_DEFAULTORDER (15-PAGE_SHIFT) 404 #define DMABUF_MINORDER 1 406 extern inlinevoiddealloc_dmabuf(struct solo1_state
*s
,struct dmabuf
*db
) 408 struct page
*page
, *pend
; 411 /* undo marking the pages as reserved */ 412 pend
=virt_to_page(db
->rawbuf
+ (PAGE_SIZE
<< db
->buforder
) -1); 413 for(page
=virt_to_page(db
->rawbuf
); page
<= pend
; page
++) 414 mem_map_unreserve(page
); 415 pci_free_consistent(s
->dev
, PAGE_SIZE
<< db
->buforder
, db
->rawbuf
, db
->dmaaddr
); 418 db
->mapped
= db
->ready
=0; 421 static intprog_dmabuf(struct solo1_state
*s
,struct dmabuf
*db
) 424 unsigned bytespersec
; 425 unsigned bufs
, sample_shift
=0; 426 struct page
*page
, *pend
; 428 db
->hwptr
= db
->swptr
= db
->total_bytes
= db
->count
= db
->error
= db
->endcleared
=0; 430 db
->ready
= db
->mapped
=0; 431 for(order
= DMABUF_DEFAULTORDER
; order
>= DMABUF_MINORDER
; order
--) 432 if((db
->rawbuf
=pci_alloc_consistent(s
->dev
, PAGE_SIZE
<< order
, &db
->dmaaddr
))) 436 db
->buforder
= order
; 437 /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */ 438 pend
=virt_to_page(db
->rawbuf
+ (PAGE_SIZE
<< db
->buforder
) -1); 439 for(page
=virt_to_page(db
->rawbuf
); page
<= pend
; page
++) 440 mem_map_reserve(page
); 442 if(s
->fmt
& (AFMT_S16_LE
| AFMT_U16_LE
)) 446 bytespersec
= s
->rate
<< sample_shift
; 447 bufs
= PAGE_SIZE
<< db
->buforder
; 448 if(db
->ossfragshift
) { 449 if((1000<< db
->ossfragshift
) < bytespersec
) 450 db
->fragshift
=ld2(bytespersec
/1000); 452 db
->fragshift
= db
->ossfragshift
; 454 db
->fragshift
=ld2(bytespersec
/100/(db
->subdivision
? db
->subdivision
:1)); 458 db
->numfrag
= bufs
>> db
->fragshift
; 459 while(db
->numfrag
<4&& db
->fragshift
>3) { 461 db
->numfrag
= bufs
>> db
->fragshift
; 463 db
->fragsize
=1<< db
->fragshift
; 464 if(db
->ossmaxfrags
>=4&& db
->ossmaxfrags
< db
->numfrag
) 465 db
->numfrag
= db
->ossmaxfrags
; 466 db
->fragsamples
= db
->fragsize
>> sample_shift
; 467 db
->dmasize
= db
->numfrag
<< db
->fragshift
; 471 extern inlineintprog_dmabuf_adc(struct solo1_state
*s
) 477 /* check if PCI implementation supports 24bit busmaster DMA */ 478 if(s
->dev
->dma_mask
>0xffffff) 480 if((c
=prog_dmabuf(s
, &s
->dma_adc
))) 482 va
= s
->dma_adc
.dmaaddr
; 483 if((va
& ~((1<<24)-1))) 484 panic("solo1: buffer above 16M boundary"); 485 outb(0, s
->ddmabase
+0xd);/* clear */ 486 outb(1, s
->ddmabase
+0xf);/* mask */ 487 /*outb(0, s->ddmabase+8);*//* enable (enable is active low!) */ 488 outb(0x54, s
->ddmabase
+0xb);/* DMA_MODE_READ | DMA_MODE_AUTOINIT */ 489 outl(va
, s
->ddmabase
); 490 outw(s
->dma_adc
.dmasize
-1, s
->ddmabase
+4); 491 c
= - s
->dma_adc
.fragsamples
; 492 write_ctrl(s
,0xa4, c
); 493 write_ctrl(s
,0xa5, c
>>8); 494 outb(0, s
->ddmabase
+0xf); 499 extern inlineintprog_dmabuf_dac(struct solo1_state
*s
) 505 if((c
=prog_dmabuf(s
, &s
->dma_dac
))) 507 memset(s
->dma_dac
.rawbuf
, (s
->fmt
& (AFMT_U8
| AFMT_U16_LE
)) ?0:0x80, s
->dma_dac
.dmasize
);/* almost correct for U16 */ 508 va
= s
->dma_dac
.dmaaddr
; 509 if((va
^ (va
+ s
->dma_dac
.dmasize
-1)) & ~((1<<20)-1)) 510 panic("solo1: buffer crosses 1M boundary"); 512 /* warning: s->dma_dac.dmasize & 0xffff must not be zero! i.e. this limits us to a 32k buffer */ 513 outw(s
->dma_dac
.dmasize
, s
->iobase
+4); 514 c
= - s
->dma_dac
.fragsamples
; 515 write_mixer(s
,0x74, c
); 516 write_mixer(s
,0x76, c
>>8); 517 outb(0xa, s
->iobase
+6); 522 extern inlinevoidclear_advance(void*buf
,unsigned bsize
,unsigned bptr
,unsigned len
,unsigned char c
) 524 if(bptr
+ len
> bsize
) { 525 unsigned x
= bsize
- bptr
; 526 memset(((char*)buf
) + bptr
, c
, x
); 530 memset(((char*)buf
) + bptr
, c
, len
); 533 /* call with spinlock held! */ 535 static voidsolo1_update_ptr(struct solo1_state
*s
) 540 /* update ADC pointer */ 541 if(s
->ena
& FMODE_READ
) { 542 hwptr
= (s
->dma_adc
.dmasize
-1-inw(s
->ddmabase
+4)) % s
->dma_adc
.dmasize
; 543 diff
= (s
->dma_adc
.dmasize
+ hwptr
- s
->dma_adc
.hwptr
) % s
->dma_adc
.dmasize
; 544 s
->dma_adc
.hwptr
= hwptr
; 545 s
->dma_adc
.total_bytes
+= diff
; 546 s
->dma_adc
.count
+= diff
; 548 printk(KERN_DEBUG
"solo1: rd: hwptr %u swptr %u dmasize %u count %u\n", 549 s
->dma_adc
.hwptr
, s
->dma_adc
.swptr
, s
->dma_adc
.dmasize
, s
->dma_adc
.count
); 551 if(s
->dma_adc
.mapped
) { 552 if(s
->dma_adc
.count
>= (signed)s
->dma_adc
.fragsize
) 553 wake_up(&s
->dma_adc
.wait
); 555 if(s
->dma_adc
.count
> (signed)(s
->dma_adc
.dmasize
- ((3* s
->dma_adc
.fragsize
) >>1))) { 556 s
->ena
&= ~FMODE_READ
; 557 write_ctrl(s
,0xb8,0xe); 560 if(s
->dma_adc
.count
>0) 561 wake_up(&s
->dma_adc
.wait
); 564 /* update DAC pointer */ 565 if(s
->ena
& FMODE_WRITE
) { 566 hwptr
= (s
->dma_dac
.dmasize
-inw(s
->iobase
+4)) % s
->dma_dac
.dmasize
; 567 diff
= (s
->dma_dac
.dmasize
+ hwptr
- s
->dma_dac
.hwptr
) % s
->dma_dac
.dmasize
; 568 s
->dma_dac
.hwptr
= hwptr
; 569 s
->dma_dac
.total_bytes
+= diff
; 571 printk(KERN_DEBUG
"solo1: wr: hwptr %u swptr %u dmasize %u count %u\n", 572 s
->dma_dac
.hwptr
, s
->dma_dac
.swptr
, s
->dma_dac
.dmasize
, s
->dma_dac
.count
); 574 if(s
->dma_dac
.mapped
) { 575 s
->dma_dac
.count
+= diff
; 576 if(s
->dma_dac
.count
>= (signed)s
->dma_dac
.fragsize
) 577 wake_up(&s
->dma_dac
.wait
); 579 s
->dma_dac
.count
-= diff
; 580 if(s
->dma_dac
.count
<=0) { 581 s
->ena
&= ~FMODE_WRITE
; 582 write_mixer(s
,0x78,0x12); 584 }else if(s
->dma_dac
.count
<= (signed)s
->dma_dac
.fragsize
&& !s
->dma_dac
.endcleared
) { 585 clear_advance(s
->dma_dac
.rawbuf
, s
->dma_dac
.dmasize
, s
->dma_dac
.swptr
, 586 s
->dma_dac
.fragsize
, (s
->fmt
& (AFMT_U8
| AFMT_U16_LE
)) ?0:0x80); 587 s
->dma_dac
.endcleared
=1; 589 if(s
->dma_dac
.count
< (signed)s
->dma_dac
.dmasize
) 590 wake_up(&s
->dma_dac
.wait
); 595 /* --------------------------------------------------------------------- */ 597 static voidprog_codec(struct solo1_state
*s
) 605 /* program sampling rates */ 606 filter
= s
->rate
*9/20;/* Set filter roll-off to 90% of rate/2 */ 607 fdiv
=256-7160000/ (filter
*82); 608 spin_lock_irqsave(&s
->lock
, flags
); 609 write_ctrl(s
,0xa1, s
->clkdiv
); 610 write_ctrl(s
,0xa2, fdiv
); 611 write_mixer(s
,0x70, s
->clkdiv
); 612 write_mixer(s
,0x72, fdiv
); 613 /* program ADC parameters */ 614 write_ctrl(s
,0xb8,0xe); 615 write_ctrl(s
,0xb9,/*0x1*/0); 616 write_ctrl(s
,0xa8, (s
->channels
>1) ?0x11:0x12); 618 if(s
->fmt
& (AFMT_S16_LE
| AFMT_U16_LE
)) 620 if(s
->fmt
& (AFMT_S16_LE
| AFMT_S8
)) 624 write_ctrl(s
,0xb7, (c
&0x70) |1); 625 write_ctrl(s
,0xb7, c
); 626 write_ctrl(s
,0xb1,0x50); 627 write_ctrl(s
,0xb2,0x50); 628 /* program DAC parameters */ 630 if(s
->fmt
& (AFMT_S16_LE
| AFMT_U16_LE
)) 632 if(s
->fmt
& (AFMT_S16_LE
| AFMT_S8
)) 636 write_mixer(s
,0x7a, c
); 637 write_mixer(s
,0x78,0x10); 639 spin_unlock_irqrestore(&s
->lock
, flags
); 642 /* --------------------------------------------------------------------- */ 644 static const char invalid_magic
[] = KERN_CRIT
"solo1: invalid magic value\n"; 646 #define VALIDATE_STATE(s) \ 648 if (!(s) || (s)->magic != SOLO1_MAGIC) { \ 649 printk(invalid_magic); \ 654 /* --------------------------------------------------------------------- */ 656 static intmixer_ioctl(struct solo1_state
*s
,unsigned int cmd
,unsigned long arg
) 658 static const unsigned int mixer_src
[8] = { 659 SOUND_MASK_MIC
, SOUND_MASK_MIC
, SOUND_MASK_CD
, SOUND_MASK_VOLUME
, 660 SOUND_MASK_MIC
,0, SOUND_MASK_LINE
,0 662 static const unsigned char mixtable1
[SOUND_MIXER_NRDEVICES
] = { 663 [SOUND_MIXER_PCM
] =1,/* voice */ 664 [SOUND_MIXER_SYNTH
] =2,/* FM */ 665 [SOUND_MIXER_CD
] =3,/* CD */ 666 [SOUND_MIXER_LINE
] =4,/* Line */ 667 [SOUND_MIXER_LINE1
] =5,/* AUX */ 668 [SOUND_MIXER_MIC
] =6,/* Mic */ 669 [SOUND_MIXER_LINE2
] =7,/* Mono in */ 670 [SOUND_MIXER_SPEAKER
] =8,/* Speaker */ 671 [SOUND_MIXER_RECLEV
] =9,/* Recording level */ 672 [SOUND_MIXER_VOLUME
] =10/* Master Volume */ 674 static const unsigned char mixreg
[] = { 683 unsigned char l
, r
, rl
, rr
, vidx
; 688 if(cmd
== SOUND_MIXER_PRIVATE1
) { 689 /* enable/disable/query mixer preamp */ 690 if(get_user(val
, (int*)arg
)) 693 val
= val
?0xff:0xf7; 694 write_mixer(s
,0x7d, (read_mixer(s
,0x7d) |0x08) & val
); 696 val
= (read_mixer(s
,0x7d) &0x08) ?1:0; 697 returnput_user(val
, (int*)arg
); 699 if(cmd
== SOUND_MIXER_PRIVATE2
) { 700 /* enable/disable/query spatializer */ 701 if(get_user(val
, (int*)arg
)) 705 write_mixer(s
,0x52, val
); 706 write_mixer(s
,0x50, val
?0x08:0); 708 returnput_user(read_mixer(s
,0x52), (int*)arg
); 710 if(cmd
== SOUND_MIXER_INFO
) { 712 strncpy(info
.id
,"Solo1",sizeof(info
.id
)); 713 strncpy(info
.name
,"ESS Solo1",sizeof(info
.name
)); 714 info
.modify_counter
= s
->mix
.modcnt
; 715 if(copy_to_user((void*)arg
, &info
,sizeof(info
))) 719 if(cmd
== SOUND_OLD_MIXER_INFO
) { 720 _old_mixer_info info
; 721 strncpy(info
.id
,"Solo1",sizeof(info
.id
)); 722 strncpy(info
.name
,"ESS Solo1",sizeof(info
.name
)); 723 if(copy_to_user((void*)arg
, &info
,sizeof(info
))) 727 if(cmd
== OSS_GETVERSION
) 728 returnput_user(SOUND_VERSION
, (int*)arg
); 729 if(_IOC_TYPE(cmd
) !='M'||_SIOC_SIZE(cmd
) !=sizeof(int)) 731 if(_SIOC_DIR(cmd
) == _SIOC_READ
) { 732 switch(_IOC_NR(cmd
)) { 733 case SOUND_MIXER_RECSRC
:/* Arg contains a bit for each recording source */ 734 returnput_user(mixer_src
[read_mixer(s
,0x1c) &7], (int*)arg
); 736 case SOUND_MIXER_DEVMASK
:/* Arg contains a bit for each supported device */ 737 returnput_user(SOUND_MASK_PCM
| SOUND_MASK_SYNTH
| SOUND_MASK_CD
| 738 SOUND_MASK_LINE
| SOUND_MASK_LINE1
| SOUND_MASK_MIC
| 739 SOUND_MASK_VOLUME
| SOUND_MASK_LINE2
| SOUND_MASK_RECLEV
| 740 SOUND_MASK_SPEAKER
, (int*)arg
); 742 case SOUND_MIXER_RECMASK
:/* Arg contains a bit for each supported recording source */ 743 returnput_user(SOUND_MASK_LINE
| SOUND_MASK_MIC
| SOUND_MASK_CD
| SOUND_MASK_VOLUME
, (int*)arg
); 745 case SOUND_MIXER_STEREODEVS
:/* Mixer channels supporting stereo */ 746 returnput_user(SOUND_MASK_PCM
| SOUND_MASK_SYNTH
| SOUND_MASK_CD
| 747 SOUND_MASK_LINE
| SOUND_MASK_LINE1
| SOUND_MASK_MIC
| 748 SOUND_MASK_VOLUME
| SOUND_MASK_LINE2
| SOUND_MASK_RECLEV
, (int*)arg
); 750 case SOUND_MIXER_CAPS
: 751 returnput_user(SOUND_CAP_EXCL_INPUT
, (int*)arg
); 755 if(i
>= SOUND_MIXER_NRDEVICES
|| !(vidx
= mixtable1
[i
])) 757 returnput_user(s
->mix
.vol
[vidx
-1], (int*)arg
); 760 if(_SIOC_DIR(cmd
) != (_SIOC_READ
|_SIOC_WRITE
)) 763 switch(_IOC_NR(cmd
)) { 764 case SOUND_MIXER_RECSRC
:/* Arg contains a bit for each recording source */ 767 static const unsigned char regs
[] = { 768 0x1c,0x1a,0x36,0x38,0x3a,0x3c,0x3e,0x60,0x62,0x6d,0x7c 772 for(i
=0; i
<sizeof(regs
); i
++) 773 printk(KERN_DEBUG
"solo1: mixer reg 0x%02x: 0x%02x\n", 774 regs
[i
],read_mixer(s
, regs
[i
])); 775 printk(KERN_DEBUG
"solo1: ctrl reg 0x%02x: 0x%02x\n", 776 0xb4,read_ctrl(s
,0xb4)); 779 if(get_user(val
, (int*)arg
)) 785 val
&= ~mixer_src
[read_mixer(s
,0x1c) &7]; 786 for(i
=0; i
<8; i
++) { 787 if(mixer_src
[i
] & val
) 792 write_mixer(s
,0x1c, i
); 795 case SOUND_MIXER_VOLUME
: 796 if(get_user(val
, (int*)arg
)) 818 write_mixer(s
,0x60, rl
); 819 write_mixer(s
,0x62, rr
); 820 #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS 821 s
->mix
.vol
[9] = ((unsigned int)r
<<8) | l
; 825 returnput_user(s
->mix
.vol
[9], (int*)arg
); 827 case SOUND_MIXER_SPEAKER
: 828 if(get_user(val
, (int*)arg
)) 837 write_mixer(s
,0x3c, rl
); 838 #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS 839 s
->mix
.vol
[7] = l
*0x101; 843 returnput_user(s
->mix
.vol
[7], (int*)arg
); 845 case SOUND_MIXER_RECLEV
: 846 if(get_user(val
, (int*)arg
)) 848 l
= (val
<<1) &0x1fe; 853 r
= (val
>>7) &0x1fe; 862 write_ctrl(s
,0xb4, (rl
<<4) | rr
); 863 #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS 864 s
->mix
.vol
[8] = ((unsigned int)r
<<8) | l
; 868 returnput_user(s
->mix
.vol
[8], (int*)arg
); 872 if(i
>= SOUND_MIXER_NRDEVICES
|| !(vidx
= mixtable1
[i
])) 874 if(get_user(val
, (int*)arg
)) 876 l
= (val
<<1) &0x1fe; 881 r
= (val
>>7) &0x1fe; 890 write_mixer(s
, mixreg
[vidx
-1], (rl
<<4) | rr
); 891 #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS 892 s
->mix
.vol
[vidx
-1] = ((unsigned int)r
<<8) | l
; 894 s
->mix
.vol
[vidx
-1] = val
; 896 returnput_user(s
->mix
.vol
[vidx
-1], (int*)arg
); 900 /* --------------------------------------------------------------------- */ 902 static loff_t
solo1_llseek(struct file
*file
, loff_t offset
,int origin
) 907 /* --------------------------------------------------------------------- */ 909 static intsolo1_open_mixdev(struct inode
*inode
,struct file
*file
) 911 int minor
=MINOR(inode
->i_rdev
); 912 struct list_head
*list
; 913 struct solo1_state
*s
; 915 for(list
= devs
.next
; ; list
= list
->next
) { 918 s
=list_entry(list
,struct solo1_state
, devs
); 919 if(s
->dev_mixer
== minor
) 923 file
->private_data
= s
; 927 static intsolo1_release_mixdev(struct inode
*inode
,struct file
*file
) 929 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 935 static intsolo1_ioctl_mixdev(struct inode
*inode
,struct file
*file
,unsigned int cmd
,unsigned long arg
) 937 returnmixer_ioctl((struct solo1_state
*)file
->private_data
, cmd
, arg
); 940 static/*const*/struct file_operations solo1_mixer_fops
= { 942 llseek
: solo1_llseek
, 943 ioctl
: solo1_ioctl_mixdev
, 944 open
: solo1_open_mixdev
, 945 release
: solo1_release_mixdev
, 948 /* --------------------------------------------------------------------- */ 950 static intdrain_dac(struct solo1_state
*s
,int nonblock
) 952 DECLARE_WAITQUEUE(wait
, current
); 957 if(s
->dma_dac
.mapped
) 959 add_wait_queue(&s
->dma_dac
.wait
, &wait
); 961 set_current_state(TASK_INTERRUPTIBLE
); 962 spin_lock_irqsave(&s
->lock
, flags
); 963 count
= s
->dma_dac
.count
; 964 spin_unlock_irqrestore(&s
->lock
, flags
); 967 if(signal_pending(current
)) 970 remove_wait_queue(&s
->dma_dac
.wait
, &wait
); 971 set_current_state(TASK_RUNNING
); 974 tmo
=3* HZ
* (count
+ s
->dma_dac
.fragsize
) /2/ s
->rate
; 975 if(s
->fmt
& (AFMT_S16_LE
| AFMT_U16_LE
)) 979 if(!schedule_timeout(tmo
+1)) 980 printk(KERN_DEBUG
"solo1: dma timed out??\n"); 982 remove_wait_queue(&s
->dma_dac
.wait
, &wait
); 983 set_current_state(TASK_RUNNING
); 984 if(signal_pending(current
)) 989 /* --------------------------------------------------------------------- */ 991 static ssize_t
solo1_read(struct file
*file
,char*buffer
,size_t count
, loff_t
*ppos
) 993 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 994 DECLARE_WAITQUEUE(wait
, current
); 1001 if(ppos
!= &file
->f_pos
) 1003 if(s
->dma_adc
.mapped
) 1005 if(!s
->dma_adc
.ready
&& (ret
=prog_dmabuf_adc(s
))) 1007 if(!access_ok(VERIFY_WRITE
, buffer
, count
)) 1010 add_wait_queue(&s
->dma_adc
.wait
, &wait
); 1012 spin_lock_irqsave(&s
->lock
, flags
); 1013 swptr
= s
->dma_adc
.swptr
; 1014 cnt
= s
->dma_adc
.dmasize
-swptr
; 1015 if(s
->dma_adc
.count
< cnt
) 1016 cnt
= s
->dma_adc
.count
; 1018 __set_current_state(TASK_INTERRUPTIBLE
); 1019 spin_unlock_irqrestore(&s
->lock
, flags
); 1023 printk(KERN_DEBUG
"solo1_read: reg B8: 0x%02x DMAstat: 0x%02x DMAcnt: 0x%04x SBstat: 0x%02x cnt: %u\n", 1024 read_ctrl(s
,0xb8),inb(s
->ddmabase
+8),inw(s
->ddmabase
+4),inb(s
->sbbase
+0xc), cnt
); 1029 printk(KERN_DEBUG
"solo1_read: regs: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8: 0x%02x\n" 1030 KERN_DEBUG
"solo1_read: regs: B1: 0x%02x B2: 0x%02x B7: 0x%02x B8: 0x%02x B9: 0x%02x\n" 1031 KERN_DEBUG
"solo1_read: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x mask: 0x%02x\n" 1032 KERN_DEBUG
"solo1_read: SBstat: 0x%02x cnt: %u\n", 1033 read_ctrl(s
,0xa1),read_ctrl(s
,0xa2),read_ctrl(s
,0xa4),read_ctrl(s
,0xa5),read_ctrl(s
,0xa8), 1034 read_ctrl(s
,0xb1),read_ctrl(s
,0xb2),read_ctrl(s
,0xb7),read_ctrl(s
,0xb8),read_ctrl(s
,0xb9), 1035 inl(s
->ddmabase
),inw(s
->ddmabase
+4),inb(s
->ddmabase
+8),inb(s
->ddmabase
+15),inb(s
->sbbase
+0xc), cnt
); 1037 if(inb(s
->ddmabase
+15) &1) 1038 printk(KERN_ERR
"solo1: cannot start recording, DDMA mask bit stuck at 1\n"); 1039 if(file
->f_flags
& O_NONBLOCK
) { 1046 printk(KERN_DEBUG
"solo1_read: regs: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8: 0x%02x\n" 1047 KERN_DEBUG
"solo1_read: regs: B1: 0x%02x B2: 0x%02x B7: 0x%02x B8: 0x%02x B9: 0x%02x\n" 1048 KERN_DEBUG
"solo1_read: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x mask: 0x%02x\n" 1049 KERN_DEBUG
"solo1_read: SBstat: 0x%02x cnt: %u\n", 1050 read_ctrl(s
,0xa1),read_ctrl(s
,0xa2),read_ctrl(s
,0xa4),read_ctrl(s
,0xa5),read_ctrl(s
,0xa8), 1051 read_ctrl(s
,0xb1),read_ctrl(s
,0xb2),read_ctrl(s
,0xb7),read_ctrl(s
,0xb8),read_ctrl(s
,0xb9), 1052 inl(s
->ddmabase
),inw(s
->ddmabase
+4),inb(s
->ddmabase
+8),inb(s
->ddmabase
+15),inb(s
->sbbase
+0xc), cnt
); 1054 if(signal_pending(current
)) { 1061 if(copy_to_user(buffer
, s
->dma_adc
.rawbuf
+ swptr
, cnt
)) { 1066 swptr
= (swptr
+ cnt
) % s
->dma_adc
.dmasize
; 1067 spin_lock_irqsave(&s
->lock
, flags
); 1068 s
->dma_adc
.swptr
= swptr
; 1069 s
->dma_adc
.count
-= cnt
; 1070 spin_unlock_irqrestore(&s
->lock
, flags
); 1076 printk(KERN_DEBUG
"solo1_read: reg B8: 0x%02x DMAstat: 0x%02x DMAcnt: 0x%04x SBstat: 0x%02x\n", 1077 read_ctrl(s
,0xb8),inb(s
->ddmabase
+8),inw(s
->ddmabase
+4),inb(s
->sbbase
+0xc)); 1080 remove_wait_queue(&s
->dma_adc
.wait
, &wait
); 1081 set_current_state(TASK_RUNNING
); 1085 static ssize_t
solo1_write(struct file
*file
,const char*buffer
,size_t count
, loff_t
*ppos
) 1087 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 1088 DECLARE_WAITQUEUE(wait
, current
); 1090 unsigned long flags
; 1095 if(ppos
!= &file
->f_pos
) 1097 if(s
->dma_dac
.mapped
) 1099 if(!s
->dma_dac
.ready
&& (ret
=prog_dmabuf_dac(s
))) 1101 if(!access_ok(VERIFY_READ
, buffer
, count
)) 1104 printk(KERN_DEBUG
"solo1_write: reg 70: 0x%02x 71: 0x%02x 72: 0x%02x 74: 0x%02x 76: 0x%02x 78: 0x%02x 7A: 0x%02x\n" 1105 KERN_DEBUG
"solo1_write: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x SBstat: 0x%02x\n", 1106 read_mixer(s
,0x70),read_mixer(s
,0x71),read_mixer(s
,0x72),read_mixer(s
,0x74),read_mixer(s
,0x76), 1107 read_mixer(s
,0x78),read_mixer(s
,0x7a),inl(s
->iobase
),inw(s
->iobase
+4),inb(s
->iobase
+6),inb(s
->sbbase
+0xc)); 1108 printk(KERN_DEBUG
"solo1_write: reg 78: 0x%02x reg 7A: 0x%02x DMAcnt: 0x%04x DMAstat: 0x%02x SBstat: 0x%02x\n", 1109 read_mixer(s
,0x78),read_mixer(s
,0x7a),inw(s
->iobase
+4),inb(s
->iobase
+6),inb(s
->sbbase
+0xc)); 1112 add_wait_queue(&s
->dma_dac
.wait
, &wait
); 1114 spin_lock_irqsave(&s
->lock
, flags
); 1115 if(s
->dma_dac
.count
<0) { 1116 s
->dma_dac
.count
=0; 1117 s
->dma_dac
.swptr
= s
->dma_dac
.hwptr
; 1119 swptr
= s
->dma_dac
.swptr
; 1120 cnt
= s
->dma_dac
.dmasize
-swptr
; 1121 if(s
->dma_dac
.count
+ cnt
> s
->dma_dac
.dmasize
) 1122 cnt
= s
->dma_dac
.dmasize
- s
->dma_dac
.count
; 1124 __set_current_state(TASK_INTERRUPTIBLE
); 1125 spin_unlock_irqrestore(&s
->lock
, flags
); 1130 if(file
->f_flags
& O_NONBLOCK
) { 1136 if(signal_pending(current
)) { 1143 if(copy_from_user(s
->dma_dac
.rawbuf
+ swptr
, buffer
, cnt
)) { 1148 swptr
= (swptr
+ cnt
) % s
->dma_dac
.dmasize
; 1149 spin_lock_irqsave(&s
->lock
, flags
); 1150 s
->dma_dac
.swptr
= swptr
; 1151 s
->dma_dac
.count
+= cnt
; 1152 s
->dma_dac
.endcleared
=0; 1153 spin_unlock_irqrestore(&s
->lock
, flags
); 1159 remove_wait_queue(&s
->dma_dac
.wait
, &wait
); 1160 set_current_state(TASK_RUNNING
); 1164 /* No kernel lock - we have our own spinlock */ 1165 static unsigned intsolo1_poll(struct file
*file
,struct poll_table_struct
*wait
) 1167 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 1168 unsigned long flags
; 1169 unsigned int mask
=0; 1172 if(file
->f_mode
& FMODE_WRITE
) { 1173 if(!s
->dma_dac
.ready
&&prog_dmabuf_dac(s
)) 1175 poll_wait(file
, &s
->dma_dac
.wait
, wait
); 1177 if(file
->f_mode
& FMODE_READ
) { 1178 if(!s
->dma_adc
.ready
&&prog_dmabuf_adc(s
)) 1180 poll_wait(file
, &s
->dma_adc
.wait
, wait
); 1182 spin_lock_irqsave(&s
->lock
, flags
); 1183 solo1_update_ptr(s
); 1184 if(file
->f_mode
& FMODE_READ
) { 1185 if(s
->dma_adc
.mapped
) { 1186 if(s
->dma_adc
.count
>= (signed)s
->dma_adc
.fragsize
) 1187 mask
|= POLLIN
| POLLRDNORM
; 1189 if(s
->dma_adc
.count
>0) 1190 mask
|= POLLIN
| POLLRDNORM
; 1193 if(file
->f_mode
& FMODE_WRITE
) { 1194 if(s
->dma_dac
.mapped
) { 1195 if(s
->dma_dac
.count
>= (signed)s
->dma_dac
.fragsize
) 1196 mask
|= POLLOUT
| POLLWRNORM
; 1198 if((signed)s
->dma_dac
.dmasize
> s
->dma_dac
.count
) 1199 mask
|= POLLOUT
| POLLWRNORM
; 1202 spin_unlock_irqrestore(&s
->lock
, flags
); 1207 static intsolo1_mmap(struct file
*file
,struct vm_area_struct
*vma
) 1209 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 1216 if(vma
->vm_flags
& VM_WRITE
) { 1217 if((ret
=prog_dmabuf_dac(s
)) !=0) 1220 }else if(vma
->vm_flags
& VM_READ
) { 1221 if((ret
=prog_dmabuf_adc(s
)) !=0) 1227 if(vma
->vm_pgoff
!=0) 1229 size
= vma
->vm_end
- vma
->vm_start
; 1230 if(size
> (PAGE_SIZE
<< db
->buforder
)) 1233 if(remap_page_range(vma
->vm_start
,virt_to_phys(db
->rawbuf
), size
, vma
->vm_page_prot
)) 1242 static intsolo1_ioctl(struct inode
*inode
,struct file
*file
,unsigned int cmd
,unsigned long arg
) 1244 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 1245 unsigned long flags
; 1246 audio_buf_info abinfo
; 1248 int val
, mapped
, ret
, count
; 1250 unsigned rate1
, rate2
; 1253 mapped
= ((file
->f_mode
& FMODE_WRITE
) && s
->dma_dac
.mapped
) || 1254 ((file
->f_mode
& FMODE_READ
) && s
->dma_adc
.mapped
); 1256 case OSS_GETVERSION
: 1257 returnput_user(SOUND_VERSION
, (int*)arg
); 1259 case SNDCTL_DSP_SYNC
: 1260 if(file
->f_mode
& FMODE_WRITE
) 1261 returndrain_dac(s
,0/*file->f_flags & O_NONBLOCK*/); 1264 case SNDCTL_DSP_SETDUPLEX
: 1267 case SNDCTL_DSP_GETCAPS
: 1268 returnput_user(DSP_CAP_DUPLEX
| DSP_CAP_REALTIME
| DSP_CAP_TRIGGER
| DSP_CAP_MMAP
, (int*)arg
); 1270 case SNDCTL_DSP_RESET
: 1271 if(file
->f_mode
& FMODE_WRITE
) { 1274 s
->dma_dac
.swptr
= s
->dma_dac
.hwptr
= s
->dma_dac
.count
= s
->dma_dac
.total_bytes
=0; 1276 if(file
->f_mode
& FMODE_READ
) { 1279 s
->dma_adc
.swptr
= s
->dma_adc
.hwptr
= s
->dma_adc
.count
= s
->dma_adc
.total_bytes
=0; 1284 case SNDCTL_DSP_SPEED
: 1285 if(get_user(val
, (int*)arg
)) 1290 s
->dma_adc
.ready
= s
->dma_dac
.ready
=0; 1291 /* program sampling rates */ 1296 div1
= (768000+ val
/2) / val
; 1297 rate1
= (768000+ div1
/2) / div1
; 1299 div2
= (793800+ val
/2) / val
; 1300 rate2
= (793800+ div2
/2) / div2
; 1301 div2
= (-div2
) &0x7f; 1302 if(abs(val
- rate2
) <abs(val
- rate1
)) { 1310 returnput_user(s
->rate
, (int*)arg
); 1312 case SNDCTL_DSP_STEREO
: 1313 if(get_user(val
, (int*)arg
)) 1317 s
->dma_adc
.ready
= s
->dma_dac
.ready
=0; 1318 /* program channels */ 1319 s
->channels
= val
?2:1; 1323 case SNDCTL_DSP_CHANNELS
: 1324 if(get_user(val
, (int*)arg
)) 1329 s
->dma_adc
.ready
= s
->dma_dac
.ready
=0; 1330 /* program channels */ 1331 s
->channels
= (val
>=2) ?2:1; 1334 returnput_user(s
->channels
, (int*)arg
); 1336 case SNDCTL_DSP_GETFMTS
:/* Returns a mask */ 1337 returnput_user(AFMT_S16_LE
|AFMT_U16_LE
|AFMT_S8
|AFMT_U8
, (int*)arg
); 1339 case SNDCTL_DSP_SETFMT
:/* Selects ONE fmt*/ 1340 if(get_user(val
, (int*)arg
)) 1342 if(val
!= AFMT_QUERY
) { 1345 s
->dma_adc
.ready
= s
->dma_dac
.ready
=0; 1346 /* program format */ 1347 if(val
!= AFMT_S16_LE
&& val
!= AFMT_U16_LE
&& 1348 val
!= AFMT_S8
&& val
!= AFMT_U8
) 1353 returnput_user(s
->fmt
, (int*)arg
); 1355 case SNDCTL_DSP_POST
: 1358 case SNDCTL_DSP_GETTRIGGER
: 1360 if(file
->f_mode
& s
->ena
& FMODE_READ
) 1361 val
|= PCM_ENABLE_INPUT
; 1362 if(file
->f_mode
& s
->ena
& FMODE_WRITE
) 1363 val
|= PCM_ENABLE_OUTPUT
; 1364 returnput_user(val
, (int*)arg
); 1366 case SNDCTL_DSP_SETTRIGGER
: 1367 if(get_user(val
, (int*)arg
)) 1369 if(file
->f_mode
& FMODE_READ
) { 1370 if(val
& PCM_ENABLE_INPUT
) { 1371 if(!s
->dma_adc
.ready
&& (ret
=prog_dmabuf_adc(s
))) 1374 if(inb(s
->ddmabase
+15) &1) 1375 printk(KERN_ERR
"solo1: cannot start recording, DDMA mask bit stuck at 1\n"); 1379 if(file
->f_mode
& FMODE_WRITE
) { 1380 if(val
& PCM_ENABLE_OUTPUT
) { 1381 if(!s
->dma_dac
.ready
&& (ret
=prog_dmabuf_dac(s
))) 1389 case SNDCTL_DSP_GETOSPACE
: 1390 if(!(file
->f_mode
& FMODE_WRITE
)) 1392 if(!s
->dma_dac
.ready
&& (ret
=prog_dmabuf_dac(s
))) 1394 spin_lock_irqsave(&s
->lock
, flags
); 1395 solo1_update_ptr(s
); 1396 abinfo
.fragsize
= s
->dma_dac
.fragsize
; 1397 count
= s
->dma_dac
.count
; 1400 abinfo
.bytes
= s
->dma_dac
.dmasize
- count
; 1401 abinfo
.fragstotal
= s
->dma_dac
.numfrag
; 1402 abinfo
.fragments
= abinfo
.bytes
>> s
->dma_dac
.fragshift
; 1403 spin_unlock_irqrestore(&s
->lock
, flags
); 1404 returncopy_to_user((void*)arg
, &abinfo
,sizeof(abinfo
)) ? -EFAULT
:0; 1406 case SNDCTL_DSP_GETISPACE
: 1407 if(!(file
->f_mode
& FMODE_READ
)) 1409 if(!s
->dma_adc
.ready
&& (ret
=prog_dmabuf_adc(s
))) 1411 spin_lock_irqsave(&s
->lock
, flags
); 1412 solo1_update_ptr(s
); 1413 abinfo
.fragsize
= s
->dma_adc
.fragsize
; 1414 abinfo
.bytes
= s
->dma_adc
.count
; 1415 abinfo
.fragstotal
= s
->dma_adc
.numfrag
; 1416 abinfo
.fragments
= abinfo
.bytes
>> s
->dma_adc
.fragshift
; 1417 spin_unlock_irqrestore(&s
->lock
, flags
); 1418 returncopy_to_user((void*)arg
, &abinfo
,sizeof(abinfo
)) ? -EFAULT
:0; 1420 case SNDCTL_DSP_NONBLOCK
: 1421 file
->f_flags
|= O_NONBLOCK
; 1424 case SNDCTL_DSP_GETODELAY
: 1425 if(!(file
->f_mode
& FMODE_WRITE
)) 1427 if(!s
->dma_dac
.ready
&& (ret
=prog_dmabuf_dac(s
))) 1429 spin_lock_irqsave(&s
->lock
, flags
); 1430 solo1_update_ptr(s
); 1431 count
= s
->dma_dac
.count
; 1432 spin_unlock_irqrestore(&s
->lock
, flags
); 1435 returnput_user(count
, (int*)arg
); 1437 case SNDCTL_DSP_GETIPTR
: 1438 if(!(file
->f_mode
& FMODE_READ
)) 1440 if(!s
->dma_adc
.ready
&& (ret
=prog_dmabuf_adc(s
))) 1442 spin_lock_irqsave(&s
->lock
, flags
); 1443 solo1_update_ptr(s
); 1444 cinfo
.bytes
= s
->dma_adc
.total_bytes
; 1445 cinfo
.blocks
= s
->dma_adc
.count
>> s
->dma_adc
.fragshift
; 1446 cinfo
.ptr
= s
->dma_adc
.hwptr
; 1447 if(s
->dma_adc
.mapped
) 1448 s
->dma_adc
.count
&= s
->dma_adc
.fragsize
-1; 1449 spin_unlock_irqrestore(&s
->lock
, flags
); 1450 returncopy_to_user((void*)arg
, &cinfo
,sizeof(cinfo
)); 1452 case SNDCTL_DSP_GETOPTR
: 1453 if(!(file
->f_mode
& FMODE_WRITE
)) 1455 if(!s
->dma_dac
.ready
&& (ret
=prog_dmabuf_dac(s
))) 1457 spin_lock_irqsave(&s
->lock
, flags
); 1458 solo1_update_ptr(s
); 1459 cinfo
.bytes
= s
->dma_dac
.total_bytes
; 1460 count
= s
->dma_dac
.count
; 1463 cinfo
.blocks
= count
>> s
->dma_dac
.fragshift
; 1464 cinfo
.ptr
= s
->dma_dac
.hwptr
; 1465 if(s
->dma_dac
.mapped
) 1466 s
->dma_dac
.count
&= s
->dma_dac
.fragsize
-1; 1467 spin_unlock_irqrestore(&s
->lock
, flags
); 1469 printk(KERN_DEBUG
"esssolo1: GETOPTR: bytes %u blocks %u ptr %u, buforder %u numfrag %u fragshift %u\n" 1470 KERN_DEBUG
"esssolo1: swptr %u count %u fragsize %u dmasize %u fragsamples %u\n", 1471 cinfo
.bytes
, cinfo
.blocks
, cinfo
.ptr
, s
->dma_dac
.buforder
, s
->dma_dac
.numfrag
, s
->dma_dac
.fragshift
, 1472 s
->dma_dac
.swptr
, s
->dma_dac
.count
, s
->dma_dac
.fragsize
, s
->dma_dac
.dmasize
, s
->dma_dac
.fragsamples
); 1474 returncopy_to_user((void*)arg
, &cinfo
,sizeof(cinfo
)); 1476 case SNDCTL_DSP_GETBLKSIZE
: 1477 if(file
->f_mode
& FMODE_WRITE
) { 1478 if((val
=prog_dmabuf_dac(s
))) 1480 returnput_user(s
->dma_dac
.fragsize
, (int*)arg
); 1482 if((val
=prog_dmabuf_adc(s
))) 1484 returnput_user(s
->dma_adc
.fragsize
, (int*)arg
); 1486 case SNDCTL_DSP_SETFRAGMENT
: 1487 if(get_user(val
, (int*)arg
)) 1489 if(file
->f_mode
& FMODE_READ
) { 1490 s
->dma_adc
.ossfragshift
= val
&0xffff; 1491 s
->dma_adc
.ossmaxfrags
= (val
>>16) &0xffff; 1492 if(s
->dma_adc
.ossfragshift
<4) 1493 s
->dma_adc
.ossfragshift
=4; 1494 if(s
->dma_adc
.ossfragshift
>15) 1495 s
->dma_adc
.ossfragshift
=15; 1496 if(s
->dma_adc
.ossmaxfrags
<4) 1497 s
->dma_adc
.ossmaxfrags
=4; 1499 if(file
->f_mode
& FMODE_WRITE
) { 1500 s
->dma_dac
.ossfragshift
= val
&0xffff; 1501 s
->dma_dac
.ossmaxfrags
= (val
>>16) &0xffff; 1502 if(s
->dma_dac
.ossfragshift
<4) 1503 s
->dma_dac
.ossfragshift
=4; 1504 if(s
->dma_dac
.ossfragshift
>15) 1505 s
->dma_dac
.ossfragshift
=15; 1506 if(s
->dma_dac
.ossmaxfrags
<4) 1507 s
->dma_dac
.ossmaxfrags
=4; 1511 case SNDCTL_DSP_SUBDIVIDE
: 1512 if((file
->f_mode
& FMODE_READ
&& s
->dma_adc
.subdivision
) || 1513 (file
->f_mode
& FMODE_WRITE
&& s
->dma_dac
.subdivision
)) 1515 if(get_user(val
, (int*)arg
)) 1517 if(val
!=1&& val
!=2&& val
!=4) 1519 if(file
->f_mode
& FMODE_READ
) 1520 s
->dma_adc
.subdivision
= val
; 1521 if(file
->f_mode
& FMODE_WRITE
) 1522 s
->dma_dac
.subdivision
= val
; 1525 case SOUND_PCM_READ_RATE
: 1526 returnput_user(s
->rate
, (int*)arg
); 1528 case SOUND_PCM_READ_CHANNELS
: 1529 returnput_user(s
->channels
, (int*)arg
); 1531 case SOUND_PCM_READ_BITS
: 1532 returnput_user((s
->fmt
& (AFMT_S8
|AFMT_U8
)) ?8:16, (int*)arg
); 1534 case SOUND_PCM_WRITE_FILTER
: 1535 case SNDCTL_DSP_SETSYNCRO
: 1536 case SOUND_PCM_READ_FILTER
: 1540 returnmixer_ioctl(s
, cmd
, arg
); 1543 static intsolo1_release(struct inode
*inode
,struct file
*file
) 1545 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 1549 if(file
->f_mode
& FMODE_WRITE
) 1550 drain_dac(s
, file
->f_flags
& O_NONBLOCK
); 1552 if(file
->f_mode
& FMODE_WRITE
) { 1554 outb(0, s
->iobase
+6);/* disable DMA */ 1555 dealloc_dmabuf(s
, &s
->dma_dac
); 1557 if(file
->f_mode
& FMODE_READ
) { 1559 outb(1, s
->ddmabase
+0xf);/* mask DMA channel */ 1560 outb(0, s
->ddmabase
+0xd);/* DMA master clear */ 1561 dealloc_dmabuf(s
, &s
->dma_adc
); 1563 s
->open_mode
&= ~(FMODE_READ
| FMODE_WRITE
); 1564 wake_up(&s
->open_wait
); 1570 static intsolo1_open(struct inode
*inode
,struct file
*file
) 1572 int minor
=MINOR(inode
->i_rdev
); 1573 DECLARE_WAITQUEUE(wait
, current
); 1574 struct list_head
*list
; 1575 struct solo1_state
*s
; 1577 for(list
= devs
.next
; ; list
= list
->next
) { 1580 s
=list_entry(list
,struct solo1_state
, devs
); 1581 if(!((s
->dev_audio
^ minor
) & ~0xf)) 1585 file
->private_data
= s
; 1586 /* wait for device to become free */ 1588 while(s
->open_mode
& (FMODE_READ
| FMODE_WRITE
)) { 1589 if(file
->f_flags
& O_NONBLOCK
) { 1593 add_wait_queue(&s
->open_wait
, &wait
); 1594 __set_current_state(TASK_INTERRUPTIBLE
); 1597 remove_wait_queue(&s
->open_wait
, &wait
); 1598 set_current_state(TASK_RUNNING
); 1599 if(signal_pending(current
)) 1608 s
->dma_adc
.ossfragshift
= s
->dma_adc
.ossmaxfrags
= s
->dma_adc
.subdivision
=0; 1609 s
->dma_dac
.ossfragshift
= s
->dma_dac
.ossmaxfrags
= s
->dma_dac
.subdivision
=0; 1610 s
->open_mode
|= file
->f_mode
& (FMODE_READ
| FMODE_WRITE
); 1616 static/*const*/struct file_operations solo1_audio_fops
= { 1618 llseek
: solo1_llseek
, 1625 release
: solo1_release
, 1628 /* --------------------------------------------------------------------- */ 1630 /* hold spinlock for the following! */ 1631 static voidsolo1_handle_midi(struct solo1_state
*s
) 1639 while(!(inb(s
->mpubase
+1) &0x80)) { 1640 ch
=inb(s
->mpubase
); 1641 if(s
->midi
.icnt
< MIDIINBUF
) { 1642 s
->midi
.ibuf
[s
->midi
.iwr
] = ch
; 1643 s
->midi
.iwr
= (s
->midi
.iwr
+1) % MIDIINBUF
; 1649 wake_up(&s
->midi
.iwait
); 1651 while(!(inb(s
->mpubase
+1) &0x40) && s
->midi
.ocnt
>0) { 1652 outb(s
->midi
.obuf
[s
->midi
.ord
], s
->mpubase
); 1653 s
->midi
.ord
= (s
->midi
.ord
+1) % MIDIOUTBUF
; 1655 if(s
->midi
.ocnt
< MIDIOUTBUF
-16) 1659 wake_up(&s
->midi
.owait
); 1662 static voidsolo1_interrupt(int irq
,void*dev_id
,struct pt_regs
*regs
) 1664 struct solo1_state
*s
= (struct solo1_state
*)dev_id
; 1665 unsigned int intsrc
; 1667 /* fastpath out, to ease interrupt sharing */ 1668 intsrc
=inb(s
->iobase
+7);/* get interrupt source(s) */ 1671 (void)inb(s
->sbbase
+0xe);/* clear interrupt */ 1672 spin_lock(&s
->lock
); 1673 /* clear audio interrupts first */ 1675 write_mixer(s
,0x7a,read_mixer(s
,0x7a) &0x7f); 1676 solo1_update_ptr(s
); 1677 solo1_handle_midi(s
); 1678 spin_unlock(&s
->lock
); 1681 static voidsolo1_midi_timer(unsigned long data
) 1683 struct solo1_state
*s
= (struct solo1_state
*)data
; 1684 unsigned long flags
; 1686 spin_lock_irqsave(&s
->lock
, flags
); 1687 solo1_handle_midi(s
); 1688 spin_unlock_irqrestore(&s
->lock
, flags
); 1689 s
->midi
.timer
.expires
= jiffies
+1; 1690 add_timer(&s
->midi
.timer
); 1693 /* --------------------------------------------------------------------- */ 1695 static ssize_t
solo1_midi_read(struct file
*file
,char*buffer
,size_t count
, loff_t
*ppos
) 1697 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 1698 DECLARE_WAITQUEUE(wait
, current
); 1700 unsigned long flags
; 1705 if(ppos
!= &file
->f_pos
) 1707 if(!access_ok(VERIFY_WRITE
, buffer
, count
)) 1712 add_wait_queue(&s
->midi
.iwait
, &wait
); 1714 spin_lock_irqsave(&s
->lock
, flags
); 1716 cnt
= MIDIINBUF
- ptr
; 1717 if(s
->midi
.icnt
< cnt
) 1720 __set_current_state(TASK_INTERRUPTIBLE
); 1721 spin_unlock_irqrestore(&s
->lock
, flags
); 1725 if(file
->f_flags
& O_NONBLOCK
) { 1731 if(signal_pending(current
)) { 1738 if(copy_to_user(buffer
, s
->midi
.ibuf
+ ptr
, cnt
)) { 1743 ptr
= (ptr
+ cnt
) % MIDIINBUF
; 1744 spin_lock_irqsave(&s
->lock
, flags
); 1746 s
->midi
.icnt
-= cnt
; 1747 spin_unlock_irqrestore(&s
->lock
, flags
); 1753 __set_current_state(TASK_RUNNING
); 1754 remove_wait_queue(&s
->midi
.iwait
, &wait
); 1758 static ssize_t
solo1_midi_write(struct file
*file
,const char*buffer
,size_t count
, loff_t
*ppos
) 1760 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 1761 DECLARE_WAITQUEUE(wait
, current
); 1763 unsigned long flags
; 1768 if(ppos
!= &file
->f_pos
) 1770 if(!access_ok(VERIFY_READ
, buffer
, count
)) 1775 add_wait_queue(&s
->midi
.owait
, &wait
); 1777 spin_lock_irqsave(&s
->lock
, flags
); 1779 cnt
= MIDIOUTBUF
- ptr
; 1780 if(s
->midi
.ocnt
+ cnt
> MIDIOUTBUF
) 1781 cnt
= MIDIOUTBUF
- s
->midi
.ocnt
; 1783 __set_current_state(TASK_INTERRUPTIBLE
); 1784 solo1_handle_midi(s
); 1786 spin_unlock_irqrestore(&s
->lock
, flags
); 1790 if(file
->f_flags
& O_NONBLOCK
) { 1796 if(signal_pending(current
)) { 1803 if(copy_from_user(s
->midi
.obuf
+ ptr
, buffer
, cnt
)) { 1808 ptr
= (ptr
+ cnt
) % MIDIOUTBUF
; 1809 spin_lock_irqsave(&s
->lock
, flags
); 1811 s
->midi
.ocnt
+= cnt
; 1812 spin_unlock_irqrestore(&s
->lock
, flags
); 1816 spin_lock_irqsave(&s
->lock
, flags
); 1817 solo1_handle_midi(s
); 1818 spin_unlock_irqrestore(&s
->lock
, flags
); 1820 __set_current_state(TASK_RUNNING
); 1821 remove_wait_queue(&s
->midi
.owait
, &wait
); 1825 /* No kernel lock - we have our own spinlock */ 1826 static unsigned intsolo1_midi_poll(struct file
*file
,struct poll_table_struct
*wait
) 1828 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 1829 unsigned long flags
; 1830 unsigned int mask
=0; 1833 if(file
->f_flags
& FMODE_WRITE
) 1834 poll_wait(file
, &s
->midi
.owait
, wait
); 1835 if(file
->f_flags
& FMODE_READ
) 1836 poll_wait(file
, &s
->midi
.iwait
, wait
); 1837 spin_lock_irqsave(&s
->lock
, flags
); 1838 if(file
->f_flags
& FMODE_READ
) { 1840 mask
|= POLLIN
| POLLRDNORM
; 1842 if(file
->f_flags
& FMODE_WRITE
) { 1843 if(s
->midi
.ocnt
< MIDIOUTBUF
) 1844 mask
|= POLLOUT
| POLLWRNORM
; 1846 spin_unlock_irqrestore(&s
->lock
, flags
); 1850 static intsolo1_midi_open(struct inode
*inode
,struct file
*file
) 1852 int minor
=MINOR(inode
->i_rdev
); 1853 DECLARE_WAITQUEUE(wait
, current
); 1854 unsigned long flags
; 1855 struct list_head
*list
; 1856 struct solo1_state
*s
; 1858 for(list
= devs
.next
; ; list
= list
->next
) { 1861 s
=list_entry(list
,struct solo1_state
, devs
); 1862 if(s
->dev_midi
== minor
) 1866 file
->private_data
= s
; 1867 /* wait for device to become free */ 1869 while(s
->open_mode
& (file
->f_mode
<< FMODE_MIDI_SHIFT
)) { 1870 if(file
->f_flags
& O_NONBLOCK
) { 1874 add_wait_queue(&s
->open_wait
, &wait
); 1875 __set_current_state(TASK_INTERRUPTIBLE
); 1878 remove_wait_queue(&s
->open_wait
, &wait
); 1879 set_current_state(TASK_RUNNING
); 1880 if(signal_pending(current
)) 1884 spin_lock_irqsave(&s
->lock
, flags
); 1885 if(!(s
->open_mode
& (FMODE_MIDI_READ
| FMODE_MIDI_WRITE
))) { 1886 s
->midi
.ird
= s
->midi
.iwr
= s
->midi
.icnt
=0; 1887 s
->midi
.ord
= s
->midi
.owr
= s
->midi
.ocnt
=0; 1888 outb(0xff, s
->mpubase
+1);/* reset command */ 1889 outb(0x3f, s
->mpubase
+1);/* uart command */ 1890 if(!(inb(s
->mpubase
+1) &0x80)) 1892 s
->midi
.ird
= s
->midi
.iwr
= s
->midi
.icnt
=0; 1893 outb(0xb0, s
->iobase
+7);/* enable A1, A2, MPU irq's */ 1894 init_timer(&s
->midi
.timer
); 1895 s
->midi
.timer
.expires
= jiffies
+1; 1896 s
->midi
.timer
.data
= (unsigned long)s
; 1897 s
->midi
.timer
.function
= solo1_midi_timer
; 1898 add_timer(&s
->midi
.timer
); 1900 if(file
->f_mode
& FMODE_READ
) { 1901 s
->midi
.ird
= s
->midi
.iwr
= s
->midi
.icnt
=0; 1903 if(file
->f_mode
& FMODE_WRITE
) { 1904 s
->midi
.ord
= s
->midi
.owr
= s
->midi
.ocnt
=0; 1906 spin_unlock_irqrestore(&s
->lock
, flags
); 1907 s
->open_mode
|= (file
->f_mode
<< FMODE_MIDI_SHIFT
) & (FMODE_MIDI_READ
| FMODE_MIDI_WRITE
); 1912 static intsolo1_midi_release(struct inode
*inode
,struct file
*file
) 1914 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 1915 DECLARE_WAITQUEUE(wait
, current
); 1916 unsigned long flags
; 1917 unsigned count
, tmo
; 1922 if(file
->f_mode
& FMODE_WRITE
) { 1923 add_wait_queue(&s
->midi
.owait
, &wait
); 1925 __set_current_state(TASK_INTERRUPTIBLE
); 1926 spin_lock_irqsave(&s
->lock
, flags
); 1927 count
= s
->midi
.ocnt
; 1928 spin_unlock_irqrestore(&s
->lock
, flags
); 1931 if(signal_pending(current
)) 1933 if(file
->f_flags
& O_NONBLOCK
) { 1934 remove_wait_queue(&s
->midi
.owait
, &wait
); 1935 set_current_state(TASK_RUNNING
); 1938 tmo
= (count
* HZ
) /3100; 1939 if(!schedule_timeout(tmo
? :1) && tmo
) 1940 printk(KERN_DEBUG
"solo1: midi timed out??\n"); 1942 remove_wait_queue(&s
->midi
.owait
, &wait
); 1943 set_current_state(TASK_RUNNING
); 1946 s
->open_mode
&= (~(file
->f_mode
<< FMODE_MIDI_SHIFT
)) & (FMODE_MIDI_READ
|FMODE_MIDI_WRITE
); 1947 spin_lock_irqsave(&s
->lock
, flags
); 1948 if(!(s
->open_mode
& (FMODE_MIDI_READ
| FMODE_MIDI_WRITE
))) { 1949 outb(0x30, s
->iobase
+7);/* enable A1, A2 irq's */ 1950 del_timer(&s
->midi
.timer
); 1952 spin_unlock_irqrestore(&s
->lock
, flags
); 1953 wake_up(&s
->open_wait
); 1959 static/*const*/struct file_operations solo1_midi_fops
= { 1961 llseek
: solo1_llseek
, 1962 read
: solo1_midi_read
, 1963 write
: solo1_midi_write
, 1964 poll
: solo1_midi_poll
, 1965 open
: solo1_midi_open
, 1966 release
: solo1_midi_release
, 1969 /* --------------------------------------------------------------------- */ 1971 static intsolo1_dmfm_ioctl(struct inode
*inode
,struct file
*file
,unsigned int cmd
,unsigned long arg
) 1973 static const unsigned char op_offset
[18] = { 1974 0x00,0x01,0x02,0x03,0x04,0x05, 1975 0x08,0x09,0x0A,0x0B,0x0C,0x0D, 1976 0x10,0x11,0x12,0x13,0x14,0x15 1978 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 1979 struct dm_fm_voice v
; 1980 struct dm_fm_note n
; 1981 struct dm_fm_params p
; 1986 case FM_IOCTL_RESET
: 1987 for(regb
=0xb0; regb
<0xb9; regb
++) { 1988 outb(regb
, s
->sbbase
); 1989 outb(0, s
->sbbase
+1); 1990 outb(regb
, s
->sbbase
+2); 1991 outb(0, s
->sbbase
+3); 1995 case FM_IOCTL_PLAY_NOTE
: 1996 if(copy_from_user(&n
, (void*)arg
,sizeof(n
))) 2007 outb(0xa0+ regb
, io
); 2008 outb(n
.fnum
&0xff, io
+1); 2009 outb(0xb0+ regb
, io
); 2010 outb(((n
.fnum
>>8) &3) | ((n
.octave
&7) <<2) | ((n
.key_on
&1) <<5), io
+1); 2013 case FM_IOCTL_SET_VOICE
: 2014 if(copy_from_user(&v
, (void*)arg
,sizeof(v
))) 2018 regb
= op_offset
[v
.voice
]; 2019 io
= s
->sbbase
+ ((v
.op
&1) <<1); 2020 outb(0x20+ regb
, io
); 2021 outb(((v
.am
&1) <<7) | ((v
.vibrato
&1) <<6) | ((v
.do_sustain
&1) <<5) | 2022 ((v
.kbd_scale
&1) <<4) | (v
.harmonic
&0xf), io
+1); 2023 outb(0x40+ regb
, io
); 2024 outb(((v
.scale_level
&0x3) <<6) | (v
.volume
&0x3f), io
+1); 2025 outb(0x60+ regb
, io
); 2026 outb(((v
.attack
&0xf) <<4) | (v
.decay
&0xf), io
+1); 2027 outb(0x80+ regb
, io
); 2028 outb(((v
.sustain
&0xf) <<4) | (v
.release
&0xf), io
+1); 2029 outb(0xe0+ regb
, io
); 2030 outb(v
.waveform
&0x7, io
+1); 2038 outb(0xc0+ regb
, io
); 2039 outb(((v
.right
&1) <<5) | ((v
.left
&1) <<4) | ((v
.feedback
&7) <<1) | 2040 (v
.connection
&1), io
+1); 2043 case FM_IOCTL_SET_PARAMS
: 2044 if(copy_from_user(&p
, (void*)arg
,sizeof(p
))) 2046 outb(0x08, s
->sbbase
); 2047 outb((p
.kbd_split
&1) <<6, s
->sbbase
+1); 2048 outb(0xbd, s
->sbbase
); 2049 outb(((p
.am_depth
&1) <<7) | ((p
.vib_depth
&1) <<6) | ((p
.rhythm
&1) <<5) | ((p
.bass
&1) <<4) | 2050 ((p
.snare
&1) <<3) | ((p
.tomtom
&1) <<2) | ((p
.cymbal
&1) <<1) | (p
.hihat
&1), s
->sbbase
+1); 2053 case FM_IOCTL_SET_OPL
: 2054 outb(4, s
->sbbase
+2); 2055 outb(arg
, s
->sbbase
+3); 2058 case FM_IOCTL_SET_MODE
: 2059 outb(5, s
->sbbase
+2); 2060 outb(arg
&1, s
->sbbase
+3); 2068 static intsolo1_dmfm_open(struct inode
*inode
,struct file
*file
) 2070 int minor
=MINOR(inode
->i_rdev
); 2071 DECLARE_WAITQUEUE(wait
, current
); 2072 struct list_head
*list
; 2073 struct solo1_state
*s
; 2075 for(list
= devs
.next
; ; list
= list
->next
) { 2078 s
=list_entry(list
,struct solo1_state
, devs
); 2079 if(s
->dev_dmfm
== minor
) 2083 file
->private_data
= s
; 2084 /* wait for device to become free */ 2086 while(s
->open_mode
& FMODE_DMFM
) { 2087 if(file
->f_flags
& O_NONBLOCK
) { 2091 add_wait_queue(&s
->open_wait
, &wait
); 2092 __set_current_state(TASK_INTERRUPTIBLE
); 2095 remove_wait_queue(&s
->open_wait
, &wait
); 2096 set_current_state(TASK_RUNNING
); 2097 if(signal_pending(current
)) 2101 if(!request_region(s
->sbbase
, FMSYNTH_EXTENT
,"ESS Solo1")) { 2103 printk(KERN_ERR
"solo1: FM synth io ports in use, opl3 loaded?\n"); 2106 /* init the stuff */ 2108 outb(0x20, s
->sbbase
+1);/* enable waveforms */ 2109 outb(4, s
->sbbase
+2); 2110 outb(0, s
->sbbase
+3);/* no 4op enabled */ 2111 outb(5, s
->sbbase
+2); 2112 outb(1, s
->sbbase
+3);/* enable OPL3 */ 2113 s
->open_mode
|= FMODE_DMFM
; 2118 static intsolo1_dmfm_release(struct inode
*inode
,struct file
*file
) 2120 struct solo1_state
*s
= (struct solo1_state
*)file
->private_data
; 2126 s
->open_mode
&= ~FMODE_DMFM
; 2127 for(regb
=0xb0; regb
<0xb9; regb
++) { 2128 outb(regb
, s
->sbbase
); 2129 outb(0, s
->sbbase
+1); 2130 outb(regb
, s
->sbbase
+2); 2131 outb(0, s
->sbbase
+3); 2133 release_region(s
->sbbase
, FMSYNTH_EXTENT
); 2134 wake_up(&s
->open_wait
); 2140 static/*const*/struct file_operations solo1_dmfm_fops
= { 2142 llseek
: solo1_llseek
, 2143 ioctl
: solo1_dmfm_ioctl
, 2144 open
: solo1_dmfm_open
, 2145 release
: solo1_dmfm_release
, 2148 /* --------------------------------------------------------------------- */ 2150 static struct initvol
{ 2153 } initvol
[] __initdata
= { 2154 { SOUND_MIXER_WRITE_VOLUME
,0x4040}, 2155 { SOUND_MIXER_WRITE_PCM
,0x4040}, 2156 { SOUND_MIXER_WRITE_SYNTH
,0x4040}, 2157 { SOUND_MIXER_WRITE_CD
,0x4040}, 2158 { SOUND_MIXER_WRITE_LINE
,0x4040}, 2159 { SOUND_MIXER_WRITE_LINE1
,0x4040}, 2160 { SOUND_MIXER_WRITE_LINE2
,0x4040}, 2161 { SOUND_MIXER_WRITE_RECLEV
,0x4040}, 2162 { SOUND_MIXER_WRITE_SPEAKER
,0x4040}, 2163 { SOUND_MIXER_WRITE_MIC
,0x4040} 2166 static intsetup_solo1(struct solo1_state
*s
) 2168 struct pci_dev
*pcidev
= s
->dev
; 2172 /* initialize DDMA base address */ 2173 printk(KERN_DEBUG
"solo1: ddma base address: 0x%lx\n", s
->ddmabase
); 2174 pci_write_config_word(pcidev
,0x60, (s
->ddmabase
& (~0xf)) |1); 2175 /* set DMA policy to DDMA, IRQ emulation off (CLKRUN disabled for now) */ 2176 pci_write_config_dword(pcidev
,0x50,0); 2177 /* disable legacy audio address decode */ 2178 pci_write_config_word(pcidev
,0x40,0x907f); 2180 /* initialize the chips */ 2181 if(!reset_ctrl(s
)) { 2182 printk(KERN_ERR
"esssolo1: cannot reset controller\n"); 2185 outb(0xb0, s
->iobase
+7);/* enable A1, A2, MPU irq's */ 2187 /* initialize mixer regs */ 2188 write_mixer(s
,0x7f,0);/* disable music digital recording */ 2189 write_mixer(s
,0x7d,0x0c);/* enable mic preamp, MONO_OUT is 2nd DAC right channel */ 2190 write_mixer(s
,0x64,0x45);/* volume control */ 2191 write_mixer(s
,0x48,0x10);/* enable music DAC/ES6xx interface */ 2192 write_mixer(s
,0x50,0);/* disable spatializer */ 2193 write_mixer(s
,0x52,0); 2194 write_mixer(s
,0x14,0);/* DAC1 minimum volume */ 2195 write_mixer(s
,0x71,0x20);/* enable new 0xA1 reg format */ 2196 outb(0, s
->ddmabase
+0xd);/* DMA master clear */ 2197 outb(1, s
->ddmabase
+0xf);/* mask channel */ 2198 /*outb(0, s->ddmabase+0x8);*//* enable controller (enable is low active!!) */ 2200 pci_set_master(pcidev
);/* enable bus mastering */ 2204 val
= SOUND_MASK_LINE
; 2205 mixer_ioctl(s
, SOUND_MIXER_WRITE_RECSRC
, (unsigned long)&val
); 2206 for(i
=0; i
<sizeof(initvol
)/sizeof(initvol
[0]); i
++) { 2207 val
= initvol
[i
].vol
; 2208 mixer_ioctl(s
, initvol
[i
].mixch
, (unsigned long)&val
); 2210 val
=1;/* enable mic preamp */ 2211 mixer_ioctl(s
, SOUND_MIXER_PRIVATE1
, (unsigned long)&val
); 2216 static intsolo1_pm_callback(struct pm_dev
*dev
, pm_request_t rqst
,void*data
) 2218 struct solo1_state
*s
= (struct solo1_state
*) dev
->data
; 2226 outb(0, s
->iobase
+6); 2227 /* DMA master clear */ 2228 outb(0, s
->ddmabase
+0xd); 2229 /* reset sequencer and FIFO */ 2230 outb(3, s
->sbbase
+6); 2231 /* turn off DDMA controller address space */ 2232 pci_write_config_word(s
->dev
,0x60,0); 2240 #define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \ 2241 (pci_resource_flags((dev), (num)) & IORESOURCE_IO)) 2243 static int __devinit
solo1_probe(struct pci_dev
*pcidev
,const struct pci_device_id
*pciid
) 2245 struct solo1_state
*s
; 2246 struct pm_dev
*pmdev
; 2247 dma_addr_t dma_mask
; 2249 if(!RSRCISIOREGION(pcidev
,0) || 2250 !RSRCISIOREGION(pcidev
,1) || 2251 !RSRCISIOREGION(pcidev
,2) || 2252 !RSRCISIOREGION(pcidev
,3)) 2256 if(pci_dma_supported(pcidev
,0x00ffffff)) { 2257 dma_mask
=0x00ffffff;/* this enables playback and recording */ 2258 }else if(pci_dma_supported(pcidev
,0xffffffff)) { 2259 dma_mask
=0xffffffff;/* this enables only playback, as the recording BMDMA can handle only 24bits */ 2261 printk(KERN_WARNING
"solo1: architecture does not support 24bit or 32bit PCI busmaster DMA\n"); 2264 if(!(s
=kmalloc(sizeof(struct solo1_state
), GFP_KERNEL
))) { 2265 printk(KERN_WARNING
"solo1: out of memory\n"); 2268 memset(s
,0,sizeof(struct solo1_state
)); 2269 init_waitqueue_head(&s
->dma_adc
.wait
); 2270 init_waitqueue_head(&s
->dma_dac
.wait
); 2271 init_waitqueue_head(&s
->open_wait
); 2272 init_waitqueue_head(&s
->midi
.iwait
); 2273 init_waitqueue_head(&s
->midi
.owait
); 2274 init_MUTEX(&s
->open_sem
); 2275 spin_lock_init(&s
->lock
); 2276 s
->magic
= SOLO1_MAGIC
; 2278 s
->iobase
=pci_resource_start(pcidev
,0); 2279 s
->sbbase
=pci_resource_start(pcidev
,1); 2280 s
->vcbase
=pci_resource_start(pcidev
,2); 2281 s
->ddmabase
= s
->vcbase
+ DDMABASE_OFFSET
; 2282 s
->mpubase
=pci_resource_start(pcidev
,3); 2283 s
->gpbase
=pci_resource_start(pcidev
,4); 2284 s
->irq
= pcidev
->irq
; 2285 if(!request_region(s
->iobase
, IOBASE_EXTENT
,"ESS Solo1")) { 2286 printk(KERN_ERR
"solo1: io ports in use\n"); 2289 if(!request_region(s
->sbbase
+FMSYNTH_EXTENT
, SBBASE_EXTENT
-FMSYNTH_EXTENT
,"ESS Solo1")) { 2290 printk(KERN_ERR
"solo1: io ports in use\n"); 2293 if(!request_region(s
->ddmabase
, DDMABASE_EXTENT
,"ESS Solo1")) { 2294 printk(KERN_ERR
"solo1: io ports in use\n"); 2297 if(!request_region(s
->mpubase
, MPUBASE_EXTENT
,"ESS Solo1")) { 2298 printk(KERN_ERR
"solo1: io ports in use\n"); 2301 if(request_irq(s
->irq
, solo1_interrupt
, SA_SHIRQ
,"ESS Solo1", s
)) { 2302 printk(KERN_ERR
"solo1: irq %u in use\n", s
->irq
); 2305 if(pci_enable_device(pcidev
)) 2307 printk(KERN_INFO
"solo1: joystick port at %#lx\n", s
->gpbase
+1); 2308 /* register devices */ 2309 if((s
->dev_audio
=register_sound_dsp(&solo1_audio_fops
, -1)) <0) 2311 if((s
->dev_mixer
=register_sound_mixer(&solo1_mixer_fops
, -1)) <0) 2313 if((s
->dev_midi
=register_sound_midi(&solo1_midi_fops
, -1)) <0) 2315 if((s
->dev_dmfm
=register_sound_special(&solo1_dmfm_fops
,15/* ?? */)) <0) 2319 /* store it in the driver field */ 2320 pci_set_drvdata(pcidev
, s
); 2321 pcidev
->dma_mask
= dma_mask
; 2322 /* put it into driver list */ 2323 list_add_tail(&s
->devs
, &devs
); 2325 pmdev
=pm_register(PM_PCI_DEV
,PM_PCI_ID(pcidev
), solo1_pm_callback
); 2332 unregister_sound_dsp(s
->dev_dmfm
); 2334 unregister_sound_dsp(s
->dev_midi
); 2336 unregister_sound_mixer(s
->dev_mixer
); 2338 unregister_sound_dsp(s
->dev_audio
); 2340 printk(KERN_ERR
"solo1: initialisation error\n"); 2341 free_irq(s
->irq
, s
); 2343 release_region(s
->iobase
, IOBASE_EXTENT
); 2345 release_region(s
->sbbase
+FMSYNTH_EXTENT
, SBBASE_EXTENT
-FMSYNTH_EXTENT
); 2347 release_region(s
->ddmabase
, DDMABASE_EXTENT
); 2349 release_region(s
->mpubase
, MPUBASE_EXTENT
); 2355 static void __devinit
solo1_remove(struct pci_dev
*dev
) 2357 struct solo1_state
*s
=pci_get_drvdata(dev
); 2362 /* stop DMA controller */ 2363 outb(0, s
->iobase
+6); 2364 outb(0, s
->ddmabase
+0xd);/* DMA master clear */ 2365 outb(3, s
->sbbase
+6);/* reset sequencer and FIFO */ 2367 pci_write_config_word(s
->dev
,0x60,0);/* turn off DDMA controller address space */ 2368 free_irq(s
->irq
, s
); 2369 release_region(s
->iobase
, IOBASE_EXTENT
); 2370 release_region(s
->sbbase
+FMSYNTH_EXTENT
, SBBASE_EXTENT
-FMSYNTH_EXTENT
); 2371 release_region(s
->ddmabase
, DDMABASE_EXTENT
); 2372 release_region(s
->mpubase
, MPUBASE_EXTENT
); 2373 unregister_sound_dsp(s
->dev_audio
); 2374 unregister_sound_mixer(s
->dev_mixer
); 2375 unregister_sound_midi(s
->dev_midi
); 2376 unregister_sound_special(s
->dev_dmfm
); 2378 pci_set_drvdata(dev
, NULL
); 2381 static struct pci_device_id id_table
[] __devinitdata
= { 2382 { PCI_VENDOR_ID_ESS
, PCI_DEVICE_ID_ESS_SOLO1
, PCI_ANY_ID
, PCI_ANY_ID
,0,0}, 2386 MODULE_DEVICE_TABLE(pci
, id_table
); 2388 static struct pci_driver solo1_driver
= { 2392 remove
: solo1_remove
2396 static int __init
init_solo1(void) 2398 if(!pci_present())/* No PCI bus in this machine! */ 2400 printk(KERN_INFO
"solo1: version v0.16 time " __TIME__
" " __DATE__
"\n"); 2401 if(!pci_register_driver(&solo1_driver
)) { 2402 pci_unregister_driver(&solo1_driver
); 2408 /* --------------------------------------------------------------------- */ 2410 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); 2411 MODULE_DESCRIPTION("ESS Solo1 Driver"); 2413 static void __exit
cleanup_solo1(void) 2415 printk(KERN_INFO
"solo1: unloading\n"); 2416 pci_unregister_driver(&solo1_driver
); 2417 pm_unregister_all(solo1_pm_callback
); 2420 /* --------------------------------------------------------------------- */ 2422 module_init(init_solo1
); 2423 module_exit(cleanup_solo1
);