/* * sound/dev_table.c * * Device call tables. * * Copyright by Hannu Savolainen 1993 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. 2. * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/sys/i386/isa/sound/dev_table.c,v 1.18 1999/12/20 18:04:59 eivind Exp $ * $DragonFly: src/sys/dev/sound/isa/i386/Attic/dev_table.c,v 1.3 2003/08/07 21:17:12 dillon Exp $ */ #define _DEV_TABLE_C_ #include "sound_config.h" #if NSND > 0 int sound_started = 0; int sndtable_get_cardcount(void); int snd_find_driver(int type); static void sndtable_init(void); int sndtable_probe(int unit, struct address_info * hw_config); int sndtable_init_card(int unit, struct address_info * hw_config); static void start_services(void); static void start_cards(void); struct address_info *sound_getconf(int card_type); int snd_find_driver(int type) { int i, n = num_sound_drivers; for (i = 0; i < n; i++) if (sound_drivers[i].card_type == type) return i; return -1; } static void start_services() { int soundcards_installed; if (!(soundcards_installed = sndtable_get_cardcount())) return ; /* No cards detected */ #ifdef CONFIG_AUDIO if (num_audiodevs) /* Audio devices present */ DMAbuf_init(); #endif #ifdef CONFIG_MIDI if (num_midis) /* MIDIbuf_init(0) */; #endif #ifdef CONFIG_SEQUENCER if (num_midis + num_synths) sequencer_init(); #endif } static void start_cards() { int drv, i, n = num_sound_cards; struct card_info *ci = snd_installed_cards ; sound_started = 1; if (trace_init) printf("Sound initialization started\n"); /* * Check the number of cards actually defined in the table */ for (i = 0; i < n && snd_installed_cards[i].card_type; i++) num_sound_cards = i + 1; for (i = 0; i < n && ci->card_type; ci++, i++) if (ci->enabled) { if ((drv = snd_find_driver(ci->card_type)) == -1) { ci->enabled = 0; /* Mark as not detected */ continue; } ci->config.card_subtype = sound_drivers[drv].card_subtype; if (sound_drivers[drv].probe(&(ci->config))) sound_drivers[drv].attach(&(ci->config)); else ci->enabled = 0; /* Mark as not detected */ } if (trace_init) printf("Sound initialization complete\n"); } static void sndtable_init() { start_cards(); } /* * sndtable_probe probes a specific device. unit is the voxware unit number. */ int sndtable_probe(int unit, struct address_info * hw_config) { int i, sel = -1, n = num_sound_cards; struct card_info *ci = snd_installed_cards ; DDB(printf("-- sndtable_probe(%d)\n", unit)); /* * for some reason unit 0 always succeeds ? */ if (!unit) return TRUE; sound_started = 1; for (i=0; icard_type; ci++, i++) if ( (ci->enabled) && (ci->card_type == unit) ) { /* DDB(printf("-- found card %d\n", i) ); */ sel = i; /* and break */ } /* * not found. Creates a new entry in the table for this unit. */ if (sel == -1 && num_sound_cards < max_sound_cards) { int i; i = sel = (num_sound_cards++); DDB(printf("-- installing card %d\n", i) ); ci = &snd_installed_cards[sel] ; ci->card_type = unit; ci->enabled = 1; } /* DDB(printf("-- installed card %d\n", sel) ); */ if (sel != -1) { int drv; ci->config.io_base = hw_config->io_base; ci->config.irq = hw_config->irq; ci->config.dma = hw_config->dma; ci->config.dma2 = hw_config->dma2; ci->config.name = hw_config->name; ci->config.always_detect = hw_config->always_detect; ci->config.card_subtype = hw_config->card_subtype; ci->config.osp = hw_config->osp; if ((drv = snd_find_driver(ci->card_type)) == -1) { ci->enabled = 0; DDB(printf("Failed to find driver\n")); return FALSE; } DDB(printf("-- Driver name '%s' probe 0x%08x\n", sound_drivers[drv].name, sound_drivers[drv].probe)); hw_config->card_subtype = ci->config.card_subtype = sound_drivers[drv].card_subtype; if (sound_drivers[drv].probe(hw_config)) { DDB(printf("-- Hardware probed OK\n")); return TRUE; } DDB(printf("-- Failed to find hardware\n")); ci->enabled = 0; /* mark as not detected */ return FALSE; } return FALSE; } int sndtable_init_card(int unit, struct address_info * hw_config) { int i, n = num_sound_cards; struct card_info *ci = snd_installed_cards ; DDB(printf("sndtable_init_card(%d) entered\n", unit)); if (!unit) { sndtable_init() ; return TRUE; } for (i = 0; i < n && ci->card_type; ci++, i++) if (ci->card_type == unit) { int drv; ci->config.io_base = hw_config->io_base; ci->config.irq = hw_config->irq; ci->config.dma = hw_config->dma; ci->config.dma2 = hw_config->dma2; ci->config.name = hw_config->name; ci->config.always_detect = hw_config->always_detect; ci->config.card_subtype = hw_config->card_subtype; ci->config.osp = hw_config->osp; if ((drv = snd_find_driver(ci->card_type)) == -1) ci->enabled = 0; /* Mark not fnd */ else { DDB(printf("Located card - calling attach routine\n")); sound_drivers[drv].attach(hw_config) ; DDB(printf("attach routine finished\n")); } start_services(); return TRUE; } DDB(printf("sndtable_init_card: No card defined with type=%d, num cards: %d\n", unit, num_sound_cards)); return FALSE; } int sndtable_get_cardcount(void) { return num_audiodevs + num_mixers + num_synths + num_midis; } struct address_info * sound_getconf(int card_type) { int j, ptr = -1, n = num_sound_cards; for (j = 0; j < n && ptr == -1 && snd_installed_cards[j].card_type; j++) if (snd_installed_cards[j].card_type == card_type) ptr = j; if (ptr == -1) return (struct address_info *) NULL; return &snd_installed_cards[ptr].config; } #endif