示例#1
0
static void
ich_filldtbl(struct sc_chinfo *ch)
{
	struct sc_info *sc = ch->parent;
	uint32_t base;
	int i;

	base = sndbuf_getbufaddr(ch->buffer);
	if ((ch->blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->buffer))
		ch->blksz = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt;
	if ((sndbuf_getblksz(ch->buffer) != ch->blksz ||
	    sndbuf_getblkcnt(ch->buffer) != ch->blkcnt) &&
	    sndbuf_resize(ch->buffer, ch->blkcnt, ch->blksz) != 0)
		device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n",
		    __func__, ch->blksz, ch->blkcnt);
	ch->blksz = sndbuf_getblksz(ch->buffer);

	for (i = 0; i < ICH_DTBL_LENGTH; i++) {
		ch->dtbl[i].buffer = base + (ch->blksz * (i % ch->blkcnt));
		ch->dtbl[i].length = ICH_BDC_IOC
				   | (ch->blksz / ch->parent->sample_size);
	}
}
示例#2
0
文件: ich.c 项目: Gwenio/DragonFlyBSD
static int
ichchan_free(kobj_t obj, void *data)
{
	struct sc_chinfo *ch;
	struct sc_info *sc;

	ch = (struct sc_chinfo *)data;
	sc = (ch != NULL) ? ch->parent : NULL;
	if (ch != NULL && sc != NULL) {
		ICH_DMA_ATTR(sc, sndbuf_getbuf(ch->buffer),
		    sndbuf_getmaxsize(ch->buffer), PAT_WRITE_BACK);
	}

	return (1);
}
示例#3
0
文件: ich.c 项目: Gwenio/DragonFlyBSD
static void *
ichchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
	struct sc_info *sc = devinfo;
	struct sc_chinfo *ch;
	unsigned int num;

	ICH_LOCK(sc);
	num = sc->chnum++;
	ch = &sc->ch[num];
	ch->num = num;
	ch->buffer = b;
	ch->channel = c;
	ch->parent = sc;
	ch->run = 0;
	ch->dtbl = sc->dtbl + (ch->num * ICH_DTBL_LENGTH);
	ch->desc_addr = sc->desc_addr +
	    (ch->num * ICH_DTBL_LENGTH * sizeof(struct ich_desc));
	ch->blkcnt = sc->blkcnt;
	ch->blksz = sc->bufsz / ch->blkcnt;

	switch(ch->num) {
	case 0: /* play */
		KASSERT(dir == PCMDIR_PLAY, ("wrong direction"));
		ch->regbase = ICH_REG_PO_BASE;
		ch->spdreg = (sc->hasvra) ? AC97_REGEXT_FDACRATE : 0;
		ch->imask = ICH_GLOB_STA_POINT;
		break;

	case 1: /* record */
		KASSERT(dir == PCMDIR_REC, ("wrong direction"));
		ch->regbase = ICH_REG_PI_BASE;
		ch->spdreg = (sc->hasvra) ? AC97_REGEXT_LADCRATE : 0;
		ch->imask = ICH_GLOB_STA_PIINT;
		break;

	case 2: /* mic */
		KASSERT(dir == PCMDIR_REC, ("wrong direction"));
		ch->regbase = ICH_REG_MC_BASE;
		ch->spdreg = (sc->hasvrm) ? AC97_REGEXT_MADCRATE : 0;
		ch->imask = ICH_GLOB_STA_MINT;
		break;

	default:
		return (NULL);
	}

	if (sc->flags & ICH_FIXED_RATE)
		ch->spdreg = 0;

	ICH_UNLOCK(sc);
	if (sndbuf_alloc(ch->buffer, sc->chan_dmat, sc->bufsz) != 0)
		return (NULL);

	ICH_DMA_ATTR(sc, sndbuf_getbuf(ch->buffer),
	    sndbuf_getmaxsize(ch->buffer), PAT_UNCACHEABLE);

	ICH_LOCK(sc);
	ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (uint32_t)(ch->desc_addr), 4);
	ICH_UNLOCK(sc);

	return (ch);
}