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$");
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
95 struct cs4231_softc;
96
97 struct 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
111 struct 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
140 struct 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
150 static int cs4231_bus_probe(device_t);
151 static int cs4231_sbus_attach(device_t);
152 static int cs4231_ebus_attach(device_t);
153 static int cs4231_attach_common(struct cs4231_softc *);
154 static int cs4231_bus_detach(device_t);
155 static int cs4231_bus_suspend(device_t);
156 static int cs4231_bus_resume(device_t);
157 static void cs4231_getversion(struct cs4231_softc *);
158 static void cs4231_free_resource(struct cs4231_softc *);
159 static void cs4231_ebdma_reset(struct cs4231_softc *);
160 static void cs4231_power_reset(struct cs4231_softc *, int);
161 static int cs4231_enable(struct cs4231_softc *, int);
162 static void cs4231_disable(struct cs4231_softc *);
163 static void cs4231_write(struct cs4231_softc *, u_int8_t, u_int8_t);
164 static u_int8_t cs4231_read(struct cs4231_softc *, u_int8_t);
165 static void cs4231_sbus_intr(void *);
166 static void cs4231_ebus_pintr(void *arg);
167 static void cs4231_ebus_cintr(void *arg);
168 static int cs4231_mixer_init(struct snd_mixer *);
169 static void cs4231_mixer_set_value(struct cs4231_softc *,
170 const struct mix_table *, u_int8_t);
171 static int cs4231_mixer_set(struct snd_mixer *, u_int32_t, u_int32_t,
172 u_int32_t);
173 static int cs4231_mixer_setrecsrc(struct snd_mixer *, u_int32_t);
174 static void *cs4231_chan_init(kobj_t, void *, struct snd_dbuf *,
175 struct pcm_channel *, int);
176 static int cs4231_chan_setformat(kobj_t, void *, u_int32_t);
177 static int cs4231_chan_setspeed(kobj_t, void *, u_int32_t);
178 static void cs4231_chan_fs(struct cs4231_softc *, int, u_int8_t);
179 static int cs4231_chan_setblocksize(kobj_t, void *, u_int32_t);
180 static int cs4231_chan_trigger(kobj_t, void *, int);
181 static int cs4231_chan_getptr(kobj_t, void *);
182 static struct pcmchan_caps *
183 cs4231_chan_getcaps(kobj_t, void *);
184 static void cs4231_trigger(struct cs4231_channel *);
185 static void cs4231_apcdma_trigger(struct cs4231_softc *,
186 struct cs4231_channel *);
187 static void cs4231_ebdma_trigger(struct cs4231_softc *,
188 struct cs4231_channel *);
189 static 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 */
225 static 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
234 static driver_t cs4231_sbus_driver = {
235 "pcm",
236 cs4231_sbus_methods,
237 PCM_SOFTC_SIZE
238 };
239
240 DRIVER_MODULE(snd_audiocs, sbus, cs4231_sbus_driver, pcm_devclass, 0, 0);
241
242 /* EBus */
243 static 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
252 static driver_t cs4231_ebus_driver = {
253 "pcm",
254 cs4231_ebus_methods,
255 PCM_SOFTC_SIZE
256 };
257
258 DRIVER_MODULE(snd_audiocs, ebus, cs4231_ebus_driver, pcm_devclass, 0, 0);
259 MODULE_DEPEND(snd_audiocs, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
260 MODULE_VERSION(snd_audiocs, 1);
261
262
263 static 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
279 static struct pcmchan_caps cs4231_caps = {5510, 48000, cs4231_fmt, 0};
280
281 /*
282 * sound(4) channel interface
283 */
284 static 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 };
294 CHANNEL_DECLARE(cs4231_chan);
295
296 /*
297 * sound(4) mixer interface
298 */
299 static 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 };
305 MIXER_DECLARE(cs4231_mixer);
306
307 static int
308 cs4231_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
320 static int
321 cs4231_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
354 static int
355 cs4231_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
375 static int
376 cs4231_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
491 chan_fail:
492 pcm_unregister(sc->sc_dev);
493 fail:
494 cs4231_free_resource(sc);
495 return (ENXIO);
496 }
497
498 static int
499 cs4231_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
527 static int
528 cs4231_bus_suspend(device_t dev)
529 {
530
531 return (ENXIO);
532 }
533
534 static int
535 cs4231_bus_resume(device_t dev)
536 {
537
538 return (ENXIO);
539 }
540
541 static void
542 cs4231_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
571 static void
572 cs4231_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
600 static void
601 cs4231_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
661 static int
662 cs4231_enable(struct cs4231_softc *sc, int how)
663 {
664 cs4231_power_reset(sc, how);
665 sc->sc_enabled = 1;
666 return (0);
667 }
668
669 static void
670 cs4231_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
695 static void
696 cs4231_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
728 static void
729 cs4231_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
735 static u_int8_t
736 cs4231_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
742 static void
743 cs4231_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 */
804 static void
805 cs4231_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 */
852 static void
853 cs4231_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
898 static 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
929 static int
930 cs4231_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
948 static void
949 cs4231_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
980 static int
981 cs4231_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
995 static int
996 cs4231_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
1027 static void *
1028 cs4231_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
1057 static int
1058 cs4231_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
1116 static int
1117 cs4231_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
1174 static void
1175 cs4231_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
1266 static int
1267 cs4231_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
1288 static int
1289 cs4231_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
1312 static int
1313 cs4231_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
1338 static struct pcmchan_caps *
1339 cs4231_chan_getcaps(kobj_t obj, void *data)
1340 {
1341
1342 return (&cs4231_caps);
1343 }
1344
1345 static void
1346 cs4231_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
1357 static void
1358 cs4231_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
1430 static void
1431 cs4231_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
1514 static void
1515 cs4231_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 }
Cache object: 6ebecd32fbc307026ccc12e6f5268252
|