1 1.48 isaki /* $NetBSD: aucc.c,v 1.48 2020/02/29 06:03:55 isaki Exp $ */ 2 1.20 augustss 3 1.1 is /* 4 1.24 is * Copyright (c) 1999 Bernardo Innocenti 5 1.24 is * All rights reserved. 6 1.24 is * 7 1.1 is * Copyright (c) 1997 Stephan Thesing 8 1.1 is * All rights reserved. 9 1.1 is * 10 1.1 is * Redistribution and use in source and binary forms, with or without 11 1.1 is * modification, are permitted provided that the following conditions 12 1.1 is * are met: 13 1.1 is * 1. Redistributions of source code must retain the above copyright 14 1.1 is * notice, this list of conditions and the following disclaimer. 15 1.1 is * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 is * notice, this list of conditions and the following disclaimer in the 17 1.1 is * documentation and/or other materials provided with the distribution. 18 1.1 is * 3. All advertising materials mentioning features or use of this software 19 1.1 is * must display the following acknowledgement: 20 1.1 is * This product includes software developed by Stephan Thesing. 21 1.1 is * 4. The name of the author may not be used to endorse or promote products 22 1.1 is * derived from this software without specific prior written permission 23 1.1 is * 24 1.1 is * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 1.1 is * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 1.1 is * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 1.1 is * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 28 1.1 is * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 1.1 is * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 1.1 is * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 1.1 is * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 1.1 is * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 1.1 is * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 1.1 is */ 35 1.1 is 36 1.24 is /* TODO: 37 1.24 is * 38 1.24 is * - channel allocation is wrong for 14bit mono 39 1.24 is * - perhaps use a calibration table for better 14bit output 40 1.40 lukem * - set 31 kHz AGA video mode to allow 44.1 kHz even if grfcc is missing 41 1.24 is * in the kernel 42 1.24 is * - 14bit output requires maximum volume 43 1.24 is */ 44 1.24 is 45 1.1 is #include "aucc.h" 46 1.1 is #if NAUCC > 0 47 1.30 aymeric 48 1.30 aymeric #include <sys/cdefs.h> 49 1.48 isaki __KERNEL_RCSID(0, "$NetBSD: aucc.c,v 1.48 2020/02/29 06:03:55 isaki Exp $"); 50 1.5 is 51 1.1 is #include <sys/param.h> 52 1.1 is #include <sys/systm.h> 53 1.1 is #include <sys/errno.h> 54 1.1 is #include <sys/ioctl.h> 55 1.1 is #include <sys/device.h> 56 1.1 is #include <sys/proc.h> 57 1.1 is #include <machine/cpu.h> 58 1.1 is 59 1.1 is #include <sys/audioio.h> 60 1.45 isaki #include <dev/audio/audio_if.h> 61 1.45 isaki #include <dev/audio/audiovar.h> /* for AUDIO_MIN_FREQUENCY */ 62 1.45 isaki 63 1.1 is #include <amiga/amiga/cc.h> 64 1.1 is #include <amiga/amiga/custom.h> 65 1.1 is #include <amiga/amiga/device.h> 66 1.1 is #include <amiga/dev/auccvar.h> 67 1.27 is 68 1.27 is #include "opt_lev6_defer.h" 69 1.1 is 70 1.7 is 71 1.7 is #ifdef LEV6_DEFER 72 1.7 is #define AUCC_MAXINT 3 73 1.7 is #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2) 74 1.7 is #else 75 1.7 is #define AUCC_MAXINT 4 76 1.7 is #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3) 77 1.7 is #endif 78 1.7 is /* this unconditionally; we may use AUD3 as slave channel with LEV6_DEFER */ 79 1.7 is #define AUCC_ALLDMAF (DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3) 80 1.7 is 81 1.1 is #ifdef AUDIO_DEBUG 82 1.29 aymeric /*extern printf(const char *,...);*/ 83 1.1 is int auccdebug = 1; 84 1.1 is #define DPRINTF(x) if (auccdebug) printf x 85 1.1 is #else 86 1.1 is #define DPRINTF(x) 87 1.1 is #endif 88 1.1 is 89 1.1 is /* clock frequency.. */ 90 1.29 aymeric extern int eclockfreq; 91 1.1 is 92 1.1 is 93 1.1 is /* hw audio ch */ 94 1.1 is extern struct audio_channel channel[4]; 95 1.1 is 96 1.1 is 97 1.1 is /* 98 1.1 is * Software state. 99 1.1 is */ 100 1.1 is struct aucc_softc { 101 1.1 is aucc_data_t sc_channel[4]; /* per channel freq, ... */ 102 1.1 is u_int sc_encoding; /* encoding AUDIO_ENCODING_.*/ 103 1.1 is int sc_channels; /* # of channels used */ 104 1.24 is int sc_precision; /* 8 or 16 bits */ 105 1.24 is int sc_14bit; /* 14bit output enabled */ 106 1.1 is 107 1.1 is int sc_intrcnt; /* interrupt count */ 108 1.37 kent int sc_channelmask; /* which channels are used ? */ 109 1.29 aymeric void (*sc_decodefunc)(u_char **, u_char *, int); 110 1.24 is /* pointer to format conversion routine */ 111 1.41 jmcneill 112 1.41 jmcneill kmutex_t sc_lock; 113 1.41 jmcneill kmutex_t sc_intr_lock; 114 1.1 is }; 115 1.1 is 116 1.1 is /* interrupt interfaces */ 117 1.29 aymeric void aucc_inthdl(int); 118 1.1 is 119 1.1 is /* forward declarations */ 120 1.29 aymeric static int init_aucc(struct aucc_softc *); 121 1.29 aymeric static u_int freqtoper(u_int); 122 1.29 aymeric static u_int pertofreq(u_int); 123 1.1 is 124 1.1 is /* autoconfiguration driver */ 125 1.42 chs void auccattach(device_t, device_t, void *); 126 1.42 chs int auccmatch(device_t, cfdata_t, void *); 127 1.1 is 128 1.42 chs CFATTACH_DECL_NEW(aucc, sizeof(struct aucc_softc), 129 1.32 thorpej auccmatch, auccattach, NULL, NULL); 130 1.1 is 131 1.1 is struct audio_device aucc_device = { 132 1.1 is "Amiga-audio", 133 1.24 is "2.0", 134 1.1 is "aucc" 135 1.1 is }; 136 1.1 is 137 1.1 is 138 1.37 kent struct aucc_softc *aucc = NULL; 139 1.1 is 140 1.1 is 141 1.1 is /* 142 1.1 is * Define our interface to the higher level audio driver. 143 1.1 is */ 144 1.29 aymeric int aucc_open(void *, int); 145 1.29 aymeric void aucc_close(void *); 146 1.36 kent int aucc_set_out_sr(void *, u_int); 147 1.45 isaki int aucc_query_format(void *, audio_format_query_t *); 148 1.36 kent int aucc_round_blocksize(void *, int, int, const audio_params_t *); 149 1.29 aymeric int aucc_commit_settings(void *); 150 1.29 aymeric int aucc_start_output(void *, void *, int, void (*)(void *), void *); 151 1.29 aymeric int aucc_start_input(void *, void *, int, void (*)(void *), void *); 152 1.29 aymeric int aucc_halt_output(void *); 153 1.29 aymeric int aucc_halt_input(void *); 154 1.29 aymeric int aucc_getdev(void *, struct audio_device *); 155 1.29 aymeric int aucc_set_port(void *, mixer_ctrl_t *); 156 1.29 aymeric int aucc_get_port(void *, mixer_ctrl_t *); 157 1.29 aymeric int aucc_query_devinfo(void *, mixer_devinfo_t *); 158 1.29 aymeric void aucc_encode(int, int, int, int, u_char *, u_short **); 159 1.45 isaki int aucc_set_format(void *, int, 160 1.45 isaki const audio_params_t *, const audio_params_t *, 161 1.45 isaki audio_filter_reg_t *, audio_filter_reg_t *); 162 1.29 aymeric int aucc_get_props(void *); 163 1.41 jmcneill void aucc_get_locks(void *, kmutex_t **, kmutex_t **); 164 1.29 aymeric 165 1.29 aymeric 166 1.29 aymeric static void aucc_decode_slinear16_1ch(u_char **, u_char *, int); 167 1.29 aymeric static void aucc_decode_slinear16_2ch(u_char **, u_char *, int); 168 1.29 aymeric static void aucc_decode_slinear16_3ch(u_char **, u_char *, int); 169 1.29 aymeric static void aucc_decode_slinear16_4ch(u_char **, u_char *, int); 170 1.29 aymeric 171 1.24 is 172 1.35 yamt const struct audio_hw_if sa_hw_if = { 173 1.44 isaki .open = aucc_open, 174 1.44 isaki .close = aucc_close, 175 1.45 isaki .query_format = aucc_query_format, 176 1.45 isaki .set_format = aucc_set_format, 177 1.44 isaki .round_blocksize = aucc_round_blocksize, 178 1.44 isaki .commit_settings = aucc_commit_settings, 179 1.44 isaki .start_output = aucc_start_output, 180 1.44 isaki .start_input = aucc_start_input, 181 1.44 isaki .halt_output = aucc_halt_output, 182 1.44 isaki .halt_input = aucc_halt_input, 183 1.44 isaki .getdev = aucc_getdev, 184 1.44 isaki .set_port = aucc_set_port, 185 1.44 isaki .get_port = aucc_get_port, 186 1.44 isaki .query_devinfo = aucc_query_devinfo, 187 1.44 isaki .get_props = aucc_get_props, 188 1.44 isaki .get_locks = aucc_get_locks, 189 1.1 is }; 190 1.1 is 191 1.45 isaki /* 192 1.45 isaki * XXX *1 How lower limit of frequency should be? same as audio(4)? 193 1.45 isaki * XXX *2 Should avoid a magic number at the upper limit of frequency. 194 1.45 isaki * XXX *3 In fact, there is a number in this range that have minimal errors. 195 1.45 isaki * It would be better if there is a mechanism which such frequency 196 1.45 isaki * is prioritized. 197 1.45 isaki * XXX *4 3/4ch modes use 8bits, 1/2ch modes use 14bits, 198 1.45 isaki * so I imagined that 1/2ch modes are better. 199 1.45 isaki */ 200 1.45 isaki #define AUCC_FORMAT(prio, ch, chmask) \ 201 1.45 isaki { \ 202 1.45 isaki .mode = AUMODE_PLAY, \ 203 1.45 isaki .priority = (prio), \ 204 1.45 isaki .encoding = AUDIO_ENCODING_SLINEAR_BE, \ 205 1.45 isaki .validbits = 16, \ 206 1.45 isaki .precision = 16, \ 207 1.45 isaki .channels = (ch), \ 208 1.45 isaki .channel_mask = (chmask), \ 209 1.45 isaki .frequency_type = 0, \ 210 1.45 isaki .frequency = { AUDIO_MIN_FREQUENCY, 28867 }, \ 211 1.45 isaki } 212 1.45 isaki static const struct audio_format aucc_formats[] = { 213 1.45 isaki AUCC_FORMAT(1, 1, AUFMT_MONAURAL), 214 1.45 isaki AUCC_FORMAT(1, 2, AUFMT_STEREO), 215 1.45 isaki AUCC_FORMAT(0, 3, AUFMT_UNKNOWN_POSITION), 216 1.45 isaki AUCC_FORMAT(0, 4, AUFMT_UNKNOWN_POSITION), 217 1.45 isaki }; 218 1.45 isaki #define AUCC_NFORMATS __arraycount(aucc_formats) 219 1.45 isaki 220 1.1 is /* autoconfig routines */ 221 1.1 is 222 1.1 is int 223 1.42 chs auccmatch(device_t parent, cfdata_t cf, void *aux) 224 1.1 is { 225 1.25 kleink static int aucc_matched = 0; 226 1.25 kleink 227 1.25 kleink if (!matchname((char *)aux, "aucc") || 228 1.1 is #ifdef DRACO 229 1.25 kleink is_draco() || 230 1.1 is #endif 231 1.25 kleink aucc_matched) 232 1.25 kleink return 0; 233 1.1 is 234 1.25 kleink aucc_matched = 1; 235 1.25 kleink return 1; 236 1.1 is } 237 1.1 is 238 1.1 is /* 239 1.1 is * Audio chip found. 240 1.1 is */ 241 1.1 is void 242 1.42 chs auccattach(device_t parent, device_t self, void *args) 243 1.1 is { 244 1.37 kent struct aucc_softc *sc; 245 1.37 kent int i; 246 1.1 is 247 1.42 chs sc = device_private(self); 248 1.1 is printf("\n"); 249 1.1 is 250 1.37 kent if ((i=init_aucc(sc))) { 251 1.1 is printf("audio: no chipmem\n"); 252 1.1 is return; 253 1.1 is } 254 1.1 is 255 1.42 chs audio_attach_mi(&sa_hw_if, sc, self); 256 1.1 is } 257 1.1 is 258 1.1 is 259 1.1 is static int 260 1.29 aymeric init_aucc(struct aucc_softc *sc) 261 1.1 is { 262 1.37 kent int i, err; 263 1.1 is 264 1.37 kent err = 0; 265 1.1 is /* init values per channel */ 266 1.37 kent for (i = 0; i < 4; i++) { 267 1.37 kent sc->sc_channel[i].nd_freq = 8000; 268 1.37 kent sc->sc_channel[i].nd_per = freqtoper(8000); 269 1.37 kent sc->sc_channel[i].nd_busy = 0; 270 1.37 kent sc->sc_channel[i].nd_dma = alloc_chipmem(AUDIO_BUF_SIZE*2); 271 1.37 kent if (sc->sc_channel[i].nd_dma == NULL) 272 1.37 kent err = 1; 273 1.37 kent sc->sc_channel[i].nd_dmalength = 0; 274 1.37 kent sc->sc_channel[i].nd_volume = 64; 275 1.37 kent sc->sc_channel[i].nd_intr = NULL; 276 1.37 kent sc->sc_channel[i].nd_intrdata = NULL; 277 1.37 kent sc->sc_channel[i].nd_doublebuf = 0; 278 1.34 wiz DPRINTF(("DMA buffer for channel %d is %p\n", i, 279 1.1 is sc->sc_channel[i].nd_dma)); 280 1.1 is } 281 1.1 is 282 1.1 is if (err) { 283 1.37 kent for (i = 0; i < 4; i++) 284 1.1 is if (sc->sc_channel[i].nd_dma) 285 1.1 is free_chipmem(sc->sc_channel[i].nd_dma); 286 1.1 is } 287 1.1 is 288 1.37 kent sc->sc_channels = 1; 289 1.37 kent sc->sc_channelmask = 0xf; 290 1.45 isaki sc->sc_precision = 16; 291 1.45 isaki sc->sc_14bit = 1; 292 1.45 isaki sc->sc_encoding = AUDIO_ENCODING_SLINEAR_BE; 293 1.45 isaki sc->sc_decodefunc = aucc_decode_slinear16_2ch; 294 1.1 is 295 1.34 wiz /* clear interrupts and DMA: */ 296 1.7 is custom.intena = AUCC_ALLINTF; 297 1.24 is custom.dmacon = AUCC_ALLDMAF; 298 1.1 is 299 1.41 jmcneill mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 300 1.41 jmcneill mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED); 301 1.41 jmcneill 302 1.1 is return err; 303 1.1 is } 304 1.1 is 305 1.1 is int 306 1.29 aymeric aucc_open(void *addr, int flags) 307 1.1 is { 308 1.37 kent struct aucc_softc *sc; 309 1.16 augustss int i; 310 1.1 is 311 1.37 kent sc = addr; 312 1.16 augustss DPRINTF(("sa_open: unit %p\n",sc)); 313 1.1 is 314 1.37 kent for (i = 0; i < AUCC_MAXINT; i++) { 315 1.37 kent sc->sc_channel[i].nd_intr = NULL; 316 1.37 kent sc->sc_channel[i].nd_intrdata = NULL; 317 1.1 is } 318 1.37 kent aucc = sc; 319 1.37 kent sc->sc_channelmask = 0xf; 320 1.1 is 321 1.38 christos DPRINTF(("saopen: ok -> sc=%p\n",sc)); 322 1.1 is 323 1.37 kent return 0; 324 1.1 is } 325 1.1 is 326 1.1 is void 327 1.29 aymeric aucc_close(void *addr) 328 1.1 is { 329 1.1 is 330 1.1 is DPRINTF(("sa_close: closed.\n")); 331 1.1 is } 332 1.1 is 333 1.1 is int 334 1.36 kent aucc_set_out_sr(void *addr, u_int sr) 335 1.1 is { 336 1.37 kent struct aucc_softc *sc; 337 1.1 is u_long per; 338 1.37 kent int i; 339 1.1 is 340 1.37 kent sc = addr; 341 1.37 kent per = freqtoper(sr); 342 1.37 kent if (per > 0xffff) 343 1.1 is return EINVAL; 344 1.37 kent sr = pertofreq(per); 345 1.1 is 346 1.37 kent for (i = 0; i < 4; i++) { 347 1.37 kent sc->sc_channel[i].nd_freq = sr; 348 1.37 kent sc->sc_channel[i].nd_per = per; 349 1.1 is } 350 1.1 is 351 1.37 kent return 0; 352 1.1 is } 353 1.1 is 354 1.1 is int 355 1.45 isaki aucc_query_format(void *addr, audio_format_query_t *afp) 356 1.1 is { 357 1.37 kent 358 1.45 isaki return audio_query_format(aucc_formats, AUCC_NFORMATS, afp); 359 1.1 is } 360 1.1 is 361 1.1 is int 362 1.45 isaki aucc_set_format(void *addr, int setmode, 363 1.45 isaki const audio_params_t *p, const audio_params_t *r, 364 1.45 isaki audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) 365 1.1 is { 366 1.37 kent struct aucc_softc *sc; 367 1.8 is 368 1.37 kent sc = addr; 369 1.45 isaki KASSERT((setmode & AUMODE_RECORD) == 0); 370 1.8 is 371 1.9 is #ifdef AUCCDEBUG 372 1.45 isaki printf("%s(setmode 0x%x," 373 1.45 isaki "enc %u bits %u, chn %u, sr %u)\n", setmode, 374 1.45 isaki p->encoding, p->precision, p->channels, p->sample_rate); 375 1.24 is #endif 376 1.24 is 377 1.45 isaki switch (p->channels) { 378 1.45 isaki case 1: 379 1.45 isaki sc->sc_decodefunc = aucc_decode_slinear16_1ch; 380 1.45 isaki break; 381 1.45 isaki case 2: 382 1.45 isaki sc->sc_decodefunc = aucc_decode_slinear16_2ch; 383 1.45 isaki break; 384 1.45 isaki case 3: 385 1.45 isaki sc->sc_decodefunc = aucc_decode_slinear16_3ch; 386 1.24 is break; 387 1.45 isaki case 4: 388 1.45 isaki sc->sc_decodefunc = aucc_decode_slinear16_4ch; 389 1.24 is break; 390 1.1 is default: 391 1.1 is return EINVAL; 392 1.1 is } 393 1.1 is 394 1.8 is sc->sc_encoding = p->encoding; 395 1.24 is sc->sc_precision = p->precision; 396 1.24 is sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2)); 397 1.24 is sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels; 398 1.8 is 399 1.8 is return aucc_set_out_sr(addr, p->sample_rate); 400 1.1 is } 401 1.1 is 402 1.1 is int 403 1.36 kent aucc_round_blocksize(void *addr, int blk, 404 1.36 kent int mode, const audio_params_t *param) 405 1.1 is { 406 1.37 kent 407 1.48 isaki if (blk > AUDIO_BUF_SIZE) 408 1.48 isaki blk = AUDIO_BUF_SIZE; 409 1.48 isaki 410 1.48 isaki blk = rounddown(blk, param->channels * param->precision / NBBY); 411 1.48 isaki return blk; 412 1.1 is } 413 1.1 is 414 1.1 is int 415 1.29 aymeric aucc_commit_settings(void *addr) 416 1.1 is { 417 1.37 kent struct aucc_softc *sc; 418 1.37 kent int i; 419 1.1 is 420 1.1 is DPRINTF(("sa_commit.\n")); 421 1.1 is 422 1.37 kent sc = addr; 423 1.37 kent for (i = 0; i < 4; i++) { 424 1.37 kent custom.aud[i].vol = sc->sc_channel[i].nd_volume; 425 1.37 kent custom.aud[i].per = sc->sc_channel[i].nd_per; 426 1.1 is } 427 1.1 is 428 1.1 is DPRINTF(("commit done\n")); 429 1.1 is 430 1.37 kent return 0; 431 1.1 is } 432 1.1 is 433 1.1 is static int masks[4] = {1,3,7,15}; /* masks for n first channels */ 434 1.1 is static int masks2[4] = {1,2,4,8}; 435 1.1 is 436 1.1 is int 437 1.29 aymeric aucc_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg) 438 1.1 is { 439 1.8 is struct aucc_softc *sc; 440 1.8 is int mask; 441 1.24 is int i, j, k, len; 442 1.24 is u_char *dmap[4]; 443 1.8 is 444 1.1 is 445 1.8 is sc = addr; 446 1.8 is mask = sc->sc_channelmask; 447 1.1 is 448 1.8 is dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL; 449 1.1 is 450 1.1 is DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg)); 451 1.1 is 452 1.10 is if (sc->sc_channels > 1) 453 1.24 is mask &= masks[sc->sc_channels - 1]; 454 1.10 is /* we use first sc_channels channels */ 455 1.24 is if (mask == 0) /* active and used channels are disjoint */ 456 1.1 is return EINVAL; 457 1.1 is 458 1.37 kent for (i = 0; i < 4; i++) { 459 1.24 is /* channels available ? */ 460 1.24 is if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy)) 461 1.1 is return EBUSY; /* channel is busy */ 462 1.24 is if (channel[i].isaudio == -1) 463 1.1 is return EBUSY; /* system uses them */ 464 1.1 is } 465 1.1 is 466 1.1 is /* enable interrupt on 1st channel */ 467 1.24 is for (i = j = 0; i < AUCC_MAXINT; i++) { 468 1.24 is if (masks2[i] & mask) { 469 1.1 is DPRINTF(("first channel is %d\n",i)); 470 1.37 kent j = i; 471 1.37 kent sc->sc_channel[i].nd_intr = intr; 472 1.37 kent sc->sc_channel[i].nd_intrdata = arg; 473 1.1 is break; 474 1.1 is } 475 1.1 is } 476 1.1 is 477 1.8 is DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1], 478 1.37 kent dmap[2], dmap[3], mask)); 479 1.8 is 480 1.34 wiz /* disable ints, DMA for channels, until all parameters set */ 481 1.8 is /* XXX dont disable DMA! custom.dmacon=mask;*/ 482 1.24 is custom.intreq = mask << INTB_AUD0; 483 1.24 is custom.intena = mask << INTB_AUD0; 484 1.1 is 485 1.34 wiz /* copy data to DMA buffer */ 486 1.29 aymeric 487 1.8 is if (sc->sc_channels == 1) { 488 1.8 is dmap[0] = 489 1.8 is dmap[1] = 490 1.8 is dmap[2] = 491 1.24 is dmap[3] = (u_char *)sc->sc_channel[j].nd_dma; 492 1.37 kent } else { 493 1.37 kent for (k = 0; k < 4; k++) { 494 1.24 is if (masks2[k+j] & mask) 495 1.24 is dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma; 496 1.8 is } 497 1.8 is } 498 1.8 is 499 1.8 is sc->sc_channel[j].nd_doublebuf ^= 1; 500 1.8 is if (sc->sc_channel[j].nd_doublebuf) { 501 1.24 is dmap[0] += AUDIO_BUF_SIZE; 502 1.24 is dmap[1] += AUDIO_BUF_SIZE; 503 1.24 is dmap[2] += AUDIO_BUF_SIZE; 504 1.24 is dmap[3] += AUDIO_BUF_SIZE; 505 1.8 is } 506 1.1 is 507 1.37 kent /* 508 1.37 kent * compute output length in bytes per channel. 509 1.24 is * divide by two only for 16bit->8bit conversion. 510 1.24 is */ 511 1.24 is len = cc / sc->sc_channels; 512 1.24 is if (!sc->sc_14bit && (sc->sc_precision == 16)) 513 1.24 is len /= 2; 514 1.24 is 515 1.24 is /* call audio decoding routine */ 516 1.24 is sc->sc_decodefunc (dmap, (u_char *)p, len); 517 1.1 is 518 1.34 wiz /* DMA buffers: we use same buffer 4 all channels 519 1.34 wiz * write DMA location and length 520 1.24 is */ 521 1.24 is for (i = k = 0; i < 4; i++) { 522 1.8 is if (masks2[i] & mask) { 523 1.1 is DPRINTF(("turning channel %d on\n",i)); 524 1.24 is /* sc->sc_channel[i].nd_busy=1; */ 525 1.24 is channel[i].isaudio = 1; 526 1.24 is channel[i].play_count = 1; 527 1.24 is channel[i].handler = NULL; 528 1.24 is custom.aud[i].per = sc->sc_channel[i].nd_per; 529 1.24 is if (sc->sc_14bit && (i > 1)) 530 1.24 is custom.aud[i].vol = 1; 531 1.24 is else 532 1.24 is custom.aud[i].vol = sc->sc_channel[i].nd_volume; 533 1.8 is custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]); 534 1.24 is custom.aud[i].len = len / 2; 535 1.24 is sc->sc_channel[i].nd_mask = mask; 536 1.1 is DPRINTF(("per is %d, vol is %d, len is %d\n",\ 537 1.8 is sc->sc_channel[i].nd_per, 538 1.24 is sc->sc_channel[i].nd_volume, len)); 539 1.1 is } 540 1.1 is } 541 1.1 is 542 1.37 kent channel[j].handler = aucc_inthdl; 543 1.1 is 544 1.1 is /* enable ints */ 545 1.24 is custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0); 546 1.1 is 547 1.24 is DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0))); 548 1.1 is 549 1.34 wiz /* enable DMA */ 550 1.24 is custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask; 551 1.1 is 552 1.34 wiz DPRINTF(("enabled DMA, mask=0x%x\n",mask)); 553 1.1 is 554 1.37 kent return 0; 555 1.1 is } 556 1.1 is 557 1.1 is /* ARGSUSED */ 558 1.1 is int 559 1.29 aymeric aucc_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg) 560 1.1 is { 561 1.1 is 562 1.1 is return ENXIO; /* no input */ 563 1.1 is } 564 1.1 is 565 1.1 is int 566 1.29 aymeric aucc_halt_output(void *addr) 567 1.1 is { 568 1.37 kent struct aucc_softc *sc; 569 1.37 kent int i; 570 1.1 is 571 1.1 is /* XXX only halt, if input is also halted ?? */ 572 1.37 kent sc = addr; 573 1.34 wiz /* stop DMA, etc */ 574 1.7 is custom.intena = AUCC_ALLINTF; 575 1.7 is custom.dmacon = AUCC_ALLDMAF; 576 1.1 is /* mark every busy unit idle */ 577 1.37 kent for (i = 0; i < 4; i++) { 578 1.37 kent sc->sc_channel[i].nd_busy = sc->sc_channel[i].nd_mask = 0; 579 1.37 kent channel[i].isaudio = 0; 580 1.37 kent channel[i].play_count = 0; 581 1.1 is } 582 1.1 is 583 1.37 kent return 0; 584 1.1 is } 585 1.1 is 586 1.1 is int 587 1.29 aymeric aucc_halt_input(void *addr) 588 1.1 is { 589 1.37 kent 590 1.1 is /* no input */ 591 1.1 is return ENXIO; 592 1.1 is } 593 1.1 is 594 1.1 is int 595 1.29 aymeric aucc_getdev(void *addr, struct audio_device *retp) 596 1.1 is { 597 1.37 kent 598 1.37 kent *retp = aucc_device; 599 1.37 kent return 0; 600 1.1 is } 601 1.1 is 602 1.1 is int 603 1.29 aymeric aucc_set_port(void *addr, mixer_ctrl_t *cp) 604 1.1 is { 605 1.37 kent struct aucc_softc *sc; 606 1.37 kent int i,j; 607 1.1 is 608 1.1 is DPRINTF(("aucc_set_port: port=%d", cp->dev)); 609 1.37 kent sc = addr; 610 1.1 is switch (cp->type) { 611 1.1 is case AUDIO_MIXER_SET: 612 1.37 kent if (cp->dev != AUCC_CHANNELS) 613 1.1 is return EINVAL; 614 1.37 kent i = cp->un.mask; 615 1.37 kent if ((i < 1) || (i > 15)) 616 1.1 is return EINVAL; 617 1.24 is 618 1.37 kent sc->sc_channelmask = i; 619 1.1 is break; 620 1.1 is 621 1.1 is case AUDIO_MIXER_VALUE: 622 1.37 kent i = cp->un.value.num_channels; 623 1.37 kent if ((i < 1) || (i > 4)) 624 1.1 is return EINVAL; 625 1.1 is 626 1.10 is #ifdef __XXXwhatsthat 627 1.37 kent if (cp->dev != AUCC_VOLUME) 628 1.1 is return EINVAL; 629 1.10 is #endif 630 1.1 is 631 1.1 is /* set volume for channel 0..i-1 */ 632 1.21 is 633 1.21 is /* evil workaround for xanim bug, IMO */ 634 1.21 is if ((sc->sc_channels == 1) && (i == 2)) { 635 1.29 aymeric sc->sc_channel[0].nd_volume = 636 1.29 aymeric sc->sc_channel[3].nd_volume = 637 1.37 kent cp->un.value.level[0] >> 2; 638 1.29 aymeric sc->sc_channel[1].nd_volume = 639 1.29 aymeric sc->sc_channel[2].nd_volume = 640 1.37 kent cp->un.value.level[1] >> 2; 641 1.37 kent } else if (i > 1) { 642 1.37 kent for (j = 0; j < i; j++) 643 1.37 kent sc->sc_channel[j].nd_volume = 644 1.37 kent cp->un.value.level[j] >> 2; 645 1.21 is } else if (sc->sc_channels > 1) 646 1.37 kent for (j = 0; j < sc->sc_channels; j++) 647 1.37 kent sc->sc_channel[j].nd_volume = 648 1.37 kent cp->un.value.level[0] >> 2; 649 1.10 is else 650 1.37 kent for (j = 0; j < 4; j++) 651 1.37 kent sc->sc_channel[j].nd_volume = 652 1.37 kent cp->un.value.level[0] >> 2; 653 1.10 is break; 654 1.1 is 655 1.1 is default: 656 1.1 is return EINVAL; 657 1.1 is break; 658 1.1 is } 659 1.1 is return 0; 660 1.1 is } 661 1.1 is 662 1.1 is 663 1.1 is int 664 1.29 aymeric aucc_get_port(void *addr, mixer_ctrl_t *cp) 665 1.1 is { 666 1.37 kent struct aucc_softc *sc; 667 1.37 kent int i,j; 668 1.1 is 669 1.1 is DPRINTF(("aucc_get_port: port=%d", cp->dev)); 670 1.37 kent sc = addr; 671 1.1 is switch (cp->type) { 672 1.1 is case AUDIO_MIXER_SET: 673 1.37 kent if (cp->dev != AUCC_CHANNELS) 674 1.1 is return EINVAL; 675 1.37 kent cp->un.mask = sc->sc_channelmask; 676 1.1 is break; 677 1.1 is 678 1.1 is case AUDIO_MIXER_VALUE: 679 1.1 is i = cp->un.value.num_channels; 680 1.37 kent if ((i < 1) || (i > 4)) 681 1.1 is return EINVAL; 682 1.1 is 683 1.37 kent for (j = 0; j < i; j++) 684 1.10 is cp->un.value.level[j] = 685 1.37 kent (sc->sc_channel[j].nd_volume << 2) + 686 1.37 kent (sc->sc_channel[j].nd_volume >> 4); 687 1.1 is break; 688 1.1 is 689 1.1 is default: 690 1.1 is return EINVAL; 691 1.1 is } 692 1.1 is return 0; 693 1.1 is } 694 1.1 is 695 1.16 augustss 696 1.16 augustss int 697 1.29 aymeric aucc_get_props(void *addr) 698 1.16 augustss { 699 1.46 isaki 700 1.47 rin return AUDIO_PROP_PLAYBACK; 701 1.16 augustss } 702 1.1 is 703 1.41 jmcneill 704 1.41 jmcneill void 705 1.41 jmcneill aucc_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread) 706 1.41 jmcneill { 707 1.41 jmcneill struct aucc_softc *sc = opaque; 708 1.41 jmcneill 709 1.41 jmcneill *intr = &sc->sc_intr_lock; 710 1.41 jmcneill *thread = &sc->sc_lock; 711 1.41 jmcneill } 712 1.41 jmcneill 713 1.1 is int 714 1.29 aymeric aucc_query_devinfo(void *addr, register mixer_devinfo_t *dip) 715 1.1 is { 716 1.37 kent int i; 717 1.1 is 718 1.1 is switch(dip->index) { 719 1.1 is case AUCC_CHANNELS: 720 1.1 is dip->type = AUDIO_MIXER_SET; 721 1.1 is dip->mixer_class = AUCC_OUTPUT_CLASS; 722 1.1 is dip->prev = dip->next = AUDIO_MIXER_LAST; 723 1.43 christos #define setname(a) strlcpy(dip->label.name, (a), sizeof(dip->label.name)) 724 1.43 christos setname(AudioNspeaker); 725 1.37 kent for (i = 0; i < 16; i++) { 726 1.43 christos snprintf(dip->un.s.member[i].label.name, 727 1.43 christos sizeof(dip->un.s.member[i].label.name), 728 1.1 is "channelmask%d", i); 729 1.1 is dip->un.s.member[i].mask = i; 730 1.1 is } 731 1.1 is dip->un.s.num_mem = 16; 732 1.1 is break; 733 1.1 is 734 1.1 is case AUCC_VOLUME: 735 1.1 is dip->type = AUDIO_MIXER_VALUE; 736 1.1 is dip->mixer_class = AUCC_OUTPUT_CLASS; 737 1.1 is dip->prev = dip->next = AUDIO_MIXER_LAST; 738 1.43 christos setname(AudioNmaster); 739 1.1 is dip->un.v.num_channels = 4; 740 1.1 is strcpy(dip->un.v.units.name, AudioNvolume); 741 1.1 is break; 742 1.1 is 743 1.1 is case AUCC_OUTPUT_CLASS: 744 1.1 is dip->type = AUDIO_MIXER_CLASS; 745 1.1 is dip->mixer_class = AUCC_OUTPUT_CLASS; 746 1.1 is dip->next = dip->prev = AUDIO_MIXER_LAST; 747 1.43 christos setname(AudioCoutputs); 748 1.1 is break; 749 1.20 augustss 750 1.1 is default: 751 1.1 is return ENXIO; 752 1.1 is } 753 1.1 is 754 1.1 is DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name)); 755 1.1 is 756 1.37 kent return 0; 757 1.1 is } 758 1.1 is 759 1.1 is /* audio int handler */ 760 1.1 is void 761 1.1 is aucc_inthdl(int ch) 762 1.1 is { 763 1.37 kent int i; 764 1.37 kent int mask; 765 1.1 is 766 1.41 jmcneill mutex_spin_enter(&aucc->sc_intr_lock); 767 1.37 kent mask = aucc->sc_channel[ch].nd_mask; 768 1.37 kent /* 769 1.37 kent * for all channels in this maskgroup: 770 1.37 kent * disable DMA, int 771 1.37 kent * mark idle 772 1.37 kent */ 773 1.37 kent DPRINTF(("inthandler called, channel %d, mask 0x%x\n", ch, mask)); 774 1.1 is 775 1.37 kent custom.intreq = mask << INTB_AUD0; /* clear request */ 776 1.24 is /* 777 1.24 is * XXX: maybe we can leave ints and/or DMA on, 778 1.24 is * if another sample has to be played? 779 1.24 is */ 780 1.37 kent custom.intena = mask << INTB_AUD0; 781 1.1 is /* 782 1.29 aymeric * XXX custom.dmacon=mask; NO!!! 783 1.29 aymeric */ 784 1.37 kent for (i = 0; i < 4; i++) { 785 1.37 kent if (masks2[i] && mask) { 786 1.1 is DPRINTF(("marking channel %d idle\n",i)); 787 1.37 kent aucc->sc_channel[i].nd_busy = 0; 788 1.37 kent aucc->sc_channel[i].nd_mask = 0; 789 1.37 kent channel[i].isaudio = channel[i].play_count = 0; 790 1.1 is } 791 1.1 is } 792 1.1 is 793 1.1 is /* call handler */ 794 1.1 is if (aucc->sc_channel[ch].nd_intr) { 795 1.1 is DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr)); 796 1.24 is (*(aucc->sc_channel[ch].nd_intr)) 797 1.24 is (aucc->sc_channel[ch].nd_intrdata); 798 1.37 kent } else 799 1.24 is DPRINTF(("zero int handler\n")); 800 1.41 jmcneill mutex_spin_exit(&aucc->sc_intr_lock); 801 1.1 is DPRINTF(("ints done\n")); 802 1.1 is } 803 1.1 is 804 1.1 is /* transform frequency to period, adjust bounds */ 805 1.1 is static u_int 806 1.29 aymeric freqtoper(u_int freq) 807 1.29 aymeric { 808 1.37 kent u_int per; 809 1.29 aymeric 810 1.37 kent per = eclockfreq * 5 / freq; 811 1.37 kent if (per < 124) 812 1.37 kent per = 124; /* must have at least 124 ticks between samples */ 813 1.1 is 814 1.1 is return per; 815 1.1 is } 816 1.1 is 817 1.1 is /* transform period to frequency */ 818 1.1 is static u_int 819 1.29 aymeric pertofreq(u_int per) 820 1.29 aymeric { 821 1.24 is 822 1.37 kent return eclockfreq * 5 / per; 823 1.24 is } 824 1.24 is 825 1.1 is 826 1.24 is /* 14bit output */ 827 1.24 is static void 828 1.29 aymeric aucc_decode_slinear16_1ch(u_char **dmap, u_char *p, int i) 829 1.24 is { 830 1.37 kent u_char *ch0; 831 1.37 kent u_char *ch3; 832 1.24 is 833 1.37 kent ch0 = dmap[0]; 834 1.37 kent ch3 = dmap[1]; /* XXX should be 3 */ 835 1.24 is while (i--) { 836 1.24 is *ch0++ = *p++; 837 1.24 is *ch3++ = *p++ >> 2; 838 1.24 is } 839 1.24 is } 840 1.1 is 841 1.24 is /* 14bit stereo output */ 842 1.24 is static void 843 1.29 aymeric aucc_decode_slinear16_2ch(u_char **dmap, u_char *p, int i) 844 1.24 is { 845 1.37 kent u_char *ch0; 846 1.37 kent u_char *ch1; 847 1.37 kent u_char *ch2; 848 1.37 kent u_char *ch3; 849 1.37 kent 850 1.37 kent ch0 = dmap[0]; 851 1.37 kent ch1 = dmap[1]; 852 1.37 kent ch2 = dmap[2]; 853 1.37 kent ch3 = dmap[3]; 854 1.24 is while (i--) { 855 1.24 is *ch0++ = *p++; 856 1.24 is *ch3++ = *p++ >> 2; 857 1.24 is *ch1++ = *p++; 858 1.24 is *ch2++ = *p++ >> 2; 859 1.24 is } 860 1.24 is } 861 1.24 is 862 1.24 is static void 863 1.29 aymeric aucc_decode_slinear16_3ch(u_char **dmap, u_char *p, int i) 864 1.24 is { 865 1.37 kent u_char *ch0; 866 1.37 kent u_char *ch1; 867 1.37 kent u_char *ch2; 868 1.37 kent 869 1.37 kent ch0 = dmap[0]; 870 1.37 kent ch1 = dmap[1]; 871 1.37 kent ch2 = dmap[2]; 872 1.24 is while (i--) { 873 1.24 is *ch0++ = *p++; p++; 874 1.24 is *ch1++ = *p++; p++; 875 1.24 is *ch2++ = *p++; p++; 876 1.24 is } 877 1.24 is } 878 1.24 is 879 1.24 is static void 880 1.29 aymeric aucc_decode_slinear16_4ch(u_char **dmap, u_char *p, int i) 881 1.1 is { 882 1.37 kent u_char *ch0; 883 1.37 kent u_char *ch1; 884 1.37 kent u_char *ch2; 885 1.37 kent u_char *ch3; 886 1.37 kent 887 1.37 kent ch0 = dmap[0]; 888 1.37 kent ch1 = dmap[1]; 889 1.37 kent ch2 = dmap[2]; 890 1.37 kent ch3 = dmap[3]; 891 1.24 is while (i--) { 892 1.24 is *ch0++ = *p++; p++; 893 1.24 is *ch1++ = *p++; p++; 894 1.24 is *ch2++ = *p++; p++; 895 1.24 is *ch3++ = *p++; p++; 896 1.24 is } 897 1.24 is } 898 1.8 is 899 1.1 is #endif /* NAUCC > 0 */ 900