1 1.75 thorpej /* $NetBSD: eso.c,v 1.75 2021/08/07 16:19:14 thorpej Exp $ */ 2 1.58 jmcneill 3 1.58 jmcneill /*- 4 1.58 jmcneill * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 1.58 jmcneill * All rights reserved. 6 1.58 jmcneill * 7 1.58 jmcneill * This code is derived from software developed for The NetBSD Foundation 8 1.58 jmcneill * by Andrew Doran. 9 1.58 jmcneill * 10 1.58 jmcneill * Redistribution and use in source and binary forms, with or without 11 1.58 jmcneill * modification, are permitted provided that the following conditions 12 1.58 jmcneill * are met: 13 1.58 jmcneill * 1. Redistributions of source code must retain the above copyright 14 1.58 jmcneill * notice, this list of conditions and the following disclaimer. 15 1.58 jmcneill * 2. Redistributions in binary form must reproduce the above copyright 16 1.58 jmcneill * notice, this list of conditions and the following disclaimer in the 17 1.58 jmcneill * documentation and/or other materials provided with the distribution. 18 1.58 jmcneill * 19 1.58 jmcneill * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.58 jmcneill * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.58 jmcneill * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.58 jmcneill * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.58 jmcneill * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.58 jmcneill * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.58 jmcneill * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.58 jmcneill * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.58 jmcneill * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.58 jmcneill * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.58 jmcneill * POSSIBILITY OF SUCH DAMAGE. 30 1.58 jmcneill */ 31 1.1 kleink 32 1.1 kleink /* 33 1.34 kleink * Copyright (c) 1999, 2000, 2004 Klaus J. Klein 34 1.1 kleink * All rights reserved. 35 1.1 kleink * 36 1.1 kleink * Redistribution and use in source and binary forms, with or without 37 1.1 kleink * modification, are permitted provided that the following conditions 38 1.1 kleink * are met: 39 1.1 kleink * 1. Redistributions of source code must retain the above copyright 40 1.1 kleink * notice, this list of conditions and the following disclaimer. 41 1.1 kleink * 2. Redistributions in binary form must reproduce the above copyright 42 1.1 kleink * notice, this list of conditions and the following disclaimer in the 43 1.1 kleink * documentation and/or other materials provided with the distribution. 44 1.1 kleink * 3. The name of the author may not be used to endorse or promote products 45 1.1 kleink * derived from this software without specific prior written permission. 46 1.1 kleink * 47 1.1 kleink * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 48 1.1 kleink * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 49 1.1 kleink * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50 1.1 kleink * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 51 1.1 kleink * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 52 1.1 kleink * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 53 1.1 kleink * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 54 1.1 kleink * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 55 1.1 kleink * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 1.1 kleink * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 1.1 kleink * SUCH DAMAGE. 58 1.1 kleink */ 59 1.1 kleink 60 1.1 kleink /* 61 1.1 kleink * ESS Technology Inc. Solo-1 PCI AudioDrive (ES1938/1946) device driver. 62 1.1 kleink */ 63 1.23 lukem 64 1.23 lukem #include <sys/cdefs.h> 65 1.75 thorpej __KERNEL_RCSID(0, "$NetBSD: eso.c,v 1.75 2021/08/07 16:19:14 thorpej Exp $"); 66 1.1 kleink 67 1.5 kleink #include "mpu.h" 68 1.5 kleink 69 1.1 kleink #include <sys/param.h> 70 1.1 kleink #include <sys/systm.h> 71 1.1 kleink #include <sys/kernel.h> 72 1.58 jmcneill #include <sys/kmem.h> 73 1.1 kleink #include <sys/device.h> 74 1.49 kleink #include <sys/queue.h> 75 1.1 kleink #include <sys/proc.h> 76 1.1 kleink 77 1.1 kleink #include <dev/pci/pcidevs.h> 78 1.1 kleink #include <dev/pci/pcivar.h> 79 1.1 kleink 80 1.1 kleink #include <sys/audioio.h> 81 1.70 isaki #include <dev/audio/audio_if.h> 82 1.1 kleink 83 1.2 augustss #include <dev/ic/mpuvar.h> 84 1.1 kleink #include <dev/ic/i8237reg.h> 85 1.1 kleink #include <dev/pci/esoreg.h> 86 1.1 kleink #include <dev/pci/esovar.h> 87 1.1 kleink 88 1.51 ad #include <sys/bus.h> 89 1.51 ad #include <sys/intr.h> 90 1.1 kleink 91 1.35 kleink /* 92 1.35 kleink * XXX Work around the 24-bit implementation limit of the Audio 1 DMA 93 1.35 kleink * XXX engine by allocating through the ISA DMA tag. 94 1.35 kleink */ 95 1.35 kleink #if defined(amd64) || defined(i386) 96 1.35 kleink #include <dev/isa/isavar.h> 97 1.35 kleink #endif 98 1.35 kleink 99 1.1 kleink #if defined(AUDIO_DEBUG) || defined(DEBUG) 100 1.1 kleink #define DPRINTF(x) printf x 101 1.1 kleink #else 102 1.1 kleink #define DPRINTF(x) 103 1.1 kleink #endif 104 1.1 kleink 105 1.1 kleink struct eso_dma { 106 1.8 kleink bus_dma_tag_t ed_dmat; 107 1.1 kleink bus_dmamap_t ed_map; 108 1.50 christos void * ed_kva; 109 1.1 kleink bus_dma_segment_t ed_segs[1]; 110 1.1 kleink int ed_nsegs; 111 1.1 kleink size_t ed_size; 112 1.49 kleink SLIST_ENTRY(eso_dma) ed_slist; 113 1.1 kleink }; 114 1.1 kleink 115 1.49 kleink #define KVADDR(dma) ((void *)(dma)->ed_kva) 116 1.1 kleink #define DMAADDR(dma) ((dma)->ed_map->dm_segs[0].ds_addr) 117 1.1 kleink 118 1.1 kleink /* Autoconfiguration interface */ 119 1.55 cegger static int eso_match(device_t, cfdata_t, void *); 120 1.55 cegger static void eso_attach(device_t, device_t, void *); 121 1.55 cegger static void eso_defer(device_t); 122 1.39 kent static int eso_print(void *, const char *); 123 1.1 kleink 124 1.62 chs CFATTACH_DECL_NEW(eso, sizeof (struct eso_softc), 125 1.27 thorpej eso_match, eso_attach, NULL, NULL); 126 1.1 kleink 127 1.1 kleink /* PCI interface */ 128 1.39 kent static int eso_intr(void *); 129 1.1 kleink 130 1.1 kleink /* MI audio layer interface */ 131 1.70 isaki static int eso_query_format(void *, audio_format_query_t *); 132 1.70 isaki static int eso_set_format(void *, int, 133 1.70 isaki const audio_params_t *, const audio_params_t *, 134 1.70 isaki audio_filter_reg_t *, audio_filter_reg_t *); 135 1.39 kent static int eso_round_blocksize(void *, int, int, const audio_params_t *); 136 1.39 kent static int eso_halt_output(void *); 137 1.39 kent static int eso_halt_input(void *); 138 1.39 kent static int eso_getdev(void *, struct audio_device *); 139 1.39 kent static int eso_set_port(void *, mixer_ctrl_t *); 140 1.39 kent static int eso_get_port(void *, mixer_ctrl_t *); 141 1.39 kent static int eso_query_devinfo(void *, mixer_devinfo_t *); 142 1.58 jmcneill static void * eso_allocm(void *, int, size_t); 143 1.58 jmcneill static void eso_freem(void *, void *, size_t); 144 1.39 kent static size_t eso_round_buffersize(void *, int, size_t); 145 1.39 kent static int eso_get_props(void *); 146 1.39 kent static int eso_trigger_output(void *, void *, void *, int, 147 1.39 kent void (*)(void *), void *, const audio_params_t *); 148 1.39 kent static int eso_trigger_input(void *, void *, void *, int, 149 1.39 kent void (*)(void *), void *, const audio_params_t *); 150 1.58 jmcneill static void eso_get_locks(void *, kmutex_t **, kmutex_t **); 151 1.1 kleink 152 1.37 yamt static const struct audio_hw_if eso_hw_if = { 153 1.70 isaki .query_format = eso_query_format, 154 1.70 isaki .set_format = eso_set_format, 155 1.69 isaki .round_blocksize = eso_round_blocksize, 156 1.69 isaki .halt_output = eso_halt_output, 157 1.69 isaki .halt_input = eso_halt_input, 158 1.69 isaki .getdev = eso_getdev, 159 1.69 isaki .set_port = eso_set_port, 160 1.69 isaki .get_port = eso_get_port, 161 1.69 isaki .query_devinfo = eso_query_devinfo, 162 1.69 isaki .allocm = eso_allocm, 163 1.69 isaki .freem = eso_freem, 164 1.69 isaki .round_buffersize = eso_round_buffersize, 165 1.69 isaki .get_props = eso_get_props, 166 1.69 isaki .trigger_output = eso_trigger_output, 167 1.69 isaki .trigger_input = eso_trigger_input, 168 1.69 isaki .get_locks = eso_get_locks, 169 1.1 kleink }; 170 1.1 kleink 171 1.1 kleink static const char * const eso_rev2model[] = { 172 1.1 kleink "ES1938", 173 1.13 kleink "ES1946", 174 1.13 kleink "ES1946 Revision E" 175 1.1 kleink }; 176 1.1 kleink 177 1.70 isaki /* 178 1.70 isaki * XXX The HW actually supports more frequencies but I select a few 179 1.70 isaki * typical frequencies which does not include rounding error. 180 1.70 isaki */ 181 1.70 isaki static const struct audio_format eso_formats[] = { 182 1.70 isaki { 183 1.70 isaki .mode = AUMODE_PLAY | AUMODE_RECORD, 184 1.70 isaki .encoding = AUDIO_ENCODING_SLINEAR_LE, 185 1.70 isaki .validbits = 16, 186 1.70 isaki .precision = 16, 187 1.70 isaki .channels = 2, 188 1.70 isaki .channel_mask = AUFMT_STEREO, 189 1.70 isaki .frequency_type = 4, 190 1.70 isaki .frequency = { 8000, 22050, 44100, 48000 }, 191 1.70 isaki }, 192 1.38 kent }; 193 1.70 isaki #define ESO_NFORMATS __arraycount(eso_formats) 194 1.38 kent 195 1.1 kleink 196 1.1 kleink /* 197 1.1 kleink * Utility routines 198 1.1 kleink */ 199 1.1 kleink /* Register access etc. */ 200 1.39 kent static uint8_t eso_read_ctlreg(struct eso_softc *, uint8_t); 201 1.39 kent static uint8_t eso_read_mixreg(struct eso_softc *, uint8_t); 202 1.39 kent static uint8_t eso_read_rdr(struct eso_softc *); 203 1.39 kent static void eso_reload_master_vol(struct eso_softc *); 204 1.39 kent static int eso_reset(struct eso_softc *); 205 1.39 kent static void eso_set_gain(struct eso_softc *, unsigned int); 206 1.39 kent static int eso_set_recsrc(struct eso_softc *, unsigned int); 207 1.39 kent static int eso_set_monooutsrc(struct eso_softc *, unsigned int); 208 1.39 kent static int eso_set_monoinbypass(struct eso_softc *, unsigned int); 209 1.39 kent static int eso_set_preamp(struct eso_softc *, unsigned int); 210 1.39 kent static void eso_write_cmd(struct eso_softc *, uint8_t); 211 1.39 kent static void eso_write_ctlreg(struct eso_softc *, uint8_t, uint8_t); 212 1.39 kent static void eso_write_mixreg(struct eso_softc *, uint8_t, uint8_t); 213 1.1 kleink /* DMA memory allocation */ 214 1.39 kent static int eso_allocmem(struct eso_softc *, size_t, size_t, size_t, 215 1.58 jmcneill int, struct eso_dma *); 216 1.39 kent static void eso_freemem(struct eso_dma *); 217 1.50 christos static struct eso_dma * eso_kva2dma(const struct eso_softc *, const void *); 218 1.1 kleink 219 1.1 kleink 220 1.1 kleink static int 221 1.55 cegger eso_match(device_t parent, cfdata_t match, void *aux) 222 1.1 kleink { 223 1.39 kent struct pci_attach_args *pa; 224 1.1 kleink 225 1.39 kent pa = aux; 226 1.1 kleink if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ESSTECH && 227 1.1 kleink PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ESSTECH_SOLO1) 228 1.39 kent return 1; 229 1.1 kleink 230 1.39 kent return 0; 231 1.1 kleink } 232 1.1 kleink 233 1.1 kleink static void 234 1.55 cegger eso_attach(device_t parent, device_t self, void *aux) 235 1.1 kleink { 236 1.39 kent struct eso_softc *sc; 237 1.39 kent struct pci_attach_args *pa; 238 1.1 kleink struct audio_attach_args aa; 239 1.1 kleink pci_intr_handle_t ih; 240 1.1 kleink bus_addr_t vcbase; 241 1.1 kleink const char *intrstring; 242 1.61 gson int idx, error; 243 1.5 kleink uint8_t a2mode, mvctl; 244 1.65 christos char intrbuf[PCI_INTRSTR_LEN]; 245 1.1 kleink 246 1.56 cegger sc = device_private(self); 247 1.62 chs sc->sc_dev = self; 248 1.39 kent pa = aux; 249 1.29 thorpej aprint_naive(": Audio controller\n"); 250 1.29 thorpej 251 1.61 gson mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 252 1.61 gson mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO); 253 1.61 gson 254 1.1 kleink sc->sc_revision = PCI_REVISION(pa->pa_class); 255 1.29 thorpej aprint_normal(": ESS Solo-1 PCI AudioDrive "); 256 1.9 cgd if (sc->sc_revision < 257 1.1 kleink sizeof (eso_rev2model) / sizeof (eso_rev2model[0])) 258 1.29 thorpej aprint_normal("%s\n", eso_rev2model[sc->sc_revision]); 259 1.1 kleink else 260 1.29 thorpej aprint_normal("(unknown rev. 0x%02x)\n", sc->sc_revision); 261 1.1 kleink 262 1.1 kleink /* Map I/O registers. */ 263 1.1 kleink if (pci_mapreg_map(pa, ESO_PCI_BAR_IO, PCI_MAPREG_TYPE_IO, 0, 264 1.1 kleink &sc->sc_iot, &sc->sc_ioh, NULL, NULL)) { 265 1.62 chs aprint_error_dev(sc->sc_dev, "can't map I/O space\n"); 266 1.1 kleink return; 267 1.1 kleink } 268 1.1 kleink if (pci_mapreg_map(pa, ESO_PCI_BAR_SB, PCI_MAPREG_TYPE_IO, 0, 269 1.1 kleink &sc->sc_sb_iot, &sc->sc_sb_ioh, NULL, NULL)) { 270 1.62 chs aprint_error_dev(sc->sc_dev, "can't map SB I/O space\n"); 271 1.1 kleink return; 272 1.1 kleink } 273 1.1 kleink if (pci_mapreg_map(pa, ESO_PCI_BAR_VC, PCI_MAPREG_TYPE_IO, 0, 274 1.1 kleink &sc->sc_dmac_iot, &sc->sc_dmac_ioh, &vcbase, &sc->sc_vcsize)) { 275 1.62 chs aprint_error_dev(sc->sc_dev, "can't map VC I/O space\n"); 276 1.1 kleink /* Don't bail out yet: we can map it later, see below. */ 277 1.1 kleink vcbase = 0; 278 1.1 kleink sc->sc_vcsize = 0x10; /* From the data sheet. */ 279 1.1 kleink } 280 1.1 kleink if (pci_mapreg_map(pa, ESO_PCI_BAR_MPU, PCI_MAPREG_TYPE_IO, 0, 281 1.3 augustss &sc->sc_mpu_iot, &sc->sc_mpu_ioh, NULL, NULL)) { 282 1.62 chs aprint_error_dev(sc->sc_dev, "can't map MPU I/O space\n"); 283 1.1 kleink return; 284 1.1 kleink } 285 1.1 kleink if (pci_mapreg_map(pa, ESO_PCI_BAR_GAME, PCI_MAPREG_TYPE_IO, 0, 286 1.1 kleink &sc->sc_game_iot, &sc->sc_game_ioh, NULL, NULL)) { 287 1.62 chs aprint_error_dev(sc->sc_dev, "can't map Game I/O space\n"); 288 1.1 kleink return; 289 1.1 kleink } 290 1.1 kleink 291 1.1 kleink sc->sc_dmat = pa->pa_dmat; 292 1.49 kleink SLIST_INIT(&sc->sc_dmas); 293 1.1 kleink sc->sc_dmac_configured = 0; 294 1.1 kleink 295 1.1 kleink /* Enable bus mastering. */ 296 1.1 kleink pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 297 1.1 kleink pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) | 298 1.1 kleink PCI_COMMAND_MASTER_ENABLE); 299 1.1 kleink 300 1.1 kleink /* Reset the device; bail out upon failure. */ 301 1.61 gson mutex_spin_enter(&sc->sc_intr_lock); 302 1.61 gson error = eso_reset(sc); 303 1.61 gson mutex_spin_exit(&sc->sc_intr_lock); 304 1.61 gson if (error != 0) { 305 1.62 chs aprint_error_dev(sc->sc_dev, "can't reset\n"); 306 1.1 kleink return; 307 1.1 kleink } 308 1.39 kent 309 1.1 kleink /* Select the DMA/IRQ policy: DDMA, ISA IRQ emulation disabled. */ 310 1.1 kleink pci_conf_write(pa->pa_pc, pa->pa_tag, ESO_PCI_S1C, 311 1.1 kleink pci_conf_read(pa->pa_pc, pa->pa_tag, ESO_PCI_S1C) & 312 1.1 kleink ~(ESO_PCI_S1C_IRQP_MASK | ESO_PCI_S1C_DMAP_MASK)); 313 1.1 kleink 314 1.5 kleink /* Enable the relevant (DMA) interrupts. */ 315 1.1 kleink bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_IRQCTL, 316 1.14 kleink ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ | ESO_IO_IRQCTL_HVIRQ | 317 1.14 kleink ESO_IO_IRQCTL_MPUIRQ); 318 1.39 kent 319 1.61 gson mutex_spin_enter(&sc->sc_intr_lock); 320 1.61 gson 321 1.1 kleink /* Set up A1's sample rate generator for new-style parameters. */ 322 1.1 kleink a2mode = eso_read_mixreg(sc, ESO_MIXREG_A2MODE); 323 1.1 kleink a2mode |= ESO_MIXREG_A2MODE_NEWA1 | ESO_MIXREG_A2MODE_ASYNC; 324 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_A2MODE, a2mode); 325 1.39 kent 326 1.31 kleink /* Slave Master Volume to Hardware Volume Control Counter, unmask IRQ.*/ 327 1.14 kleink mvctl = eso_read_mixreg(sc, ESO_MIXREG_MVCTL); 328 1.14 kleink mvctl &= ~ESO_MIXREG_MVCTL_SPLIT; 329 1.14 kleink mvctl |= ESO_MIXREG_MVCTL_HVIRQM; 330 1.14 kleink eso_write_mixreg(sc, ESO_MIXREG_MVCTL, mvctl); 331 1.14 kleink 332 1.1 kleink /* Set mixer regs to something reasonable, needs work. */ 333 1.12 kleink sc->sc_recmon = sc->sc_spatializer = sc->sc_mvmute = 0; 334 1.34 kleink eso_set_monooutsrc(sc, ESO_MIXREG_MPM_MOMUTE); 335 1.34 kleink eso_set_monoinbypass(sc, 0); 336 1.34 kleink eso_set_preamp(sc, 1); 337 1.1 kleink for (idx = 0; idx < ESO_NGAINDEVS; idx++) { 338 1.1 kleink int v; 339 1.39 kent 340 1.1 kleink switch (idx) { 341 1.39 kent case ESO_MIC_PLAY_VOL: 342 1.1 kleink case ESO_LINE_PLAY_VOL: 343 1.1 kleink case ESO_CD_PLAY_VOL: 344 1.1 kleink case ESO_MONO_PLAY_VOL: 345 1.1 kleink case ESO_AUXB_PLAY_VOL: 346 1.1 kleink case ESO_DAC_REC_VOL: 347 1.1 kleink case ESO_LINE_REC_VOL: 348 1.1 kleink case ESO_SYNTH_REC_VOL: 349 1.1 kleink case ESO_CD_REC_VOL: 350 1.1 kleink case ESO_MONO_REC_VOL: 351 1.1 kleink case ESO_AUXB_REC_VOL: 352 1.1 kleink case ESO_SPATIALIZER: 353 1.1 kleink v = 0; 354 1.1 kleink break; 355 1.1 kleink case ESO_MASTER_VOL: 356 1.1 kleink v = ESO_GAIN_TO_6BIT(AUDIO_MAX_GAIN / 2); 357 1.1 kleink break; 358 1.1 kleink default: 359 1.1 kleink v = ESO_GAIN_TO_4BIT(AUDIO_MAX_GAIN / 2); 360 1.1 kleink break; 361 1.1 kleink } 362 1.1 kleink sc->sc_gain[idx][ESO_LEFT] = sc->sc_gain[idx][ESO_RIGHT] = v; 363 1.1 kleink eso_set_gain(sc, idx); 364 1.1 kleink } 365 1.61 gson 366 1.1 kleink eso_set_recsrc(sc, ESO_MIXREG_ERS_MIC); 367 1.39 kent 368 1.61 gson mutex_spin_exit(&sc->sc_intr_lock); 369 1.61 gson 370 1.1 kleink /* Map and establish the interrupt. */ 371 1.20 sommerfe if (pci_intr_map(pa, &ih)) { 372 1.62 chs aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n"); 373 1.1 kleink return; 374 1.1 kleink } 375 1.58 jmcneill 376 1.65 christos intrstring = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf)); 377 1.68 jdolecek sc->sc_ih = pci_intr_establish_xname(pa->pa_pc, ih, IPL_AUDIO, 378 1.68 jdolecek eso_intr, sc, device_xname(self)); 379 1.1 kleink if (sc->sc_ih == NULL) { 380 1.62 chs aprint_error_dev(sc->sc_dev, "couldn't establish interrupt"); 381 1.1 kleink if (intrstring != NULL) 382 1.57 njoly aprint_error(" at %s", intrstring); 383 1.57 njoly aprint_error("\n"); 384 1.58 jmcneill mutex_destroy(&sc->sc_lock); 385 1.58 jmcneill mutex_destroy(&sc->sc_intr_lock); 386 1.1 kleink return; 387 1.1 kleink } 388 1.66 msaitoh aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstring); 389 1.1 kleink 390 1.58 jmcneill cv_init(&sc->sc_pcv, "esoho"); 391 1.58 jmcneill cv_init(&sc->sc_rcv, "esohi"); 392 1.58 jmcneill 393 1.1 kleink /* 394 1.1 kleink * Set up the DDMA Control register; a suitable I/O region has been 395 1.1 kleink * supposedly mapped in the VC base address register. 396 1.1 kleink * 397 1.1 kleink * The Solo-1 has an ... interesting silicon bug that causes it to 398 1.1 kleink * not respond to I/O space accesses to the Audio 1 DMA controller 399 1.1 kleink * if the latter's mapping base address is aligned on a 1K boundary. 400 1.1 kleink * As a consequence, it is quite possible for the mapping provided 401 1.1 kleink * in the VC BAR to be useless. To work around this, we defer this 402 1.1 kleink * part until all autoconfiguration on our parent bus is completed 403 1.1 kleink * and then try to map it ourselves in fulfillment of the constraint. 404 1.39 kent * 405 1.1 kleink * According to the register map we may write to the low 16 bits 406 1.1 kleink * only, but experimenting has shown we're safe. 407 1.1 kleink * -kjk 408 1.1 kleink */ 409 1.1 kleink if (ESO_VALID_DDMAC_BASE(vcbase)) { 410 1.1 kleink pci_conf_write(pa->pa_pc, pa->pa_tag, ESO_PCI_DDMAC, 411 1.1 kleink vcbase | ESO_PCI_DDMAC_DE); 412 1.1 kleink sc->sc_dmac_configured = 1; 413 1.1 kleink 414 1.62 chs aprint_normal_dev(sc->sc_dev, 415 1.53 cegger "mapping Audio 1 DMA using VC I/O space at 0x%lx\n", 416 1.53 cegger (unsigned long)vcbase); 417 1.1 kleink } else { 418 1.1 kleink DPRINTF(("%s: VC I/O space at 0x%lx not suitable, deferring\n", 419 1.62 chs device_xname(sc->sc_dev), (unsigned long)vcbase)); 420 1.1 kleink sc->sc_pa = *pa; 421 1.1 kleink config_defer(self, eso_defer); 422 1.1 kleink } 423 1.39 kent 424 1.62 chs audio_attach_mi(&eso_hw_if, sc, sc->sc_dev); 425 1.1 kleink 426 1.1 kleink aa.type = AUDIODEV_TYPE_OPL; 427 1.1 kleink aa.hwif = NULL; 428 1.1 kleink aa.hdl = NULL; 429 1.74 thorpej (void)config_found(sc->sc_dev, &aa, audioprint, 430 1.75 thorpej CFARGS(.iattr = "eso")); 431 1.1 kleink 432 1.3 augustss aa.type = AUDIODEV_TYPE_MPU; 433 1.3 augustss aa.hwif = NULL; 434 1.3 augustss aa.hdl = NULL; 435 1.74 thorpej sc->sc_mpudev = config_found(sc->sc_dev, &aa, audioprint, 436 1.75 thorpej CFARGS(.iattr = "eso")); 437 1.5 kleink if (sc->sc_mpudev != NULL) { 438 1.5 kleink /* Unmask the MPU irq. */ 439 1.58 jmcneill mutex_spin_enter(&sc->sc_intr_lock); 440 1.5 kleink mvctl = eso_read_mixreg(sc, ESO_MIXREG_MVCTL); 441 1.5 kleink mvctl |= ESO_MIXREG_MVCTL_MPUIRQM; 442 1.5 kleink eso_write_mixreg(sc, ESO_MIXREG_MVCTL, mvctl); 443 1.58 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 444 1.5 kleink } 445 1.24 kleink 446 1.24 kleink aa.type = AUDIODEV_TYPE_AUX; 447 1.24 kleink aa.hwif = NULL; 448 1.24 kleink aa.hdl = NULL; 449 1.74 thorpej (void)config_found(sc->sc_dev, &aa, eso_print, 450 1.75 thorpej CFARGS(.iattr = "eso")); 451 1.1 kleink } 452 1.1 kleink 453 1.1 kleink static void 454 1.55 cegger eso_defer(device_t self) 455 1.1 kleink { 456 1.39 kent struct eso_softc *sc; 457 1.39 kent struct pci_attach_args *pa; 458 1.1 kleink bus_addr_t addr, start; 459 1.1 kleink 460 1.56 cegger sc = device_private(self); 461 1.39 kent pa = &sc->sc_pa; 462 1.62 chs aprint_normal_dev(sc->sc_dev, ""); 463 1.1 kleink 464 1.1 kleink /* 465 1.1 kleink * This is outright ugly, but since we must not make assumptions 466 1.1 kleink * on the underlying allocator's behaviour it's the most straight- 467 1.1 kleink * forward way to implement it. Note that we skip over the first 468 1.1 kleink * 1K region, which is typically occupied by an attached ISA bus. 469 1.1 kleink */ 470 1.58 jmcneill mutex_enter(&sc->sc_lock); 471 1.1 kleink for (start = 0x0400; start < 0xffff; start += 0x0400) { 472 1.1 kleink if (bus_space_alloc(sc->sc_iot, 473 1.1 kleink start + sc->sc_vcsize, start + 0x0400 - 1, 474 1.1 kleink sc->sc_vcsize, sc->sc_vcsize, 0, 0, &addr, 475 1.1 kleink &sc->sc_dmac_ioh) != 0) 476 1.1 kleink continue; 477 1.1 kleink 478 1.58 jmcneill mutex_spin_enter(&sc->sc_intr_lock); 479 1.1 kleink pci_conf_write(pa->pa_pc, pa->pa_tag, ESO_PCI_DDMAC, 480 1.1 kleink addr | ESO_PCI_DDMAC_DE); 481 1.58 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 482 1.1 kleink sc->sc_dmac_iot = sc->sc_iot; 483 1.1 kleink sc->sc_dmac_configured = 1; 484 1.29 thorpej aprint_normal("mapping Audio 1 DMA using I/O space at 0x%lx\n", 485 1.1 kleink (unsigned long)addr); 486 1.1 kleink 487 1.58 jmcneill mutex_exit(&sc->sc_lock); 488 1.1 kleink return; 489 1.1 kleink } 490 1.58 jmcneill mutex_exit(&sc->sc_lock); 491 1.39 kent 492 1.29 thorpej aprint_error("can't map Audio 1 DMA into I/O space\n"); 493 1.24 kleink } 494 1.24 kleink 495 1.24 kleink /* ARGSUSED */ 496 1.24 kleink static int 497 1.45 christos eso_print(void *aux, const char *pnp) 498 1.24 kleink { 499 1.24 kleink 500 1.24 kleink /* Only joys can attach via this; easy. */ 501 1.24 kleink if (pnp) 502 1.28 thorpej aprint_normal("joy at %s:", pnp); 503 1.24 kleink 504 1.39 kent return UNCONF; 505 1.1 kleink } 506 1.1 kleink 507 1.1 kleink static void 508 1.39 kent eso_write_cmd(struct eso_softc *sc, uint8_t cmd) 509 1.1 kleink { 510 1.1 kleink int i; 511 1.1 kleink 512 1.1 kleink /* Poll for busy indicator to become clear. */ 513 1.1 kleink for (i = 0; i < ESO_WDR_TIMEOUT; i++) { 514 1.1 kleink if ((bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_RSR) 515 1.1 kleink & ESO_SB_RSR_BUSY) == 0) { 516 1.1 kleink bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, 517 1.1 kleink ESO_SB_WDR, cmd); 518 1.1 kleink return; 519 1.1 kleink } else { 520 1.1 kleink delay(10); 521 1.1 kleink } 522 1.1 kleink } 523 1.1 kleink 524 1.62 chs printf("%s: WDR timeout\n", device_xname(sc->sc_dev)); 525 1.1 kleink return; 526 1.1 kleink } 527 1.1 kleink 528 1.1 kleink /* Write to a controller register */ 529 1.1 kleink static void 530 1.39 kent eso_write_ctlreg(struct eso_softc *sc, uint8_t reg, uint8_t val) 531 1.1 kleink { 532 1.1 kleink 533 1.1 kleink /* DPRINTF(("ctlreg 0x%02x = 0x%02x\n", reg, val)); */ 534 1.39 kent 535 1.1 kleink eso_write_cmd(sc, reg); 536 1.1 kleink eso_write_cmd(sc, val); 537 1.1 kleink } 538 1.1 kleink 539 1.1 kleink /* Read out the Read Data Register */ 540 1.1 kleink static uint8_t 541 1.39 kent eso_read_rdr(struct eso_softc *sc) 542 1.1 kleink { 543 1.1 kleink int i; 544 1.1 kleink 545 1.1 kleink for (i = 0; i < ESO_RDR_TIMEOUT; i++) { 546 1.1 kleink if (bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, 547 1.1 kleink ESO_SB_RBSR) & ESO_SB_RBSR_RDAV) { 548 1.1 kleink return (bus_space_read_1(sc->sc_sb_iot, 549 1.1 kleink sc->sc_sb_ioh, ESO_SB_RDR)); 550 1.1 kleink } else { 551 1.1 kleink delay(10); 552 1.1 kleink } 553 1.1 kleink } 554 1.1 kleink 555 1.62 chs printf("%s: RDR timeout\n", device_xname(sc->sc_dev)); 556 1.1 kleink return (-1); 557 1.1 kleink } 558 1.1 kleink 559 1.1 kleink static uint8_t 560 1.39 kent eso_read_ctlreg(struct eso_softc *sc, uint8_t reg) 561 1.1 kleink { 562 1.1 kleink 563 1.1 kleink eso_write_cmd(sc, ESO_CMD_RCR); 564 1.1 kleink eso_write_cmd(sc, reg); 565 1.39 kent return eso_read_rdr(sc); 566 1.1 kleink } 567 1.1 kleink 568 1.1 kleink static void 569 1.39 kent eso_write_mixreg(struct eso_softc *sc, uint8_t reg, uint8_t val) 570 1.1 kleink { 571 1.58 jmcneill 572 1.58 jmcneill KASSERT(mutex_owned(&sc->sc_intr_lock)); 573 1.1 kleink 574 1.1 kleink /* DPRINTF(("mixreg 0x%02x = 0x%02x\n", reg, val)); */ 575 1.39 kent 576 1.1 kleink bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERADDR, reg); 577 1.1 kleink bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERDATA, val); 578 1.1 kleink } 579 1.1 kleink 580 1.1 kleink static uint8_t 581 1.39 kent eso_read_mixreg(struct eso_softc *sc, uint8_t reg) 582 1.1 kleink { 583 1.1 kleink uint8_t val; 584 1.1 kleink 585 1.58 jmcneill KASSERT(mutex_owned(&sc->sc_intr_lock)); 586 1.58 jmcneill 587 1.1 kleink bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERADDR, reg); 588 1.1 kleink val = bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERDATA); 589 1.39 kent 590 1.39 kent return val; 591 1.1 kleink } 592 1.1 kleink 593 1.1 kleink static int 594 1.39 kent eso_intr(void *hdl) 595 1.1 kleink { 596 1.52 xtraeme struct eso_softc *sc = hdl; 597 1.52 xtraeme #if NMPU > 0 598 1.52 xtraeme struct mpu_softc *sc_mpu = device_private(sc->sc_mpudev); 599 1.52 xtraeme #endif 600 1.1 kleink uint8_t irqctl; 601 1.1 kleink 602 1.58 jmcneill mutex_spin_enter(&sc->sc_intr_lock); 603 1.58 jmcneill 604 1.1 kleink irqctl = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ESO_IO_IRQCTL); 605 1.1 kleink 606 1.1 kleink /* If it wasn't ours, that's all she wrote. */ 607 1.5 kleink if ((irqctl & (ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ | 608 1.58 jmcneill ESO_IO_IRQCTL_HVIRQ | ESO_IO_IRQCTL_MPUIRQ)) == 0) { 609 1.58 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 610 1.39 kent return 0; 611 1.58 jmcneill } 612 1.39 kent 613 1.1 kleink if (irqctl & ESO_IO_IRQCTL_A1IRQ) { 614 1.1 kleink /* Clear interrupt. */ 615 1.1 kleink (void)bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, 616 1.1 kleink ESO_SB_RBSR); 617 1.39 kent 618 1.1 kleink if (sc->sc_rintr) 619 1.1 kleink sc->sc_rintr(sc->sc_rarg); 620 1.1 kleink else 621 1.58 jmcneill cv_broadcast(&sc->sc_rcv); 622 1.1 kleink } 623 1.1 kleink 624 1.1 kleink if (irqctl & ESO_IO_IRQCTL_A2IRQ) { 625 1.1 kleink /* 626 1.1 kleink * Clear the A2 IRQ latch: the cached value reflects the 627 1.1 kleink * current DAC settings with the IRQ latch bit not set. 628 1.1 kleink */ 629 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_A2C2, sc->sc_a2c2); 630 1.1 kleink 631 1.1 kleink if (sc->sc_pintr) 632 1.1 kleink sc->sc_pintr(sc->sc_parg); 633 1.1 kleink else 634 1.58 jmcneill cv_broadcast(&sc->sc_pcv); 635 1.1 kleink } 636 1.1 kleink 637 1.14 kleink if (irqctl & ESO_IO_IRQCTL_HVIRQ) { 638 1.14 kleink /* Clear interrupt. */ 639 1.14 kleink eso_write_mixreg(sc, ESO_MIXREG_CHVIR, ESO_MIXREG_CHVIR_CHVIR); 640 1.14 kleink 641 1.14 kleink /* 642 1.14 kleink * Raise a flag to cause a lazy update of the in-softc gain 643 1.14 kleink * values the next time the software mixer is read to keep 644 1.14 kleink * interrupt service cost low. ~0 cannot occur otherwise 645 1.14 kleink * as the master volume has a precision of 6 bits only. 646 1.14 kleink */ 647 1.14 kleink sc->sc_gain[ESO_MASTER_VOL][ESO_LEFT] = (uint8_t)~0; 648 1.14 kleink } 649 1.14 kleink 650 1.5 kleink #if NMPU > 0 651 1.52 xtraeme if ((irqctl & ESO_IO_IRQCTL_MPUIRQ) && sc_mpu != NULL) 652 1.52 xtraeme mpu_intr(sc_mpu); 653 1.1 kleink #endif 654 1.39 kent 655 1.58 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 656 1.39 kent return 1; 657 1.1 kleink } 658 1.1 kleink 659 1.1 kleink /* Perform a software reset, including DMA FIFOs. */ 660 1.1 kleink static int 661 1.39 kent eso_reset(struct eso_softc *sc) 662 1.1 kleink { 663 1.1 kleink int i; 664 1.1 kleink 665 1.1 kleink bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_RESET, 666 1.1 kleink ESO_SB_RESET_SW | ESO_SB_RESET_FIFO); 667 1.1 kleink /* `Delay' suggested in the data sheet. */ 668 1.1 kleink (void)bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_STATUS); 669 1.1 kleink bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_RESET, 0); 670 1.1 kleink 671 1.1 kleink /* Wait for reset to take effect. */ 672 1.1 kleink for (i = 0; i < ESO_RESET_TIMEOUT; i++) { 673 1.1 kleink /* Poll for data to become available. */ 674 1.1 kleink if ((bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, 675 1.1 kleink ESO_SB_RBSR) & ESO_SB_RBSR_RDAV) != 0 && 676 1.1 kleink bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, 677 1.1 kleink ESO_SB_RDR) == ESO_SB_RDR_RESETMAGIC) { 678 1.1 kleink 679 1.1 kleink /* Activate Solo-1 extension commands. */ 680 1.1 kleink eso_write_cmd(sc, ESO_CMD_EXTENB); 681 1.1 kleink /* Reset mixer registers. */ 682 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_RESET, 683 1.1 kleink ESO_MIXREG_RESET_RESET); 684 1.1 kleink 685 1.39 kent return 0; 686 1.1 kleink } else { 687 1.1 kleink delay(1000); 688 1.1 kleink } 689 1.1 kleink } 690 1.39 kent 691 1.62 chs printf("%s: reset timeout\n", device_xname(sc->sc_dev)); 692 1.39 kent return -1; 693 1.1 kleink } 694 1.1 kleink 695 1.1 kleink static int 696 1.70 isaki eso_query_format(void *hdl, audio_format_query_t *afp) 697 1.1 kleink { 698 1.39 kent 699 1.70 isaki return audio_query_format(eso_formats, ESO_NFORMATS, afp); 700 1.1 kleink } 701 1.1 kleink 702 1.1 kleink static int 703 1.70 isaki eso_set_format(void *hdl, int setmode, 704 1.70 isaki const audio_params_t *play, const audio_params_t *rec, 705 1.70 isaki audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) 706 1.1 kleink { 707 1.39 kent struct eso_softc *sc; 708 1.70 isaki const struct audio_params *p; 709 1.70 isaki int mode; 710 1.1 kleink unsigned int srg, fltdiv; 711 1.38 kent 712 1.39 kent sc = hdl; 713 1.38 kent for (mode = AUMODE_RECORD; mode != -1; 714 1.1 kleink mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 715 1.1 kleink if ((setmode & mode) == 0) 716 1.1 kleink continue; 717 1.1 kleink 718 1.1 kleink p = (mode == AUMODE_PLAY) ? play : rec; 719 1.1 kleink 720 1.70 isaki /* We use a few fixed rate which doesn't have rounding error. */ 721 1.70 isaki switch (p->sample_rate) { 722 1.70 isaki case 8000: 723 1.70 isaki case 48000: 724 1.70 isaki srg = (128 - ESO_CLK1 / p->sample_rate); 725 1.70 isaki srg |= ESO_CLK1_SELECT; 726 1.70 isaki break; 727 1.70 isaki case 22050: 728 1.70 isaki case 44100: 729 1.70 isaki srg = (128 - ESO_CLK0 / p->sample_rate); 730 1.70 isaki break; 731 1.70 isaki default: 732 1.70 isaki /* NOTREACHED */ 733 1.39 kent return EINVAL; 734 1.70 isaki } 735 1.1 kleink /* Roll-off frequency of 87%, as in the ES1888 driver. */ 736 1.70 isaki fltdiv = 256 - 200279L / p->sample_rate; 737 1.58 jmcneill 738 1.58 jmcneill mutex_spin_enter(&sc->sc_intr_lock); 739 1.1 kleink if (mode == AUMODE_RECORD) { 740 1.1 kleink /* Audio 1 */ 741 1.1 kleink DPRINTF(("A1 srg 0x%02x fdiv 0x%02x\n", srg, fltdiv)); 742 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_SRG, srg); 743 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_FLTDIV, fltdiv); 744 1.1 kleink } else { 745 1.1 kleink /* Audio 2 */ 746 1.1 kleink DPRINTF(("A2 srg 0x%02x fdiv 0x%02x\n", srg, fltdiv)); 747 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_A2SRG, srg); 748 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_A2FLTDIV, fltdiv); 749 1.1 kleink } 750 1.58 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 751 1.1 kleink } 752 1.1 kleink 753 1.39 kent return 0; 754 1.1 kleink } 755 1.1 kleink 756 1.1 kleink static int 757 1.45 christos eso_round_blocksize(void *hdl, int blk, int mode, 758 1.45 christos const audio_params_t *param) 759 1.1 kleink { 760 1.1 kleink 761 1.39 kent return blk & -32; /* keep good alignment; at least 16 req'd */ 762 1.1 kleink } 763 1.1 kleink 764 1.1 kleink static int 765 1.39 kent eso_halt_output(void *hdl) 766 1.1 kleink { 767 1.39 kent struct eso_softc *sc; 768 1.58 jmcneill int error; 769 1.39 kent 770 1.39 kent sc = hdl; 771 1.62 chs DPRINTF(("%s: halt_output\n", device_xname(sc->sc_dev))); 772 1.1 kleink 773 1.1 kleink /* 774 1.1 kleink * Disable auto-initialize DMA, allowing the FIFO to drain and then 775 1.1 kleink * stop. The interrupt callback pointer is cleared at this 776 1.1 kleink * point so that an outstanding FIFO interrupt for the remaining data 777 1.1 kleink * will be acknowledged without further processing. 778 1.1 kleink * 779 1.1 kleink * This does not immediately `abort' an operation in progress (c.f. 780 1.1 kleink * audio(9)) but is the method to leave the FIFO behind in a clean 781 1.1 kleink * state with the least hair. (Besides, that item needs to be 782 1.1 kleink * rephrased for trigger_*()-based DMA environments.) 783 1.1 kleink */ 784 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_A2C1, 785 1.1 kleink ESO_MIXREG_A2C1_FIFOENB | ESO_MIXREG_A2C1_DMAENB); 786 1.1 kleink bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM, 787 1.1 kleink ESO_IO_A2DMAM_DMAENB); 788 1.1 kleink 789 1.1 kleink sc->sc_pintr = NULL; 790 1.58 jmcneill error = cv_timedwait_sig(&sc->sc_pcv, &sc->sc_intr_lock, sc->sc_pdrain); 791 1.39 kent 792 1.1 kleink /* Shut down DMA completely. */ 793 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_A2C1, 0); 794 1.1 kleink bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM, 0); 795 1.39 kent 796 1.39 kent return error == EWOULDBLOCK ? 0 : error; 797 1.1 kleink } 798 1.1 kleink 799 1.1 kleink static int 800 1.39 kent eso_halt_input(void *hdl) 801 1.1 kleink { 802 1.39 kent struct eso_softc *sc; 803 1.58 jmcneill int error; 804 1.39 kent 805 1.39 kent sc = hdl; 806 1.62 chs DPRINTF(("%s: halt_input\n", device_xname(sc->sc_dev))); 807 1.1 kleink 808 1.1 kleink /* Just like eso_halt_output(), but for Audio 1. */ 809 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_A1C2, 810 1.1 kleink ESO_CTLREG_A1C2_READ | ESO_CTLREG_A1C2_ADC | 811 1.1 kleink ESO_CTLREG_A1C2_DMAENB); 812 1.1 kleink bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MODE, 813 1.1 kleink DMA37MD_WRITE | DMA37MD_DEMAND); 814 1.1 kleink 815 1.1 kleink sc->sc_rintr = NULL; 816 1.58 jmcneill error = cv_timedwait_sig(&sc->sc_rcv, &sc->sc_intr_lock, sc->sc_rdrain); 817 1.1 kleink 818 1.1 kleink /* Shut down DMA completely. */ 819 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_A1C2, 820 1.1 kleink ESO_CTLREG_A1C2_READ | ESO_CTLREG_A1C2_ADC); 821 1.1 kleink bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK, 822 1.1 kleink ESO_DMAC_MASK_MASK); 823 1.1 kleink 824 1.39 kent return error == EWOULDBLOCK ? 0 : error; 825 1.1 kleink } 826 1.1 kleink 827 1.1 kleink static int 828 1.39 kent eso_getdev(void *hdl, struct audio_device *retp) 829 1.1 kleink { 830 1.39 kent struct eso_softc *sc; 831 1.1 kleink 832 1.39 kent sc = hdl; 833 1.1 kleink strncpy(retp->name, "ESS Solo-1", sizeof (retp->name)); 834 1.1 kleink snprintf(retp->version, sizeof (retp->version), "0x%02x", 835 1.1 kleink sc->sc_revision); 836 1.9 cgd if (sc->sc_revision < 837 1.1 kleink sizeof (eso_rev2model) / sizeof (eso_rev2model[0])) 838 1.1 kleink strncpy(retp->config, eso_rev2model[sc->sc_revision], 839 1.1 kleink sizeof (retp->config)); 840 1.1 kleink else 841 1.1 kleink strncpy(retp->config, "unknown", sizeof (retp->config)); 842 1.39 kent 843 1.39 kent return 0; 844 1.1 kleink } 845 1.1 kleink 846 1.1 kleink static int 847 1.39 kent eso_set_port(void *hdl, mixer_ctrl_t *cp) 848 1.1 kleink { 849 1.39 kent struct eso_softc *sc; 850 1.1 kleink unsigned int lgain, rgain; 851 1.1 kleink uint8_t tmp; 852 1.58 jmcneill int error; 853 1.39 kent 854 1.39 kent sc = hdl; 855 1.58 jmcneill error = 0; 856 1.58 jmcneill 857 1.58 jmcneill mutex_spin_enter(&sc->sc_intr_lock); 858 1.58 jmcneill 859 1.1 kleink switch (cp->dev) { 860 1.1 kleink case ESO_DAC_PLAY_VOL: 861 1.1 kleink case ESO_MIC_PLAY_VOL: 862 1.1 kleink case ESO_LINE_PLAY_VOL: 863 1.1 kleink case ESO_SYNTH_PLAY_VOL: 864 1.1 kleink case ESO_CD_PLAY_VOL: 865 1.1 kleink case ESO_AUXB_PLAY_VOL: 866 1.1 kleink case ESO_RECORD_VOL: 867 1.1 kleink case ESO_DAC_REC_VOL: 868 1.1 kleink case ESO_MIC_REC_VOL: 869 1.1 kleink case ESO_LINE_REC_VOL: 870 1.1 kleink case ESO_SYNTH_REC_VOL: 871 1.1 kleink case ESO_CD_REC_VOL: 872 1.1 kleink case ESO_AUXB_REC_VOL: 873 1.58 jmcneill if (cp->type != AUDIO_MIXER_VALUE) { 874 1.58 jmcneill error = EINVAL; 875 1.58 jmcneill break; 876 1.58 jmcneill } 877 1.39 kent 878 1.1 kleink /* 879 1.1 kleink * Stereo-capable mixer ports: if we get a single-channel 880 1.1 kleink * gain value passed in, then we duplicate it to both left 881 1.1 kleink * and right channels. 882 1.1 kleink */ 883 1.1 kleink switch (cp->un.value.num_channels) { 884 1.1 kleink case 1: 885 1.1 kleink lgain = rgain = ESO_GAIN_TO_4BIT( 886 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 887 1.1 kleink break; 888 1.1 kleink case 2: 889 1.1 kleink lgain = ESO_GAIN_TO_4BIT( 890 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]); 891 1.1 kleink rgain = ESO_GAIN_TO_4BIT( 892 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); 893 1.1 kleink break; 894 1.1 kleink default: 895 1.58 jmcneill error = EINVAL; 896 1.58 jmcneill break; 897 1.1 kleink } 898 1.1 kleink 899 1.58 jmcneill if (!error) { 900 1.58 jmcneill sc->sc_gain[cp->dev][ESO_LEFT] = lgain; 901 1.58 jmcneill sc->sc_gain[cp->dev][ESO_RIGHT] = rgain; 902 1.58 jmcneill eso_set_gain(sc, cp->dev); 903 1.58 jmcneill } 904 1.1 kleink break; 905 1.1 kleink 906 1.1 kleink case ESO_MASTER_VOL: 907 1.58 jmcneill if (cp->type != AUDIO_MIXER_VALUE) { 908 1.58 jmcneill error = EINVAL; 909 1.58 jmcneill break; 910 1.58 jmcneill } 911 1.1 kleink 912 1.1 kleink /* Like above, but a precision of 6 bits. */ 913 1.1 kleink switch (cp->un.value.num_channels) { 914 1.1 kleink case 1: 915 1.1 kleink lgain = rgain = ESO_GAIN_TO_6BIT( 916 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 917 1.1 kleink break; 918 1.1 kleink case 2: 919 1.1 kleink lgain = ESO_GAIN_TO_6BIT( 920 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]); 921 1.1 kleink rgain = ESO_GAIN_TO_6BIT( 922 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); 923 1.1 kleink break; 924 1.1 kleink default: 925 1.58 jmcneill error = EINVAL; 926 1.58 jmcneill break; 927 1.1 kleink } 928 1.1 kleink 929 1.58 jmcneill if (!error) { 930 1.58 jmcneill sc->sc_gain[cp->dev][ESO_LEFT] = lgain; 931 1.58 jmcneill sc->sc_gain[cp->dev][ESO_RIGHT] = rgain; 932 1.58 jmcneill eso_set_gain(sc, cp->dev); 933 1.58 jmcneill } 934 1.1 kleink break; 935 1.1 kleink 936 1.1 kleink case ESO_SPATIALIZER: 937 1.1 kleink if (cp->type != AUDIO_MIXER_VALUE || 938 1.58 jmcneill cp->un.value.num_channels != 1) { 939 1.58 jmcneill error = EINVAL; 940 1.58 jmcneill break; 941 1.58 jmcneill } 942 1.1 kleink 943 1.1 kleink sc->sc_gain[cp->dev][ESO_LEFT] = 944 1.1 kleink sc->sc_gain[cp->dev][ESO_RIGHT] = 945 1.1 kleink ESO_GAIN_TO_6BIT( 946 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 947 1.1 kleink eso_set_gain(sc, cp->dev); 948 1.1 kleink break; 949 1.39 kent 950 1.1 kleink case ESO_MONO_PLAY_VOL: 951 1.1 kleink case ESO_MONO_REC_VOL: 952 1.1 kleink if (cp->type != AUDIO_MIXER_VALUE || 953 1.58 jmcneill cp->un.value.num_channels != 1) { 954 1.58 jmcneill error = EINVAL; 955 1.58 jmcneill break; 956 1.58 jmcneill } 957 1.1 kleink 958 1.1 kleink sc->sc_gain[cp->dev][ESO_LEFT] = 959 1.1 kleink sc->sc_gain[cp->dev][ESO_RIGHT] = 960 1.1 kleink ESO_GAIN_TO_4BIT( 961 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 962 1.1 kleink eso_set_gain(sc, cp->dev); 963 1.1 kleink break; 964 1.39 kent 965 1.1 kleink case ESO_PCSPEAKER_VOL: 966 1.1 kleink if (cp->type != AUDIO_MIXER_VALUE || 967 1.58 jmcneill cp->un.value.num_channels != 1) { 968 1.58 jmcneill error = EINVAL; 969 1.58 jmcneill break; 970 1.58 jmcneill } 971 1.1 kleink 972 1.1 kleink sc->sc_gain[cp->dev][ESO_LEFT] = 973 1.1 kleink sc->sc_gain[cp->dev][ESO_RIGHT] = 974 1.1 kleink ESO_GAIN_TO_3BIT( 975 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 976 1.1 kleink eso_set_gain(sc, cp->dev); 977 1.1 kleink break; 978 1.1 kleink 979 1.1 kleink case ESO_SPATIALIZER_ENABLE: 980 1.58 jmcneill if (cp->type != AUDIO_MIXER_ENUM) { 981 1.58 jmcneill error = EINVAL; 982 1.58 jmcneill break; 983 1.58 jmcneill } 984 1.1 kleink 985 1.1 kleink sc->sc_spatializer = (cp->un.ord != 0); 986 1.1 kleink 987 1.1 kleink tmp = eso_read_mixreg(sc, ESO_MIXREG_SPAT); 988 1.1 kleink if (sc->sc_spatializer) 989 1.1 kleink tmp |= ESO_MIXREG_SPAT_ENB; 990 1.1 kleink else 991 1.1 kleink tmp &= ~ESO_MIXREG_SPAT_ENB; 992 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_SPAT, 993 1.1 kleink tmp | ESO_MIXREG_SPAT_RSTREL); 994 1.1 kleink break; 995 1.12 kleink 996 1.12 kleink case ESO_MASTER_MUTE: 997 1.58 jmcneill if (cp->type != AUDIO_MIXER_ENUM) { 998 1.58 jmcneill error = EINVAL; 999 1.58 jmcneill break; 1000 1.58 jmcneill } 1001 1.12 kleink 1002 1.12 kleink sc->sc_mvmute = (cp->un.ord != 0); 1003 1.12 kleink 1004 1.12 kleink if (sc->sc_mvmute) { 1005 1.12 kleink eso_write_mixreg(sc, ESO_MIXREG_LMVM, 1006 1.12 kleink eso_read_mixreg(sc, ESO_MIXREG_LMVM) | 1007 1.12 kleink ESO_MIXREG_LMVM_MUTE); 1008 1.12 kleink eso_write_mixreg(sc, ESO_MIXREG_RMVM, 1009 1.12 kleink eso_read_mixreg(sc, ESO_MIXREG_RMVM) | 1010 1.12 kleink ESO_MIXREG_RMVM_MUTE); 1011 1.39 kent } else { 1012 1.12 kleink eso_write_mixreg(sc, ESO_MIXREG_LMVM, 1013 1.12 kleink eso_read_mixreg(sc, ESO_MIXREG_LMVM) & 1014 1.12 kleink ~ESO_MIXREG_LMVM_MUTE); 1015 1.12 kleink eso_write_mixreg(sc, ESO_MIXREG_RMVM, 1016 1.12 kleink eso_read_mixreg(sc, ESO_MIXREG_RMVM) & 1017 1.12 kleink ~ESO_MIXREG_RMVM_MUTE); 1018 1.12 kleink } 1019 1.12 kleink break; 1020 1.39 kent 1021 1.1 kleink case ESO_MONOOUT_SOURCE: 1022 1.58 jmcneill if (cp->type != AUDIO_MIXER_ENUM) { 1023 1.58 jmcneill error = EINVAL; 1024 1.58 jmcneill break; 1025 1.58 jmcneill } 1026 1.1 kleink 1027 1.58 jmcneill error = eso_set_monooutsrc(sc, cp->un.ord); 1028 1.58 jmcneill break; 1029 1.34 kleink 1030 1.34 kleink case ESO_MONOIN_BYPASS: 1031 1.58 jmcneill if (cp->type != AUDIO_MIXER_ENUM) { 1032 1.58 jmcneill error = EINVAL; 1033 1.58 jmcneill break; 1034 1.58 jmcneill } 1035 1.34 kleink 1036 1.58 jmcneill error = (eso_set_monoinbypass(sc, cp->un.ord)); 1037 1.58 jmcneill break; 1038 1.34 kleink 1039 1.1 kleink case ESO_RECORD_MONITOR: 1040 1.58 jmcneill if (cp->type != AUDIO_MIXER_ENUM) { 1041 1.58 jmcneill error = EINVAL; 1042 1.58 jmcneill break; 1043 1.58 jmcneill } 1044 1.1 kleink 1045 1.1 kleink sc->sc_recmon = (cp->un.ord != 0); 1046 1.39 kent 1047 1.1 kleink tmp = eso_read_ctlreg(sc, ESO_CTLREG_ACTL); 1048 1.1 kleink if (sc->sc_recmon) 1049 1.1 kleink tmp |= ESO_CTLREG_ACTL_RECMON; 1050 1.1 kleink else 1051 1.1 kleink tmp &= ~ESO_CTLREG_ACTL_RECMON; 1052 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_ACTL, tmp); 1053 1.1 kleink break; 1054 1.1 kleink 1055 1.1 kleink case ESO_RECORD_SOURCE: 1056 1.58 jmcneill if (cp->type != AUDIO_MIXER_ENUM) { 1057 1.58 jmcneill error = EINVAL; 1058 1.58 jmcneill break; 1059 1.58 jmcneill } 1060 1.1 kleink 1061 1.58 jmcneill error = eso_set_recsrc(sc, cp->un.ord); 1062 1.58 jmcneill break; 1063 1.1 kleink 1064 1.1 kleink case ESO_MIC_PREAMP: 1065 1.58 jmcneill if (cp->type != AUDIO_MIXER_ENUM) { 1066 1.58 jmcneill error = EINVAL; 1067 1.58 jmcneill break; 1068 1.58 jmcneill } 1069 1.39 kent 1070 1.58 jmcneill error = eso_set_preamp(sc, cp->un.ord); 1071 1.58 jmcneill break; 1072 1.1 kleink 1073 1.1 kleink default: 1074 1.58 jmcneill error = EINVAL; 1075 1.58 jmcneill break; 1076 1.1 kleink } 1077 1.39 kent 1078 1.58 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 1079 1.58 jmcneill return error; 1080 1.1 kleink } 1081 1.1 kleink 1082 1.1 kleink static int 1083 1.39 kent eso_get_port(void *hdl, mixer_ctrl_t *cp) 1084 1.1 kleink { 1085 1.39 kent struct eso_softc *sc; 1086 1.1 kleink 1087 1.39 kent sc = hdl; 1088 1.58 jmcneill 1089 1.58 jmcneill mutex_spin_enter(&sc->sc_intr_lock); 1090 1.58 jmcneill 1091 1.1 kleink switch (cp->dev) { 1092 1.14 kleink case ESO_MASTER_VOL: 1093 1.14 kleink /* Reload from mixer after hardware volume control use. */ 1094 1.14 kleink if (sc->sc_gain[cp->dev][ESO_LEFT] == (uint8_t)~0) 1095 1.14 kleink eso_reload_master_vol(sc); 1096 1.14 kleink /* FALLTHROUGH */ 1097 1.1 kleink case ESO_DAC_PLAY_VOL: 1098 1.1 kleink case ESO_MIC_PLAY_VOL: 1099 1.1 kleink case ESO_LINE_PLAY_VOL: 1100 1.1 kleink case ESO_SYNTH_PLAY_VOL: 1101 1.1 kleink case ESO_CD_PLAY_VOL: 1102 1.1 kleink case ESO_AUXB_PLAY_VOL: 1103 1.1 kleink case ESO_RECORD_VOL: 1104 1.1 kleink case ESO_DAC_REC_VOL: 1105 1.1 kleink case ESO_MIC_REC_VOL: 1106 1.1 kleink case ESO_LINE_REC_VOL: 1107 1.1 kleink case ESO_SYNTH_REC_VOL: 1108 1.1 kleink case ESO_CD_REC_VOL: 1109 1.1 kleink case ESO_AUXB_REC_VOL: 1110 1.1 kleink /* 1111 1.1 kleink * Stereo-capable ports: if a single-channel query is made, 1112 1.1 kleink * just return the left channel's value (since single-channel 1113 1.1 kleink * settings themselves are applied to both channels). 1114 1.1 kleink */ 1115 1.1 kleink switch (cp->un.value.num_channels) { 1116 1.1 kleink case 1: 1117 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1118 1.1 kleink sc->sc_gain[cp->dev][ESO_LEFT]; 1119 1.1 kleink break; 1120 1.1 kleink case 2: 1121 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1122 1.1 kleink sc->sc_gain[cp->dev][ESO_LEFT]; 1123 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1124 1.1 kleink sc->sc_gain[cp->dev][ESO_RIGHT]; 1125 1.1 kleink break; 1126 1.1 kleink default: 1127 1.58 jmcneill break; 1128 1.1 kleink } 1129 1.1 kleink break; 1130 1.39 kent 1131 1.1 kleink case ESO_MONO_PLAY_VOL: 1132 1.1 kleink case ESO_PCSPEAKER_VOL: 1133 1.1 kleink case ESO_MONO_REC_VOL: 1134 1.1 kleink case ESO_SPATIALIZER: 1135 1.58 jmcneill if (cp->un.value.num_channels != 1) { 1136 1.58 jmcneill break; 1137 1.58 jmcneill } 1138 1.1 kleink cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1139 1.1 kleink sc->sc_gain[cp->dev][ESO_LEFT]; 1140 1.1 kleink break; 1141 1.1 kleink 1142 1.1 kleink case ESO_RECORD_MONITOR: 1143 1.1 kleink cp->un.ord = sc->sc_recmon; 1144 1.1 kleink break; 1145 1.39 kent 1146 1.1 kleink case ESO_RECORD_SOURCE: 1147 1.1 kleink cp->un.ord = sc->sc_recsrc; 1148 1.1 kleink break; 1149 1.1 kleink 1150 1.1 kleink case ESO_MONOOUT_SOURCE: 1151 1.1 kleink cp->un.ord = sc->sc_monooutsrc; 1152 1.1 kleink break; 1153 1.34 kleink 1154 1.34 kleink case ESO_MONOIN_BYPASS: 1155 1.34 kleink cp->un.ord = sc->sc_monoinbypass; 1156 1.34 kleink break; 1157 1.39 kent 1158 1.1 kleink case ESO_SPATIALIZER_ENABLE: 1159 1.1 kleink cp->un.ord = sc->sc_spatializer; 1160 1.1 kleink break; 1161 1.39 kent 1162 1.1 kleink case ESO_MIC_PREAMP: 1163 1.1 kleink cp->un.ord = sc->sc_preamp; 1164 1.1 kleink break; 1165 1.1 kleink 1166 1.12 kleink case ESO_MASTER_MUTE: 1167 1.14 kleink /* Reload from mixer after hardware volume control use. */ 1168 1.48 kleink if (sc->sc_gain[ESO_MASTER_VOL][ESO_LEFT] == (uint8_t)~0) 1169 1.48 kleink eso_reload_master_vol(sc); 1170 1.12 kleink cp->un.ord = sc->sc_mvmute; 1171 1.12 kleink break; 1172 1.12 kleink 1173 1.1 kleink default: 1174 1.58 jmcneill break; 1175 1.1 kleink } 1176 1.1 kleink 1177 1.58 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 1178 1.39 kent return 0; 1179 1.1 kleink } 1180 1.1 kleink 1181 1.1 kleink static int 1182 1.45 christos eso_query_devinfo(void *hdl, mixer_devinfo_t *dip) 1183 1.1 kleink { 1184 1.1 kleink 1185 1.1 kleink switch (dip->index) { 1186 1.1 kleink case ESO_DAC_PLAY_VOL: 1187 1.1 kleink dip->mixer_class = ESO_INPUT_CLASS; 1188 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1189 1.1 kleink strcpy(dip->label.name, AudioNdac); 1190 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1191 1.1 kleink dip->un.v.num_channels = 2; 1192 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1193 1.1 kleink break; 1194 1.1 kleink case ESO_MIC_PLAY_VOL: 1195 1.1 kleink dip->mixer_class = ESO_INPUT_CLASS; 1196 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1197 1.1 kleink strcpy(dip->label.name, AudioNmicrophone); 1198 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1199 1.1 kleink dip->un.v.num_channels = 2; 1200 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1201 1.1 kleink break; 1202 1.1 kleink case ESO_LINE_PLAY_VOL: 1203 1.1 kleink dip->mixer_class = ESO_INPUT_CLASS; 1204 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1205 1.1 kleink strcpy(dip->label.name, AudioNline); 1206 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1207 1.1 kleink dip->un.v.num_channels = 2; 1208 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1209 1.1 kleink break; 1210 1.1 kleink case ESO_SYNTH_PLAY_VOL: 1211 1.1 kleink dip->mixer_class = ESO_INPUT_CLASS; 1212 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1213 1.1 kleink strcpy(dip->label.name, AudioNfmsynth); 1214 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1215 1.1 kleink dip->un.v.num_channels = 2; 1216 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1217 1.1 kleink break; 1218 1.1 kleink case ESO_MONO_PLAY_VOL: 1219 1.1 kleink dip->mixer_class = ESO_INPUT_CLASS; 1220 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1221 1.1 kleink strcpy(dip->label.name, "mono_in"); 1222 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1223 1.1 kleink dip->un.v.num_channels = 1; 1224 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1225 1.1 kleink break; 1226 1.1 kleink case ESO_CD_PLAY_VOL: 1227 1.1 kleink dip->mixer_class = ESO_INPUT_CLASS; 1228 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1229 1.1 kleink strcpy(dip->label.name, AudioNcd); 1230 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1231 1.1 kleink dip->un.v.num_channels = 2; 1232 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1233 1.1 kleink break; 1234 1.1 kleink case ESO_AUXB_PLAY_VOL: 1235 1.1 kleink dip->mixer_class = ESO_INPUT_CLASS; 1236 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1237 1.1 kleink strcpy(dip->label.name, "auxb"); 1238 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1239 1.1 kleink dip->un.v.num_channels = 2; 1240 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1241 1.1 kleink break; 1242 1.1 kleink 1243 1.1 kleink case ESO_MIC_PREAMP: 1244 1.1 kleink dip->mixer_class = ESO_MICROPHONE_CLASS; 1245 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1246 1.1 kleink strcpy(dip->label.name, AudioNpreamp); 1247 1.1 kleink dip->type = AUDIO_MIXER_ENUM; 1248 1.1 kleink dip->un.e.num_mem = 2; 1249 1.1 kleink strcpy(dip->un.e.member[0].label.name, AudioNoff); 1250 1.1 kleink dip->un.e.member[0].ord = 0; 1251 1.1 kleink strcpy(dip->un.e.member[1].label.name, AudioNon); 1252 1.1 kleink dip->un.e.member[1].ord = 1; 1253 1.1 kleink break; 1254 1.1 kleink case ESO_MICROPHONE_CLASS: 1255 1.1 kleink dip->mixer_class = ESO_MICROPHONE_CLASS; 1256 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1257 1.1 kleink strcpy(dip->label.name, AudioNmicrophone); 1258 1.1 kleink dip->type = AUDIO_MIXER_CLASS; 1259 1.1 kleink break; 1260 1.39 kent 1261 1.1 kleink case ESO_INPUT_CLASS: 1262 1.1 kleink dip->mixer_class = ESO_INPUT_CLASS; 1263 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1264 1.1 kleink strcpy(dip->label.name, AudioCinputs); 1265 1.1 kleink dip->type = AUDIO_MIXER_CLASS; 1266 1.1 kleink break; 1267 1.39 kent 1268 1.1 kleink case ESO_MASTER_VOL: 1269 1.1 kleink dip->mixer_class = ESO_OUTPUT_CLASS; 1270 1.12 kleink dip->prev = AUDIO_MIXER_LAST; 1271 1.12 kleink dip->next = ESO_MASTER_MUTE; 1272 1.1 kleink strcpy(dip->label.name, AudioNmaster); 1273 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1274 1.1 kleink dip->un.v.num_channels = 2; 1275 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1276 1.1 kleink break; 1277 1.12 kleink case ESO_MASTER_MUTE: 1278 1.12 kleink dip->mixer_class = ESO_OUTPUT_CLASS; 1279 1.12 kleink dip->prev = ESO_MASTER_VOL; 1280 1.12 kleink dip->next = AUDIO_MIXER_LAST; 1281 1.12 kleink strcpy(dip->label.name, AudioNmute); 1282 1.12 kleink dip->type = AUDIO_MIXER_ENUM; 1283 1.12 kleink dip->un.e.num_mem = 2; 1284 1.12 kleink strcpy(dip->un.e.member[0].label.name, AudioNoff); 1285 1.12 kleink dip->un.e.member[0].ord = 0; 1286 1.12 kleink strcpy(dip->un.e.member[1].label.name, AudioNon); 1287 1.12 kleink dip->un.e.member[1].ord = 1; 1288 1.12 kleink break; 1289 1.12 kleink 1290 1.1 kleink case ESO_PCSPEAKER_VOL: 1291 1.1 kleink dip->mixer_class = ESO_OUTPUT_CLASS; 1292 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1293 1.1 kleink strcpy(dip->label.name, "pc_speaker"); 1294 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1295 1.1 kleink dip->un.v.num_channels = 1; 1296 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1297 1.1 kleink break; 1298 1.1 kleink case ESO_MONOOUT_SOURCE: 1299 1.1 kleink dip->mixer_class = ESO_OUTPUT_CLASS; 1300 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1301 1.1 kleink strcpy(dip->label.name, "mono_out"); 1302 1.1 kleink dip->type = AUDIO_MIXER_ENUM; 1303 1.1 kleink dip->un.e.num_mem = 3; 1304 1.1 kleink strcpy(dip->un.e.member[0].label.name, AudioNmute); 1305 1.1 kleink dip->un.e.member[0].ord = ESO_MIXREG_MPM_MOMUTE; 1306 1.1 kleink strcpy(dip->un.e.member[1].label.name, AudioNdac); 1307 1.1 kleink dip->un.e.member[1].ord = ESO_MIXREG_MPM_MOA2R; 1308 1.1 kleink strcpy(dip->un.e.member[2].label.name, AudioNmixerout); 1309 1.1 kleink dip->un.e.member[2].ord = ESO_MIXREG_MPM_MOREC; 1310 1.1 kleink break; 1311 1.34 kleink 1312 1.34 kleink case ESO_MONOIN_BYPASS: 1313 1.34 kleink dip->mixer_class = ESO_MONOIN_CLASS; 1314 1.34 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1315 1.34 kleink strcpy(dip->label.name, "bypass"); 1316 1.34 kleink dip->type = AUDIO_MIXER_ENUM; 1317 1.34 kleink dip->un.e.num_mem = 2; 1318 1.34 kleink strcpy(dip->un.e.member[0].label.name, AudioNoff); 1319 1.34 kleink dip->un.e.member[0].ord = 0; 1320 1.34 kleink strcpy(dip->un.e.member[1].label.name, AudioNon); 1321 1.34 kleink dip->un.e.member[1].ord = 1; 1322 1.34 kleink break; 1323 1.34 kleink case ESO_MONOIN_CLASS: 1324 1.34 kleink dip->mixer_class = ESO_MONOIN_CLASS; 1325 1.34 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1326 1.34 kleink strcpy(dip->label.name, "mono_in"); 1327 1.34 kleink dip->type = AUDIO_MIXER_CLASS; 1328 1.34 kleink break; 1329 1.34 kleink 1330 1.1 kleink case ESO_SPATIALIZER: 1331 1.1 kleink dip->mixer_class = ESO_OUTPUT_CLASS; 1332 1.1 kleink dip->prev = AUDIO_MIXER_LAST; 1333 1.1 kleink dip->next = ESO_SPATIALIZER_ENABLE; 1334 1.1 kleink strcpy(dip->label.name, AudioNspatial); 1335 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1336 1.1 kleink dip->un.v.num_channels = 1; 1337 1.1 kleink strcpy(dip->un.v.units.name, "level"); 1338 1.1 kleink break; 1339 1.1 kleink case ESO_SPATIALIZER_ENABLE: 1340 1.1 kleink dip->mixer_class = ESO_OUTPUT_CLASS; 1341 1.1 kleink dip->prev = ESO_SPATIALIZER; 1342 1.1 kleink dip->next = AUDIO_MIXER_LAST; 1343 1.1 kleink strcpy(dip->label.name, "enable"); 1344 1.1 kleink dip->type = AUDIO_MIXER_ENUM; 1345 1.1 kleink dip->un.e.num_mem = 2; 1346 1.1 kleink strcpy(dip->un.e.member[0].label.name, AudioNoff); 1347 1.1 kleink dip->un.e.member[0].ord = 0; 1348 1.1 kleink strcpy(dip->un.e.member[1].label.name, AudioNon); 1349 1.1 kleink dip->un.e.member[1].ord = 1; 1350 1.1 kleink break; 1351 1.39 kent 1352 1.1 kleink case ESO_OUTPUT_CLASS: 1353 1.1 kleink dip->mixer_class = ESO_OUTPUT_CLASS; 1354 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1355 1.1 kleink strcpy(dip->label.name, AudioCoutputs); 1356 1.1 kleink dip->type = AUDIO_MIXER_CLASS; 1357 1.1 kleink break; 1358 1.1 kleink 1359 1.1 kleink case ESO_RECORD_MONITOR: 1360 1.1 kleink dip->mixer_class = ESO_MONITOR_CLASS; 1361 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1362 1.1 kleink strcpy(dip->label.name, AudioNmute); 1363 1.1 kleink dip->type = AUDIO_MIXER_ENUM; 1364 1.1 kleink dip->un.e.num_mem = 2; 1365 1.1 kleink strcpy(dip->un.e.member[0].label.name, AudioNoff); 1366 1.1 kleink dip->un.e.member[0].ord = 0; 1367 1.1 kleink strcpy(dip->un.e.member[1].label.name, AudioNon); 1368 1.1 kleink dip->un.e.member[1].ord = 1; 1369 1.1 kleink break; 1370 1.1 kleink case ESO_MONITOR_CLASS: 1371 1.1 kleink dip->mixer_class = ESO_MONITOR_CLASS; 1372 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1373 1.1 kleink strcpy(dip->label.name, AudioCmonitor); 1374 1.1 kleink dip->type = AUDIO_MIXER_CLASS; 1375 1.1 kleink break; 1376 1.1 kleink 1377 1.1 kleink case ESO_RECORD_VOL: 1378 1.1 kleink dip->mixer_class = ESO_RECORD_CLASS; 1379 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1380 1.1 kleink strcpy(dip->label.name, AudioNrecord); 1381 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1382 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1383 1.1 kleink break; 1384 1.1 kleink case ESO_RECORD_SOURCE: 1385 1.1 kleink dip->mixer_class = ESO_RECORD_CLASS; 1386 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1387 1.1 kleink strcpy(dip->label.name, AudioNsource); 1388 1.1 kleink dip->type = AUDIO_MIXER_ENUM; 1389 1.1 kleink dip->un.e.num_mem = 4; 1390 1.1 kleink strcpy(dip->un.e.member[0].label.name, AudioNmicrophone); 1391 1.1 kleink dip->un.e.member[0].ord = ESO_MIXREG_ERS_MIC; 1392 1.1 kleink strcpy(dip->un.e.member[1].label.name, AudioNline); 1393 1.1 kleink dip->un.e.member[1].ord = ESO_MIXREG_ERS_LINE; 1394 1.1 kleink strcpy(dip->un.e.member[2].label.name, AudioNcd); 1395 1.1 kleink dip->un.e.member[2].ord = ESO_MIXREG_ERS_CD; 1396 1.1 kleink strcpy(dip->un.e.member[3].label.name, AudioNmixerout); 1397 1.1 kleink dip->un.e.member[3].ord = ESO_MIXREG_ERS_MIXER; 1398 1.1 kleink break; 1399 1.1 kleink case ESO_DAC_REC_VOL: 1400 1.1 kleink dip->mixer_class = ESO_RECORD_CLASS; 1401 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1402 1.1 kleink strcpy(dip->label.name, AudioNdac); 1403 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1404 1.1 kleink dip->un.v.num_channels = 2; 1405 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1406 1.1 kleink break; 1407 1.1 kleink case ESO_MIC_REC_VOL: 1408 1.1 kleink dip->mixer_class = ESO_RECORD_CLASS; 1409 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1410 1.1 kleink strcpy(dip->label.name, AudioNmicrophone); 1411 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1412 1.1 kleink dip->un.v.num_channels = 2; 1413 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1414 1.1 kleink break; 1415 1.1 kleink case ESO_LINE_REC_VOL: 1416 1.1 kleink dip->mixer_class = ESO_RECORD_CLASS; 1417 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1418 1.1 kleink strcpy(dip->label.name, AudioNline); 1419 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1420 1.1 kleink dip->un.v.num_channels = 2; 1421 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1422 1.1 kleink break; 1423 1.1 kleink case ESO_SYNTH_REC_VOL: 1424 1.1 kleink dip->mixer_class = ESO_RECORD_CLASS; 1425 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1426 1.1 kleink strcpy(dip->label.name, AudioNfmsynth); 1427 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1428 1.1 kleink dip->un.v.num_channels = 2; 1429 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1430 1.1 kleink break; 1431 1.1 kleink case ESO_MONO_REC_VOL: 1432 1.1 kleink dip->mixer_class = ESO_RECORD_CLASS; 1433 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1434 1.1 kleink strcpy(dip->label.name, "mono_in"); 1435 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1436 1.1 kleink dip->un.v.num_channels = 1; /* No lies */ 1437 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1438 1.1 kleink break; 1439 1.1 kleink case ESO_CD_REC_VOL: 1440 1.1 kleink dip->mixer_class = ESO_RECORD_CLASS; 1441 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1442 1.1 kleink strcpy(dip->label.name, AudioNcd); 1443 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1444 1.1 kleink dip->un.v.num_channels = 2; 1445 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1446 1.1 kleink break; 1447 1.1 kleink case ESO_AUXB_REC_VOL: 1448 1.1 kleink dip->mixer_class = ESO_RECORD_CLASS; 1449 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1450 1.1 kleink strcpy(dip->label.name, "auxb"); 1451 1.1 kleink dip->type = AUDIO_MIXER_VALUE; 1452 1.1 kleink dip->un.v.num_channels = 2; 1453 1.1 kleink strcpy(dip->un.v.units.name, AudioNvolume); 1454 1.1 kleink break; 1455 1.1 kleink case ESO_RECORD_CLASS: 1456 1.1 kleink dip->mixer_class = ESO_RECORD_CLASS; 1457 1.1 kleink dip->next = dip->prev = AUDIO_MIXER_LAST; 1458 1.1 kleink strcpy(dip->label.name, AudioCrecord); 1459 1.1 kleink dip->type = AUDIO_MIXER_CLASS; 1460 1.1 kleink break; 1461 1.39 kent 1462 1.1 kleink default: 1463 1.39 kent return ENXIO; 1464 1.1 kleink } 1465 1.1 kleink 1466 1.39 kent return 0; 1467 1.1 kleink } 1468 1.1 kleink 1469 1.1 kleink static int 1470 1.45 christos eso_allocmem(struct eso_softc *sc, size_t size, size_t align, 1471 1.58 jmcneill size_t boundary, int direction, struct eso_dma *ed) 1472 1.1 kleink { 1473 1.58 jmcneill int error; 1474 1.1 kleink 1475 1.1 kleink ed->ed_size = size; 1476 1.39 kent 1477 1.8 kleink error = bus_dmamem_alloc(ed->ed_dmat, ed->ed_size, align, boundary, 1478 1.1 kleink ed->ed_segs, sizeof (ed->ed_segs) / sizeof (ed->ed_segs[0]), 1479 1.58 jmcneill &ed->ed_nsegs, BUS_DMA_WAITOK); 1480 1.1 kleink if (error) 1481 1.1 kleink goto out; 1482 1.1 kleink 1483 1.8 kleink error = bus_dmamem_map(ed->ed_dmat, ed->ed_segs, ed->ed_nsegs, 1484 1.58 jmcneill ed->ed_size, &ed->ed_kva, BUS_DMA_WAITOK | BUS_DMA_COHERENT); 1485 1.1 kleink if (error) 1486 1.1 kleink goto free; 1487 1.1 kleink 1488 1.8 kleink error = bus_dmamap_create(ed->ed_dmat, ed->ed_size, 1, ed->ed_size, 0, 1489 1.58 jmcneill BUS_DMA_WAITOK, &ed->ed_map); 1490 1.1 kleink if (error) 1491 1.1 kleink goto unmap; 1492 1.1 kleink 1493 1.49 kleink error = bus_dmamap_load(ed->ed_dmat, ed->ed_map, ed->ed_kva, 1494 1.58 jmcneill ed->ed_size, NULL, BUS_DMA_WAITOK | 1495 1.72 joerg ((direction == AUMODE_RECORD) ? BUS_DMA_READ : BUS_DMA_WRITE)); 1496 1.1 kleink if (error) 1497 1.1 kleink goto destroy; 1498 1.1 kleink 1499 1.39 kent return 0; 1500 1.1 kleink 1501 1.1 kleink destroy: 1502 1.8 kleink bus_dmamap_destroy(ed->ed_dmat, ed->ed_map); 1503 1.1 kleink unmap: 1504 1.49 kleink bus_dmamem_unmap(ed->ed_dmat, ed->ed_kva, ed->ed_size); 1505 1.1 kleink free: 1506 1.8 kleink bus_dmamem_free(ed->ed_dmat, ed->ed_segs, ed->ed_nsegs); 1507 1.1 kleink out: 1508 1.39 kent return error; 1509 1.1 kleink } 1510 1.1 kleink 1511 1.1 kleink static void 1512 1.39 kent eso_freemem(struct eso_dma *ed) 1513 1.1 kleink { 1514 1.1 kleink 1515 1.8 kleink bus_dmamap_unload(ed->ed_dmat, ed->ed_map); 1516 1.8 kleink bus_dmamap_destroy(ed->ed_dmat, ed->ed_map); 1517 1.49 kleink bus_dmamem_unmap(ed->ed_dmat, ed->ed_kva, ed->ed_size); 1518 1.8 kleink bus_dmamem_free(ed->ed_dmat, ed->ed_segs, ed->ed_nsegs); 1519 1.1 kleink } 1520 1.39 kent 1521 1.49 kleink static struct eso_dma * 1522 1.50 christos eso_kva2dma(const struct eso_softc *sc, const void *kva) 1523 1.49 kleink { 1524 1.49 kleink struct eso_dma *p; 1525 1.49 kleink 1526 1.49 kleink SLIST_FOREACH(p, &sc->sc_dmas, ed_slist) { 1527 1.49 kleink if (KVADDR(p) == kva) 1528 1.49 kleink return p; 1529 1.49 kleink } 1530 1.49 kleink 1531 1.62 chs panic("%s: kva2dma: bad kva: %p", device_xname(sc->sc_dev), kva); 1532 1.49 kleink /* NOTREACHED */ 1533 1.49 kleink } 1534 1.49 kleink 1535 1.1 kleink static void * 1536 1.58 jmcneill eso_allocm(void *hdl, int direction, size_t size) 1537 1.1 kleink { 1538 1.39 kent struct eso_softc *sc; 1539 1.1 kleink struct eso_dma *ed; 1540 1.1 kleink size_t boundary; 1541 1.1 kleink int error; 1542 1.1 kleink 1543 1.39 kent sc = hdl; 1544 1.67 chs ed = kmem_alloc(sizeof (*ed), KM_SLEEP); 1545 1.1 kleink 1546 1.1 kleink /* 1547 1.1 kleink * Apparently the Audio 1 DMA controller's current address 1548 1.1 kleink * register can't roll over a 64K address boundary, so we have to 1549 1.32 kleink * take care of that ourselves. Similarly, the Audio 2 DMA 1550 1.32 kleink * controller needs a 1M address boundary. 1551 1.1 kleink */ 1552 1.1 kleink if (direction == AUMODE_RECORD) 1553 1.1 kleink boundary = 0x10000; 1554 1.1 kleink else 1555 1.32 kleink boundary = 0x100000; 1556 1.1 kleink 1557 1.35 kleink /* 1558 1.35 kleink * XXX Work around allocation problems for Audio 1, which 1559 1.35 kleink * XXX implements the 24 low address bits only, with 1560 1.35 kleink * XXX machine-specific DMA tag use. 1561 1.35 kleink */ 1562 1.8 kleink #ifdef alpha 1563 1.8 kleink /* 1564 1.35 kleink * XXX Force allocation through the (ISA) SGMAP. 1565 1.8 kleink */ 1566 1.8 kleink if (direction == AUMODE_RECORD) 1567 1.8 kleink ed->ed_dmat = alphabus_dma_get_tag(sc->sc_dmat, ALPHA_BUS_ISA); 1568 1.8 kleink else 1569 1.35 kleink #elif defined(amd64) || defined(i386) 1570 1.35 kleink /* 1571 1.35 kleink * XXX Force allocation through the ISA DMA tag. 1572 1.35 kleink */ 1573 1.35 kleink if (direction == AUMODE_RECORD) 1574 1.35 kleink ed->ed_dmat = &isa_bus_dma_tag; 1575 1.35 kleink else 1576 1.8 kleink #endif 1577 1.8 kleink ed->ed_dmat = sc->sc_dmat; 1578 1.8 kleink 1579 1.58 jmcneill error = eso_allocmem(sc, size, 32, boundary, direction, ed); 1580 1.1 kleink if (error) { 1581 1.58 jmcneill kmem_free(ed, sizeof(*ed)); 1582 1.39 kent return NULL; 1583 1.1 kleink } 1584 1.49 kleink SLIST_INSERT_HEAD(&sc->sc_dmas, ed, ed_slist); 1585 1.1 kleink 1586 1.39 kent return KVADDR(ed); 1587 1.1 kleink } 1588 1.1 kleink 1589 1.1 kleink static void 1590 1.58 jmcneill eso_freem(void *hdl, void *addr, size_t size) 1591 1.1 kleink { 1592 1.39 kent struct eso_softc *sc; 1593 1.49 kleink struct eso_dma *p; 1594 1.1 kleink 1595 1.39 kent sc = hdl; 1596 1.49 kleink p = eso_kva2dma(sc, addr); 1597 1.49 kleink 1598 1.49 kleink SLIST_REMOVE(&sc->sc_dmas, p, eso_dma, ed_slist); 1599 1.49 kleink eso_freemem(p); 1600 1.58 jmcneill kmem_free(p, sizeof(*p)); 1601 1.1 kleink } 1602 1.1 kleink 1603 1.1 kleink static size_t 1604 1.45 christos eso_round_buffersize(void *hdl, int direction, size_t bufsize) 1605 1.1 kleink { 1606 1.16 kleink size_t maxsize; 1607 1.1 kleink 1608 1.16 kleink /* 1609 1.17 cjs * The playback DMA buffer size on the Solo-1 is limited to 0xfff0 1610 1.17 cjs * bytes. This is because IO_A2DMAC is a two byte value 1611 1.17 cjs * indicating the literal byte count, and the 4 least significant 1612 1.17 cjs * bits are read-only. Zero is not used as a special case for 1613 1.17 cjs * 0x10000. 1614 1.16 kleink * 1615 1.17 cjs * For recording, DMAC_DMAC is the byte count - 1, so 0x10000 can 1616 1.17 cjs * be represented. 1617 1.16 kleink */ 1618 1.17 cjs maxsize = (direction == AUMODE_PLAY) ? 0xfff0 : 0x10000; 1619 1.16 kleink 1620 1.16 kleink if (bufsize > maxsize) 1621 1.16 kleink bufsize = maxsize; 1622 1.1 kleink 1623 1.39 kent return bufsize; 1624 1.1 kleink } 1625 1.1 kleink 1626 1.1 kleink /* ARGSUSED */ 1627 1.1 kleink static int 1628 1.45 christos eso_get_props(void *hdl) 1629 1.1 kleink { 1630 1.1 kleink 1631 1.71 isaki return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE | 1632 1.71 isaki AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 1633 1.1 kleink } 1634 1.1 kleink 1635 1.1 kleink static int 1636 1.39 kent eso_trigger_output(void *hdl, void *start, void *end, int blksize, 1637 1.39 kent void (*intr)(void *), void *arg, const audio_params_t *param) 1638 1.1 kleink { 1639 1.39 kent struct eso_softc *sc; 1640 1.1 kleink struct eso_dma *ed; 1641 1.1 kleink uint8_t a2c1; 1642 1.39 kent 1643 1.39 kent sc = hdl; 1644 1.1 kleink DPRINTF(( 1645 1.1 kleink "%s: trigger_output: start %p, end %p, blksize %d, intr %p(%p)\n", 1646 1.62 chs device_xname(sc->sc_dev), start, end, blksize, intr, arg)); 1647 1.38 kent DPRINTF(("%s: param: rate %u, encoding %u, precision %u, channels %u\n", 1648 1.62 chs device_xname(sc->sc_dev), param->sample_rate, param->encoding, 1649 1.38 kent param->precision, param->channels)); 1650 1.39 kent 1651 1.1 kleink /* Find DMA buffer. */ 1652 1.49 kleink ed = eso_kva2dma(sc, start); 1653 1.35 kleink DPRINTF(("%s: dmaaddr %lx\n", 1654 1.62 chs device_xname(sc->sc_dev), (unsigned long)DMAADDR(ed))); 1655 1.39 kent 1656 1.1 kleink sc->sc_pintr = intr; 1657 1.1 kleink sc->sc_parg = arg; 1658 1.1 kleink 1659 1.18 kleink /* Compute drain timeout. */ 1660 1.39 kent sc->sc_pdrain = (blksize * NBBY * hz) / 1661 1.18 kleink (param->sample_rate * param->channels * 1662 1.38 kent param->precision) + 2; /* slop */ 1663 1.18 kleink 1664 1.1 kleink /* DMA transfer count (in `words'!) reload using 2's complement. */ 1665 1.1 kleink blksize = -(blksize >> 1); 1666 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_A2TCRLO, blksize & 0xff); 1667 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_A2TCRHI, blksize >> 8); 1668 1.1 kleink 1669 1.1 kleink /* Update DAC to reflect DMA count and audio parameters. */ 1670 1.1 kleink /* Note: we cache A2C2 in order to avoid r/m/w at interrupt time. */ 1671 1.38 kent if (param->precision == 16) 1672 1.1 kleink sc->sc_a2c2 |= ESO_MIXREG_A2C2_16BIT; 1673 1.1 kleink else 1674 1.1 kleink sc->sc_a2c2 &= ~ESO_MIXREG_A2C2_16BIT; 1675 1.1 kleink if (param->channels == 2) 1676 1.1 kleink sc->sc_a2c2 |= ESO_MIXREG_A2C2_STEREO; 1677 1.1 kleink else 1678 1.1 kleink sc->sc_a2c2 &= ~ESO_MIXREG_A2C2_STEREO; 1679 1.1 kleink if (param->encoding == AUDIO_ENCODING_SLINEAR_BE || 1680 1.1 kleink param->encoding == AUDIO_ENCODING_SLINEAR_LE) 1681 1.1 kleink sc->sc_a2c2 |= ESO_MIXREG_A2C2_SIGNED; 1682 1.1 kleink else 1683 1.1 kleink sc->sc_a2c2 &= ~ESO_MIXREG_A2C2_SIGNED; 1684 1.1 kleink /* Unmask IRQ. */ 1685 1.1 kleink sc->sc_a2c2 |= ESO_MIXREG_A2C2_IRQM; 1686 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_A2C2, sc->sc_a2c2); 1687 1.39 kent 1688 1.1 kleink /* Set up DMA controller. */ 1689 1.1 kleink bus_space_write_4(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAA, 1690 1.10 leo DMAADDR(ed)); 1691 1.1 kleink bus_space_write_2(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAC, 1692 1.10 leo (uint8_t *)end - (uint8_t *)start); 1693 1.1 kleink bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM, 1694 1.1 kleink ESO_IO_A2DMAM_DMAENB | ESO_IO_A2DMAM_AUTO); 1695 1.39 kent 1696 1.1 kleink /* Start DMA. */ 1697 1.1 kleink a2c1 = eso_read_mixreg(sc, ESO_MIXREG_A2C1); 1698 1.1 kleink a2c1 &= ~ESO_MIXREG_A2C1_RESV0; /* Paranoia? XXX bit 5 */ 1699 1.1 kleink a2c1 |= ESO_MIXREG_A2C1_FIFOENB | ESO_MIXREG_A2C1_DMAENB | 1700 1.1 kleink ESO_MIXREG_A2C1_AUTO; 1701 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_A2C1, a2c1); 1702 1.39 kent 1703 1.39 kent return 0; 1704 1.1 kleink } 1705 1.1 kleink 1706 1.1 kleink static int 1707 1.39 kent eso_trigger_input(void *hdl, void *start, void *end, int blksize, 1708 1.39 kent void (*intr)(void *), void *arg, const audio_params_t *param) 1709 1.1 kleink { 1710 1.39 kent struct eso_softc *sc; 1711 1.1 kleink struct eso_dma *ed; 1712 1.1 kleink uint8_t actl, a1c1; 1713 1.1 kleink 1714 1.39 kent sc = hdl; 1715 1.1 kleink DPRINTF(( 1716 1.1 kleink "%s: trigger_input: start %p, end %p, blksize %d, intr %p(%p)\n", 1717 1.62 chs device_xname(sc->sc_dev), start, end, blksize, intr, arg)); 1718 1.38 kent DPRINTF(("%s: param: rate %u, encoding %u, precision %u, channels %u\n", 1719 1.62 chs device_xname(sc->sc_dev), param->sample_rate, param->encoding, 1720 1.38 kent param->precision, param->channels)); 1721 1.1 kleink 1722 1.1 kleink /* 1723 1.1 kleink * If we failed to configure the Audio 1 DMA controller, bail here 1724 1.1 kleink * while retaining availability of the DAC direction (in Audio 2). 1725 1.1 kleink */ 1726 1.1 kleink if (!sc->sc_dmac_configured) 1727 1.39 kent return EIO; 1728 1.1 kleink 1729 1.1 kleink /* Find DMA buffer. */ 1730 1.49 kleink ed = eso_kva2dma(sc, start); 1731 1.35 kleink DPRINTF(("%s: dmaaddr %lx\n", 1732 1.62 chs device_xname(sc->sc_dev), (unsigned long)DMAADDR(ed))); 1733 1.1 kleink 1734 1.1 kleink sc->sc_rintr = intr; 1735 1.1 kleink sc->sc_rarg = arg; 1736 1.18 kleink 1737 1.18 kleink /* Compute drain timeout. */ 1738 1.39 kent sc->sc_rdrain = (blksize * NBBY * hz) / 1739 1.18 kleink (param->sample_rate * param->channels * 1740 1.38 kent param->precision) + 2; /* slop */ 1741 1.1 kleink 1742 1.1 kleink /* Set up ADC DMA converter parameters. */ 1743 1.1 kleink actl = eso_read_ctlreg(sc, ESO_CTLREG_ACTL); 1744 1.1 kleink if (param->channels == 2) { 1745 1.1 kleink actl &= ~ESO_CTLREG_ACTL_MONO; 1746 1.1 kleink actl |= ESO_CTLREG_ACTL_STEREO; 1747 1.1 kleink } else { 1748 1.1 kleink actl &= ~ESO_CTLREG_ACTL_STEREO; 1749 1.1 kleink actl |= ESO_CTLREG_ACTL_MONO; 1750 1.1 kleink } 1751 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_ACTL, actl); 1752 1.1 kleink 1753 1.1 kleink /* Set up Transfer Type: maybe move to attach time? */ 1754 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_A1TT, ESO_CTLREG_A1TT_DEMAND4); 1755 1.1 kleink 1756 1.1 kleink /* DMA transfer count reload using 2's complement. */ 1757 1.1 kleink blksize = -blksize; 1758 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_A1TCRLO, blksize & 0xff); 1759 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_A1TCRHI, blksize >> 8); 1760 1.1 kleink 1761 1.1 kleink /* Set up and enable Audio 1 DMA FIFO. */ 1762 1.1 kleink a1c1 = ESO_CTLREG_A1C1_RESV1 | ESO_CTLREG_A1C1_FIFOENB; 1763 1.38 kent if (param->precision == 16) 1764 1.1 kleink a1c1 |= ESO_CTLREG_A1C1_16BIT; 1765 1.1 kleink if (param->channels == 2) 1766 1.1 kleink a1c1 |= ESO_CTLREG_A1C1_STEREO; 1767 1.1 kleink else 1768 1.1 kleink a1c1 |= ESO_CTLREG_A1C1_MONO; 1769 1.1 kleink if (param->encoding == AUDIO_ENCODING_SLINEAR_BE || 1770 1.1 kleink param->encoding == AUDIO_ENCODING_SLINEAR_LE) 1771 1.1 kleink a1c1 |= ESO_CTLREG_A1C1_SIGNED; 1772 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_A1C1, a1c1); 1773 1.1 kleink 1774 1.1 kleink /* Set up ADC IRQ/DRQ parameters. */ 1775 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_LAIC, 1776 1.1 kleink ESO_CTLREG_LAIC_PINENB | ESO_CTLREG_LAIC_EXTENB); 1777 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_DRQCTL, 1778 1.1 kleink ESO_CTLREG_DRQCTL_ENB1 | ESO_CTLREG_DRQCTL_EXTENB); 1779 1.1 kleink 1780 1.1 kleink /* Set up and enable DMA controller. */ 1781 1.1 kleink bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_CLEAR, 0); 1782 1.1 kleink bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK, 1783 1.1 kleink ESO_DMAC_MASK_MASK); 1784 1.1 kleink bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MODE, 1785 1.1 kleink DMA37MD_WRITE | DMA37MD_LOOP | DMA37MD_DEMAND); 1786 1.1 kleink bus_space_write_4(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_DMAA, 1787 1.10 leo DMAADDR(ed)); 1788 1.1 kleink bus_space_write_2(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_DMAC, 1789 1.10 leo (uint8_t *)end - (uint8_t *)start - 1); 1790 1.1 kleink bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK, 0); 1791 1.1 kleink 1792 1.1 kleink /* Start DMA. */ 1793 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_A1C2, 1794 1.1 kleink ESO_CTLREG_A1C2_DMAENB | ESO_CTLREG_A1C2_READ | 1795 1.1 kleink ESO_CTLREG_A1C2_AUTO | ESO_CTLREG_A1C2_ADC); 1796 1.1 kleink 1797 1.39 kent return 0; 1798 1.1 kleink } 1799 1.1 kleink 1800 1.58 jmcneill 1801 1.58 jmcneill static void 1802 1.58 jmcneill eso_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread) 1803 1.58 jmcneill { 1804 1.58 jmcneill struct eso_softc *sc; 1805 1.58 jmcneill 1806 1.58 jmcneill sc = addr; 1807 1.58 jmcneill *intr = &sc->sc_intr_lock; 1808 1.58 jmcneill *thread = &sc->sc_lock; 1809 1.58 jmcneill } 1810 1.58 jmcneill 1811 1.34 kleink /* 1812 1.34 kleink * Mixer utility functions. 1813 1.34 kleink */ 1814 1.34 kleink static int 1815 1.39 kent eso_set_recsrc(struct eso_softc *sc, unsigned int recsrc) 1816 1.34 kleink { 1817 1.34 kleink mixer_devinfo_t di; 1818 1.34 kleink int i; 1819 1.34 kleink 1820 1.58 jmcneill KASSERT(mutex_owned(&sc->sc_intr_lock)); 1821 1.58 jmcneill 1822 1.34 kleink di.index = ESO_RECORD_SOURCE; 1823 1.34 kleink if (eso_query_devinfo(sc, &di) != 0) 1824 1.34 kleink panic("eso_set_recsrc: eso_query_devinfo failed"); 1825 1.34 kleink 1826 1.34 kleink for (i = 0; i < di.un.e.num_mem; i++) { 1827 1.34 kleink if (recsrc == di.un.e.member[i].ord) { 1828 1.34 kleink eso_write_mixreg(sc, ESO_MIXREG_ERS, recsrc); 1829 1.34 kleink sc->sc_recsrc = recsrc; 1830 1.39 kent return 0; 1831 1.34 kleink } 1832 1.34 kleink } 1833 1.34 kleink 1834 1.39 kent return EINVAL; 1835 1.34 kleink } 1836 1.34 kleink 1837 1.1 kleink static int 1838 1.39 kent eso_set_monooutsrc(struct eso_softc *sc, unsigned int monooutsrc) 1839 1.7 kleink { 1840 1.7 kleink mixer_devinfo_t di; 1841 1.7 kleink int i; 1842 1.7 kleink uint8_t mpm; 1843 1.7 kleink 1844 1.58 jmcneill KASSERT(mutex_owned(&sc->sc_intr_lock)); 1845 1.58 jmcneill 1846 1.7 kleink di.index = ESO_MONOOUT_SOURCE; 1847 1.7 kleink if (eso_query_devinfo(sc, &di) != 0) 1848 1.7 kleink panic("eso_set_monooutsrc: eso_query_devinfo failed"); 1849 1.7 kleink 1850 1.7 kleink for (i = 0; i < di.un.e.num_mem; i++) { 1851 1.7 kleink if (monooutsrc == di.un.e.member[i].ord) { 1852 1.7 kleink mpm = eso_read_mixreg(sc, ESO_MIXREG_MPM); 1853 1.7 kleink mpm &= ~ESO_MIXREG_MPM_MOMASK; 1854 1.7 kleink mpm |= monooutsrc; 1855 1.7 kleink eso_write_mixreg(sc, ESO_MIXREG_MPM, mpm); 1856 1.7 kleink sc->sc_monooutsrc = monooutsrc; 1857 1.39 kent return 0; 1858 1.7 kleink } 1859 1.7 kleink } 1860 1.7 kleink 1861 1.39 kent return EINVAL; 1862 1.7 kleink } 1863 1.7 kleink 1864 1.7 kleink static int 1865 1.39 kent eso_set_monoinbypass(struct eso_softc *sc, unsigned int monoinbypass) 1866 1.1 kleink { 1867 1.7 kleink mixer_devinfo_t di; 1868 1.7 kleink int i; 1869 1.34 kleink uint8_t mpm; 1870 1.1 kleink 1871 1.58 jmcneill KASSERT(mutex_owned(&sc->sc_intr_lock)); 1872 1.58 jmcneill 1873 1.34 kleink di.index = ESO_MONOIN_BYPASS; 1874 1.7 kleink if (eso_query_devinfo(sc, &di) != 0) 1875 1.34 kleink panic("eso_set_monoinbypass: eso_query_devinfo failed"); 1876 1.7 kleink 1877 1.7 kleink for (i = 0; i < di.un.e.num_mem; i++) { 1878 1.34 kleink if (monoinbypass == di.un.e.member[i].ord) { 1879 1.34 kleink mpm = eso_read_mixreg(sc, ESO_MIXREG_MPM); 1880 1.34 kleink mpm &= ~(ESO_MIXREG_MPM_MOMASK | ESO_MIXREG_MPM_RESV0); 1881 1.34 kleink mpm |= (monoinbypass ? ESO_MIXREG_MPM_MIBYPASS : 0); 1882 1.34 kleink eso_write_mixreg(sc, ESO_MIXREG_MPM, mpm); 1883 1.34 kleink sc->sc_monoinbypass = monoinbypass; 1884 1.39 kent return 0; 1885 1.7 kleink } 1886 1.7 kleink } 1887 1.39 kent 1888 1.39 kent return EINVAL; 1889 1.34 kleink } 1890 1.34 kleink 1891 1.34 kleink static int 1892 1.39 kent eso_set_preamp(struct eso_softc *sc, unsigned int preamp) 1893 1.34 kleink { 1894 1.34 kleink mixer_devinfo_t di; 1895 1.34 kleink int i; 1896 1.34 kleink uint8_t mpm; 1897 1.34 kleink 1898 1.58 jmcneill KASSERT(mutex_owned(&sc->sc_intr_lock)); 1899 1.58 jmcneill 1900 1.34 kleink di.index = ESO_MIC_PREAMP; 1901 1.34 kleink if (eso_query_devinfo(sc, &di) != 0) 1902 1.34 kleink panic("eso_set_preamp: eso_query_devinfo failed"); 1903 1.7 kleink 1904 1.34 kleink for (i = 0; i < di.un.e.num_mem; i++) { 1905 1.34 kleink if (preamp == di.un.e.member[i].ord) { 1906 1.34 kleink mpm = eso_read_mixreg(sc, ESO_MIXREG_MPM); 1907 1.34 kleink mpm &= ~(ESO_MIXREG_MPM_PREAMP | ESO_MIXREG_MPM_RESV0); 1908 1.34 kleink mpm |= (preamp ? ESO_MIXREG_MPM_PREAMP : 0); 1909 1.34 kleink eso_write_mixreg(sc, ESO_MIXREG_MPM, mpm); 1910 1.34 kleink sc->sc_preamp = preamp; 1911 1.39 kent return 0; 1912 1.34 kleink } 1913 1.34 kleink } 1914 1.39 kent 1915 1.39 kent return EINVAL; 1916 1.14 kleink } 1917 1.14 kleink 1918 1.14 kleink /* 1919 1.14 kleink * Reload Master Volume and Mute values in softc from mixer; used when 1920 1.14 kleink * those have previously been invalidated by use of hardware volume controls. 1921 1.14 kleink */ 1922 1.14 kleink static void 1923 1.39 kent eso_reload_master_vol(struct eso_softc *sc) 1924 1.14 kleink { 1925 1.14 kleink uint8_t mv; 1926 1.14 kleink 1927 1.58 jmcneill KASSERT(mutex_owned(&sc->sc_intr_lock)); 1928 1.58 jmcneill 1929 1.14 kleink mv = eso_read_mixreg(sc, ESO_MIXREG_LMVM); 1930 1.14 kleink sc->sc_gain[ESO_MASTER_VOL][ESO_LEFT] = 1931 1.14 kleink (mv & ~ESO_MIXREG_LMVM_MUTE) << 2; 1932 1.14 kleink mv = eso_read_mixreg(sc, ESO_MIXREG_LMVM); 1933 1.14 kleink sc->sc_gain[ESO_MASTER_VOL][ESO_RIGHT] = 1934 1.14 kleink (mv & ~ESO_MIXREG_RMVM_MUTE) << 2; 1935 1.14 kleink /* Currently both channels are muted simultaneously; either is OK. */ 1936 1.14 kleink sc->sc_mvmute = (mv & ESO_MIXREG_RMVM_MUTE) != 0; 1937 1.1 kleink } 1938 1.1 kleink 1939 1.1 kleink static void 1940 1.39 kent eso_set_gain(struct eso_softc *sc, unsigned int port) 1941 1.1 kleink { 1942 1.1 kleink uint8_t mixreg, tmp; 1943 1.1 kleink 1944 1.58 jmcneill KASSERT(mutex_owned(&sc->sc_intr_lock)); 1945 1.58 jmcneill 1946 1.1 kleink switch (port) { 1947 1.1 kleink case ESO_DAC_PLAY_VOL: 1948 1.1 kleink mixreg = ESO_MIXREG_PVR_A2; 1949 1.1 kleink break; 1950 1.1 kleink case ESO_MIC_PLAY_VOL: 1951 1.1 kleink mixreg = ESO_MIXREG_PVR_MIC; 1952 1.1 kleink break; 1953 1.1 kleink case ESO_LINE_PLAY_VOL: 1954 1.1 kleink mixreg = ESO_MIXREG_PVR_LINE; 1955 1.1 kleink break; 1956 1.1 kleink case ESO_SYNTH_PLAY_VOL: 1957 1.1 kleink mixreg = ESO_MIXREG_PVR_SYNTH; 1958 1.1 kleink break; 1959 1.1 kleink case ESO_CD_PLAY_VOL: 1960 1.1 kleink mixreg = ESO_MIXREG_PVR_CD; 1961 1.1 kleink break; 1962 1.1 kleink case ESO_AUXB_PLAY_VOL: 1963 1.1 kleink mixreg = ESO_MIXREG_PVR_AUXB; 1964 1.1 kleink break; 1965 1.39 kent 1966 1.1 kleink case ESO_DAC_REC_VOL: 1967 1.1 kleink mixreg = ESO_MIXREG_RVR_A2; 1968 1.1 kleink break; 1969 1.1 kleink case ESO_MIC_REC_VOL: 1970 1.1 kleink mixreg = ESO_MIXREG_RVR_MIC; 1971 1.1 kleink break; 1972 1.1 kleink case ESO_LINE_REC_VOL: 1973 1.1 kleink mixreg = ESO_MIXREG_RVR_LINE; 1974 1.1 kleink break; 1975 1.1 kleink case ESO_SYNTH_REC_VOL: 1976 1.1 kleink mixreg = ESO_MIXREG_RVR_SYNTH; 1977 1.1 kleink break; 1978 1.1 kleink case ESO_CD_REC_VOL: 1979 1.1 kleink mixreg = ESO_MIXREG_RVR_CD; 1980 1.1 kleink break; 1981 1.1 kleink case ESO_AUXB_REC_VOL: 1982 1.1 kleink mixreg = ESO_MIXREG_RVR_AUXB; 1983 1.1 kleink break; 1984 1.1 kleink case ESO_MONO_PLAY_VOL: 1985 1.1 kleink mixreg = ESO_MIXREG_PVR_MONO; 1986 1.1 kleink break; 1987 1.1 kleink case ESO_MONO_REC_VOL: 1988 1.1 kleink mixreg = ESO_MIXREG_RVR_MONO; 1989 1.1 kleink break; 1990 1.39 kent 1991 1.1 kleink case ESO_PCSPEAKER_VOL: 1992 1.1 kleink /* Special case - only 3-bit, mono, and reserved bits. */ 1993 1.1 kleink tmp = eso_read_mixreg(sc, ESO_MIXREG_PCSVR); 1994 1.1 kleink tmp &= ESO_MIXREG_PCSVR_RESV; 1995 1.1 kleink /* Map bits 7:5 -> 2:0. */ 1996 1.1 kleink tmp |= (sc->sc_gain[port][ESO_LEFT] >> 5); 1997 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_PCSVR, tmp); 1998 1.1 kleink return; 1999 1.1 kleink 2000 1.1 kleink case ESO_MASTER_VOL: 2001 1.1 kleink /* Special case - separate regs, and 6-bit precision. */ 2002 1.12 kleink /* Map bits 7:2 -> 5:0, reflect mute settings. */ 2003 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_LMVM, 2004 1.12 kleink (sc->sc_gain[port][ESO_LEFT] >> 2) | 2005 1.12 kleink (sc->sc_mvmute ? ESO_MIXREG_LMVM_MUTE : 0x00)); 2006 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_RMVM, 2007 1.12 kleink (sc->sc_gain[port][ESO_RIGHT] >> 2) | 2008 1.12 kleink (sc->sc_mvmute ? ESO_MIXREG_RMVM_MUTE : 0x00)); 2009 1.1 kleink return; 2010 1.1 kleink 2011 1.1 kleink case ESO_SPATIALIZER: 2012 1.1 kleink /* Special case - only `mono', and higher precision. */ 2013 1.1 kleink eso_write_mixreg(sc, ESO_MIXREG_SPATLVL, 2014 1.1 kleink sc->sc_gain[port][ESO_LEFT]); 2015 1.1 kleink return; 2016 1.39 kent 2017 1.1 kleink case ESO_RECORD_VOL: 2018 1.1 kleink /* Very Special case, controller register. */ 2019 1.1 kleink eso_write_ctlreg(sc, ESO_CTLREG_RECLVL,ESO_4BIT_GAIN_TO_STEREO( 2020 1.1 kleink sc->sc_gain[port][ESO_LEFT], sc->sc_gain[port][ESO_RIGHT])); 2021 1.1 kleink return; 2022 1.1 kleink 2023 1.1 kleink default: 2024 1.39 kent #ifdef DIAGNOSTIC 2025 1.1 kleink panic("eso_set_gain: bad port %u", port); 2026 1.1 kleink /* NOTREACHED */ 2027 1.1 kleink #else 2028 1.1 kleink return; 2029 1.39 kent #endif 2030 1.39 kent } 2031 1.1 kleink 2032 1.1 kleink eso_write_mixreg(sc, mixreg, ESO_4BIT_GAIN_TO_STEREO( 2033 1.1 kleink sc->sc_gain[port][ESO_LEFT], sc->sc_gain[port][ESO_RIGHT])); 2034 1.1 kleink } 2035