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