当前位置:首页 > s3c2440 uda1341驱动分析
DPRINTK(\audio_channels = val; break;
case SOUND_PCM_READ_CHANNELS:
DPRINTK(\put_user(audio_channels, (long *) arg); break;
case SNDCTL_DSP_SPEED: get_user(val, (long *) arg); val = audio_set_dsp_speed(val); if (val 0) return -EINVAL;
put_user(val, (long *) arg); break;
case SOUND_PCM_READ_RATE: put_user(audio_rate, (long *) arg); break;
case SNDCTL_DSP_GETFMTS:
put_user(AUDIO_FMT_MASK, (long *) arg); break;
case SNDCTL_DSP_GETBLKSIZE: if(file->f_mode & FMODE_WRITE)
return put_user(audio_fragsize, (long *) arg); else
return put_user(audio_fragsize, (int *) arg); case SNDCTL_DSP_SETFRAGMENT: if (file->f_mode & FMODE_WRITE) { if (output_stream.buffers) return -EBUSY;
get_user(val, (long *) arg); audio_fragsize = 1 (val & 0xFFFF); if (audio_fragsize 16) audio_fragsize = 16; if (audio_fragsize > 16384) audio_fragsize = 16384;
audio_nbfrags = (val >> 16) & 0x7FFF; if (audio_nbfrags 2) audio_nbfrags = 2;
if (audio_nbfrags * audio_fragsize > 128 * 1024) audio_nbfrags = 128 * 1024 / audio_fragsize; if (audio_setup_buf(&output_stream)) return -ENOMEM; }
if (file->f_mode & FMODE_READ) {
if (input_stream.buffers) return -EBUSY;
get_user(val, (int *) arg);
audio_fragsize = 1 (val & 0xFFFF); if (audio_fragsize 16) audio_fragsize = 16; if (audio_fragsize > 16384) audio_fragsize = 16384;
audio_nbfrags = (val >> 16) & 0x7FFF; if (audio_nbfrags 2) audio_nbfrags = 2;
if (audio_nbfrags * audio_fragsize > 128 * 1024) audio_nbfrags = 128 * 1024 / audio_fragsize; if (audio_setup_buf(&input_stream)) return -ENOMEM; } break;
case SNDCTL_DSP_SYNC: return audio_sync(file);
case SNDCTL_DSP_GETOSPACE: {
audio_stream_t *s = &output_stream; audio_buf_info *inf = (audio_buf_info *) arg; int err = access_ok(VERIFY_WRITE, inf, sizeof(*inf)); int i;
int frags = 0, bytes = 0; if (err) return err;
for (i = 0; i s->nbfrags; i++) { if (s->buffers.sem.count > 0) { if (s->buffers.size == 0) frags++; bytes += s->fragsize - s->buffers.size; } }
put_user(frags, &inf->fragments); put_user(s->nbfrags, &inf->fragstotal); put_user(s->fragsize, &inf->fragsize); put_user(bytes, &inf->bytes); break; }
case SNDCTL_DSP_GETISPACE: {
audio_stream_t *s = &input_stream;
audio_buf_info *inf = (audio_buf_info *) arg;
int err = access_ok(VERIFY_WRITE, inf, sizeof(*inf)); int i;
int frags = 0, bytes = 0;
if (!(file->f_mode & FMODE_READ)) return -EINVAL; if (err) return err;
for(i = 0; i s->nbfrags; i++){ if (s->buffers.sem.count > 0) {
if (s->buffers.size == s->fragsize) frags++;
bytes += s->buffers.size; } }
put_user(frags, &inf->fragments); put_user(s->nbfrags, &inf->fragstotal); put_user(s->fragsize, &inf->fragsize); put_user(bytes, &inf->bytes); break; }
case SNDCTL_DSP_RESET:
if (file->f_mode & FMODE_READ) { audio_clear_buf(&input_stream); }
if (file->f_mode & FMODE_WRITE) { audio_clear_buf(&output_stream); } return 0;
case SNDCTL_DSP_NONBLOCK: file->f_flags |= O_NONBLOCK; return 0;
case SNDCTL_DSP_POST: case SNDCTL_DSP_SUBDIVIDE: case SNDCTL_DSP_GETCAPS: case SNDCTL_DSP_GETTRIGGER: case SNDCTL_DSP_SETTRIGGER: case SNDCTL_DSP_GETIPTR: case SNDCTL_DSP_GETOPTR: case SNDCTL_DSP_MAPINBUF: case SNDCTL_DSP_MAPOUTBUF: case SNDCTL_DSP_SETSYNCRO: case SNDCTL_DSP_SETDUPLEX: return -ENOSYS;
default:
return smdk2410_mixer_ioctl(inode, file, cmd, arg); } return 0; } open:
判断设备是否正忙->设置相关参数->初始化iis总线->清除缓冲区
static int smdk2410_audio_open(struct inode *inode, struct file *file) {
int cold = !audio_active; DPRINTK(\
if ((file->f_flags & O_ACCMODE) == O_RDONLY) { if (audio_rd_refcount || audio_wr_refcount) return -EBUSY; audio_rd_refcount++;
} else if ((file->f_flags & O_ACCMODE) == O_WRONLY) { if (audio_wr_refcount) return -EBUSY; audio_wr_refcount++;
} else if ((file->f_flags & O_ACCMODE) == O_RDWR) { if (audio_rd_refcount || audio_wr_refcount) return -EBUSY; audio_rd_refcount++; audio_wr_refcount++; } else
return -EINVAL; if (cold) {
audio_rate = AUDIO_RATE_DEFAULT;
audio_channels = AUDIO_CHANNELS_DEFAULT; audio_fragsize = AUDIO_FRAGSIZE_DEFAULT; audio_nbfrags = AUDIO_NBFRAGS_DEFAULT; if ((file->f_mode & FMODE_WRITE)){
init_s3c2410_iis_bus_tx();//可写则初始化iis发送 audio_clear_buf(&output_stream); }
if ((file->f_mode & FMODE_READ)){
init_s3c2410_iis_bus_rx();//可读则初始化iis接收 audio_clear_buf(&input_stream); } } return 0; } release:
共分享92篇相关文档