1 1.25 uwe /* $NetBSD: wss_pnpbios.c,v 1.25 2021/10/06 23:58:49 uwe Exp $ */ 2 1.1 drochner /* 3 1.1 drochner * Copyright (c) 1999 4 1.1 drochner * Matthias Drochner. All rights reserved. 5 1.1 drochner * 6 1.1 drochner * Redistribution and use in source and binary forms, with or without 7 1.1 drochner * modification, are permitted provided that the following conditions 8 1.1 drochner * are met: 9 1.1 drochner * 1. Redistributions of source code must retain the above copyright 10 1.1 drochner * notice, this list of conditions, and the following disclaimer. 11 1.1 drochner * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 drochner * notice, this list of conditions and the following disclaimer in the 13 1.1 drochner * documentation and/or other materials provided with the distribution. 14 1.1 drochner * 15 1.1 drochner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 1.1 drochner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 1.1 drochner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 1.1 drochner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 1.1 drochner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 1.1 drochner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 1.1 drochner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 1.1 drochner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 1.1 drochner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 1.1 drochner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 1.1 drochner * SUCH DAMAGE. 26 1.1 drochner */ 27 1.6 lukem 28 1.6 lukem #include <sys/cdefs.h> 29 1.25 uwe __KERNEL_RCSID(0, "$NetBSD: wss_pnpbios.c,v 1.25 2021/10/06 23:58:49 uwe Exp $"); 30 1.1 drochner 31 1.1 drochner #include <sys/param.h> 32 1.1 drochner #include <sys/systm.h> 33 1.1 drochner #include <sys/errno.h> 34 1.1 drochner #include <sys/ioctl.h> 35 1.1 drochner #include <sys/syslog.h> 36 1.1 drochner #include <sys/device.h> 37 1.1 drochner #include <sys/proc.h> 38 1.1 drochner 39 1.20 dyoung #include <sys/bus.h> 40 1.1 drochner 41 1.1 drochner #include <sys/audioio.h> 42 1.22 isaki #include <dev/audio/audio_if.h> 43 1.1 drochner 44 1.1 drochner #include <dev/isa/isavar.h> 45 1.1 drochner #include <dev/isa/isadmavar.h> 46 1.1 drochner 47 1.1 drochner #include <i386/pnpbios/pnpbiosvar.h> 48 1.1 drochner 49 1.1 drochner #include <dev/isa/ad1848var.h> 50 1.1 drochner #include <dev/isa/wssreg.h> 51 1.1 drochner #include <dev/isa/wssvar.h> 52 1.1 drochner 53 1.18 cegger int wss_pnpbios_match(device_t, cfdata_t, void *); 54 1.18 cegger void wss_pnpbios_attach(device_t, device_t, void *); 55 1.12 perry int wss_pnpbios_hints_index(const char *); 56 1.3 groo 57 1.1 drochner 58 1.19 tsutsui CFATTACH_DECL_NEW(wss_pnpbios, sizeof(struct wss_softc), 59 1.10 thorpej wss_pnpbios_match, wss_pnpbios_attach, NULL, NULL); 60 1.1 drochner 61 1.3 groo struct wss_pnpbios_hint { 62 1.3 groo char idstr[8]; 63 1.3 groo int io_region_idx_ad1848; /* which region index is the DAC? */ 64 1.3 groo int io_region_idx_opl; /* which region index is the OPL? */ 65 1.3 groo int offset_ad1848; /* offset from start of DAC region */ 66 1.3 groo }; 67 1.3 groo 68 1.3 groo struct wss_pnpbios_hint wss_pnpbios_hints[] = { 69 1.3 groo { "NMX2210", 1, 2, WSS_CODEC }, 70 1.3 groo { "CSC0000", 0, 1, 0 }, /* Dell Latitude CPi */ 71 1.5 soren { "CSC0100", 0, 1, 0 }, /* CS4610 with CS4236 codec */ 72 1.3 groo { { 0 }, 0, 0, 0 } 73 1.3 groo }; 74 1.3 groo 75 1.3 groo 76 1.3 groo int 77 1.17 dsl wss_pnpbios_hints_index(const char *idstr) 78 1.3 groo { 79 1.3 groo int idx = 0; 80 1.3 groo 81 1.3 groo while (wss_pnpbios_hints[idx].idstr[0] != 0) { 82 1.3 groo if (!strcmp(wss_pnpbios_hints[idx].idstr, idstr)) 83 1.3 groo return idx; 84 1.3 groo ++idx; 85 1.3 groo } 86 1.3 groo 87 1.3 groo return -1; 88 1.3 groo } 89 1.3 groo 90 1.1 drochner int 91 1.21 msaitoh wss_pnpbios_match(device_t parent, cfdata_t match, void *aux) 92 1.1 drochner { 93 1.1 drochner struct pnpbiosdev_attach_args *aa = aux; 94 1.1 drochner 95 1.3 groo if (wss_pnpbios_hints_index(aa->idstr) == -1) 96 1.21 msaitoh return 0; 97 1.1 drochner 98 1.21 msaitoh return 2; /* beat sb */ 99 1.1 drochner } 100 1.1 drochner 101 1.1 drochner void 102 1.21 msaitoh wss_pnpbios_attach(device_t parent, device_t self, void *aux) 103 1.1 drochner { 104 1.18 cegger struct wss_softc *sc = device_private(self); 105 1.1 drochner struct pnpbiosdev_attach_args *aa = aux; 106 1.1 drochner struct audio_attach_args arg; 107 1.3 groo struct wss_pnpbios_hint *wph; 108 1.3 groo 109 1.1 drochner #if 0 110 1.1 drochner static u_char interrupt_bits[12] = { 111 1.1 drochner -1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20 112 1.1 drochner }; 113 1.1 drochner static u_char dma_bits[4] = {1, 2, 0, 3}; 114 1.1 drochner #endif 115 1.1 drochner 116 1.21 msaitoh aprint_naive("\n"); 117 1.3 groo wph = &wss_pnpbios_hints[wss_pnpbios_hints_index(aa->idstr)]; 118 1.3 groo 119 1.3 groo if (pnpbios_io_map(aa->pbt, aa->resc, wph->io_region_idx_ad1848, 120 1.3 groo &sc->sc_iot, &sc->sc_ioh)) { 121 1.21 msaitoh aprint_error(": can't map i/o space\n"); 122 1.1 drochner return; 123 1.1 drochner } 124 1.3 groo if (pnpbios_io_map(aa->pbt, aa->resc, wph->io_region_idx_opl, 125 1.3 groo &sc->sc_iot, &sc->sc_opl_ioh)) { 126 1.21 msaitoh aprint_error(": can't map i/o space\n"); 127 1.1 drochner return; 128 1.1 drochner } 129 1.1 drochner 130 1.19 tsutsui sc->sc_ad1848.sc_ad1848.sc_dev = self; 131 1.1 drochner sc->wss_ic = aa->ic; 132 1.1 drochner 133 1.4 thorpej if (pnpbios_getirqnum(aa->pbt, aa->resc, 0, &sc->wss_irq, NULL)) { 134 1.21 msaitoh aprint_error(": can't get IRQ\n"); 135 1.1 drochner return; 136 1.1 drochner } 137 1.1 drochner 138 1.1 drochner if (pnpbios_getdmachan(aa->pbt, aa->resc, 0, &sc->wss_playdrq)) { 139 1.21 msaitoh aprint_error(": can't get DMA channel\n"); 140 1.1 drochner return; 141 1.1 drochner } 142 1.7 mrg if (pnpbios_getdmachan(aa->pbt, aa->resc, 1, &sc->wss_recdrq)) { 143 1.21 msaitoh aprint_error(": can't get recording DMA channel"); 144 1.11 uwe sc->wss_recdrq = sc->wss_playdrq; 145 1.7 mrg } 146 1.1 drochner 147 1.1 drochner sc->sc_ad1848.sc_ad1848.sc_iot = sc->sc_iot; 148 1.3 groo bus_space_subregion(sc->sc_iot, sc->sc_ioh, wph->offset_ad1848, 4, 149 1.1 drochner &sc->sc_ad1848.sc_ad1848.sc_ioh); 150 1.1 drochner 151 1.21 msaitoh aprint_normal("\n"); 152 1.2 thorpej pnpbios_print_devres(self, aa); 153 1.2 thorpej 154 1.21 msaitoh aprint_naive("%s", device_xname(self)); 155 1.21 msaitoh aprint_normal("%s", device_xname(self)); 156 1.1 drochner 157 1.1 drochner if (!ad1848_isa_probe(&sc->sc_ad1848)) { 158 1.16 cegger aprint_error_dev(self, "ad1848 probe failed\n"); 159 1.1 drochner return; 160 1.1 drochner } 161 1.1 drochner 162 1.1 drochner wssattach(sc); 163 1.1 drochner #if 0 164 1.1 drochner /* XXX recdrq */ 165 1.1 drochner bus_space_write_1(sc->sc_iot, sc->sc_ioh, WSS_CONFIG, 166 1.21 msaitoh (interrupt_bits[sc->wss_irq] | dma_bits[sc->wss_playdrq])); 167 1.1 drochner #endif 168 1.1 drochner arg.type = AUDIODEV_TYPE_OPL; 169 1.1 drochner arg.hwif = 0; 170 1.1 drochner arg.hdl = 0; 171 1.25 uwe config_found(self, &arg, audioprint, CFARGS(.iattr = "wss")); 172 1.1 drochner } 173 1.1 drochner 174