es137x.c revision 53413
1178172Simp/*
2178172Simp * Support the ENSONIQ AudioPCI board and Creative Labs SoundBlaster PCI
3206713Sjmallett * boards based on the ES1370, ES1371 and ES1373 chips.
4206713Sjmallett *
5206713Sjmallett * Copyright (c) 1999 Russell Cattelan <cattelan@thebarn.com>
6206713Sjmallett * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
7206713Sjmallett * Copyright (c) 1998 by Joachim Kuebart. All rights reserved.
8206713Sjmallett *
9206713Sjmallett * Redistribution and use in source and binary forms, with or without
10206713Sjmallett * modification, are permitted provided that the following conditions
11206713Sjmallett * are met:
12206713Sjmallett *
13206713Sjmallett * 1. Redistributions of source code must retain the above copyright
14206713Sjmallett *    notice, this list of conditions and the following disclaimer.
15206713Sjmallett *
16206713Sjmallett * 2. Redistributions in binary form must reproduce the above copyright
17206713Sjmallett *    notice, this list of conditions and the following disclaimer in
18206713Sjmallett *    the documentation and/or other materials provided with the
19206713Sjmallett *    distribution.
20206713Sjmallett *
21206713Sjmallett * 3. All advertising materials mentioning features or use of this
22206713Sjmallett *    software must display the following acknowledgement:
23206713Sjmallett *	This product includes software developed by Joachim Kuebart.
24206713Sjmallett *
25206713Sjmallett * 4. The name of the author may not be used to endorse or promote
26206713Sjmallett *    products derived from this software without specific prior
27178172Simp *    written permission.
28178172Simp *
29178172Simp * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
30178172Simp * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
31178172Simp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32178172Simp * DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
33178172Simp * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34178172Simp * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35178172Simp * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36178172Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37178172Simp * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38178172Simp * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39178172Simp * OF THE POSSIBILITY OF SUCH DAMAGE.
40178172Simp *
41178172Simp * $FreeBSD: head/sys/dev/sound/pci/es137x.c 53413 1999-11-19 07:29:10Z roger $
42178172Simp */
43178172Simp
44178172Simp/*
45178172Simp * Part of this code was heavily inspired by the linux driver from
46178172Simp * Thomas Sailer (sailer@ife.ee.ethz.ch)
47178172Simp * Just about everything has been touched and reworked in some way but
48178172Simp * the all the underlying sequences/timing/register values are from
49178172Simp * Thomas' code.
50178172Simp *
51178172Simp*/
52178172Simp
53178172Simp#include "pci.h"
54178172Simp#include "pcm.h"
55178172Simp
56178172Simp#include <dev/pcm/sound.h>
57178172Simp#include <dev/pcm/ac97.h>
58178172Simp#include <dev/pcm/pci/es137x.h>
59178172Simp
60178172Simp#include <pci/pcireg.h>
61178172Simp#include <pci/pcivar.h>
62178172Simp
63178172Simp#include <sys/sysctl.h>
64178172Simp
65178172Simp#if NPCI != 0
66178172Simp
67178172Simpstatic int debug = 0;
68178172SimpSYSCTL_INT(_debug, OID_AUTO, es_debug, CTLFLAG_RW, &debug, 0, "");
69178172Simp
70178172Simp#define MEM_MAP_REG 0x14
71178172Simp
72178172Simp/* PCI IDs of supported chips */
73178172Simp#define ES1370_PCI_ID 0x50001274
74178172Simp#define ES1371_PCI_ID 0x13711274
75178172Simp
76178172Simp/* device private data */
77178172Simpstruct es_info;
78178172Simp
79178172Simptypedef struct es_chinfo {
80178172Simp	struct es_info *parent;
81178172Simp	pcm_channel *channel;
82178172Simp	snd_dbuf *buffer;
83178172Simp	int dir;
84178172Simp	u_int32_t fmt;
85178172Simp} es_chinfo_t;
86206713Sjmallett
87206713Sjmalletttypedef struct es_info {
88206713Sjmallett	bus_space_tag_t st;
89206713Sjmallett	bus_space_handle_t sh;
90206713Sjmallett	bus_dma_tag_t	parent_dmat;
91206713Sjmallett
92178172Simp	/* Contents of board's registers */
93178172Simp	u_long		ctrl;
94178172Simp	u_long		sctrl;
95178172Simp	struct es_chinfo pch, rch;
96178172Simp} es_info_t;
97178172Simp
98178172Simp/* -------------------------------------------------------------------- */
99178172Simp/* prototypes */
100178172Simp
101178172Simpstatic u_int	es1371_wait_src_ready(es_info_t *);
102178172Simpstatic void	es1371_src_write(es_info_t *, u_short, unsigned short);
103178172Simpstatic u_int	es1371_adc_rate (es_info_t *, u_int, int);
104178172Simpstatic u_int	es1371_dac1_rate(es_info_t *, u_int, int);
105178172Simpstatic u_int	es1371_dac2_rate(es_info_t *, u_int, int);
106178172Simpstatic void	es1371_wrcodec(void *, int,   u_int32_t);
107178172Simpstatic u_int32_t	es1371_rdcodec(void *, u_int32_t);
108178172Simpstatic int	es1371_init(es_info_t *es);
109178172Simpstatic int	eschan1371_setspeed(void *data, u_int32_t speed);
110178172Simp
111216947Sjmallettstatic int      es_init(struct es_info *);
112216947Sjmallettstatic void     es_intr(void *);
113216947Sjmallettstatic int      write_codec(struct es_info *, u_char, u_char);
114216947Sjmallett
115216947Sjmallett/* channel interface */
116206713Sjmallettstatic void *eschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir);
117216972Sjmallettstatic int	eschan_setdir(void *data, int dir);
118178172Simpstatic int	eschan_setformat(void *data, u_int32_t format);
119178172Simpstatic int	eschan_setspeed(void *data, u_int32_t speed);
120178172Simpstatic int	eschan_setblocksize(void *data, u_int32_t blocksize);
121178172Simpstatic int	eschan_trigger(void *data, int go);
122178172Simpstatic int	eschan_getptr(void *data);
123178172Simpstatic pcmchan_caps *eschan_getcaps(void *data);
124178172Simp
125178172Simpstatic pcmchan_caps es_playcaps = {
126178172Simp	4000, 48000,
127178172Simp	AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
128178172Simp	AFMT_STEREO | AFMT_S16_LE
129178172Simp};
130178172Simp
131178172Simpstatic pcmchan_caps es_reccaps = {
132178172Simp	4000, 48000,
133178172Simp	AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
134178172Simp	AFMT_STEREO | AFMT_S16_LE
135178172Simp};
136178172Simp
137178172Simpstatic pcm_channel es_chantemplate = {
138178172Simp	eschan_init,
139206713Sjmallett	eschan_setdir,
140216972Sjmallett	eschan_setformat,
141216972Sjmallett	eschan_setspeed,
142216972Sjmallett	eschan_setblocksize,
143216972Sjmallett	eschan_trigger,
144216972Sjmallett	eschan_getptr,
145206713Sjmallett	eschan_getcaps,
146216972Sjmallett};
147178172Simp
148216972Sjmallett/* -------------------------------------------------------------------- */
149178172Simp
150178172Simp/* The mixer interface */
151216972Sjmallett
152178172Simpstatic int es_mixinit(snd_mixer *m);
153178172Simpstatic int es_mixset(snd_mixer *m, unsigned dev, unsigned left, unsigned right);
154178172Simpstatic int es_mixsetrecsrc(snd_mixer *m, u_int32_t src);
155178172Simp
156178172Simpstatic snd_mixer es_mixer = {
157178172Simp	"Ensoniq AudioPCI 1370 mixer",
158178172Simp	es_mixinit,
159178172Simp	es_mixset,
160178172Simp	es_mixsetrecsrc,
161178172Simp};
162178172Simp
163178172Simpstatic const struct {
164178172Simp	unsigned        volidx:4;
165178172Simp	unsigned        left:4;
166178172Simp	unsigned        right:4;
167178172Simp	unsigned        stereo:1;
168178172Simp	unsigned        recmask:13;
169178172Simp	unsigned        avail:1;
170178172Simp}       mixtable[SOUND_MIXER_NRDEVICES] = {
171178172Simp	[SOUND_MIXER_VOLUME]	= { 0, 0x0, 0x1, 1, 0x0000, 1 },
172178172Simp	[SOUND_MIXER_PCM] 	= { 1, 0x2, 0x3, 1, 0x0400, 1 },
173216972Sjmallett	[SOUND_MIXER_SYNTH]	= { 2, 0x4, 0x5, 1, 0x0060, 1 },
174202031Simp	[SOUND_MIXER_CD]	= { 3, 0x6, 0x7, 1, 0x0006, 1 },
175206829Sjmallett	[SOUND_MIXER_LINE]	= { 4, 0x8, 0x9, 1, 0x0018, 1 },
176202031Simp	[SOUND_MIXER_LINE1]	= { 5, 0xa, 0xb, 1, 0x1800, 1 },
177202031Simp	[SOUND_MIXER_LINE2]	= { 6, 0xc, 0x0, 0, 0x0100, 1 },
178202031Simp	[SOUND_MIXER_LINE3]	= { 7, 0xd, 0x0, 0, 0x0200, 1 },
179202031Simp	[SOUND_MIXER_MIC]	= { 8, 0xe, 0x0, 0, 0x0001, 1 },
180202031Simp	[SOUND_MIXER_OGAIN]	= { 9, 0xf, 0x0, 0, 0x0000, 1 } };
181202031Simp
182202031Simpstatic int
183202031Simpes_mixinit(snd_mixer *m)
184206829Sjmallett{
185202031Simp	int i;
186202031Simp	u_int32_t v;
187202031Simp
188202031Simp	v = 0;
189202031Simp	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
190202031Simp		if (mixtable[i].avail) v |= (1 << i);
191202031Simp	mix_setdevs(m, v);
192202031Simp	v = 0;
193202031Simp	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
194202031Simp		if (mixtable[i].recmask) v |= (1 << i);
195210311Sjmallett	mix_setrecdevs(m, v);
196178172Simp	return 0;
197178172Simp}
198202031Simp
199202031Simpstatic int
200202031Simpes_mixset(snd_mixer *m, unsigned dev, unsigned left, unsigned right)
201202031Simp{
202202031Simp	int l, r, rl, rr;
203202031Simp
204202031Simp	if (!mixtable[dev].avail) return -1;
205178172Simp	l = left;
206178172Simp	r = mixtable[dev].stereo? right : l;
207178172Simp	if (mixtable[dev].left == 0xf) {
208216972Sjmallett		rl = (l < 2)? 0x80 : 7 - (l - 2) / 14;
209216972Sjmallett	} else {
210216972Sjmallett		rl = (l < 10)? 0x80 : 15 - (l - 10) / 6;
211216972Sjmallett	}
212216972Sjmallett	if (mixtable[dev].stereo) {
213216972Sjmallett		rr = (r < 10)? 0x80 : 15 - (r - 10) / 6;
214216972Sjmallett		write_codec(mix_getdevinfo(m), mixtable[dev].right, rr);
215216972Sjmallett	}
216216972Sjmallett	write_codec(mix_getdevinfo(m), mixtable[dev].left, rl);
217216947Sjmallett	return l | (r << 8);
218216972Sjmallett}
219216947Sjmallett
220216972Sjmallettstatic int
221178172Simpes_mixsetrecsrc(snd_mixer *m, u_int32_t src)
222178172Simp{
223206713Sjmallett	int i, j = 0;
224216972Sjmallett
225216972Sjmallett	if (src == 0) src = 1 << SOUND_MIXER_MIC;
226216972Sjmallett	src &= mix_getrecdevs(m);
227216972Sjmallett	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
228206713Sjmallett		if ((src & (1 << i)) != 0) j |= mixtable[i].recmask;
229216972Sjmallett
230206713Sjmallett	write_codec(mix_getdevinfo(m), CODEC_LIMIX1, j & 0x55);
231216972Sjmallett	write_codec(mix_getdevinfo(m), CODEC_RIMIX1, j & 0xaa);
232216972Sjmallett	write_codec(mix_getdevinfo(m), CODEC_LIMIX2, (j >> 8) & 0x17);
233216972Sjmallett	write_codec(mix_getdevinfo(m), CODEC_RIMIX2, (j >> 8) & 0x0f);
234216972Sjmallett	write_codec(mix_getdevinfo(m), CODEC_OMIX1, 0x7f);
235216972Sjmallett	write_codec(mix_getdevinfo(m), CODEC_OMIX2, 0x3f);
236216972Sjmallett	return src;
237216972Sjmallett}
238216972Sjmallett
239216972Sjmallettstatic int
240204635Sgnnwrite_codec(struct es_info *es, u_char i, u_char data)
241216972Sjmallett{
242216972Sjmallett	int		wait = 100;	/* 100 msec timeout */
243216972Sjmallett
244216972Sjmallett	do {
245204635Sgnn		if ((bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS) &
246216972Sjmallett		      STAT_CSTAT) == 0) {
247216972Sjmallett			bus_space_write_2(es->st, es->sh, ES1370_REG_CODEC,
248178172Simp				((u_short)i << CODEC_INDEX_SHIFT) | data);
249178172Simp			return 0;
250178172Simp		}
251178172Simp		DELAY(1000);
252178172Simp	} while (--wait);
253178172Simp	printf("pcm: write_codec timed out\n");
254178172Simp	return -1;
255178172Simp}
256178172Simp
257206713Sjmallett/* -------------------------------------------------------------------- */
258178172Simp
259178172Simp/* channel interface */
260178172Simpstatic void *
261178172Simpeschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
262178172Simp{
263178172Simp	struct es_info *es = devinfo;
264178172Simp	struct es_chinfo *ch = (dir == PCMDIR_PLAY)? &es->pch : &es->rch;
265178172Simp
266178172Simp	ch->parent = es;
267178172Simp	ch->channel = c;
268178172Simp	ch->buffer = b;
269178172Simp	ch->buffer->bufsize = ES_BUFFSIZE;
270178172Simp	if (chn_allocbuf(ch->buffer, es->parent_dmat) == -1) return NULL;
271206713Sjmallett	return ch;
272206713Sjmallett}
273206713Sjmallett
274206713Sjmallettstatic int
275206713Sjmalletteschan_setdir(void *data, int dir)
276206713Sjmallett{
277206713Sjmallett	struct es_chinfo *ch = data;
278178172Simp	struct es_info *es = ch->parent;
279212532Sjchandra
280212532Sjchandra	if (dir == PCMDIR_PLAY) {
281212532Sjchandra		bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE,
282212532Sjchandra				  ES1370_REG_DAC2_FRAMEADR >> 8);
283212532Sjchandra		bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMEADR & 0xff,
284212532Sjchandra				  vtophys(ch->buffer->buf));
285212632Sneel		bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMECNT & 0xff,
286212532Sjchandra				  (ch->buffer->bufsize >> 2) - 1);
287212532Sjchandra	} else {
288212532Sjchandra		bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE,
289212532Sjchandra				  ES1370_REG_ADC_FRAMEADR >> 8);
290212532Sjchandra		bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMEADR & 0xff,
291212532Sjchandra				  vtophys(ch->buffer->buf));
292212532Sjchandra		bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMECNT & 0xff,
293212532Sjchandra				  (ch->buffer->bufsize >> 2) - 1);
294212532Sjchandra	}
295212532Sjchandra	ch->dir = dir;
296212532Sjchandra	return 0;
297178172Simp}
298178172Simp
299178172Simpstatic int
300178172Simpeschan_setformat(void *data, u_int32_t format)
301178172Simp{
302178172Simp	struct es_chinfo *ch = data;
303205675Sneel	struct es_info *es = ch->parent;
304205675Sneel
305205675Sneel	if (ch->dir == PCMDIR_PLAY) {
306205675Sneel		es->sctrl &= ~SCTRL_P2FMT;
307205675Sneel		if (format & AFMT_S16_LE) es->sctrl |= SCTRL_P2SEB;
308205675Sneel		if (format & AFMT_STEREO) es->sctrl |= SCTRL_P2SMB;
309205675Sneel	} else {
310205675Sneel		es->sctrl &= ~SCTRL_R1FMT;
311205675Sneel		if (format & AFMT_S16_LE) es->sctrl |= SCTRL_R1SEB;
312205675Sneel		if (format & AFMT_STEREO) es->sctrl |= SCTRL_R1SMB;
313205675Sneel	}
314205675Sneel	bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
315205675Sneel	ch->fmt = format;
316205675Sneel	return 0;
317205675Sneel}
318205675Sneel
319205675Sneelstatic int
320205675Sneeleschan_setspeed(void *data, u_int32_t speed)
321205675Sneel{
322205675Sneel	struct es_chinfo *ch = data;
323205675Sneel	struct es_info *es = ch->parent;
324205675Sneel
325205675Sneel	es->ctrl &= ~CTRL_PCLKDIV;
326205675Sneel	es->ctrl |= DAC2_SRTODIV(speed) << CTRL_SH_PCLKDIV;
327205675Sneel	bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
328205675Sneel	/* rec/play speeds locked together - should indicate in flags */
329205675Sneel#if 0
330205675Sneel	if (ch->direction == PCMDIR_PLAY) d->rec[0].speed = speed;
331205675Sneel	else d->play[0].speed = speed;
332178172Simp#endif
333178172Simp	return speed; /* XXX calc real speed */
334178172Simp}
335178172Simp
336178172Simpstatic int
337178172Simpeschan_setblocksize(void *data, u_int32_t blocksize)
338178172Simp{
339178172Simp	return blocksize;
340178172Simp}
341178172Simp
342178172Simpstatic int
343178172Simpeschan_trigger(void *data, int go)
344178172Simp{
345178172Simp	struct es_chinfo *ch = data;
346178172Simp	struct es_info *es = ch->parent;
347178172Simp	unsigned cnt = ch->buffer->dl / ch->buffer->sample_size - 1;
348178172Simp
349178172Simp	if (ch->dir == PCMDIR_PLAY) {
350178172Simp		if (go == PCMTRIG_START) {
351178172Simp			int b = (ch->fmt & AFMT_S16_LE)? 2 : 1;
352178172Simp			es->ctrl |= CTRL_DAC2_EN;
353178172Simp			es->sctrl &= ~(SCTRL_P2ENDINC | SCTRL_P2STINC |
354178172Simp				       SCTRL_P2LOOPSEL | SCTRL_P2PAUSE |
355178172Simp				       SCTRL_P2DACSEN);
356178172Simp			es->sctrl |= SCTRL_P2INTEN | (b << SCTRL_SH_P2ENDINC);
357178172Simp			bus_space_write_4(es->st, es->sh,
358178172Simp					  ES1370_REG_DAC2_SCOUNT, cnt);
359178172Simp		} else es->ctrl &= ~CTRL_DAC2_EN;
360178172Simp	} else {
361178172Simp		if (go == PCMTRIG_START) {
362178172Simp			es->ctrl |= CTRL_ADC_EN;
363178172Simp			es->sctrl &= ~SCTRL_R1LOOPSEL;
364178172Simp			es->sctrl |= SCTRL_R1INTEN;
365178172Simp			bus_space_write_4(es->st, es->sh,
366178172Simp					  ES1370_REG_ADC_SCOUNT, cnt);
367178172Simp		} else es->ctrl &= ~CTRL_ADC_EN;
368178172Simp	}
369178172Simp	bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
370178172Simp	bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
371178172Simp	return 0;
372178172Simp}
373178172Simp
374178172Simpstatic int
375178172Simpeschan_getptr(void *data)
376178172Simp{
377178172Simp	struct es_chinfo *ch = data;
378178172Simp	struct es_info *es = ch->parent;
379178172Simp	if (ch->dir == PCMDIR_PLAY) {
380178172Simp		bus_space_write_4(es->st, es->sh, ES1370_REG_MEMPAGE,
381178172Simp				  ES1370_REG_DAC2_FRAMECNT >> 8);
382178172Simp		return (bus_space_read_4(es->st, es->sh,
383178172Simp				         ES1370_REG_DAC2_FRAMECNT & 0xff) >> 14) & 0x3fffc;
384178172Simp	} else {
385178172Simp		bus_space_write_4(es->st, es->sh, ES1370_REG_MEMPAGE,
386178172Simp				  ES1370_REG_ADC_FRAMECNT >> 8);
387178172Simp		return (bus_space_read_4(es->st, es->sh,
388178172Simp				         ES1370_REG_ADC_FRAMECNT & 0xff) >> 14) & 0x3fffc;
389178172Simp	}
390178172Simp}
391178172Simp
392178172Simpstatic pcmchan_caps *
393178172Simpeschan_getcaps(void *data)
394178172Simp{
395178172Simp	struct es_chinfo *ch = data;
396178172Simp	return (ch->dir == PCMDIR_PLAY)? &es_playcaps : &es_reccaps;
397178172Simp}
398178172Simp
399178172Simp/* The interrupt handler */
400178172Simpstatic void
401178172Simpes_intr (void *p)
402178172Simp{
403178172Simp	struct es_info *es = p;
404178172Simp	unsigned	intsrc, sctrl;
405178172Simp
406178172Simp	intsrc = bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS);
407178172Simp	if ((intsrc & STAT_INTR) == 0) return;
408178172Simp
409178172Simp	sctrl = es->sctrl;
410178172Simp	if (intsrc & STAT_ADC)  sctrl &= ~SCTRL_R1INTEN;
411178172Simp	if (intsrc & STAT_DAC1)	sctrl &= ~SCTRL_P1INTEN;
412178172Simp	if (intsrc & STAT_DAC2)	sctrl &= ~SCTRL_P2INTEN;
413178172Simp
414178172Simp	bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, sctrl);
415178172Simp	bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
416178172Simp
417178172Simp	if (intsrc & STAT_DAC2)	chn_intr(es->pch.channel);
418178172Simp	if (intsrc & STAT_ADC) chn_intr(es->rch.channel);
419178172Simp}
420178172Simp
421
422/* ES1371 specific code */
423
424#define CODEC_ID_SESHIFT	10
425#define CODEC_ID_SEMASK		0x1f
426
427#define CODEC_PIRD		0x00800000  /* 0 = write AC97 register */
428#define CODEC_PIADD_MASK	0x007f0000
429#define CODEC_PIADD_SHIFT	16
430#define CODEC_PIDAT_MASK	0x0000ffff
431#define CODEC_PIDAT_SHIFT	0
432
433#define CODEC_PORD		0x00800000  /* 0 = write AC97 register */
434#define CODEC_POADD_MASK	0x007f0000
435#define CODEC_POADD_SHIFT	16
436#define CODEC_PODAT_MASK	0x0000ffff
437#define CODEC_PODAT_SHIFT	0
438
439#define CODEC_RDY		0x80000000  /* AC97 read data valid */
440#define CODEC_WIP		0x40000000  /* AC97 write in progress */
441
442#define ES1370_REG_CONTROL	0x00
443#define ES1370_REG_SERIAL_CONTROL	0x20
444#define ES1371_REG_CODEC	0x14
445#define ES1371_REG_LEGACY	0x18	     /* W/R: Legacy control/status register */
446#define ES1371_REG_SMPRATE	0x10	     /* W/R: Codec rate converter interface register */
447
448#define ES1371_SYNC_RES		(1<<14)	 /* Warm AC97 reset */
449#define ES1371_DIS_R1		(1<<19)	 /* record channel accumulator update disable */
450#define ES1371_DIS_P2		(1<<20)	 /* playback channel 2 accumulator update disable */
451#define ES1371_DIS_P1		(1<<21)	 /* playback channel 1 accumulator update disable */
452#define ES1371_DIS_SRC		(1<<22)	 /* sample rate converter disable */
453#define ES1371_SRC_RAM_BUSY	(1<<23)	 /* R/O: sample rate memory is busy */
454#define ES1371_SRC_RAM_WE	(1<<24)	 /* R/W: read/write control for sample rate converter */
455#define ES1371_SRC_RAM_ADDRO(o) (((o)&0x7f)<<25)	/* address of the sample rate converter */
456#define ES1371_SRC_RAM_DATAO(o) (((o)&0xffff)<<0)	/* current value of the sample rate converter */
457#define ES1371_SRC_RAM_DATAI(i) (((i)>>0)&0xffff)	/* current value of the sample rate converter */
458
459/*
460 *  Sample rate converter addresses
461 */
462
463#define ES_SMPREG_DAC1		0x70
464#define ES_SMPREG_DAC2		0x74
465#define ES_SMPREG_ADC		0x78
466#define ES_SMPREG_TRUNC_N	0x00
467#define ES_SMPREG_INT_REGS	0x01
468#define ES_SMPREG_VFREQ_FRAC	0x03
469#define ES_SMPREG_VOL_ADC	0x6c
470#define ES_SMPREG_VOL_DAC1	0x7c
471#define ES_SMPREG_VOL_DAC2	0x7e
472
473
474int
475es1371_init(struct es_info *es)
476{
477	int idx;
478
479	if(debug > 0) printf("es_init\n");
480
481	es->ctrl = 0;
482	es->sctrl = 0;
483	/* initialize the chips */
484	bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
485	bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
486	bus_space_write_4(es->st, es->sh, ES1371_REG_LEGACY, 0);
487	/* AC'97 warm reset to start the bitclk */
488	bus_space_write_4(es->st, es->sh, ES1371_REG_LEGACY, es->ctrl | ES1371_SYNC_RES);
489	DELAY(2000);
490	bus_space_write_4(es->st, es->sh,  ES1370_REG_SERIAL_CONTROL,es->ctrl);
491	/* Init the sample rate converter */
492	bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE, ES1371_DIS_SRC);
493	for (idx = 0; idx < 0x80; idx++)
494	  es1371_src_write(es, idx, 0);
495	es1371_src_write(es, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N,  16 << 4);
496	es1371_src_write(es, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10);
497	es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N,  16 << 4);
498	es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10);
499	es1371_src_write(es, ES_SMPREG_VOL_ADC,                   1 << 12);
500	es1371_src_write(es, ES_SMPREG_VOL_ADC  + 1,              1 << 12);
501	es1371_src_write(es, ES_SMPREG_VOL_DAC1,                  1 << 12);
502	es1371_src_write(es, ES_SMPREG_VOL_DAC1 + 1,              1 << 12);
503	es1371_src_write(es, ES_SMPREG_VOL_DAC2,                  1 << 12);
504	es1371_src_write(es, ES_SMPREG_VOL_DAC2 + 1,              1 << 12);
505	es1371_adc_rate (es, 22050,                               1);
506	es1371_dac1_rate(es, 22050,                               1);
507	es1371_dac2_rate(es, 22050,                               1);
508	/* WARNING:
509	 * enabling the sample rate converter without properly programming
510	 * its parameters causes the chip to lock up (the SRC busy bit will
511	 * be stuck high, and I've found no way to rectify this other than
512	 * power cycle)
513	 */
514	bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE, 0);
515
516	return (0);
517}
518
519void
520es1371_wrcodec(void *s, int addr, u_int32_t data)
521{
522  /*	unsigned long flags; */
523    int sl;
524    unsigned t, x;
525	struct es_info *es = (struct es_info*)s;
526
527	if(debug > 0) printf("wrcodec addr 0x%x data 0x%x\n",addr,data);
528
529	for (t = 0; t < 0x1000; t++)
530	  if(!(bus_space_read_4(es->st, es->sh,(ES1371_REG_CODEC & CODEC_WIP))))
531			break;
532	sl = spltty();
533	/* save the current state for later */
534 	x =  bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE);
535	/* enable SRC state data in SRC mux */
536	bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE,
537	  (es1371_wait_src_ready(s) &
538	   (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1)));
539	/* wait for a SAFE time to write addr/data and then do it, dammit */
540	for (t = 0; t < 0x1000; t++)
541	  if (( bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE) & 0x00070000) == 0x00010000)
542		break;
543
544	if(debug > 2) printf("one b_s_w: 0x%x 0x%x 0x%x\n",es->sh,ES1371_REG_CODEC,
545			 ((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) |
546			 ((data << CODEC_PODAT_SHIFT) & CODEC_PODAT_MASK));
547
548	bus_space_write_4(es->st, es->sh,ES1371_REG_CODEC,
549			  ((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) |
550			  ((data << CODEC_PODAT_SHIFT) & CODEC_PODAT_MASK));
551	/* restore SRC reg */
552	es1371_wait_src_ready(s);
553	if(debug > 2) printf("two b_s_w: 0x%x 0x%x 0x%x\n",es->sh,ES1371_REG_SMPRATE,x);
554	bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,x);
555	splx(sl);
556}
557
558u_int32_t
559es1371_rdcodec(void *s, u_int32_t addr)
560{
561  /*  unsigned long flags; */
562  int sl;
563  unsigned t, x;
564
565  struct es_info *es = (struct es_info *)s;
566
567  if(debug > 0) printf("rdcodec addr 0x%x ... ",addr);
568
569  for (t = 0; t < 0x1000; t++)
570	if (!(x = bus_space_read_4(es->st,es->sh,ES1371_REG_CODEC) & CODEC_WIP))
571	  break;
572   if(debug >0) printf("loop 1 t 0x%x x 0x%x ",t,x);
573
574  sl = spltty();
575
576  /* save the current state for later */
577  x =  bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE);
578  /* enable SRC state data in SRC mux */
579  bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE,
580					(es1371_wait_src_ready(s) &
581					 (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1)));
582  /* wait for a SAFE time to write addr/data and then do it, dammit */
583  for (t = 0; t < 0x5000; t++)
584	if (( x = bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE) & 0x00070000) == 0x00010000)
585	  break;
586  if(debug >0) printf("loop 2 t 0x%x x 0x%x ",t,x);
587  bus_space_write_4(es->st, es->sh,ES1371_REG_CODEC,
588					((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | CODEC_PORD);
589
590  /* restore SRC reg */
591  es1371_wait_src_ready(s);
592  bus_space_write_4(es->st,es->sh,ES1371_REG_SMPRATE,x);
593
594  splx(sl);
595
596  /* now wait for the stinkin' data (RDY) */
597  for (t = 0; t < 0x1000; t++)
598	if ((x = bus_space_read_4(es->st,es->sh,ES1371_REG_CODEC)) & CODEC_RDY)
599	  break;
600  if(debug > 0) printf("loop 3 t 0x%x 0x%x ret 0x%x\n",t,x,((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT));
601  return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT);
602}
603
604
605
606
607static u_int
608es1371_src_read(es_info_t *es, u_short reg){
609
610  unsigned int r;
611
612  r = es1371_wait_src_ready(es) &
613	(ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1);
614  r |= ES1371_SRC_RAM_ADDRO(reg);
615  bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
616  return ES1371_SRC_RAM_DATAI(es1371_wait_src_ready(es));
617}
618
619static void
620es1371_src_write(es_info_t *es, u_short reg, u_short data){
621	u_int r;
622
623	r = es1371_wait_src_ready(es) &
624	    (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1);
625	r |= ES1371_SRC_RAM_ADDRO(reg) |  ES1371_SRC_RAM_DATAO(data);
626	/*	printf("es1371_src_write 0x%x 0x%x\n",ES1371_REG_SMPRATE,r | ES1371_SRC_RAM_WE); */
627	bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r | ES1371_SRC_RAM_WE);
628}
629
630static u_int
631es1371_adc_rate(es_info_t *es, u_int rate, int set){
632  u_int n, truncm, freq, result;
633
634  if (rate > 48000)
635	rate = 48000;
636  if (rate < 4000)
637	rate = 4000;
638  n = rate / 3000;
639  if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
640	n--;
641  truncm = (21 * n - 1) | 1;
642  freq = ((48000UL << 15) / rate) * n;
643  result = (48000UL << 15) / (freq / n);
644  if (set) {
645	if (rate >= 24000) {
646	  if (truncm > 239)
647		truncm = 239;
648	  es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
649				   (((239 - truncm) >> 1) << 9) | (n << 4));
650	} else {
651	  if (truncm > 119)
652		truncm = 119;
653	  es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
654			   0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));
655	}
656	es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_INT_REGS,
657		 (es1371_src_read(es, ES_SMPREG_ADC + ES_SMPREG_INT_REGS) &
658		  0x00ff) | ((freq >> 5) & 0xfc00));
659	es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
660	es1371_src_write(es, ES_SMPREG_VOL_ADC, n << 8);
661	es1371_src_write(es, ES_SMPREG_VOL_ADC + 1, n << 8);
662	}
663	return result;
664}
665
666static u_int
667es1371_dac1_rate(es_info_t *es, u_int rate, int set){
668  u_int freq, r, result;
669
670  if (rate > 48000)
671	rate = 48000;
672  if (rate < 4000)
673	rate = 4000;
674  freq = (rate << 15) / 3000;
675  result = (freq * 3000) >> 15;
676  if (set) {
677	r = (es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1));
678	bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
679	es1371_src_write(es, ES_SMPREG_DAC1 +
680			 ES_SMPREG_INT_REGS,
681			 (es1371_src_read(es,
682			  ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS) & 0x00ff) | ((freq >> 5) & 0xfc00));
683	es1371_src_write(es, ES_SMPREG_DAC1 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
684	r = (es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P2 | ES1371_DIS_R1));
685	bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
686  }
687  return result;
688}
689
690static u_int
691es1371_dac2_rate(es_info_t *es, u_int rate, int set){
692  u_int freq, r, result;
693
694  if (rate > 48000)
695	rate = 48000;
696  if (rate < 4000)
697	rate = 4000;
698  freq = (rate << 15) / 3000;
699  result = (freq * 3000) >> 15;
700  if (set) {
701	r = (es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1));
702	bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
703	/*	if(debug > 0) printf("dac2_rate 0x%x\n",bus_space_read_4(es->st, es->sh,ES1371_REG_SMPRATE)); */
704	es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS,
705				 (es1371_src_read(es, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS) &
706				  0x00ff) | ((freq >> 5) & 0xfc00));
707	es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
708	r = (es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_R1));
709	bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
710	/*	if(debug > 0) printf("dac2_rate 0x%x\n",bus_space_read_4(es->st, es->sh,ES1371_REG_SMPRATE)); */
711  }
712  return result;
713}
714
715
716static u_int
717es1371_wait_src_ready(es_info_t *es){
718  u_int t, r;
719
720  for (t = 0; t < 500; t++) {
721	if (!((r = bus_space_read_4(es->st, es->sh,ES1371_REG_SMPRATE)) & ES1371_SRC_RAM_BUSY)){
722	  return r;
723	}
724	DELAY(1000);
725  }
726  printf("es1371: wait source ready timeout 0x%x [0x%x]\n", ES1371_REG_SMPRATE, r);
727  return 0;
728}
729
730
731int
732eschan1371_setspeed(void *data, u_int32_t speed)
733{
734  struct es_chinfo *ch = data;
735  struct es_info *es = ch->parent;
736
737  /* rec/play speeds locked together - should indicate in flags */
738  es1371_dac2_rate(es, speed, 1); /* play */
739  es1371_adc_rate (es, speed, 1); /* record */
740
741  return speed; /* XXX calc real speed */
742}
743
744
745
746/* -------------------------------------------------------------------- */
747
748/*
749 * Probe and attach the card
750 */
751
752static int
753es_init(struct es_info *es)
754{
755	es->ctrl = CTRL_CDC_EN | CTRL_SERR_DIS |
756		(DAC2_SRTODIV(DSP_DEFAULT_SPEED) << CTRL_SH_PCLKDIV);
757	bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
758
759	es->sctrl = 0;
760	bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
761
762	write_codec(es, CODEC_RES_PD, 3);/* No RST, PD */
763	write_codec(es, CODEC_CSEL, 0);	/* CODEC ADC and CODEC DAC use
764					 * {LR,B}CLK2 and run off the LRCLK2
765					 * PLL; program DAC_SYNC=0!  */
766	write_codec(es, CODEC_ADSEL, 0);/* Recording source is mixer */
767	write_codec(es, CODEC_MGAIN, 0);/* MIC amp is 0db */
768
769	return 0;
770}
771
772static int
773es_pci_probe(device_t dev)
774{
775	if (pci_get_devid(dev) == ES1370_PCI_ID) {
776		device_set_desc(dev, "AudioPCI ES1370");
777		return 0;
778	} else if (pci_get_devid(dev) == ES1371_PCI_ID) {
779		device_set_desc(dev, "AudioPCI ES1371");
780		return 0;
781	}
782	return ENXIO;
783}
784
785static int
786es_pci_attach(device_t dev)
787{
788	snddev_info    *d;
789	u_int32_t	data;
790	struct es_info *es = 0;
791	int		type = 0;
792	int		regid;
793	struct resource *reg = 0;
794	int		mapped;
795	int		irqid;
796	struct resource *irq = 0;
797	void		*ih = 0;
798	char		status[SND_STATUSLEN];
799	struct ac97_info *codec;
800
801	d = device_get_softc(dev);
802	if ((es = malloc(sizeof *es, M_DEVBUF, M_NOWAIT)) == NULL) {
803		device_printf(dev, "cannot allocate softc\n");
804		return ENXIO;
805	}
806	bzero(es, sizeof *es);
807
808	mapped = 0;
809	data = pci_read_config(dev, PCIR_COMMAND, 2);
810	if (mapped == 0 && (data & PCIM_CMD_MEMEN)) {
811		regid = MEM_MAP_REG;
812		type = SYS_RES_MEMORY;
813		reg = bus_alloc_resource(dev, type, &regid,
814					 0, ~0, 1, RF_ACTIVE);
815		if (reg) {
816			es->st = rman_get_bustag(reg);
817			es->sh = rman_get_bushandle(reg);
818			mapped++;
819		}
820	}
821	if (mapped == 0 && (data & PCIM_CMD_PORTEN)) {
822		regid = PCI_MAP_REG_START;
823		type = SYS_RES_IOPORT;
824		reg = bus_alloc_resource(dev, type, &regid,
825					 0, ~0, 1, RF_ACTIVE);
826		if (reg) {
827			es->st = rman_get_bustag(reg);
828			es->sh = rman_get_bushandle(reg);
829			mapped++;
830		}
831	}
832	if (mapped == 0) {
833		device_printf(dev, "unable to map register space\n");
834		goto bad;
835	}
836
837	if (pci_get_devid(dev) == ES1371_PCI_ID) {
838	  if(-1 == es1371_init(es)){
839		device_printf(dev, "unable to initialize the card\n");
840		goto bad;
841	  }
842	  codec = ac97_create(es,(ac97_read *)es1371_rdcodec,(ac97_write *)es1371_wrcodec);
843	  if (codec == NULL) goto bad;
844	  /* our init routine does everything for us */
845	  /* set to NULL; flag mixer_init not to run the ac97_init */
846	  /*	  ac97_mixer.init = NULL;  */
847	  mixer_init(d, &ac97_mixer, codec);
848	  /* change the routine for setting speed */
849	  es_chantemplate.setspeed = eschan1371_setspeed;
850	} else  if (pci_get_devid(dev) == ES1370_PCI_ID) {
851	  if (-1 == es_init(es)){
852		device_printf(dev, "unable to initialize the card\n");
853		goto bad;
854	  }
855	  mixer_init(d, &es_mixer, es);
856	}
857
858
859	irqid = 0;
860	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &irqid,
861				 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
862	if (!irq
863	    || bus_setup_intr(dev, irq, INTR_TYPE_TTY, es_intr, es, &ih)) {
864		device_printf(dev, "unable to map interrupt\n");
865		goto bad;
866	}
867
868	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
869		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
870		/*highaddr*/BUS_SPACE_MAXADDR,
871		/*filter*/NULL, /*filterarg*/NULL,
872		/*maxsize*/ES_BUFFSIZE, /*nsegments*/1, /*maxsegz*/0x3ffff,
873		/*flags*/0, &es->parent_dmat) != 0) {
874		device_printf(dev, "unable to create dma tag\n");
875		goto bad;
876	}
877
878	snprintf(status, SND_STATUSLEN, "at %s 0x%lx irq %ld",
879		 (type == SYS_RES_IOPORT)? "io" : "memory",
880		 rman_get_start(reg), rman_get_start(irq));
881
882	if (pcm_register(dev, es, 1, 1)) goto bad;
883	pcm_addchan(dev, PCMDIR_REC, &es_chantemplate, es);
884	pcm_addchan(dev, PCMDIR_PLAY, &es_chantemplate, es);
885	pcm_setstatus(dev, status);
886
887	return 0;
888
889 bad:
890	if (es) free(es, M_DEVBUF);
891	if (reg) bus_release_resource(dev, type, regid, reg);
892	if (ih) bus_teardown_intr(dev, irq, ih);
893	if (irq) bus_release_resource(dev, SYS_RES_IRQ, irqid, irq);
894	return ENXIO;
895}
896
897static device_method_t es_methods[] = {
898	/* Device interface */
899	DEVMETHOD(device_probe,		es_pci_probe),
900	DEVMETHOD(device_attach,	es_pci_attach),
901
902	{ 0, 0 }
903};
904
905static driver_t es_driver = {
906	"pcm",
907	es_methods,
908	sizeof(snddev_info),
909};
910
911static devclass_t pcm_devclass;
912
913DRIVER_MODULE(es, pci, es_driver, pcm_devclass, 0, 0);
914
915
916#endif /* NPCI != 0 */
917