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