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