1139749Simp/*-
2119853Scg * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
3110499Snyan * All rights reserved.
4110499Snyan *
5110499Snyan * Redistribution and use in source and binary forms, with or without
6110499Snyan * modification, are permitted provided that the following conditions
7110499Snyan * are met:
8110499Snyan * 1. Redistributions of source code must retain the above copyright
9110499Snyan *    notice, this list of conditions and the following disclaimer.
10110499Snyan * 2. Redistributions in binary form must reproduce the above copyright
11110499Snyan *    notice, this list of conditions and the following disclaimer in the
12110499Snyan *    documentation and/or other materials provided with the distribution.
13110499Snyan *
14110499Snyan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15110499Snyan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16110499Snyan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17110499Snyan * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18110499Snyan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19110499Snyan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20110499Snyan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21110499Snyan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22110499Snyan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23110499Snyan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24110499Snyan * SUCH DAMAGE.
25110499Snyan */
26110499Snyan
27193640Sariff#ifdef HAVE_KERNEL_OPTION_HEADERS
28193640Sariff#include "opt_snd.h"
29193640Sariff#endif
30193640Sariff
31110499Snyan#include <dev/sound/pcm/sound.h>
32110499Snyan
33110499Snyan#include <isa/isavar.h>
34110499Snyan
35110499SnyanSND_DECLARE_FILE("$FreeBSD$");
36110499Snyan
37110499Snyanint
38110499Snyansndbuf_dmasetup(struct snd_dbuf *b, struct resource *drq)
39110499Snyan{
40110499Snyan	/* should do isa_dma_acquire/isa_dma_release here */
41110499Snyan	if (drq == NULL) {
42110499Snyan		b->dmachan = -1;
43110499Snyan	} else {
44110499Snyan		sndbuf_setflags(b, SNDBUF_F_DMA, 1);
45110499Snyan		b->dmachan = rman_get_start(drq);
46110499Snyan	}
47110499Snyan	return 0;
48110499Snyan}
49110499Snyan
50110499Snyanint
51110499Snyansndbuf_dmasetdir(struct snd_dbuf *b, int dir)
52110499Snyan{
53110499Snyan	KASSERT(b, ("sndbuf_dmasetdir called with b == NULL"));
54110499Snyan	KASSERT(sndbuf_getflags(b) & SNDBUF_F_DMA, ("sndbuf_dmasetdir called on non-ISA buffer"));
55110499Snyan
56110499Snyan	b->dir = (dir == PCMDIR_PLAY)? ISADMA_WRITE : ISADMA_READ;
57110499Snyan	return 0;
58110499Snyan}
59110499Snyan
60110499Snyanvoid
61110499Snyansndbuf_dma(struct snd_dbuf *b, int go)
62110499Snyan{
63110499Snyan	KASSERT(b, ("sndbuf_dma called with b == NULL"));
64110499Snyan	KASSERT(sndbuf_getflags(b) & SNDBUF_F_DMA, ("sndbuf_dma called on non-ISA buffer"));
65110499Snyan
66110499Snyan	switch (go) {
67110499Snyan	case PCMTRIG_START:
68110499Snyan		/* isa_dmainit(b->chan, size); */
69110499Snyan		isa_dmastart(b->dir | ISADMA_RAW, b->buf, b->bufsize, b->dmachan);
70110499Snyan		break;
71110499Snyan
72110499Snyan	case PCMTRIG_STOP:
73110499Snyan	case PCMTRIG_ABORT:
74110499Snyan		isa_dmastop(b->dmachan);
75110499Snyan		isa_dmadone(b->dir | ISADMA_RAW, b->buf, b->bufsize, b->dmachan);
76110499Snyan		break;
77110499Snyan	}
78110499Snyan
79110499Snyan	DEB(printf("buf 0x%p ISA DMA %s, channel %d\n",
80110499Snyan		b,
81110499Snyan		(go == PCMTRIG_START)? "started" : "stopped",
82110499Snyan		b->dmachan));
83110499Snyan}
84110499Snyan
85110499Snyanint
86110499Snyansndbuf_dmaptr(struct snd_dbuf *b)
87110499Snyan{
88110499Snyan	int i;
89110499Snyan
90110499Snyan	KASSERT(b, ("sndbuf_dmaptr called with b == NULL"));
91110499Snyan	KASSERT(sndbuf_getflags(b) & SNDBUF_F_DMA, ("sndbuf_dmaptr called on non-ISA buffer"));
92110499Snyan
93110499Snyan	if (!sndbuf_runsz(b))
94110499Snyan		return 0;
95110499Snyan	i = isa_dmastatus(b->dmachan);
96110499Snyan	KASSERT(i >= 0, ("isa_dmastatus returned %d", i));
97110499Snyan	return b->bufsize - i;
98110499Snyan}
99110499Snyan
100110499Snyanvoid
101110499Snyansndbuf_dmabounce(struct snd_dbuf *b)
102110499Snyan{
103110499Snyan	KASSERT(b, ("sndbuf_dmabounce called with b == NULL"));
104110499Snyan	KASSERT(sndbuf_getflags(b) & SNDBUF_F_DMA, ("sndbuf_dmabounce called on non-ISA buffer"));
105110499Snyan
106110499Snyan	/* tell isa_dma to bounce data in/out */
107110499Snyan}
108