cmi.c revision 128513
160484Sobrien/*
260484Sobrien * Copyright (c) 2000 Orion Hodson <O.Hodson@cs.ucl.ac.uk>
360484Sobrien * All rights reserved.
460484Sobrien *
560484Sobrien * Redistribution and use in source and binary forms, with or without
660484Sobrien * modification, are permitted provided that the following conditions
760484Sobrien * are met:
860484Sobrien * 1. Redistributions of source code must retain the above copyright
960484Sobrien *    notice, this list of conditions and the following disclaimer.
1060484Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1160484Sobrien *    notice, this list of conditions and the following disclaimer in the
1260484Sobrien *    documentation and/or other materials provided with the distribution.
1360484Sobrien *
1460484Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1560484Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1660484Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1760484Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1860484Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1960484Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2060484Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2160484Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT
2260484Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2360484Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF
2460484Sobrien * SUCH DAMAGE.
2560484Sobrien *
2660484Sobrien * This driver exists largely as a result of other people's efforts.
27130561Sobrien * Much of register handling is based on NetBSD CMI8x38 audio driver
28130561Sobrien * by Takuya Shiozaki <AoiMoe@imou.to>.  Chen-Li Tien
2960484Sobrien * <cltien@cmedia.com.tw> clarified points regarding the DMA related
3060484Sobrien * registers and the 8738 mixer devices.  His Linux driver was also a
3160484Sobrien * useful reference point.
3260484Sobrien *
3360484Sobrien * TODO: MIDI
3460484Sobrien *
3560484Sobrien * SPDIF contributed by Gerhard Gonter <gonter@whisky.wu-wien.ac.at>.
3660484Sobrien *
3760484Sobrien * This card/code does not always manage to sample at 44100 - actual
3860484Sobrien * rate drifts slightly between recordings (usually 0-3%).  No
3960484Sobrien * differences visible in register dumps between times that work and
4060484Sobrien * those that don't.
4160484Sobrien */
4260484Sobrien
4360484Sobrien#include <dev/sound/pcm/sound.h>
4460484Sobrien#include <dev/sound/pci/cmireg.h>
4560484Sobrien#include <dev/sound/isa/sb.h>
4660484Sobrien
4760484Sobrien#include <dev/pci/pcireg.h>
4860484Sobrien#include <dev/pci/pcivar.h>
4960484Sobrien
5060484Sobrien#include <sys/sysctl.h>
5160484Sobrien
5260484Sobrien#include "mixer_if.h"
5360484Sobrien
5460484SobrienSND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/cmi.c 128513 2004-04-21 04:23:51Z green $");
5560484Sobrien
5660484Sobrien/* Supported chip ID's */
5760484Sobrien#define CMI8338A_PCI_ID   0x010013f6
5860484Sobrien#define CMI8338B_PCI_ID   0x010113f6
5960484Sobrien#define CMI8738_PCI_ID    0x011113f6
6060484Sobrien#define CMI8738B_PCI_ID   0x011213f6
6160484Sobrien
6260484Sobrien/* Buffer size max is 64k for permitted DMA boundaries */
6360484Sobrien#define CMI_DEFAULT_BUFSZ      16384
6460484Sobrien
6560484Sobrien/* Interrupts per length of buffer */
6660484Sobrien#define CMI_INTR_PER_BUFFER      2
6760484Sobrien
6860484Sobrien/* Clarify meaning of named defines in cmireg.h */
6960484Sobrien#define CMPCI_REG_DMA0_MAX_SAMPLES  CMPCI_REG_DMA0_BYTES
7060484Sobrien#define CMPCI_REG_DMA0_INTR_SAMPLES CMPCI_REG_DMA0_SAMPLES
7160484Sobrien#define CMPCI_REG_DMA1_MAX_SAMPLES  CMPCI_REG_DMA1_BYTES
7260484Sobrien#define CMPCI_REG_DMA1_INTR_SAMPLES CMPCI_REG_DMA1_SAMPLES
7360484Sobrien
7460484Sobrien/* Our indication of custom mixer control */
7560484Sobrien#define CMPCI_NON_SB16_CONTROL		0xff
7660484Sobrien
7760484Sobrien/* Debugging macro's */
7860484Sobrien#undef DEB
7960484Sobrien#ifndef DEB
8060484Sobrien#define DEB(x) /* x */
8160484Sobrien#endif /* DEB */
8260484Sobrien
8360484Sobrien#ifndef DEBMIX
8460484Sobrien#define DEBMIX(x) /* x */
8560484Sobrien#endif  /* DEBMIX */
8660484Sobrien
8760484Sobrien/* ------------------------------------------------------------------------- */
8860484Sobrien/* Structures */
8960484Sobrien
9060484Sobrienstruct sc_info;
9160484Sobrien
9260484Sobrienstruct sc_chinfo {
9360484Sobrien	struct sc_info		*parent;
9460484Sobrien	struct pcm_channel	*channel;
9560484Sobrien	struct snd_dbuf		*buffer;
9660484Sobrien	u_int32_t		fmt, spd, phys_buf, bps;
9760484Sobrien	u_int32_t		dma_active:1, dma_was_active:1;
9860484Sobrien	int			dir;
9960484Sobrien};
10060484Sobrien
10160484Sobrienstruct sc_info {
10260484Sobrien	device_t		dev;
10360484Sobrien
10460484Sobrien	bus_space_tag_t		st;
10560484Sobrien	bus_space_handle_t	sh;
10660484Sobrien	bus_dma_tag_t		parent_dmat;
10760484Sobrien	struct resource		*reg, *irq;
10860484Sobrien	int			regid, irqid;
10960484Sobrien	void 			*ih;
11060484Sobrien	struct mtx		*lock;
11160484Sobrien
11260484Sobrien	int			spdif_enabled;
11360484Sobrien	unsigned int		bufsz;
11460484Sobrien	struct sc_chinfo 	pch, rch;
11560484Sobrien};
116130561Sobrien
11760484Sobrien/* Channel caps */
118130561Sobrien
11960484Sobrienstatic u_int32_t cmi_fmt[] = {
12060484Sobrien	AFMT_U8,
12160484Sobrien	AFMT_STEREO | AFMT_U8,
12260484Sobrien	AFMT_S16_LE,
12360484Sobrien	AFMT_STEREO | AFMT_S16_LE,
12460484Sobrien	0
12560484Sobrien};
12660484Sobrien
12760484Sobrienstatic struct pcmchan_caps cmi_caps = {5512, 48000, cmi_fmt, 0};
128130561Sobrien
12960484Sobrien/* ------------------------------------------------------------------------- */
13060484Sobrien/* Register Utilities */
13160484Sobrien
13260484Sobrienstatic u_int32_t
13360484Sobriencmi_rd(struct sc_info *sc, int regno, int size)
13460484Sobrien{
13560484Sobrien	switch (size) {
13660484Sobrien	case 1:
13760484Sobrien		return bus_space_read_1(sc->st, sc->sh, regno);
13860484Sobrien	case 2:
13960484Sobrien		return bus_space_read_2(sc->st, sc->sh, regno);
14060484Sobrien	case 4:
14160484Sobrien		return bus_space_read_4(sc->st, sc->sh, regno);
14260484Sobrien	default:
14360484Sobrien		DEB(printf("cmi_rd: failed 0x%04x %d\n", regno, size));
14460484Sobrien		return 0xFFFFFFFF;
14560484Sobrien	}
14660484Sobrien}
14760484Sobrien
14860484Sobrienstatic void
14960484Sobriencmi_wr(struct sc_info *sc, int regno, u_int32_t data, int size)
15060484Sobrien{
15160484Sobrien	switch (size) {
15260484Sobrien	case 1:
15360484Sobrien		bus_space_write_1(sc->st, sc->sh, regno, data);
15460484Sobrien		break;
15560484Sobrien	case 2:
15660484Sobrien		bus_space_write_2(sc->st, sc->sh, regno, data);
15760484Sobrien		break;
158130561Sobrien	case 4:
15960484Sobrien		bus_space_write_4(sc->st, sc->sh, regno, data);
160130561Sobrien		break;
16160484Sobrien	}
16260484Sobrien}
163130561Sobrien
16460484Sobrienstatic void
16560484Sobriencmi_partial_wr4(struct sc_info *sc,
16660484Sobrien		int reg, int shift, u_int32_t mask, u_int32_t val)
16760484Sobrien{
16860484Sobrien	u_int32_t r;
16960484Sobrien
17060484Sobrien	r = cmi_rd(sc, reg, 4);
17160484Sobrien	r &= ~(mask << shift);
17260484Sobrien	r |= val << shift;
17360484Sobrien	cmi_wr(sc, reg, r, 4);
17460484Sobrien}
17560484Sobrien
176130561Sobrienstatic void
177130561Sobriencmi_clr4(struct sc_info *sc, int reg, u_int32_t mask)
178130561Sobrien{
179130561Sobrien	u_int32_t r;
18060484Sobrien
181130561Sobrien	r = cmi_rd(sc, reg, 4);
18260484Sobrien	r &= ~mask;
18360484Sobrien	cmi_wr(sc, reg, r, 4);
18460484Sobrien}
18560484Sobrien
18660484Sobrienstatic void
18760484Sobriencmi_set4(struct sc_info *sc, int reg, u_int32_t mask)
18860484Sobrien{
18960484Sobrien	u_int32_t r;
19060484Sobrien
19160484Sobrien	r = cmi_rd(sc, reg, 4);
19260484Sobrien	r |= mask;
19360484Sobrien	cmi_wr(sc, reg, r, 4);
19460484Sobrien}
19560484Sobrien
19660484Sobrien/* ------------------------------------------------------------------------- */
19760484Sobrien/* Rate Mapping */
19860484Sobrien
19960484Sobrienstatic int cmi_rates[] = {5512, 8000, 11025, 16000,
20060484Sobrien			  22050, 32000, 44100, 48000};
20160484Sobrien#define NUM_CMI_RATES (sizeof(cmi_rates)/sizeof(cmi_rates[0]))
20260484Sobrien
20360484Sobrien/* cmpci_rate_to_regvalue returns sampling freq selector for FCR1
20460484Sobrien * register - reg order is 5k,11k,22k,44k,8k,16k,32k,48k */
20560484Sobrien
20660484Sobrienstatic u_int32_t
20760484Sobriencmpci_rate_to_regvalue(int rate)
20860484Sobrien{
20960484Sobrien	int i, r;
21060484Sobrien
21160484Sobrien	for(i = 0; i < NUM_CMI_RATES - 1; i++) {
21260484Sobrien		if (rate < ((cmi_rates[i] + cmi_rates[i + 1]) / 2)) {
21360484Sobrien			break;
21460484Sobrien		}
21560484Sobrien	}
21660484Sobrien
21760484Sobrien	DEB(printf("cmpci_rate_to_regvalue: %d -> %d\n", rate, cmi_rates[i]));
21860484Sobrien
21960484Sobrien	r = ((i >> 1) | (i << 2)) & 0x07;
22060484Sobrien	return r;
22160484Sobrien}
22260484Sobrien
22360484Sobrienstatic int
22460484Sobriencmpci_regvalue_to_rate(u_int32_t r)
22560484Sobrien{
22660484Sobrien	int i;
22760484Sobrien
22860484Sobrien	i = ((r << 1) | (r >> 2)) & 0x07;
22960484Sobrien	DEB(printf("cmpci_regvalue_to_rate: %d -> %d\n", r, i));
23060484Sobrien	return cmi_rates[i];
23160484Sobrien}
23260484Sobrien
23360484Sobrien/* ------------------------------------------------------------------------- */
23460484Sobrien/* ADC/DAC control - there are 2 dma channels on 8738, either can be
23560484Sobrien * playback or capture.  We use ch0 for playback and ch1 for capture. */
23660484Sobrien
23760484Sobrienstatic void
23860484Sobriencmi_dma_prog(struct sc_info *sc, struct sc_chinfo *ch, u_int32_t base)
23960484Sobrien{
24060484Sobrien	u_int32_t s, i, sz;
24160484Sobrien
24260484Sobrien	ch->phys_buf = sndbuf_getbufaddr(ch->buffer);
24360484Sobrien
24460484Sobrien	cmi_wr(sc, base, ch->phys_buf, 4);
24560484Sobrien	sz = (u_int32_t)sndbuf_getsize(ch->buffer);
24660484Sobrien
24760484Sobrien	s = sz / ch->bps - 1;
24860484Sobrien	cmi_wr(sc, base + 4, s, 2);
24960484Sobrien
25060484Sobrien	i = sz / (ch->bps * CMI_INTR_PER_BUFFER) - 1;
25160484Sobrien	cmi_wr(sc, base + 6, i, 2);
25260484Sobrien}
25360484Sobrien
254
255static void
256cmi_ch0_start(struct sc_info *sc, struct sc_chinfo *ch)
257{
258	cmi_dma_prog(sc, ch, CMPCI_REG_DMA0_BASE);
259
260	cmi_set4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_ENABLE);
261	cmi_set4(sc, CMPCI_REG_INTR_CTRL,
262		 CMPCI_REG_CH0_INTR_ENABLE);
263
264	ch->dma_active = 1;
265}
266
267static u_int32_t
268cmi_ch0_stop(struct sc_info *sc, struct sc_chinfo *ch)
269{
270	u_int32_t r = ch->dma_active;
271
272	cmi_clr4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE);
273	cmi_clr4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_ENABLE);
274        cmi_set4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET);
275        cmi_clr4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET);
276	ch->dma_active = 0;
277	return r;
278}
279
280static void
281cmi_ch1_start(struct sc_info *sc, struct sc_chinfo *ch)
282{
283	cmi_dma_prog(sc, ch, CMPCI_REG_DMA1_BASE);
284	cmi_set4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE);
285	/* Enable Interrupts */
286	cmi_set4(sc, CMPCI_REG_INTR_CTRL,
287		 CMPCI_REG_CH1_INTR_ENABLE);
288	DEB(printf("cmi_ch1_start: dma prog\n"));
289	ch->dma_active = 1;
290}
291
292static u_int32_t
293cmi_ch1_stop(struct sc_info *sc, struct sc_chinfo *ch)
294{
295	u_int32_t r = ch->dma_active;
296
297	cmi_clr4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
298	cmi_clr4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE);
299        cmi_set4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET);
300        cmi_clr4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET);
301	ch->dma_active = 0;
302	return r;
303}
304
305static void
306cmi_spdif_speed(struct sc_info *sc, int speed) {
307	u_int32_t fcr1, lcr, mcr;
308
309	if (speed >= 44100) {
310		fcr1 = CMPCI_REG_SPDIF0_ENABLE;
311		lcr  = CMPCI_REG_XSPDIF_ENABLE;
312		mcr  = (speed == 48000) ?
313			CMPCI_REG_W_SPDIF_48L | CMPCI_REG_SPDIF_48K : 0;
314	} else {
315		fcr1 = mcr = lcr = 0;
316	}
317
318	cmi_partial_wr4(sc, CMPCI_REG_MISC, 0,
319			CMPCI_REG_W_SPDIF_48L | CMPCI_REG_SPDIF_48K, mcr);
320	cmi_partial_wr4(sc, CMPCI_REG_FUNC_1, 0,
321			CMPCI_REG_SPDIF0_ENABLE, fcr1);
322	cmi_partial_wr4(sc, CMPCI_REG_LEGACY_CTRL, 0,
323			CMPCI_REG_XSPDIF_ENABLE, lcr);
324}
325
326/* ------------------------------------------------------------------------- */
327/* Channel Interface implementation */
328
329static void *
330cmichan_init(kobj_t obj, void *devinfo,
331	     struct snd_dbuf *b, struct pcm_channel *c, int dir)
332{
333	struct sc_info   *sc = devinfo;
334	struct sc_chinfo *ch = (dir == PCMDIR_PLAY) ? &sc->pch : &sc->rch;
335
336	ch->parent     = sc;
337	ch->channel    = c;
338	ch->bps        = 1;
339	ch->fmt        = AFMT_U8;
340	ch->spd        = DSP_DEFAULT_SPEED;
341	ch->buffer     = b;
342	ch->dma_active = 0;
343	if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) != 0) {
344		DEB(printf("cmichan_init failed\n"));
345		return NULL;
346	}
347
348	ch->dir = dir;
349	snd_mtxlock(sc->lock);
350	if (ch->dir == PCMDIR_PLAY) {
351		cmi_dma_prog(sc, ch, CMPCI_REG_DMA0_BASE);
352	} else {
353		cmi_dma_prog(sc, ch, CMPCI_REG_DMA1_BASE);
354	}
355	snd_mtxunlock(sc->lock);
356
357	return ch;
358}
359
360static int
361cmichan_setformat(kobj_t obj, void *data, u_int32_t format)
362{
363	struct sc_chinfo *ch = data;
364	struct sc_info	*sc = ch->parent;
365	u_int32_t f;
366
367	if (format & AFMT_S16_LE) {
368		f = CMPCI_REG_FORMAT_16BIT;
369		ch->bps = 2;
370	} else {
371		f = CMPCI_REG_FORMAT_8BIT;
372		ch->bps = 1;
373	}
374
375	if (format & AFMT_STEREO) {
376		f |= CMPCI_REG_FORMAT_STEREO;
377		ch->bps *= 2;
378	} else {
379		f |= CMPCI_REG_FORMAT_MONO;
380	}
381
382	snd_mtxlock(sc->lock);
383	if (ch->dir == PCMDIR_PLAY) {
384		cmi_partial_wr4(ch->parent,
385				CMPCI_REG_CHANNEL_FORMAT,
386				CMPCI_REG_CH0_FORMAT_SHIFT,
387				CMPCI_REG_CH0_FORMAT_MASK,
388				f);
389	} else {
390		cmi_partial_wr4(ch->parent,
391				CMPCI_REG_CHANNEL_FORMAT,
392				CMPCI_REG_CH1_FORMAT_SHIFT,
393				CMPCI_REG_CH1_FORMAT_MASK,
394				f);
395	}
396	snd_mtxunlock(sc->lock);
397	ch->fmt = format;
398
399	return 0;
400}
401
402static int
403cmichan_setspeed(kobj_t obj, void *data, u_int32_t speed)
404{
405	struct sc_chinfo *ch = data;
406	struct sc_info	*sc = ch->parent;
407	u_int32_t r, rsp;
408
409	r = cmpci_rate_to_regvalue(speed);
410	snd_mtxlock(sc->lock);
411	if (ch->dir == PCMDIR_PLAY) {
412		if (speed < 44100) {
413			/* disable if req before rate change */
414			cmi_spdif_speed(ch->parent, speed);
415		}
416		cmi_partial_wr4(ch->parent,
417				CMPCI_REG_FUNC_1,
418				CMPCI_REG_DAC_FS_SHIFT,
419				CMPCI_REG_DAC_FS_MASK,
420				r);
421		if (speed >= 44100 && ch->parent->spdif_enabled) {
422			/* enable if req after rate change */
423			cmi_spdif_speed(ch->parent, speed);
424		}
425		rsp = cmi_rd(ch->parent, CMPCI_REG_FUNC_1, 4);
426		rsp >>= CMPCI_REG_DAC_FS_SHIFT;
427		rsp &= 	CMPCI_REG_DAC_FS_MASK;
428	} else {
429		cmi_partial_wr4(ch->parent,
430				CMPCI_REG_FUNC_1,
431				CMPCI_REG_ADC_FS_SHIFT,
432				CMPCI_REG_ADC_FS_MASK,
433				r);
434		rsp = cmi_rd(ch->parent, CMPCI_REG_FUNC_1, 4);
435		rsp >>= CMPCI_REG_ADC_FS_SHIFT;
436		rsp &= 	CMPCI_REG_ADC_FS_MASK;
437	}
438	snd_mtxunlock(sc->lock);
439	ch->spd = cmpci_regvalue_to_rate(r);
440
441	DEB(printf("cmichan_setspeed (%s) %d -> %d (%d)\n",
442		   (ch->dir == PCMDIR_PLAY) ? "play" : "rec",
443		   speed, ch->spd, cmpci_regvalue_to_rate(rsp)));
444
445	return ch->spd;
446}
447
448static int
449cmichan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
450{
451	struct sc_chinfo *ch = data;
452	struct sc_info	 *sc = ch->parent;
453
454	/* user has requested interrupts every blocksize bytes */
455	if (blocksize > sc->bufsz / CMI_INTR_PER_BUFFER) {
456		blocksize = sc->bufsz / CMI_INTR_PER_BUFFER;
457	}
458	sndbuf_resize(ch->buffer, CMI_INTR_PER_BUFFER, blocksize);
459
460	return blocksize;
461}
462
463static int
464cmichan_trigger(kobj_t obj, void *data, int go)
465{
466	struct sc_chinfo	*ch = data;
467	struct sc_info		*sc = ch->parent;
468
469	snd_mtxlock(sc->lock);
470	if (ch->dir == PCMDIR_PLAY) {
471		switch(go) {
472		case PCMTRIG_START:
473			cmi_ch0_start(sc, ch);
474			break;
475		case PCMTRIG_ABORT:
476			cmi_ch0_stop(sc, ch);
477			break;
478		}
479	} else {
480		switch(go) {
481		case PCMTRIG_START:
482			cmi_ch1_start(sc, ch);
483			break;
484		case PCMTRIG_ABORT:
485			cmi_ch1_stop(sc, ch);
486			break;
487		}
488	}
489	snd_mtxunlock(sc->lock);
490	return 0;
491}
492
493static int
494cmichan_getptr(kobj_t obj, void *data)
495{
496	struct sc_chinfo	*ch = data;
497	struct sc_info		*sc = ch->parent;
498	u_int32_t physptr, bufptr, sz;
499
500	snd_mtxlock(sc->lock);
501	if (ch->dir == PCMDIR_PLAY) {
502		physptr = cmi_rd(sc, CMPCI_REG_DMA0_BASE, 4);
503	} else {
504		physptr = cmi_rd(sc, CMPCI_REG_DMA1_BASE, 4);
505	}
506	snd_mtxunlock(sc->lock);
507
508	sz = sndbuf_getsize(ch->buffer);
509	bufptr = (physptr - ch->phys_buf + sz - ch->bps) % sz;
510
511	return bufptr;
512}
513
514static void
515cmi_intr(void *data)
516{
517	struct sc_info *sc = data;
518	u_int32_t intrstat;
519	u_int32_t toclear;
520
521	snd_mtxlock(sc->lock);
522	intrstat = cmi_rd(sc, CMPCI_REG_INTR_STATUS, 4);
523	if ((intrstat & CMPCI_REG_ANY_INTR) != 0) {
524
525		toclear = 0;
526		if (intrstat & CMPCI_REG_CH0_INTR) {
527			toclear |= CMPCI_REG_CH0_INTR_ENABLE;
528			//cmi_clr4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE);
529		}
530
531		if (intrstat & CMPCI_REG_CH1_INTR) {
532			toclear |= CMPCI_REG_CH1_INTR_ENABLE;
533			//cmi_clr4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
534		}
535
536		if (toclear) {
537			cmi_clr4(sc, CMPCI_REG_INTR_CTRL, toclear);
538			snd_mtxunlock(sc->lock);
539
540			/* Signal interrupts to channel */
541			if (intrstat & CMPCI_REG_CH0_INTR) {
542				chn_intr(sc->pch.channel);
543			}
544
545			if (intrstat & CMPCI_REG_CH1_INTR) {
546				chn_intr(sc->rch.channel);
547			}
548
549			snd_mtxlock(sc->lock);
550			cmi_set4(sc, CMPCI_REG_INTR_CTRL, toclear);
551
552		}
553	}
554	snd_mtxunlock(sc->lock);
555	return;
556}
557
558static struct pcmchan_caps *
559cmichan_getcaps(kobj_t obj, void *data)
560{
561	return &cmi_caps;
562}
563
564static kobj_method_t cmichan_methods[] = {
565    	KOBJMETHOD(channel_init,		cmichan_init),
566    	KOBJMETHOD(channel_setformat,		cmichan_setformat),
567    	KOBJMETHOD(channel_setspeed,		cmichan_setspeed),
568    	KOBJMETHOD(channel_setblocksize,	cmichan_setblocksize),
569    	KOBJMETHOD(channel_trigger,		cmichan_trigger),
570    	KOBJMETHOD(channel_getptr,		cmichan_getptr),
571    	KOBJMETHOD(channel_getcaps,		cmichan_getcaps),
572	{ 0, 0 }
573};
574CHANNEL_DECLARE(cmichan);
575
576/* ------------------------------------------------------------------------- */
577/* Mixer - sb16 with kinks */
578
579static void
580cmimix_wr(struct sc_info *sc, u_int8_t port, u_int8_t val)
581{
582	cmi_wr(sc, CMPCI_REG_SBADDR, port, 1);
583	cmi_wr(sc, CMPCI_REG_SBDATA, val, 1);
584}
585
586static u_int8_t
587cmimix_rd(struct sc_info *sc, u_int8_t port)
588{
589	cmi_wr(sc, CMPCI_REG_SBADDR, port, 1);
590	return (u_int8_t)cmi_rd(sc, CMPCI_REG_SBDATA, 1);
591}
592
593struct sb16props {
594	u_int8_t  rreg;     /* right reg chan register */
595	u_int8_t  stereo:1; /* (no explanation needed, honest) */
596	u_int8_t  rec:1;    /* recording source */
597	u_int8_t  bits:3;   /* num bits to represent maximum gain rep */
598	u_int8_t  oselect;  /* output select mask */
599	u_int8_t  iselect;  /* right input select mask */
600} static const cmt[SOUND_MIXER_NRDEVICES] = {
601	[SOUND_MIXER_SYNTH]   = {CMPCI_SB16_MIXER_FM_R,      1, 1, 5,
602				 CMPCI_SB16_SW_FM,   CMPCI_SB16_MIXER_FM_SRC_R},
603	[SOUND_MIXER_CD]      = {CMPCI_SB16_MIXER_CDDA_R,    1, 1, 5,
604				 CMPCI_SB16_SW_CD,   CMPCI_SB16_MIXER_CD_SRC_R},
605	[SOUND_MIXER_LINE]    = {CMPCI_SB16_MIXER_LINE_R,    1, 1, 5,
606				 CMPCI_SB16_SW_LINE, CMPCI_SB16_MIXER_LINE_SRC_R},
607	[SOUND_MIXER_MIC]     = {CMPCI_SB16_MIXER_MIC,       0, 1, 5,
608				 CMPCI_SB16_SW_MIC,  CMPCI_SB16_MIXER_MIC_SRC},
609	[SOUND_MIXER_SPEAKER] = {CMPCI_SB16_MIXER_SPEAKER,  0, 0, 2, 0, 0},
610	[SOUND_MIXER_PCM]     = {CMPCI_SB16_MIXER_VOICE_R,  1, 0, 5, 0, 0},
611	[SOUND_MIXER_VOLUME]  = {CMPCI_SB16_MIXER_MASTER_R, 1, 0, 5, 0, 0},
612	/* These controls are not implemented in CMI8738, but maybe at a
613	   future date.  They are not documented in C-Media documentation,
614	   though appear in other drivers for future h/w (ALSA, Linux, NetBSD).
615	*/
616	[SOUND_MIXER_IGAIN]   = {CMPCI_SB16_MIXER_INGAIN_R,  1, 0, 2, 0, 0},
617	[SOUND_MIXER_OGAIN]   = {CMPCI_SB16_MIXER_OUTGAIN_R, 1, 0, 2, 0, 0},
618	[SOUND_MIXER_BASS]    = {CMPCI_SB16_MIXER_BASS_R,    1, 0, 4, 0, 0},
619	[SOUND_MIXER_TREBLE]  = {CMPCI_SB16_MIXER_TREBLE_R,  1, 0, 4, 0, 0},
620	/* The mic pre-amp is implemented with non-SB16 compatible
621	   registers. */
622	[SOUND_MIXER_MONITOR]  = {CMPCI_NON_SB16_CONTROL,     0, 1, 4, 0},
623};
624
625#define MIXER_GAIN_REG_RTOL(r) (r - 1)
626
627static int
628cmimix_init(struct snd_mixer *m)
629{
630	struct sc_info	*sc = mix_getdevinfo(m);
631	u_int32_t	i,v;
632
633	for(i = v = 0; i < SOUND_MIXER_NRDEVICES; i++) {
634		if (cmt[i].bits) v |= 1 << i;
635	}
636	mix_setdevs(m, v);
637
638	for(i = v = 0; i < SOUND_MIXER_NRDEVICES; i++) {
639		if (cmt[i].rec) v |= 1 << i;
640	}
641	mix_setrecdevs(m, v);
642
643	cmimix_wr(sc, CMPCI_SB16_MIXER_RESET, 0);
644	cmimix_wr(sc, CMPCI_SB16_MIXER_ADCMIX_L, 0);
645	cmimix_wr(sc, CMPCI_SB16_MIXER_ADCMIX_R, 0);
646	cmimix_wr(sc, CMPCI_SB16_MIXER_OUTMIX,
647		  CMPCI_SB16_SW_CD | CMPCI_SB16_SW_MIC | CMPCI_SB16_SW_LINE);
648	return 0;
649}
650
651static int
652cmimix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
653{
654	struct sc_info *sc = mix_getdevinfo(m);
655	u_int32_t r, l, max;
656	u_int8_t  v;
657
658	max = (1 << cmt[dev].bits) - 1;
659
660	if (cmt[dev].rreg == CMPCI_NON_SB16_CONTROL) {
661		/* For time being this can only be one thing (mic in
662		 * mic/aux reg) */
663		v = cmi_rd(sc, CMPCI_REG_AUX_MIC, 1) & 0xf0;
664		l = left * max / 100;
665		/* 3 bit gain with LSB MICGAIN off(1),on(1) -> 4 bit value */
666		v |= ((l << 1) | (~l >> 3)) & 0x0f;
667		cmi_wr(sc, CMPCI_REG_AUX_MIC, v, 1);
668		return 0;
669	}
670
671	l  = (left * max / 100) << (8 - cmt[dev].bits);
672	if (cmt[dev].stereo) {
673		r = (right * max / 100) << (8 - cmt[dev].bits);
674		cmimix_wr(sc, MIXER_GAIN_REG_RTOL(cmt[dev].rreg), l);
675		cmimix_wr(sc, cmt[dev].rreg, r);
676		DEBMIX(printf("Mixer stereo write dev %d reg 0x%02x "\
677			      "value 0x%02x:0x%02x\n",
678			      dev, MIXER_GAIN_REG_RTOL(cmt[dev].rreg), l, r));
679	} else {
680		r = l;
681		cmimix_wr(sc, cmt[dev].rreg, l);
682		DEBMIX(printf("Mixer mono write dev %d reg 0x%02x " \
683			      "value 0x%02x:0x%02x\n",
684			      dev, cmt[dev].rreg, l, l));
685	}
686
687	/* Zero gain does not mute channel from output, but this does... */
688	v = cmimix_rd(sc, CMPCI_SB16_MIXER_OUTMIX);
689	if (l == 0 && r == 0) {
690		v &= ~cmt[dev].oselect;
691	} else {
692		v |= cmt[dev].oselect;
693	}
694	cmimix_wr(sc,  CMPCI_SB16_MIXER_OUTMIX, v);
695
696	return 0;
697}
698
699static int
700cmimix_setrecsrc(struct snd_mixer *m, u_int32_t src)
701{
702	struct sc_info *sc = mix_getdevinfo(m);
703	u_int32_t i, ml, sl;
704
705	ml = sl = 0;
706	for(i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
707		if ((1<<i) & src) {
708			if (cmt[i].stereo) {
709				sl |= cmt[i].iselect;
710			} else {
711				ml |= cmt[i].iselect;
712			}
713		}
714	}
715	cmimix_wr(sc, CMPCI_SB16_MIXER_ADCMIX_R, sl|ml);
716	DEBMIX(printf("cmimix_setrecsrc: reg 0x%02x val 0x%02x\n",
717		      CMPCI_SB16_MIXER_ADCMIX_R, sl|ml));
718	ml = CMPCI_SB16_MIXER_SRC_R_TO_L(ml);
719	cmimix_wr(sc, CMPCI_SB16_MIXER_ADCMIX_L, sl|ml);
720	DEBMIX(printf("cmimix_setrecsrc: reg 0x%02x val 0x%02x\n",
721		      CMPCI_SB16_MIXER_ADCMIX_L, sl|ml));
722
723	return src;
724}
725
726/* Optional SPDIF support. */
727
728static int
729cmi_initsys(struct sc_info* sc)
730{
731#ifdef SND_DYNSYSCTL
732	SYSCTL_ADD_INT(snd_sysctl_tree(sc->dev),
733		       SYSCTL_CHILDREN(snd_sysctl_tree_top(sc->dev)),
734		       OID_AUTO, "spdif_enabled", CTLFLAG_RW,
735		       &sc->spdif_enabled, 0,
736		       "enable SPDIF output at 44.1 kHz and above");
737#endif /* SND_DYNSYSCTL */
738	return 0;
739}
740
741/* ------------------------------------------------------------------------- */
742static kobj_method_t cmi_mixer_methods[] = {
743	KOBJMETHOD(mixer_init,	cmimix_init),
744	KOBJMETHOD(mixer_set,	cmimix_set),
745	KOBJMETHOD(mixer_setrecsrc,	cmimix_setrecsrc),
746	{ 0, 0 }
747};
748MIXER_DECLARE(cmi_mixer);
749
750/* ------------------------------------------------------------------------- */
751/* Power and reset */
752
753static void
754cmi_power(struct sc_info *sc, int state)
755{
756	switch (state) {
757	case 0: /* full power */
758		cmi_clr4(sc, CMPCI_REG_MISC, CMPCI_REG_POWER_DOWN);
759		break;
760	default:
761		/* power off */
762		cmi_set4(sc, CMPCI_REG_MISC, CMPCI_REG_POWER_DOWN);
763		break;
764	}
765}
766
767static int
768cmi_init(struct sc_info *sc)
769{
770	/* Effect reset */
771	cmi_set4(sc, CMPCI_REG_MISC, CMPCI_REG_BUS_AND_DSP_RESET);
772	DELAY(100);
773	cmi_clr4(sc, CMPCI_REG_MISC, CMPCI_REG_BUS_AND_DSP_RESET);
774
775	/* Disable interrupts and channels */
776	cmi_clr4(sc, CMPCI_REG_FUNC_0,
777		 CMPCI_REG_CH0_ENABLE | CMPCI_REG_CH1_ENABLE);
778	cmi_clr4(sc, CMPCI_REG_INTR_CTRL,
779		 CMPCI_REG_CH0_INTR_ENABLE | CMPCI_REG_CH1_INTR_ENABLE);
780
781	/* Configure DMA channels, ch0 = play, ch1 = capture */
782	cmi_clr4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_DIR);
783	cmi_set4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_DIR);
784
785	/* Attempt to enable 4 Channel output */
786	cmi_set4(sc, CMPCI_REG_MISC, CMPCI_REG_N4SPK3D);
787
788	/* Disable SPDIF1 - not compatible with config */
789	cmi_clr4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF1_ENABLE);
790	cmi_clr4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP);
791
792	return 0;
793}
794
795static void
796cmi_uninit(struct sc_info *sc)
797{
798	/* Disable interrupts and channels */
799	cmi_clr4(sc, CMPCI_REG_INTR_CTRL,
800		 CMPCI_REG_CH0_INTR_ENABLE |
801		 CMPCI_REG_CH1_INTR_ENABLE |
802		 CMPCI_REG_TDMA_INTR_ENABLE);
803	cmi_clr4(sc, CMPCI_REG_FUNC_0,
804		 CMPCI_REG_CH0_ENABLE | CMPCI_REG_CH1_ENABLE);
805}
806
807/* ------------------------------------------------------------------------- */
808/* Bus and device registration */
809static int
810cmi_probe(device_t dev)
811{
812	switch(pci_get_devid(dev)) {
813	case CMI8338A_PCI_ID:
814		device_set_desc(dev, "CMedia CMI8338A");
815		return 0;
816	case CMI8338B_PCI_ID:
817		device_set_desc(dev, "CMedia CMI8338B");
818		return 0;
819	case CMI8738_PCI_ID:
820		device_set_desc(dev, "CMedia CMI8738");
821		return 0;
822	case CMI8738B_PCI_ID:
823		device_set_desc(dev, "CMedia CMI8738B");
824		return 0;
825	default:
826		return ENXIO;
827	}
828}
829
830static int
831cmi_attach(device_t dev)
832{
833	struct snddev_info	*d;
834	struct sc_info		*sc;
835	u_int32_t		data;
836	char			status[SND_STATUSLEN];
837
838	d = device_get_softc(dev);
839	sc = malloc(sizeof(struct sc_info), M_DEVBUF, M_NOWAIT | M_ZERO);
840	if (sc == NULL) {
841		device_printf(dev, "cannot allocate softc\n");
842		return ENXIO;
843	}
844
845	sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
846	data = pci_read_config(dev, PCIR_COMMAND, 2);
847	data |= (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN);
848	pci_write_config(dev, PCIR_COMMAND, data, 2);
849	data = pci_read_config(dev, PCIR_COMMAND, 2);
850
851	sc->dev = dev;
852	sc->regid = PCIR_BAR(0);
853	sc->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->regid,
854				      0, BUS_SPACE_UNRESTRICTED, 1, RF_ACTIVE);
855	if (!sc->reg) {
856		device_printf(dev, "cmi_attach: Cannot allocate bus resource\n");
857		goto bad;
858	}
859	sc->st = rman_get_bustag(sc->reg);
860	sc->sh = rman_get_bushandle(sc->reg);
861
862	sc->irqid = 0;
863	sc->irq   = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
864					   RF_ACTIVE | RF_SHAREABLE);
865	if (!sc->irq ||
866	    snd_setup_intr(dev, sc->irq, INTR_MPSAFE, cmi_intr, sc, &sc->ih)) {
867		device_printf(dev, "cmi_attach: Unable to map interrupt\n");
868		goto bad;
869	}
870
871	sc->bufsz = pcm_getbuffersize(dev, 4096, CMI_DEFAULT_BUFSZ, 65536);
872
873	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
874			       /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
875			       /*highaddr*/BUS_SPACE_MAXADDR,
876			       /*filter*/NULL, /*filterarg*/NULL,
877			       /*maxsize*/sc->bufsz, /*nsegments*/1,
878			       /*maxsegz*/0x3ffff, /*flags*/0,
879			       /*lockfunc*/busdma_lock_mutex,
880			       /*lockfunc*/&Giant,
881			       &sc->parent_dmat) != 0) {
882		device_printf(dev, "cmi_attach: Unable to create dma tag\n");
883		goto bad;
884	}
885
886	cmi_power(sc, 0);
887	if (cmi_init(sc))
888		goto bad;
889
890	if (mixer_init(dev, &cmi_mixer_class, sc))
891		goto bad;
892
893	if (pcm_register(dev, sc, 1, 1))
894		goto bad;
895
896	cmi_initsys(sc);
897
898	pcm_addchan(dev, PCMDIR_PLAY, &cmichan_class, sc);
899	pcm_addchan(dev, PCMDIR_REC, &cmichan_class, sc);
900
901	snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld %s",
902		 rman_get_start(sc->reg), rman_get_start(sc->irq),PCM_KLDSTRING(snd_cmi));
903	pcm_setstatus(dev, status);
904
905	DEB(printf("cmi_attach: succeeded\n"));
906	return 0;
907
908 bad:
909	if (sc->parent_dmat)
910		bus_dma_tag_destroy(sc->parent_dmat);
911	if (sc->ih)
912		bus_teardown_intr(dev, sc->irq, sc->ih);
913	if (sc->irq)
914		bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
915	if (sc->reg)
916		bus_release_resource(dev, SYS_RES_IOPORT, sc->regid, sc->reg);
917	if (sc->lock)
918		snd_mtxfree(sc->lock);
919	if (sc)
920		free(sc, M_DEVBUF);
921
922	return ENXIO;
923}
924
925static int
926cmi_detach(device_t dev)
927{
928	struct sc_info *sc;
929	int r;
930
931	r = pcm_unregister(dev);
932	if (r) return r;
933
934	sc = pcm_getdevinfo(dev);
935	cmi_uninit(sc);
936	cmi_power(sc, 3);
937
938	bus_dma_tag_destroy(sc->parent_dmat);
939	bus_teardown_intr(dev, sc->irq, sc->ih);
940	bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
941	bus_release_resource(dev, SYS_RES_IOPORT, sc->regid, sc->reg);
942	snd_mtxfree(sc->lock);
943	free(sc, M_DEVBUF);
944
945	return 0;
946}
947
948static int
949cmi_suspend(device_t dev)
950{
951	struct sc_info *sc = pcm_getdevinfo(dev);
952
953	snd_mtxlock(sc->lock);
954	sc->pch.dma_was_active = cmi_ch0_stop(sc, &sc->pch);
955	sc->rch.dma_was_active = cmi_ch1_stop(sc, &sc->rch);
956	cmi_power(sc, 3);
957	snd_mtxunlock(sc->lock);
958	return 0;
959}
960
961static int
962cmi_resume(device_t dev)
963{
964	struct sc_info *sc = pcm_getdevinfo(dev);
965
966	snd_mtxlock(sc->lock);
967	cmi_power(sc, 0);
968	if (cmi_init(sc) != 0) {
969		device_printf(dev, "unable to reinitialize the card\n");
970		snd_mtxunlock(sc->lock);
971		return ENXIO;
972	}
973
974	if (mixer_reinit(dev) == -1) {
975		device_printf(dev, "unable to reinitialize the mixer\n");
976		snd_mtxunlock(sc->lock);
977                return ENXIO;
978        }
979
980	if (sc->pch.dma_was_active) {
981		cmichan_setspeed(NULL, &sc->pch, sc->pch.spd);
982		cmichan_setformat(NULL, &sc->pch, sc->pch.fmt);
983		cmi_ch0_start(sc, &sc->pch);
984	}
985
986	if (sc->rch.dma_was_active) {
987		cmichan_setspeed(NULL, &sc->rch, sc->rch.spd);
988		cmichan_setformat(NULL, &sc->rch, sc->rch.fmt);
989		cmi_ch1_start(sc, &sc->rch);
990	}
991	snd_mtxunlock(sc->lock);
992	return 0;
993}
994
995static device_method_t cmi_methods[] = {
996	DEVMETHOD(device_probe,         cmi_probe),
997	DEVMETHOD(device_attach,        cmi_attach),
998	DEVMETHOD(device_detach,        cmi_detach),
999	DEVMETHOD(device_resume,        cmi_resume),
1000	DEVMETHOD(device_suspend,       cmi_suspend),
1001	{ 0, 0 }
1002};
1003
1004static driver_t cmi_driver = {
1005	"pcm",
1006	cmi_methods,
1007	PCM_SOFTC_SIZE
1008};
1009
1010DRIVER_MODULE(snd_cmi, pci, cmi_driver, pcm_devclass, 0, 0);
1011MODULE_DEPEND(snd_cmi, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
1012MODULE_VERSION(snd_cmi, 1);
1013