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