38#include <sys/kernel.h>
40#include <sys/malloc.h>
43#include <machine/dbdma.h>
44#include <machine/resource.h>
45#include <machine/bus.h>
47#include <dev/ofw/ofw_bus.h>
49#ifdef HAVE_KERNEL_OPTION_HEADERS
83 for (i = 0; i < dma->
slots; ++i) {
84 dbdma_insert_command(dma->
channel,
106 dbdma_set_branch_selector(dma->
channel, 1 << 0, 1 << 0);
107 dbdma_set_device_status(dma->
channel, 1 << 0, 0);
109 dbdma_sync_commands(dma->
channel, BUS_DMASYNC_PREWRITE);
112#define AOA_BUFFER_SIZE 65536
123 err = bus_dma_tag_create(bus_get_dma_tag(self),
124 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
129 dma = malloc(
sizeof(*dma), M_DEVBUF, M_WAITOK | M_ZERO);
132 dma->
blksz = PAGE_SIZE;
134 mtx_init(&dma->
mutex,
"AOA", NULL, MTX_DEF);
144 bus_dma_tag_destroy(dma->
tag);
145 mtx_destroy(&dma->
mutex);
155 DPRINTF((
"aoa_chan_setblocksize: blocksz = %u, dma->blksz = %u\n",
156 blocksz, dma->
blksz));
157 KASSERT(!dma->
running, (
"dma is running"));
158 KASSERT(blocksz > 0, (
"bad blocksz"));
161 __asm
volatile (
"cntlzw %0,%1" :
"=r"(lz) :
"r"(blocksz));
162 blocksz = 1 << (31 - lz);
163 DPRINTF((
"blocksz = %u\n", blocksz));
166 if (blocksz > dma->
bufsz)
167 blocksz = dma->
bufsz;
171 DPRINTF((
"sndbuf_resize returned %d\n", err));
175 if (blocksz == dma->
blksz)
179 err = dbdma_resize_channel(dma->
channel, 2 + dma->
bufsz / blocksz);
181 DPRINTF((
"dbdma_resize_channel returned %d\n", err));
186 dma->
blksz = blocksz;
241 err = dbdma_allocate_channel(dma->
reg, 0, bus_get_dma_tag(sc->
sc_dev),
249 dbdma_free_channel(dma->
channel);
281 mtx_lock(&dma->
mutex);
286 dbdma_set_device_status(dma->
channel, 1 << 0, 1 << 0);
293 dbdma_set_device_status(dma->
channel, 1 << 0, 0);
295 for (i = 0; i < dma->
slots; ++i)
296 dbdma_clear_cmd_status(dma->
channel, i);
298 mtx_unlock(&dma->
mutex);
312 dbdma_free_channel(dma->
channel);
327 mtx_lock(&dma->
mutex);
329 while (dbdma_get_cmd_status(dma->
channel, dma->
slot)) {
333 mtx_unlock(&dma->
mutex);
335 mtx_lock(&dma->
mutex);
338 mtx_unlock(&dma->
mutex);
382 DPRINTF((
"pcm_getbuffersize returned %d\n", err));
386 snprintf(
status,
sizeof(
status),
"at %s", ofw_bus_get_name(self));
static void * aoa_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
static u_int32_t sc_fmt[]
static int aoa_chan_free(kobj_t obj, void *data)
static void aoa_dma_set_program(struct aoa_dma *dma)
static kobj_method_t aoa_chan_methods[]
CHANNEL_DECLARE(aoa_chan)
static u_int32_t aoa_chan_getptr(kobj_t obj, void *data)
static int aoa_chan_trigger(kobj_t obj, void *data, int go)
static u_int32_t aoa_chan_setspeed(kobj_t obj, void *data, u_int32_t speed)
static int aoa_chan_setformat(kobj_t obj, void *data, u_int32_t format)
static void aoa_dma_delete(struct aoa_dma *dma)
static struct pcmchan_caps * aoa_chan_getcaps(kobj_t obj, void *data)
void aoa_interrupt(void *xsc)
int aoa_attach(void *xsc)
static u_int32_t aoa_chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksz)
static struct aoa_dma * aoa_dma_create(struct aoa_softc *sc)
static struct pcmchan_caps aoa_caps
int sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, int dmaflags, unsigned int size)
bus_addr_t sndbuf_getbufaddr(struct snd_dbuf *buf)
unsigned int sndbuf_getsize(struct snd_dbuf *b)
void sndbuf_free(struct snd_dbuf *b)
int sndbuf_resize(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz)
void chn_intr(struct pcm_channel *c)
int pcm_setstatus(device_t dev, char *str)
int pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo)
int pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
unsigned int pcm_getbuffersize(device_t dev, unsigned int minbufsz, unsigned int deflt, unsigned int maxbufsz)
#define SND_FORMAT(f, c, e)
dbdma_channel_t * channel
struct resource * sc_odma