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
99struct cs4231_softc;
100
101struct 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
115struct 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
143struct 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
153static int	cs4231_bus_probe(device_t);
154static int	cs4231_sbus_attach(device_t);
155static int	cs4231_ebus_attach(device_t);
156static int	cs4231_attach_common(struct cs4231_softc *);
157static int	cs4231_bus_detach(device_t);
158static int	cs4231_bus_suspend(device_t);
159static int	cs4231_bus_resume(device_t);
160static void	cs4231_getversion(struct cs4231_softc *);
161static void	cs4231_free_resource(struct cs4231_softc *);
162static void	cs4231_ebdma_reset(struct cs4231_softc *);
163static void	cs4231_power_reset(struct cs4231_softc *, int);
164static int	cs4231_enable(struct cs4231_softc *, int);
165static void	cs4231_disable(struct cs4231_softc *);
166static void	cs4231_write(struct cs4231_softc *, u_int8_t, u_int8_t);
167static u_int8_t cs4231_read(struct cs4231_softc *, u_int8_t);
168static void	cs4231_sbus_intr(void *);
169static void	cs4231_ebus_pintr(void *arg);
170static void	cs4231_ebus_cintr(void *arg);
171static int	cs4231_mixer_init(struct snd_mixer *);
172static void	cs4231_mixer_set_value(struct cs4231_softc *,
173    const struct mix_table *, u_int8_t);
174static int	cs4231_mixer_set(struct snd_mixer *, u_int32_t, u_int32_t,
175    u_int32_t);
176static u_int32_t	cs4231_mixer_setrecsrc(struct snd_mixer *, u_int32_t);
177static void	*cs4231_chan_init(kobj_t, void *, struct snd_dbuf *,
178    struct pcm_channel *, int);
179static int	cs4231_chan_setformat(kobj_t, void *, u_int32_t);
180static u_int32_t	cs4231_chan_setspeed(kobj_t, void *, u_int32_t);
181static void	cs4231_chan_fs(struct cs4231_softc *, int, u_int8_t);
182static u_int32_t	cs4231_chan_setblocksize(kobj_t, void *, u_int32_t);
183static int	cs4231_chan_trigger(kobj_t, void *, int);
184static u_int32_t	cs4231_chan_getptr(kobj_t, void *);
185static struct pcmchan_caps *
186    cs4231_chan_getcaps(kobj_t, void *);
187static void	cs4231_trigger(struct cs4231_channel *);
188static void	cs4231_apcdma_trigger(struct cs4231_softc *,
189    struct cs4231_channel *);
190static void	cs4231_ebdma_trigger(struct cs4231_softc *,
191    struct cs4231_channel *);
192static 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 */
228static 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
238static driver_t cs4231_sbus_driver = {
239	"pcm",
240	cs4231_sbus_methods,
241	PCM_SOFTC_SIZE
242};
243
244DRIVER_MODULE(snd_audiocs, sbus, cs4231_sbus_driver, pcm_devclass, 0, 0);
245
246/* EBus */
247static 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
257static driver_t cs4231_ebus_driver = {
258	"pcm",
259	cs4231_ebus_methods,
260	PCM_SOFTC_SIZE
261};
262
263DRIVER_MODULE(snd_audiocs, ebus, cs4231_ebus_driver, pcm_devclass, 0, 0);
264MODULE_DEPEND(snd_audiocs, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
265MODULE_VERSION(snd_audiocs, 1);
266
267
268static 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
284static struct pcmchan_caps cs4231_caps = {5510, 48000, cs4231_fmt, 0};
285
286/*
287 * sound(4) channel interface
288 */
289static 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};
299CHANNEL_DECLARE(cs4231_chan);
300
301/*
302 * sound(4) mixer interface
303 */
304static 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};
310MIXER_DECLARE(cs4231_mixer);
311
312static int
313cs4231_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
327static int
328cs4231_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
354static int
355cs4231_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
372static int
373cs4231_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
483chan_fail:
484	pcm_unregister(sc->sc_dev);
485fail:
486	cs4231_free_resource(sc);
487	return (ENXIO);
488}
489
490static int
491cs4231_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
519static int
520cs4231_bus_suspend(device_t dev)
521{
522
523	return (ENXIO);
524}
525
526static int
527cs4231_bus_resume(device_t dev)
528{
529
530	return (ENXIO);
531}
532
533static void
534cs4231_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
563static void
564cs4231_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
592static void
593cs4231_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
653static int
654cs4231_enable(struct cs4231_softc *sc, int how)
655{
656	cs4231_power_reset(sc, how);
657	sc->sc_enabled = 1;
658        return (0);
659}
660
661static void
662cs4231_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
687static void
688cs4231_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
720static void
721cs4231_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
727static u_int8_t
728cs4231_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
734static void
735cs4231_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 */
796static void
797cs4231_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 */
844static void
845cs4231_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
890static 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
921static int
922cs4231_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
940static void
941cs4231_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
972static int
973cs4231_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
987static u_int32_t
988cs4231_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
1019static void *
1020cs4231_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
1049static int
1050cs4231_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
1108static u_int32_t
1109cs4231_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
1166static void
1167cs4231_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
1258static u_int32_t
1259cs4231_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
1280static int
1281cs4231_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
1304static u_int32_t
1305cs4231_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
1329static struct pcmchan_caps *
1330cs4231_chan_getcaps(kobj_t obj, void *data)
1331{
1332
1333	return (&cs4231_caps);
1334}
1335
1336static void
1337cs4231_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
1348static void
1349cs4231_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
1421static void
1422cs4231_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
1505static void
1506cs4231_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}
1565