1 1.41 isaki /* $NetBSD: aria.c,v 1.41 2019/06/08 08:02:38 isaki Exp $ */ 2 1.5 mycroft 3 1.1 augustss /*- 4 1.32 elric * Copyright (c) 1995, 1996, 1998 The NetBSD Foundation, Inc. 5 1.32 elric * All rights reserved. 6 1.32 elric * 7 1.32 elric * This code is derived from software contributed to The NetBSD Foundation 8 1.32 elric * by Roland C. Dowdeswell. 9 1.1 augustss * 10 1.1 augustss * Redistribution and use in source and binary forms, with or without 11 1.1 augustss * modification, are permitted provided that the following conditions 12 1.1 augustss * are met: 13 1.1 augustss * 1. Redistributions of source code must retain the above copyright 14 1.1 augustss * notice, this list of conditions and the following disclaimer. 15 1.1 augustss * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 augustss * notice, this list of conditions and the following disclaimer in the 17 1.1 augustss * documentation and/or other materials provided with the distribution. 18 1.1 augustss * 19 1.32 elric * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.32 elric * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.32 elric * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.32 elric * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.32 elric * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.32 elric * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.32 elric * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.32 elric * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.32 elric * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.32 elric * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.32 elric * POSSIBILITY OF SUCH DAMAGE. 30 1.1 augustss */ 31 1.1 augustss 32 1.1 augustss /*- 33 1.1 augustss * TODO: 34 1.1 augustss * o Test the driver on cards other than a single 35 1.1 augustss * Prometheus Aria 16. 36 1.1 augustss * o Look into where aria_prometheus_kludge() belongs. 37 1.18 wiz * o Add some DMA code. It accomplishes its goal by 38 1.1 augustss * direct IO at the moment. 39 1.1 augustss * I cannot effectively code it. 40 1.1 augustss * o Rework the mixer interface. 41 1.1 augustss * o Deal with the lvls better. We need to do better mapping 42 1.1 augustss * between logarithmic scales and the one byte that 43 1.1 augustss * we are passed. 44 1.1 augustss * o Deal better with cards that have no mixer. 45 1.1 augustss */ 46 1.11 lukem 47 1.11 lukem #include <sys/cdefs.h> 48 1.41 isaki __KERNEL_RCSID(0, "$NetBSD: aria.c,v 1.41 2019/06/08 08:02:38 isaki Exp $"); 49 1.1 augustss 50 1.1 augustss #include <sys/param.h> 51 1.1 augustss #include <sys/systm.h> 52 1.1 augustss #include <sys/errno.h> 53 1.1 augustss #include <sys/ioctl.h> 54 1.1 augustss #include <sys/syslog.h> 55 1.1 augustss #include <sys/device.h> 56 1.1 augustss #include <sys/proc.h> 57 1.1 augustss #include <sys/buf.h> 58 1.20 mycroft #include <sys/fcntl.h> 59 1.28 ad #include <sys/cpu.h> 60 1.28 ad #include <sys/bus.h> 61 1.34 jmcneill #include <sys/audioio.h> 62 1.1 augustss 63 1.40 isaki #include <dev/audio/audio_if.h> 64 1.1 augustss 65 1.1 augustss #include <dev/isa/isavar.h> 66 1.1 augustss #include <dev/isa/ariareg.h> 67 1.1 augustss 68 1.1 augustss #ifdef AUDIO_DEBUG 69 1.1 augustss #define DPRINTF(x) printf x 70 1.1 augustss int ariadebug = 0; 71 1.1 augustss #else 72 1.1 augustss #define DPRINTF(x) 73 1.1 augustss #endif 74 1.1 augustss 75 1.1 augustss struct aria_mixdev_info { 76 1.1 augustss u_char num_channels; 77 1.1 augustss u_char level[2]; 78 1.1 augustss u_char mute; 79 1.1 augustss }; 80 1.1 augustss 81 1.1 augustss struct aria_mixmaster { 82 1.1 augustss u_char num_channels; 83 1.1 augustss u_char level[2]; 84 1.1 augustss u_char treble[2]; 85 1.1 augustss u_char bass[2]; 86 1.1 augustss }; 87 1.1 augustss 88 1.1 augustss struct aria_softc { 89 1.37 chs device_t sc_dev; /* base device */ 90 1.34 jmcneill kmutex_t sc_lock; 91 1.34 jmcneill kmutex_t sc_intr_lock; 92 1.1 augustss void *sc_ih; /* interrupt vectoring */ 93 1.1 augustss bus_space_tag_t sc_iot; /* Tag on 'da bus. */ 94 1.1 augustss bus_space_handle_t sc_ioh; /* Handle of iospace */ 95 1.2 thorpej isa_chipset_tag_t sc_ic; /* ISA chipset info */ 96 1.1 augustss 97 1.1 augustss u_short sc_open; /* reference count of open calls */ 98 1.1 augustss u_short sc_play; /* non-paused play chans 2**chan */ 99 1.1 augustss u_short sc_record; /* non-paused record chans 2**chan */ 100 1.1 augustss /* XXX -- keep this? */ 101 1.1 augustss u_short sc_gain[2]; /* left/right gain (play) */ 102 1.1 augustss 103 1.1 augustss u_long sc_rate; /* Sample rate for input and output */ 104 1.17 wiz u_int sc_encoding; /* audio encoding -- mu-law/linear */ 105 1.1 augustss int sc_chans; /* # of channels */ 106 1.1 augustss int sc_precision; /* # bits per sample */ 107 1.1 augustss 108 1.1 augustss u_long sc_interrupts; /* number of interrupts taken */ 109 1.1 augustss void (*sc_rintr)(void*); /* record transfer completion intr handler */ 110 1.1 augustss void (*sc_pintr)(void*); /* play transfer completion intr handler */ 111 1.1 augustss void *sc_rarg; /* arg for sc_rintr() */ 112 1.1 augustss void *sc_parg; /* arg for sc_pintr() */ 113 1.1 augustss 114 1.1 augustss int sc_blocksize; /* literal dio block size */ 115 1.1 augustss void *sc_rdiobuffer; /* record: where the next samples should be */ 116 1.1 augustss void *sc_pdiobuffer; /* play: where the next samples are */ 117 1.1 augustss 118 1.1 augustss u_short sc_hardware; /* bit field of hardware present */ 119 1.1 augustss #define ARIA_TELEPHONE 0x0001 /* has telephone input */ 120 1.1 augustss #define ARIA_MIXER 0x0002 /* has SC18075 digital mixer */ 121 1.1 augustss #define ARIA_MODEL 0x0004 /* is SC18025 (=0) or SC18026 (=1) */ 122 1.1 augustss 123 1.1 augustss struct aria_mixdev_info aria_mix[6]; 124 1.1 augustss struct aria_mixmaster ariamix_master; 125 1.1 augustss u_char aria_mix_source; 126 1.1 augustss 127 1.1 augustss int sc_sendcmd_err; 128 1.1 augustss }; 129 1.1 augustss 130 1.31 cegger int ariaprobe(device_t, cfdata_t, void *); 131 1.31 cegger void ariaattach(device_t, device_t, void *); 132 1.23 kent void ariaclose(void *); 133 1.23 kent int ariaopen(void *, int); 134 1.23 kent int ariareset(bus_space_tag_t, bus_space_handle_t); 135 1.23 kent int aria_reset(struct aria_softc *); 136 1.23 kent int aria_getdev(void *, struct audio_device *); 137 1.23 kent 138 1.23 kent void aria_do_kludge(bus_space_tag_t, bus_space_handle_t, 139 1.23 kent bus_space_handle_t, 140 1.23 kent u_short, u_short, u_short, u_short); 141 1.23 kent void aria_prometheus_kludge(struct isa_attach_args *, bus_space_handle_t); 142 1.23 kent 143 1.40 isaki int aria_query_format(void *, audio_format_query_t *); 144 1.23 kent int aria_round_blocksize(void *, int, int, const audio_params_t *); 145 1.23 kent int aria_speaker_ctl(void *, int); 146 1.23 kent int aria_commit_settings(void *); 147 1.40 isaki int aria_set_format(void *, int, 148 1.40 isaki const audio_params_t *, const audio_params_t *, 149 1.40 isaki audio_filter_reg_t *, audio_filter_reg_t *); 150 1.23 kent int aria_get_props(void *); 151 1.34 jmcneill void aria_get_locks(void *, kmutex_t **, kmutex_t **); 152 1.23 kent 153 1.23 kent int aria_start_output(void *, void *, int, void (*)(void *), void*); 154 1.23 kent int aria_start_input(void *, void *, int, void (*)(void *), void*); 155 1.23 kent 156 1.23 kent int aria_halt_input(void *); 157 1.23 kent int aria_halt_output(void *); 158 1.23 kent 159 1.23 kent int aria_sendcmd(struct aria_softc *, u_short, int, int, int); 160 1.23 kent 161 1.23 kent u_short aria_getdspmem(struct aria_softc *, u_short); 162 1.23 kent void aria_putdspmem(struct aria_softc *, u_short, u_short); 163 1.23 kent 164 1.23 kent int aria_intr(void *); 165 1.23 kent short ariaversion(struct aria_softc *); 166 1.23 kent 167 1.23 kent void aria_set_mixer(struct aria_softc *, int); 168 1.23 kent 169 1.23 kent void aria_mix_write(struct aria_softc *, int, int); 170 1.23 kent int aria_mix_read(struct aria_softc *, int); 171 1.23 kent 172 1.23 kent int aria_mixer_set_port(void *, mixer_ctrl_t *); 173 1.23 kent int aria_mixer_get_port(void *, mixer_ctrl_t *); 174 1.23 kent int aria_mixer_query_devinfo(void *, mixer_devinfo_t *); 175 1.1 augustss 176 1.37 chs CFATTACH_DECL_NEW(aria, sizeof(struct aria_softc), 177 1.15 thorpej ariaprobe, ariaattach, NULL, NULL); 178 1.1 augustss 179 1.1 augustss /* XXX temporary test for 1.3 */ 180 1.1 augustss #ifndef AudioNaux 181 1.1 augustss /* 1.3 */ 182 1.1 augustss struct cfdriver aria_cd = { 183 1.1 augustss NULL, "aria", DV_DULL 184 1.1 augustss }; 185 1.1 augustss #endif 186 1.1 augustss 187 1.1 augustss struct audio_device aria_device = { 188 1.1 augustss "Aria 16(se)", 189 1.1 augustss "x", 190 1.1 augustss "aria" 191 1.1 augustss }; 192 1.1 augustss 193 1.40 isaki #define ARIA_FORMAT(enc, prec) \ 194 1.40 isaki { \ 195 1.40 isaki .mode = AUMODE_PLAY | AUMODE_RECORD, \ 196 1.40 isaki .encoding = (enc), \ 197 1.40 isaki .validbits = (prec), \ 198 1.40 isaki .precision = (prec), \ 199 1.40 isaki .channels = 2, \ 200 1.40 isaki .channel_mask = AUFMT_STEREO, \ 201 1.40 isaki .frequency_type = 6, \ 202 1.40 isaki .frequency = { 7875, 11025, 15750, 22050, 31500, 44100 }, \ 203 1.40 isaki } 204 1.40 isaki /* XXX Some models seem to support mulaw/alaw. */ 205 1.40 isaki const struct audio_format aria_formats[] = { 206 1.40 isaki ARIA_FORMAT(AUDIO_ENCODING_ULINEAR, 8), 207 1.40 isaki ARIA_FORMAT(AUDIO_ENCODING_SLINEAR_LE, 16), 208 1.40 isaki }; 209 1.40 isaki #define ARIA_NFORMATS __arraycount(aria_formats) 210 1.40 isaki 211 1.1 augustss /* 212 1.1 augustss * Define our interface to the higher level audio driver. 213 1.1 augustss */ 214 1.1 augustss 215 1.21 yamt const struct audio_hw_if aria_hw_if = { 216 1.39 isaki .open = ariaopen, 217 1.39 isaki .close = ariaclose, 218 1.40 isaki .query_format = aria_query_format, 219 1.40 isaki .set_format = aria_set_format, 220 1.39 isaki .round_blocksize = aria_round_blocksize, 221 1.39 isaki .commit_settings = aria_commit_settings, 222 1.39 isaki .start_output = aria_start_output, 223 1.39 isaki .start_input = aria_start_input, 224 1.39 isaki .halt_output = aria_halt_output, 225 1.39 isaki .halt_input = aria_halt_input, 226 1.39 isaki .getdev = aria_getdev, 227 1.39 isaki .set_port = aria_mixer_set_port, 228 1.39 isaki .get_port = aria_mixer_get_port, 229 1.39 isaki .query_devinfo = aria_mixer_query_devinfo, 230 1.39 isaki .get_props = aria_get_props, 231 1.39 isaki .get_locks = aria_get_locks, 232 1.1 augustss }; 233 1.1 augustss 234 1.1 augustss /* 235 1.1 augustss * Probe / attach routines. 236 1.1 augustss */ 237 1.1 augustss 238 1.1 augustss /* 239 1.1 augustss * Probe for the aria hardware. 240 1.1 augustss */ 241 1.1 augustss int 242 1.31 cegger ariaprobe(device_t parent, cfdata_t cf, void *aux) 243 1.1 augustss { 244 1.1 augustss bus_space_handle_t ioh; 245 1.23 kent struct isa_attach_args *ia; 246 1.1 augustss 247 1.23 kent ia = aux; 248 1.12 thorpej if (ia->ia_nio < 1) 249 1.23 kent return 0; 250 1.12 thorpej if (ia->ia_nirq < 1) 251 1.23 kent return 0; 252 1.12 thorpej 253 1.12 thorpej if (ISA_DIRECT_CONFIG(ia)) 254 1.23 kent return 0; 255 1.12 thorpej 256 1.12 thorpej if (!ARIA_BASE_VALID(ia->ia_io[0].ir_addr)) { 257 1.12 thorpej printf("aria: configured iobase %d invalid\n", 258 1.12 thorpej ia->ia_io[0].ir_addr); 259 1.1 augustss return 0; 260 1.1 augustss } 261 1.23 kent 262 1.12 thorpej if (!ARIA_IRQ_VALID(ia->ia_irq[0].ir_irq)) { 263 1.12 thorpej printf("aria: configured irq %d invalid\n", 264 1.12 thorpej ia->ia_irq[0].ir_irq); 265 1.1 augustss return 0; 266 1.1 augustss } 267 1.1 augustss 268 1.12 thorpej if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, ARIADSP_NPORT, 269 1.12 thorpej 0, &ioh)) { 270 1.1 augustss DPRINTF(("aria: aria probe failed\n")); 271 1.1 augustss return 0; 272 1.1 augustss } 273 1.1 augustss 274 1.1 augustss if (cf->cf_flags & 1) 275 1.1 augustss aria_prometheus_kludge(ia, ioh); 276 1.1 augustss 277 1.1 augustss if (ariareset(ia->ia_iot, ioh) != 0) { 278 1.1 augustss DPRINTF(("aria: aria probe failed\n")); 279 1.1 augustss bus_space_unmap(ia->ia_iot, ioh, ARIADSP_NPORT); 280 1.1 augustss return 0; 281 1.1 augustss } 282 1.1 augustss 283 1.12 thorpej bus_space_unmap(ia->ia_iot, ioh, ARIADSP_NPORT); 284 1.12 thorpej 285 1.12 thorpej ia->ia_nio = 1; 286 1.12 thorpej ia->ia_io[0].ir_size = ARIADSP_NPORT; 287 1.12 thorpej 288 1.12 thorpej ia->ia_nirq = 1; 289 1.12 thorpej 290 1.12 thorpej ia->ia_niomem = 0; 291 1.12 thorpej ia->ia_ndrq = 0; 292 1.1 augustss 293 1.1 augustss DPRINTF(("aria: aria probe succeeded\n")); 294 1.1 augustss return 1; 295 1.1 augustss } 296 1.1 augustss 297 1.1 augustss /* 298 1.1 augustss * I didn't call this a kludge for 299 1.1 augustss * nothing. This is cribbed from 300 1.1 augustss * ariainit, the author of that 301 1.1 augustss * disassembled some code to discover 302 1.1 augustss * how to set up the initial values of 303 1.1 augustss * the card. Without this, the card 304 1.1 augustss * is dead. (It will not respond to _any_ 305 1.1 augustss * input at all.) 306 1.1 augustss * 307 1.1 augustss * ariainit can be found (ftp) at: 308 1.1 augustss * ftp://ftp.wi.leidenuniv.nl/pub/audio/aria/programming/contrib/ariainit.zip 309 1.1 augustss * currently. 310 1.1 augustss */ 311 1.1 augustss 312 1.1 augustss void 313 1.23 kent aria_prometheus_kludge(struct isa_attach_args *ia, bus_space_handle_t ioh1) 314 1.1 augustss { 315 1.1 augustss bus_space_tag_t iot; 316 1.1 augustss bus_space_handle_t ioh; 317 1.1 augustss u_short end; 318 1.1 augustss 319 1.1 augustss DPRINTF(("aria: begin aria_prometheus_kludge\n")); 320 1.1 augustss 321 1.23 kent /* Begin Config Sequence */ 322 1.1 augustss 323 1.1 augustss iot = ia->ia_iot; 324 1.1 augustss bus_space_map(iot, 0x200, 8, 0, &ioh); 325 1.1 augustss 326 1.23 kent bus_space_write_1(iot, ioh, 4, 0x4c); 327 1.23 kent bus_space_write_1(iot, ioh, 5, 0x42); 328 1.23 kent bus_space_write_1(iot, ioh, 6, 0x00); 329 1.23 kent bus_space_write_2(iot, ioh, 0, 0x0f); 330 1.23 kent bus_space_write_1(iot, ioh, 1, 0x00); 331 1.23 kent bus_space_write_2(iot, ioh, 0, 0x02); 332 1.23 kent bus_space_write_1(iot, ioh, 1, ia->ia_io[0].ir_addr>>2); 333 1.23 kent 334 1.23 kent /* 335 1.23 kent * These next three lines set up the iobase 336 1.23 kent * and the irq; and disable the drq. 337 1.23 kent */ 338 1.12 thorpej aria_do_kludge(iot, ioh, ioh1, 0x111, 339 1.12 thorpej ((ia->ia_io[0].ir_addr-0x280)>>2)+0xA0, 0xbf, 0xa0); 340 1.12 thorpej aria_do_kludge(iot, ioh, ioh1, 0x011, 341 1.12 thorpej ia->ia_irq[0].ir_irq-6, 0xf8, 0x00); 342 1.1 augustss aria_do_kludge(iot, ioh, ioh1, 0x011, 0x00, 0xef, 0x00); 343 1.1 augustss 344 1.23 kent /* The rest of these lines just disable everything else */ 345 1.1 augustss aria_do_kludge(iot, ioh, ioh1, 0x113, 0x00, 0x88, 0x00); 346 1.1 augustss aria_do_kludge(iot, ioh, ioh1, 0x013, 0x00, 0xf8, 0x00); 347 1.1 augustss aria_do_kludge(iot, ioh, ioh1, 0x013, 0x00, 0xef, 0x00); 348 1.1 augustss aria_do_kludge(iot, ioh, ioh1, 0x117, 0x00, 0x88, 0x00); 349 1.1 augustss aria_do_kludge(iot, ioh, ioh1, 0x017, 0x00, 0xff, 0x00); 350 1.1 augustss 351 1.23 kent /* End Sequence */ 352 1.1 augustss bus_space_write_1(iot, ioh, 0, 0x0f); 353 1.1 augustss end = bus_space_read_1(iot, ioh1, 0); 354 1.1 augustss bus_space_write_2(iot, ioh, 0, 0x0f); 355 1.1 augustss bus_space_write_1(iot, ioh, 1, end|0x80); 356 1.1 augustss bus_space_read_1(iot, ioh, 0); 357 1.1 augustss 358 1.1 augustss bus_space_unmap(iot, ioh, 8); 359 1.23 kent /* 360 1.23 kent * This delay is necessary for some reason, 361 1.23 kent * at least it would crash, and sometimes not 362 1.23 kent * probe properly if it did not exist. 363 1.23 kent */ 364 1.1 augustss delay(1000000); 365 1.1 augustss } 366 1.1 augustss 367 1.1 augustss void 368 1.23 kent aria_do_kludge( 369 1.23 kent bus_space_tag_t iot, 370 1.23 kent bus_space_handle_t ioh, 371 1.23 kent bus_space_handle_t ioh1, 372 1.23 kent u_short func, 373 1.23 kent u_short bits, 374 1.23 kent u_short and, 375 1.23 kent u_short or) 376 1.1 augustss { 377 1.1 augustss u_int i; 378 1.23 kent 379 1.1 augustss if (func & 0x100) { 380 1.1 augustss func &= ~0x100; 381 1.1 augustss if (bits) { 382 1.1 augustss bus_space_write_2(iot, ioh, 0, func-1); 383 1.1 augustss bus_space_write_1(iot, ioh, 1, bits); 384 1.1 augustss } 385 1.1 augustss } else 386 1.1 augustss or |= bits; 387 1.1 augustss 388 1.1 augustss bus_space_write_1(iot, ioh, 0, func); 389 1.1 augustss i = bus_space_read_1(iot, ioh1, 0); 390 1.1 augustss bus_space_write_2(iot, ioh, 0, func); 391 1.1 augustss bus_space_write_1(iot, ioh, 1, (i&and) | or); 392 1.1 augustss } 393 1.1 augustss 394 1.1 augustss /* 395 1.1 augustss * Attach hardware to driver, attach hardware driver to audio 396 1.1 augustss * pseudo-device driver. 397 1.1 augustss */ 398 1.1 augustss void 399 1.31 cegger ariaattach(device_t parent, device_t self, void *aux) 400 1.1 augustss { 401 1.1 augustss bus_space_handle_t ioh; 402 1.23 kent struct aria_softc *sc; 403 1.23 kent struct isa_attach_args *ia; 404 1.1 augustss u_short i; 405 1.1 augustss 406 1.37 chs sc = device_private(self); 407 1.37 chs sc->sc_dev = self; 408 1.23 kent ia = aux; 409 1.12 thorpej if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, ARIADSP_NPORT, 410 1.12 thorpej 0, &ioh)) 411 1.29 cegger panic("%s: can map io port range", device_xname(self)); 412 1.1 augustss 413 1.1 augustss sc->sc_iot = ia->ia_iot; 414 1.1 augustss sc->sc_ioh = ioh; 415 1.2 thorpej sc->sc_ic = ia->ia_ic; 416 1.1 augustss 417 1.34 jmcneill mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 418 1.35 mrg mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO); 419 1.34 jmcneill 420 1.12 thorpej sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, 421 1.35 mrg IST_EDGE, IPL_AUDIO, aria_intr, sc); 422 1.1 augustss 423 1.33 jakllsch DPRINTF(("isa_intr_establish() returns (%p)\n", sc->sc_ih)); 424 1.1 augustss 425 1.1 augustss i = aria_getdspmem(sc, ARIAA_HARDWARE_A); 426 1.1 augustss 427 1.1 augustss sc->sc_hardware = 0; 428 1.1 augustss sc->sc_hardware |= ((i>>13)&0x01)==1 ? ARIA_TELEPHONE:0; 429 1.1 augustss sc->sc_hardware |= (((i>>5)&0x07))==0x04 ? ARIA_MIXER:0; 430 1.1 augustss sc->sc_hardware |= (aria_getdspmem(sc, ARIAA_MODEL_A)>=1)?ARIA_MODEL:0; 431 1.1 augustss 432 1.1 augustss sc->sc_open = 0; 433 1.1 augustss sc->sc_play = 0; 434 1.1 augustss sc->sc_record = 0; 435 1.1 augustss sc->sc_rate = 7875; 436 1.1 augustss sc->sc_chans = 1; 437 1.1 augustss sc->sc_blocksize = 1024; 438 1.1 augustss sc->sc_precision = 8; 439 1.23 kent sc->sc_rintr = 0; 440 1.23 kent sc->sc_rarg = 0; 441 1.23 kent sc->sc_pintr = 0; 442 1.23 kent sc->sc_parg = 0; 443 1.1 augustss sc->sc_gain[0] = 127; 444 1.1 augustss sc->sc_gain[1] = 127; 445 1.1 augustss 446 1.1 augustss for (i=0; i<6; i++) { 447 1.1 augustss if (i == ARIAMIX_TEL_LVL) 448 1.1 augustss sc->aria_mix[i].num_channels = 1; 449 1.1 augustss else 450 1.1 augustss sc->aria_mix[i].num_channels = 2; 451 1.1 augustss sc->aria_mix[i].level[0] = 127; 452 1.1 augustss sc->aria_mix[i].level[1] = 127; 453 1.1 augustss } 454 1.1 augustss 455 1.1 augustss sc->ariamix_master.num_channels = 2; 456 1.1 augustss sc->ariamix_master.level[0] = 222; 457 1.1 augustss sc->ariamix_master.level[1] = 222; 458 1.1 augustss sc->ariamix_master.bass[0] = 127; 459 1.1 augustss sc->ariamix_master.bass[1] = 127; 460 1.1 augustss sc->ariamix_master.treble[0] = 127; 461 1.1 augustss sc->ariamix_master.treble[1] = 127; 462 1.1 augustss sc->aria_mix_source = 0; 463 1.1 augustss 464 1.1 augustss aria_commit_settings(sc); 465 1.1 augustss 466 1.1 augustss printf(": dsp %s", (ARIA_MODEL&sc->sc_hardware)?"SC18026":"SC18025"); 467 1.1 augustss if (ARIA_TELEPHONE&sc->sc_hardware) 468 1.1 augustss printf(", tel"); 469 1.1 augustss if (ARIA_MIXER&sc->sc_hardware) 470 1.1 augustss printf(", SC18075 mixer"); 471 1.1 augustss printf("\n"); 472 1.1 augustss 473 1.23 kent snprintf(aria_device.version, sizeof(aria_device.version), "%s", 474 1.1 augustss ARIA_MODEL & sc->sc_hardware ? "SC18026" : "SC18025"); 475 1.1 augustss 476 1.37 chs audio_attach_mi(&aria_hw_if, (void *)sc, sc->sc_dev); 477 1.1 augustss } 478 1.1 augustss 479 1.1 augustss /* 480 1.1 augustss * Various routines to interface to higher level audio driver 481 1.1 augustss */ 482 1.1 augustss 483 1.1 augustss int 484 1.23 kent ariaopen(void *addr, int flags) 485 1.1 augustss { 486 1.23 kent struct aria_softc *sc; 487 1.1 augustss 488 1.23 kent sc = addr; 489 1.1 augustss DPRINTF(("ariaopen() called\n")); 490 1.23 kent 491 1.1 augustss if (!sc) 492 1.1 augustss return ENXIO; 493 1.23 kent 494 1.1 augustss if (flags&FREAD) 495 1.1 augustss sc->sc_open |= ARIAR_OPEN_RECORD; 496 1.1 augustss if (flags&FWRITE) 497 1.1 augustss sc->sc_open |= ARIAR_OPEN_PLAY; 498 1.1 augustss 499 1.1 augustss return 0; 500 1.1 augustss } 501 1.1 augustss 502 1.1 augustss int 503 1.27 christos aria_getdev(void *addr, struct audio_device *retp) 504 1.1 augustss { 505 1.23 kent 506 1.1 augustss *retp = aria_device; 507 1.1 augustss return 0; 508 1.1 augustss } 509 1.1 augustss 510 1.1 augustss /* 511 1.1 augustss * Various routines to interface to higher level audio driver 512 1.1 augustss */ 513 1.1 augustss 514 1.1 augustss int 515 1.40 isaki aria_query_format(void *addr, audio_format_query_t *afp) 516 1.1 augustss { 517 1.1 augustss 518 1.40 isaki return audio_query_format(aria_formats, ARIA_NFORMATS, afp); 519 1.1 augustss } 520 1.1 augustss 521 1.1 augustss /* 522 1.1 augustss * Store blocksize in bytes. 523 1.1 augustss */ 524 1.1 augustss 525 1.1 augustss int 526 1.27 christos aria_round_blocksize(void *addr, int blk, int mode, 527 1.27 christos const audio_params_t *param) 528 1.1 augustss { 529 1.1 augustss int i; 530 1.23 kent 531 1.1 augustss #if 0 /* XXX -- this is being a tad bit of a problem... */ 532 1.23 kent for (i = 64; i < 1024; i *= 2) 533 1.1 augustss if (blk <= i) 534 1.1 augustss break; 535 1.1 augustss #else 536 1.1 augustss i = 1024; 537 1.1 augustss #endif 538 1.23 kent return i; 539 1.1 augustss } 540 1.1 augustss 541 1.1 augustss int 542 1.27 christos aria_get_props(void *addr) 543 1.1 augustss { 544 1.23 kent 545 1.40 isaki /* XXX This driver doesn't seem to be written as full duplex. */ 546 1.41 isaki return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE; 547 1.1 augustss } 548 1.1 augustss 549 1.1 augustss int 550 1.40 isaki aria_set_format(void *addr, int setmode, 551 1.40 isaki const audio_params_t *p, const audio_params_t *r, 552 1.40 isaki audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) 553 1.1 augustss { 554 1.23 kent struct aria_softc *sc; 555 1.1 augustss 556 1.23 kent sc = addr; 557 1.1 augustss 558 1.40 isaki /* *p and *r are the identical because !AUDIO_PROP_INDEPENDENT. */ 559 1.1 augustss sc->sc_encoding = p->encoding; 560 1.1 augustss sc->sc_precision = p->precision; 561 1.1 augustss sc->sc_chans = p->channels; 562 1.1 augustss sc->sc_rate = p->sample_rate; 563 1.1 augustss return 0; 564 1.1 augustss } 565 1.1 augustss 566 1.1 augustss /* 567 1.1 augustss * This is where all of the twiddling goes on. 568 1.1 augustss */ 569 1.1 augustss 570 1.1 augustss int 571 1.23 kent aria_commit_settings(void *addr) 572 1.1 augustss { 573 1.23 kent static u_char tones[16] = 574 1.1 augustss { 7, 6, 5, 4, 3, 2, 1, 0, 8, 9, 10, 11, 12, 13, 14, 15 }; 575 1.23 kent struct aria_softc *sc; 576 1.23 kent bus_space_tag_t iot; 577 1.23 kent bus_space_handle_t ioh; 578 1.1 augustss u_short format; 579 1.1 augustss u_short left, right; 580 1.1 augustss u_short samp; 581 1.1 augustss u_char i; 582 1.1 augustss 583 1.1 augustss DPRINTF(("aria_commit_settings\n")); 584 1.1 augustss 585 1.23 kent sc = addr; 586 1.23 kent iot = sc->sc_iot; 587 1.23 kent ioh = sc->sc_ioh; 588 1.1 augustss switch (sc->sc_rate) { 589 1.1 augustss case 7875: format = 0x00; samp = 0x60; break; 590 1.1 augustss case 11025: format = 0x00; samp = 0x40; break; 591 1.1 augustss case 15750: format = 0x10; samp = 0x60; break; 592 1.1 augustss case 22050: format = 0x10; samp = 0x40; break; 593 1.1 augustss case 31500: format = 0x10; samp = 0x20; break; 594 1.1 augustss case 44100: format = 0x20; samp = 0x00; break; 595 1.1 augustss default: format = 0x00; samp = 0x40; break;/* XXX can we get here? */ 596 1.1 augustss } 597 1.1 augustss 598 1.23 kent format |= (sc->sc_precision == 16) ? 0x02 : 0x00; 599 1.23 kent format |= (sc->sc_chans == 2) ? 1 : 0; 600 1.1 augustss samp |= bus_space_read_2(iot, ioh, ARIADSP_STATUS) & ~0x60; 601 1.1 augustss 602 1.1 augustss aria_sendcmd(sc, ARIADSPC_FORMAT, format, -1, -1); 603 1.1 augustss bus_space_write_2(iot, ioh, ARIADSP_CONTROL, samp); 604 1.1 augustss 605 1.1 augustss if (sc->sc_hardware&ARIA_MIXER) { 606 1.1 augustss for (i = 0; i < 6; i++) 607 1.1 augustss aria_set_mixer(sc, i); 608 1.23 kent 609 1.1 augustss if (sc->sc_chans==2) { 610 1.23 kent aria_sendcmd(sc, ARIADSPC_CHAN_VOL, ARIAR_PLAY_CHAN, 611 1.1 augustss ((sc->sc_gain[0]+sc->sc_gain[1])/2)<<7, 612 1.1 augustss -1); 613 1.23 kent aria_sendcmd(sc, ARIADSPC_CHAN_PAN, ARIAR_PLAY_CHAN, 614 1.1 augustss (sc->sc_gain[0]-sc->sc_gain[1])/4+0x40, 615 1.1 augustss -1); 616 1.1 augustss } else { 617 1.23 kent aria_sendcmd(sc, ARIADSPC_CHAN_VOL, ARIAR_PLAY_CHAN, 618 1.1 augustss sc->sc_gain[0]<<7, -1); 619 1.23 kent aria_sendcmd(sc, ARIADSPC_CHAN_PAN, ARIAR_PLAY_CHAN, 620 1.1 augustss 0x40, -1); 621 1.1 augustss } 622 1.1 augustss 623 1.23 kent aria_sendcmd(sc, ARIADSPC_MASMONMODE, 624 1.1 augustss sc->ariamix_master.num_channels != 2, -1, -1); 625 1.1 augustss 626 1.23 kent aria_sendcmd(sc, ARIADSPC_MIXERVOL, 0x0004, 627 1.23 kent sc->ariamix_master.level[0] << 7, 628 1.1 augustss sc->ariamix_master.level[1] << 7); 629 1.1 augustss 630 1.1 augustss /* Convert treble/bass from byte to soundcard style */ 631 1.1 augustss 632 1.23 kent left = (tones[(sc->ariamix_master.treble[0]>>4)&0x0f]<<8) | 633 1.1 augustss tones[(sc->ariamix_master.bass[0]>>4)&0x0f]; 634 1.23 kent right = (tones[(sc->ariamix_master.treble[1]>>4)&0x0f]<<8) | 635 1.1 augustss tones[(sc->ariamix_master.bass[1]>>4)&0x0f]; 636 1.1 augustss 637 1.1 augustss aria_sendcmd(sc, ARIADSPC_TONE, left, right, -1); 638 1.1 augustss } 639 1.1 augustss 640 1.1 augustss aria_sendcmd(sc, ARIADSPC_BLOCKSIZE, sc->sc_blocksize/2, -1, -1); 641 1.1 augustss 642 1.1 augustss /* 643 1.1 augustss * If we think that the card is recording or playing, start it up again here. 644 1.1 augustss * Some of the previous commands turn the channels off. 645 1.1 augustss */ 646 1.1 augustss 647 1.1 augustss if (sc->sc_record&(1<<ARIAR_RECORD_CHAN)) 648 1.1 augustss aria_sendcmd(sc, ARIADSPC_START_REC, ARIAR_RECORD_CHAN, -1,-1); 649 1.1 augustss 650 1.1 augustss if (sc->sc_play&(1<<ARIAR_PLAY_CHAN)) 651 1.1 augustss aria_sendcmd(sc, ARIADSPC_START_PLAY, ARIAR_PLAY_CHAN, -1, -1); 652 1.1 augustss 653 1.23 kent return 0; 654 1.1 augustss } 655 1.1 augustss 656 1.1 augustss void 657 1.23 kent aria_set_mixer(struct aria_softc *sc, int i) 658 1.1 augustss { 659 1.1 augustss u_char source; 660 1.23 kent 661 1.1 augustss switch(i) { 662 1.1 augustss case ARIAMIX_MIC_LVL: source = 0x0001; break; 663 1.1 augustss case ARIAMIX_CD_LVL: source = 0x0002; break; 664 1.1 augustss case ARIAMIX_LINE_IN_LVL: source = 0x0008; break; 665 1.1 augustss case ARIAMIX_TEL_LVL: source = 0x0020; break; 666 1.1 augustss case ARIAMIX_AUX_LVL: source = 0x0010; break; 667 1.1 augustss case ARIAMIX_DAC_LVL: source = 0x0004; break; 668 1.23 kent default: source = 0x0000; break; 669 1.1 augustss } 670 1.23 kent 671 1.1 augustss if (source != 0x0000 && source != 0x0004) { 672 1.1 augustss if (sc->aria_mix[i].mute == 1) 673 1.1 augustss aria_sendcmd(sc, ARIADSPC_INPMONMODE, source, 3, -1); 674 1.1 augustss else 675 1.23 kent aria_sendcmd(sc, ARIADSPC_INPMONMODE, source, 676 1.23 kent sc->aria_mix[i].num_channels != 2, -1); 677 1.23 kent 678 1.23 kent aria_sendcmd(sc, ARIADSPC_INPMONMODE, 0x8000|source, 679 1.1 augustss sc->aria_mix[i].num_channels != 2, -1); 680 1.23 kent aria_sendcmd(sc, ARIADSPC_MIXERVOL, source, 681 1.23 kent sc->aria_mix[i].level[0] << 7, 682 1.1 augustss sc->aria_mix[i].level[1] << 7); 683 1.1 augustss } 684 1.23 kent 685 1.1 augustss if (sc->aria_mix_source == i) { 686 1.1 augustss aria_sendcmd(sc, ARIADSPC_ADCSOURCE, source, -1, -1); 687 1.23 kent 688 1.1 augustss if (sc->sc_open & ARIAR_OPEN_RECORD) 689 1.1 augustss aria_sendcmd(sc, ARIADSPC_ADCCONTROL, 1, -1, -1); 690 1.23 kent else 691 1.1 augustss aria_sendcmd(sc, ARIADSPC_ADCCONTROL, 0, -1, -1); 692 1.1 augustss } 693 1.1 augustss } 694 1.1 augustss 695 1.1 augustss void 696 1.23 kent ariaclose(void *addr) 697 1.1 augustss { 698 1.23 kent struct aria_softc *sc; 699 1.1 augustss 700 1.23 kent sc = addr; 701 1.23 kent DPRINTF(("aria_close sc=%p\n", sc)); 702 1.1 augustss 703 1.1 augustss sc->sc_open = 0; 704 1.1 augustss 705 1.1 augustss if (aria_reset(sc) != 0) { 706 1.1 augustss delay(500); 707 1.1 augustss aria_reset(sc); 708 1.1 augustss } 709 1.1 augustss } 710 1.1 augustss 711 1.1 augustss /* 712 1.1 augustss * Reset the hardware. 713 1.1 augustss */ 714 1.1 augustss 715 1.23 kent int ariareset(bus_space_tag_t iot, bus_space_handle_t ioh) 716 1.1 augustss { 717 1.23 kent struct aria_softc tmp, *sc; 718 1.1 augustss 719 1.23 kent sc = &tmp; 720 1.1 augustss sc->sc_iot = iot; 721 1.1 augustss sc->sc_ioh = ioh; 722 1.1 augustss return aria_reset(sc); 723 1.1 augustss } 724 1.1 augustss 725 1.1 augustss int 726 1.23 kent aria_reset(struct aria_softc *sc) 727 1.1 augustss { 728 1.23 kent bus_space_tag_t iot; 729 1.23 kent bus_space_handle_t ioh; 730 1.23 kent int fail; 731 1.1 augustss int i; 732 1.1 augustss 733 1.23 kent iot = sc->sc_iot; 734 1.23 kent ioh = sc->sc_ioh; 735 1.23 kent fail = 0; 736 1.23 kent bus_space_write_2(iot, ioh, ARIADSP_CONTROL, 737 1.1 augustss ARIAR_ARIA_SYNTH | ARIAR_SR22K|ARIAR_DSPINTWR); 738 1.1 augustss aria_putdspmem(sc, 0x6102, 0); 739 1.1 augustss 740 1.1 augustss fail |= aria_sendcmd(sc, ARIADSPC_SYSINIT, 0x0000, 0x0000, 0x0000); 741 1.1 augustss 742 1.1 augustss for (i=0; i < ARIAR_NPOLL; i++) 743 1.1 augustss if (aria_getdspmem(sc, ARIAA_TASK_A) == 1) 744 1.1 augustss break; 745 1.1 augustss 746 1.23 kent bus_space_write_2(iot, ioh, ARIADSP_CONTROL, 747 1.1 augustss ARIAR_ARIA_SYNTH|ARIAR_SR22K | ARIAR_DSPINTWR | 748 1.1 augustss ARIAR_PCINTWR); 749 1.1 augustss fail |= aria_sendcmd(sc, ARIADSPC_MODE, ARIAV_MODE_NO_SYNTH,-1,-1); 750 1.1 augustss 751 1.23 kent return fail; 752 1.1 augustss } 753 1.1 augustss 754 1.1 augustss /* 755 1.1 augustss * Lower-level routines 756 1.1 augustss */ 757 1.1 augustss 758 1.1 augustss void 759 1.23 kent aria_putdspmem(struct aria_softc *sc, u_short loc, u_short val) 760 1.1 augustss { 761 1.23 kent bus_space_tag_t iot; 762 1.23 kent bus_space_handle_t ioh; 763 1.23 kent 764 1.23 kent iot = sc->sc_iot; 765 1.23 kent ioh = sc->sc_ioh; 766 1.1 augustss bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, loc); 767 1.1 augustss bus_space_write_2(iot, ioh, ARIADSP_DMADATA, val); 768 1.1 augustss } 769 1.1 augustss 770 1.1 augustss u_short 771 1.23 kent aria_getdspmem(struct aria_softc *sc, u_short loc) 772 1.1 augustss { 773 1.23 kent bus_space_tag_t iot; 774 1.23 kent bus_space_handle_t ioh; 775 1.23 kent 776 1.23 kent iot = sc->sc_iot; 777 1.23 kent ioh = sc->sc_ioh; 778 1.1 augustss bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, loc); 779 1.1 augustss return bus_space_read_2(iot, ioh, ARIADSP_DMADATA); 780 1.1 augustss } 781 1.1 augustss 782 1.1 augustss /* 783 1.1 augustss * aria_sendcmd() 784 1.1 augustss * each full DSP command is unified into this 785 1.1 augustss * function. 786 1.1 augustss */ 787 1.1 augustss 788 1.1 augustss #define ARIASEND(data, flag) \ 789 1.1 augustss for (i = ARIAR_NPOLL; \ 790 1.1 augustss (bus_space_read_2(iot, ioh, ARIADSP_STATUS) & ARIAR_BUSY) && i>0; \ 791 1.1 augustss i--) \ 792 1.1 augustss ; \ 793 1.1 augustss if (bus_space_read_2(iot, ioh, ARIADSP_STATUS) & ARIAR_BUSY) \ 794 1.1 augustss fail |= flag; \ 795 1.1 augustss bus_space_write_2(iot, ioh, ARIADSP_WRITE, (u_short)data) 796 1.1 augustss 797 1.1 augustss int 798 1.23 kent aria_sendcmd(struct aria_softc *sc, u_short command, 799 1.23 kent int arg1, int arg2, int arg3) 800 1.23 kent { 801 1.23 kent bus_space_tag_t iot; 802 1.23 kent bus_space_handle_t ioh; 803 1.23 kent int i, fail; 804 1.1 augustss 805 1.23 kent iot = sc->sc_iot; 806 1.23 kent ioh = sc->sc_ioh; 807 1.23 kent fail = 0; 808 1.1 augustss ARIASEND(command, 1); 809 1.1 augustss if (arg1 != -1) { 810 1.1 augustss ARIASEND(arg1, 2); 811 1.1 augustss } 812 1.1 augustss if (arg2 != -1) { 813 1.1 augustss ARIASEND(arg2, 4); 814 1.1 augustss } 815 1.1 augustss if (arg3 != -1) { 816 1.1 augustss ARIASEND(arg3, 8); 817 1.1 augustss } 818 1.1 augustss ARIASEND(ARIADSPC_TERM, 16); 819 1.23 kent 820 1.1 augustss if (fail) { 821 1.1 augustss sc->sc_sendcmd_err++; 822 1.1 augustss #ifdef AUDIO_DEBUG 823 1.1 augustss DPRINTF(("aria_sendcmd: failure=(%d) cmd=(0x%x) fail=(0x%x)\n", 824 1.1 augustss sc->sc_sendcmd_err, command, fail)); 825 1.1 augustss #endif 826 1.1 augustss return -1; 827 1.1 augustss } 828 1.1 augustss 829 1.1 augustss return 0; 830 1.1 augustss } 831 1.1 augustss #undef ARIASEND 832 1.1 augustss 833 1.1 augustss int 834 1.23 kent aria_halt_input(void *addr) 835 1.1 augustss { 836 1.23 kent struct aria_softc *sc; 837 1.1 augustss 838 1.23 kent sc = addr; 839 1.1 augustss DPRINTF(("aria_halt_input\n")); 840 1.1 augustss 841 1.1 augustss if (sc->sc_record & (1<<0)) { 842 1.1 augustss aria_sendcmd(sc, ARIADSPC_STOP_REC, 0, -1, -1); 843 1.1 augustss sc->sc_record &= ~(1<<0); 844 1.20 mycroft sc->sc_rdiobuffer = 0; 845 1.1 augustss } 846 1.1 augustss 847 1.23 kent return 0; 848 1.1 augustss } 849 1.1 augustss 850 1.1 augustss int 851 1.23 kent aria_halt_output(void *addr) 852 1.1 augustss { 853 1.23 kent struct aria_softc *sc; 854 1.1 augustss 855 1.23 kent sc = addr; 856 1.1 augustss DPRINTF(("aria_halt_output\n")); 857 1.1 augustss 858 1.1 augustss if (sc->sc_play & (1<<1)) { 859 1.1 augustss aria_sendcmd(sc, ARIADSPC_STOP_PLAY, 1, -1, -1); 860 1.1 augustss sc->sc_play &= ~(1<<1); 861 1.20 mycroft sc->sc_pdiobuffer = 0; 862 1.1 augustss } 863 1.1 augustss 864 1.23 kent return 0; 865 1.1 augustss } 866 1.1 augustss 867 1.1 augustss /* 868 1.1 augustss * Here we just set up the buffers. If we receive 869 1.1 augustss * an interrupt without these set, it is ignored. 870 1.1 augustss */ 871 1.1 augustss 872 1.1 augustss int 873 1.23 kent aria_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg) 874 1.1 augustss { 875 1.23 kent struct aria_softc *sc; 876 1.1 augustss 877 1.23 kent sc = addr; 878 1.23 kent DPRINTF(("aria_start_input %d @ %p\n", cc, p)); 879 1.1 augustss 880 1.1 augustss if (cc != sc->sc_blocksize) { 881 1.1 augustss DPRINTF(("aria_start_input reqsize %d not sc_blocksize %d\n", 882 1.1 augustss cc, sc->sc_blocksize)); 883 1.1 augustss return EINVAL; 884 1.1 augustss } 885 1.1 augustss 886 1.1 augustss sc->sc_rarg = arg; 887 1.1 augustss sc->sc_rintr = intr; 888 1.1 augustss sc->sc_rdiobuffer = p; 889 1.1 augustss 890 1.1 augustss if (!(sc->sc_record&(1<<ARIAR_RECORD_CHAN))) { 891 1.1 augustss aria_sendcmd(sc, ARIADSPC_START_REC, ARIAR_RECORD_CHAN, -1,-1); 892 1.1 augustss sc->sc_record |= (1<<ARIAR_RECORD_CHAN); 893 1.1 augustss } 894 1.1 augustss 895 1.1 augustss return 0; 896 1.1 augustss } 897 1.1 augustss 898 1.1 augustss int 899 1.23 kent aria_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg) 900 1.1 augustss { 901 1.23 kent struct aria_softc *sc; 902 1.1 augustss 903 1.23 kent sc = addr; 904 1.23 kent DPRINTF(("aria_start_output %d @ %p\n", cc, p)); 905 1.1 augustss 906 1.1 augustss if (cc != sc->sc_blocksize) { 907 1.1 augustss DPRINTF(("aria_start_output reqsize %d not sc_blocksize %d\n", 908 1.1 augustss cc, sc->sc_blocksize)); 909 1.1 augustss return EINVAL; 910 1.1 augustss } 911 1.1 augustss 912 1.1 augustss sc->sc_parg = arg; 913 1.1 augustss sc->sc_pintr = intr; 914 1.1 augustss sc->sc_pdiobuffer = p; 915 1.1 augustss 916 1.1 augustss if (!(sc->sc_play&(1<<ARIAR_PLAY_CHAN))) { 917 1.1 augustss aria_sendcmd(sc, ARIADSPC_START_PLAY, ARIAR_PLAY_CHAN, -1, -1); 918 1.1 augustss sc->sc_play |= (1<<ARIAR_PLAY_CHAN); 919 1.1 augustss } 920 1.1 augustss 921 1.1 augustss return 0; 922 1.1 augustss } 923 1.1 augustss 924 1.1 augustss /* 925 1.1 augustss * Process an interrupt. This should be a 926 1.1 augustss * request (from the card) to write or read 927 1.1 augustss * samples. 928 1.1 augustss */ 929 1.1 augustss int 930 1.23 kent aria_intr(void *arg) 931 1.1 augustss { 932 1.23 kent struct aria_softc *sc; 933 1.23 kent bus_space_tag_t iot; 934 1.23 kent bus_space_handle_t ioh; 935 1.23 kent u_short *pdata; 936 1.23 kent u_short *rdata; 937 1.1 augustss u_short address; 938 1.1 augustss 939 1.23 kent sc = arg; 940 1.34 jmcneill 941 1.34 jmcneill mutex_spin_enter(&sc->sc_intr_lock); 942 1.34 jmcneill 943 1.23 kent iot = sc->sc_iot; 944 1.23 kent ioh = sc->sc_ioh; 945 1.23 kent pdata = sc->sc_pdiobuffer; 946 1.23 kent rdata = sc->sc_rdiobuffer; 947 1.1 augustss #if 0 /* XXX -- BAD BAD BAD (That this is #define'd out */ 948 1.1 augustss DPRINTF(("Checking to see if this is our intr\n")); 949 1.1 augustss 950 1.34 jmcneill if ((inw(iobase) & 1) != 0x1) { 951 1.34 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 952 1.1 augustss return 0; /* not for us */ 953 1.34 jmcneill } 954 1.1 augustss #endif 955 1.1 augustss 956 1.1 augustss sc->sc_interrupts++; 957 1.1 augustss 958 1.1 augustss DPRINTF(("aria_intr\n")); 959 1.1 augustss 960 1.1 augustss if ((sc->sc_open & ARIAR_OPEN_PLAY) && (pdata!=NULL)) { 961 1.33 jakllsch DPRINTF(("aria_intr play=(%p)\n", pdata)); 962 1.1 augustss address = 0x8000 - 2*(sc->sc_blocksize); 963 1.1 augustss address+= aria_getdspmem(sc, ARIAA_PLAY_FIFO_A); 964 1.1 augustss bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, address); 965 1.23 kent bus_space_write_multi_2(iot, ioh, ARIADSP_DMADATA, pdata, 966 1.1 augustss sc->sc_blocksize / 2); 967 1.1 augustss if (sc->sc_pintr != NULL) 968 1.1 augustss (*sc->sc_pintr)(sc->sc_parg); 969 1.1 augustss } 970 1.1 augustss 971 1.1 augustss if ((sc->sc_open & ARIAR_OPEN_RECORD) && (rdata!=NULL)) { 972 1.33 jakllsch DPRINTF(("aria_intr record=(%p)\n", rdata)); 973 1.1 augustss address = 0x8000 - (sc->sc_blocksize); 974 1.1 augustss address+= aria_getdspmem(sc, ARIAA_REC_FIFO_A); 975 1.1 augustss bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, address); 976 1.23 kent bus_space_read_multi_2(iot, ioh, ARIADSP_DMADATA, rdata, 977 1.1 augustss sc->sc_blocksize / 2); 978 1.1 augustss if (sc->sc_rintr != NULL) 979 1.1 augustss (*sc->sc_rintr)(sc->sc_rarg); 980 1.1 augustss } 981 1.1 augustss 982 1.1 augustss aria_sendcmd(sc, ARIADSPC_TRANSCOMPLETE, -1, -1, -1); 983 1.1 augustss 984 1.34 jmcneill mutex_spin_exit(&sc->sc_intr_lock); 985 1.1 augustss return 1; 986 1.1 augustss } 987 1.1 augustss 988 1.1 augustss int 989 1.23 kent aria_mixer_set_port(void *addr, mixer_ctrl_t *cp) 990 1.1 augustss { 991 1.23 kent struct aria_softc *sc; 992 1.23 kent int error; 993 1.1 augustss 994 1.1 augustss DPRINTF(("aria_mixer_set_port\n")); 995 1.23 kent sc = addr; 996 1.23 kent error = EINVAL; 997 1.1 augustss 998 1.1 augustss /* This could be done better, no mixer still has some controls. */ 999 1.1 augustss if (!(ARIA_MIXER & sc->sc_hardware)) 1000 1.1 augustss return ENXIO; 1001 1.1 augustss 1002 1.1 augustss if (cp->type == AUDIO_MIXER_VALUE) { 1003 1.1 augustss mixer_level_t *mv = &cp->un.value; 1004 1.1 augustss switch (cp->dev) { 1005 1.1 augustss case ARIAMIX_MIC_LVL: 1006 1.1 augustss if (mv->num_channels == 1 || mv->num_channels == 2) { 1007 1.23 kent sc->aria_mix[ARIAMIX_MIC_LVL].num_channels = 1008 1.1 augustss mv->num_channels; 1009 1.23 kent sc->aria_mix[ARIAMIX_MIC_LVL].level[0] = 1010 1.1 augustss mv->level[0]; 1011 1.23 kent sc->aria_mix[ARIAMIX_MIC_LVL].level[1] = 1012 1.1 augustss mv->level[1]; 1013 1.1 augustss error = 0; 1014 1.1 augustss } 1015 1.1 augustss break; 1016 1.23 kent 1017 1.1 augustss case ARIAMIX_LINE_IN_LVL: 1018 1.1 augustss if (mv->num_channels == 1 || mv->num_channels == 2) { 1019 1.1 augustss sc->aria_mix[ARIAMIX_LINE_IN_LVL].num_channels= 1020 1.1 augustss mv->num_channels; 1021 1.23 kent sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[0] = 1022 1.1 augustss mv->level[0]; 1023 1.23 kent sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[1] = 1024 1.1 augustss mv->level[1]; 1025 1.1 augustss error = 0; 1026 1.1 augustss } 1027 1.1 augustss break; 1028 1.23 kent 1029 1.1 augustss case ARIAMIX_CD_LVL: 1030 1.1 augustss if (mv->num_channels == 1 || mv->num_channels == 2) { 1031 1.23 kent sc->aria_mix[ARIAMIX_CD_LVL].num_channels = 1032 1.1 augustss mv->num_channels; 1033 1.23 kent sc->aria_mix[ARIAMIX_CD_LVL].level[0] = 1034 1.1 augustss mv->level[0]; 1035 1.23 kent sc->aria_mix[ARIAMIX_CD_LVL].level[1] = 1036 1.1 augustss mv->level[1]; 1037 1.1 augustss error = 0; 1038 1.1 augustss } 1039 1.1 augustss break; 1040 1.23 kent 1041 1.1 augustss case ARIAMIX_TEL_LVL: 1042 1.1 augustss if (mv->num_channels == 1) { 1043 1.23 kent sc->aria_mix[ARIAMIX_TEL_LVL].num_channels = 1044 1.1 augustss mv->num_channels; 1045 1.23 kent sc->aria_mix[ARIAMIX_TEL_LVL].level[0] = 1046 1.1 augustss mv->level[0]; 1047 1.1 augustss error = 0; 1048 1.1 augustss } 1049 1.1 augustss break; 1050 1.23 kent 1051 1.1 augustss case ARIAMIX_DAC_LVL: 1052 1.1 augustss if (mv->num_channels == 1 || mv->num_channels == 2) { 1053 1.23 kent sc->aria_mix[ARIAMIX_DAC_LVL].num_channels = 1054 1.1 augustss mv->num_channels; 1055 1.23 kent sc->aria_mix[ARIAMIX_DAC_LVL].level[0] = 1056 1.1 augustss mv->level[0]; 1057 1.23 kent sc->aria_mix[ARIAMIX_DAC_LVL].level[1] = 1058 1.1 augustss mv->level[1]; 1059 1.1 augustss error = 0; 1060 1.1 augustss } 1061 1.1 augustss break; 1062 1.1 augustss 1063 1.1 augustss case ARIAMIX_AUX_LVL: 1064 1.1 augustss if (mv->num_channels == 1 || mv->num_channels == 2) { 1065 1.23 kent sc->aria_mix[ARIAMIX_AUX_LVL].num_channels = 1066 1.1 augustss mv->num_channels; 1067 1.23 kent sc->aria_mix[ARIAMIX_AUX_LVL].level[0] = 1068 1.1 augustss mv->level[0]; 1069 1.23 kent sc->aria_mix[ARIAMIX_AUX_LVL].level[1] = 1070 1.1 augustss mv->level[1]; 1071 1.1 augustss error = 0; 1072 1.1 augustss } 1073 1.1 augustss break; 1074 1.23 kent 1075 1.1 augustss case ARIAMIX_MASTER_LVL: 1076 1.1 augustss if (mv->num_channels == 1 || mv->num_channels == 2) { 1077 1.23 kent sc->ariamix_master.num_channels = 1078 1.1 augustss mv->num_channels; 1079 1.1 augustss sc->ariamix_master.level[0] = mv->level[0]; 1080 1.1 augustss sc->ariamix_master.level[1] = mv->level[1]; 1081 1.1 augustss error = 0; 1082 1.1 augustss } 1083 1.1 augustss break; 1084 1.23 kent 1085 1.1 augustss case ARIAMIX_MASTER_TREBLE: 1086 1.1 augustss if (mv->num_channels == 2) { 1087 1.23 kent sc->ariamix_master.treble[0] = 1088 1.1 augustss mv->level[0] == 0 ? 1 : mv->level[0]; 1089 1.23 kent sc->ariamix_master.treble[1] = 1090 1.1 augustss mv->level[1] == 0 ? 1 : mv->level[1]; 1091 1.1 augustss error = 0; 1092 1.1 augustss } 1093 1.1 augustss break; 1094 1.1 augustss case ARIAMIX_MASTER_BASS: 1095 1.1 augustss if (mv->num_channels == 2) { 1096 1.23 kent sc->ariamix_master.bass[0] = 1097 1.1 augustss mv->level[0] == 0 ? 1 : mv->level[0]; 1098 1.23 kent sc->ariamix_master.bass[1] = 1099 1.1 augustss mv->level[1] == 0 ? 1 : mv->level[1]; 1100 1.1 augustss error = 0; 1101 1.1 augustss } 1102 1.1 augustss break; 1103 1.1 augustss case ARIAMIX_OUT_LVL: 1104 1.1 augustss if (mv->num_channels == 1 || mv->num_channels == 2) { 1105 1.1 augustss sc->sc_gain[0] = mv->level[0]; 1106 1.1 augustss sc->sc_gain[1] = mv->level[1]; 1107 1.1 augustss error = 0; 1108 1.1 augustss } 1109 1.1 augustss break; 1110 1.1 augustss default: 1111 1.23 kent break; 1112 1.1 augustss } 1113 1.1 augustss } 1114 1.1 augustss 1115 1.1 augustss if (cp->type == AUDIO_MIXER_ENUM) 1116 1.1 augustss switch(cp->dev) { 1117 1.1 augustss case ARIAMIX_RECORD_SOURCE: 1118 1.1 augustss if (cp->un.ord>=0 && cp->un.ord<=6) { 1119 1.1 augustss sc->aria_mix_source = cp->un.ord; 1120 1.1 augustss error = 0; 1121 1.1 augustss } 1122 1.1 augustss break; 1123 1.1 augustss 1124 1.1 augustss case ARIAMIX_MIC_MUTE: 1125 1.1 augustss if (cp->un.ord == 0 || cp->un.ord == 1) { 1126 1.1 augustss sc->aria_mix[ARIAMIX_MIC_LVL].mute =cp->un.ord; 1127 1.1 augustss error = 0; 1128 1.1 augustss } 1129 1.1 augustss break; 1130 1.1 augustss 1131 1.1 augustss case ARIAMIX_LINE_IN_MUTE: 1132 1.1 augustss if (cp->un.ord == 0 || cp->un.ord == 1) { 1133 1.23 kent sc->aria_mix[ARIAMIX_LINE_IN_LVL].mute = 1134 1.1 augustss cp->un.ord; 1135 1.1 augustss error = 0; 1136 1.1 augustss } 1137 1.1 augustss break; 1138 1.1 augustss 1139 1.1 augustss case ARIAMIX_CD_MUTE: 1140 1.1 augustss if (cp->un.ord == 0 || cp->un.ord == 1) { 1141 1.1 augustss sc->aria_mix[ARIAMIX_CD_LVL].mute = cp->un.ord; 1142 1.1 augustss error = 0; 1143 1.1 augustss } 1144 1.1 augustss break; 1145 1.1 augustss 1146 1.1 augustss case ARIAMIX_DAC_MUTE: 1147 1.1 augustss if (cp->un.ord == 0 || cp->un.ord == 1) { 1148 1.1 augustss sc->aria_mix[ARIAMIX_DAC_LVL].mute =cp->un.ord; 1149 1.1 augustss error = 0; 1150 1.1 augustss } 1151 1.1 augustss break; 1152 1.1 augustss 1153 1.1 augustss case ARIAMIX_AUX_MUTE: 1154 1.1 augustss if (cp->un.ord == 0 || cp->un.ord == 1) { 1155 1.1 augustss sc->aria_mix[ARIAMIX_AUX_LVL].mute =cp->un.ord; 1156 1.1 augustss error = 0; 1157 1.1 augustss } 1158 1.1 augustss break; 1159 1.1 augustss 1160 1.1 augustss case ARIAMIX_TEL_MUTE: 1161 1.1 augustss if (cp->un.ord == 0 || cp->un.ord == 1) { 1162 1.1 augustss sc->aria_mix[ARIAMIX_TEL_LVL].mute =cp->un.ord; 1163 1.1 augustss error = 0; 1164 1.1 augustss } 1165 1.1 augustss break; 1166 1.1 augustss 1167 1.1 augustss default: 1168 1.1 augustss /* NOTREACHED */ 1169 1.1 augustss return ENXIO; 1170 1.1 augustss } 1171 1.1 augustss 1172 1.23 kent return error; 1173 1.1 augustss } 1174 1.1 augustss 1175 1.1 augustss int 1176 1.23 kent aria_mixer_get_port(void *addr, mixer_ctrl_t *cp) 1177 1.1 augustss { 1178 1.23 kent struct aria_softc *sc; 1179 1.23 kent int error; 1180 1.1 augustss 1181 1.1 augustss DPRINTF(("aria_mixer_get_port\n")); 1182 1.23 kent sc = addr; 1183 1.23 kent error = EINVAL; 1184 1.1 augustss 1185 1.1 augustss /* This could be done better, no mixer still has some controls. */ 1186 1.1 augustss if (!(ARIA_MIXER&sc->sc_hardware)) 1187 1.1 augustss return ENXIO; 1188 1.1 augustss 1189 1.1 augustss switch (cp->dev) { 1190 1.1 augustss case ARIAMIX_MIC_LVL: 1191 1.1 augustss if (cp->type == AUDIO_MIXER_VALUE) { 1192 1.23 kent cp->un.value.num_channels = 1193 1.1 augustss sc->aria_mix[ARIAMIX_MIC_LVL].num_channels; 1194 1.23 kent cp->un.value.level[0] = 1195 1.1 augustss sc->aria_mix[ARIAMIX_MIC_LVL].level[0]; 1196 1.23 kent cp->un.value.level[1] = 1197 1.1 augustss sc->aria_mix[ARIAMIX_MIC_LVL].level[1]; 1198 1.1 augustss error = 0; 1199 1.1 augustss } 1200 1.1 augustss break; 1201 1.23 kent 1202 1.1 augustss case ARIAMIX_LINE_IN_LVL: 1203 1.1 augustss if (cp->type == AUDIO_MIXER_VALUE) { 1204 1.23 kent cp->un.value.num_channels = 1205 1.1 augustss sc->aria_mix[ARIAMIX_LINE_IN_LVL].num_channels; 1206 1.23 kent cp->un.value.level[0] = 1207 1.1 augustss sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[0]; 1208 1.23 kent cp->un.value.level[1] = 1209 1.1 augustss sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[1]; 1210 1.1 augustss error = 0; 1211 1.1 augustss } 1212 1.1 augustss break; 1213 1.1 augustss 1214 1.1 augustss case ARIAMIX_CD_LVL: 1215 1.1 augustss if (cp->type == AUDIO_MIXER_VALUE) { 1216 1.23 kent cp->un.value.num_channels = 1217 1.1 augustss sc->aria_mix[ARIAMIX_CD_LVL].num_channels; 1218 1.23 kent cp->un.value.level[0] = 1219 1.1 augustss sc->aria_mix[ARIAMIX_CD_LVL].level[0]; 1220 1.23 kent cp->un.value.level[1] = 1221 1.1 augustss sc->aria_mix[ARIAMIX_CD_LVL].level[1]; 1222 1.1 augustss error = 0; 1223 1.1 augustss } 1224 1.1 augustss break; 1225 1.1 augustss 1226 1.1 augustss case ARIAMIX_TEL_LVL: 1227 1.1 augustss if (cp->type == AUDIO_MIXER_VALUE) { 1228 1.23 kent cp->un.value.num_channels = 1229 1.1 augustss sc->aria_mix[ARIAMIX_TEL_LVL].num_channels; 1230 1.23 kent cp->un.value.level[0] = 1231 1.1 augustss sc->aria_mix[ARIAMIX_TEL_LVL].level[0]; 1232 1.1 augustss error = 0; 1233 1.1 augustss } 1234 1.1 augustss break; 1235 1.1 augustss case ARIAMIX_DAC_LVL: 1236 1.1 augustss if (cp->type == AUDIO_MIXER_VALUE) { 1237 1.23 kent cp->un.value.num_channels = 1238 1.1 augustss sc->aria_mix[ARIAMIX_DAC_LVL].num_channels; 1239 1.23 kent cp->un.value.level[0] = 1240 1.1 augustss sc->aria_mix[ARIAMIX_DAC_LVL].level[0]; 1241 1.23 kent cp->un.value.level[1] = 1242 1.1 augustss sc->aria_mix[ARIAMIX_DAC_LVL].level[1]; 1243 1.1 augustss error = 0; 1244 1.1 augustss } 1245 1.1 augustss break; 1246 1.1 augustss 1247 1.1 augustss case ARIAMIX_AUX_LVL: 1248 1.1 augustss if (cp->type == AUDIO_MIXER_VALUE) { 1249 1.23 kent cp->un.value.num_channels = 1250 1.1 augustss sc->aria_mix[ARIAMIX_AUX_LVL].num_channels; 1251 1.23 kent cp->un.value.level[0] = 1252 1.1 augustss sc->aria_mix[ARIAMIX_AUX_LVL].level[0]; 1253 1.23 kent cp->un.value.level[1] = 1254 1.1 augustss sc->aria_mix[ARIAMIX_AUX_LVL].level[1]; 1255 1.1 augustss error = 0; 1256 1.1 augustss } 1257 1.1 augustss break; 1258 1.1 augustss 1259 1.1 augustss case ARIAMIX_MIC_MUTE: 1260 1.1 augustss if (cp->type == AUDIO_MIXER_ENUM) { 1261 1.1 augustss cp->un.ord = sc->aria_mix[ARIAMIX_MIC_LVL].mute; 1262 1.1 augustss error = 0; 1263 1.1 augustss } 1264 1.1 augustss break; 1265 1.1 augustss 1266 1.1 augustss case ARIAMIX_LINE_IN_MUTE: 1267 1.1 augustss if (cp->type == AUDIO_MIXER_ENUM) { 1268 1.1 augustss cp->un.ord = sc->aria_mix[ARIAMIX_LINE_IN_LVL].mute; 1269 1.1 augustss error = 0; 1270 1.1 augustss } 1271 1.1 augustss break; 1272 1.1 augustss 1273 1.1 augustss case ARIAMIX_CD_MUTE: 1274 1.1 augustss if (cp->type == AUDIO_MIXER_ENUM) { 1275 1.1 augustss cp->un.ord = sc->aria_mix[ARIAMIX_CD_LVL].mute; 1276 1.1 augustss error = 0; 1277 1.1 augustss } 1278 1.1 augustss break; 1279 1.1 augustss 1280 1.1 augustss case ARIAMIX_DAC_MUTE: 1281 1.1 augustss if (cp->type == AUDIO_MIXER_ENUM) { 1282 1.1 augustss cp->un.ord = sc->aria_mix[ARIAMIX_DAC_LVL].mute; 1283 1.1 augustss error = 0; 1284 1.1 augustss } 1285 1.1 augustss break; 1286 1.1 augustss 1287 1.1 augustss case ARIAMIX_AUX_MUTE: 1288 1.1 augustss if (cp->type == AUDIO_MIXER_ENUM) { 1289 1.1 augustss cp->un.ord = sc->aria_mix[ARIAMIX_AUX_LVL].mute; 1290 1.1 augustss error = 0; 1291 1.1 augustss } 1292 1.1 augustss break; 1293 1.1 augustss 1294 1.1 augustss case ARIAMIX_TEL_MUTE: 1295 1.1 augustss if (cp->type == AUDIO_MIXER_ENUM) { 1296 1.1 augustss cp->un.ord = sc->aria_mix[ARIAMIX_TEL_LVL].mute; 1297 1.1 augustss error = 0; 1298 1.1 augustss } 1299 1.1 augustss break; 1300 1.1 augustss 1301 1.1 augustss case ARIAMIX_MASTER_LVL: 1302 1.1 augustss if (cp->type == AUDIO_MIXER_VALUE) { 1303 1.23 kent cp->un.value.num_channels = 1304 1.1 augustss sc->ariamix_master.num_channels; 1305 1.1 augustss cp->un.value.level[0] = sc->ariamix_master.level[0]; 1306 1.1 augustss cp->un.value.level[1] = sc->ariamix_master.level[1]; 1307 1.1 augustss error = 0; 1308 1.1 augustss } 1309 1.1 augustss break; 1310 1.1 augustss 1311 1.1 augustss case ARIAMIX_MASTER_TREBLE: 1312 1.1 augustss if (cp->type == AUDIO_MIXER_VALUE) { 1313 1.1 augustss cp->un.value.num_channels = 2; 1314 1.1 augustss cp->un.value.level[0] = sc->ariamix_master.treble[0]; 1315 1.1 augustss cp->un.value.level[1] = sc->ariamix_master.treble[1]; 1316 1.1 augustss error = 0; 1317 1.1 augustss } 1318 1.1 augustss break; 1319 1.1 augustss 1320 1.1 augustss case ARIAMIX_MASTER_BASS: 1321 1.1 augustss if (cp->type == AUDIO_MIXER_VALUE) { 1322 1.1 augustss cp->un.value.num_channels = 2; 1323 1.1 augustss cp->un.value.level[0] = sc->ariamix_master.bass[0]; 1324 1.1 augustss cp->un.value.level[1] = sc->ariamix_master.bass[1]; 1325 1.1 augustss error = 0; 1326 1.1 augustss } 1327 1.1 augustss break; 1328 1.1 augustss 1329 1.1 augustss case ARIAMIX_OUT_LVL: 1330 1.1 augustss if (cp->type == AUDIO_MIXER_VALUE) { 1331 1.1 augustss cp->un.value.num_channels = sc->sc_chans; 1332 1.1 augustss cp->un.value.level[0] = sc->sc_gain[0]; 1333 1.1 augustss cp->un.value.level[1] = sc->sc_gain[1]; 1334 1.1 augustss error = 0; 1335 1.1 augustss } 1336 1.1 augustss break; 1337 1.1 augustss case ARIAMIX_RECORD_SOURCE: 1338 1.1 augustss if (cp->type == AUDIO_MIXER_ENUM) { 1339 1.1 augustss cp->un.ord = sc->aria_mix_source; 1340 1.1 augustss error = 0; 1341 1.1 augustss } 1342 1.1 augustss break; 1343 1.1 augustss 1344 1.1 augustss default: 1345 1.1 augustss return ENXIO; 1346 1.1 augustss /* NOT REACHED */ 1347 1.1 augustss } 1348 1.1 augustss 1349 1.23 kent return error; 1350 1.1 augustss } 1351 1.1 augustss 1352 1.1 augustss int 1353 1.23 kent aria_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip) 1354 1.1 augustss { 1355 1.23 kent struct aria_softc *sc; 1356 1.1 augustss 1357 1.1 augustss DPRINTF(("aria_mixer_query_devinfo\n")); 1358 1.23 kent sc = addr; 1359 1.1 augustss 1360 1.1 augustss /* This could be done better, no mixer still has some controls. */ 1361 1.1 augustss if (!(ARIA_MIXER & sc->sc_hardware)) 1362 1.1 augustss return ENXIO; 1363 1.1 augustss 1364 1.1 augustss dip->prev = dip->next = AUDIO_MIXER_LAST; 1365 1.1 augustss 1366 1.1 augustss switch(dip->index) { 1367 1.1 augustss case ARIAMIX_MIC_LVL: 1368 1.1 augustss dip->type = AUDIO_MIXER_VALUE; 1369 1.1 augustss dip->mixer_class = ARIAMIX_INPUT_CLASS; 1370 1.1 augustss dip->next = ARIAMIX_MIC_MUTE; 1371 1.1 augustss strcpy(dip->label.name, AudioNmicrophone); 1372 1.1 augustss dip->un.v.num_channels = 2; 1373 1.1 augustss strcpy(dip->un.v.units.name, AudioNvolume); 1374 1.1 augustss break; 1375 1.1 augustss 1376 1.1 augustss case ARIAMIX_LINE_IN_LVL: 1377 1.1 augustss dip->type = AUDIO_MIXER_VALUE; 1378 1.1 augustss dip->mixer_class = ARIAMIX_INPUT_CLASS; 1379 1.1 augustss dip->next = ARIAMIX_LINE_IN_MUTE; 1380 1.1 augustss strcpy(dip->label.name, AudioNline); 1381 1.1 augustss dip->un.v.num_channels = 2; 1382 1.1 augustss strcpy(dip->un.v.units.name, AudioNvolume); 1383 1.1 augustss break; 1384 1.1 augustss 1385 1.1 augustss case ARIAMIX_CD_LVL: 1386 1.1 augustss dip->type = AUDIO_MIXER_VALUE; 1387 1.1 augustss dip->mixer_class = ARIAMIX_INPUT_CLASS; 1388 1.1 augustss dip->next = ARIAMIX_CD_MUTE; 1389 1.1 augustss strcpy(dip->label.name, AudioNcd); 1390 1.1 augustss dip->un.v.num_channels = 2; 1391 1.1 augustss strcpy(dip->un.v.units.name, AudioNvolume); 1392 1.1 augustss break; 1393 1.1 augustss 1394 1.1 augustss case ARIAMIX_TEL_LVL: 1395 1.1 augustss dip->type = AUDIO_MIXER_VALUE; 1396 1.1 augustss dip->mixer_class = ARIAMIX_INPUT_CLASS; 1397 1.1 augustss dip->next = ARIAMIX_TEL_MUTE; 1398 1.1 augustss strcpy(dip->label.name, "telephone"); 1399 1.1 augustss dip->un.v.num_channels = 1; 1400 1.1 augustss strcpy(dip->un.v.units.name, AudioNvolume); 1401 1.1 augustss break; 1402 1.1 augustss 1403 1.1 augustss case ARIAMIX_DAC_LVL: 1404 1.1 augustss dip->type = AUDIO_MIXER_VALUE; 1405 1.1 augustss dip->mixer_class = ARIAMIX_INPUT_CLASS; 1406 1.1 augustss dip->next = ARIAMIX_DAC_MUTE; 1407 1.1 augustss strcpy(dip->label.name, AudioNdac); 1408 1.1 augustss dip->un.v.num_channels = 1; 1409 1.1 augustss strcpy(dip->un.v.units.name, AudioNvolume); 1410 1.1 augustss break; 1411 1.1 augustss 1412 1.1 augustss case ARIAMIX_AUX_LVL: 1413 1.1 augustss dip->type = AUDIO_MIXER_VALUE; 1414 1.1 augustss dip->mixer_class = ARIAMIX_INPUT_CLASS; 1415 1.1 augustss dip->next = ARIAMIX_AUX_MUTE; 1416 1.1 augustss strcpy(dip->label.name, AudioNoutput); 1417 1.1 augustss dip->un.v.num_channels = 1; 1418 1.1 augustss strcpy(dip->un.v.units.name, AudioNvolume); 1419 1.1 augustss break; 1420 1.1 augustss 1421 1.1 augustss case ARIAMIX_MIC_MUTE: 1422 1.1 augustss dip->prev = ARIAMIX_MIC_LVL; 1423 1.1 augustss goto mute; 1424 1.1 augustss 1425 1.1 augustss case ARIAMIX_LINE_IN_MUTE: 1426 1.1 augustss dip->prev = ARIAMIX_LINE_IN_LVL; 1427 1.1 augustss goto mute; 1428 1.23 kent 1429 1.1 augustss case ARIAMIX_CD_MUTE: 1430 1.1 augustss dip->prev = ARIAMIX_CD_LVL; 1431 1.1 augustss goto mute; 1432 1.23 kent 1433 1.1 augustss case ARIAMIX_DAC_MUTE: 1434 1.1 augustss dip->prev = ARIAMIX_DAC_LVL; 1435 1.1 augustss goto mute; 1436 1.1 augustss 1437 1.1 augustss case ARIAMIX_AUX_MUTE: 1438 1.1 augustss dip->prev = ARIAMIX_AUX_LVL; 1439 1.1 augustss goto mute; 1440 1.1 augustss 1441 1.1 augustss case ARIAMIX_TEL_MUTE: 1442 1.1 augustss dip->prev = ARIAMIX_TEL_LVL; 1443 1.1 augustss goto mute; 1444 1.1 augustss 1445 1.1 augustss mute: 1446 1.1 augustss dip->mixer_class = ARIAMIX_INPUT_CLASS; 1447 1.1 augustss dip->type = AUDIO_MIXER_ENUM; 1448 1.1 augustss strcpy(dip->label.name, AudioNmute); 1449 1.1 augustss dip->un.e.num_mem = 2; 1450 1.1 augustss strcpy(dip->un.e.member[0].label.name, AudioNoff); 1451 1.1 augustss dip->un.e.member[0].ord = 0; 1452 1.1 augustss strcpy(dip->un.e.member[1].label.name, AudioNon); 1453 1.1 augustss dip->un.e.member[1].ord = 1; 1454 1.1 augustss break; 1455 1.1 augustss 1456 1.1 augustss case ARIAMIX_MASTER_LVL: 1457 1.1 augustss dip->type = AUDIO_MIXER_VALUE; 1458 1.1 augustss dip->mixer_class = ARIAMIX_OUTPUT_CLASS; 1459 1.1 augustss dip->next = AUDIO_MIXER_LAST; 1460 1.1 augustss strcpy(dip->label.name, AudioNvolume); 1461 1.1 augustss dip->un.v.num_channels = 2; 1462 1.1 augustss strcpy(dip->un.v.units.name, AudioNvolume); 1463 1.1 augustss break; 1464 1.1 augustss 1465 1.1 augustss case ARIAMIX_MASTER_TREBLE: 1466 1.1 augustss dip->type = AUDIO_MIXER_VALUE; 1467 1.1 augustss dip->mixer_class = ARIAMIX_EQ_CLASS; 1468 1.1 augustss strcpy(dip->label.name, AudioNtreble); 1469 1.1 augustss dip->un.v.num_channels = 2; 1470 1.1 augustss strcpy(dip->un.v.units.name, AudioNtreble); 1471 1.1 augustss break; 1472 1.1 augustss 1473 1.1 augustss case ARIAMIX_MASTER_BASS: 1474 1.1 augustss dip->type = AUDIO_MIXER_VALUE; 1475 1.1 augustss dip->mixer_class = ARIAMIX_EQ_CLASS; 1476 1.1 augustss strcpy(dip->label.name, AudioNbass); 1477 1.1 augustss dip->un.v.num_channels = 2; 1478 1.1 augustss strcpy(dip->un.v.units.name, AudioNbass); 1479 1.1 augustss break; 1480 1.1 augustss 1481 1.1 augustss case ARIAMIX_OUT_LVL: 1482 1.1 augustss dip->type = AUDIO_MIXER_VALUE; 1483 1.1 augustss dip->mixer_class = ARIAMIX_OUTPUT_CLASS; 1484 1.1 augustss strcpy(dip->label.name, AudioNoutput); 1485 1.1 augustss dip->un.v.num_channels = 2; 1486 1.1 augustss strcpy(dip->un.v.units.name, AudioNvolume); 1487 1.1 augustss break; 1488 1.1 augustss 1489 1.1 augustss case ARIAMIX_RECORD_SOURCE: 1490 1.1 augustss dip->mixer_class = ARIAMIX_RECORD_CLASS; 1491 1.1 augustss dip->type = AUDIO_MIXER_ENUM; 1492 1.1 augustss strcpy(dip->label.name, AudioNsource); 1493 1.1 augustss dip->un.e.num_mem = 6; 1494 1.1 augustss strcpy(dip->un.e.member[0].label.name, AudioNoutput); 1495 1.1 augustss dip->un.e.member[0].ord = ARIAMIX_AUX_LVL; 1496 1.1 augustss strcpy(dip->un.e.member[1].label.name, AudioNmicrophone); 1497 1.1 augustss dip->un.e.member[1].ord = ARIAMIX_MIC_LVL; 1498 1.1 augustss strcpy(dip->un.e.member[2].label.name, AudioNdac); 1499 1.1 augustss dip->un.e.member[2].ord = ARIAMIX_DAC_LVL; 1500 1.1 augustss strcpy(dip->un.e.member[3].label.name, AudioNline); 1501 1.1 augustss dip->un.e.member[3].ord = ARIAMIX_LINE_IN_LVL; 1502 1.1 augustss strcpy(dip->un.e.member[4].label.name, AudioNcd); 1503 1.1 augustss dip->un.e.member[4].ord = ARIAMIX_CD_LVL; 1504 1.1 augustss strcpy(dip->un.e.member[5].label.name, "telephone"); 1505 1.1 augustss dip->un.e.member[5].ord = ARIAMIX_TEL_LVL; 1506 1.1 augustss break; 1507 1.1 augustss 1508 1.1 augustss case ARIAMIX_INPUT_CLASS: 1509 1.1 augustss dip->type = AUDIO_MIXER_CLASS; 1510 1.1 augustss dip->mixer_class = ARIAMIX_INPUT_CLASS; 1511 1.1 augustss strcpy(dip->label.name, AudioCinputs); 1512 1.1 augustss break; 1513 1.1 augustss 1514 1.1 augustss case ARIAMIX_OUTPUT_CLASS: 1515 1.1 augustss dip->type = AUDIO_MIXER_CLASS; 1516 1.1 augustss dip->mixer_class = ARIAMIX_OUTPUT_CLASS; 1517 1.1 augustss strcpy(dip->label.name, AudioCoutputs); 1518 1.1 augustss break; 1519 1.1 augustss 1520 1.1 augustss case ARIAMIX_RECORD_CLASS: 1521 1.1 augustss dip->type = AUDIO_MIXER_CLASS; 1522 1.1 augustss dip->mixer_class = ARIAMIX_RECORD_CLASS; 1523 1.1 augustss strcpy(dip->label.name, AudioCrecord); 1524 1.1 augustss break; 1525 1.1 augustss 1526 1.1 augustss case ARIAMIX_EQ_CLASS: 1527 1.1 augustss dip->type = AUDIO_MIXER_CLASS; 1528 1.1 augustss dip->mixer_class = ARIAMIX_EQ_CLASS; 1529 1.1 augustss strcpy(dip->label.name, AudioCequalization); 1530 1.1 augustss break; 1531 1.1 augustss 1532 1.1 augustss default: 1533 1.1 augustss return ENXIO; 1534 1.1 augustss /*NOTREACHED*/ 1535 1.1 augustss } 1536 1.1 augustss return 0; 1537 1.1 augustss } 1538 1.34 jmcneill 1539 1.36 jakllsch void 1540 1.34 jmcneill aria_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread) 1541 1.34 jmcneill { 1542 1.34 jmcneill struct aria_softc *sc; 1543 1.34 jmcneill 1544 1.34 jmcneill sc = addr; 1545 1.34 jmcneill *intr = &sc->sc_intr_lock; 1546 1.34 jmcneill *thread = &sc->sc_lock; 1547 1.34 jmcneill } 1548