es137x.c revision 170521
1139749Simp/*-
253413Sroger * Support the ENSONIQ AudioPCI board and Creative Labs SoundBlaster PCI
353413Sroger * boards based on the ES1370, ES1371 and ES1373 chips.
450724Scg *
553413Sroger * Copyright (c) 1999 Russell Cattelan <cattelan@thebarn.com>
6119853Scg * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
750724Scg * Copyright (c) 1998 by Joachim Kuebart. All rights reserved.
850724Scg *
950724Scg * Redistribution and use in source and binary forms, with or without
1050724Scg * modification, are permitted provided that the following conditions
1150724Scg * are met:
1250724Scg *
1350724Scg * 1. Redistributions of source code must retain the above copyright
1450724Scg *    notice, this list of conditions and the following disclaimer.
1550724Scg *
1650724Scg * 2. Redistributions in binary form must reproduce the above copyright
1750724Scg *    notice, this list of conditions and the following disclaimer in
1850724Scg *    the documentation and/or other materials provided with the
1950724Scg *    distribution.
2050724Scg *
2150724Scg * 3. All advertising materials mentioning features or use of this
2250724Scg *    software must display the following acknowledgement:
2350724Scg *	This product includes software developed by Joachim Kuebart.
2450724Scg *
2550724Scg * 4. The name of the author may not be used to endorse or promote
2650724Scg *    products derived from this software without specific prior
2750724Scg *    written permission.
2850724Scg *
2950724Scg * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
3050724Scg * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
3150724Scg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3250724Scg * DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
3350724Scg * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3450724Scg * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
3550724Scg * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3650724Scg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3750724Scg * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3850724Scg * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
3950724Scg * OF THE POSSIBILITY OF SUCH DAMAGE.
4050724Scg */
4150724Scg
4253413Sroger/*
4353413Sroger * Part of this code was heavily inspired by the linux driver from
4453413Sroger * Thomas Sailer (sailer@ife.ee.ethz.ch)
4554831Scg * Just about everything has been touched and reworked in some way but
4654831Scg * the all the underlying sequences/timing/register values are from
4753413Sroger * Thomas' code.
4853413Sroger *
4953413Sroger*/
5053413Sroger
5153465Scg#include <dev/sound/pcm/sound.h>
5253465Scg#include <dev/sound/pcm/ac97.h>
5353465Scg#include <dev/sound/pci/es137x.h>
5450724Scg
55119287Simp#include <dev/pci/pcireg.h>
56119287Simp#include <dev/pci/pcivar.h>
5750724Scg
5853413Sroger#include <sys/sysctl.h>
5953413Sroger
6070134Scg#include "mixer_if.h"
6170134Scg
6282180ScgSND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/es137x.c 170521 2007-06-11 00:49:46Z ariff $");
6382180Scg
6450724Scg#define MEM_MAP_REG 0x14
6550724Scg
6650724Scg/* PCI IDs of supported chips */
6750724Scg#define ES1370_PCI_ID 0x50001274
6853413Sroger#define ES1371_PCI_ID 0x13711274
6956154Speter#define ES1371_PCI_ID2 0x13713274
7076086Scg#define CT5880_PCI_ID 0x58801274
71119548Sorion#define CT4730_PCI_ID 0x89381102
7250724Scg
7378033Scg#define ES1371REV_ES1371_A  0x02
7476086Scg#define ES1371REV_ES1371_B  0x09
7576086Scg
7676086Scg#define ES1371REV_ES1373_8  0x08
7776086Scg#define ES1371REV_ES1373_A  0x04
7876086Scg#define ES1371REV_ES1373_B  0x06
7976086Scg
8076086Scg#define ES1371REV_CT5880_A  0x07
8176086Scg
8276086Scg#define CT5880REV_CT5880_C  0x02
8376086Scg#define CT5880REV_CT5880_D  0x03
8495678Scg#define CT5880REV_CT5880_E  0x04
8576086Scg
86119548Sorion#define CT4730REV_CT4730_A  0x00
87119548Sorion
8884658Scg#define ES_DEFAULT_BUFSZ 4096
8959019Scg
90152419Sariff/* 2 DAC for playback, 1 ADC for record */
91152419Sariff#define ES_DAC1		0
92152419Sariff#define ES_DAC2		1
93152419Sariff#define ES_ADC		2
94152419Sariff#define ES_NCHANS	3
95152419Sariff
96167648Sariff#define ES_DMA_SEGS_MIN	2
97167648Sariff#define ES_DMA_SEGS_MAX	256
98167648Sariff#define ES_BLK_MIN	64
99167648Sariff#define ES_BLK_ALIGN	(~(ES_BLK_MIN - 1))
100167648Sariff
101152419Sariff#define ES1370_DAC1_MINSPEED	5512
102152419Sariff#define ES1370_DAC1_MAXSPEED	44100
103152419Sariff
10450724Scg/* device private data */
10550724Scgstruct es_info;
10650724Scg
10755209Scgstruct es_chinfo {
10850724Scg	struct es_info *parent;
10974763Scg	struct pcm_channel *channel;
11074763Scg	struct snd_dbuf *buffer;
111152419Sariff	struct pcmchan_caps caps;
112152419Sariff	int dir, num, index;
113164614Sariff	uint32_t fmt, blksz, blkcnt, bufsz;
114164614Sariff	uint32_t ptr, prevptr;
115164614Sariff	int active;
11655209Scg};
11750724Scg
118152419Sariff/*
119152419Sariff *     32bit Ensoniq Configuration (es->escfg).
120152419Sariff *     ----------------------------------------
121152419Sariff *
122152419Sariff *     +-------+--------+------+------+---------+--------+---------+---------+
123152419Sariff * len |  16   |    1   |  1   |  1   |    2    |   2    |    1    |    8    |
124152419Sariff *     +-------+--------+------+------+---------+--------+---------+---------+
125152419Sariff *     | fixed | single |      |      |         |        |   is    | general |
126152419Sariff *     | rate  |   pcm  | DACx | DACy | numplay | numrec | es1370? | purpose |
127152419Sariff *     |       |  mixer |      |      |         |        |         |         |
128152419Sariff *     +-------+--------+------+------+---------+--------+---------+---------+
129152419Sariff */
130152419Sariff#define ES_FIXED_RATE(cfgv)	\
131152419Sariff		(((cfgv) & 0xffff0000) >> 16)
132152419Sariff#define ES_SET_FIXED_RATE(cfgv, nv)	\
133152419Sariff		(((cfgv) & ~0xffff0000) | (((nv) & 0xffff) << 16))
134152419Sariff#define ES_SINGLE_PCM_MIX(cfgv)	\
135152419Sariff		(((cfgv) & 0x8000) >> 15)
136152419Sariff#define ES_SET_SINGLE_PCM_MIX(cfgv, nv)	\
137152419Sariff		(((cfgv) & ~0x8000) | (((nv) ? 1 : 0) << 15))
138152419Sariff#define ES_DAC_FIRST(cfgv)	\
139152419Sariff		(((cfgv) & 0x4000) >> 14)
140152419Sariff#define ES_SET_DAC_FIRST(cfgv, nv)	\
141152419Sariff		(((cfgv) & ~0x4000) | (((nv) & 0x1) << 14))
142152419Sariff#define ES_DAC_SECOND(cfgv)	\
143152419Sariff		(((cfgv) & 0x2000) >> 13)
144152419Sariff#define ES_SET_DAC_SECOND(cfgv, nv)	\
145152419Sariff		(((cfgv) & ~0x2000) | (((nv) & 0x1) << 13))
146152419Sariff#define ES_NUMPLAY(cfgv)	\
147152419Sariff		(((cfgv) & 0x1800) >> 11)
148152419Sariff#define ES_SET_NUMPLAY(cfgv, nv)	\
149152419Sariff		(((cfgv) & ~0x1800) | (((nv) & 0x3) << 11))
150152419Sariff#define ES_NUMREC(cfgv)	\
151152419Sariff		(((cfgv) & 0x600) >> 9)
152152419Sariff#define ES_SET_NUMREC(cfgv, nv)	\
153152419Sariff		(((cfgv) & ~0x600) | (((nv) & 0x3) << 9))
154152419Sariff#define ES_IS_ES1370(cfgv)	\
155152419Sariff		(((cfgv) & 0x100) >> 8)
156152419Sariff#define ES_SET_IS_ES1370(cfgv, nv)	\
157152419Sariff		(((cfgv) & ~0x100) | (((nv) ? 1 : 0) << 8))
158152419Sariff#define ES_GP(cfgv)	\
159152419Sariff		((cfgv) & 0xff)
160152419Sariff#define ES_SET_GP(cfgv, nv)	\
161152419Sariff		(((cfgv) & ~0xff) | ((nv) & 0xff))
162152419Sariff
163152419Sariff#define ES_DAC1_ENABLED(cfgv)	\
164152419Sariff		(ES_NUMPLAY(cfgv) > 1 || \
165152419Sariff		(ES_NUMPLAY(cfgv) == 1 && ES_DAC_FIRST(cfgv) == ES_DAC1))
166152419Sariff#define ES_DAC2_ENABLED(cfgv)	\
167152419Sariff		(ES_NUMPLAY(cfgv) > 1 || \
168152419Sariff		(ES_NUMPLAY(cfgv) == 1 && ES_DAC_FIRST(cfgv) == ES_DAC2))
169152419Sariff
170152419Sariff/*
171152419Sariff * DAC 1/2 configuration through kernel hint - hint.pcm.<unit>.dac="val"
172152419Sariff *
173152419Sariff * 0 = Enable both DACs - Default
174152419Sariff * 1 = Enable single DAC (DAC1)
175152419Sariff * 2 = Enable single DAC (DAC2)
176152419Sariff * 3 = Enable both DACs, swap position (DAC2 comes first instead of DAC1)
177152419Sariff */
178152419Sariff#define ES_DEFAULT_DAC_CFG	0
179152419Sariff
18055209Scgstruct es_info {
18150724Scg	bus_space_tag_t st;
18250724Scg	bus_space_handle_t sh;
18350724Scg	bus_dma_tag_t	parent_dmat;
18450724Scg
18565644Scg	struct resource *reg, *irq;
18665644Scg	int regtype, regid, irqid;
18765644Scg	void *ih;
18865644Scg
18959019Scg	device_t dev;
19054831Scg	int num;
191164614Sariff	unsigned int bufsz, blkcnt;
19284658Scg
19350724Scg	/* Contents of board's registers */
194150832Snetchild	uint32_t	ctrl;
195150832Snetchild	uint32_t	sctrl;
196152419Sariff	uint32_t	escfg;
197152419Sariff	struct es_chinfo ch[ES_NCHANS];
198148591Snetchild	struct mtx	*lock;
199164614Sariff	struct callout	poll_timer;
200164614Sariff	int poll_ticks, polling;
20155209Scg};
20250724Scg
203150832Snetchild#define ES_LOCK(sc)		snd_mtxlock((sc)->lock)
204150832Snetchild#define ES_UNLOCK(sc)		snd_mtxunlock((sc)->lock)
205150832Snetchild#define ES_LOCK_ASSERT(sc)	snd_mtxassert((sc)->lock)
20654831Scg
20753413Sroger/* prototypes */
20854831Scgstatic void     es_intr(void *);
209150832Snetchildstatic uint32_t	es1371_wait_src_ready(struct es_info *);
210164614Sariffstatic void	es1371_src_write(struct es_info *,
211164614Sariff					unsigned short, unsigned short);
212164614Sariffstatic unsigned int	es1371_adc_rate(struct es_info *, unsigned int, int);
213164614Sariffstatic unsigned int	es1371_dac_rate(struct es_info *, unsigned int, int);
214150832Snetchildstatic int	es1371_init(struct es_info *);
21554831Scgstatic int      es1370_init(struct es_info *);
216164614Sariffstatic int      es1370_wrcodec(struct es_info *, unsigned char, unsigned char);
21750724Scg
218164614Sariffstatic uint32_t es_fmt[] = {
21964881Scg	AFMT_U8,
22064881Scg	AFMT_STEREO | AFMT_U8,
22164881Scg	AFMT_S16_LE,
22264881Scg	AFMT_STEREO | AFMT_S16_LE,
22364881Scg	0
22450724Scg};
225150832Snetchildstatic struct pcmchan_caps es_caps = {4000, 48000, es_fmt, 0};
22650724Scg
22750724Scgstatic const struct {
22850724Scg	unsigned        volidx:4;
22950724Scg	unsigned        left:4;
23050724Scg	unsigned        right:4;
23150724Scg	unsigned        stereo:1;
23250724Scg	unsigned        recmask:13;
23350724Scg	unsigned        avail:1;
23450724Scg}       mixtable[SOUND_MIXER_NRDEVICES] = {
235152419Sariff	[SOUND_MIXER_VOLUME]	= { 0, 0x0, 0x1, 1, 0x1f7f, 1 },
23650724Scg	[SOUND_MIXER_PCM] 	= { 1, 0x2, 0x3, 1, 0x0400, 1 },
23750724Scg	[SOUND_MIXER_SYNTH]	= { 2, 0x4, 0x5, 1, 0x0060, 1 },
23850724Scg	[SOUND_MIXER_CD]	= { 3, 0x6, 0x7, 1, 0x0006, 1 },
23950724Scg	[SOUND_MIXER_LINE]	= { 4, 0x8, 0x9, 1, 0x0018, 1 },
24050724Scg	[SOUND_MIXER_LINE1]	= { 5, 0xa, 0xb, 1, 0x1800, 1 },
24150724Scg	[SOUND_MIXER_LINE2]	= { 6, 0xc, 0x0, 0, 0x0100, 1 },
24250724Scg	[SOUND_MIXER_LINE3]	= { 7, 0xd, 0x0, 0, 0x0200, 1 },
24350724Scg	[SOUND_MIXER_MIC]	= { 8, 0xe, 0x0, 0, 0x0001, 1 },
24454831Scg	[SOUND_MIXER_OGAIN]	= { 9, 0xf, 0x0, 0, 0x0000, 1 }
24554831Scg};
24650724Scg
247164614Sariffstatic __inline uint32_t
248148591Snetchildes_rd(struct es_info *es, int regno, int size)
249148591Snetchild{
250148591Snetchild	switch (size) {
251148591Snetchild	case 1:
252164614Sariff		return (bus_space_read_1(es->st, es->sh, regno));
253148591Snetchild	case 2:
254164614Sariff		return (bus_space_read_2(es->st, es->sh, regno));
255148591Snetchild	case 4:
256164614Sariff		return (bus_space_read_4(es->st, es->sh, regno));
257148591Snetchild	default:
258164614Sariff		return (0xFFFFFFFF);
259148591Snetchild	}
260148591Snetchild}
261148591Snetchild
262150832Snetchildstatic __inline void
263164614Sariffes_wr(struct es_info *es, int regno, uint32_t data, int size)
264148591Snetchild{
265148591Snetchild
266148591Snetchild	switch (size) {
267148591Snetchild	case 1:
268148591Snetchild		bus_space_write_1(es->st, es->sh, regno, data);
269148591Snetchild		break;
270148591Snetchild	case 2:
271148591Snetchild		bus_space_write_2(es->st, es->sh, regno, data);
272148591Snetchild		break;
273148591Snetchild	case 4:
274148591Snetchild		bus_space_write_4(es->st, es->sh, regno, data);
275148591Snetchild		break;
276148591Snetchild	}
277148591Snetchild}
278148591Snetchild
27970134Scg/* -------------------------------------------------------------------- */
28070134Scg/* The es1370 mixer interface */
28170134Scg
28250724Scgstatic int
28374763Scges1370_mixinit(struct snd_mixer *m)
28450724Scg{
285152419Sariff	struct es_info *es;
28650724Scg	int i;
287164614Sariff	uint32_t v;
28850724Scg
289152419Sariff	es = mix_getdevinfo(m);
29050724Scg	v = 0;
291164614Sariff	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
292164614Sariff		if (mixtable[i].avail)
293164614Sariff			v |= (1 << i);
294164614Sariff	}
295152419Sariff	/*
296152419Sariff	 * Each DAC1/2 for ES1370 can be controlled independently
297152419Sariff	 *   DAC1 = controlled by synth
298152419Sariff	 *   DAC2 = controlled by pcm
299152419Sariff	 * This is indeed can confuse user if DAC1 become primary playback
300152419Sariff	 * channel. Try to be smart and combine both if necessary.
301152419Sariff	 */
302152419Sariff	if (ES_SINGLE_PCM_MIX(es->escfg))
303152419Sariff		v &= ~(1 << SOUND_MIXER_SYNTH);
30450724Scg	mix_setdevs(m, v);
30550724Scg	v = 0;
306164614Sariff	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
307164614Sariff		if (mixtable[i].recmask)
308164614Sariff			v |= (1 << i);
309164614Sariff	}
310152419Sariff	if (ES_SINGLE_PCM_MIX(es->escfg)) /* ditto */
311152419Sariff		v &= ~(1 << SOUND_MIXER_SYNTH);
31250724Scg	mix_setrecdevs(m, v);
313164614Sariff	return (0);
31450724Scg}
31550724Scg
31650724Scgstatic int
31774763Scges1370_mixset(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
31850724Scg{
319150832Snetchild	struct es_info *es;
320152419Sariff	int l, r, rl, rr, set_dac1;
32150724Scg
322164614Sariff	if (!mixtable[dev].avail)
323164614Sariff		return (-1);
32450724Scg	l = left;
325164614Sariff	r = (mixtable[dev].stereo) ? right : l;
326164614Sariff	if (mixtable[dev].left == 0xf)
327164614Sariff		rl = (l < 2) ? 0x80 : 7 - (l - 2) / 14;
328164614Sariff	else
329164614Sariff		rl = (l < 10) ? 0x80 : 15 - (l - 10) / 6;
330150832Snetchild	es = mix_getdevinfo(m);
331150832Snetchild	ES_LOCK(es);
332152419Sariff	if (dev == SOUND_MIXER_PCM && (ES_SINGLE_PCM_MIX(es->escfg)) &&
333164614Sariff	    ES_DAC1_ENABLED(es->escfg))
334152419Sariff		set_dac1 = 1;
335164614Sariff	else
336152419Sariff		set_dac1 = 0;
33750724Scg	if (mixtable[dev].stereo) {
338164614Sariff		rr = (r < 10) ? 0x80 : 15 - (r - 10) / 6;
339150832Snetchild		es1370_wrcodec(es, mixtable[dev].right, rr);
340152419Sariff		if (set_dac1 && mixtable[SOUND_MIXER_SYNTH].stereo)
341164614Sariff			es1370_wrcodec(es,
342164614Sariff			    mixtable[SOUND_MIXER_SYNTH].right, rr);
34350724Scg	}
344150832Snetchild	es1370_wrcodec(es, mixtable[dev].left, rl);
345152419Sariff	if (set_dac1)
346152419Sariff		es1370_wrcodec(es, mixtable[SOUND_MIXER_SYNTH].left, rl);
347150832Snetchild	ES_UNLOCK(es);
348150832Snetchild
349164614Sariff	return (l | (r << 8));
35050724Scg}
35150724Scg
35250724Scgstatic int
353164614Sariffes1370_mixsetrecsrc(struct snd_mixer *m, uint32_t src)
35450724Scg{
355150832Snetchild	struct es_info *es;
35650724Scg	int i, j = 0;
35750724Scg
358150832Snetchild	es = mix_getdevinfo(m);
35950724Scg	if (src == 0) src = 1 << SOUND_MIXER_MIC;
36050724Scg	src &= mix_getrecdevs(m);
36150724Scg	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
36250724Scg		if ((src & (1 << i)) != 0) j |= mixtable[i].recmask;
36350724Scg
364150832Snetchild	ES_LOCK(es);
365152419Sariff	if ((src & (1 << SOUND_MIXER_PCM)) && ES_SINGLE_PCM_MIX(es->escfg) &&
366164614Sariff	    ES_DAC1_ENABLED(es->escfg))
367152419Sariff		j |= mixtable[SOUND_MIXER_SYNTH].recmask;
368150832Snetchild	es1370_wrcodec(es, CODEC_LIMIX1, j & 0x55);
369150832Snetchild	es1370_wrcodec(es, CODEC_RIMIX1, j & 0xaa);
370150832Snetchild	es1370_wrcodec(es, CODEC_LIMIX2, (j >> 8) & 0x17);
371150832Snetchild	es1370_wrcodec(es, CODEC_RIMIX2, (j >> 8) & 0x0f);
372150832Snetchild	es1370_wrcodec(es, CODEC_OMIX1, 0x7f);
373150832Snetchild	es1370_wrcodec(es, CODEC_OMIX2, 0x3f);
374150832Snetchild	ES_UNLOCK(es);
375150832Snetchild
376164614Sariff	return (src);
37750724Scg}
37850724Scg
37970134Scgstatic kobj_method_t es1370_mixer_methods[] = {
380164614Sariff	KOBJMETHOD(mixer_init,		es1370_mixinit),
381164614Sariff	KOBJMETHOD(mixer_set,		es1370_mixset),
382164614Sariff	KOBJMETHOD(mixer_setrecsrc,	es1370_mixsetrecsrc),
38370134Scg	{ 0, 0 }
38470134Scg};
38570134ScgMIXER_DECLARE(es1370_mixer);
38670134Scg
38770134Scg/* -------------------------------------------------------------------- */
38870134Scg
38950724Scgstatic int
390164614Sariffes1370_wrcodec(struct es_info *es, unsigned char i, unsigned char data)
39150724Scg{
392164614Sariff	unsigned int t;
39350724Scg
394150832Snetchild	ES_LOCK_ASSERT(es);
395150832Snetchild
396148591Snetchild	for (t = 0; t < 0x1000; t++) {
397148591Snetchild		if ((es_rd(es, ES1370_REG_STATUS, 4) &
398164614Sariff		    STAT_CSTAT) == 0) {
399148591Snetchild			es_wr(es, ES1370_REG_CODEC,
400164614Sariff			    ((unsigned short)i << CODEC_INDEX_SHIFT) | data, 2);
401164614Sariff			return (0);
40250724Scg		}
403148591Snetchild		DELAY(1);
404148591Snetchild	}
405150832Snetchild	device_printf(es->dev, "%s: timed out\n", __func__);
406164614Sariff	return (-1);
40750724Scg}
40850724Scg
40950724Scg/* -------------------------------------------------------------------- */
41050724Scg
41150724Scg/* channel interface */
41250724Scgstatic void *
413164614Sariffeschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
414164614Sariff				struct pcm_channel *c, int dir)
41550724Scg{
41650724Scg	struct es_info *es = devinfo;
417152419Sariff	struct es_chinfo *ch;
418152419Sariff	uint32_t index;
41950724Scg
420152419Sariff	ES_LOCK(es);
421152419Sariff
422152419Sariff	if (dir == PCMDIR_PLAY) {
423152419Sariff		index = ES_GP(es->escfg);
424152419Sariff		es->escfg = ES_SET_GP(es->escfg, index + 1);
425164614Sariff		if (index == 0)
426152419Sariff			index = ES_DAC_FIRST(es->escfg);
427164614Sariff		else if (index == 1)
428152419Sariff			index = ES_DAC_SECOND(es->escfg);
429164614Sariff		else {
430164614Sariff			device_printf(es->dev,
431164614Sariff			    "Invalid ES_GP index: %d\n", index);
432152419Sariff			ES_UNLOCK(es);
433164614Sariff			return (NULL);
434152419Sariff		}
435152419Sariff		if (!(index == ES_DAC1 || index == ES_DAC2)) {
436164614Sariff			device_printf(es->dev, "Unknown DAC: %d\n", index + 1);
437152419Sariff			ES_UNLOCK(es);
438164614Sariff			return (NULL);
439152419Sariff		}
440152419Sariff		if (es->ch[index].channel != NULL) {
441152419Sariff			device_printf(es->dev, "DAC%d already initialized!\n",
442164614Sariff			    index + 1);
443152419Sariff			ES_UNLOCK(es);
444164614Sariff			return (NULL);
445152419Sariff		}
446152419Sariff	} else
447152419Sariff		index = ES_ADC;
448152419Sariff
449152419Sariff	ch = &es->ch[index];
450152419Sariff	ch->index = index;
451152419Sariff	ch->num = es->num++;
452152419Sariff	ch->caps = es_caps;
453152419Sariff	if (ES_IS_ES1370(es->escfg)) {
454152419Sariff		if (ch->index == ES_DAC1) {
455152419Sariff			ch->caps.maxspeed = ES1370_DAC1_MAXSPEED;
456152419Sariff			ch->caps.minspeed = ES1370_DAC1_MINSPEED;
457152419Sariff		} else {
458152419Sariff			uint32_t fixed_rate = ES_FIXED_RATE(es->escfg);
459152419Sariff			if (!(fixed_rate < es_caps.minspeed ||
460164614Sariff			    fixed_rate > es_caps.maxspeed)) {
461152419Sariff				ch->caps.maxspeed = fixed_rate;
462152419Sariff				ch->caps.minspeed = fixed_rate;
463152419Sariff			}
464152419Sariff		}
465152419Sariff	}
46650724Scg	ch->parent = es;
46750724Scg	ch->channel = c;
46850724Scg	ch->buffer = b;
46984658Scg	ch->bufsz = es->bufsz;
470164614Sariff	ch->blkcnt = es->blkcnt;
471164614Sariff	ch->blksz = ch->bufsz / ch->blkcnt;
472150832Snetchild	ch->dir = dir;
473152419Sariff	ES_UNLOCK(es);
474168847Sariff	if (sndbuf_alloc(ch->buffer, es->parent_dmat, 0, ch->bufsz) != 0)
475164614Sariff		return (NULL);
476150832Snetchild	ES_LOCK(es);
47750724Scg	if (dir == PCMDIR_PLAY) {
478152419Sariff		if (ch->index == ES_DAC1) {
479164614Sariff			es_wr(es, ES1370_REG_MEMPAGE,
480164614Sariff			    ES1370_REG_DAC1_FRAMEADR >> 8, 1);
481164614Sariff			es_wr(es, ES1370_REG_DAC1_FRAMEADR & 0xff,
482164614Sariff			    sndbuf_getbufaddr(ch->buffer), 4);
483164614Sariff			es_wr(es, ES1370_REG_DAC1_FRAMECNT & 0xff,
484164614Sariff			    (ch->bufsz >> 2) - 1, 4);
485152419Sariff		} else {
486164614Sariff			es_wr(es, ES1370_REG_MEMPAGE,
487164614Sariff			    ES1370_REG_DAC2_FRAMEADR >> 8, 1);
488164614Sariff			es_wr(es, ES1370_REG_DAC2_FRAMEADR & 0xff,
489164614Sariff			    sndbuf_getbufaddr(ch->buffer), 4);
490164614Sariff			es_wr(es, ES1370_REG_DAC2_FRAMECNT & 0xff,
491164614Sariff			    (ch->bufsz >> 2) - 1, 4);
492152419Sariff		}
49350724Scg	} else {
494148591Snetchild		es_wr(es, ES1370_REG_MEMPAGE, ES1370_REG_ADC_FRAMEADR >> 8, 1);
495164614Sariff		es_wr(es, ES1370_REG_ADC_FRAMEADR & 0xff,
496164614Sariff		    sndbuf_getbufaddr(ch->buffer), 4);
497164614Sariff		es_wr(es, ES1370_REG_ADC_FRAMECNT & 0xff,
498164614Sariff		    (ch->bufsz >> 2) - 1, 4);
49950724Scg	}
500150832Snetchild	ES_UNLOCK(es);
501164614Sariff	return (ch);
50250724Scg}
50350724Scg
50450724Scgstatic int
505164614Sariffeschan_setformat(kobj_t obj, void *data, uint32_t format)
50650724Scg{
50750724Scg	struct es_chinfo *ch = data;
50850724Scg	struct es_info *es = ch->parent;
50950724Scg
510150832Snetchild	ES_LOCK(es);
51150724Scg	if (ch->dir == PCMDIR_PLAY) {
512152419Sariff		if (ch->index == ES_DAC1) {
513152419Sariff			es->sctrl &= ~SCTRL_P1FMT;
514164614Sariff			if (format & AFMT_S16_LE)
515164614Sariff				es->sctrl |= SCTRL_P1SEB;
516164614Sariff			if (format & AFMT_STEREO)
517164614Sariff				es->sctrl |= SCTRL_P1SMB;
518152419Sariff		} else {
519152419Sariff			es->sctrl &= ~SCTRL_P2FMT;
520164614Sariff			if (format & AFMT_S16_LE)
521164614Sariff				es->sctrl |= SCTRL_P2SEB;
522164614Sariff			if (format & AFMT_STEREO)
523164614Sariff				es->sctrl |= SCTRL_P2SMB;
524152419Sariff		}
52550724Scg	} else {
52650724Scg		es->sctrl &= ~SCTRL_R1FMT;
527164614Sariff		if (format & AFMT_S16_LE)
528164614Sariff			es->sctrl |= SCTRL_R1SEB;
529164614Sariff		if (format & AFMT_STEREO)
530164614Sariff			es->sctrl |= SCTRL_R1SMB;
53150724Scg	}
532148591Snetchild	es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4);
533150832Snetchild	ES_UNLOCK(es);
53450724Scg	ch->fmt = format;
535164614Sariff	return (0);
53650724Scg}
53750724Scg
53850724Scgstatic int
539164614Sariffeschan1370_setspeed(kobj_t obj, void *data, uint32_t speed)
54050724Scg{
54150724Scg	struct es_chinfo *ch = data;
54250724Scg	struct es_info *es = ch->parent;
54350724Scg
544164614Sariff	ES_LOCK(es);
545152419Sariff	/* Fixed rate , do nothing. */
546152419Sariff	if (ch->caps.minspeed == ch->caps.maxspeed)
547164614Sariff		return (ch->caps.maxspeed);
548152419Sariff	if (speed < ch->caps.minspeed)
549152419Sariff		speed = ch->caps.minspeed;
550152419Sariff	if (speed > ch->caps.maxspeed)
551152419Sariff		speed = ch->caps.maxspeed;
552152419Sariff	if (ch->index == ES_DAC1) {
553152419Sariff		/*
554152419Sariff		 * DAC1 does not support continuous rate settings.
555152419Sariff		 * Pick the nearest and use it since FEEDER_RATE will
556152419Sariff		 * do the the proper conversion for us.
557152419Sariff		 */
558152419Sariff		es->ctrl &= ~CTRL_WTSRSEL;
559152419Sariff		if (speed < 8268) {
560152419Sariff			speed = 5512;
561152419Sariff			es->ctrl |= 0 << CTRL_SH_WTSRSEL;
562152419Sariff		} else if (speed < 16537) {
563152419Sariff			speed = 11025;
564152419Sariff			es->ctrl |= 1 << CTRL_SH_WTSRSEL;
565152419Sariff		} else if (speed < 33075) {
566152419Sariff			speed = 22050;
567152419Sariff			es->ctrl |= 2 << CTRL_SH_WTSRSEL;
568152419Sariff		} else {
569152419Sariff			speed = 44100;
570152419Sariff			es->ctrl |= 3 << CTRL_SH_WTSRSEL;
571152419Sariff		}
572152419Sariff	} else {
573152419Sariff		es->ctrl &= ~CTRL_PCLKDIV;
574152419Sariff		es->ctrl |= DAC2_SRTODIV(speed) << CTRL_SH_PCLKDIV;
575150832Snetchild	}
576148591Snetchild	es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4);
577150832Snetchild	ES_UNLOCK(es);
578164614Sariff	return (speed);
57950724Scg}
58050724Scg
58170134Scgstatic int
582164614Sariffeschan1371_setspeed(kobj_t obj, void *data, uint32_t speed)
58354831Scg{
58454831Scg  	struct es_chinfo *ch = data;
58554831Scg  	struct es_info *es = ch->parent;
586152419Sariff	uint32_t i;
587152419Sariff	int delta;
58854831Scg
589150832Snetchild	ES_LOCK(es);
590148591Snetchild	if (ch->dir == PCMDIR_PLAY)
591152419Sariff  		i = es1371_dac_rate(es, speed, ch->index); /* play */
592148591Snetchild	else
593152419Sariff  		i = es1371_adc_rate(es, speed, ch->index); /* record */
594150832Snetchild	ES_UNLOCK(es);
595164614Sariff	delta = (speed > i) ? (speed - i) : (i - speed);
596148591Snetchild	if (delta < 2)
597164614Sariff		return (speed);
598164614Sariff	return (i);
59954831Scg}
60054831Scg
60150724Scgstatic int
602167648Sariffeschan_setfragments(kobj_t obj, void *data, uint32_t blksz, uint32_t blkcnt)
60350724Scg{
60470321Scg  	struct es_chinfo *ch = data;
605164614Sariff  	struct es_info *es = ch->parent;
60670321Scg
607167648Sariff	blksz &= ES_BLK_ALIGN;
608164614Sariff
609167648Sariff	if (blksz > (sndbuf_getmaxsize(ch->buffer) / ES_DMA_SEGS_MIN))
610167648Sariff		blksz = sndbuf_getmaxsize(ch->buffer) / ES_DMA_SEGS_MIN;
611167648Sariff	if (blksz < ES_BLK_MIN)
612167648Sariff		blksz = ES_BLK_MIN;
613167648Sariff	if (blkcnt > ES_DMA_SEGS_MAX)
614167648Sariff		blkcnt = ES_DMA_SEGS_MAX;
615167648Sariff	if (blkcnt < ES_DMA_SEGS_MIN)
616167648Sariff		blkcnt = ES_DMA_SEGS_MIN;
617164614Sariff
618167648Sariff	while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) {
619167648Sariff		if ((blkcnt >> 1) >= ES_DMA_SEGS_MIN)
620167648Sariff			blkcnt >>= 1;
621167648Sariff		else if ((blksz >> 1) >= ES_BLK_MIN)
622167648Sariff			blksz >>= 1;
623167648Sariff		else
624167648Sariff			break;
625167648Sariff	}
626167648Sariff
627164614Sariff	if ((sndbuf_getblksz(ch->buffer) != blksz ||
628167648Sariff	    sndbuf_getblkcnt(ch->buffer) != blkcnt) &&
629167648Sariff	    sndbuf_resize(ch->buffer, blkcnt, blksz) != 0)
630164614Sariff		device_printf(es->dev, "%s: failed blksz=%u blkcnt=%u\n",
631167648Sariff		    __func__, blksz, blkcnt);
632164614Sariff
633164614Sariff	ch->bufsz = sndbuf_getsize(ch->buffer);
634164614Sariff	ch->blksz = sndbuf_getblksz(ch->buffer);
635167648Sariff	ch->blkcnt = sndbuf_getblkcnt(ch->buffer);
636164614Sariff
637167648Sariff	return (1);
638167648Sariff}
639167648Sariff
640167648Sariffstatic int
641167648Sariffeschan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
642167648Sariff{
643167648Sariff  	struct es_chinfo *ch = data;
644167648Sariff  	struct es_info *es = ch->parent;
645167648Sariff
646167648Sariff	eschan_setfragments(obj, data, blksz, es->blkcnt);
647167648Sariff
648164614Sariff	return (ch->blksz);
649164614Sariff}
650164614Sariff
651164614Sariff#define es_chan_active(es)	((es)->ch[ES_DAC1].active + \
652164614Sariff				(es)->ch[ES_DAC2].active + \
653164614Sariff				(es)->ch[ES_ADC].active)
654164614Sariff
655164614Sariffstatic __inline int
656164614Sariffes_poll_channel(struct es_chinfo *ch)
657164614Sariff{
658164614Sariff	struct es_info *es;
659164614Sariff	uint32_t sz, delta;
660164614Sariff	uint32_t reg, ptr;
661164614Sariff
662164614Sariff	if (ch == NULL || ch->channel == NULL || ch->active == 0)
663164614Sariff		return (0);
664164614Sariff
665164614Sariff	es = ch->parent;
666164614Sariff	if (ch->dir == PCMDIR_PLAY) {
667164614Sariff		if (ch->index == ES_DAC1)
668164614Sariff			reg = ES1370_REG_DAC1_FRAMECNT;
669164614Sariff		else
670164614Sariff			reg = ES1370_REG_DAC2_FRAMECNT;
671164614Sariff	} else
672164614Sariff		reg = ES1370_REG_ADC_FRAMECNT;
673164614Sariff	sz = ch->blksz * ch->blkcnt;
674164614Sariff	es_wr(es, ES1370_REG_MEMPAGE, reg >> 8, 4);
675164614Sariff	ptr = es_rd(es, reg & 0x000000ff, 4) >> 16;
676164614Sariff	ptr <<= 2;
677164614Sariff	ch->ptr = ptr;
678164614Sariff	ptr %= sz;
679164614Sariff	ptr &= ~(ch->blksz - 1);
680164614Sariff	delta = (sz + ptr - ch->prevptr) % sz;
681164614Sariff
682164614Sariff	if (delta < ch->blksz)
683164614Sariff		return (0);
684164614Sariff
685164614Sariff	ch->prevptr = ptr;
686164614Sariff
687164614Sariff	return (1);
688164614Sariff}
689164614Sariff
690164614Sariffstatic void
691164614Sariffes_poll_callback(void *arg)
692164614Sariff{
693164614Sariff	struct es_info *es = arg;
694164614Sariff	uint32_t trigger = 0;
695164614Sariff	int i;
696164614Sariff
697164614Sariff	if (es == NULL)
698164614Sariff		return;
699164614Sariff
700164614Sariff	ES_LOCK(es);
701164614Sariff	if (es->polling == 0 || es_chan_active(es) == 0) {
702164614Sariff		ES_UNLOCK(es);
703164614Sariff		return;
704150832Snetchild	}
705164614Sariff
706164614Sariff	for (i = 0; i < ES_NCHANS; i++) {
707164614Sariff		if (es_poll_channel(&es->ch[i]) != 0)
708164614Sariff			trigger |= 1 << i;
709164614Sariff	}
710164614Sariff
711164614Sariff	/* XXX */
712164614Sariff	callout_reset(&es->poll_timer, 1/*es->poll_ticks*/,
713164614Sariff	    es_poll_callback, es);
714164614Sariff
715164614Sariff	ES_UNLOCK(es);
716164614Sariff
717164614Sariff	for (i = 0; i < ES_NCHANS; i++) {
718164614Sariff		if (trigger & (1 << i))
719164614Sariff			chn_intr(es->ch[i].channel);
720164614Sariff	}
72150724Scg}
72250724Scg
72350724Scgstatic int
72470134Scgeschan_trigger(kobj_t obj, void *data, int go)
72550724Scg{
72650724Scg	struct es_chinfo *ch = data;
72750724Scg	struct es_info *es = ch->parent;
728152419Sariff	uint32_t cnt, b = 0;
72950724Scg
730170521Sariff	if (!PCMTRIG_COMMON(go))
731170521Sariff		return 0;
73260958Scg
733164614Sariff	ES_LOCK(es);
73470321Scg	cnt = (ch->blksz / sndbuf_getbps(ch->buffer)) - 1;
735152419Sariff	if (ch->fmt & AFMT_16BIT)
736152419Sariff		b |= 0x02;
737152419Sariff	if (ch->fmt & AFMT_STEREO)
738152419Sariff		b |= 0x01;
73950724Scg	if (ch->dir == PCMDIR_PLAY) {
74050724Scg		if (go == PCMTRIG_START) {
741152419Sariff			if (ch->index == ES_DAC1) {
742152419Sariff				es->ctrl |= CTRL_DAC1_EN;
743164614Sariff				es->sctrl &= ~(SCTRL_P1LOOPSEL |
744164614Sariff				    SCTRL_P1PAUSE | SCTRL_P1SCTRLD);
745164614Sariff				if (es->polling == 0)
746164614Sariff					es->sctrl |= SCTRL_P1INTEN;
747164614Sariff				else
748164614Sariff					es->sctrl &= ~SCTRL_P1INTEN;
749164614Sariff				es->sctrl |= b;
750152419Sariff				es_wr(es, ES1370_REG_DAC1_SCOUNT, cnt, 4);
751152419Sariff				/* start at beginning of buffer */
752164614Sariff				es_wr(es, ES1370_REG_MEMPAGE,
753164614Sariff				    ES1370_REG_DAC1_FRAMECNT >> 8, 4);
754164614Sariff				es_wr(es, ES1370_REG_DAC1_FRAMECNT & 0xff,
755164614Sariff				    (ch->bufsz >> 2) - 1, 4);
756152419Sariff			} else {
757152419Sariff				es->ctrl |= CTRL_DAC2_EN;
758164614Sariff				es->sctrl &= ~(SCTRL_P2ENDINC | SCTRL_P2STINC |
759164614Sariff				    SCTRL_P2LOOPSEL | SCTRL_P2PAUSE |
760164614Sariff				    SCTRL_P2DACSEN);
761164614Sariff				if (es->polling == 0)
762164614Sariff					es->sctrl |= SCTRL_P2INTEN;
763164614Sariff				else
764164614Sariff					es->sctrl &= ~SCTRL_P2INTEN;
765164614Sariff				es->sctrl |= (b << 2) |
766164614Sariff				    ((((b >> 1) & 1) + 1) << SCTRL_SH_P2ENDINC);
767152419Sariff				es_wr(es, ES1370_REG_DAC2_SCOUNT, cnt, 4);
768152419Sariff				/* start at beginning of buffer */
769164614Sariff				es_wr(es, ES1370_REG_MEMPAGE,
770164614Sariff				    ES1370_REG_DAC2_FRAMECNT >> 8, 4);
771164614Sariff				es_wr(es, ES1370_REG_DAC2_FRAMECNT & 0xff,
772164614Sariff				    (ch->bufsz >> 2) - 1, 4);
773152419Sariff			}
774164614Sariff		} else
775164614Sariff			es->ctrl &= ~((ch->index == ES_DAC1) ?
776164614Sariff			    CTRL_DAC1_EN : CTRL_DAC2_EN);
77750724Scg	} else {
77850724Scg		if (go == PCMTRIG_START) {
77950724Scg			es->ctrl |= CTRL_ADC_EN;
78050724Scg			es->sctrl &= ~SCTRL_R1LOOPSEL;
781164614Sariff			if (es->polling == 0)
782164614Sariff				es->sctrl |= SCTRL_R1INTEN;
783164614Sariff			else
784164614Sariff				es->sctrl &= ~SCTRL_R1INTEN;
785164614Sariff			es->sctrl |= b << 4;
786148591Snetchild			es_wr(es, ES1370_REG_ADC_SCOUNT, cnt, 4);
78759323Scg			/* start at beginning of buffer */
788164614Sariff			es_wr(es, ES1370_REG_MEMPAGE,
789164614Sariff			    ES1370_REG_ADC_FRAMECNT >> 8, 4);
790164614Sariff			es_wr(es, ES1370_REG_ADC_FRAMECNT & 0xff,
791164614Sariff			    (ch->bufsz >> 2) - 1, 4);
792164614Sariff		} else
793164614Sariff			es->ctrl &= ~CTRL_ADC_EN;
79450724Scg	}
795148591Snetchild	es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4);
796148591Snetchild	es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4);
797164614Sariff	if (go == PCMTRIG_START) {
798164614Sariff		if (es->polling != 0) {
799164614Sariff			ch->ptr = 0;
800164614Sariff			ch->prevptr = 0;
801164614Sariff			if (es_chan_active(es) == 0) {
802164614Sariff				es->poll_ticks = 1;
803164614Sariff				callout_reset(&es->poll_timer, 1,
804164614Sariff				    es_poll_callback, es);
805164614Sariff			}
806164614Sariff		}
807164614Sariff		ch->active = 1;
808164614Sariff	} else {
809164614Sariff		ch->active = 0;
810164614Sariff		if (es->polling != 0) {
811164614Sariff			if (es_chan_active(es) == 0) {
812164614Sariff				callout_stop(&es->poll_timer);
813164614Sariff				es->poll_ticks = 1;
814164614Sariff			}
815164614Sariff		}
816164614Sariff	}
817150832Snetchild	ES_UNLOCK(es);
818164614Sariff	return (0);
81950724Scg}
82050724Scg
82150724Scgstatic int
82270134Scgeschan_getptr(kobj_t obj, void *data)
82350724Scg{
82450724Scg	struct es_chinfo *ch = data;
82550724Scg	struct es_info *es = ch->parent;
826164614Sariff	uint32_t reg, cnt;
82759323Scg
828150832Snetchild	ES_LOCK(es);
829164614Sariff	if (es->polling != 0)
830164614Sariff		cnt = ch->ptr;
831164614Sariff	else {
832164614Sariff		if (ch->dir == PCMDIR_PLAY) {
833164614Sariff			if (ch->index == ES_DAC1)
834164614Sariff				reg = ES1370_REG_DAC1_FRAMECNT;
835164614Sariff			else
836164614Sariff				reg = ES1370_REG_DAC2_FRAMECNT;
837164614Sariff		} else
838164614Sariff			reg = ES1370_REG_ADC_FRAMECNT;
839164614Sariff		es_wr(es, ES1370_REG_MEMPAGE, reg >> 8, 4);
840164614Sariff		cnt = es_rd(es, reg & 0x000000ff, 4) >> 16;
841164614Sariff		/* cnt is longwords */
842164614Sariff		cnt <<= 2;
843164614Sariff	}
844150832Snetchild	ES_UNLOCK(es);
845164614Sariff
846167648Sariff	cnt &= ES_BLK_ALIGN;
847164614Sariff
848164614Sariff	return (cnt);
84950724Scg}
85050724Scg
85174763Scgstatic struct pcmchan_caps *
85270134Scgeschan_getcaps(kobj_t obj, void *data)
85350724Scg{
85450724Scg	struct es_chinfo *ch = data;
855150832Snetchild
856164614Sariff	return (&ch->caps);
85750724Scg}
85850724Scg
85970134Scgstatic kobj_method_t eschan1370_methods[] = {
860164614Sariff	KOBJMETHOD(channel_init,		eschan_init),
861164614Sariff	KOBJMETHOD(channel_setformat,		eschan_setformat),
862164614Sariff	KOBJMETHOD(channel_setspeed,		eschan1370_setspeed),
863164614Sariff	KOBJMETHOD(channel_setblocksize,	eschan_setblocksize),
864167648Sariff	KOBJMETHOD(channel_setfragments,	eschan_setfragments),
865164614Sariff	KOBJMETHOD(channel_trigger,		eschan_trigger),
866164614Sariff	KOBJMETHOD(channel_getptr,		eschan_getptr),
867164614Sariff	KOBJMETHOD(channel_getcaps,		eschan_getcaps),
86870134Scg	{ 0, 0 }
86970134Scg};
87070134ScgCHANNEL_DECLARE(eschan1370);
87170134Scg
87270134Scgstatic kobj_method_t eschan1371_methods[] = {
873164614Sariff	KOBJMETHOD(channel_init,		eschan_init),
874164614Sariff	KOBJMETHOD(channel_setformat,		eschan_setformat),
875164614Sariff	KOBJMETHOD(channel_setspeed,		eschan1371_setspeed),
876164614Sariff	KOBJMETHOD(channel_setblocksize,	eschan_setblocksize),
877167648Sariff	KOBJMETHOD(channel_setfragments,	eschan_setfragments),
878164614Sariff	KOBJMETHOD(channel_trigger,		eschan_trigger),
879164614Sariff	KOBJMETHOD(channel_getptr,		eschan_getptr),
880164614Sariff	KOBJMETHOD(channel_getcaps,		eschan_getcaps),
88170134Scg	{ 0, 0 }
88270134Scg};
88370134ScgCHANNEL_DECLARE(eschan1371);
88470134Scg
88570134Scg/* -------------------------------------------------------------------- */
88650724Scg/* The interrupt handler */
88750724Scgstatic void
88854831Scges_intr(void *p)
88950724Scg{
89050724Scg	struct es_info *es = p;
891150832Snetchild	uint32_t intsrc, sctrl;
89250724Scg
893150832Snetchild	ES_LOCK(es);
894164614Sariff	if (es->polling != 0) {
895164614Sariff		ES_UNLOCK(es);
896164614Sariff		return;
897164614Sariff	}
898148591Snetchild	intsrc = es_rd(es, ES1370_REG_STATUS, 4);
899148591Snetchild	if ((intsrc & STAT_INTR) == 0) {
900150832Snetchild		ES_UNLOCK(es);
901148591Snetchild		return;
902148591Snetchild	}
90350724Scg
90450724Scg	sctrl = es->sctrl;
905164614Sariff	if (intsrc & STAT_ADC)
906164614Sariff		sctrl &= ~SCTRL_R1INTEN;
907164614Sariff	if (intsrc & STAT_DAC1)
908164614Sariff		sctrl &= ~SCTRL_P1INTEN;
909164614Sariff	if (intsrc & STAT_DAC2)
910164614Sariff		sctrl &= ~SCTRL_P2INTEN;
91150724Scg
912148591Snetchild	es_wr(es, ES1370_REG_SERIAL_CONTROL, sctrl, 4);
913148591Snetchild	es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4);
914150832Snetchild	ES_UNLOCK(es);
91550724Scg
916164614Sariff	if (intsrc & STAT_ADC)
917164614Sariff		chn_intr(es->ch[ES_ADC].channel);
918164614Sariff	if (intsrc & STAT_DAC1)
919164614Sariff		chn_intr(es->ch[ES_DAC1].channel);
920164614Sariff	if (intsrc & STAT_DAC2)
921164614Sariff		chn_intr(es->ch[ES_DAC2].channel);
92250724Scg}
92350724Scg
92454831Scg/* ES1370 specific */
92554831Scgstatic int
92654831Scges1370_init(struct es_info *es)
92754831Scg{
928152419Sariff	uint32_t fixed_rate;
929152419Sariff	int r, single_pcm;
930150832Snetchild
931152419Sariff	/* ES1370 default to fixed rate operation */
932150832Snetchild	if (resource_int_value(device_get_name(es->dev),
933164614Sariff	    device_get_unit(es->dev), "fixed_rate", &r) == 0) {
934152419Sariff		fixed_rate = r;
935152419Sariff		if (fixed_rate) {
936152419Sariff			if (fixed_rate < es_caps.minspeed)
937152419Sariff				fixed_rate = es_caps.minspeed;
938152419Sariff			if (fixed_rate > es_caps.maxspeed)
939152419Sariff				fixed_rate = es_caps.maxspeed;
940150832Snetchild		}
941150832Snetchild	} else
942152419Sariff		fixed_rate = es_caps.maxspeed;
943152419Sariff
944152419Sariff	if (resource_int_value(device_get_name(es->dev),
945164614Sariff	    device_get_unit(es->dev), "single_pcm_mixer", &r) == 0)
946164614Sariff		single_pcm = (r != 0) ? 1 : 0;
947152419Sariff	else
948152419Sariff		single_pcm = 1;
949152419Sariff
950150832Snetchild	ES_LOCK(es);
951152419Sariff	if (ES_NUMPLAY(es->escfg) == 1)
952152419Sariff		single_pcm = 1;
953152419Sariff	/* This is ES1370 */
954152419Sariff	es->escfg = ES_SET_IS_ES1370(es->escfg, 1);
955164614Sariff	if (fixed_rate)
956152419Sariff		es->escfg = ES_SET_FIXED_RATE(es->escfg, fixed_rate);
957164614Sariff	else {
958152419Sariff		es->escfg = ES_SET_FIXED_RATE(es->escfg, 0);
959152419Sariff		fixed_rate = DSP_DEFAULT_SPEED;
960150832Snetchild	}
961164614Sariff	if (single_pcm)
962152419Sariff		es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 1);
963164614Sariff	else
964152419Sariff		es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 0);
965152419Sariff	es->ctrl = CTRL_CDC_EN | CTRL_JYSTK_EN | CTRL_SERR_DIS |
966164614Sariff	    (DAC2_SRTODIV(fixed_rate) << CTRL_SH_PCLKDIV);
967152419Sariff	es->ctrl |= 3 << CTRL_SH_WTSRSEL;
968148591Snetchild	es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4);
96953413Sroger
97054831Scg	es->sctrl = 0;
971148591Snetchild	es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4);
97253413Sroger
973164614Sariff	/* No RST, PD */
974164614Sariff	es1370_wrcodec(es, CODEC_RES_PD, 3);
975164614Sariff	/*
976164614Sariff	 * CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off the LRCLK2 PLL;
977164614Sariff	 * program DAC_SYNC=0!
978164614Sariff	 */
979164614Sariff	es1370_wrcodec(es, CODEC_CSEL, 0);
980164614Sariff	/* Recording source is mixer */
981164614Sariff	es1370_wrcodec(es, CODEC_ADSEL, 0);
982164614Sariff	/* MIC amp is 0db */
983164614Sariff	es1370_wrcodec(es, CODEC_MGAIN, 0);
984150832Snetchild	ES_UNLOCK(es);
98553413Sroger
986164614Sariff	return (0);
98754831Scg}
98853413Sroger
98954831Scg/* ES1371 specific */
99053413Srogerint
991150832Snetchildes1371_init(struct es_info *es)
99253413Sroger{
993154285Sariff	uint32_t cssr, devid, revid, subdev;
99453413Sroger	int idx;
99553413Sroger
996150832Snetchild	ES_LOCK(es);
997152419Sariff	/* This is NOT ES1370 */
998152419Sariff	es->escfg = ES_SET_IS_ES1370(es->escfg, 0);
99954831Scg	es->num = 0;
100053413Sroger	es->sctrl = 0;
1001148591Snetchild	cssr = 0;
1002150832Snetchild	devid = pci_get_devid(es->dev);
1003150832Snetchild	revid = pci_get_revid(es->dev);
1004164614Sariff	subdev = (pci_get_subdevice(es->dev) << 16) |
1005164614Sariff	    pci_get_subvendor(es->dev);
1006154285Sariff	/*
1007154285Sariff	 * Joyport blacklist. Either we're facing with broken hardware
1008154285Sariff	 * or because this hardware need special (unknown) initialization
1009154285Sariff	 * procedures.
1010154285Sariff	 */
1011154285Sariff	switch (subdev) {
1012154285Sariff	case 0x20001274:	/* old Ensoniq */
1013154285Sariff		es->ctrl = 0;
1014154285Sariff		break;
1015154285Sariff	default:
1016154285Sariff		es->ctrl = CTRL_JYSTK_EN;
1017154285Sariff		break;
1018154285Sariff	}
1019148591Snetchild	if (devid == CT4730_PCI_ID) {
1020148591Snetchild		/* XXX amplifier hack? */
1021148591Snetchild		es->ctrl |= (1 << 16);
1022148591Snetchild	}
102353413Sroger	/* initialize the chips */
1024148591Snetchild	es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4);
1025148591Snetchild	es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4);
1026148591Snetchild	es_wr(es, ES1371_REG_LEGACY, 0, 4);
102776086Scg	if ((devid == ES1371_PCI_ID && revid == ES1371REV_ES1373_8) ||
102876086Scg	    (devid == ES1371_PCI_ID && revid == ES1371REV_CT5880_A) ||
102976086Scg	    (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_C) ||
103095678Scg	    (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_D) ||
1031148591Snetchild	    (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_E)) {
1032148591Snetchild		cssr = 1 << 29;
1033148591Snetchild		es_wr(es, ES1370_REG_STATUS, cssr, 4);
103474753Scg		DELAY(20000);
103555209Scg	}
103653413Sroger	/* AC'97 warm reset to start the bitclk */
1037152419Sariff	es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4);
1038152419Sariff	es_wr(es, ES1371_REG_LEGACY, ES1371_SYNC_RES, 4);
103953413Sroger	DELAY(2000);
1040152419Sariff	es_wr(es, ES1370_REG_CONTROL, es->sctrl, 4);
1041148591Snetchild	es1371_wait_src_ready(es);
104253413Sroger	/* Init the sample rate converter */
1043148591Snetchild	es_wr(es, ES1371_REG_SMPRATE, ES1371_DIS_SRC, 4);
104453413Sroger	for (idx = 0; idx < 0x80; idx++)
104554831Scg		es1371_src_write(es, idx, 0);
1046164614Sariff	es1371_src_write(es, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4);
104753413Sroger	es1371_src_write(es, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10);
1048164614Sariff	es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4);
104953413Sroger	es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10);
1050164614Sariff	es1371_src_write(es, ES_SMPREG_VOL_ADC, 1 << 12);
1051164614Sariff	es1371_src_write(es, ES_SMPREG_VOL_ADC + 1, 1 << 12);
1052164614Sariff	es1371_src_write(es, ES_SMPREG_VOL_DAC1, 1 << 12);
1053164614Sariff	es1371_src_write(es, ES_SMPREG_VOL_DAC1 + 1, 1 << 12);
1054164614Sariff	es1371_src_write(es, ES_SMPREG_VOL_DAC2, 1 << 12);
1055164614Sariff	es1371_src_write(es, ES_SMPREG_VOL_DAC2 + 1, 1 << 12);
1056164614Sariff	es1371_adc_rate(es, 22050, ES_ADC);
1057164614Sariff	es1371_dac_rate(es, 22050, ES_DAC1);
1058164614Sariff	es1371_dac_rate(es, 22050, ES_DAC2);
1059164614Sariff	/*
1060164614Sariff	 * WARNING:
106153413Sroger	 * enabling the sample rate converter without properly programming
106253413Sroger	 * its parameters causes the chip to lock up (the SRC busy bit will
106353413Sroger	 * be stuck high, and I've found no way to rectify this other than
106453413Sroger	 * power cycle)
106553413Sroger	 */
1066148591Snetchild	es1371_wait_src_ready(es);
1067148591Snetchild	es_wr(es, ES1371_REG_SMPRATE, 0, 4);
1068148591Snetchild	/* try to reset codec directly */
1069148591Snetchild	es_wr(es, ES1371_REG_CODEC, 0, 4);
1070148591Snetchild	es_wr(es, ES1370_REG_STATUS, cssr, 4);
1071150832Snetchild	ES_UNLOCK(es);
107253413Sroger
107353413Sroger	return (0);
107453413Sroger}
107553413Sroger
107670134Scg/* -------------------------------------------------------------------- */
107770134Scg
107870134Scgstatic int
1079164614Sariffes1371_wrcd(kobj_t obj, void *s, int addr, uint32_t data)
108053413Sroger{
1081150832Snetchild	uint32_t t, x, orig;
108253413Sroger	struct es_info *es = (struct es_info*)s;
108353413Sroger
1084167648Sariff	for (t = 0; t < 0x1000; t++) {
1085148591Snetchild	  	if (!es_rd(es, ES1371_REG_CODEC & CODEC_WIP, 4))
108653413Sroger			break;
1087167648Sariff	}
108853413Sroger	/* save the current state for later */
1089148591Snetchild 	x = orig = es_rd(es, ES1371_REG_SMPRATE, 4);
109053413Sroger	/* enable SRC state data in SRC mux */
1091164614Sariff	es_wr(es, ES1371_REG_SMPRATE, (x & (ES1371_DIS_SRC | ES1371_DIS_P1 |
1092164614Sariff	    ES1371_DIS_P2 | ES1371_DIS_R1)) | 0x00010000, 4);
1093148591Snetchild	/* busy wait */
1094164614Sariff	for (t = 0; t < 0x1000; t++) {
1095164614Sariff	  	if ((es_rd(es, ES1371_REG_SMPRATE, 4) & 0x00870000) ==
1096164614Sariff		    0x00000000)
1097148591Snetchild			break;
1098164614Sariff	}
109953413Sroger	/* wait for a SAFE time to write addr/data and then do it, dammit */
1100164614Sariff	for (t = 0; t < 0x1000; t++) {
1101164614Sariff	  	if ((es_rd(es, ES1371_REG_SMPRATE, 4) & 0x00870000) ==
1102164614Sariff		    0x00010000)
110354831Scg			break;
1104164614Sariff	}
110554831Scg
1106164614Sariff	es_wr(es, ES1371_REG_CODEC, ((addr << CODEC_POADD_SHIFT) &
1107164614Sariff	    CODEC_POADD_MASK) | ((data << CODEC_PODAT_SHIFT) &
1108164614Sariff	    CODEC_PODAT_MASK), 4);
110953413Sroger	/* restore SRC reg */
111053413Sroger	es1371_wait_src_ready(s);
1111148591Snetchild	es_wr(es, ES1371_REG_SMPRATE, orig, 4);
111270134Scg
1113164614Sariff	return (0);
111453413Sroger}
111553413Sroger
111670134Scgstatic int
111770134Scges1371_rdcd(kobj_t obj, void *s, int addr)
111853413Sroger{
1119150832Snetchild  	uint32_t t, x, orig;
112054831Scg  	struct es_info *es = (struct es_info *)s;
112153413Sroger
1122164614Sariff  	for (t = 0; t < 0x1000; t++) {
1123148591Snetchild		if (!(x = es_rd(es, ES1371_REG_CODEC, 4) & CODEC_WIP))
112454831Scg	  		break;
1125164614Sariff	}
112653413Sroger
112754831Scg  	/* save the current state for later */
1128148591Snetchild  	x = orig = es_rd(es, ES1371_REG_SMPRATE, 4);
112954831Scg  	/* enable SRC state data in SRC mux */
1130164614Sariff  	es_wr(es, ES1371_REG_SMPRATE, (x & (ES1371_DIS_SRC | ES1371_DIS_P1 |
1131164614Sariff	    ES1371_DIS_P2 | ES1371_DIS_R1)) | 0x00010000, 4);
1132148591Snetchild	/* busy wait */
1133164614Sariff  	for (t = 0; t < 0x1000; t++) {
1134164614Sariff		if ((x = es_rd(es, ES1371_REG_SMPRATE, 4) & 0x00870000) ==
1135164614Sariff		    0x00000000)
1136148591Snetchild	  		break;
1137164614Sariff	}
113854831Scg  	/* wait for a SAFE time to write addr/data and then do it, dammit */
1139164614Sariff  	for (t = 0; t < 0x1000; t++) {
1140164614Sariff		if ((x = es_rd(es, ES1371_REG_SMPRATE, 4) & 0x00870000) ==
1141164614Sariff		    0x00010000)
114254831Scg	  		break;
1143164614Sariff	}
114453413Sroger
1145164614Sariff  	es_wr(es, ES1371_REG_CODEC, ((addr << CODEC_POADD_SHIFT) &
1146164614Sariff	    CODEC_POADD_MASK) | CODEC_PORD, 4);
1147148591Snetchild
114854831Scg  	/* restore SRC reg */
114954831Scg  	es1371_wait_src_ready(s);
1150148591Snetchild  	es_wr(es, ES1371_REG_SMPRATE, orig, 4);
115153413Sroger
115254831Scg  	/* now wait for the stinkin' data (RDY) */
1153164614Sariff  	for (t = 0; t < 0x1000; t++) {
1154148591Snetchild		if ((x = es_rd(es, ES1371_REG_CODEC, 4)) & CODEC_RDY)
115554831Scg	  		break;
1156164614Sariff	}
1157148591Snetchild
115854831Scg  	return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT);
115953413Sroger}
116053413Sroger
116170134Scgstatic kobj_method_t es1371_ac97_methods[] = {
1162164614Sariff	KOBJMETHOD(ac97_read,		es1371_rdcd),
1163164614Sariff	KOBJMETHOD(ac97_write,		es1371_wrcd),
116470134Scg	{ 0, 0 }
116570134Scg};
116670134ScgAC97_DECLARE(es1371_ac97);
116770134Scg
116870134Scg/* -------------------------------------------------------------------- */
116970134Scg
1170164614Sariffstatic unsigned int
1171164614Sariffes1371_src_read(struct es_info *es, unsigned short reg)
117254831Scg{
1173150832Snetchild  	uint32_t r;
117453413Sroger
1175164614Sariff  	r = es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 |
1176164614Sariff	    ES1371_DIS_P2 | ES1371_DIS_R1);
117754831Scg  	r |= ES1371_SRC_RAM_ADDRO(reg);
1178148591Snetchild  	es_wr(es, ES1371_REG_SMPRATE, r, 4);
1179164614Sariff  	return (ES1371_SRC_RAM_DATAI(es1371_wait_src_ready(es)));
118053413Sroger}
118153413Sroger
118253413Srogerstatic void
1183164614Sariffes1371_src_write(struct es_info *es, unsigned short reg, unsigned short data)
1184148591Snetchild{
1185150832Snetchild	uint32_t r;
118653413Sroger
1187164614Sariff	r = es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 |
1188164614Sariff	    ES1371_DIS_P2 | ES1371_DIS_R1);
118953413Sroger	r |= ES1371_SRC_RAM_ADDRO(reg) |  ES1371_SRC_RAM_DATAO(data);
1190148591Snetchild	es_wr(es, ES1371_REG_SMPRATE, r | ES1371_SRC_RAM_WE, 4);
119153413Sroger}
119253413Sroger
1193164614Sariffstatic unsigned int
1194164614Sariffes1371_adc_rate(struct es_info *es, unsigned int rate, int set)
119554831Scg{
1196164614Sariff  	unsigned int n, truncm, freq, result;
119754831Scg
1198150832Snetchild	ES_LOCK_ASSERT(es);
1199150832Snetchild
1200164614Sariff  	if (rate > 48000)
1201164614Sariff		rate = 48000;
1202164614Sariff  	if (rate < 4000)
1203164614Sariff		rate = 4000;
120454831Scg  	n = rate / 3000;
120554831Scg  	if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
120654831Scg		n--;
120754831Scg  	truncm = (21 * n - 1) | 1;
120854831Scg  	freq = ((48000UL << 15) / rate) * n;
120954831Scg  	result = (48000UL << 15) / (freq / n);
121054831Scg  	if (set) {
121154831Scg		if (rate >= 24000) {
1212164614Sariff	  		if (truncm > 239)
1213164614Sariff				truncm = 239;
121454831Scg	  		es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
1215164614Sariff			    (((239 - truncm) >> 1) << 9) | (n << 4));
121654831Scg		} else {
1217164614Sariff	  		if (truncm > 119)
1218164614Sariff				truncm = 119;
121954831Scg	  		es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
1220164614Sariff			    0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));
122154831Scg		}
122254831Scg		es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_INT_REGS,
1223164614Sariff		    (es1371_src_read(es, ES_SMPREG_ADC + ES_SMPREG_INT_REGS) &
1224164614Sariff		    0x00ff) | ((freq >> 5) & 0xfc00));
1225164614Sariff		es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC,
1226164614Sariff		    freq & 0x7fff);
122754831Scg		es1371_src_write(es, ES_SMPREG_VOL_ADC, n << 8);
122854831Scg		es1371_src_write(es, ES_SMPREG_VOL_ADC + 1, n << 8);
122953413Sroger	}
1230164614Sariff	return (result);
123153413Sroger}
123253413Sroger
1233164614Sariffstatic unsigned int
1234164614Sariffes1371_dac_rate(struct es_info *es, unsigned int rate, int set)
123554831Scg{
1236164614Sariff  	unsigned int freq, r, result, dac, dis;
123753413Sroger
1238150832Snetchild	ES_LOCK_ASSERT(es);
1239150832Snetchild
1240164614Sariff  	if (rate > 48000)
1241164614Sariff		rate = 48000;
1242164614Sariff  	if (rate < 4000)
1243164614Sariff		rate = 4000;
1244152419Sariff  	freq = ((rate << 15) + 1500) / 3000;
124554831Scg  	result = (freq * 3000) >> 15;
1246164614Sariff
1247152419Sariff	dac = (set == ES_DAC1) ? ES_SMPREG_DAC1 : ES_SMPREG_DAC2;
1248152419Sariff	dis = (set == ES_DAC1) ? ES1371_DIS_P2 : ES1371_DIS_P1;
1249164614Sariff	r = (es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 |
1250164614Sariff	    ES1371_DIS_P2 | ES1371_DIS_R1));
1251152419Sariff	es_wr(es, ES1371_REG_SMPRATE, r, 4);
1252152419Sariff	es1371_src_write(es, dac + ES_SMPREG_INT_REGS,
1253164614Sariff	    (es1371_src_read(es, dac + ES_SMPREG_INT_REGS) & 0x00ff) |
1254164614Sariff	    ((freq >> 5) & 0xfc00));
1255152419Sariff	es1371_src_write(es, dac + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
1256164614Sariff	r = (es1371_wait_src_ready(es) &
1257164614Sariff	    (ES1371_DIS_SRC | dis | ES1371_DIS_R1));
1258152419Sariff	es_wr(es, ES1371_REG_SMPRATE, r, 4);
1259164614Sariff  	return (result);
126053413Sroger}
126153413Sroger
1262150832Snetchildstatic uint32_t
126355209Scges1371_wait_src_ready(struct es_info *es)
126454831Scg{
1265150832Snetchild  	uint32_t t, r;
126653413Sroger
1267148591Snetchild  	for (t = 0; t < 0x1000; t++) {
1268164614Sariff		if (!((r = es_rd(es, ES1371_REG_SMPRATE, 4)) &
1269164614Sariff		    ES1371_SRC_RAM_BUSY))
1270164614Sariff	  		return (r);
1271148591Snetchild		DELAY(1);
127254831Scg  	}
1273150832Snetchild	device_printf(es->dev, "%s: timed out 0x%x [0x%x]\n", __func__,
1274150832Snetchild		ES1371_REG_SMPRATE, r);
1275164614Sariff  	return (0);
127653413Sroger}
127753413Sroger
127850724Scg/* -------------------------------------------------------------------- */
127950724Scg
128050724Scg/*
128150724Scg * Probe and attach the card
128250724Scg */
128350724Scg
128450724Scgstatic int
128550724Scges_pci_probe(device_t dev)
128650724Scg{
128776086Scg	switch(pci_get_devid(dev)) {
128876086Scg	case ES1370_PCI_ID:
128950724Scg		device_set_desc(dev, "AudioPCI ES1370");
1290164614Sariff		return (BUS_PROBE_DEFAULT);
129176086Scg	case ES1371_PCI_ID:
129276086Scg		switch(pci_get_revid(dev)) {
129378033Scg		case ES1371REV_ES1371_A:
129478033Scg			device_set_desc(dev, "AudioPCI ES1371-A");
1295164614Sariff			return (BUS_PROBE_DEFAULT);
129676086Scg		case ES1371REV_ES1371_B:
129776086Scg			device_set_desc(dev, "AudioPCI ES1371-B");
1298164614Sariff			return (BUS_PROBE_DEFAULT);
129976086Scg		case ES1371REV_ES1373_A:
130076086Scg			device_set_desc(dev, "AudioPCI ES1373-A");
1301164614Sariff			return (BUS_PROBE_DEFAULT);
130276086Scg		case ES1371REV_ES1373_B:
130376086Scg			device_set_desc(dev, "AudioPCI ES1373-B");
1304164614Sariff			return (BUS_PROBE_DEFAULT);
130576086Scg		case ES1371REV_ES1373_8:
130676086Scg			device_set_desc(dev, "AudioPCI ES1373-8");
1307164614Sariff			return (BUS_PROBE_DEFAULT);
130876086Scg		case ES1371REV_CT5880_A:
130976086Scg			device_set_desc(dev, "Creative CT5880-A");
1310164614Sariff			return (BUS_PROBE_DEFAULT);
131176086Scg		default:
131276086Scg			device_set_desc(dev, "AudioPCI ES1371-?");
1313164614Sariff			device_printf(dev,
1314164614Sariff			    "unknown revision %d -- please report to "
1315164614Sariff			    "freebsd-multimedia@freebsd.org\n",
1316164614Sariff			    pci_get_revid(dev));
1317164614Sariff			return (BUS_PROBE_DEFAULT);
131876086Scg		}
131976086Scg	case ES1371_PCI_ID2:
132078033Scg		device_set_desc(dev, "Strange AudioPCI ES1371-? (vid=3274)");
1321164614Sariff		device_printf(dev,
1322164614Sariff		    "unknown revision %d -- please report to "
1323164614Sariff		    "freebsd-multimedia@freebsd.org\n", pci_get_revid(dev));
1324164614Sariff		return (BUS_PROBE_DEFAULT);
1325119548Sorion	case CT4730_PCI_ID:
1326119548Sorion		switch(pci_get_revid(dev)) {
1327119548Sorion		case CT4730REV_CT4730_A:
1328164614Sariff			device_set_desc(dev,
1329164614Sariff			    "Creative SB AudioPCI CT4730/EV1938");
1330164614Sariff			return (BUS_PROBE_DEFAULT);
1331119548Sorion		default:
1332119548Sorion			device_set_desc(dev, "Creative SB AudioPCI CT4730-?");
1333164614Sariff			device_printf(dev,
1334164614Sariff			    "unknown revision %d -- please report to "
1335164614Sariff			    "freebsd-multimedia@freebsd.org\n",
1336164614Sariff			    pci_get_revid(dev));
1337164614Sariff			return (BUS_PROBE_DEFAULT);
1338119548Sorion		}
133976086Scg	case CT5880_PCI_ID:
134076086Scg		switch(pci_get_revid(dev)) {
134176086Scg		case CT5880REV_CT5880_C:
134276086Scg			device_set_desc(dev, "Creative CT5880-C");
1343164614Sariff			return (BUS_PROBE_DEFAULT);
134476086Scg		case CT5880REV_CT5880_D:
134576086Scg			device_set_desc(dev, "Creative CT5880-D");
1346164614Sariff			return (BUS_PROBE_DEFAULT);
134795678Scg		case CT5880REV_CT5880_E:
134895678Scg			device_set_desc(dev, "Creative CT5880-E");
1349164614Sariff			return (BUS_PROBE_DEFAULT);
135076086Scg		default:
135176086Scg			device_set_desc(dev, "Creative CT5880-?");
1352164614Sariff			device_printf(dev,
1353164614Sariff			    "unknown revision %d -- please report to "
1354164614Sariff			    "freebsd-multimedia@freebsd.org\n",
1355164614Sariff			    pci_get_revid(dev));
1356164614Sariff			return (BUS_PROBE_DEFAULT);
135776086Scg		}
135876086Scg	default:
1359164614Sariff		return (ENXIO);
136050724Scg	}
136150724Scg}
136250724Scg
1363148591Snetchild#ifdef SND_DYNSYSCTL
136450724Scgstatic int
1365150832Snetchildsysctl_es137x_spdif_enable(SYSCTL_HANDLER_ARGS)
1366148591Snetchild{
1367148591Snetchild	struct es_info *es;
1368148591Snetchild	device_t dev;
1369150832Snetchild	uint32_t r;
1370150832Snetchild	int err, new_en;
1371148591Snetchild
1372148591Snetchild	dev = oidp->oid_arg1;
1373148591Snetchild	es = pcm_getdevinfo(dev);
1374150832Snetchild	ES_LOCK(es);
1375150832Snetchild	r = es_rd(es, ES1370_REG_STATUS, 4);
1376150832Snetchild	ES_UNLOCK(es);
1377150832Snetchild	new_en = (r & ENABLE_SPDIF) ? 1 : 0;
1378170289Sdwmalone	err = sysctl_handle_int(oidp, &new_en, 0, req);
1379148591Snetchild
1380148591Snetchild	if (err || req->newptr == NULL)
1381150832Snetchild		return (err);
1382148591Snetchild	if (new_en < 0 || new_en > 1)
1383150832Snetchild		return (EINVAL);
1384148591Snetchild
1385150832Snetchild	ES_LOCK(es);
1386148591Snetchild	if (new_en) {
1387148591Snetchild		r |= ENABLE_SPDIF;
1388148591Snetchild		es->ctrl |= SPDIFEN_B;
1389148591Snetchild		es->ctrl |= RECEN_B;
1390148591Snetchild	} else {
1391148591Snetchild		r &= ~ENABLE_SPDIF;
1392148591Snetchild		es->ctrl &= ~SPDIFEN_B;
1393148591Snetchild		es->ctrl &= ~RECEN_B;
1394148591Snetchild	}
1395148591Snetchild	es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4);
1396148591Snetchild	es_wr(es, ES1370_REG_STATUS, r, 4);
1397150832Snetchild	ES_UNLOCK(es);
1398150832Snetchild
1399150832Snetchild	return (0);
1400148591Snetchild}
1401148591Snetchild
1402148591Snetchildstatic int
1403150832Snetchildsysctl_es137x_latency_timer(SYSCTL_HANDLER_ARGS)
1404148591Snetchild{
1405148591Snetchild	struct es_info *es;
1406148591Snetchild	device_t dev;
1407150832Snetchild	uint32_t val;
1408150832Snetchild	int err;
1409148591Snetchild
1410148591Snetchild	dev = oidp->oid_arg1;
1411148591Snetchild	es = pcm_getdevinfo(dev);
1412150832Snetchild	ES_LOCK(es);
1413148591Snetchild	val = pci_read_config(dev, PCIR_LATTIMER, 1);
1414150832Snetchild	ES_UNLOCK(es);
1415170289Sdwmalone	err = sysctl_handle_int(oidp, &val, 0, req);
1416164614Sariff
1417148591Snetchild	if (err || req->newptr == NULL)
1418150832Snetchild		return (err);
1419150832Snetchild	if (val > 255)
1420150832Snetchild		return (EINVAL);
1421148591Snetchild
1422150832Snetchild	ES_LOCK(es);
1423148591Snetchild	pci_write_config(dev, PCIR_LATTIMER, val, 1);
1424150832Snetchild	ES_UNLOCK(es);
1425150832Snetchild
1426150832Snetchild	return (0);
1427148591Snetchild}
1428150832Snetchild
1429150832Snetchildstatic int
1430150832Snetchildsysctl_es137x_fixed_rate(SYSCTL_HANDLER_ARGS)
1431150832Snetchild{
1432150832Snetchild	struct es_info *es;
1433150832Snetchild	device_t dev;
1434150832Snetchild	uint32_t val;
1435150832Snetchild	int err;
1436150832Snetchild
1437150832Snetchild	dev = oidp->oid_arg1;
1438150832Snetchild	es = pcm_getdevinfo(dev);
1439150832Snetchild	ES_LOCK(es);
1440152419Sariff	val = ES_FIXED_RATE(es->escfg);
1441152419Sariff	if (val < es_caps.minspeed)
1442150832Snetchild		val = 0;
1443150832Snetchild	ES_UNLOCK(es);
1444170289Sdwmalone	err = sysctl_handle_int(oidp, &val, 0, req);
1445164614Sariff
1446150832Snetchild	if (err || req->newptr == NULL)
1447150832Snetchild		return (err);
1448150832Snetchild	if (val != 0 && (val < es_caps.minspeed || val > es_caps.maxspeed))
1449150832Snetchild		return (EINVAL);
1450150832Snetchild
1451150832Snetchild	ES_LOCK(es);
1452152419Sariff	if (es->ctrl & (CTRL_DAC2_EN|CTRL_ADC_EN)) {
1453152419Sariff		ES_UNLOCK(es);
1454152419Sariff		return (EBUSY);
1455152419Sariff	}
1456150832Snetchild	if (val) {
1457152419Sariff		if (val != ES_FIXED_RATE(es->escfg)) {
1458152419Sariff			es->escfg = ES_SET_FIXED_RATE(es->escfg, val);
1459152419Sariff			es->ch[ES_DAC2].caps.maxspeed = val;
1460152419Sariff			es->ch[ES_DAC2].caps.minspeed = val;
1461152419Sariff			es->ch[ES_ADC].caps.maxspeed = val;
1462152419Sariff			es->ch[ES_ADC].caps.minspeed = val;
1463152419Sariff			es->ctrl &= ~CTRL_PCLKDIV;
1464152419Sariff			es->ctrl |= DAC2_SRTODIV(val) << CTRL_SH_PCLKDIV;
1465152419Sariff			es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4);
1466152419Sariff		}
1467150832Snetchild	} else {
1468152419Sariff		es->escfg = ES_SET_FIXED_RATE(es->escfg, 0);
1469152419Sariff		es->ch[ES_DAC2].caps = es_caps;
1470152419Sariff		es->ch[ES_ADC].caps = es_caps;
1471150832Snetchild	}
1472150832Snetchild	ES_UNLOCK(es);
1473150832Snetchild
1474150832Snetchild	return (0);
1475150832Snetchild}
1476152419Sariff
1477152419Sariffstatic int
1478152419Sariffsysctl_es137x_single_pcm_mixer(SYSCTL_HANDLER_ARGS)
1479152419Sariff{
1480152419Sariff	struct es_info *es;
1481152419Sariff	struct snddev_info *d;
1482152419Sariff	struct snd_mixer *m;
1483152419Sariff	struct cdev *i_dev;
1484152419Sariff	device_t dev;
1485152419Sariff	uint32_t val, set;
1486152419Sariff	int recsrc, level, err;
1487152419Sariff
1488152419Sariff	dev = oidp->oid_arg1;
1489152419Sariff	d = device_get_softc(dev);
1490152419Sariff	if (d == NULL || d->mixer_dev == NULL || d->mixer_dev->si_drv1 == NULL)
1491152419Sariff		return (EINVAL);
1492152419Sariff	es = d->devinfo;
1493152419Sariff	if (es == NULL)
1494152419Sariff		return (EINVAL);
1495152419Sariff	ES_LOCK(es);
1496152419Sariff	set = ES_SINGLE_PCM_MIX(es->escfg);
1497152419Sariff	val = set;
1498152419Sariff	ES_UNLOCK(es);
1499170289Sdwmalone	err = sysctl_handle_int(oidp, &val, 0, req);
1500164614Sariff
1501152419Sariff	if (err || req->newptr == NULL)
1502152419Sariff		return (err);
1503152419Sariff	if (!(val == 0 || val == 1))
1504152419Sariff		return (EINVAL);
1505152419Sariff	if (val == set)
1506152419Sariff		return (0);
1507152419Sariff	i_dev = d->mixer_dev;
1508152419Sariff	if (mixer_ioctl(i_dev, 0, (caddr_t)&recsrc, 0, NULL) != EBADF)
1509152419Sariff		return (EBUSY);
1510164614Sariff	err = mixer_ioctl(i_dev, MIXER_READ(SOUND_MIXER_PCM), (caddr_t)&level,
1511164614Sariff	    -1, NULL);
1512152419Sariff	if (!err)
1513152419Sariff		err = mixer_ioctl(i_dev, MIXER_READ(SOUND_MIXER_RECSRC),
1514164614Sariff		    (caddr_t)&recsrc, -1, NULL);
1515152419Sariff	if (err)
1516152419Sariff		return (err);
1517152419Sariff	if (level < 0)
1518152419Sariff		return (EINVAL);
1519152419Sariff
1520152419Sariff	ES_LOCK(es);
1521152419Sariff	if (es->ctrl & (CTRL_ADC_EN | CTRL_DAC1_EN | CTRL_DAC2_EN)) {
1522152419Sariff		ES_UNLOCK(es);
1523152419Sariff		return (EBUSY);
1524152419Sariff	}
1525164614Sariff	if (val)
1526152419Sariff		es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 1);
1527164614Sariff	else
1528152419Sariff		es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 0);
1529152419Sariff	ES_UNLOCK(es);
1530152419Sariff	m = i_dev->si_drv1;
1531152419Sariff	if (!val) {
1532152419Sariff		mix_setdevs(m, mix_getdevs(d->mixer_dev->si_drv1) |
1533164614Sariff		    (1 << SOUND_MIXER_SYNTH));
1534152419Sariff		mix_setrecdevs(m, mix_getrecdevs(d->mixer_dev->si_drv1) |
1535164614Sariff		    (1 << SOUND_MIXER_SYNTH));
1536152419Sariff		err = mixer_ioctl(i_dev, MIXER_WRITE(SOUND_MIXER_SYNTH),
1537164614Sariff		    (caddr_t)&level, -1, NULL);
1538152419Sariff	} else {
1539152419Sariff		err = mixer_ioctl(i_dev, MIXER_WRITE(SOUND_MIXER_SYNTH),
1540164614Sariff		    (caddr_t)&level, -1, NULL);
1541152419Sariff		mix_setdevs(m, mix_getdevs(d->mixer_dev->si_drv1) &
1542164614Sariff		    ~(1 << SOUND_MIXER_SYNTH));
1543152419Sariff		mix_setrecdevs(m, mix_getrecdevs(d->mixer_dev->si_drv1) &
1544164614Sariff		    ~(1 << SOUND_MIXER_SYNTH));
1545152419Sariff	}
1546152419Sariff	if (!err) {
1547152419Sariff		level = recsrc;
1548152419Sariff		if (recsrc & (1 << SOUND_MIXER_PCM))
1549152419Sariff			recsrc |= 1 << SOUND_MIXER_SYNTH;
1550152419Sariff		else if (recsrc & (1 << SOUND_MIXER_SYNTH))
1551152419Sariff			recsrc |= 1 << SOUND_MIXER_PCM;
1552152419Sariff		if (level != recsrc)
1553164614Sariff			err = mixer_ioctl(i_dev,
1554164614Sariff			    MIXER_WRITE(SOUND_MIXER_RECSRC),
1555164614Sariff			    (caddr_t)&recsrc, -1, NULL);
1556152419Sariff	}
1557152419Sariff	return (err);
1558152419Sariff}
1559164614Sariff
1560164614Sariffstatic int
1561164614Sariffsysctl_es_polling(SYSCTL_HANDLER_ARGS)
1562164614Sariff{
1563164614Sariff	struct es_info *es;
1564164614Sariff	device_t dev;
1565164614Sariff	int err, val;
1566164614Sariff
1567164614Sariff	dev = oidp->oid_arg1;
1568164614Sariff	es = pcm_getdevinfo(dev);
1569164614Sariff	if (es == NULL)
1570164614Sariff		return (EINVAL);
1571164614Sariff	ES_LOCK(es);
1572164614Sariff	val = es->polling;
1573164614Sariff	ES_UNLOCK(es);
1574170289Sdwmalone	err = sysctl_handle_int(oidp, &val, 0, req);
1575164614Sariff
1576164614Sariff	if (err || req->newptr == NULL)
1577164614Sariff		return (err);
1578164614Sariff	if (val < 0 || val > 1)
1579164614Sariff		return (EINVAL);
1580164614Sariff
1581164614Sariff	ES_LOCK(es);
1582164614Sariff	if (val != es->polling) {
1583164614Sariff		if (es_chan_active(es) != 0)
1584164614Sariff			err = EBUSY;
1585164614Sariff		else if (val == 0)
1586164614Sariff			es->polling = 0;
1587164614Sariff		else
1588164614Sariff			es->polling = 1;
1589164614Sariff	}
1590164614Sariff	ES_UNLOCK(es);
1591164614Sariff
1592164614Sariff	return (err);
1593164614Sariff}
1594148591Snetchild#endif /* SND_DYNSYSCTL */
1595148591Snetchild
1596148591Snetchildstatic void
1597148591Snetchildes_init_sysctls(device_t dev)
1598148591Snetchild{
1599148591Snetchild#ifdef SND_DYNSYSCTL
1600148591Snetchild	struct es_info *es;
1601148591Snetchild	int r, devid, revid;
1602148591Snetchild
1603148591Snetchild	devid = pci_get_devid(dev);
1604148591Snetchild	revid = pci_get_revid(dev);
1605148591Snetchild	es = pcm_getdevinfo(dev);
1606148591Snetchild	if ((devid == ES1371_PCI_ID && revid == ES1371REV_ES1373_8) ||
1607167648Sariff	    (devid == ES1371_PCI_ID && revid == ES1371REV_CT5880_A) ||
1608167648Sariff	    (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_C) ||
1609167648Sariff	    (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_D) ||
1610167648Sariff	    (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_E)) {
1611159732Snetchild		/* XXX: an user should be able to set this with a control tool,
1612159732Snetchild		   if not done before 7.0-RELEASE, this needs to be converted
1613159732Snetchild		   to a device specific sysctl "dev.pcm.X.yyy" via
1614159732Snetchild		   device_get_sysctl_*() as discussed on multimedia@ in msg-id
1615159732Snetchild		   <861wujij2q.fsf@xps.des.no> */
1616164614Sariff		SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
1617164614Sariff		    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
1618164614Sariff		    "spdif_enabled", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev),
1619164614Sariff		    sysctl_es137x_spdif_enable, "I",
1620164614Sariff		    "Enable S/PDIF output on primary playback channel");
1621150832Snetchild	} else if (devid == ES1370_PCI_ID) {
1622152419Sariff		/*
1623152419Sariff		 * Enable fixed rate sysctl if both DAC2 / ADC enabled.
1624152419Sariff		 */
1625164614Sariff		if (es->ch[ES_DAC2].channel != NULL &&
1626164614Sariff		    es->ch[ES_ADC].channel != NULL) {
1627159732Snetchild		/* XXX: an user should be able to set this with a control tool,
1628159732Snetchild		   if not done before 7.0-RELEASE, this needs to be converted
1629159732Snetchild		   to a device specific sysctl "dev.pcm.X.yyy" via
1630159732Snetchild		   device_get_sysctl_*() as discussed on multimedia@ in msg-id
1631159732Snetchild		   <861wujij2q.fsf@xps.des.no> */
1632164614Sariff			SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
1633164614Sariff			    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
1634164614Sariff			    OID_AUTO, "fixed_rate", CTLTYPE_INT | CTLFLAG_RW,
1635164614Sariff			    dev, sizeof(dev), sysctl_es137x_fixed_rate, "I",
1636164614Sariff			    "Enable fixed rate playback/recording");
1637152419Sariff		}
1638152419Sariff		/*
1639152419Sariff		 * Enable single pcm mixer sysctl if both DAC1/2 enabled.
1640152419Sariff		 */
1641164614Sariff		if (es->ch[ES_DAC1].channel != NULL &&
1642164614Sariff		    es->ch[ES_DAC2].channel != NULL) {
1643159732Snetchild		/* XXX: an user should be able to set this with a control tool,
1644159732Snetchild		   if not done before 7.0-RELEASE, this needs to be converted
1645159732Snetchild		   to a device specific sysctl "dev.pcm.X.yyy" via
1646159732Snetchild		   device_get_sysctl_*() as discussed on multimedia@ in msg-id
1647159732Snetchild		   <861wujij2q.fsf@xps.des.no> */
1648164614Sariff			SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
1649164614Sariff			    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
1650164614Sariff			    OID_AUTO, "single_pcm_mixer",
1651164614Sariff			    CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev),
1652164614Sariff			    sysctl_es137x_single_pcm_mixer, "I",
1653164614Sariff			    "Single PCM mixer controller for both DAC1/DAC2");
1654152419Sariff		}
1655148591Snetchild	}
1656164614Sariff	if (resource_int_value(device_get_name(dev), device_get_unit(dev),
1657164614Sariff	    "latency_timer", &r) == 0 && !(r < 0 || r > 255))
1658148591Snetchild		pci_write_config(dev, PCIR_LATTIMER, r, 1);
1659159732Snetchild	/* XXX: this needs to be converted to a device specific sysctl
1660159732Snetchild	   "dev.pcm.X.yyy" via device_get_sysctl_*() as discussed on
1661159732Snetchild	   multimedia@ in msg-id <861wujij2q.fsf@xps.des.no> */
1662164614Sariff	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
1663164614Sariff	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
1664164614Sariff	    "latency_timer", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev),
1665164614Sariff	    sysctl_es137x_latency_timer, "I",
1666164614Sariff	    "PCI Latency Timer configuration");
1667164614Sariff	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
1668164614Sariff	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
1669164614Sariff	    "polling", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev),
1670164614Sariff	    sysctl_es_polling, "I",
1671164614Sariff	    "Enable polling mode");
1672148591Snetchild#endif /* SND_DYNSYSCTL */
1673148591Snetchild}
1674148591Snetchild
1675148591Snetchildstatic int
167650724Scges_pci_attach(device_t dev)
167750724Scg{
1678164614Sariff	uint32_t	data;
1679150832Snetchild	struct es_info *es = NULL;
1680152419Sariff	int		mapped, i, numplay, dac_cfg;
168150724Scg	char		status[SND_STATUSLEN];
1682150832Snetchild	struct ac97_info *codec = NULL;
168370134Scg	kobj_class_t    ct = NULL;
1684150832Snetchild	uint32_t devid;
168550724Scg
168678564Sgreid	if ((es = malloc(sizeof *es, M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
168750724Scg		device_printf(dev, "cannot allocate softc\n");
1688164614Sariff		return (ENXIO);
168950724Scg	}
1690167608Sariff	es->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_es137x softc");
169159019Scg	es->dev = dev;
1692152419Sariff	es->escfg = 0;
169350724Scg	mapped = 0;
1694150832Snetchild
1695150832Snetchild	pci_enable_busmaster(dev);
169650724Scg	data = pci_read_config(dev, PCIR_COMMAND, 2);
1697150832Snetchild	data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN);
169855426Scg	pci_write_config(dev, PCIR_COMMAND, data, 2);
169955426Scg	data = pci_read_config(dev, PCIR_COMMAND, 2);
170050724Scg	if (mapped == 0 && (data & PCIM_CMD_MEMEN)) {
170165644Scg		es->regid = MEM_MAP_REG;
170265644Scg		es->regtype = SYS_RES_MEMORY;
1703127135Snjl		es->reg = bus_alloc_resource_any(dev, es->regtype, &es->regid,
1704164614Sariff		    RF_ACTIVE);
1705150832Snetchild		if (es->reg)
170650724Scg			mapped++;
170750724Scg	}
170850724Scg	if (mapped == 0 && (data & PCIM_CMD_PORTEN)) {
1709119690Sjhb		es->regid = PCIR_BAR(0);
171065644Scg		es->regtype = SYS_RES_IOPORT;
1711127135Snjl		es->reg = bus_alloc_resource_any(dev, es->regtype, &es->regid,
1712164614Sariff		    RF_ACTIVE);
1713150832Snetchild		if (es->reg)
171450724Scg			mapped++;
171550724Scg	}
171650724Scg	if (mapped == 0) {
171750724Scg		device_printf(dev, "unable to map register space\n");
171850724Scg		goto bad;
171950724Scg	}
172054831Scg
1721150832Snetchild	es->st = rman_get_bustag(es->reg);
1722150832Snetchild	es->sh = rman_get_bushandle(es->reg);
1723164614Sariff	callout_init(&es->poll_timer, CALLOUT_MPSAFE);
1724164614Sariff	es->poll_ticks = 1;
1725164614Sariff
1726164614Sariff	if (resource_int_value(device_get_name(dev),
1727164614Sariff	    device_get_unit(dev), "polling", &i) == 0 && i != 0)
1728164614Sariff		es->polling = 1;
1729164614Sariff	else
1730164614Sariff		es->polling = 0;
1731164614Sariff
173284658Scg	es->bufsz = pcm_getbuffersize(dev, 4096, ES_DEFAULT_BUFSZ, 65536);
1733164614Sariff	if (resource_int_value(device_get_name(dev),
1734164614Sariff	    device_get_unit(dev), "blocksize", &i) == 0 && i > 0) {
1735167648Sariff		i &= ES_BLK_ALIGN;
1736167648Sariff		if (i < ES_BLK_MIN)
1737167648Sariff			i = ES_BLK_MIN;
1738164614Sariff		es->blkcnt = es->bufsz / i;
1739164614Sariff		i = 0;
1740164614Sariff		while (es->blkcnt >> i)
1741164614Sariff			i++;
1742164614Sariff		es->blkcnt = 1 << (i - 1);
1743167648Sariff		if (es->blkcnt < ES_DMA_SEGS_MIN)
1744167648Sariff			es->blkcnt = ES_DMA_SEGS_MIN;
1745167648Sariff		else if (es->blkcnt > ES_DMA_SEGS_MAX)
1746167648Sariff			es->blkcnt = ES_DMA_SEGS_MAX;
174784658Scg
1748164614Sariff	} else
1749164614Sariff		es->blkcnt = 2;
1750164614Sariff
1751164614Sariff	if (resource_int_value(device_get_name(dev), device_get_unit(dev),
1752164614Sariff	    "dac", &dac_cfg) == 0) {
1753152419Sariff		if (dac_cfg < 0 || dac_cfg > 3)
1754152419Sariff			dac_cfg = ES_DEFAULT_DAC_CFG;
1755152419Sariff	} else
1756152419Sariff		dac_cfg = ES_DEFAULT_DAC_CFG;
1757152419Sariff
1758152419Sariff	switch (dac_cfg) {
1759164614Sariff	case 0:	/* Enable all DAC: DAC1, DAC2 */
1760164614Sariff		numplay = 2;
1761164614Sariff		es->escfg = ES_SET_DAC_FIRST(es->escfg, ES_DAC1);
1762164614Sariff		es->escfg = ES_SET_DAC_SECOND(es->escfg, ES_DAC2);
1763164614Sariff		break;
1764164614Sariff	case 1: /* Only DAC1 */
1765164614Sariff		numplay = 1;
1766164614Sariff		es->escfg = ES_SET_DAC_FIRST(es->escfg, ES_DAC1);
1767164614Sariff		break;
1768164614Sariff	case 3: /* Enable all DAC / swap position: DAC2, DAC1 */
1769164614Sariff		numplay = 2;
1770164614Sariff		es->escfg = ES_SET_DAC_FIRST(es->escfg, ES_DAC2);
1771164614Sariff		es->escfg = ES_SET_DAC_SECOND(es->escfg, ES_DAC1);
1772164614Sariff		break;
1773164614Sariff	case 2: /* Only DAC2 */
1774164614Sariff	default:
1775164614Sariff		numplay = 1;
1776164614Sariff		es->escfg = ES_SET_DAC_FIRST(es->escfg, ES_DAC2);
1777164614Sariff		break;
1778152419Sariff	}
1779152419Sariff	es->escfg = ES_SET_NUMPLAY(es->escfg, numplay);
1780152419Sariff	es->escfg = ES_SET_NUMREC(es->escfg, 1);
1781152419Sariff
1782148591Snetchild	devid = pci_get_devid(dev);
1783150832Snetchild	switch (devid) {
1784150832Snetchild	case ES1371_PCI_ID:
1785150832Snetchild	case ES1371_PCI_ID2:
1786150832Snetchild	case CT5880_PCI_ID:
1787150832Snetchild	case CT4730_PCI_ID:
1788150832Snetchild		es1371_init(es);
1789150832Snetchild		codec = AC97_CREATE(dev, es, es1371_ac97);
1790150832Snetchild	  	if (codec == NULL)
179154831Scg			goto bad;
179254831Scg	  	/* our init routine does everything for us */
179354831Scg	  	/* set to NULL; flag mixer_init not to run the ac97_init */
179454831Scg	  	/*	  ac97_mixer.init = NULL;  */
1795150832Snetchild		if (mixer_init(dev, ac97_getmixerclass(), codec))
1796150832Snetchild			goto bad;
179770134Scg		ct = &eschan1371_class;
1798150832Snetchild		break;
1799150832Snetchild	case ES1370_PCI_ID:
1800150832Snetchild	  	es1370_init(es);
1801152419Sariff		/*
1802152419Sariff		 * Disable fixed rate operation if DAC2 disabled.
1803152419Sariff		 * This is a special case for es1370 only, where the
1804152419Sariff		 * speed of both ADC and DAC2 locked together.
1805152419Sariff		 */
1806164614Sariff		if (!ES_DAC2_ENABLED(es->escfg))
1807152419Sariff			es->escfg = ES_SET_FIXED_RATE(es->escfg, 0);
1808150832Snetchild	  	if (mixer_init(dev, &es1370_mixer_class, es))
180954831Scg			goto bad;
181070134Scg		ct = &eschan1370_class;
1811150832Snetchild		break;
1812150832Snetchild	default:
1813150832Snetchild		goto bad;
1814150832Snetchild		/* NOTREACHED */
1815150832Snetchild	}
181650724Scg
181765644Scg	es->irqid = 0;
1818127135Snjl	es->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &es->irqid,
1819164614Sariff	    RF_ACTIVE | RF_SHAREABLE);
1820164614Sariff	if (!es->irq || snd_setup_intr(dev, es->irq, INTR_MPSAFE, es_intr,
1821164614Sariff	    es, &es->ih)) {
182250724Scg		device_printf(dev, "unable to map interrupt\n");
182350724Scg		goto bad;
182450724Scg	}
182550724Scg
1826166165Smarius	if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev),
1827166165Smarius		/*alignment*/2, /*boundary*/0,
182850724Scg		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
182950724Scg		/*highaddr*/BUS_SPACE_MAXADDR,
183050724Scg		/*filter*/NULL, /*filterarg*/NULL,
183184658Scg		/*maxsize*/es->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
1832148591Snetchild		/*flags*/0, /*lockfunc*/NULL,
1833148591Snetchild		/*lockarg*/NULL, &es->parent_dmat) != 0) {
183450724Scg		device_printf(dev, "unable to create dma tag\n");
183550724Scg		goto bad;
183650724Scg	}
183750724Scg
1838126695Smatk	snprintf(status, SND_STATUSLEN, "at %s 0x%lx irq %ld %s",
1839164614Sariff	    (es->regtype == SYS_RES_IOPORT)? "io" : "memory",
1840164614Sariff	    rman_get_start(es->reg), rman_get_start(es->irq),
1841164614Sariff	    PCM_KLDSTRING(snd_es137x));
184250724Scg
1843152419Sariff	if (pcm_register(dev, es, numplay, 1))
1844150832Snetchild		goto bad;
1845152419Sariff	for (i = 0; i < numplay; i++)
1846152419Sariff		pcm_addchan(dev, PCMDIR_PLAY, ct, es);
184754831Scg	pcm_addchan(dev, PCMDIR_REC, ct, es);
1848148591Snetchild	es_init_sysctls(dev);
184950724Scg	pcm_setstatus(dev, status);
1850152419Sariff	es->escfg = ES_SET_GP(es->escfg, 0);
1851164614Sariff	if (numplay == 1)
1852152419Sariff		device_printf(dev, "<Playback: DAC%d / Record: ADC>\n",
1853164614Sariff		    ES_DAC_FIRST(es->escfg) + 1);
1854164614Sariff	else if (numplay == 2)
1855152419Sariff		device_printf(dev, "<Playback: DAC%d,DAC%d / Record: ADC>\n",
1856164614Sariff		    ES_DAC_FIRST(es->escfg) + 1, ES_DAC_SECOND(es->escfg) + 1);
1857164614Sariff	return (0);
185850724Scg
1859164614Sariffbad:
1860164614Sariff	if (es->parent_dmat)
1861164614Sariff		bus_dma_tag_destroy(es->parent_dmat);
1862164614Sariff	if (es->ih)
1863164614Sariff		bus_teardown_intr(dev, es->irq, es->ih);
1864164614Sariff	if (es->irq)
1865164614Sariff		bus_release_resource(dev, SYS_RES_IRQ, es->irqid, es->irq);
1866164614Sariff	if (codec)
1867164614Sariff		ac97_destroy(codec);
1868164614Sariff	if (es->reg)
1869164614Sariff		bus_release_resource(dev, es->regtype, es->regid, es->reg);
1870164614Sariff	if (es->lock)
1871164614Sariff		snd_mtxfree(es->lock);
1872164614Sariff	if (es)
1873164614Sariff		free(es, M_DEVBUF);
1874164614Sariff	return (ENXIO);
187550724Scg}
187650724Scg
187765644Scgstatic int
187865644Scges_pci_detach(device_t dev)
187965644Scg{
188065644Scg	int r;
188165644Scg	struct es_info *es;
188265644Scg
188365644Scg	r = pcm_unregister(dev);
1884164614Sariff	if (r)
1885164614Sariff		return (r);
188665644Scg
188765644Scg	es = pcm_getdevinfo(dev);
188865644Scg	bus_teardown_intr(dev, es->irq, es->ih);
188965644Scg	bus_release_resource(dev, SYS_RES_IRQ, es->irqid, es->irq);
1890148591Snetchild	bus_release_resource(dev, es->regtype, es->regid, es->reg);
1891150832Snetchild	bus_dma_tag_destroy(es->parent_dmat);
1892148591Snetchild	snd_mtxfree(es->lock);
189365644Scg	free(es, M_DEVBUF);
189465644Scg
1895164614Sariff	return (0);
189665644Scg}
189765644Scg
189850724Scgstatic device_method_t es_methods[] = {
189950724Scg	/* Device interface */
190050724Scg	DEVMETHOD(device_probe,		es_pci_probe),
190150724Scg	DEVMETHOD(device_attach,	es_pci_attach),
190265644Scg	DEVMETHOD(device_detach,	es_pci_detach),
190350724Scg
190450724Scg	{ 0, 0 }
190550724Scg};
190650724Scg
190750724Scgstatic driver_t es_driver = {
190850724Scg	"pcm",
190950724Scg	es_methods,
191082180Scg	PCM_SOFTC_SIZE,
191150724Scg};
191250724Scg
191362483ScgDRIVER_MODULE(snd_es137x, pci, es_driver, pcm_devclass, 0, 0);
1914132236StanimuraMODULE_DEPEND(snd_es137x, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
191562483ScgMODULE_VERSION(snd_es137x, 1);
1916