ich.c revision 82478
1/*
2 * Copyright (c) 2000 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp>
3 * Copyright (c) 2001 Cameron Grant <cg@freebsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <dev/sound/pcm/sound.h>
29#include <dev/sound/pcm/ac97.h>
30#include <dev/sound/pci/ich.h>
31
32#include <pci/pcireg.h>
33#include <pci/pcivar.h>
34
35SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/ich.c 82478 2001-08-29 02:31:03Z cg $");
36
37/* -------------------------------------------------------------------- */
38
39#define ICH_TIMEOUT 1000 /* semaphore timeout polling count */
40#define ICH_DTBL_LENGTH 32
41#define ICH_DEFAULT_BUFSZ 16384
42
43/* buffer descriptor */
44struct ich_desc {
45	volatile u_int32_t buffer;
46	volatile u_int32_t length;
47};
48
49struct sc_info;
50
51/* channel registers */
52struct sc_chinfo {
53	u_int32_t num, run;
54	u_int32_t blksz, blkcnt;
55	u_int32_t regbase, spdreg;
56	u_int32_t civ;
57
58	struct snd_dbuf *buffer;
59	struct pcm_channel *channel;
60	struct sc_info *parent;
61
62	struct ich_desc *dtbl;
63};
64
65/* device private data */
66struct sc_info {
67	device_t dev;
68	int hasvra, hasvrm;
69	int chnum;
70
71	struct resource *nambar, *nabmbar, *irq;
72	int nambarid, nabmbarid, irqid;
73	bus_space_tag_t nambart, nabmbart;
74	bus_space_handle_t nambarh, nabmbarh;
75	bus_dma_tag_t dmat;
76	bus_dmamap_t dtmap;
77	void *ih;
78
79	struct ac97_info *codec;
80	struct sc_chinfo ch[3];
81	struct ich_desc *dtbl;
82};
83
84/* -------------------------------------------------------------------- */
85
86static u_int32_t ich_fmt[] = {
87	AFMT_STEREO | AFMT_S16_LE,
88	0
89};
90static struct pcmchan_caps ich_vrcaps = {8000, 48000, ich_fmt, 0};
91static struct pcmchan_caps ich_caps = {48000, 48000, ich_fmt, 0};
92
93/* -------------------------------------------------------------------- */
94/* Hardware */
95static u_int32_t
96ich_rd(struct sc_info *sc, int regno, int size)
97{
98	switch (size) {
99	case 1:
100		return bus_space_read_1(sc->nabmbart, sc->nabmbarh, regno);
101	case 2:
102		return bus_space_read_2(sc->nabmbart, sc->nabmbarh, regno);
103	case 4:
104		return bus_space_read_4(sc->nabmbart, sc->nabmbarh, regno);
105	default:
106		return 0xffffffff;
107	}
108}
109
110static void
111ich_wr(struct sc_info *sc, int regno, u_int32_t data, int size)
112{
113	switch (size) {
114	case 1:
115		bus_space_write_1(sc->nabmbart, sc->nabmbarh, regno, data);
116		break;
117	case 2:
118		bus_space_write_2(sc->nabmbart, sc->nabmbarh, regno, data);
119		break;
120	case 4:
121		bus_space_write_4(sc->nabmbart, sc->nabmbarh, regno, data);
122		break;
123	}
124}
125
126/* ac97 codec */
127static int
128ich_waitcd(void *devinfo)
129{
130	int i;
131	u_int32_t data;
132	struct sc_info *sc = (struct sc_info *)devinfo;
133
134	for (i = 0; i < ICH_TIMEOUT; i++) {
135		data = ich_rd(sc, ICH_REG_ACC_SEMA, 1);
136		if ((data & 0x01) == 0)
137			return 0;
138	}
139	device_printf(sc->dev, "CODEC semaphore timeout\n");
140	return ETIMEDOUT;
141}
142
143static int
144ich_rdcd(kobj_t obj, void *devinfo, int regno)
145{
146	struct sc_info *sc = (struct sc_info *)devinfo;
147
148	regno &= 0xff;
149	ich_waitcd(sc);
150
151	return bus_space_read_2(sc->nambart, sc->nambarh, regno);
152}
153
154static int
155ich_wrcd(kobj_t obj, void *devinfo, int regno, u_int16_t data)
156{
157	struct sc_info *sc = (struct sc_info *)devinfo;
158
159	regno &= 0xff;
160	ich_waitcd(sc);
161	bus_space_write_2(sc->nambart, sc->nambarh, regno, data);
162
163	return 0;
164}
165
166static kobj_method_t ich_ac97_methods[] = {
167	KOBJMETHOD(ac97_read,		ich_rdcd),
168	KOBJMETHOD(ac97_write,		ich_wrcd),
169	{ 0, 0 }
170};
171AC97_DECLARE(ich_ac97);
172
173/* -------------------------------------------------------------------- */
174/* common routines */
175
176static void
177ich_filldtbl(struct sc_chinfo *ch)
178{
179	u_int32_t base;
180	int i;
181
182	base = vtophys(sndbuf_getbuf(ch->buffer));
183	ch->blkcnt = sndbuf_getsize(ch->buffer) / ch->blksz;
184	if (ch->blkcnt != 2 && ch->blkcnt != 4 && ch->blkcnt != 8 && ch->blkcnt != 16 && ch->blkcnt != 32) {
185		ch->blkcnt = 2;
186		ch->blksz = sndbuf_getsize(ch->buffer) / ch->blkcnt;
187	}
188
189	for (i = 0; i < ICH_DTBL_LENGTH; i++) {
190		ch->dtbl[i].buffer = base + (ch->blksz * (i % ch->blkcnt));
191		ch->dtbl[i].length = ICH_BDC_IOC | (ch->blksz / 2);
192	}
193}
194
195static int
196ich_resetchan(struct sc_info *sc, int num)
197{
198	int i, cr, regbase;
199
200	if (num == 0)
201		regbase = ICH_REG_PO_BASE;
202	else if (num == 1)
203		regbase = ICH_REG_PI_BASE;
204	else if (num == 2)
205		regbase = ICH_REG_MC_BASE;
206	else
207		return ENXIO;
208
209	ich_wr(sc, regbase + ICH_REG_X_CR, 0, 1);
210	DELAY(100);
211	ich_wr(sc, regbase + ICH_REG_X_CR, ICH_X_CR_RR, 1);
212	for (i = 0; i < ICH_TIMEOUT; i++) {
213		cr = ich_rd(sc, regbase + ICH_REG_X_CR, 1);
214		if (cr == 0)
215			return 0;
216	}
217
218	device_printf(sc->dev, "cannot reset channel %d\n", num);
219	return ENXIO;
220}
221
222/* -------------------------------------------------------------------- */
223/* channel interface */
224
225static void *
226ichchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
227{
228	struct sc_info *sc = devinfo;
229	struct sc_chinfo *ch;
230	int num;
231
232	num = sc->chnum++;
233	ch = &sc->ch[num];
234	ch->num = num;
235	ch->buffer = b;
236	ch->channel = c;
237	ch->parent = sc;
238	ch->run = 0;
239	ch->dtbl = sc->dtbl + (ch->num * ICH_DTBL_LENGTH);
240	ch->blkcnt = 2;
241	ch->blksz = ICH_DEFAULT_BUFSZ / ch->blkcnt;
242
243	switch(ch->num) {
244	case 0: /* play */
245		KASSERT(dir == PCMDIR_PLAY, ("wrong direction"));
246		ch->regbase = ICH_REG_PO_BASE;
247		ch->spdreg = sc->hasvra? AC97_REGEXT_FDACRATE : 0;
248		break;
249
250	case 1: /* record */
251		KASSERT(dir == PCMDIR_REC, ("wrong direction"));
252		ch->regbase = ICH_REG_PI_BASE;
253		ch->spdreg = sc->hasvra? AC97_REGEXT_LADCRATE : 0;
254		break;
255
256	case 2: /* mic */
257		KASSERT(dir == PCMDIR_REC, ("wrong direction"));
258		ch->regbase = ICH_REG_MC_BASE;
259		ch->spdreg = sc->hasvrm? AC97_REGEXT_MADCRATE : 0;
260		break;
261
262	default:
263		return NULL;
264	}
265
266	if (sndbuf_alloc(ch->buffer, sc->dmat, ICH_DEFAULT_BUFSZ))
267		return NULL;
268
269	ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4);
270
271	return ch;
272}
273
274static int
275ichchan_setformat(kobj_t obj, void *data, u_int32_t format)
276{
277	return 0;
278}
279
280static int
281ichchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
282{
283	struct sc_chinfo *ch = data;
284	struct sc_info *sc = ch->parent;
285
286	if (ch->spdreg)
287		return ac97_setrate(sc->codec, ch->spdreg, speed);
288	else
289		return 48000;
290}
291
292static int
293ichchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
294{
295	struct sc_chinfo *ch = data;
296	struct sc_info *sc = ch->parent;
297
298	ch->blksz = blocksize;
299	ich_filldtbl(ch);
300	ich_wr(sc, ch->regbase + ICH_REG_X_LVI, ch->blkcnt - 1, 1);
301
302	return ch->blksz;
303}
304
305static int
306ichchan_trigger(kobj_t obj, void *data, int go)
307{
308	struct sc_chinfo *ch = data;
309	struct sc_info *sc = ch->parent;
310
311	switch (go) {
312	case PCMTRIG_START:
313		ch->run = 1;
314		ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4);
315		ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE, 1);
316		break;
317
318	case PCMTRIG_ABORT:
319		ich_resetchan(sc, ch->num);
320		ch->run = 0;
321		break;
322	}
323	return 0;
324}
325
326static int
327ichchan_getptr(kobj_t obj, void *data)
328{
329	struct sc_chinfo *ch = data;
330	struct sc_info *sc = ch->parent;
331      	u_int32_t pos;
332
333	ch->civ = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1) % ch->blkcnt;
334
335	pos = ch->civ * ch->blksz;
336
337	return pos;
338}
339
340static struct pcmchan_caps *
341ichchan_getcaps(kobj_t obj, void *data)
342{
343	struct sc_chinfo *ch = data;
344
345	return ch->spdreg? &ich_vrcaps : &ich_caps;
346}
347
348static kobj_method_t ichchan_methods[] = {
349	KOBJMETHOD(channel_init,		ichchan_init),
350	KOBJMETHOD(channel_setformat,		ichchan_setformat),
351	KOBJMETHOD(channel_setspeed,		ichchan_setspeed),
352	KOBJMETHOD(channel_setblocksize,	ichchan_setblocksize),
353	KOBJMETHOD(channel_trigger,		ichchan_trigger),
354	KOBJMETHOD(channel_getptr,		ichchan_getptr),
355	KOBJMETHOD(channel_getcaps,		ichchan_getcaps),
356	{ 0, 0 }
357};
358CHANNEL_DECLARE(ichchan);
359
360/* -------------------------------------------------------------------- */
361/* The interrupt handler */
362
363static void
364ich_intr(void *p)
365{
366	struct sc_info *sc = (struct sc_info *)p;
367	struct sc_chinfo *ch;
368	u_int32_t cbi, lbi, lvi, st;
369	int i;
370
371	for (i = 0; i < 3; i++) {
372		ch = &sc->ch[i];
373		/* check channel status */
374		st = ich_rd(sc, ch->regbase + ICH_REG_X_SR, 2);
375		st &= ICH_X_SR_FIFOE | ICH_X_SR_BCIS | ICH_X_SR_LVBCI;
376		if (st != 0) {
377			if (st & (ICH_X_SR_BCIS | ICH_X_SR_LVBCI)) {
378				/* block complete - update buffer */
379				if (ch->run)
380					chn_intr(ch->channel);
381				lvi = ich_rd(sc, ch->regbase + ICH_REG_X_LVI, 1);
382				cbi = ch->civ % ch->blkcnt;
383				if (cbi == 0)
384					cbi = ch->blkcnt - 1;
385				else
386					cbi--;
387				lbi = lvi % ch->blkcnt;
388				if (cbi >= lbi)
389					lvi += cbi - lbi;
390				else
391					lvi += cbi + ch->blkcnt - lbi;
392				lvi %= ICH_DTBL_LENGTH;
393				ich_wr(sc, ch->regbase + ICH_REG_X_LVI, lvi, 1);
394			}
395			/* clear status bit */
396			ich_wr(sc, ch->regbase + ICH_REG_X_SR, st, 2);
397		}
398	}
399}
400
401/* -------------------------------------------------------------------- */
402/* Probe and attach the card */
403
404static void
405ich_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
406{
407	return;
408}
409
410static int
411ich_init(struct sc_info *sc)
412{
413	u_int32_t stat;
414	int sz;
415
416	ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD, 4);
417	DELAY(600000);
418	stat = ich_rd(sc, ICH_REG_GLOB_STA, 4);
419
420	if ((stat & ICH_GLOB_STA_PCR) == 0)
421		return ENXIO;
422
423	ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD | ICH_GLOB_CTL_PRES, 4);
424
425	if (ich_resetchan(sc, 0) || ich_resetchan(sc, 1) || ich_resetchan(sc, 2))
426		return ENXIO;
427
428	if (bus_dmamem_alloc(sc->dmat, (void **)&sc->dtbl, BUS_DMA_NOWAIT, &sc->dtmap))
429		return ENOSPC;
430
431	sz = sizeof(struct ich_desc) * ICH_DTBL_LENGTH * 3;
432	if (bus_dmamap_load(sc->dmat, sc->dtmap, sc->dtbl, sz, ich_setmap, NULL, 0)) {
433		bus_dmamem_free(sc->dmat, (void **)&sc->dtbl, sc->dtmap);
434		return ENOSPC;
435	}
436
437	return 0;
438}
439
440static int
441ich_pci_probe(device_t dev)
442{
443	switch(pci_get_devid(dev)) {
444	case 0x71958086:
445		device_set_desc(dev, "Intel 443MX");
446		return 0;
447
448	case 0x24158086:
449		device_set_desc(dev, "Intel 82801AA (ICH)");
450		return 0;
451
452	case 0x24258086:
453		device_set_desc(dev, "Intel 82901AB (ICH)");
454		return 0;
455
456	case 0x24458086:
457		device_set_desc(dev, "Intel 82801BA (ICH2)");
458		return 0;
459
460	default:
461		return ENXIO;
462	}
463}
464
465static int
466ich_pci_attach(device_t dev)
467{
468	u_int32_t		data;
469	struct sc_info 		*sc;
470	char 			status[SND_STATUSLEN];
471
472	if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) {
473		device_printf(dev, "cannot allocate softc\n");
474		return ENXIO;
475	}
476
477	bzero(sc, sizeof(*sc));
478	sc->dev = dev;
479
480	data = pci_read_config(dev, PCIR_COMMAND, 2);
481	data |= (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
482	pci_write_config(dev, PCIR_COMMAND, data, 2);
483	data = pci_read_config(dev, PCIR_COMMAND, 2);
484
485	sc->nambarid = PCIR_NAMBAR;
486	sc->nabmbarid = PCIR_NABMBAR;
487	sc->nambar = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->nambarid, 0, ~0, 1, RF_ACTIVE);
488	sc->nabmbar = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->nabmbarid, 0, ~0, 1, RF_ACTIVE);
489
490	if (!sc->nambar || !sc->nabmbar) {
491		device_printf(dev, "unable to map IO port space\n");
492		goto bad;
493	}
494
495	sc->nambart = rman_get_bustag(sc->nambar);
496	sc->nambarh = rman_get_bushandle(sc->nambar);
497	sc->nabmbart = rman_get_bustag(sc->nabmbar);
498	sc->nabmbarh = rman_get_bushandle(sc->nabmbar);
499
500	if (bus_dma_tag_create(NULL, 8, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
501			       NULL, NULL, ICH_DEFAULT_BUFSZ, 1, 0x3ffff, 0, &sc->dmat) != 0) {
502		device_printf(dev, "unable to create dma tag\n");
503		goto bad;
504	}
505
506	if (ich_init(sc)) {
507		device_printf(dev, "unable to initialize the card\n");
508		goto bad;
509	}
510
511	sc->codec = AC97_CREATE(dev, sc, ich_ac97);
512	if (sc->codec == NULL)
513		goto bad;
514	mixer_init(dev, ac97_getmixerclass(), sc->codec);
515
516	/* check and set VRA function */
517	if (ac97_setextmode(sc->codec, AC97_EXTCAP_VRA) == 0)
518		sc->hasvra = 1;
519	if (ac97_setextmode(sc->codec, AC97_EXTCAP_VRM) == 0)
520		sc->hasvrm = 1;
521
522	sc->irqid = 0;
523	sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
524	if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ich_intr, sc, &sc->ih)) {
525		device_printf(dev, "unable to map interrupt\n");
526		goto bad;
527	}
528
529	if (pcm_register(dev, sc, 1, 2))
530		goto bad;
531
532	pcm_addchan(dev, PCMDIR_PLAY, &ichchan_class, sc);
533	pcm_addchan(dev, PCMDIR_REC, &ichchan_class, sc);
534	pcm_addchan(dev, PCMDIR_REC, &ichchan_class, sc);
535
536	snprintf(status, SND_STATUSLEN, "at io 0x%lx, 0x%lx irq %ld",
537		 rman_get_start(sc->nambar), rman_get_start(sc->nabmbar), rman_get_start(sc->irq));
538
539	pcm_setstatus(dev, status);
540
541	return 0;
542
543bad:
544	if (sc->codec)
545		ac97_destroy(sc->codec);
546	if (sc->nambar)
547		bus_release_resource(dev, SYS_RES_IOPORT,
548		    sc->nambarid, sc->nambar);
549	if (sc->nabmbar)
550		bus_release_resource(dev, SYS_RES_IOPORT,
551		    sc->nabmbarid, sc->nabmbar);
552	if (sc->ih)
553		bus_teardown_intr(dev, sc->irq, sc->ih);
554	if (sc->irq)
555		bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
556	free(sc, M_DEVBUF);
557	return ENXIO;
558}
559
560static int
561ich_pci_detach(device_t dev)
562{
563	struct sc_info *sc;
564	int r;
565
566	r = pcm_unregister(dev);
567	if (r)
568		return r;
569	sc = pcm_getdevinfo(dev);
570
571	bus_teardown_intr(dev, sc->irq, sc->ih);
572	bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
573	bus_release_resource(dev, SYS_RES_IOPORT, sc->nambarid, sc->nambar);
574	bus_release_resource(dev, SYS_RES_IOPORT, sc->nabmbarid, sc->nabmbar);
575	bus_dma_tag_destroy(sc->dmat);
576	free(sc, M_DEVBUF);
577	return 0;
578}
579
580static int
581ich_pci_resume(device_t dev)
582{
583	struct sc_info *sc;
584
585	sc = pcm_getdevinfo(dev);
586
587	/* Reinit audio device */
588    	if (ich_init(sc) == -1) {
589		device_printf(dev, "unable to reinitialize the card\n");
590		return ENXIO;
591	}
592	/* Reinit mixer */
593    	if (mixer_reinit(dev) == -1) {
594		device_printf(dev, "unable to reinitialize the mixer\n");
595		return ENXIO;
596	}
597	return 0;
598}
599
600static device_method_t ich_methods[] = {
601	/* Device interface */
602	DEVMETHOD(device_probe,		ich_pci_probe),
603	DEVMETHOD(device_attach,	ich_pci_attach),
604	DEVMETHOD(device_detach,	ich_pci_detach),
605	DEVMETHOD(device_resume,	ich_pci_resume),
606	{ 0, 0 }
607};
608
609static driver_t ich_driver = {
610	"pcm",
611	ich_methods,
612	PCM_SOFTC_SIZE,
613};
614
615DRIVER_MODULE(snd_ich, pci, ich_driver, pcm_devclass, 0, 0);
616MODULE_DEPEND(snd_ich, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
617MODULE_VERSION(snd_ich, 1);
618