29#ifdef HAVE_KERNEL_OPTION_HEADERS
37#include <isa/isavar.h>
85 rman_res_t start, rman_res_t end, rman_res_t
count, u_int flags);
90 driver_filter_t *filter,
92 void *arg,
void **cookiep);
103static int sb_rd(
struct resource *io,
int reg);
104static void sb_wr(
struct resource *io,
int reg, u_int8_t val);
106static int sb_cmd(
struct resource *io, u_char val);
144 return bus_space_read_1(rman_get_bustag(io),
145 rman_get_bushandle(io),
152 bus_space_write_1(rman_get_bustag(io),
153 rman_get_bushandle(io),
168 for (i = 0; i < 1000; i++) {
173 if (i > 10) DELAY((i > 100)? 1000 : 10);
175 printf(
"sb_dspwr(0x%02x) timed out.\n",
val);
203 for (i = 1000; i > 0; i--) {
224 int ver, essver, rev;
228 if (ver < 0x100 || ver > 0x4ff)
return 0;
233 rev = essver & 0x000f;
235 if (essver == 0x4880) ver |= 0x1000;
236 else if (essver == 0x6880) ver = 0x0500 | rev;
242 {0x01008c0e,
"Creative ViBRA16C"},
243 {0x31008c0e,
"Creative SB16/SB32"},
244 {0x41008c0e,
"Creative SB16/SB32"},
245 {0x42008c0e,
"Creative SB AWE64"},
246 {0x43008c0e,
"Creative ViBRA16X"},
247 {0x44008c0e,
"Creative SB AWE64 Gold"},
248 {0x45008c0e,
"Creative SB AWE64"},
249 {0x46008c0e,
"Creative SB AWE64"},
251 {0x01000000,
"Avance Logic ALS100+"},
252 {0x01100000,
"Avance Asound 110"},
253 {0x01200000,
"Avance Logic ALS120"},
255 {0x81167316,
"ESS ES1681"},
256 {0x02017316,
"ESS ES1688"},
257 {0x68097316,
"ESS ES1688"},
258 {0x68187316,
"ESS ES1868"},
259 {0x03007316,
"ESS ES1869"},
260 {0x69187316,
"ESS ES1869"},
261 {0xabb0110e,
"ESS ES1869 (Compaq OEM)"},
262 {0xacb0110e,
"ESS ES1869 (Compaq OEM)"},
263 {0x78187316,
"ESS ES1878"},
264 {0x79187316,
"ESS ES1879"},
265 {0x88187316,
"ESS ES1888"},
266 {0x07017316,
"ESS ES1888 (DEC OEM)"},
267 {0x06017316,
"ESS ES1888 (Dell OEM)"},
277 lid = isa_get_logicalid(
dev);
278 vid = isa_get_vendorid(
dev);
280 if (lid == 0x01000000 &&
vid != 0x01009305)
288 io = bus_alloc_resource_anywhere(
dev, SYS_RES_IOPORT, &
rid,
293 if (ver == 0)
goto bad2;
294 switch ((ver & 0x00000f00) >> 8) {
296 device_set_desc(
dev,
"SoundBlaster 1.0 (not supported)");
301 s =
"SoundBlaster 2.0";
305 s = (ver & 0x0000f000)?
"ESS 488" :
"SoundBlaster Pro";
309 s =
"SoundBlaster 16";
313 s = (ver & 0x00000008)?
"ESS 688" :
"ESS 1688";
316 if (s) device_set_desc(
dev, s);
317bad2: bus_release_resource(
dev, SYS_RES_IOPORT,
rid, io);
318bad:
return s? 0 : ENXIO;
328 u_int32_t logical_id = isa_get_logicalid(
dev);
329 int flags = device_get_flags(
dev);
330 int f, dh, dl, x,
irq, i;
332 gone_in_dev(
dev, 14,
"ISA sound driver");
334 bus_set_resource(
dev, SYS_RES_DRQ, 1,
338 scp = device_get_softc(
dev);
339 bzero(scp,
sizeof(*scp));
342 err =
"alloc_resource";
345 err =
"sb_reset_dsp";
347 err =
"sb_identify_board";
349 if (scp->
bd_ver == 0)
goto bad;
351 if (logical_id == 0x01200000 && scp->
bd_ver < 0x0400) scp->
bd_ver = 0x0499;
352 switch ((scp->
bd_ver & 0x0f00) >> 8) {
370 if (scp->
drq[0]) dl = rman_get_start(scp->
drq[0]);
else dl = -1;
371 if (scp->
drq[1]) dh = rman_get_start(scp->
drq[1]);
else dh = dl;
372 if (!logical_id && (dh < dl)) {
375 scp->
drq[0] = scp->
drq[1];
377 dl = rman_get_start(scp->
drq[0]);
378 dh = rman_get_start(scp->
drq[1]);
382 irq = rman_get_start(scp->
irq[0]);
384 else if (
irq == 7) x = 4;
385 else if (
irq == 9) x = 1;
386 else if (
irq == 10) x = 8;
388 err =
"bad irq (5/7/9/10 valid)";
394 device_printf(
dev,
"setting card to irq %d, drq %d",
irq, dl);
395 if (dl != dh) printf(
", %d", dh);
401 switch (logical_id) {
411 for (i = 0; i <
IRQ_MAX; i++) {
419 if (
func == NULL)
goto bad;
426 if (
func == NULL)
goto bad;
433 if (
func == NULL)
goto bad;
439 bus_generic_attach(
dev);
443bad:
if (err) device_printf(
dev,
"%s\n", err);
459 return bus_generic_detach(
dev);
479 driver_filter_t *filter,
481 void *arg,
void **cookiep)
487 if (filter != NULL) {
488 printf(
"sbc.c: we cannot use a filter here\n");
494 if (
irq == scp->
irq[i]) ihl = &scp->
ihl[i];
498 if (ihl == NULL) ret = EINVAL;
500 while ((ret == 0) && (i <
INTR_MAX)) {
501 if (ihl->
intr[i] == NULL) {
504 *cookiep = &ihl->
intr[i];
509 return (ret > 0)? EINVAL : 0;
523 if (
irq == scp->
irq[i]) ihl = &scp->
ihl[i];
527 if (ihl == NULL) ret = EINVAL;
529 while ((ret == 0) && (i <
INTR_MAX)) {
530 if (cookie == &ihl->
intr[i]) {
537 return (ret > 0)? EINVAL : 0;
540static struct resource *
542 rman_res_t start, rman_res_t end, rman_res_t
count, u_int flags)
545 int *alloced, rid_max, alloced_max;
546 struct resource **res;
548 scp = device_get_softc(
bus);
572 if (*
rid > rid_max || alloced[*
rid] == alloced_max)
584 int *alloced, rid_max;
586 scp = device_get_softc(
bus);
604 if (
rid > rid_max || alloced[
rid] == 0)
619 *result =
func->func;
635 int index, uintptr_t
value)
652 for (i = 0 ; i <
IO_MAX ; i++) {
653 if (scp->
io[i] == NULL) {
655 scp->
io[i] = bus_alloc_resource_anywhere(scp->
dev,
660 if (i == 0 && scp->
io[i] == NULL)
665 for (i = 0 ; i <
DRQ_MAX ; i++) {
666 if (scp->
drq[i] == NULL) {
668 scp->
drq[i] = bus_alloc_resource_any(scp->
dev,
672 if (i == 0 && scp->
drq[i] == NULL)
677 for (i = 0 ; i <
IRQ_MAX ; i++) {
678 if (scp->
irq[i] == NULL) {
680 scp->
irq[i] = bus_alloc_resource_any(scp->
dev,
684 if (i == 0 && scp->
irq[i] == NULL)
697 for (i = 0 ; i <
IO_MAX ; i++) {
698 if (scp->
io[i] != NULL) {
699 bus_release_resource(scp->
dev, SYS_RES_IOPORT, scp->
io_rid[i], scp->
io[i]);
703 for (i = 0 ; i <
DRQ_MAX ; i++) {
704 if (scp->
drq[i] != NULL) {
705 bus_release_resource(scp->
dev, SYS_RES_DRQ, scp->
drq_rid[i], scp->
drq[i]);
709 for (i = 0 ; i <
IRQ_MAX ; i++) {
710 if (scp->
irq[i] != NULL) {
711 if (scp->
ih[i] != NULL)
712 bus_teardown_intr(scp->
dev, scp->
irq[i], scp->
ih[i]);
714 bus_release_resource(scp->
dev, SYS_RES_IRQ, scp->
irq_rid[i], scp->
irq[i]);
726 DEVMETHOD(device_shutdown, bus_generic_shutdown),
727 DEVMETHOD(device_suspend, bus_generic_suspend),
728 DEVMETHOD(device_resume, bus_generic_resume),
735 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
736 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
static void sb_wr(struct resource *io, int reg, u_int8_t val)
void sbc_lockassert(struct sbc_softc *scp)
static int sb_dspready(struct resource *io)
static int sb_rd(struct resource *io, int reg)
static void sb_setmixer(struct resource *io, u_int port, u_int value)
static void sbc_lockdestroy(struct sbc_softc *scp)
static int sbc_write_ivar(device_t bus, device_t dev, int index, uintptr_t value)
static int sbc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *result)
static devclass_t sbc_devclass
static int sb_identify_board(struct resource *io)
static int alloc_resource(struct sbc_softc *scp)
DRIVER_MODULE(snd_sbc, isa, sbc_driver, sbc_devclass, 0, 0)
static int release_resource(struct sbc_softc *scp)
static void sbc_lockinit(struct sbc_softc *scp)
static struct resource * sbc_alloc_resource(device_t bus, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
static struct isa_pnp_id sbc_ids[]
static int sbc_attach(device_t dev)
void sbc_unlock(struct sbc_softc *scp)
static int sb_reset_dsp(struct resource *io)
SND_DECLARE_FILE("$FreeBSD$")
static void sbc_intr(void *p)
static device_method_t sbc_methods[]
static int sbc_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie)
static int sb_cmd(struct resource *io, u_char val)
void sbc_lock(struct sbc_softc *scp)
MODULE_VERSION(snd_sbc, 1)
static int sbc_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r)
static u_int sb_get_byte(struct resource *io)
static int sbc_probe(device_t dev)
static int sbc_detach(device_t dev)
static int sbc_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg, void **cookiep)
static int sb_dspwr(struct resource *io, u_char val)
MODULE_DEPEND(snd_sbc, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER)
static driver_t sbc_driver
void snd_mtxassert(void *m)
void * snd_mtxcreate(const char *desc, const char *type)
void snd_mtxfree(void *m)
int snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand, void *param, void **cookiep)
driver_intr_t * intr[INTR_MAX]
void * intr_arg[INTR_MAX]
struct sbc_softc * parent
struct sbc_ihl ihl[IRQ_MAX]
struct resource * drq[DRQ_MAX]
struct resource * irq[IRQ_MAX]
struct resource * io[IO_MAX]