cs4231.c revision 139749
1/*- 2 * Copyright (c) 1999 Jason L. Wright (jason@thought.net) 3 * Copyright (c) 2004 Pyun YongHyeon 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 * 27 * Effort sponsored in part by the Defense Advanced Research Projects 28 * Agency (DARPA) and Air Force Research Laboratory, Air Force 29 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 30 * 31 * from: OpenBSD: cs4231.c,v 1.21 2003/07/03 20:36:07 jason Exp 32 */ 33 34/* 35 * Driver for CS4231 based audio found in some sun4m systems (cs4231) 36 * based on ideas from the S/Linux project and the NetBSD project. 37 */ 38 39#include <sys/cdefs.h> 40__FBSDID("$FreeBSD: head/sys/dev/sound/sbus/cs4231.c 139749 2005-01-06 01:43:34Z imp $"); 41 42#include <sys/param.h> 43#include <sys/systm.h> 44#include <sys/bus.h> 45#include <sys/kernel.h> 46#include <sys/resource.h> 47 48#include <dev/ofw/ofw_bus.h> 49#include <dev/ofw/openfirm.h> 50#include <machine/bus.h> 51#include <machine/ofw_machdep.h> 52 53#include <dev/sound/pcm/sound.h> 54#include <dev/sound/sbus/apcdmareg.h> 55#include <dev/sound/sbus/cs4231.h> 56 57#include <sparc64/sbus/sbusvar.h> 58#include <sparc64/ebus/ebusreg.h> 59 60#include "mixer_if.h" 61 62/* 63 * The driver supports CS4231A audio chips found on Sbus/Ebus based 64 * UltraSPARCs. Though, CS4231A says it supports full-duplex mode, I 65 * doubt it due to the lack of independent sampling frequency register 66 * for playback/capture. 67 * Since I couldn't find any documentation for APCDMA programming 68 * information, I guessed the usage of APCDMA from that of OpenBSD's 69 * driver. The EBDMA infomation of PCIO can be obtained from 70 * http://solutions.sun.com/embedded/databook/web/microprocessors/pcio.html 71 * And CS4231A datasheet can also be obtained from 72 * ftp://ftp.alsa-project.org/pub/manuals/cirrus/4231a.pdf 73 * 74 * Audio capture(recording) was not tested at all and may have bugs. 75 * Sorry, I don't have microphone. Don't try to use full-duplex mode. 76 * It wouldn't work. 77 */ 78#define CS_TIMEOUT 90000 79 80#define CS4231_MIN_BUF_SZ (16*1024) 81#define CS4231_DEFAULT_BUF_SZ (32*1024) 82#define CS4231_MAX_BUF_SZ (64*1024) 83#define CS4231_MAX_BLK_SZ (8*1024) 84#define CS4231_MAX_APC_DMA_SZ (8*1024) 85 86 87#undef CS4231_DEBUG 88#ifdef CS4231_DEBUG 89#define DPRINTF(x) printf x 90#else 91#define DPRINTF(x) 92#endif 93#define CS4231_AUTO_CALIBRATION 94 95struct cs4231_softc; 96 97struct cs4231_channel { 98 struct cs4231_softc *parent; 99 struct pcm_channel *channel; 100 struct snd_dbuf *buffer; 101 u_int32_t format; 102 u_int32_t speed; 103 u_int32_t nextaddr; 104 u_int32_t togo; 105 int dir; 106 int locked; 107}; 108 109#define CS4231_RES_MEM_MAX 4 110#define CS4231_RES_IRQ_MAX 2 111struct cs4231_softc { 112 struct device *sc_dev; 113 int sc_rid[CS4231_RES_MEM_MAX]; 114 struct resource *sc_res[CS4231_RES_MEM_MAX]; 115 bus_space_handle_t sc_regh[CS4231_RES_MEM_MAX]; 116 bus_space_tag_t sc_regt[CS4231_RES_MEM_MAX]; 117 118 int sc_irqrid[CS4231_RES_IRQ_MAX]; 119 struct resource *sc_irqres[CS4231_RES_IRQ_MAX]; 120 void *sc_ih[CS4231_RES_IRQ_MAX]; 121 bus_dma_tag_t sc_dmat[CS4231_RES_IRQ_MAX]; 122 int sc_burst; 123 124 u_int32_t sc_bufsz; 125 struct cs4231_channel sc_pch; 126 struct cs4231_channel sc_rch; 127 int sc_enabled; 128 int sc_rtype; 129 int sc_nmres; 130 int sc_nires; 131 int sc_codecv; 132 int sc_chipvid; 133 int sc_flags; 134#define CS4231_SBUS 0x01 135#define CS4231_EBUS 0x02 136 137 struct mtx *sc_lock; 138}; 139 140struct mix_table { 141 u_int32_t reg:8; 142 u_int32_t bits:8; 143 u_int32_t mute:8; 144 u_int32_t shift:4; 145 u_int32_t neg:1; 146 u_int32_t avail:1; 147 u_int32_t recdev:1; 148}; 149 150static int cs4231_bus_probe(device_t); 151static int cs4231_sbus_attach(device_t); 152static int cs4231_ebus_attach(device_t); 153static int cs4231_attach_common(struct cs4231_softc *); 154static int cs4231_bus_detach(device_t); 155static int cs4231_bus_suspend(device_t); 156static int cs4231_bus_resume(device_t); 157static void cs4231_getversion(struct cs4231_softc *); 158static void cs4231_free_resource(struct cs4231_softc *); 159static void cs4231_ebdma_reset(struct cs4231_softc *); 160static void cs4231_power_reset(struct cs4231_softc *, int); 161static int cs4231_enable(struct cs4231_softc *, int); 162static void cs4231_disable(struct cs4231_softc *); 163static void cs4231_write(struct cs4231_softc *, u_int8_t, u_int8_t); 164static u_int8_t cs4231_read(struct cs4231_softc *, u_int8_t); 165static void cs4231_sbus_intr(void *); 166static void cs4231_ebus_pintr(void *arg); 167static void cs4231_ebus_cintr(void *arg); 168static int cs4231_mixer_init(struct snd_mixer *); 169static void cs4231_mixer_set_value(struct cs4231_softc *, 170 const struct mix_table *, u_int8_t); 171static int cs4231_mixer_set(struct snd_mixer *, u_int32_t, u_int32_t, 172 u_int32_t); 173static int cs4231_mixer_setrecsrc(struct snd_mixer *, u_int32_t); 174static void *cs4231_chan_init(kobj_t, void *, struct snd_dbuf *, 175 struct pcm_channel *, int); 176static int cs4231_chan_setformat(kobj_t, void *, u_int32_t); 177static int cs4231_chan_setspeed(kobj_t, void *, u_int32_t); 178static void cs4231_chan_fs(struct cs4231_softc *, int, u_int8_t); 179static int cs4231_chan_setblocksize(kobj_t, void *, u_int32_t); 180static int cs4231_chan_trigger(kobj_t, void *, int); 181static int cs4231_chan_getptr(kobj_t, void *); 182static struct pcmchan_caps * 183 cs4231_chan_getcaps(kobj_t, void *); 184static void cs4231_trigger(struct cs4231_channel *); 185static void cs4231_apcdma_trigger(struct cs4231_softc *, 186 struct cs4231_channel *); 187static void cs4231_ebdma_trigger(struct cs4231_softc *, 188 struct cs4231_channel *); 189static void cs4231_halt(struct cs4231_channel *); 190 191#define CS4231_LOCK(sc) snd_mtxlock(sc->sc_lock) 192#define CS4231_UNLOCK(sc) snd_mtxunlock(sc->sc_lock) 193#define CS4231_LOCK_ASSERT(sc) snd_mtxassert(sc->sc_lock) 194 195#define CS_WRITE(sc,r,v) \ 196 bus_space_write_1((sc)->sc_regt[0], (sc)->sc_regh[0], (r) << 2, (v)) 197#define CS_READ(sc,r) \ 198 bus_space_read_1((sc)->sc_regt[0], (sc)->sc_regh[0], (r) << 2) 199 200#define APC_WRITE(sc,r,v) \ 201 bus_space_write_4(sc->sc_regt[0], sc->sc_regh[0], r, v) 202#define APC_READ(sc,r) \ 203 bus_space_read_4(sc->sc_regt[0], sc->sc_regh[0], r) 204 205#define EBDMA_P_WRITE(sc,r,v) \ 206 bus_space_write_4((sc)->sc_regt[1], (sc)->sc_regh[1], (r), (v)) 207#define EBDMA_P_READ(sc,r) \ 208 bus_space_read_4((sc)->sc_regt[1], (sc)->sc_regh[1], (r)) 209 210#define EBDMA_C_WRITE(sc,r,v) \ 211 bus_space_write_4((sc)->sc_regt[2], (sc)->sc_regh[2], (r), (v)) 212#define EBDMA_C_READ(sc,r) \ 213 bus_space_read_4((sc)->sc_regt[2], (sc)->sc_regh[2], (r)) 214 215#define AUXIO_CODEC 0x00 216#define AUXIO_WRITE(sc,r,v) \ 217 bus_space_write_4((sc)->sc_regt[3], (sc)->sc_regh[3], (r), (v)) 218#define AUXIO_READ(sc,r) \ 219 bus_space_read_4((sc)->sc_regt[3], (sc)->sc_regh[3], (r)) 220 221#define CODEC_WARM_RESET 0 222#define CODEC_COLD_RESET 1 223 224/* SBus */ 225static device_method_t cs4231_sbus_methods[] = { 226 DEVMETHOD(device_probe, cs4231_bus_probe), 227 DEVMETHOD(device_attach, cs4231_sbus_attach), 228 DEVMETHOD(device_detach, cs4231_bus_detach), 229 DEVMETHOD(device_suspend, cs4231_bus_suspend), 230 DEVMETHOD(device_resume, cs4231_bus_resume), 231 {0, 0} 232}; 233 234static driver_t cs4231_sbus_driver = { 235 "pcm", 236 cs4231_sbus_methods, 237 PCM_SOFTC_SIZE 238}; 239 240DRIVER_MODULE(snd_audiocs, sbus, cs4231_sbus_driver, pcm_devclass, 0, 0); 241 242/* EBus */ 243static device_method_t cs4231_ebus_methods[] = { 244 DEVMETHOD(device_probe, cs4231_bus_probe), 245 DEVMETHOD(device_attach, cs4231_ebus_attach), 246 DEVMETHOD(device_detach, cs4231_bus_detach), 247 DEVMETHOD(device_suspend, cs4231_bus_suspend), 248 DEVMETHOD(device_resume, cs4231_bus_resume), 249 {0, 0} 250}; 251 252static driver_t cs4231_ebus_driver = { 253 "pcm", 254 cs4231_ebus_methods, 255 PCM_SOFTC_SIZE 256}; 257 258DRIVER_MODULE(snd_audiocs, ebus, cs4231_ebus_driver, pcm_devclass, 0, 0); 259MODULE_DEPEND(snd_audiocs, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 260MODULE_VERSION(snd_audiocs, 1); 261 262 263static u_int32_t cs4231_fmt[] = { 264 AFMT_U8, 265 AFMT_STEREO | AFMT_U8, 266 AFMT_MU_LAW, 267 AFMT_STEREO | AFMT_MU_LAW, 268 AFMT_A_LAW, 269 AFMT_STEREO | AFMT_A_LAW, 270 AFMT_IMA_ADPCM, 271 AFMT_STEREO | AFMT_IMA_ADPCM, 272 AFMT_S16_LE, 273 AFMT_STEREO | AFMT_S16_LE, 274 AFMT_S16_BE, 275 AFMT_STEREO | AFMT_S16_BE, 276 0 277}; 278 279static struct pcmchan_caps cs4231_caps = {5510, 48000, cs4231_fmt, 0}; 280 281/* 282 * sound(4) channel interface 283 */ 284static kobj_method_t cs4231_chan_methods[] = { 285 KOBJMETHOD(channel_init, cs4231_chan_init), 286 KOBJMETHOD(channel_setformat, cs4231_chan_setformat), 287 KOBJMETHOD(channel_setspeed, cs4231_chan_setspeed), 288 KOBJMETHOD(channel_setblocksize, cs4231_chan_setblocksize), 289 KOBJMETHOD(channel_trigger, cs4231_chan_trigger), 290 KOBJMETHOD(channel_getptr, cs4231_chan_getptr), 291 KOBJMETHOD(channel_getcaps, cs4231_chan_getcaps), 292 { 0, 0 } 293}; 294CHANNEL_DECLARE(cs4231_chan); 295 296/* 297 * sound(4) mixer interface 298 */ 299static kobj_method_t cs4231_mixer_methods[] = { 300 KOBJMETHOD(mixer_init, cs4231_mixer_init), 301 KOBJMETHOD(mixer_set, cs4231_mixer_set), 302 KOBJMETHOD(mixer_setrecsrc, cs4231_mixer_setrecsrc), 303 { 0, 0 } 304}; 305MIXER_DECLARE(cs4231_mixer); 306 307static int 308cs4231_bus_probe(device_t dev) 309{ 310 const char *name; 311 312 name = ofw_bus_get_name(dev); 313 if (strcmp("SUNW,CS4231", name) == 0) { 314 device_set_desc(dev, "Sun Audiocs"); 315 return (0); 316 } 317 return (ENXIO); 318} 319 320static int 321cs4231_sbus_attach(device_t dev) 322{ 323 struct snddev_info *d; 324 struct cs4231_softc *sc; 325 int burst; 326 327 d = device_get_softc(dev); 328 sc = malloc(sizeof(struct cs4231_softc), M_DEVBUF, M_NOWAIT | M_ZERO); 329 if (sc == NULL) { 330 device_printf(dev, "cannot allocate softc\n"); 331 return (ENOMEM); 332 } 333 sc->sc_dev = dev; 334 /* 335 * XXX 336 * No public documentation exists on programming burst size of APCDMA. 337 */ 338 burst = sbus_get_burstsz(sc->sc_dev); 339 if ((burst & SBUS_BURST_64)) 340 sc->sc_burst = 64; 341 else if ((burst & SBUS_BURST_32)) 342 sc->sc_burst = 32; 343 else if ((burst & SBUS_BURST_16)) 344 sc->sc_burst = 16; 345 else 346 sc->sc_burst = 0; 347 sc->sc_flags = CS4231_SBUS; 348 sc->sc_rtype = SYS_RES_MEMORY; 349 sc->sc_nmres = 1; 350 sc->sc_nires = 1; 351 return cs4231_attach_common(sc); 352} 353 354static int 355cs4231_ebus_attach(device_t dev) 356{ 357 struct snddev_info *d; 358 struct cs4231_softc *sc; 359 360 d = device_get_softc(dev); 361 sc = malloc(sizeof(struct cs4231_softc), M_DEVBUF, M_NOWAIT | M_ZERO); 362 if (sc == NULL) { 363 device_printf(dev, "cannot allocate softc\n"); 364 return (ENOMEM); 365 } 366 sc->sc_dev = dev; 367 sc->sc_burst = EBDCSR_BURST_1; 368 sc->sc_rtype = SYS_RES_IOPORT; 369 sc->sc_nmres = CS4231_RES_MEM_MAX; 370 sc->sc_nires = CS4231_RES_IRQ_MAX; 371 sc->sc_flags = CS4231_EBUS; 372 return cs4231_attach_common(sc); 373} 374 375static int 376cs4231_attach_common(struct cs4231_softc *sc) 377{ 378 char status[SND_STATUSLEN]; 379 driver_intr_t *ihandler; 380 int i; 381 382 sc->sc_lock = snd_mtxcreate(device_get_nameunit(sc->sc_dev), 383 "sound softc"); 384 if (sc->sc_lock == NULL) { 385 device_printf(sc->sc_dev, "cannot create mutex\n"); 386 free(sc, M_DEVBUF); 387 return (ENXIO); 388 } 389 390 for (i = 0; i < sc->sc_nmres; i++) { 391 sc->sc_rid[i] = i; 392 if ((sc->sc_res[i] = bus_alloc_resource_any(sc->sc_dev, 393 sc->sc_rtype, &sc->sc_rid[i], RF_ACTIVE)) == NULL) { 394 device_printf(sc->sc_dev, 395 "cannot map register %d\n", i); 396 goto fail; 397 } 398 sc->sc_regt[i] = rman_get_bustag(sc->sc_res[i]); 399 sc->sc_regh[i] = rman_get_bushandle(sc->sc_res[i]); 400 } 401 for (i = 0; i < sc->sc_nires; i++) { 402 sc->sc_irqrid[i] = i; 403 if ((sc->sc_irqres[i] = bus_alloc_resource_any(sc->sc_dev, 404 SYS_RES_IRQ, &sc->sc_irqrid[i], RF_SHAREABLE | RF_ACTIVE)) 405 == NULL) { 406 if ((sc->sc_flags & CS4231_SBUS) != 0) 407 device_printf(sc->sc_dev, 408 "cannot allocate interrupt\n"); 409 else 410 device_printf(sc->sc_dev, "cannot allocate %s " 411 "interrupt\n", i == 0 ? "capture" : 412 "playback"); 413 goto fail; 414 } 415 } 416 417 ihandler = cs4231_sbus_intr; 418 for (i = 0; i < sc->sc_nires; i++) { 419 if ((sc->sc_flags & CS4231_EBUS) != 0) { 420 if (i == 0) 421 ihandler = cs4231_ebus_cintr; 422 else 423 ihandler = cs4231_ebus_pintr; 424 } 425 if (snd_setup_intr(sc->sc_dev, sc->sc_irqres[i], INTR_MPSAFE, 426 ihandler, sc, &sc->sc_ih[i])) { 427 if ((sc->sc_flags & CS4231_SBUS) != 0) 428 device_printf(sc->sc_dev, 429 "cannot set up interrupt\n"); 430 else 431 device_printf(sc->sc_dev, "cannot set up %s " 432 " interrupt\n", i == 0 ? "capture" : 433 "playback"); 434 goto fail; 435 } 436 } 437 438 sc->sc_bufsz = pcm_getbuffersize(sc->sc_dev, CS4231_MIN_BUF_SZ, 439 CS4231_DEFAULT_BUF_SZ, CS4231_MAX_BUF_SZ); 440 for (i = 0; i < sc->sc_nires; i++) { 441 if (bus_dma_tag_create( 442 NULL, /* parent */ 443 64, 0, /* alignment, boundary */ 444 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 445 BUS_SPACE_MAXADDR, /* highaddr */ 446 NULL, NULL, /* filtfunc, filtfuncarg */ 447 sc->sc_bufsz, /* maxsize */ 448 1, /* nsegments */ 449 sc->sc_bufsz, /* maxsegsz */ 450 BUS_DMA_ALLOCNOW, /* flags */ 451 NULL, /* lockfunc */ 452 NULL, /* lockfuncarg */ 453 &sc->sc_dmat[i])) { 454 if ((sc->sc_flags & CS4231_SBUS) != 0) 455 device_printf(sc->sc_dev, 456 "cannot allocate DMA tag\n"); 457 else 458 device_printf(sc->sc_dev, "cannot allocate %s " 459 "DMA tag\n", i == 0 ? "capture" : 460 "playback"); 461 goto fail; 462 } 463 } 464 cs4231_enable(sc, CODEC_WARM_RESET); 465 cs4231_getversion(sc); 466 if (mixer_init(sc->sc_dev, &cs4231_mixer_class, sc) != 0) 467 goto fail; 468 if (pcm_register(sc->sc_dev, sc, 1, 1)) { 469 device_printf(sc->sc_dev, "cannot register to pcm\n"); 470 goto fail; 471 } 472 if (pcm_addchan(sc->sc_dev, PCMDIR_REC, &cs4231_chan_class, sc) != 0) 473 goto chan_fail; 474 if (pcm_addchan(sc->sc_dev, PCMDIR_PLAY, &cs4231_chan_class, sc) != 0) 475 goto chan_fail; 476 if ((sc->sc_flags & CS4231_SBUS) != 0) 477 snprintf(status, SND_STATUSLEN, "at mem 0x%lx irq %ld bufsz %u", 478 rman_get_start(sc->sc_res[0]), 479 rman_get_start(sc->sc_irqres[0]), sc->sc_bufsz); 480 else 481 snprintf(status, SND_STATUSLEN, "at io 0x%lx 0x%lx 0x%lx 0x%lx " 482 "irq %ld %ld bufsz %u", rman_get_start(sc->sc_res[0]), 483 rman_get_start(sc->sc_res[1]), 484 rman_get_start(sc->sc_res[2]), 485 rman_get_start(sc->sc_res[3]), 486 rman_get_start(sc->sc_irqres[0]), 487 rman_get_start(sc->sc_irqres[1]), sc->sc_bufsz); 488 pcm_setstatus(sc->sc_dev, status); 489 return (0); 490 491chan_fail: 492 pcm_unregister(sc->sc_dev); 493fail: 494 cs4231_free_resource(sc); 495 return (ENXIO); 496} 497 498static int 499cs4231_bus_detach(device_t dev) 500{ 501 struct cs4231_softc *sc; 502 struct cs4231_channel *pch, *rch; 503 int error; 504 505 sc = pcm_getdevinfo(dev); 506 CS4231_LOCK(sc); 507 pch = &sc->sc_pch; 508 rch = &sc->sc_pch; 509 if (pch->locked || rch->locked) { 510 CS4231_UNLOCK(sc); 511 return (EBUSY); 512 } 513 /* 514 * Since EBDMA requires valid DMA buffer to drain its FIFO, we need 515 * real DMA buffer for draining. 516 */ 517 if ((sc->sc_flags & CS4231_EBUS) != 0) 518 cs4231_ebdma_reset(sc); 519 CS4231_UNLOCK(sc); 520 error = pcm_unregister(dev); 521 if (error) 522 return (error); 523 cs4231_free_resource(sc); 524 return (0); 525} 526 527static int 528cs4231_bus_suspend(device_t dev) 529{ 530 531 return (ENXIO); 532} 533 534static int 535cs4231_bus_resume(device_t dev) 536{ 537 538 return (ENXIO); 539} 540 541static void 542cs4231_getversion(struct cs4231_softc *sc) 543{ 544 u_int8_t v; 545 546 v = cs4231_read(sc, CS_MISC_INFO); 547 sc->sc_codecv = v & CS_CODEC_ID_MASK; 548 v = cs4231_read(sc, CS_VERSION_ID); 549 v &= (CS_VERSION_NUMBER | CS_VERSION_CHIPID); 550 sc->sc_chipvid = v; 551 switch(v) { 552 case 0x80: 553 device_printf(sc->sc_dev, "<CS4231 Codec Id. %d>\n", 554 sc->sc_codecv); 555 break; 556 case 0xa0: 557 device_printf(sc->sc_dev, "<CS4231A Codec Id. %d>\n", 558 sc->sc_codecv); 559 break; 560 case 0x82: 561 device_printf(sc->sc_dev, "<CS4232 Codec Id. %d>\n", 562 sc->sc_codecv); 563 break; 564 default: 565 device_printf(sc->sc_dev, 566 "<Unknown 0x%x Codec Id. %d\n", v, sc->sc_codecv); 567 break; 568 } 569} 570 571static void 572cs4231_ebdma_reset(struct cs4231_softc *sc) 573{ 574 int i; 575 576 /* playback */ 577 EBDMA_P_WRITE(sc, EBDMA_DCSR, 578 EBDMA_P_READ(sc, EBDMA_DCSR) & ~(EBDCSR_INTEN | EBDCSR_NEXTEN)); 579 EBDMA_P_WRITE(sc, EBDMA_DCSR, EBDCSR_RESET); 580 for (i = CS_TIMEOUT; 581 i && EBDMA_P_READ(sc, EBDMA_DCSR) & EBDCSR_DRAIN; i--) 582 DELAY(1); 583 if (i == 0) 584 device_printf(sc->sc_dev, 585 "timeout waiting for playback DMA reset\n"); 586 EBDMA_P_WRITE(sc, EBDMA_DCSR, sc->sc_burst); 587 /* capture */ 588 EBDMA_C_WRITE(sc, EBDMA_DCSR, 589 EBDMA_C_READ(sc, EBDMA_DCSR) & ~(EBDCSR_INTEN | EBDCSR_NEXTEN)); 590 EBDMA_C_WRITE(sc, EBDMA_DCSR, EBDCSR_RESET); 591 for (i = CS_TIMEOUT; 592 i && EBDMA_C_READ(sc, EBDMA_DCSR) & EBDCSR_DRAIN; i--) 593 DELAY(1); 594 if (i == 0) 595 device_printf(sc->sc_dev, 596 "timeout waiting for capture DMA reset\n"); 597 EBDMA_C_WRITE(sc, EBDMA_DCSR, sc->sc_burst); 598} 599 600static void 601cs4231_power_reset(struct cs4231_softc *sc, int how) 602{ 603 u_int32_t v; 604 int i; 605 606 if ((sc->sc_flags & CS4231_SBUS) != 0) { 607 APC_WRITE(sc, APC_CSR, APC_CSR_RESET); 608 DELAY(10); 609 APC_WRITE(sc, APC_CSR, 0); 610 DELAY(10); 611 APC_WRITE(sc, 612 APC_CSR, APC_READ(sc, APC_CSR) | APC_CSR_CODEC_RESET); 613 DELAY(20); 614 APC_WRITE(sc, 615 APC_CSR, APC_READ(sc, APC_CSR) & (~APC_CSR_CODEC_RESET)); 616 } else { 617 v = AUXIO_READ(sc, AUXIO_CODEC); 618 if (how == CODEC_WARM_RESET && v != 0) { 619 AUXIO_WRITE(sc, AUXIO_CODEC, 0); 620 DELAY(20); 621 } else if (how == CODEC_COLD_RESET){ 622 AUXIO_WRITE(sc, AUXIO_CODEC, 1); 623 DELAY(20); 624 AUXIO_WRITE(sc, AUXIO_CODEC, 0); 625 DELAY(20); 626 } 627 cs4231_ebdma_reset(sc); 628 } 629 630 for (i = CS_TIMEOUT; 631 i && CS_READ(sc, CS4231_IADDR) == CS_IN_INIT; i--) 632 DELAY(10); 633 if (i == 0) 634 device_printf(sc->sc_dev, "timeout waiting for reset\n"); 635 636 /* turn on cs4231 mode */ 637 cs4231_write(sc, CS_MISC_INFO, 638 cs4231_read(sc, CS_MISC_INFO) | CS_MODE2); 639 /* enable interupts & clear CSR */ 640 cs4231_write(sc, CS_PIN_CONTROL, 641 cs4231_read(sc, CS_PIN_CONTROL) | INTERRUPT_ENABLE); 642 CS_WRITE(sc, CS4231_STATUS, 0); 643 /* enable DAC output */ 644 cs4231_write(sc, CS_LEFT_OUTPUT_CONTROL, 645 cs4231_read(sc, CS_LEFT_OUTPUT_CONTROL) & ~OUTPUT_MUTE); 646 cs4231_write(sc, CS_RIGHT_OUTPUT_CONTROL, 647 cs4231_read(sc, CS_RIGHT_OUTPUT_CONTROL) & ~OUTPUT_MUTE); 648 /* mute AUX1 since it generates noises */ 649 cs4231_write(sc, CS_LEFT_AUX1_CONTROL, 650 cs4231_read(sc, CS_LEFT_AUX1_CONTROL) | AUX_INPUT_MUTE); 651 cs4231_write(sc, CS_RIGHT_AUX1_CONTROL, 652 cs4231_read(sc, CS_RIGHT_AUX1_CONTROL) | AUX_INPUT_MUTE); 653 /* protect buffer underrun and set output level to 0dB */ 654 cs4231_write(sc, CS_ALT_FEATURE1, 655 cs4231_read(sc, CS_ALT_FEATURE1) | CS_DAC_ZERO | CS_OUTPUT_LVL); 656 /* enable high pass filter, dual xtal was disabled due to noises */ 657 cs4231_write(sc, CS_ALT_FEATURE2, 658 cs4231_read(sc, CS_ALT_FEATURE2) | CS_HPF_ENABLE); 659} 660 661static int 662cs4231_enable(struct cs4231_softc *sc, int how) 663{ 664 cs4231_power_reset(sc, how); 665 sc->sc_enabled = 1; 666 return (0); 667} 668 669static void 670cs4231_disable(struct cs4231_softc *sc) 671{ 672 u_int8_t v; 673 674 CS4231_LOCK_ASSERT(sc); 675 676 if (sc->sc_enabled == 0) 677 return; 678 sc->sc_enabled = 0; 679 CS4231_UNLOCK(sc); 680 cs4231_halt(&sc->sc_pch); 681 cs4231_halt(&sc->sc_rch); 682 CS4231_LOCK(sc); 683 v = cs4231_read(sc, CS_PIN_CONTROL) & ~INTERRUPT_ENABLE; 684 cs4231_write(sc, CS_PIN_CONTROL, v); 685 686 if ((sc->sc_flags & CS4231_SBUS) != 0) { 687 APC_WRITE(sc, APC_CSR, APC_CSR_RESET); 688 DELAY(10); 689 APC_WRITE(sc, APC_CSR, 0); 690 DELAY(10); 691 } else 692 cs4231_ebdma_reset(sc); 693} 694 695static void 696cs4231_free_resource(struct cs4231_softc *sc) 697{ 698 int i; 699 700 CS4231_LOCK(sc); 701 cs4231_disable(sc); 702 CS4231_UNLOCK(sc); 703 for (i = 0; i < sc->sc_nires; i++) { 704 if (sc->sc_irqres[i]) { 705 if (sc->sc_ih[i]) { 706 bus_teardown_intr(sc->sc_dev, sc->sc_irqres[i], 707 sc->sc_ih[i]); 708 sc->sc_ih[i] = NULL; 709 } 710 bus_release_resource(sc->sc_dev, SYS_RES_IRQ, 711 sc->sc_irqrid[i], sc->sc_irqres[i]); 712 sc->sc_irqres[i] = NULL; 713 } 714 } 715 for (i = 0; i < sc->sc_nires; i++) { 716 if (sc->sc_dmat[i]) 717 bus_dma_tag_destroy(sc->sc_dmat[i]); 718 } 719 for (i = 0; i < sc->sc_nmres; i++) { 720 if (sc->sc_res[i]) 721 bus_release_resource(sc->sc_dev, sc->sc_rtype, 722 sc->sc_rid[i], sc->sc_res[i]); 723 } 724 snd_mtxfree(sc->sc_lock); 725 free(sc, M_DEVBUF); 726} 727 728static void 729cs4231_write(struct cs4231_softc *sc, u_int8_t r, u_int8_t v) 730{ 731 CS_WRITE(sc, CS4231_IADDR, r); 732 CS_WRITE(sc, CS4231_IDATA, v); 733} 734 735static u_int8_t 736cs4231_read(struct cs4231_softc *sc, u_int8_t r) 737{ 738 CS_WRITE(sc, CS4231_IADDR, r); 739 return (CS_READ(sc, CS4231_IDATA)); 740} 741 742static void 743cs4231_sbus_intr(void *arg) 744{ 745 struct cs4231_softc *sc; 746 struct cs4231_channel *pch, *rch; 747 u_int32_t csr; 748 u_int8_t status; 749 750 sc = arg; 751 CS4231_LOCK(sc); 752 753 csr = APC_READ(sc, APC_CSR); 754 if ((csr & APC_CSR_GI) == 0) { 755 CS4231_UNLOCK(sc); 756 return; 757 } 758 APC_WRITE(sc, APC_CSR, csr); 759 760 if ((csr & APC_CSR_EIE) && (csr & APC_CSR_EI)) { 761 status = cs4231_read(sc, CS_TEST_AND_INIT); 762 device_printf(sc->sc_dev, 763 "apc error interrupt : stat = 0x%x\n", status); 764 } 765 766 pch = rch = NULL; 767 if ((csr & APC_CSR_PMIE) && (csr & APC_CSR_PMI)) { 768 u_long nextaddr, saddr; 769 u_int32_t togo; 770 771 pch = &sc->sc_pch; 772 togo = pch->togo; 773 saddr = sndbuf_getbufaddr(pch->buffer); 774 nextaddr = pch->nextaddr + togo; 775 if (nextaddr >= saddr + sndbuf_getsize(pch->buffer)) 776 nextaddr = saddr; 777 APC_WRITE(sc, APC_PNVA, nextaddr); 778 APC_WRITE(sc, APC_PNC, togo); 779 pch->nextaddr = nextaddr; 780 } 781 782 if ((csr & APC_CSR_CIE) && (csr & APC_CSR_CI) && (csr & APC_CSR_CD)) { 783 u_long nextaddr, saddr; 784 u_int32_t togo; 785 786 rch = &sc->sc_rch; 787 togo = rch->togo; 788 saddr = sndbuf_getbufaddr(rch->buffer); 789 nextaddr = rch->nextaddr + togo; 790 if (nextaddr >= saddr + sndbuf_getsize(rch->buffer)) 791 nextaddr = saddr; 792 APC_WRITE(sc, APC_CNVA, nextaddr); 793 APC_WRITE(sc, APC_CNC, togo); 794 rch->nextaddr = nextaddr; 795 } 796 CS4231_UNLOCK(sc); 797 if (pch) 798 chn_intr(pch->channel); 799 if (rch) 800 chn_intr(rch->channel); 801} 802 803/* playback interrupt handler */ 804static void 805cs4231_ebus_pintr(void *arg) 806{ 807 struct cs4231_softc *sc; 808 struct cs4231_channel *ch; 809 u_int32_t csr; 810 u_int8_t status; 811 812 sc = arg; 813 CS4231_LOCK(sc); 814 815 csr = EBDMA_P_READ(sc, EBDMA_DCSR); 816 if ((csr & EBDCSR_INT) == 0) { 817 CS4231_UNLOCK(sc); 818 return; 819 } 820 821 if ((csr & EBDCSR_ERR)) { 822 status = cs4231_read(sc, CS_TEST_AND_INIT); 823 device_printf(sc->sc_dev, 824 "ebdma error interrupt : stat = 0x%x\n", status); 825 } 826 EBDMA_P_WRITE(sc, EBDMA_DCSR, csr | EBDCSR_TC); 827 828 ch = NULL; 829 if (csr & EBDCSR_TC) { 830 u_long nextaddr, saddr; 831 u_int32_t togo; 832 833 ch = &sc->sc_pch; 834 togo = ch->togo; 835 saddr = sndbuf_getbufaddr(ch->buffer); 836 nextaddr = ch->nextaddr + togo; 837 if (nextaddr >= saddr + sndbuf_getsize(ch->buffer)) 838 nextaddr = saddr; 839 /* 840 * EBDMA_DCNT is loaded automatically 841 * EBDMA_P_WRITE(sc, EBDMA_DCNT, togo); 842 */ 843 EBDMA_P_WRITE(sc, EBDMA_DADDR, nextaddr); 844 ch->nextaddr = nextaddr; 845 } 846 CS4231_UNLOCK(sc); 847 if (ch) 848 chn_intr(ch->channel); 849} 850 851/* capture interrupt handler */ 852static void 853cs4231_ebus_cintr(void *arg) 854{ 855 struct cs4231_softc *sc; 856 struct cs4231_channel *ch; 857 u_int32_t csr; 858 u_int8_t status; 859 860 sc = arg; 861 CS4231_LOCK(sc); 862 863 csr = EBDMA_C_READ(sc, EBDMA_DCSR); 864 if ((csr & EBDCSR_INT) == 0) { 865 CS4231_UNLOCK(sc); 866 return; 867 } 868 if ((csr & EBDCSR_ERR)) { 869 status = cs4231_read(sc, CS_TEST_AND_INIT); 870 device_printf(sc->sc_dev, 871 "dma error interrupt : stat = 0x%x\n", status); 872 } 873 EBDMA_C_WRITE(sc, EBDMA_DCSR, csr | EBDCSR_TC); 874 875 ch = NULL; 876 if (csr & EBDCSR_TC) { 877 u_long nextaddr, saddr; 878 u_int32_t togo; 879 880 ch = &sc->sc_rch; 881 togo = ch->togo; 882 saddr = sndbuf_getbufaddr(ch->buffer); 883 nextaddr = ch->nextaddr + togo; 884 if (nextaddr >= saddr + sndbuf_getblksz(ch->buffer)) 885 nextaddr = saddr; 886 /* 887 * EBDMA_DCNT is loaded automatically 888 * EBDMA_C_WRITE(sc, EBDMA_DCNT, togo); 889 */ 890 EBDMA_C_WRITE(sc, EBDMA_DADDR, nextaddr); 891 ch->nextaddr = nextaddr; 892 } 893 CS4231_UNLOCK(sc); 894 if (ch) 895 chn_intr(ch->channel); 896} 897 898static const struct mix_table cs4231_mix_table[SOUND_MIXER_NRDEVICES][2] = { 899 [SOUND_MIXER_PCM] = { 900 { CS_LEFT_OUTPUT_CONTROL, 6, OUTPUT_MUTE, 0, 1, 1, 0 }, 901 { CS_RIGHT_OUTPUT_CONTROL, 6, OUTPUT_MUTE, 0, 1, 1, 0 } 902 }, 903 [SOUND_MIXER_SPEAKER] = { 904 { CS_MONO_IO_CONTROL, 4, MONO_OUTPUT_MUTE, 0, 1, 1, 0 }, 905 { CS_REG_NONE, 0, 0, 0, 0, 1, 0 } 906 }, 907 [SOUND_MIXER_LINE] = { 908 { CS_LEFT_LINE_CONTROL, 5, LINE_INPUT_MUTE, 0, 1, 1, 1 }, 909 { CS_RIGHT_LINE_CONTROL, 5, LINE_INPUT_MUTE, 0, 1, 1, 1 } 910 }, 911 /* 912 * AUX1 : removed intentionally since it generates noises 913 * AUX2 : Ultra1/Ultra2 has no internal CD-ROM audio in 914 */ 915 [SOUND_MIXER_CD] = { 916 { CS_LEFT_AUX2_CONTROL, 5, LINE_INPUT_MUTE, 0, 1, 1, 1 }, 917 { CS_RIGHT_AUX2_CONTROL, 5, LINE_INPUT_MUTE, 0, 1, 1, 1 } 918 }, 919 [SOUND_MIXER_MIC] = { 920 { CS_LEFT_INPUT_CONTROL, 4, 0, 0, 0, 1, 1 }, 921 { CS_RIGHT_INPUT_CONTROL, 4, 0, 0, 0, 1, 1 } 922 }, 923 [SOUND_MIXER_IGAIN] = { 924 { CS_LEFT_INPUT_CONTROL, 4, 0, 0, 1, 0 }, 925 { CS_RIGHT_INPUT_CONTROL, 4, 0, 0, 1, 0 } 926 } 927}; 928 929static int 930cs4231_mixer_init(struct snd_mixer *m) 931{ 932 u_int32_t v; 933 int i; 934 935 v = 0; 936 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) 937 if (cs4231_mix_table[i][0].avail != 0) 938 v |= (1 << i); 939 mix_setdevs(m, v); 940 v = 0; 941 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) 942 if (cs4231_mix_table[i][0].recdev != 0) 943 v |= (1 << i); 944 mix_setrecdevs(m, v); 945 return (0); 946} 947 948static void 949cs4231_mixer_set_value(struct cs4231_softc *sc, const struct mix_table *mt, 950 u_int8_t v) 951{ 952 u_int8_t mask, reg; 953 u_int8_t old, shift, val; 954 955 if (mt->avail == 0 || mt->reg == CS_REG_NONE) 956 return; 957 reg = mt->reg; 958 if (mt->neg != 0) 959 val = 100 - v; 960 else 961 val = v; 962 mask = (1 << mt->bits) - 1; 963 val = ((val * mask) + 50) / 100; 964 shift = mt->shift; 965 val <<= shift; 966 if (v == 0) 967 val |= mt->mute; 968 old = cs4231_read(sc, reg); 969 old &= ~(mt->mute | (mask << shift)); 970 val |= old; 971 if (reg == CS_LEFT_INPUT_CONTROL || reg == CS_RIGHT_INPUT_CONTROL) { 972 if ((val & (mask << shift)) != 0) 973 val |= ADC_INPUT_GAIN_ENABLE; 974 else 975 val &= ~ADC_INPUT_GAIN_ENABLE; 976 } 977 cs4231_write(sc, reg, val); 978} 979 980static int 981cs4231_mixer_set(struct snd_mixer *m, u_int32_t dev, u_int32_t left, 982 u_int32_t right) 983{ 984 struct cs4231_softc *sc; 985 986 sc = mix_getdevinfo(m); 987 CS4231_LOCK(sc); 988 cs4231_mixer_set_value(sc, &cs4231_mix_table[dev][0], left); 989 cs4231_mixer_set_value(sc, &cs4231_mix_table[dev][1], right); 990 CS4231_UNLOCK(sc); 991 992 return (left | (right << 8)); 993} 994 995static int 996cs4231_mixer_setrecsrc(struct snd_mixer *m, u_int32_t src) 997{ 998 struct cs4231_softc *sc; 999 u_int8_t v; 1000 1001 sc = mix_getdevinfo(m); 1002 switch (src) { 1003 case SOUND_MASK_LINE: 1004 v = CS_IN_LINE; 1005 break; 1006 1007 case SOUND_MASK_CD: 1008 v = CS_IN_DAC; 1009 break; 1010 1011 case SOUND_MASK_MIC: 1012 default: 1013 v = CS_IN_MIC; 1014 src = SOUND_MASK_MIC; 1015 break; 1016 } 1017 CS4231_LOCK(sc); 1018 cs4231_write(sc, CS_LEFT_INPUT_CONTROL, 1019 (cs4231_read(sc, CS_LEFT_INPUT_CONTROL) & CS_IN_MASK) | v); 1020 cs4231_write(sc, CS_RIGHT_INPUT_CONTROL, 1021 (cs4231_read(sc, CS_RIGHT_INPUT_CONTROL) & CS_IN_MASK) | v); 1022 CS4231_UNLOCK(sc); 1023 1024 return (src); 1025} 1026 1027static void * 1028cs4231_chan_init(kobj_t obj, void *dev, struct snd_dbuf *b, 1029 struct pcm_channel *c, int dir) 1030{ 1031 struct cs4231_softc *sc; 1032 struct cs4231_channel *ch; 1033 bus_dma_tag_t dmat; 1034 1035 sc = dev; 1036 ch = (dir == PCMDIR_PLAY) ? &sc->sc_pch : &sc->sc_rch; 1037 ch->parent = sc; 1038 ch->channel = c; 1039 ch->dir = dir; 1040 ch->buffer = b; 1041 if ((sc->sc_flags & CS4231_SBUS) != 0) 1042 dmat = sc->sc_dmat[0]; 1043 else { 1044 if (dir == PCMDIR_PLAY) 1045 dmat = sc->sc_dmat[1]; 1046 else 1047 dmat = sc->sc_dmat[0]; 1048 } 1049 if (sndbuf_alloc(ch->buffer, dmat, sc->sc_bufsz) != 0) 1050 return (NULL); 1051 DPRINTF(("%s channel addr: 0x%lx\n", dir == PCMDIR_PLAY ? "playback" : 1052 "capture", sndbuf_getbufaddr(ch->buffer))); 1053 1054 return (ch); 1055} 1056 1057static int 1058cs4231_chan_setformat(kobj_t obj, void *data, u_int32_t format) 1059{ 1060 struct cs4231_softc *sc; 1061 struct cs4231_channel *ch; 1062 u_int32_t encoding; 1063 u_int8_t fs, v; 1064 1065 ch = data; 1066 sc = ch->parent; 1067 1068 CS4231_LOCK(sc); 1069 if (ch->format == format) { 1070 CS4231_UNLOCK(sc); 1071 return (0); 1072 } 1073 1074 encoding = format & ~AFMT_STEREO; 1075 fs = 0; 1076 switch (encoding) { 1077 case AFMT_U8: 1078 fs = CS_AFMT_U8; 1079 break; 1080 case AFMT_MU_LAW: 1081 fs = CS_AFMT_MU_LAW; 1082 break; 1083 case AFMT_S16_LE: 1084 fs = CS_AFMT_S16_LE; 1085 break; 1086 case AFMT_A_LAW: 1087 fs = CS_AFMT_A_LAW; 1088 break; 1089 case AFMT_IMA_ADPCM: 1090 fs = CS_AFMT_IMA_ADPCM; 1091 break; 1092 case AFMT_S16_BE: 1093 fs = CS_AFMT_S16_BE; 1094 break; 1095 default: 1096 fs = CS_AFMT_U8; 1097 format = AFMT_U8; 1098 break; 1099 } 1100 1101 if (format & AFMT_STEREO) 1102 fs |= CS_AFMT_STEREO; 1103 1104 DPRINTF(("FORMAT: %s : 0x%x\n", ch->dir == PCMDIR_PLAY ? "playback" : 1105 "capture", format)); 1106 v = cs4231_read(sc, CS_CLOCK_DATA_FORMAT); 1107 v &= CS_CLOCK_DATA_FORMAT_MASK; 1108 fs |= v; 1109 cs4231_chan_fs(sc, ch->dir, fs); 1110 ch->format = format; 1111 CS4231_UNLOCK(sc); 1112 1113 return (0); 1114} 1115 1116static int 1117cs4231_chan_setspeed(kobj_t obj, void *data, u_int32_t speed) 1118{ 1119 typedef struct { 1120 u_int32_t speed; 1121 u_int8_t bits; 1122 } speed_struct; 1123 1124 const static speed_struct speed_table[] = { 1125 {5510, (0 << 1) | CLOCK_XTAL2}, 1126 {5510, (0 << 1) | CLOCK_XTAL2}, 1127 {6620, (7 << 1) | CLOCK_XTAL2}, 1128 {8000, (0 << 1) | CLOCK_XTAL1}, 1129 {9600, (7 << 1) | CLOCK_XTAL1}, 1130 {11025, (1 << 1) | CLOCK_XTAL2}, 1131 {16000, (1 << 1) | CLOCK_XTAL1}, 1132 {18900, (2 << 1) | CLOCK_XTAL2}, 1133 {22050, (3 << 1) | CLOCK_XTAL2}, 1134 {27420, (2 << 1) | CLOCK_XTAL1}, 1135 {32000, (3 << 1) | CLOCK_XTAL1}, 1136 {33075, (6 << 1) | CLOCK_XTAL2}, 1137 {33075, (4 << 1) | CLOCK_XTAL2}, 1138 {44100, (5 << 1) | CLOCK_XTAL2}, 1139 {48000, (6 << 1) | CLOCK_XTAL1}, 1140 }; 1141 1142 struct cs4231_softc *sc; 1143 struct cs4231_channel *ch; 1144 int i, n, sel; 1145 u_int8_t fs; 1146 1147 ch = data; 1148 sc = ch->parent; 1149 CS4231_LOCK(sc); 1150 if (ch->speed == speed) { 1151 CS4231_UNLOCK(sc); 1152 return (speed); 1153 } 1154 n = sizeof(speed_table) / sizeof(speed_struct); 1155 1156 for (i = 1, sel =0; i < n - 1; i++) 1157 if (abs(speed - speed_table[i].speed) < 1158 abs(speed - speed_table[sel].speed)) 1159 sel = i; 1160 DPRINTF(("SPEED: %s : %dHz -> %dHz\n", ch->dir == PCMDIR_PLAY ? 1161 "playback" : "capture", speed, speed_table[sel].speed)); 1162 speed = speed_table[sel].speed; 1163 1164 fs = cs4231_read(sc, CS_CLOCK_DATA_FORMAT); 1165 fs &= ~CS_CLOCK_DATA_FORMAT_MASK; 1166 fs |= speed_table[sel].bits; 1167 cs4231_chan_fs(sc, ch->dir, fs); 1168 ch->speed = speed; 1169 CS4231_UNLOCK(sc); 1170 1171 return (speed); 1172} 1173 1174static void 1175cs4231_chan_fs(struct cs4231_softc *sc, int dir, u_int8_t fs) 1176{ 1177 int i, doreset; 1178#ifdef CS4231_AUTO_CALIBRATION 1179 u_int8_t v; 1180#endif 1181 1182 CS4231_LOCK_ASSERT(sc); 1183 1184 /* set autocalibration */ 1185 doreset = 0; 1186#ifdef CS4231_AUTO_CALIBRATION 1187 v = cs4231_read(sc, CS_INTERFACE_CONFIG) | AUTO_CAL_ENABLE; 1188 CS_WRITE(sc, CS4231_IADDR, MODE_CHANGE_ENABLE); 1189 CS_WRITE(sc, CS4231_IADDR, MODE_CHANGE_ENABLE | CS_INTERFACE_CONFIG); 1190 CS_WRITE(sc, CS4231_IDATA, v); 1191#endif 1192 1193 /* 1194 * We always need to write CS_CLOCK_DATA_FORMAT register since 1195 * the clock frequency is shared with playback/capture. 1196 */ 1197 CS_WRITE(sc, CS4231_IADDR, MODE_CHANGE_ENABLE | CS_CLOCK_DATA_FORMAT); 1198 CS_WRITE(sc, CS4231_IDATA, fs); 1199 CS_READ(sc, CS4231_IDATA); 1200 CS_READ(sc, CS4231_IDATA); 1201 for (i = CS_TIMEOUT; 1202 i && CS_READ(sc, CS4231_IADDR) == CS_IN_INIT; i--) 1203 DELAY(10); 1204 if (i == 0) { 1205 device_printf(sc->sc_dev, "timeout setting playback speed\n"); 1206 doreset++; 1207 } 1208 1209 /* 1210 * capture channel 1211 * cs4231 doesn't allow seperate fs setup for playback/capture. 1212 * I believe this will break full-duplex operation. 1213 */ 1214 if (dir == PCMDIR_REC) { 1215 CS_WRITE(sc, CS4231_IADDR, MODE_CHANGE_ENABLE | CS_REC_FORMAT); 1216 CS_WRITE(sc, CS4231_IDATA, fs); 1217 CS_READ(sc, CS4231_IDATA); 1218 CS_READ(sc, CS4231_IDATA); 1219 for (i = CS_TIMEOUT; 1220 i && CS_READ(sc, CS4231_IADDR) == CS_IN_INIT; i--) 1221 DELAY(10); 1222 if (i == 0) { 1223 device_printf(sc->sc_dev, 1224 "timeout setting capture format\n"); 1225 doreset++; 1226 } 1227 } 1228 1229 CS_WRITE(sc, CS4231_IADDR, 0); 1230 for (i = CS_TIMEOUT; 1231 i && CS_READ(sc, CS4231_IADDR) == CS_IN_INIT; i--) 1232 DELAY(10); 1233 if (i == 0) { 1234 device_printf(sc->sc_dev, "timeout waiting for !MCE\n"); 1235 doreset++; 1236 } 1237 1238#ifdef CS4231_AUTO_CALIBRATION 1239 CS_WRITE(sc, CS4231_IADDR, CS_TEST_AND_INIT); 1240 for (i = CS_TIMEOUT; 1241 i && CS_READ(sc, CS4231_IDATA) & AUTO_CAL_IN_PROG; i--) 1242 DELAY(10); 1243 if (i == 0) { 1244 device_printf(sc->sc_dev, 1245 "timeout waiting for autocalibration\n"); 1246 doreset++; 1247 } 1248#endif 1249 if (doreset) { 1250 /* 1251 * Maybe the last resort to avoid a dreadful message like 1252 * "pcm0:play:0: play interrupt timeout, channel dead" would 1253 * be hardware reset. 1254 */ 1255 device_printf(sc->sc_dev, "trying to hardware reset\n"); 1256 cs4231_disable(sc); 1257 cs4231_enable(sc, CODEC_COLD_RESET); 1258 CS4231_UNLOCK(sc); /* XXX */ 1259 if (mixer_reinit(sc->sc_dev) != 0) 1260 device_printf(sc->sc_dev, 1261 "unable to reinitialize the mixer\n"); 1262 CS4231_LOCK(sc); 1263 } 1264} 1265 1266static int 1267cs4231_chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 1268{ 1269 struct cs4231_softc *sc; 1270 struct cs4231_channel *ch; 1271 int nblks, error; 1272 1273 ch = data; 1274 sc = ch->parent; 1275 1276 if (blocksize > CS4231_MAX_BLK_SZ) 1277 blocksize = CS4231_MAX_BLK_SZ; 1278 nblks = sc->sc_bufsz / blocksize; 1279 error = sndbuf_resize(ch->buffer, nblks, blocksize); 1280 if (error != 0) 1281 device_printf(sc->sc_dev, 1282 "unable to block size, blksz = %d, error = %d\n", 1283 blocksize, error); 1284 1285 return (blocksize); 1286} 1287 1288static int 1289cs4231_chan_trigger(kobj_t obj, void *data, int go) 1290{ 1291 struct cs4231_channel *ch; 1292 1293 ch = data; 1294 switch (go) { 1295 case PCMTRIG_EMLDMAWR: 1296 case PCMTRIG_EMLDMARD: 1297 break; 1298 case PCMTRIG_START: 1299 cs4231_trigger(ch); 1300 break; 1301 case PCMTRIG_ABORT: 1302 case PCMTRIG_STOP: 1303 cs4231_halt(ch); 1304 break; 1305 default: 1306 break; 1307 } 1308 1309 return (0); 1310} 1311 1312static int 1313cs4231_chan_getptr(kobj_t obj, void *data) 1314{ 1315 struct cs4231_softc *sc; 1316 struct cs4231_channel *ch; 1317 u_int32_t cur; 1318 int ptr, sz; 1319 1320 ch = data; 1321 sc = ch->parent; 1322 1323 CS4231_LOCK(sc); 1324 if ((sc->sc_flags & CS4231_SBUS) != 0) 1325 cur = (ch->dir == PCMDIR_PLAY) ? APC_READ(sc, APC_PVA) : 1326 APC_READ(sc, APC_CVA); 1327 else 1328 cur = (ch->dir == PCMDIR_PLAY) ? EBDMA_P_READ(sc, EBDMA_DADDR) : 1329 EBDMA_C_READ(sc, EBDMA_DADDR); 1330 sz = sndbuf_getsize(ch->buffer); 1331 ptr = cur - sndbuf_getbufaddr(ch->buffer) + sz; 1332 CS4231_UNLOCK(sc); 1333 1334 ptr %= sz; 1335 return (ptr); 1336} 1337 1338static struct pcmchan_caps * 1339cs4231_chan_getcaps(kobj_t obj, void *data) 1340{ 1341 1342 return (&cs4231_caps); 1343} 1344 1345static void 1346cs4231_trigger(struct cs4231_channel *ch) 1347{ 1348 struct cs4231_softc *sc; 1349 1350 sc = ch->parent; 1351 if ((sc->sc_flags & CS4231_SBUS) != 0) 1352 cs4231_apcdma_trigger(sc, ch); 1353 else 1354 cs4231_ebdma_trigger(sc, ch); 1355} 1356 1357static void 1358cs4231_apcdma_trigger(struct cs4231_softc *sc, struct cs4231_channel *ch) 1359{ 1360 u_int32_t csr, togo; 1361 u_int32_t nextaddr; 1362 1363 CS4231_LOCK(sc); 1364 if (ch->locked) { 1365 device_printf(sc->sc_dev, "%s channel already triggered\n", 1366 ch->dir == PCMDIR_PLAY ? "playback" : "capture"); 1367 CS4231_UNLOCK(sc); 1368 return; 1369 } 1370 1371 nextaddr = sndbuf_getbufaddr(ch->buffer); 1372 togo = sndbuf_getsize(ch->buffer) / 2; 1373 if (togo > CS4231_MAX_APC_DMA_SZ) 1374 togo = CS4231_MAX_APC_DMA_SZ; 1375 ch->togo = togo; 1376 if (ch->dir == PCMDIR_PLAY) { 1377 DPRINTF(("TRG: PNVA = 0x%x, togo = 0x%x\n", nextaddr, togo)); 1378 1379 cs4231_read(sc, CS_TEST_AND_INIT); /* clear pending error */ 1380 csr = APC_READ(sc, APC_CSR); 1381 APC_WRITE(sc, APC_PNVA, nextaddr); 1382 APC_WRITE(sc, APC_PNC, togo); 1383 1384 if ((csr & APC_CSR_PDMA_GO) == 0 || 1385 (csr & APC_CSR_PPAUSE) != 0) { 1386 APC_WRITE(sc, APC_CSR, APC_READ(sc, APC_CSR) & 1387 ~(APC_CSR_PIE | APC_CSR_PPAUSE)); 1388 APC_WRITE(sc, APC_CSR, APC_READ(sc, APC_CSR) | 1389 APC_CSR_GIE | APC_CSR_PIE | APC_CSR_EIE | 1390 APC_CSR_EI | APC_CSR_PMIE | APC_CSR_PDMA_GO); 1391 cs4231_write(sc, CS_INTERFACE_CONFIG, 1392 cs4231_read(sc, CS_INTERFACE_CONFIG) | 1393 PLAYBACK_ENABLE); 1394 } 1395 /* load next address */ 1396 if (APC_READ(sc, APC_CSR) & APC_CSR_PD) { 1397 nextaddr += togo; 1398 APC_WRITE(sc, APC_PNVA, nextaddr); 1399 APC_WRITE(sc, APC_PNC, togo); 1400 } 1401 } else { 1402 DPRINTF(("TRG: CNVA = 0x%x, togo = 0x%x\n", nextaddr, togo)); 1403 1404 cs4231_read(sc, CS_TEST_AND_INIT); /* clear pending error */ 1405 APC_WRITE(sc, APC_CNVA, nextaddr); 1406 APC_WRITE(sc, APC_CNC, togo); 1407 csr = APC_READ(sc, APC_CSR); 1408 if ((csr & APC_CSR_CDMA_GO) == 0 || 1409 (csr & APC_CSR_CPAUSE) != 0) { 1410 csr &= APC_CSR_CPAUSE; 1411 csr |= APC_CSR_GIE | APC_CSR_CMIE | APC_CSR_CIE | 1412 APC_CSR_EI | APC_CSR_CDMA_GO; 1413 APC_WRITE(sc, APC_CSR, csr); 1414 cs4231_write(sc, CS_INTERFACE_CONFIG, 1415 cs4231_read(sc, CS_INTERFACE_CONFIG) | 1416 CAPTURE_ENABLE); 1417 } 1418 /* load next address */ 1419 if (APC_READ(sc, APC_CSR) & APC_CSR_CD) { 1420 nextaddr += togo; 1421 APC_WRITE(sc, APC_CNVA, nextaddr); 1422 APC_WRITE(sc, APC_CNC, togo); 1423 } 1424 } 1425 ch->nextaddr = nextaddr; 1426 ch->locked = 1; 1427 CS4231_UNLOCK(sc); 1428} 1429 1430static void 1431cs4231_ebdma_trigger(struct cs4231_softc *sc, struct cs4231_channel *ch) 1432{ 1433 u_int32_t csr, togo; 1434 u_int32_t nextaddr; 1435 1436 CS4231_LOCK(sc); 1437 if (ch->locked) { 1438 device_printf(sc->sc_dev, "%s channel already triggered\n", 1439 ch->dir == PCMDIR_PLAY ? "playback" : "capture"); 1440 CS4231_UNLOCK(sc); 1441 return; 1442 } 1443 1444 nextaddr = sndbuf_getbufaddr(ch->buffer); 1445 togo = sndbuf_getsize(ch->buffer) / 2; 1446 if (togo % 64 == 0) 1447 sc->sc_burst = EBDCSR_BURST_16; 1448 else if (togo % 32 == 0) 1449 sc->sc_burst = EBDCSR_BURST_8; 1450 else if (togo % 16 == 0) 1451 sc->sc_burst = EBDCSR_BURST_4; 1452 else 1453 sc->sc_burst = EBDCSR_BURST_1; 1454 ch->togo = togo; 1455 DPRINTF(("TRG: DNAR = 0x%x, togo = 0x%x\n", nextaddr, togo)); 1456 if (ch->dir == PCMDIR_PLAY) { 1457 cs4231_read(sc, CS_TEST_AND_INIT); /* clear pending error */ 1458 csr = EBDMA_P_READ(sc, EBDMA_DCSR); 1459 1460 if (csr & EBDCSR_DMAEN) { 1461 EBDMA_P_WRITE(sc, EBDMA_DCNT, togo); 1462 EBDMA_P_WRITE(sc, EBDMA_DADDR, nextaddr); 1463 } else { 1464 EBDMA_P_WRITE(sc, EBDMA_DCSR, EBDCSR_RESET); 1465 EBDMA_P_WRITE(sc, EBDMA_DCSR, sc->sc_burst); 1466 EBDMA_P_WRITE(sc, EBDMA_DCNT, togo); 1467 EBDMA_P_WRITE(sc, EBDMA_DADDR, nextaddr); 1468 1469 EBDMA_P_WRITE(sc, EBDMA_DCSR, sc->sc_burst | 1470 EBDCSR_DMAEN | EBDCSR_INTEN | EBDCSR_CNTEN | 1471 EBDCSR_NEXTEN); 1472 cs4231_write(sc, CS_INTERFACE_CONFIG, 1473 cs4231_read(sc, CS_INTERFACE_CONFIG) | 1474 PLAYBACK_ENABLE); 1475 } 1476 /* load next address */ 1477 if (EBDMA_P_READ(sc, EBDMA_DCSR) & EBDCSR_A_LOADED) { 1478 nextaddr += togo; 1479 EBDMA_P_WRITE(sc, EBDMA_DCNT, togo); 1480 EBDMA_P_WRITE(sc, EBDMA_DADDR, nextaddr); 1481 } 1482 } else { 1483 cs4231_read(sc, CS_TEST_AND_INIT); /* clear pending error */ 1484 csr = EBDMA_C_READ(sc, EBDMA_DCSR); 1485 1486 if (csr & EBDCSR_DMAEN) { 1487 EBDMA_C_WRITE(sc, EBDMA_DCNT, togo); 1488 EBDMA_C_WRITE(sc, EBDMA_DADDR, nextaddr); 1489 } else { 1490 EBDMA_C_WRITE(sc, EBDMA_DCSR, EBDCSR_RESET); 1491 EBDMA_C_WRITE(sc, EBDMA_DCSR, sc->sc_burst); 1492 EBDMA_C_WRITE(sc, EBDMA_DCNT, togo); 1493 EBDMA_C_WRITE(sc, EBDMA_DADDR, nextaddr); 1494 1495 EBDMA_C_WRITE(sc, EBDMA_DCSR, sc->sc_burst | 1496 EBDCSR_WRITE | EBDCSR_DMAEN | EBDCSR_INTEN | 1497 EBDCSR_CNTEN | EBDCSR_NEXTEN); 1498 cs4231_write(sc, CS_INTERFACE_CONFIG, 1499 cs4231_read(sc, CS_INTERFACE_CONFIG) | 1500 CAPTURE_ENABLE); 1501 } 1502 /* load next address */ 1503 if (EBDMA_C_READ(sc, EBDMA_DCSR) & EBDCSR_A_LOADED) { 1504 nextaddr += togo; 1505 EBDMA_C_WRITE(sc, EBDMA_DCNT, togo); 1506 EBDMA_C_WRITE(sc, EBDMA_DADDR, nextaddr); 1507 } 1508 } 1509 ch->nextaddr = nextaddr; 1510 ch->locked = 1; 1511 CS4231_UNLOCK(sc); 1512} 1513 1514static void 1515cs4231_halt(struct cs4231_channel *ch) 1516{ 1517 struct cs4231_softc *sc; 1518 u_int8_t status; 1519 int i; 1520 1521 sc = ch->parent; 1522 CS4231_LOCK(sc); 1523 if (ch->locked == 0) { 1524 CS4231_UNLOCK(sc); 1525 return; 1526 } 1527 1528 if (ch->dir == PCMDIR_PLAY ) { 1529 if ((sc->sc_flags & CS4231_SBUS) != 0) { 1530 /* XXX Kills some capture bits */ 1531 APC_WRITE(sc, APC_CSR, APC_READ(sc, APC_CSR) & 1532 ~(APC_CSR_EI | APC_CSR_GIE | APC_CSR_PIE | 1533 APC_CSR_EIE | APC_CSR_PDMA_GO | APC_CSR_PMIE)); 1534 } else { 1535 EBDMA_P_WRITE(sc, EBDMA_DCSR, 1536 EBDMA_P_READ(sc, EBDMA_DCSR) & ~EBDCSR_DMAEN); 1537 } 1538 /* Waiting for playback FIFO to empty */ 1539 status = cs4231_read(sc, CS_TEST_AND_INIT); 1540 for (i = CS_TIMEOUT; 1541 i && (status & PLAYBACK_UNDERRUN) == 0; i--) { 1542 DELAY(5); 1543 status = cs4231_read(sc, CS_TEST_AND_INIT); 1544 } 1545 if (i == 0) 1546 device_printf(sc->sc_dev, "timeout waiting for " 1547 "playback FIFO drain\n"); 1548 cs4231_write(sc, CS_INTERFACE_CONFIG, 1549 cs4231_read(sc, CS_INTERFACE_CONFIG) & (~PLAYBACK_ENABLE)); 1550 } else { 1551 if ((sc->sc_flags & CS4231_SBUS) != 0) { 1552 /* XXX Kills some playback bits */ 1553 APC_WRITE(sc, APC_CSR, APC_CSR_CAPTURE_PAUSE); 1554 } else { 1555 EBDMA_C_WRITE(sc, EBDMA_DCSR, 1556 EBDMA_C_READ(sc, EBDMA_DCSR) & ~EBDCSR_DMAEN); 1557 } 1558 /* Waiting for capture FIFO to empty */ 1559 status = cs4231_read(sc, CS_TEST_AND_INIT); 1560 for (i = CS_TIMEOUT; 1561 i && (status & CAPTURE_OVERRUN) == 0; i--) { 1562 DELAY(5); 1563 status = cs4231_read(sc, CS_TEST_AND_INIT); 1564 } 1565 if (i == 0) 1566 device_printf(sc->sc_dev, "timeout waiting for " 1567 "capture FIFO drain\n"); 1568 cs4231_write(sc, CS_INTERFACE_CONFIG, 1569 cs4231_read(sc, CS_INTERFACE_CONFIG) & (~CAPTURE_ENABLE)); 1570 } 1571 ch->locked = 0; 1572 CS4231_UNLOCK(sc); 1573} 1574