typedef struct { int size; /* buffer size */ char *start; /* point to actual buffer */ dma_addr_t dma_addr; /* physical buffer address */ struct semaphore sem; /* down before touching the buffer */ int master; /* owner for buffer allocation, contain size when true */ } audio_buf_t; typedef struct { audio_buf_t *buffers; /* pointer to audio buffer structures */ audio_buf_t *buf; /* current buffer used by read/write */ u_int buf_idx; /* index for the pointer above */ u_int fragsize; /* fragment i.e. buffer size */ u_int nbfrags; /* nbr of fragments */ enum dma_ch dmach; } audio_stream_t; static audio_stream_t output_stream; static audio_stream_t input_stream; #define NEXT_BUF(_s_,_b_) { \ (_s_)->_b_##_idx++; \ (_s_)->_b_##_idx %= (_s_)->nbfrags; \ (_s_)->_b_ = (_s_)->buffers + (_s_)->_b_##_idx; }
static u_int audio_rate; static int audio_channels; static int audio_fmt; static u_int audio_fragsize; static u_int audio_nbfrags;
static int audio_rd_refcount; static int audio_wr_refcount; #define audio_active (audio_rd_refcount | audio_wr_refcount) static int audio_dev_dsp; static int audio_dev_mixer; static int audio_mix_modcnt; static int uda1341_volume; static u8 uda_sampling; static int uda1341_boost; static int mixer_igain=0x4; /* -6db*/
static void uda1341_l3_address(u8 data) { int i; unsigned long flags;
b = s->buffers + ((s->nbfrags + s->buf_idx - 1) % s->nbfrags); if (down_interruptible(&b->sem)) return -EINTR; up(&b->sem);
return 0; } static inline int copy_from_user_mono_stereo(char *to, const char *from, int count) { u_int *dst = (u_int *)to; const char *end = from + count;
if (!access_ok(VERIFY_READ, from, count)) return -EFAULT;
if ((int)from & 0x2) { u_int v; __get_user(v, (const u_short *)from); from += 2; *dst++ = v | (v << 16); }
while (from < end-2) { u_int v, x, y; __get_user(v, (const u_int *)from); from += 4; x = v << 16; x |= x >> 16; y = v >> 16; y |= y << 16; *dst++ = x; *dst++ = y; }
if (from < end) { u_int v; __get_user(v, (const u_short *)from); *dst = v | (v << 16); }
for (i = 0; i < s->nbfrags; i++) { audio_buf_t *b = s->buf; down(&b->sem); s3c2410_dma_enqueue(s->dmach, (void *) b, b->dma_addr, s->fragsize); NEXT_BUF(s, buf); } } printk(KERN_WARNING "in smdk2410_audio_read\n");
while (count > 0) { audio_buf_t *b = s->buf;
/* Wait for a buffer to become full */ if (file->f_flags & O_NONBLOCK) { ret = -EAGAIN; if (down_trylock(&b->sem)) break; } else { ret = -ERESTARTSYS; if (down_interruptible(&b->sem)) break; }
chunksize = b->size; if (chunksize > count) chunksize = count;
static int __init audio_init_dma(audio_stream_t * s, char *desc) { int ret ; enum s3c2410_dmasrc source; int hwcfg; unsigned long devaddr; int dcon; unsigned int flags = 0;