emu10kx-pcm.c revision 160409
1/*-
2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
3 * Copyright (c) 2003-2006 Yuriy Tsibizov <yuriy.tsibizov@gfk.ru>
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 AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sys/dev/sound/pci/emu10kx-pcm.c 160409 2006-07-16 20:10:08Z netchild $
28 */
29
30#include <sys/param.h>
31#include <sys/types.h>
32#include <sys/bus.h>
33#include <machine/bus.h>
34#include <sys/rman.h>
35#include <sys/systm.h>
36#include <sys/sbuf.h>
37#include <sys/queue.h>
38#include <sys/systm.h>
39#include <sys/lock.h>
40#include <sys/mutex.h>
41
42#include <dev/sound/chip.h>
43#include <dev/sound/pcm/sound.h>
44#include <dev/sound/pcm/ac97.h>
45
46#include "mixer_if.h"
47
48#include "opt_emu10kx.h"
49#include <dev/sound/pci/emu10kx.h>
50#include "emu10k1-alsa%diked.h"
51
52struct emu_pcm_pchinfo {
53	int		spd;
54	int		fmt;
55	int		blksz;
56	int		run;
57	struct emu_voice *master;
58	struct emu_voice *slave;
59	struct snd_dbuf	*buffer;
60	struct pcm_channel *channel;
61	struct emu_pcm_info *pcm;
62	int		timer;
63};
64
65struct emu_pcm_rchinfo {
66	int		spd;
67	int		fmt;
68	int		blksz;
69	int		run;
70	uint32_t 	idxreg;
71	uint32_t	basereg;
72	uint32_t	sizereg;
73	uint32_t	setupreg;
74	uint32_t	irqmask;
75	uint32_t	iprmask;
76	int 		ihandle;
77	struct snd_dbuf	*buffer;
78	struct pcm_channel *channel;
79	struct emu_pcm_info *pcm;
80};
81
82/* Hardware channels for front output */
83#define	MAX_CHANNELS	4
84
85#if MAX_CHANNELS > 13
86#error	Too many hardware channels defined. 13 is the maximum
87#endif
88struct emu_pcm_info {
89	struct mtx		*lock;
90	device_t		dev;		/* device information */
91	struct snddev_info 	*devinfo;	/* pcm device information */
92	struct emu_sc_info 	*card;
93	struct emu_pcm_pchinfo	pch[MAX_CHANNELS];	/* hardware channels */
94	int			pnum;		/* next free channel number */
95	struct emu_pcm_rchinfo	rch;
96	struct emu_route	rt;
97	int			route;
98	int			ihandle;	/* interrupt handler */
99	unsigned int		bufsz;
100	int			is_emu10k1;
101	struct ac97_info	*codec;
102	uint32_t 		ac97_state[0x7F];
103};
104
105
106static uint32_t emu_rfmt[] = {
107	AFMT_S16_LE,
108	AFMT_STEREO | AFMT_S16_LE,
109	0
110};
111static struct pcmchan_caps emu_reccaps = {
112	/* XXX should be "8000, 48000, emu_rfmt, 0", but 8000/8bit/mono is broken */
113	11025, 48000, emu_rfmt, 0
114};
115
116static uint32_t emu_pfmt[] = {
117	AFMT_U8,
118	AFMT_STEREO | AFMT_U8,
119	AFMT_S16_LE,
120	AFMT_STEREO | AFMT_S16_LE,
121	0
122};
123static uint32_t emu_pfmt_mono[] = {
124	AFMT_U8,
125	AFMT_S16_LE,
126	0
127};
128
129static struct pcmchan_caps emu_playcaps = {4000, 48000, emu_pfmt, 0};
130static struct pcmchan_caps emu_playcaps_mono = {4000, 48000, emu_pfmt_mono, 0};
131
132static int emu10k1_adcspeed[8] = {48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000};
133/* audigy supports 12kHz. */
134static int emu10k2_adcspeed[9] = {48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};
135
136static uint32_t emu_pcm_intr(void *pcm, uint32_t stat);
137
138static const struct emu_dspmix_props {
139	u_int8_t	present;
140} dspmix [SOUND_MIXER_NRDEVICES] = {
141	[SOUND_MIXER_VOLUME] =	{1},
142	[SOUND_MIXER_PCM] =	{1},
143};
144
145static int
146emu_dspmixer_init(struct snd_mixer *m)
147{
148	int i;
149	int v;
150
151	v = 0;
152	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
153		if (dspmix[i].present)
154			v |= 1 << i;
155	}
156	mix_setdevs(m, v);
157
158	mix_setrecdevs(m, 0);
159	return (0);
160}
161
162static int
163emu_dspmixer_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
164{
165	struct emu_pcm_info *sc;
166
167	sc = mix_getdevinfo(m);
168
169	switch (dev) {
170	case SOUND_MIXER_VOLUME:
171		switch (sc->route) {
172		case RT_REAR:
173			emumix_set_volume(sc->card, M_MASTER_REAR_L, left);
174			emumix_set_volume(sc->card, M_MASTER_REAR_R, right);
175			break;
176		case RT_CENTER:
177			emumix_set_volume(sc->card, M_MASTER_CENTER, (left+right)/2);
178			break;
179		case RT_SUB:
180			emumix_set_volume(sc->card, M_MASTER_SUBWOOFER, (left+right)/2);
181			break;
182		}
183		break;
184	case SOUND_MIXER_PCM:
185		switch (sc->route) {
186		case RT_REAR:
187			emumix_set_volume(sc->card, M_FX2_REAR_L, left);
188			emumix_set_volume(sc->card, M_FX3_REAR_R, right);
189			break;
190		case RT_CENTER:
191			emumix_set_volume(sc->card, M_FX4_CENTER, (left+right)/2);
192			break;
193		case RT_SUB:
194			emumix_set_volume(sc->card, M_FX5_SUBWOOFER, (left+right)/2);
195			break;
196		}
197		break;
198	default:
199		device_printf(sc->dev, "mixer error: unknown device %d\n", dev);
200	}
201	return  (0);
202}
203
204static int
205emu_dspmixer_setrecsrc(struct snd_mixer *m __unused, u_int32_t src __unused)
206{
207	return (0);
208}
209
210static kobj_method_t emudspmixer_methods[] = {
211	KOBJMETHOD(mixer_init,		emu_dspmixer_init),
212	KOBJMETHOD(mixer_set,		emu_dspmixer_set),
213	KOBJMETHOD(mixer_setrecsrc,	emu_dspmixer_setrecsrc),
214	{ 0, 0 }
215};
216MIXER_DECLARE(emudspmixer);
217
218/*
219 * AC97 emulation code for Audigy and later cards.
220 * Some parts of AC97 codec are not used by hardware, but can be used
221 * to change some DSP controls via AC97 mixer interface. This includes:
222 * - master volume controls MASTER_FRONT_[R|L]
223 * - pcm volume controls FX[0|1]_FRONT_[R|L]
224 * - rec volume controls MASTER_REC_[R|L]
225 * We do it because we need to put it under user control....
226 * We also keep some parts of AC97 disabled to get better sound quality
227 */
228
229#define	AC97LEFT(x)	((x & 0x7F00)>>8)
230#define	AC97RIGHT(x)	(x & 0x007F)
231#define	AC97MUTE(x)	((x & 0x8000)>>15)
232#define	BIT4_TO100(x)	(100-(x)*100/(0x0f))
233#define	BIT6_TO100(x)	(100-(x)*100/(0x3f))
234#define	BIT4_TO255(x)	(255-(x)*255/(0x0f))
235#define	BIT6_TO255(x)	(255-(x)*255/(0x3f))
236#define	V100_TOBIT6(x)	(0x3f*(100-x)/100)
237#define	V100_TOBIT4(x)	(0x0f*(100-x)/100)
238#define	AC97ENCODE(x_muted,x_left,x_right)	(((x_muted&1)<<15) | ((x_left&0x3f)<<8) | (x_right&0x3f))
239
240static int
241emu_ac97_read_emulation(struct emu_pcm_info *sc, int regno)
242{
243	int use_ac97;
244	int emulated;
245	int tmp;
246
247	use_ac97 = 1;
248	emulated = 0;
249
250	switch (regno) {
251	case AC97_MIX_MASTER:
252		emulated = sc->ac97_state[AC97_MIX_MASTER];
253		use_ac97 = 0;
254		break;
255	case AC97_MIX_PCM:
256		emulated = sc->ac97_state[AC97_MIX_PCM];
257		use_ac97 = 0;
258		break;
259	case AC97_REG_RECSEL:
260		emulated = 0x0505;
261		use_ac97 = 0;
262		break;
263	case AC97_MIX_RGAIN:
264		emulated = sc->ac97_state[AC97_MIX_RGAIN];
265		use_ac97 = 0;
266		break;
267	}
268
269	emu_wr(sc->card, AC97ADDRESS, regno, 1);
270	tmp = emu_rd(sc->card, AC97DATA, 2);
271
272	if (use_ac97)
273		emulated = tmp;
274
275	return (emulated);
276}
277
278static void
279emu_ac97_write_emulation(struct emu_pcm_info *sc, int regno, uint32_t data)
280{
281	int write_ac97;
282	int left, right;
283	uint32_t emu_left, emu_right;
284	int is_mute;
285
286	write_ac97 = 1;
287
288	left = AC97LEFT(data);
289	emu_left = BIT6_TO100(left);	/* We show us as 6-bit AC97 mixer */
290	right = AC97RIGHT(data);
291	emu_right = BIT6_TO100(right);
292	is_mute = AC97MUTE(data);
293	if (is_mute)
294		emu_left = emu_right = 0;
295
296	switch (regno) {
297		/* TODO: reset emulator on AC97_RESET */
298	case AC97_MIX_MASTER:
299		emumix_set_volume(sc->card, M_MASTER_FRONT_L, emu_left);
300		emumix_set_volume(sc->card, M_MASTER_FRONT_R, emu_right);
301		sc->ac97_state[AC97_MIX_MASTER] = data & (0x8000 | 0x3f3f);
302		data = 0x8000;	/* Mute AC97 main out */
303		break;
304	case AC97_MIX_PCM:	/* PCM OUT VOL */
305		emumix_set_volume(sc->card, M_FX0_FRONT_L, emu_left);
306		emumix_set_volume(sc->card, M_FX1_FRONT_R, emu_right);
307		sc->ac97_state[AC97_MIX_PCM] = data & (0x8000 | 0x3f3f);
308		data = 0x8000;	/* Mute AC97 PCM out */
309		break;
310	case AC97_REG_RECSEL:
311		/*
312		 * PCM recording source is set to "stereo mix" (labeled "vol"
313		 * in mixer) XXX !I can't remember why!
314		 */
315		data = 0x0505;
316		break;
317	case AC97_MIX_RGAIN:	/* RECORD GAIN */
318		emu_left = BIT4_TO100(left);	/* rgain is 4-bit */
319		emu_right = BIT4_TO100(right);
320		emumix_set_volume(sc->card, M_MASTER_REC_L, 100-emu_left);
321		emumix_set_volume(sc->card, M_MASTER_REC_R, 100-emu_right);
322		/*
323		 * Record gain on AC97 should stay zero to get AC97 sound on
324		 * AC97_[RL] connectors on EMU10K2 chip. AC97 on Audigy is not
325		 * directly connected to any output, only to EMU10K2 chip Use
326		 * this control to set AC97 mix volume inside EMU10K2 chip
327		 */
328		sc->ac97_state[AC97_MIX_RGAIN] = data & (0x8000 | 0x0f0f);
329		data = 0x0000;
330		break;
331	}
332	if (write_ac97) {
333		emu_wr(sc->card, AC97ADDRESS, regno, 1);
334		emu_wr(sc->card, AC97DATA, data, 2);
335	}
336}
337
338static int
339emu_erdcd(kobj_t obj __unused, void *devinfo, int regno)
340{
341	struct emu_pcm_info *sc = (struct emu_pcm_info *)devinfo;
342
343	return (emu_ac97_read_emulation(sc, regno));
344}
345
346static int
347emu_ewrcd(kobj_t obj __unused, void *devinfo, int regno, uint32_t data)
348{
349	struct emu_pcm_info *sc = (struct emu_pcm_info *)devinfo;
350
351	emu_ac97_write_emulation(sc, regno, data);
352	return (0);
353}
354
355static kobj_method_t emu_eac97_methods[] = {
356	KOBJMETHOD(ac97_read, emu_erdcd),
357	KOBJMETHOD(ac97_write, emu_ewrcd),
358	{0, 0}
359};
360AC97_DECLARE(emu_eac97);
361
362/* real ac97 codec */
363static int
364emu_rdcd(kobj_t obj __unused, void *devinfo, int regno)
365{
366	int rd;
367	struct emu_pcm_info *sc = (struct emu_pcm_info *)devinfo;
368
369	KASSERT(sc->card != NULL, ("emu_rdcd: no soundcard"));
370	emu_wr(sc->card, AC97ADDRESS, regno, 1);
371	rd = emu_rd(sc->card, AC97DATA, 2);
372	return (rd);
373}
374
375static int
376emu_wrcd(kobj_t obj __unused, void *devinfo, int regno, uint32_t data)
377{
378	struct emu_pcm_info *sc = (struct emu_pcm_info *)devinfo;
379
380	KASSERT(sc->card != NULL, ("emu_wrcd: no soundcard"));
381	emu_wr(sc->card, AC97ADDRESS, regno, 1);
382	emu_wr(sc->card, AC97DATA, data, 2);
383	return (0);
384}
385
386static kobj_method_t emu_ac97_methods[] = {
387	KOBJMETHOD(ac97_read, emu_rdcd),
388	KOBJMETHOD(ac97_write, emu_wrcd),
389	{0, 0}
390};
391AC97_DECLARE(emu_ac97);
392
393
394static int
395emu_k1_recval(int speed)
396{
397	int val;
398
399	val = 0;
400	while ((val < 7) && (speed < emu10k1_adcspeed[val]))
401		val++;
402	if (val == 6) val=5; /* XXX 8kHz does not work */
403	return (val);
404}
405
406static int
407emu_k2_recval(int speed)
408{
409	int val;
410
411	val = 0;
412	while ((val < 8) && (speed < emu10k2_adcspeed[val]))
413		val++;
414	if (val == 7) val=6; /* XXX 8kHz does not work */
415	return (val);
416}
417
418static void *
419emupchan_init(kobj_t obj __unused, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir __unused)
420{
421	struct emu_pcm_info *sc = devinfo;
422	struct emu_pcm_pchinfo *ch;
423	void *r;
424
425	KASSERT(dir == PCMDIR_PLAY, ("emupchan_init: bad direction"));
426	KASSERT(sc->card != NULL, ("empchan_init: no soundcard"));
427
428
429	if (sc->pnum >= MAX_CHANNELS)
430		return (NULL);
431	ch = &(sc->pch[sc->pnum++]);
432	ch->buffer = b;
433	ch->pcm = sc;
434	ch->channel = c;
435	ch->blksz = sc->bufsz;
436	ch->fmt = AFMT_U8;
437	ch->spd = 8000;
438	ch->master = emu_valloc(sc->card);
439	/*
440	 * XXX we have to allocate slave even for mono channel until we
441	 * fix emu_vfree to handle this case.
442	 */
443	ch->slave = emu_valloc(sc->card);
444	ch->timer = emu_timer_create(sc->card);
445	r = (emu_vinit(sc->card, ch->master, ch->slave, sc->bufsz, ch->buffer)) ? NULL : ch;
446	return (r);
447}
448
449static int
450emupchan_free(kobj_t obj __unused, void *c_devinfo)
451{
452	struct emu_pcm_pchinfo *ch = c_devinfo;
453	struct emu_pcm_info *sc = ch->pcm;
454
455	emu_timer_clear(sc->card, ch->timer);
456	if (ch->slave != NULL)
457		emu_vfree(sc->card, ch->slave);
458	emu_vfree(sc->card, ch->master);
459	return (0);
460}
461
462static int
463emupchan_setformat(kobj_t obj __unused, void *c_devinfo, uint32_t format)
464{
465	struct emu_pcm_pchinfo *ch = c_devinfo;
466
467	ch->fmt = format;
468	return (0);
469}
470
471static int
472emupchan_setspeed(kobj_t obj __unused, void *c_devinfo, uint32_t speed)
473{
474	struct emu_pcm_pchinfo *ch = c_devinfo;
475
476	ch->spd = speed;
477	return (ch->spd);
478}
479
480static int
481emupchan_setblocksize(kobj_t obj __unused, void *c_devinfo, uint32_t blocksize)
482{
483	struct emu_pcm_pchinfo *ch = c_devinfo;
484	struct emu_pcm_info *sc = ch->pcm;
485
486	if (blocksize > ch->pcm->bufsz)
487		blocksize = ch->pcm->bufsz;
488	snd_mtxlock(sc->lock);
489	ch->blksz = blocksize;
490	emu_timer_set(sc->card, ch->timer, ch->blksz / sndbuf_getbps(ch->buffer));
491	snd_mtxunlock(sc->lock);
492	return (blocksize);
493}
494
495static int
496emupchan_trigger(kobj_t obj __unused, void *c_devinfo, int go)
497{
498	struct emu_pcm_pchinfo *ch = c_devinfo;
499	struct emu_pcm_info *sc = ch->pcm;
500
501	if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
502		return (0);
503	snd_mtxlock(sc->lock); /* XXX can we trigger on parallel threads ? */
504	if (go == PCMTRIG_START) {
505		emu_vsetup(ch->master, ch->fmt, ch->spd);
506		emu_vroute(sc->card, &(sc->rt), ch->master);
507		emu_vwrite(sc->card, ch->master);
508		emu_timer_set(sc->card, ch->timer, ch->blksz / sndbuf_getbps(ch->buffer));
509		emu_timer_enable(sc->card, ch->timer, 1);
510	}
511	/* PCM interrupt handler will handle PCMTRIG_STOP event */
512	ch->run = (go == PCMTRIG_START) ? 1 : 0;
513	emu_vtrigger(sc->card, ch->master, ch->run);
514	snd_mtxunlock(sc->lock);
515	return (0);
516}
517
518static int
519emupchan_getptr(kobj_t obj __unused, void *c_devinfo)
520{
521	struct emu_pcm_pchinfo *ch = c_devinfo;
522	struct emu_pcm_info *sc = ch->pcm;
523	int r;
524
525	r = emu_vpos(sc->card, ch->master);
526
527	return (r);
528}
529
530static struct pcmchan_caps *
531emupchan_getcaps(kobj_t obj __unused, void *c_devinfo __unused)
532{
533	struct emu_pcm_pchinfo *ch = c_devinfo;
534	struct emu_pcm_info *sc = ch->pcm;
535
536	switch (sc->route) {
537	case RT_FRONT:
538		/* FALLTHROUGH */
539	case RT_REAR:
540		/* FALLTHROUGH */
541	case RT_SIDE:
542		return (&emu_playcaps);
543		break;
544	case RT_CENTER:
545		/* FALLTHROUGH */
546	case RT_SUB:
547		return (&emu_playcaps_mono);
548		break;
549	}
550	return (NULL);
551}
552
553static kobj_method_t emupchan_methods[] = {
554	KOBJMETHOD(channel_init, emupchan_init),
555	KOBJMETHOD(channel_free, emupchan_free),
556	KOBJMETHOD(channel_setformat, emupchan_setformat),
557	KOBJMETHOD(channel_setspeed, emupchan_setspeed),
558	KOBJMETHOD(channel_setblocksize, emupchan_setblocksize),
559	KOBJMETHOD(channel_trigger, emupchan_trigger),
560	KOBJMETHOD(channel_getptr, emupchan_getptr),
561	KOBJMETHOD(channel_getcaps, emupchan_getcaps),
562	{0, 0}
563};
564CHANNEL_DECLARE(emupchan);
565
566static void *
567emurchan_init(kobj_t obj __unused, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir __unused)
568{
569	struct emu_pcm_info *sc = devinfo;
570	struct emu_pcm_rchinfo *ch;
571
572	KASSERT(dir == PCMDIR_REC, ("emurchan_init: bad direction"));
573	ch = &sc->rch;
574	ch->buffer = b;
575	ch->pcm = sc;
576	ch->channel = c;
577	ch->blksz = sc->bufsz;
578	ch->fmt = AFMT_U8;
579	ch->spd = 11025;	/* XXX 8000 Hz does not work */
580	ch->idxreg = sc->is_emu10k1 ? ADCIDX : A_ADCIDX;
581	ch->basereg = ADCBA;
582	ch->sizereg = ADCBS;
583	ch->setupreg = ADCCR;
584	ch->irqmask = INTE_ADCBUFENABLE;
585	ch->iprmask = IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL;
586
587	if (sndbuf_alloc(ch->buffer, emu_gettag(sc->card), sc->bufsz) != 0)
588		return (NULL);
589	else {
590		emu_wrptr(sc->card, 0, ch->basereg, sndbuf_getbufaddr(ch->buffer));
591		emu_wrptr(sc->card, 0, ch->sizereg, 0);	/* off */
592		return (ch);
593	}
594}
595
596static int
597emurchan_setformat(kobj_t obj __unused, void *c_devinfo, uint32_t format)
598{
599	struct emu_pcm_rchinfo *ch = c_devinfo;
600
601	ch->fmt = format;
602	return (0);
603}
604
605static int
606emurchan_setspeed(kobj_t obj __unused, void *c_devinfo, uint32_t speed)
607{
608	struct emu_pcm_rchinfo *ch = c_devinfo;
609
610	if (ch->pcm->is_emu10k1) {
611		speed = emu10k1_adcspeed[emu_k1_recval(speed)];
612	} else {
613		speed = emu10k2_adcspeed[emu_k2_recval(speed)];
614	}
615	ch->spd = speed;
616	return (ch->spd);
617}
618
619static int
620emurchan_setblocksize(kobj_t obj __unused, void *c_devinfo, uint32_t blocksize)
621{
622	struct emu_pcm_rchinfo *ch = c_devinfo;
623
624	ch->blksz = blocksize;
625	return (blocksize);
626}
627
628static int
629emurchan_trigger(kobj_t obj __unused, void *c_devinfo, int go)
630{
631	struct emu_pcm_rchinfo *ch = c_devinfo;
632	struct emu_pcm_info *sc = ch->pcm;
633	uint32_t val, sz;
634
635	switch (sc->bufsz) {
636	case 4096:
637		sz = ADCBS_BUFSIZE_4096;
638		break;
639	case 8192:
640		sz = ADCBS_BUFSIZE_8192;
641		break;
642	case 16384:
643		sz = ADCBS_BUFSIZE_16384;
644		break;
645	case 32768:
646		sz = ADCBS_BUFSIZE_32768;
647		break;
648	case 65536:
649		sz = ADCBS_BUFSIZE_65536;
650		break;
651	default:
652		sz = ADCBS_BUFSIZE_4096;
653	}
654
655	snd_mtxlock(sc->lock);
656	switch (go) {
657	case PCMTRIG_START:
658		ch->run = 1;
659		emu_wrptr(sc->card, 0, ch->sizereg, sz);
660		val = sc->is_emu10k1 ? ADCCR_LCHANENABLE : A_ADCCR_LCHANENABLE;
661		if (ch->fmt & AFMT_STEREO)
662			val |= sc->is_emu10k1 ? ADCCR_RCHANENABLE : A_ADCCR_RCHANENABLE;
663		val |= sc->is_emu10k1 ? emu_k1_recval(ch->spd) : emu_k2_recval(ch->spd);
664		emu_wrptr(sc->card, 0, ch->setupreg, 0);
665		emu_wrptr(sc->card, 0, ch->setupreg, val);
666		ch->ihandle = emu_intr_register(sc->card, ch->irqmask, ch->iprmask, &emu_pcm_intr, sc);
667		break;
668	case PCMTRIG_STOP:
669		/* FALLTHROUGH */
670	case PCMTRIG_ABORT:
671		ch->run = 0;
672		emu_wrptr(sc->card, 0, ch->sizereg, 0);
673		if (ch->setupreg)
674			emu_wrptr(sc->card, 0, ch->setupreg, 0);
675		(void)emu_intr_unregister(sc->card, ch->ihandle);
676		break;
677	case PCMTRIG_EMLDMAWR:
678		/* FALLTHROUGH */
679	case PCMTRIG_EMLDMARD:
680		/* FALLTHROUGH */
681	default:
682		break;
683	}
684	snd_mtxunlock(sc->lock);
685
686	return (0);
687}
688
689static int
690emurchan_getptr(kobj_t obj __unused, void *c_devinfo)
691{
692	struct emu_pcm_rchinfo *ch = c_devinfo;
693	struct emu_pcm_info *sc = ch->pcm;
694	int r;
695
696	r = emu_rdptr(sc->card, 0, ch->idxreg) & 0x0000ffff;
697
698	return (r);
699}
700
701static struct pcmchan_caps *
702emurchan_getcaps(kobj_t obj __unused, void *c_devinfo __unused)
703{
704	return (&emu_reccaps);
705}
706
707static kobj_method_t emurchan_methods[] = {
708	KOBJMETHOD(channel_init, emurchan_init),
709	KOBJMETHOD(channel_setformat, emurchan_setformat),
710	KOBJMETHOD(channel_setspeed, emurchan_setspeed),
711	KOBJMETHOD(channel_setblocksize, emurchan_setblocksize),
712	KOBJMETHOD(channel_trigger, emurchan_trigger),
713	KOBJMETHOD(channel_getptr, emurchan_getptr),
714	KOBJMETHOD(channel_getcaps, emurchan_getcaps),
715	{0, 0}
716};
717CHANNEL_DECLARE(emurchan);
718
719
720static uint32_t
721emu_pcm_intr(void *pcm, uint32_t stat)
722{
723	struct emu_pcm_info *sc = (struct emu_pcm_info *)pcm;
724	uint32_t ack;
725	int i;
726
727	ack = 0;
728
729	if (stat & IPR_INTERVALTIMER) {
730		ack |= IPR_INTERVALTIMER;
731		for (i = 0; i < MAX_CHANNELS; i++)
732			if (sc->pch[i].channel) {
733				if (sc->pch[i].run == 1)
734					chn_intr(sc->pch[i].channel);
735				else
736					emu_timer_enable(sc->card, sc->pch[i].timer, 0);
737			}
738	}
739
740
741	if (stat & (IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL)) {
742		ack |= stat & (IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL);
743		if (sc->rch.channel)
744			chn_intr(sc->rch.channel);
745	}
746	return (ack);
747}
748
749static int
750emu_pcm_init(struct emu_pcm_info *sc)
751{
752	sc->bufsz = pcm_getbuffersize(sc->dev, 4096, EMU_DEFAULT_BUFSZ, EMU_MAX_BUFSZ);
753	return (0);
754}
755
756static int
757emu_pcm_uninit(struct emu_pcm_info *sc __unused)
758{
759	return (0);
760}
761
762static int
763emu_pcm_probe(device_t dev)
764{
765	uintptr_t func, route, r;
766	const char *rt;
767	char buffer[255];
768
769	r = BUS_READ_IVAR(device_get_parent(dev), dev, EMU_VAR_FUNC, &func);
770
771	if (func != SCF_PCM)
772		return (ENXIO);
773
774	rt = "UNKNOWN";
775	r = BUS_READ_IVAR(device_get_parent(dev), dev, EMU_VAR_ROUTE, &route);
776	switch (route) {
777	case RT_FRONT:
778		rt = "FRONT";
779		break;
780	case RT_REAR:
781		rt = "REAR";
782		break;
783	case RT_CENTER:
784		rt = "CENTER";
785		break;
786	case RT_SUB:
787		rt = "SUBWOOFER";
788		break;
789	case RT_SIDE:
790		rt = "SIDE";
791		break;
792	}
793
794	snprintf(buffer, 255, "EMU10Kx DSP %s PCM Interface", rt);
795	device_set_desc_copy(dev, buffer);
796	return (0);
797}
798
799static int
800emu_pcm_attach(device_t dev)
801{
802	struct emu_pcm_info *sc;
803	unsigned int i;
804	char status[SND_STATUSLEN];
805	uint32_t inte, ipr;
806	uintptr_t route, r, is_emu10k1;
807
808	if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO)) == NULL) {
809		device_printf(dev, "cannot allocate softc\n");
810		return (ENXIO);
811	}
812	bzero(sc, sizeof(*sc));
813
814	sc->card = (struct emu_sc_info *)(device_get_softc(device_get_parent(dev)));
815	if (sc->card == NULL) {
816		device_printf(dev, "cannot get bridge conf\n");
817		return (ENXIO);
818	}
819
820	sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
821	sc->dev = dev;
822
823	r = BUS_READ_IVAR(device_get_parent(dev), dev, EMU_VAR_ISEMU10K1, &is_emu10k1);
824	sc->is_emu10k1 = is_emu10k1 ? 1 : 0;
825
826	sc->codec = NULL;
827
828	for (i = 0; i < 8; i++) {
829		sc->rt.routing_left[i] = i;
830		sc->rt.amounts_left[i] = 0x00;
831		sc->rt.routing_right[i] = i;
832		sc->rt.amounts_right[i] = 0x00;
833	}
834
835	r = BUS_READ_IVAR(device_get_parent(dev), dev, EMU_VAR_ROUTE, &route);
836	sc->route = route;
837	switch (route) {
838	case RT_FRONT:
839		sc->rt.amounts_left[0] = 0xff;
840		sc->rt.amounts_right[1] = 0xff;
841		if (sc->is_emu10k1)
842			sc->codec = AC97_CREATE(dev, sc, emu_ac97);
843		else
844			sc->codec = AC97_CREATE(dev, sc, emu_eac97);
845 		if (sc->codec == NULL) {
846 			if (mixer_init(dev, &emudspmixer_class, sc)) {
847 				device_printf(dev, "failed to initialize DSP mixer\n");
848 				goto bad;
849 			}
850 		} else
851			if (mixer_init(dev, ac97_getmixerclass(), sc->codec) == -1) {
852 				device_printf(dev, "can't initialize AC97 mixer!\n");
853 				goto bad;
854			}
855		break;
856	case RT_REAR:
857		sc->rt.amounts_left[2] = 0xff;
858		sc->rt.amounts_right[3] = 0xff;
859		if (mixer_init(dev, &emudspmixer_class, sc)) {
860			device_printf(dev, "failed to initialize mixer\n");
861			goto bad;
862		}
863		break;
864	case RT_CENTER:
865		sc->rt.amounts_left[4] = 0xff;
866		if (mixer_init(dev, &emudspmixer_class, sc)) {
867			device_printf(dev, "failed to initialize mixer\n");
868			goto bad;
869		}
870		break;
871	case RT_SUB:
872		sc->rt.amounts_left[5] = 0xff;
873		if (mixer_init(dev, &emudspmixer_class, sc)) {
874			device_printf(dev, "failed to initialize mixer\n");
875			goto bad;
876		}
877		break;
878	case RT_SIDE:
879		sc->rt.amounts_left[6] = 0xff;
880		sc->rt.amounts_right[7] = 0xff;
881		if (mixer_init(dev, &emudspmixer_class, sc)) {
882			device_printf(dev, "failed to initialize mixer\n");
883			goto bad;
884		}
885		break;
886	default:
887		device_printf(dev, "invalid default route\n");
888		goto bad;
889	}
890
891	inte = INTE_INTERVALTIMERENB;
892	ipr = IPR_INTERVALTIMER; /* Used by playback */
893	sc->ihandle = emu_intr_register(sc->card, inte, ipr, &emu_pcm_intr, sc);
894
895	if (emu_pcm_init(sc) == -1) {
896		device_printf(dev, "unable to initialize PCM part of the card\n");
897		goto bad;
898	}
899
900	/* XXX we should better get number of available channels from parent */
901	if (pcm_register(dev, sc, (route == RT_FRONT) ? MAX_CHANNELS : 1, (route == RT_FRONT) ? 1 : 0)) {
902		device_printf(dev, "can't register PCM channels!\n");
903		goto bad;
904	}
905	sc->pnum = 0;
906	pcm_addchan(dev, PCMDIR_PLAY, &emupchan_class, sc);
907	if (route == RT_FRONT) {
908		for (i = 1; i < MAX_CHANNELS; i++)
909			pcm_addchan(dev, PCMDIR_PLAY, &emupchan_class, sc);
910		pcm_addchan(dev, PCMDIR_REC, &emurchan_class, sc);
911	}
912	snprintf(status, SND_STATUSLEN, "on %s", device_get_nameunit(device_get_parent(dev)));
913	pcm_setstatus(dev, status);
914
915	return (0);
916
917bad:
918	if (sc->codec)
919		ac97_destroy(sc->codec);
920	if (sc->lock)
921		snd_mtxfree(sc->lock);
922	free(sc, M_DEVBUF);
923	return (ENXIO);
924}
925
926static int
927emu_pcm_detach(device_t dev)
928{
929	int r;
930	struct emu_pcm_info *sc;
931
932	sc = pcm_getdevinfo(dev);
933
934	r = pcm_unregister(dev);
935
936	if (r) 	return (r);
937
938	emu_pcm_uninit(sc);
939
940	if (sc->lock)
941		snd_mtxfree(sc->lock);
942	free(sc, M_DEVBUF);
943
944	return (0);
945}
946
947static device_method_t emu_pcm_methods[] = {
948	DEVMETHOD(device_probe, emu_pcm_probe),
949	DEVMETHOD(device_attach, emu_pcm_attach),
950	DEVMETHOD(device_detach, emu_pcm_detach),
951
952	{0, 0}
953};
954
955static driver_t emu_pcm_driver = {
956	"pcm",
957	emu_pcm_methods,
958	PCM_SOFTC_SIZE,
959	NULL,
960	0,
961	NULL
962};
963DRIVER_MODULE(snd_emu10kx_pcm, emu10kx, emu_pcm_driver, pcm_devclass, 0, 0);
964MODULE_DEPEND(snd_emu10kx_pcm, snd_emu10kx, SND_EMU10KX_MINVER, SND_EMU10KX_PREFVER, SND_EMU10KX_MAXVER);
965MODULE_DEPEND(snd_emu10kx_pcm, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
966MODULE_VERSION(snd_emu10kx_pcm, SND_EMU10KX_PREFVER);
967