2 * sound/386bsd/soundcard.c
4 * Soundcard driver for 386BSD.
6 * Copyright by Hannu Savolainen 1993
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met: 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 2.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $FreeBSD: src/sys/i386/isa/sound/soundcard.c,v 1.87 1999/12/20 18:05:01 eivind Exp $
29 * $DragonFly: src/sys/dev/sound/isa/i386/Attic/soundcard.c,v 1.3 2003/07/21 05:50:41 dillon Exp $
32 #include <i386/isa/sound/sound_config.h>
33 #if NSND > 0 /* from "snd.h" */
36 #include <sys/select.h>
41 #include <i386/isa/isa_device.h>
45 ** Register definitions for DMA controller 1 (channels 0..3):
47 #define DMA1_CHN(c) (IO_DMA1 + 1*(2*(c))) /* addr reg for channel c */
48 #define DMA1_SMSK (IO_DMA1 + 1*10) /* single mask register */
49 #define DMA1_MODE (IO_DMA1 + 1*11) /* mode register */
50 #define DMA1_FFC (IO_DMA1 + 1*12) /* clear first/last FF */
53 ** Register definitions for DMA controller 2 (channels 4..7):
55 #define DMA2_CHN(c) (IO_DMA2 + 2*(2*(c))) /* addr reg for channel c */
56 #define DMA2_SMSK (IO_DMA2 + 2*10) /* single mask register */
57 #define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */
58 #define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */
61 #define FIX_RETURN(ret) {if ((ret)<0) return -(ret); else return 0;}
63 static int soundcards_installed = 0; /* Number of installed soundcards */
64 static int soundcard_configured = 0;
66 static struct fileinfo files[SND_NDEVS];
67 struct selinfo selinfo[SND_NDEVS >> 4];
70 MIDIbuf_poll (int dev, struct fileinfo *file, int events, select_table * wait);
73 audio_poll(int dev, struct fileinfo * file, int events, select_table * wait);
76 sequencer_poll (int dev, struct fileinfo *file, int events, select_table * wait);
78 static int sndprobe __P((struct isa_device *));
79 static int sndattach __P((struct isa_device *));
81 static d_open_t sndopen;
82 static d_close_t sndclose;
83 static d_ioctl_t sndioctl;
84 static d_read_t sndread;
85 static d_write_t sndwrite;
86 static d_poll_t sndpoll;
87 static d_mmap_t sndmmap;
89 static char driver_name[] = "snd";
92 static struct cdevsw snd_cdevsw = {
93 /* name */ driver_name,
100 /* close */ sndclose,
102 /* write */ sndwrite,
103 /* ioctl */ sndioctl,
106 /* strategy */ nostrategy,
114 static void sound_mem_init(void);
117 * for each "device XXX" entry in the config file, we have
118 * a struct isa_driver which is linked into isa_devtab_null[]
120 * XXX It is a bit stupid to call the generic routine so many times and
121 * switch then to the specific one, but the alternative way would be
122 * to replicate some code in the probe/attach routines.
125 struct isa_driver opldriver = {sndprobe, sndattach, "opl"};
126 struct isa_driver trixdriver = {sndprobe, sndattach, "trix"};
127 struct isa_driver trixsbdriver = {sndprobe, sndattach, "trixsb"};
128 struct isa_driver sbdriver = {sndprobe, sndattach, "sb"};
129 struct isa_driver sbxvidriver = {sndprobe, sndattach, "sbxvi"};
130 struct isa_driver sbmididriver = {sndprobe, sndattach, "sbmidi"};
131 struct isa_driver awedriver = {sndprobe, sndattach, "awe"};
132 struct isa_driver pasdriver = {sndprobe, sndattach, "pas"};
133 struct isa_driver mpudriver = {sndprobe, sndattach, "mpu"};
134 struct isa_driver gusdriver = {sndprobe, sndattach, "gus"};
135 struct isa_driver gusxvidriver = {sndprobe, sndattach, "gusxvi"};
136 struct isa_driver gusmaxdriver = {sndprobe, sndattach, "gusmax"};
137 struct isa_driver uartdriver = {sndprobe, sndattach, "uart"};
138 struct isa_driver mssdriver = {sndprobe, sndattach, "mss"};
139 struct isa_driver cssdriver = {sndprobe, sndattach, "css"};
140 struct isa_driver sscapedriver = {sndprobe, sndattach, "sscape"};
141 struct isa_driver sscape_mssdriver = {sndprobe, sndattach, "sscape_mss"};
142 struct isa_driver nssdriver = {sndprobe, sndattach, "nss"};
144 short ipri_to_irq(u_short ipri);
146 static ointhand2_t sndintr;
151 struct timeval timecopy;
153 getmicrotime(&timecopy);
154 return timecopy.tv_usec / (1000000 / hz) +
155 (u_long) timecopy.tv_sec * hz;
159 sndmmap( dev_t dev, vm_offset_t offset, int nprot )
161 struct dma_buffparms * dmap;
162 u_int min = minor(dev) >> 4;
164 if (min > 0 ) return (-1);
166 dmap = audio_devs[min]->dmap_out;
168 if (nprot & PROT_EXEC)
170 dmap->mapping_flags |= DMA_MAP_MAPPED ;
171 return( i386_btop(vtophys(dmap->raw_buf) + offset) );
176 sndread(dev_t dev, struct uio * buf, int flag)
178 int count = buf->uio_resid;
179 u_int min = minor(dev);
181 FIX_RETURN(sound_read_sw(min, &files[min], buf, count));
186 sndwrite(dev_t dev, struct uio * buf, int flag)
188 int count = buf->uio_resid;
189 u_int min = minor(dev);
191 FIX_RETURN(sound_write_sw(min, &files[min], buf, count));
195 sndopen(dev_t dev, int flags, int mode, struct proc * p)
198 struct fileinfo tmp_file;
199 u_int min = minor(dev);
201 if (!soundcard_configured && min) {
202 printf("SoundCard Error: soundcard system has not been configured\n");
207 if (flags & FREAD && flags & FWRITE)
208 tmp_file.mode = OPEN_READWRITE;
209 else if (flags & FREAD)
210 tmp_file.mode = OPEN_READ;
211 else if (flags & FWRITE)
212 tmp_file.mode = OPEN_WRITE;
214 selinfo[min >> 4].si_pid = 0;
215 selinfo[min >> 4].si_flags = 0;
216 if ((retval = sound_open_sw(min, &tmp_file)) < 0)
219 bcopy((char *) &tmp_file, (char *) &files[min], sizeof(tmp_file));
226 sndclose(dev_t dev, int flags, int mode, struct proc * p)
228 u_int min = minor(dev);
230 sound_release_sw(min, &files[min]);
235 sndioctl(dev_t dev, u_long cmd, caddr_t arg, int mode, struct proc * p)
237 u_int min = minor(dev);
238 FIX_RETURN(sound_ioctl_sw(min, &files[min], cmd, arg));
242 sndpoll(dev_t dev, int events, struct proc * p)
244 u_int min = minor(dev);
246 /* printf ("snd_select(dev=%d, rw=%d, pid=%d)\n", min, rw, p->p_pid); */
248 switch (min & 0x0f) {
249 #ifdef CONFIG_SEQUENCER
252 return sequencer_poll(min, &files[min], events, p);
258 return MIDIbuf_poll(min, &files[min], events, p);
267 return audio_poll(min, &files[min], events, p);
275 #endif /* ALLOW_POLL */
276 DEB(printf("sound_ioctl(min=%d, cmd=0x%x, arg=0x%x)\n", min, cmd, arg));
281 /* XXX this should become ffs(ipri), perhaps -1 lr 970705 */
283 ipri_to_irq(u_short ipri)
286 * Converts the ipri (bitmask) to the corresponding irq number
290 for (irq = 0; irq < 16; irq++)
291 if (ipri == (1 << irq))
294 return -1; /* Invalid argument */
298 driver_to_voxunit(struct isa_driver * driver)
301 * converts a sound driver pointer into the equivalent VoxWare device
304 if (driver == &opldriver)
305 return (SNDCARD_ADLIB);
306 else if (driver == &sbdriver)
308 else if (driver == &pasdriver)
309 return (SNDCARD_PAS);
310 else if (driver == &gusdriver)
311 return (SNDCARD_GUS);
312 else if (driver == &mpudriver)
313 return (SNDCARD_MPU401);
314 else if (driver == &sbxvidriver)
315 return (SNDCARD_SB16);
316 else if (driver == &sbmididriver)
317 return (SNDCARD_SB16MIDI);
318 else if(driver == &awedriver)
319 return(SNDCARD_AWE32);
320 else if (driver == &uartdriver)
321 return (SNDCARD_UART6850);
322 else if (driver == &gusdriver)
323 return (SNDCARD_GUS16);
324 else if (driver == &mssdriver)
325 return (SNDCARD_MSS);
326 else if (driver == &cssdriver)
327 return (SNDCARD_CS4232);
328 else if (driver == &sscapedriver)
329 return(SNDCARD_SSCAPE);
330 else if (driver == &sscape_mssdriver)
331 return(SNDCARD_SSCAPE_MSS);
332 else if (driver == &trixdriver)
333 return (SNDCARD_TRXPRO);
334 else if (driver == &trixsbdriver)
335 return (SNDCARD_TRXPRO_SB);
336 else if (driver == &nssdriver)
337 return (SNDCARD_NSS);
343 * very dirty: tmp_osp is allocated in sndprobe, and used at the next
347 static sound_os_info *temp_osp;
350 * sndprobe is called for each isa_device. From here, a voxware unit
351 * number is determined, and the appropriate probe routine is selected.
352 * The parameters from the config line are passed to the hw_config struct.
356 sndprobe(struct isa_device * dev)
358 struct address_info hw_config;
361 temp_osp = (sound_os_info *)malloc(sizeof(sound_os_info),
364 panic("SOUND: Cannot allocate memory\n");
367 * get config info from the kernel config. These may be overridden
368 * by the local autoconfiguration routines though (e.g. pnp stuff).
371 hw_config.io_base = dev->id_iobase;
372 hw_config.irq = ipri_to_irq(dev->id_irq);
373 hw_config.dma = dev->id_drq;
376 * misuse the flags field for read dma. Note that, to use 0 as
377 * read dma channel, one of the high bits should be set. lr970705 XXX
380 if (dev->id_flags != 0)
381 hw_config.dma2 = dev->id_flags & 0x7;
385 hw_config.always_detect = 0;
386 hw_config.name = NULL;
387 hw_config.card_subtype = 0;
389 temp_osp->unit = dev->id_unit;
390 hw_config.osp = temp_osp;
391 unit = driver_to_voxunit(dev->id_driver);
393 if (sndtable_probe(unit, &hw_config)) {
394 dev->id_iobase = hw_config.io_base;
395 dev->id_irq = hw_config.irq == -1 ? 0 : (1 << hw_config.irq);
396 dev->id_drq = hw_config.dma;
398 if (hw_config.dma != hw_config.dma2 && ( hw_config.dma2 != -1))
399 dev->id_flags = hw_config.dma2 | 0x100; /* XXX lr */
408 sndattach(struct isa_device * dev)
411 static int midi_initialized = 0;
412 static int seq_initialized = 0;
413 struct address_info hw_config;
417 * Associate interrupt handlers with devices. XXX this may be incomplete.
419 dname = dev->id_driver->name;
420 #if defined(CONFIG_AD1848)
421 if (strcmp(dname, "css") == 0 || strcmp(dname, "gusxvi") == 0 ||
422 strcmp(dname, "mss") == 0)
423 dev->id_ointr = adintr;
426 if (strcmp(dname, "gus") == 0)
427 dev->id_ointr = gusintr;
430 if (strcmp(dname, "pas") == 0)
431 dev->id_ointr = pasintr;
433 #if NSB > 0 && (defined(CONFIG_MIDI) || defined(CONFIG_AUDIO))
434 if (strcmp(dname, "sb") == 0)
435 dev->id_ointr = sbintr;
437 if (strcmp(dname, "sscape_mss") == 0)
438 dev->id_ointr = sndintr;
440 if (strcmp(dname, "sscape") == 0 || strcmp(dname, "trix") == 0)
441 dev->id_ointr = sscapeintr;
444 if (strcmp(dname, "uart0") == 0)
445 dev->id_ointr = m6850intr;
447 #if NMPU > 0 && defined(CONFIG_MIDI)
448 if (strcmp(dname, "mpu") == 0)
449 dev->id_ointr = mpuintr;
452 if (strcmp(dname, "nss") == 0)
453 dev->id_ointr = nssintr;
456 unit = driver_to_voxunit(dev->id_driver);
457 hw_config.io_base = dev->id_iobase;
458 hw_config.irq = ipri_to_irq(dev->id_irq);
459 hw_config.dma = dev->id_drq;
461 /* misuse the flags field for read dma */
462 if (dev->id_flags != 0)
463 hw_config.dma2 = dev->id_flags & 0x7;
467 hw_config.card_subtype = 0;
468 hw_config.osp = temp_osp;
473 if (!(sndtable_init_card(unit, &hw_config))) { /* init card */
474 printf(" <Driver not configured>");
478 * Init the high level sound driver
481 if (!(soundcards_installed = sndtable_get_cardcount())) {
482 DDB(printf("No drivers actually installed\n"));
483 return FALSE; /* No cards detected */
488 if (num_audiodevs) { /* Audio devices present */
492 soundcard_configured = 1;
495 if (num_midis && !midi_initialized)
496 midi_initialized = 1;
498 if ((num_midis + num_synths) && !seq_initialized) {
503 cdevsw_add(&snd_cdevsw);
504 #define GID_SND GID_GAMES
505 #define UID_SND UID_ROOT
506 #define PERM_SND 0660
508 * make links to first successfully probed device, don't do it if
509 * duplicate creation of same node failed (ie. bad cookie returned)
511 if (dev->id_driver == &opldriver){
512 make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_SEQ,
513 UID_SND, GID_SND, PERM_SND, "sequencer%r", dev->id_unit);
514 } else if (dev->id_driver == &mpudriver ||
515 dev->id_driver == &sbmididriver ||
516 dev->id_driver == &uartdriver){
517 make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_MIDIN,
518 UID_SND, GID_SND, PERM_SND, "midi%r", dev->id_unit);
520 make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_DSP,
521 UID_SND, GID_SND, PERM_SND, "dsp%r", dev->id_unit);
522 make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_DSP16,
523 UID_SND, GID_SND, PERM_SND, "dspW%r", dev->id_unit);
524 make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_AUDIO,
525 UID_SND, GID_SND, PERM_SND, "audio%r", dev->id_unit);
526 make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_CTL,
527 UID_SND, GID_SND, PERM_SND, "mixer%r", dev->id_unit);
528 make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_STATUS,
529 UID_SND, GID_SND, PERM_SND, "sndstat%r", dev->id_unit);
538 alloc_dmap(int dev, int chan, struct dma_buffparms * dmap)
543 tmpbuf = contigmalloc(audio_devs[dev]->buffsize, M_DEVBUF, M_NOWAIT,
544 0ul, 0xfffffful, 1ul, chan & 4 ? 0x20000ul : 0x10000ul);
546 printf("soundcard buffer alloc failed \n");
548 if (tmpbuf == NULL) {
549 printf("snd: Unable to allocate %d bytes of buffer\n",
550 2 * (int) audio_devs[dev]->buffsize);
553 dmap->raw_buf = tmpbuf;
555 * Use virtual address as the physical address, since isa_dmastart
556 * performs the phys address computation.
559 dmap->raw_buf_phys = (uintptr_t) tmpbuf;
560 for (i = 0; i < audio_devs[dev]->buffsize; i++) *tmpbuf++ = 0x80;
568 static u_long dsp_init_mask = 0;
570 for (dev = 0; dev < num_audiodevs; dev++) /* Enumerate devices */
571 if (!(dsp_init_mask & (1 << dev))) /* Not already done */
572 if (audio_devs[dev]->dmachan1 >= 0) {
573 dsp_init_mask |= (1 << dev);
574 audio_devs[dev]->buffsize = DSP_BUFFSIZE;
575 /* Now allocate the buffers */
576 alloc_dmap(dev, audio_devs[dev]->dmachan1,
577 audio_devs[dev]->dmap_out);
578 if (audio_devs[dev]->flags & DMA_DUPLEX)
579 alloc_dmap(dev, audio_devs[dev]->dmachan2,
580 audio_devs[dev]->dmap_in);
588 snd_ioctl_return(int *addr, int value)
591 return value; /* Error */
597 typedef void (*irq_proc_t) (int irq);
598 static irq_proc_t irq_proc[MAX_UNIT] = {NULL};
599 static int irq_irq[MAX_UNIT] = {0};
602 snd_set_irq_handler(int int_lvl, void (*hndlr) (int), sound_os_info * osp)
604 if (osp->unit >= MAX_UNIT) {
605 printf("Sound error: Unit number too high (%d)\n", osp->unit);
608 irq_proc[osp->unit] = hndlr;
609 irq_irq[osp->unit] = int_lvl;
616 if ( (unit >= MAX_UNIT) || (irq_proc[unit] == NULL) )
619 irq_proc[unit] (irq_irq[unit]); /* Call the installed handler */
623 conf_printf(char *name, struct address_info * hw_config)
628 printf("snd0: <%s> ", name);
630 if (hw_config->io_base != -1 )
631 printf("at 0x%03x", hw_config->io_base);
633 if (hw_config->irq != -1 )
634 printf(" irq %d", hw_config->irq);
636 if (hw_config->dma != -1 || hw_config->dma2 != -1) {
637 printf(" dma %d", hw_config->dma);
638 if (hw_config->dma2 != -1)
639 printf(",%d", hw_config->dma2);
646 conf_printf2(char *name, int base, int irq, int dma, int dma2)
651 printf("snd0: <%s> ", name);
653 if (hw_config->io_base != -1 )
654 printf("at 0x%03x", hw_config->io_base);
657 printf(" irq %d", irq);
659 if (dma != -1 || dma2 != -1) {
660 printf(" dma %d", dma);
669 void tenmicrosec (int j)
672 for (k = 0; k < j/10 ; k++) {
673 for (i = 0; i < 16; i++)
678 #endif /* NSND > 0 */