Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / sound / sscape.c
blob85e523cbde067147fb4bf290e0050d6e44f8da66
1 /*
2 * sound/sscape.c
4 * Low level driver for Ensoniq SoundScape
7 * Copyright (C) by Hannu Savolainen 1993-1997
9 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10 * Version 2 (June 1991). See the "COPYING" file distributed with this software
11 * for more info.
14 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
15 * Sergey Smitienko : ensoniq p'n'p support
16 * Christoph Hellwig : adapted to module_init/module_exit
17 * Bartlomiej Zolnierkiewicz : added __init to attach_sscape()
20 #include <linux/init.h>
21 #include <linux/module.h>
23 #include"sound_config.h"
24 #include"sound_firmware.h"
26 #include <linux/types.h>
27 #include <linux/errno.h>
28 #include <linux/signal.h>
29 #include <linux/fcntl.h>
30 #include <linux/ctype.h>
31 #include <linux/stddef.h>
32 #include <linux/kmod.h>
33 #include <asm/dma.h>
34 #include <asm/io.h>
35 #include <asm/segment.h>
36 #include <linux/wait.h>
37 #include <linux/malloc.h>
38 #include <linux/ioport.h>
39 #include <linux/delay.h>
40 #include <linux/proc_fs.h>
41 #include <linux/wrapper.h>
43 #include"coproc.h"
45 #include"ad1848.h"
46 #include"mpu401.h"
49 * I/O ports
51 #define MIDI_DATA 0
52 #define MIDI_CTRL 1
53 #define HOST_CTRL 2
54 #define TX_READY 0x02
55 #define RX_READY 0x01
56 #define HOST_DATA 3
57 #define ODIE_ADDR 4
58 #define ODIE_DATA 5
61 * Indirect registers
64 #define GA_INTSTAT_REG 0
65 #define GA_INTENA_REG 1
66 #define GA_DMAA_REG 2
67 #define GA_DMAB_REG 3
68 #define GA_INTCFG_REG 4
69 #define GA_DMACFG_REG 5
70 #define GA_CDCFG_REG 6
71 #define GA_SMCFGA_REG 7
72 #define GA_SMCFGB_REG 8
73 #define GA_HMCTL_REG 9
76 * DMA channel identifiers (A and B)
79 #define SSCAPE_DMA_A 0
80 #define SSCAPE_DMA_B 1
82 #define PORT(name) (devc->base+name)
85 * Host commands recognized by the OBP microcode
88 #define CMD_GEN_HOST_ACK 0x80
89 #define CMD_GEN_MPU_ACK 0x81
90 #define CMD_GET_BOARD_TYPE 0x82
91 #define CMD_SET_CONTROL 0x88/* Old firmware only */
92 #define CMD_GET_CONTROL 0x89/* Old firmware only */
93 #define CTL_MASTER_VOL 0
94 #define CTL_MIC_MODE 2
95 #define CTL_SYNTH_VOL 4
96 #define CTL_WAVE_VOL 7
97 #define CMD_SET_EXTMIDI 0x8a
98 #define CMD_GET_EXTMIDI 0x8b
99 #define CMD_SET_MT32 0x8c
100 #define CMD_GET_MT32 0x8d
102 #define CMD_ACK 0x80
104 #define IC_ODIE 1
105 #define IC_OPUS 2
107 typedefstruct sscape_info
109 int base, irq, dma;
111 int codec, codec_irq;/* required to setup pnp cards*/
112 int codec_type;
113 int ic_type;
114 char* raw_buf;
115 unsigned long raw_buf_phys;
116 int buffsize;/* -------------------------- */
118 int ok;/* Properly detected */
119 int failed;
120 int dma_allocated;
121 int codec_audiodev;
122 int opened;
123 int*osp;
124 int my_audiodev;
125 } sscape_info;
127 static struct sscape_info adev_info = {
131 static struct sscape_info *devc = &adev_info;
132 static int sscape_mididev = -1;
134 /* Some older cards have assigned interrupt bits differently than new ones */
135 static char valid_interrupts_old[] = {
136 9,7,5,15
139 static char valid_interrupts_new[] = {
140 9,5,7,10
143 static char*valid_interrupts = valid_interrupts_new;
146 * See the bottom of the driver. This can be set by spea =0/1.
149 #ifdef REVEAL_SPEA
150 static char old_hardware =1;
151 #else
152 static char old_hardware =0;
153 #endif
155 static voidsleep(unsigned howlong)
157 current->state = TASK_INTERRUPTIBLE;
158 schedule_timeout(howlong);
161 static unsigned charsscape_read(struct sscape_info *devc,int reg)
163 unsigned long flags;
164 unsigned char val;
166 save_flags(flags);
167 cli();
168 outb(reg,PORT(ODIE_ADDR));
169 val =inb(PORT(ODIE_DATA));
170 restore_flags(flags);
171 return val;
174 static voidsscape_write(struct sscape_info *devc,int reg,int data)
176 unsigned long flags;
178 save_flags(flags);
179 cli();
180 outb(reg,PORT(ODIE_ADDR));
181 outb(data,PORT(ODIE_DATA));
182 restore_flags(flags);
185 static unsigned charsscape_pnp_read_codec(sscape_info* devc,unsigned char reg)
187 unsigned char res;
188 unsigned long flags;
190 save_flags(flags);
191 cli();
192 outb( reg, devc -> codec);
193 res =inb(devc -> codec +1);
194 restore_flags(flags);
195 return res;
199 static voidsscape_pnp_write_codec(sscape_info* devc,unsigned char reg,unsigned char data)
201 unsigned long flags;
203 save_flags(flags);
204 cli();
205 outb( reg, devc -> codec);
206 outb( data, devc -> codec +1);
207 restore_flags(flags);
210 static voidhost_open(struct sscape_info *devc)
212 outb((0x00),PORT(HOST_CTRL));/* Put the board to the host mode */
215 static voidhost_close(struct sscape_info *devc)
217 outb((0x03),PORT(HOST_CTRL));/* Put the board to the MIDI mode */
220 static inthost_write(struct sscape_info *devc,unsigned char*data,int count)
222 unsigned long flags;
223 int i, timeout_val;
225 save_flags(flags);
226 cli();
229 * Send the command and data bytes
232 for(i =0; i < count; i++)
234 for(timeout_val =10000; timeout_val >0; timeout_val--)
235 if(inb(PORT(HOST_CTRL)) & TX_READY)
236 break;
238 if(timeout_val <=0)
240 restore_flags(flags);
241 return0;
243 outb(data[i],PORT(HOST_DATA));
245 restore_flags(flags);
246 return1;
249 static inthost_read(struct sscape_info *devc)
251 unsigned long flags;
252 int timeout_val;
253 unsigned char data;
255 save_flags(flags);
256 cli();
259 * Read a byte
262 for(timeout_val =10000; timeout_val >0; timeout_val--)
263 if(inb(PORT(HOST_CTRL)) & RX_READY)
264 break;
266 if(timeout_val <=0)
268 restore_flags(flags);
269 return-1;
271 data =inb(PORT(HOST_DATA));
272 restore_flags(flags);
273 return data;
276 #if 0/* unused */
277 static inthost_command1(struct sscape_info *devc,int cmd)
279 unsigned char buf[10];
280 buf[0] = (unsigned char) (cmd &0xff);
281 returnhost_write(devc, buf,1);
283 #endif/* unused */
286 static inthost_command2(struct sscape_info *devc,int cmd,int parm1)
288 unsigned char buf[10];
290 buf[0] = (unsigned char) (cmd &0xff);
291 buf[1] = (unsigned char) (parm1 &0xff);
293 returnhost_write(devc, buf,2);
296 static inthost_command3(struct sscape_info *devc,int cmd,int parm1,int parm2)
298 unsigned char buf[10];
300 buf[0] = (unsigned char) (cmd &0xff);
301 buf[1] = (unsigned char) (parm1 &0xff);
302 buf[2] = (unsigned char) (parm2 &0xff);
303 returnhost_write(devc, buf,3);
306 static voidset_mt32(struct sscape_info *devc,int value)
308 host_open(devc);
309 host_command2(devc, CMD_SET_MT32, value ?1:0);
310 if(host_read(devc) != CMD_ACK)
312 /* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */
314 host_close(devc);
317 static voidset_control(struct sscape_info *devc,int ctrl,int value)
319 host_open(devc);
320 host_command3(devc, CMD_SET_CONTROL, ctrl, value);
321 if(host_read(devc) != CMD_ACK)
323 /* printk( "SNDSCAPE: Setting control (%d) failed\n", ctrl); */
325 host_close(devc);
328 static voiddo_dma(struct sscape_info *devc,int dma_chan,unsigned long buf,int blk_size,int mode)
330 unsigned char temp;
332 if(dma_chan != SSCAPE_DMA_A)
334 printk(KERN_WARNING "soundscape: Tried to use DMA channel != A. Why?\n");
335 return;
337 audio_devs[devc->codec_audiodev]->flags &= ~DMA_AUTOMODE;
338 DMAbuf_start_dma(devc->codec_audiodev, buf, blk_size, mode);
339 audio_devs[devc->codec_audiodev]->flags |= DMA_AUTOMODE;
341 temp = devc->dma <<4;/* Setup DMA channel select bits */
342 if(devc->dma <=3)
343 temp |=0x80;/* 8 bit DMA channel */
345 temp |=1;/* Trigger DMA */
346 sscape_write(devc, GA_DMAA_REG, temp);
347 temp &=0xfe;/* Clear DMA trigger */
348 sscape_write(devc, GA_DMAA_REG, temp);
351 static intverify_mpu(struct sscape_info *devc)
354 * The SoundScape board could be in three modes (MPU, 8250 and host).
355 * If the card is not in the MPU mode, enabling the MPU driver will
356 * cause infinite loop (the driver believes that there is always some
357 * received data in the buffer.
359 * Detect this by looking if there are more than 10 received MIDI bytes
360 * (0x00) in the buffer.
363 int i;
365 for(i =0; i <10; i++)
367 if(inb(devc->base + HOST_CTRL) &0x80)
368 return1;
370 if(inb(devc->base) !=0x00)
371 return1;
373 printk(KERN_WARNING "SoundScape: The device is not in the MPU-401 mode\n");
374 return0;
377 static intsscape_coproc_open(void*dev_info,int sub_device)
379 if(sub_device == COPR_MIDI)
381 set_mt32(devc,0);
382 if(!verify_mpu(devc))
383 return-EIO;
385 return0;
388 static voidsscape_coproc_close(void*dev_info,int sub_device)
390 struct sscape_info *devc = dev_info;
391 unsigned long flags;
393 save_flags(flags);
394 cli();
395 if(devc->dma_allocated)
397 sscape_write(devc, GA_DMAA_REG,0x20);/* DMA channel disabled */
398 devc->dma_allocated =0;
400 restore_flags(flags);
401 return;
404 static voidsscape_coproc_reset(void*dev_info)
408 static intsscape_download_boot(struct sscape_info *devc,unsigned char*block,int size,int flag)
410 unsigned long flags;
411 unsigned char temp;
412 volatileint done, timeout_val;
413 static unsigned char codec_dma_bits =0;
415 if(flag & CPF_FIRST)
418 * First block. Have to allocate DMA and to reset the board
419 * before continuing.
422 save_flags(flags);
423 cli();
424 codec_dma_bits =sscape_read(devc, GA_CDCFG_REG);
426 if(devc->dma_allocated ==0)
427 devc->dma_allocated =1;
429 restore_flags(flags);
431 sscape_write(devc, GA_HMCTL_REG,
432 (temp =sscape_read(devc, GA_HMCTL_REG)) &0x3f);/*Reset */
434 for(timeout_val =10000; timeout_val >0; timeout_val--)
435 sscape_read(devc, GA_HMCTL_REG);/* Delay */
437 /* Take board out of reset */
438 sscape_write(devc, GA_HMCTL_REG,
439 (temp =sscape_read(devc, GA_HMCTL_REG)) |0x80);
442 * Transfer one code block using DMA
444 if(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL)
446 printk(KERN_WARNING "soundscape: DMA buffer not available\n");
447 return0;
449 memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);
451 save_flags(flags);
452 cli();
454 /******** INTERRUPTS DISABLED NOW ********/
456 do_dma(devc, SSCAPE_DMA_A,
457 audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys,
458 size, DMA_MODE_WRITE);
461 * Wait until transfer completes.
464 done =0;
465 timeout_val =30;
466 while(!done && timeout_val-- >0)
468 int resid;
470 if(HZ /50)
471 sleep(HZ /50);
472 clear_dma_ff(devc->dma);
473 if((resid =get_dma_residue(devc->dma)) ==0)
474 done =1;
477 restore_flags(flags);
478 if(!done)
479 return0;
481 if(flag & CPF_LAST)
484 * Take the board out of reset
486 outb((0x00),PORT(HOST_CTRL));
487 outb((0x00),PORT(MIDI_CTRL));
489 temp =sscape_read(devc, GA_HMCTL_REG);
490 temp |=0x40;
491 sscape_write(devc, GA_HMCTL_REG, temp);/* Kickstart the board */
494 * Wait until the ODB wakes up
497 save_flags(flags);
498 cli();
499 done =0;
500 timeout_val =5* HZ;
501 while(!done && timeout_val-- >0)
503 unsigned char x;
505 sleep(1);
506 x =inb(PORT(HOST_DATA));
507 if(x ==0xff|| x ==0xfe)/* OBP startup acknowledge */
509 DDB(printk("Soundscape: Acknowledge = %x\n", x));
510 done =1;
513 sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);
515 restore_flags(flags);
516 if(!done)
518 printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
519 return0;
521 save_flags(flags);
522 cli();
523 done =0;
524 timeout_val =5* HZ;
525 while(!done && timeout_val-- >0)
527 sleep(1);
528 if(inb(PORT(HOST_DATA)) ==0xfe)/* Host startup acknowledge */
529 done =1;
531 restore_flags(flags);
532 if(!done)
534 printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
535 return0;
537 printk(KERN_INFO "SoundScape board initialized OK\n");
538 set_control(devc, CTL_MASTER_VOL,100);
539 set_control(devc, CTL_SYNTH_VOL,100);
541 #ifdef SSCAPE_DEBUG3
543 * Temporary debugging aid. Print contents of the registers after
544 * downloading the code.
547 int i;
549 for(i =0; i <13; i++)
550 printk("I%d = %02x (new value)\n", i,sscape_read(devc, i));
552 #endif
555 return1;
558 static intdownload_boot_block(void*dev_info, copr_buffer * buf)
560 if(buf->len <=0|| buf->len >sizeof(buf->data))
561 return-EINVAL;
563 if(!sscape_download_boot(devc, buf->data, buf->len, buf->flags))
565 printk(KERN_ERR "soundscape: Unable to load microcode block to the OBP.\n");
566 return-EIO;
568 return0;
571 static intsscape_coproc_ioctl(void*dev_info,unsigned int cmd, caddr_t arg,int local)
573 copr_buffer *buf;
574 int err;
576 switch(cmd)
578 case SNDCTL_COPR_RESET:
579 sscape_coproc_reset(dev_info);
580 return0;
582 case SNDCTL_COPR_LOAD:
583 buf = (copr_buffer *)vmalloc(sizeof(copr_buffer));
584 if(buf == NULL)
585 return-ENOSPC;
586 if(copy_from_user(buf, arg,sizeof(copr_buffer)))
588 vfree(buf);
589 return-EFAULT;
591 err =download_boot_block(dev_info, buf);
592 vfree(buf);
593 return err;
595 default:
596 return-EINVAL;
600 static coproc_operations sscape_coproc_operations =
602 "SoundScape M68K",
603 sscape_coproc_open,
604 sscape_coproc_close,
605 sscape_coproc_ioctl,
606 sscape_coproc_reset,
607 &adev_info
610 static int sscape_detected =0;
611 static int sscape_is_pnp =0;
613 void __init attach_sscape(struct address_info *hw_config)
615 #ifndef SSCAPE_REGS
617 * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
618 * These values are card
619 * dependent. If you have another SoundScape based card, you have to
620 * find the correct values. Do the following:
621 * - Compile this driver with SSCAPE_DEBUG1 defined.
622 * - Shut down and power off your machine.
623 * - Boot with DOS so that the SSINIT.EXE program is run.
624 * - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
625 * when detecting the SoundScape.
626 * - Modify the following list to use the values printed during boot.
627 * Undefine the SSCAPE_DEBUG1
629 #define SSCAPE_REGS { \
630 /* I0 */ 0x00, \
631 /* I1 */ 0xf0,/* Note! Ignored. Set always to 0xf0 */ \
632 /* I2 */ 0x20,/* Note! Ignored. Set always to 0x20 */ \
633 /* I3 */ 0x20,/* Note! Ignored. Set always to 0x20 */ \
634 /* I4 */ 0xf5,/* Ignored */ \
635 /* I5 */ 0x10, \
636 /* I6 */ 0x00, \
637 /* I7 */ 0x2e,/* I7 MEM config A. Likely to vary between models */ \
638 /* I8 */ 0x00,/* I8 MEM config B. Likely to vary between models */ \
639 /* I9 */ 0x40/* Ignored */ \
641 #endif
643 unsigned long flags;
644 static unsigned char regs[10] = SSCAPE_REGS;
646 int i, irq_bits =0xff;
648 if(sscape_detected != hw_config->io_base)
649 return;
651 request_region(devc->base +2,6,"SoundScape");
652 if(old_hardware)
654 valid_interrupts = valid_interrupts_old;
655 conf_printf("Ensoniq SoundScape (old)", hw_config);
657 else
658 conf_printf("Ensoniq SoundScape", hw_config);
660 for(i =0; i <sizeof(valid_interrupts); i++)
662 if(hw_config->irq == valid_interrupts[i])
664 irq_bits = i;
665 break;
668 if(hw_config->irq >15|| (regs[4] = irq_bits ==0xff))
670 printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq);
671 return;
674 if(sscape_is_pnp ==0) {
676 save_flags(flags);
677 cli();
678 for(i =1; i <10; i++)
680 switch(i)
682 case1:/* Host interrupt enable */
683 sscape_write(devc, i,0xf0);/* All interrupts enabled */
684 break;
686 case2:/* DMA A status/trigger register */
687 case3:/* DMA B status/trigger register */
688 sscape_write(devc, i,0x20);/* DMA channel disabled */
689 break;
691 case4:/* Host interrupt config reg */
692 sscape_write(devc, i,0xf0| (irq_bits <<2) | irq_bits);
693 break;
695 case5:/* Don't destroy CD-ROM DMA config bits (0xc0) */
696 sscape_write(devc, i, (regs[i] &0x3f) | (sscape_read(devc, i) &0xc0));
697 break;
699 case6:/* CD-ROM config (WSS codec actually) */
700 sscape_write(devc, i, regs[i]);
701 break;
703 case9:/* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
704 sscape_write(devc, i, (sscape_read(devc, i) &0xf0) |0x08);
705 break;
707 default:
708 sscape_write(devc, i, regs[i]);
711 restore_flags(flags);
713 #ifdef SSCAPE_DEBUG2
715 * Temporary debugging aid. Print contents of the registers after
716 * changing them.
719 int i;
721 for(i =0; i <13; i++)
722 printk("I%d = %02x (new value)\n", i,sscape_read(devc, i));
724 #endif
726 if(probe_mpu401(hw_config))
727 hw_config->always_detect =1;
728 hw_config->name ="SoundScape";
730 hw_config->irq *= -1;/* Negative value signals IRQ sharing */
731 attach_mpu401(hw_config, THIS_MODULE);
732 hw_config->irq *= -1;/* Restore it */
734 if(hw_config->slots[1] != -1)/* The MPU driver installed itself */
736 sscape_mididev = hw_config->slots[1];
737 midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
739 sscape_write(devc, GA_INTENA_REG,0x80);/* Master IRQ enable */
740 devc->ok =1;
741 devc->failed =0;
744 static intdetect_ga(sscape_info * devc)
746 unsigned char save;
748 DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base));
750 if(check_region(devc->base,8))
751 return0;
754 * First check that the address register of "ODIE" is
755 * there and that it has exactly 4 writable bits.
756 * First 4 bits
759 if((save =inb(PORT(ODIE_ADDR))) &0xf0)
761 DDB(printk("soundscape: Detect error A\n"));
762 return0;
764 outb((0x00),PORT(ODIE_ADDR));
765 if(inb(PORT(ODIE_ADDR)) !=0x00)
767 DDB(printk("soundscape: Detect error B\n"));
768 return0;
770 outb((0xff),PORT(ODIE_ADDR));
771 if(inb(PORT(ODIE_ADDR)) !=0x0f)
773 DDB(printk("soundscape: Detect error C\n"));
774 return0;
776 outb((save),PORT(ODIE_ADDR));
779 * Now verify that some indirect registers return zero on some bits.
780 * This may break the driver with some future revisions of "ODIE" but...
783 if(sscape_read(devc,0) &0x0c)
785 DDB(printk("soundscape: Detect error D (%x)\n",sscape_read(devc,0)));
786 return0;
788 if(sscape_read(devc,1) &0x0f)
790 DDB(printk("soundscape: Detect error E\n"));
791 return0;
793 if(sscape_read(devc,5) &0x0f)
795 DDB(printk("soundscape: Detect error F\n"));
796 return0;
798 return1;
801 static intsscape_read_host_ctrl(sscape_info* devc)
803 returnhost_read(devc);
806 static voidsscape_write_host_ctrl2(sscape_info *devc,int a,int b)
808 host_command2(devc, a, b);
811 static intsscape_alloc_dma(sscape_info *devc)
813 char*start_addr, *end_addr;
814 int dma_pagesize;
815 int sz, size;
816 struct page *page;
818 if(devc->raw_buf != NULL)return0;/* Already done */
819 dma_pagesize = (devc->dma <4) ? (64*1024) : (128*1024);
820 devc->raw_buf = NULL;
821 devc->buffsize =8192*4;
822 if(devc->buffsize > dma_pagesize) devc->buffsize = dma_pagesize;
823 start_addr = NULL;
825 * Now loop until we get a free buffer. Try to get smaller buffer if
826 * it fails. Don't accept smaller than 8k buffer for performance
827 * reasons.
829 while(start_addr == NULL && devc->buffsize > PAGE_SIZE) {
830 for(sz =0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<=1);
831 devc->buffsize = PAGE_SIZE * (1<< sz);
832 start_addr = (char*)__get_free_pages(GFP_ATOMIC|GFP_DMA, sz);
833 if(start_addr == NULL) devc->buffsize /=2;
836 if(start_addr == NULL) {
837 printk(KERN_ERR "sscape pnp init error: Couldn't allocate DMA buffer\n");
838 return0;
839 }else{
840 /* make some checks */
841 end_addr = start_addr + devc->buffsize -1;
842 /* now check if it fits into the same dma-pagesize */
844 if(((long) start_addr & ~(dma_pagesize -1)) != ((long) end_addr & ~(dma_pagesize -1))
845 || end_addr >= (char*) (MAX_DMA_ADDRESS)) {
846 printk(KERN_ERR "sscape pnp: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, devc->buffsize);
847 return0;
850 devc->raw_buf = start_addr;
851 devc->raw_buf_phys =virt_to_bus(start_addr);
853 for(page =virt_to_page(start_addr); page <=virt_to_page(end_addr); page++)
854 mem_map_reserve(page);
855 return1;
858 static voidsscape_free_dma(sscape_info *devc)
860 int sz, size;
861 unsigned long start_addr, end_addr;
862 struct page *page;
864 if(devc->raw_buf == NULL)return;
865 for(sz =0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<=1);
866 start_addr = (unsigned long) devc->raw_buf;
867 end_addr = start_addr + devc->buffsize;
869 for(page =virt_to_page(start_addr); page <=virt_to_page(end_addr); page++)
870 mem_map_unreserve(page);
872 free_pages((unsigned long) devc->raw_buf, sz);
873 devc->raw_buf = NULL;
876 /* Intel version !!!!!!!!! */
878 static intsscape_start_dma(int chan,unsigned long physaddr,int count,int dma_mode)
880 unsigned long flags;
882 flags =claim_dma_lock();
883 disable_dma(chan);
884 clear_dma_ff(chan);
885 set_dma_mode(chan, dma_mode);
886 set_dma_addr(chan, physaddr);
887 set_dma_count(chan, count);
888 enable_dma(chan);
889 release_dma_lock(flags);
890 return0;
893 static voidsscape_pnp_start_dma(sscape_info* devc,int arg )
895 int reg;
896 if(arg ==0) reg =2;
897 else reg =3;
899 sscape_write(devc, reg,sscape_read( devc, reg) |0x01);
900 sscape_write(devc, reg,sscape_read( devc, reg) &0xFE);
903 static intsscape_pnp_wait_dma(sscape_info* devc,int arg )
905 int reg;
906 unsigned long i;
907 unsigned char d;
909 if(arg ==0) reg =2;
910 else reg =3;
912 sleep(1);
913 i =0;
915 d =sscape_read(devc, reg) &1;
916 if( d ==1)break;
917 i++;
918 }while(i <500000);
919 d =sscape_read(devc, reg) &1;
920 return d;
923 static intsscape_pnp_alloc_dma(sscape_info* devc)
925 /* printk(KERN_INFO "sscape: requesting dma\n"); */
926 if(request_dma(devc -> dma,"sscape"))return0;
927 /* printk(KERN_INFO "sscape: dma channel allocated\n"); */
928 if(!sscape_alloc_dma(devc)) {
929 free_dma(devc -> dma);
930 return0;
932 return1;
935 static voidsscape_pnp_free_dma(sscape_info* devc)
937 sscape_free_dma( devc);
938 free_dma(devc -> dma );
939 /* printk(KERN_INFO "sscape: dma released\n"); */
942 static intsscape_pnp_upload_file(sscape_info* devc,char* fn)
944 int done =0;
945 int timeout_val;
946 char* data,*dt;
947 int len,l;
948 unsigned long flags;
950 sscape_write( devc,9,sscape_read(devc,9) &0x3F);
951 sscape_write( devc,2, (devc -> dma <<4) |0x80);
952 sscape_write( devc,3,0x20);
953 sscape_write( devc,9,sscape_read( devc,9) |0x80);
955 len =mod_firmware_load(fn, &data);
956 if(len ==0) {
957 printk(KERN_ERR "sscape: file not found: %s\n", fn);
958 return0;
960 dt = data;
961 save_flags(flags);
962 cli();
963 while( len >0) {
964 if(len > devc -> buffsize) l = devc->buffsize;
965 else l = len;
966 len -= l;
967 memcpy(devc->raw_buf, dt, l); dt += l;
968 sscape_start_dma(devc->dma, devc->raw_buf_phys, l,0x48);
969 sscape_pnp_start_dma( devc,0);
970 if(sscape_pnp_wait_dma( devc,0) ==0)return0;
973 restore_flags(flags);
974 vfree(data);
976 outb(0, devc -> base +2);
977 outb(0, devc -> base);
979 sscape_write( devc,9,sscape_read( devc,9) |0x40);
981 timeout_val =5* HZ;
982 while(!done && timeout_val-- >0)
984 unsigned char x;
985 sleep(1);
986 x =inb( devc -> base +3);
987 if(x ==0xff|| x ==0xfe)/* OBP startup acknowledge */
989 //printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
990 done =1;
993 timeout_val =5* HZ;
994 done =0;
995 while(!done && timeout_val-- >0)
997 unsigned char x;
998 sleep(1);
999 x =inb( devc -> base +3);
1000 if(x ==0xfe)/* OBP startup acknowledge */
1002 //printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
1003 done =1;
1007 if( !done )printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
1009 sscape_write( devc,2, devc->ic_type == IC_ODIE ?0x70:0x40);
1010 sscape_write( devc,3, (devc -> dma <<4) +0x80);
1011 return1;
1014 static void __init sscape_pnp_init_hw(sscape_info* devc)
1016 unsigned char midi_irq =0, sb_irq =0;
1017 unsigned i;
1018 static char code_file_name[23] ="/sndscape/sndscape.cox";
1020 int sscape_sb_enable =0;
1021 int sscape_joystic_enable =0x7f;
1022 int sscape_mic_enable =0;
1023 int sscape_ext_midi =0;
1025 if( !sscape_pnp_alloc_dma(devc) ) {
1026 printk(KERN_ERR "sscape: faild to allocate dma\n");
1027 return;
1030 for(i =0; i <4; i++) {
1031 if( devc -> irq == valid_interrupts[i] )
1032 midi_irq = i;
1033 if( devc -> codec_irq == valid_interrupts[i] )
1034 sb_irq = i;
1037 sscape_write( devc,5,0x50);
1038 sscape_write( devc,7,0x2e);
1039 sscape_write( devc,8,0x00);
1041 sscape_write( devc,2, devc->ic_type == IC_ODIE ?0x70:0x40);
1042 sscape_write( devc,3, ( devc -> dma <<4) |0x80);
1044 if( sscape_sb_enable )
1045 sscape_write(devc,4,0xF0| (sb_irq <<2) | midi_irq);
1046 else
1047 sscape_write(devc,4,0xF0| (midi_irq<<2) | midi_irq);
1049 i =0x10;//sscape_read(devc, 9) & (devc->ic_type == IC_ODIE ? 0xf0 : 0xc0);
1050 if( sscape_sb_enable )
1051 i |= devc->ic_type == IC_ODIE ?0x05:0x07;
1052 if(sscape_joystic_enable) i |=8;
1054 sscape_write(devc,9, i);
1055 sscape_write(devc,6,0x80);
1056 sscape_write(devc,1,0x80);
1058 if(devc -> codec_type ==2) {
1059 sscape_pnp_write_codec( devc,0x0C,0x50);
1060 sscape_pnp_write_codec( devc,0x10,sscape_pnp_read_codec( devc,0x10) &0x3F);
1061 sscape_pnp_write_codec( devc,0x11,sscape_pnp_read_codec( devc,0x11) |0xC0);
1062 sscape_pnp_write_codec( devc,29,0x20);
1065 if(sscape_pnp_upload_file(devc,"/sndscape/scope.cod") ==0) {
1066 printk(KERN_ERR "sscape: faild to upload file /sndscape/scope.cod\n");
1067 sscape_pnp_free_dma(devc);
1068 return;
1071 i =sscape_read_host_ctrl( devc );
1073 if( (i &0x0F) >7) {
1074 printk(KERN_ERR "sscape: scope.cod faild\n");
1075 sscape_pnp_free_dma(devc);
1076 return;
1078 if( i &0x10)sscape_write( devc,7,0x2F);
1079 code_file_name[21] = (char) ( i &0x0F) +0x30;
1080 if(sscape_pnp_upload_file( devc, code_file_name) ==0) {
1081 printk(KERN_ERR "sscape: faild to upload file %s\n", code_file_name);
1082 sscape_pnp_free_dma(devc);
1083 return;
1086 if(devc->ic_type != IC_ODIE) {
1087 sscape_pnp_write_codec( devc,10, (sscape_pnp_read_codec(devc,10) &0x7f) |
1088 ( sscape_mic_enable ==0?0x00:0x80) );
1090 sscape_write_host_ctrl2( devc,0x84,0x32);
1091 sscape_write_host_ctrl2( devc,0x86,0x32);
1092 sscape_write_host_ctrl2( devc,0x8A, sscape_ext_midi);
1094 sscape_pnp_write_codec( devc,6,0x3f);//WAV_VOL
1095 sscape_pnp_write_codec( devc,7,0x3f);//WAV_VOL
1096 sscape_pnp_write_codec( devc,2,0x1F);//WD_CDXVOLL
1097 sscape_pnp_write_codec( devc,3,0x1F);//WD_CDXVOLR
1099 if(devc -> codec_type ==1) {
1100 sscape_pnp_write_codec( devc,4,0x1F);
1101 sscape_pnp_write_codec( devc,5,0x1F);
1102 sscape_write_host_ctrl2( devc,0x88, sscape_mic_enable);
1103 }else{
1104 int t;
1105 sscape_pnp_write_codec( devc,0x10,0x1F<<1);
1106 sscape_pnp_write_codec( devc,0x11,0xC0| (0x1F<<1));
1108 t =sscape_pnp_read_codec( devc,0x00) &0xDF;
1109 if( (sscape_mic_enable ==0)) t |=0;
1110 else t |=0x20;
1111 sscape_pnp_write_codec( devc,0x00, t);
1112 t =sscape_pnp_read_codec( devc,0x01) &0xDF;
1113 if( (sscape_mic_enable ==0) ) t |=0;
1114 else t |=0x20;
1115 sscape_pnp_write_codec( devc,0x01, t);
1116 sscape_pnp_write_codec( devc,0x40|29,0x20);
1117 outb(0, devc -> codec);
1119 if(devc -> ic_type == IC_OPUS ) {
1120 int i =sscape_read( devc,9);
1121 sscape_write( devc,9, i |3);
1122 sscape_write( devc,3,0x40);
1124 if(check_region(0x228,1)) {
1125 outb(0,0x228);
1126 release_region(0x228,1);
1128 sscape_write( devc,3, (devc -> dma <<4) |0x80);
1129 sscape_write( devc,9, i );
1132 host_close( devc );
1133 sscape_pnp_free_dma(devc);
1136 static int __init detect_sscape_pnp(sscape_info* devc)
1138 long i, irq_bits =0xff;
1139 unsigned int d;
1141 DDB(printk("Entered detect_sscape_pnp(%x)\n", devc->base));
1143 if(check_region(devc->base,8)) {
1144 printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->base);
1145 return0;
1148 if(check_region(devc->codec,2)) {
1149 printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->codec);
1150 return0;
1153 if( (inb( devc -> base +2) &0x78) !=0)return0;
1155 d =inb( devc -> base +4) &0xF0;
1156 if( (d &0x80) !=0)return0;
1158 if(d ==0) {
1159 devc->codec_type =1;
1160 devc->ic_type = IC_ODIE;
1162 else if( (d &0x60) !=0) {
1163 devc->codec_type =2;
1164 devc->ic_type = IC_OPUS;
1166 else if( (d &0x40) !=0) {
1167 devc->codec_type =2;
1168 devc->ic_type = IC_ODIE;
1170 else return0;
1172 sscape_is_pnp =1;
1174 outb(0xFA, devc -> base+4);
1175 if((inb( devc -> base+4) &0x9F) !=0x0A)
1176 return0;
1177 outb(0xFE, devc -> base+4);
1178 if( (inb(devc -> base+4) &0x9F) !=0x0E)
1179 return0;
1180 if( (inb(devc -> base+5) &0x9F) !=0x0E)
1181 return0;
1183 if(devc->codec_type ==2) {
1184 if(devc -> codec != devc -> base +8)
1185 printk("soundscape warning: incorrect codec port specified\n");
1186 devc -> codec = devc -> base +8;
1187 d =0x10| (sscape_read(devc,9) &0xCF);
1188 sscape_write(devc,9, d);
1189 sscape_write(devc,6,0x80);
1190 }else{
1191 //todo: check codec is not base + 8
1194 d = (sscape_read(devc,9) &0x3F) |0xC0;
1195 sscape_write(devc,9, d);
1197 for(i =0; i <550000; i++)
1198 if( !(inb(devc -> codec) &0x80) )break;
1200 d =inb(devc -> codec);
1201 if(d &0x80)
1202 return0;
1203 if(inb(devc -> codec +2) ==0xFF)
1204 return0;
1206 sscape_write(devc,9,sscape_read(devc,9) &0x3F);
1208 d =inb(devc -> codec) &0x80;
1209 if( d ==0) {
1210 printk(KERN_INFO "soundscape: hardware detected\n");
1211 valid_interrupts = valid_interrupts_new;
1212 }else{
1213 printk(KERN_INFO "soundscape: board looks like media fx\n");
1214 valid_interrupts = valid_interrupts_old;
1215 old_hardware =1;
1218 sscape_write( devc,9,0xC0| (sscape_read(devc,9) &0x3F) );
1220 for(i =0; i <550000; i++)
1221 if( !(inb(devc -> codec) &0x80))
1222 break;
1224 sscape_pnp_init_hw(devc);
1226 for(i =0; i <sizeof(valid_interrupts); i++)
1228 if(devc->codec_irq == valid_interrupts[i]) {
1229 irq_bits = i;
1230 break;
1233 sscape_write(devc, GA_INTENA_REG,0x00);
1234 sscape_write(devc, GA_DMACFG_REG,0x50);
1235 sscape_write(devc, GA_DMAA_REG,0x70);
1236 sscape_write(devc, GA_DMAB_REG,0x20);
1237 sscape_write(devc, GA_INTCFG_REG,0xf0);
1238 sscape_write(devc, GA_CDCFG_REG,0x89| (devc->dma <<4) | (irq_bits <<1));
1240 sscape_pnp_write_codec( devc,0,sscape_pnp_read_codec( devc,0) |0x20);
1241 sscape_pnp_write_codec( devc,0,sscape_pnp_read_codec( devc,1) |0x20);
1243 release_region(devc->codec,2);
1244 release_region(devc->base,8);
1246 return1;
1249 static int __init probe_sscape(struct address_info *hw_config)
1252 if(sscape_detected !=0&& sscape_detected != hw_config->io_base)
1253 return0;
1255 devc->base = hw_config->io_base;
1256 devc->irq = hw_config->irq;
1257 devc->dma = hw_config->dma;
1258 devc->osp = hw_config->osp;
1260 #ifdef SSCAPE_DEBUG1
1262 * Temporary debugging aid. Print contents of the registers before
1263 * changing them.
1266 int i;
1268 for(i =0; i <13; i++)
1269 printk("I%d = %02x (old value)\n", i,sscape_read(devc, i));
1271 #endif
1272 devc->failed =1;
1274 if(!detect_ga(devc)) {
1275 if(detect_sscape_pnp(devc)) {
1276 sscape_detected = hw_config->io_base;
1277 return1;
1279 else return0;
1282 if(old_hardware)/* Check that it's really an old Spea/Reveal card. */
1284 unsigned char tmp;
1285 int cc;
1287 if(!((tmp =sscape_read(devc, GA_HMCTL_REG)) &0xc0))
1289 sscape_write(devc, GA_HMCTL_REG, tmp |0x80);
1290 for(cc =0; cc <200000; ++cc)
1291 inb(devc->base + ODIE_ADDR);
1294 sscape_detected = hw_config->io_base;
1295 return1;
1298 static int __init probe_ss_ms_sound(struct address_info *hw_config)
1300 int i, irq_bits =0xff;
1301 int ad_flags =0;
1303 if(devc->failed)
1305 printk(KERN_ERR "soundscape: Card not detected\n");
1306 return0;
1308 if(devc->ok ==0)
1310 printk(KERN_ERR "soundscape: Invalid initialization order.\n");
1311 return0;
1313 for(i =0; i <sizeof(valid_interrupts); i++)
1315 if(hw_config->irq == valid_interrupts[i])
1317 irq_bits = i;
1318 break;
1321 if(hw_config->irq >15|| irq_bits ==0xff)
1323 printk(KERN_ERR "soundscape: Invalid MSS IRQ%d\n", hw_config->irq);
1324 return0;
1327 if(!sscape_is_pnp) {
1328 if(old_hardware)
1329 ad_flags =0x12345677;/* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
1330 returnad1848_detect(hw_config->io_base, &ad_flags, hw_config->osp);
1332 else{
1333 if(old_hardware)
1334 ad_flags =0x12345677;/* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
1335 else
1336 ad_flags =0x87654321;/* Tell that we have a soundscape pnp with 1845 chip */
1337 returnad1848_detect(hw_config->io_base, &ad_flags, hw_config->osp);
1341 static void __init attach_ss_ms_sound(struct address_info *hw_config)
1344 * This routine configures the SoundScape card for use with the
1345 * Win Sound System driver. The AD1848 codec interface uses the CD-ROM
1346 * config registers of the "ODIE".
1349 int i, irq_bits =0xff;
1352 if(!sscape_is_pnp)/*pnp is already setup*/
1355 * Setup the DMA polarity.
1357 sscape_write(devc, GA_DMACFG_REG,0x50);
1360 * Take the gate-array off of the DMA channel.
1362 sscape_write(devc, GA_DMAB_REG,0x20);
1365 * Init the AD1848 (CD-ROM) config reg.
1367 for(i =0; i <sizeof(valid_interrupts); i++)
1369 if(hw_config->irq == valid_interrupts[i])
1371 irq_bits = i;
1372 break;
1375 sscape_write(devc, GA_CDCFG_REG,0x89| (hw_config->dma <<4) | (irq_bits <<1));
1378 if(hw_config->irq == devc->irq)
1379 printk(KERN_WARNING "soundscape: Warning! The WSS mode can't share IRQ with MIDI\n");
1381 hw_config->slots[0] =ad1848_init(
1382 sscape_is_pnp ?"SoundScape":"SoundScape PNP",
1383 hw_config->io_base,
1384 hw_config->irq,
1385 hw_config->dma,
1386 hw_config->dma,
1388 devc->osp,
1389 THIS_MODULE);
1392 if(hw_config->slots[0] != -1)/* The AD1848 driver installed itself */
1394 audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations;
1395 devc->codec_audiodev = hw_config->slots[0];
1396 devc->my_audiodev = hw_config->slots[0];
1398 /* Set proper routings here (what are they) */
1399 AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
1402 #ifdef SSCAPE_DEBUG5
1404 * Temporary debugging aid. Print contents of the registers
1405 * after the AD1848 device has been initialized.
1408 int i;
1410 for(i =0; i <13; i++)
1411 printk("I%d = %02x\n", i,sscape_read(devc, i));
1413 #endif
1417 static void __exit unload_sscape(struct address_info *hw_config)
1419 release_region(devc->base +2,6);
1420 unload_mpu401(hw_config);
1423 static void __exit unload_ss_ms_sound(struct address_info *hw_config)
1425 ad1848_unload(hw_config->io_base,
1426 hw_config->irq,
1427 devc->dma,
1428 devc->dma,
1430 sound_unload_audiodev(hw_config->slots[0]);
1433 static struct address_info cfg;
1434 static struct address_info cfg_mpu;
1436 static int __initdata spea = -1;
1437 static int __initdata mss =0;
1438 static int __initdata dma = -1;
1439 static int __initdata irq = -1;
1440 static int __initdata io = -1;
1441 static int __initdata mpu_irq = -1;
1442 static int __initdata mpu_io = -1;
1444 MODULE_PARM(dma,"i");
1445 MODULE_PARM(irq,"i");
1446 MODULE_PARM(io,"i");
1447 MODULE_PARM(spea,"i");/* spea=0/1 set the old_hardware */
1448 MODULE_PARM(mpu_irq,"i");
1449 MODULE_PARM(mpu_io,"i");
1450 MODULE_PARM(mss,"i");
1452 static int __init init_sscape(void)
1454 printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
1456 cfg.irq = irq;
1457 cfg.dma = dma;
1458 cfg.io_base = io;
1460 cfg_mpu.irq = mpu_irq;
1461 cfg_mpu.io_base = mpu_io;
1462 /* WEH - Try to get right dma channel */
1463 cfg_mpu.dma = dma;
1465 devc->codec = cfg.io_base;
1466 devc->codec_irq = cfg.irq;
1467 devc->codec_type =0;
1468 devc->ic_type =0;
1469 devc->raw_buf = NULL;
1471 if(cfg.dma == -1|| cfg.irq == -1|| cfg.io_base == -1) {
1472 printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
1473 return-EINVAL;
1476 if(cfg_mpu.irq == -1&& cfg_mpu.io_base != -1) {
1477 printk(KERN_ERR "MPU_IRQ must be specified if MPU_IO is set.\n");
1478 return-EINVAL;
1481 if(spea != -1) {
1482 old_hardware = spea;
1483 printk(KERN_INFO "Forcing %s hardware support.\n",
1484 spea?"new":"old");
1486 if(probe_sscape(&cfg_mpu) ==0)
1487 return-ENODEV;
1489 attach_sscape(&cfg_mpu);
1491 mss =probe_ss_ms_sound(&cfg);
1493 if(mss)
1494 attach_ss_ms_sound(&cfg);
1496 return0;
1499 static void __exit cleanup_sscape(void)
1501 if(mss)
1502 unload_ss_ms_sound(&cfg);
1503 unload_sscape(&cfg_mpu);
1506 module_init(init_sscape);
1507 module_exit(cleanup_sscape);
1509 #ifndef MODULE
1510 static int __init setup_sscape(char*str)
1512 /* io, irq, dma, mpu_io, mpu_irq */
1513 int ints[6];
1515 str =get_options(str,ARRAY_SIZE(ints), ints);
1517 io = ints[1];
1518 irq = ints[2];
1519 dma = ints[3];
1520 mpu_io = ints[4];
1521 mpu_irq = ints[5];
1523 return1;
1526 __setup("sscape=", setup_sscape);
1527 #endif
close