⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 maestro3.c

📁 iis s3c2410-uda1341语音系统的 开发
💻 C
📖 第 1 页 / 共 5 页
字号:
        return 0;    set_current_state(TASK_INTERRUPTIBLE);    add_wait_queue(&s->dma_dac.wait, &wait);    for (;;) {        spin_lock_irqsave(&s->lock, flags);        count = s->dma_dac.count;        spin_unlock_irqrestore(&s->lock, flags);        if (count <= 0)            break;        if (signal_pending(current))            break;        if (nonblock) {            remove_wait_queue(&s->dma_dac.wait, &wait);            set_current_state(TASK_RUNNING);            return -EBUSY;        }        tmo = (count * HZ) / s->ratedac;        tmo >>= sample_shift[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK];        /* XXX this is just broken.  someone is waking us up alot, or schedule_timeout is broken.            or something.  who cares. - zach */        if (!schedule_timeout(tmo ? tmo : 1) && tmo)            DPRINTK(DPCRAP,"dma timed out?? %ld\n",jiffies);    }    remove_wait_queue(&s->dma_dac.wait, &wait);    set_current_state(TASK_RUNNING);    if (signal_pending(current))            return -ERESTARTSYS;    return 0;}static ssize_t m3_read(struct file *file, char *buffer, size_t count, loff_t *ppos){    struct m3_state *s = (struct m3_state *)file->private_data;    ssize_t ret;    unsigned long flags;    unsigned swptr;    int cnt;        VALIDATE_STATE(s);    if (ppos != &file->f_pos)        return -ESPIPE;    if (s->dma_adc.mapped)        return -ENXIO;    if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))        return ret;    if (!access_ok(VERIFY_WRITE, buffer, count))        return -EFAULT;    ret = 0;    spin_lock_irqsave(&s->lock, flags);    while (count > 0) {        int timed_out;        swptr = s->dma_adc.swptr;        cnt = s->dma_adc.dmasize-swptr;        if (s->dma_adc.count < cnt)            cnt = s->dma_adc.count;        if (cnt > count)            cnt = count;        if (cnt <= 0) {            start_adc(s);            if (file->f_flags & O_NONBLOCK)             {                ret = ret ? ret : -EAGAIN;                goto out;            }            spin_unlock_irqrestore(&s->lock, flags);            timed_out = interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ) == 0;            spin_lock_irqsave(&s->lock, flags);            if(timed_out) {                printk("read: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n",                       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count,                        s->dma_adc.hwptr, s->dma_adc.swptr);                stop_adc(s);                set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);                s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;            }            if (signal_pending(current))             {                ret = ret ? ret : -ERESTARTSYS;                goto out;            }            continue;        }            spin_unlock_irqrestore(&s->lock, flags);        if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {            ret = ret ? ret : -EFAULT;            return ret;        }        spin_lock_irqsave(&s->lock, flags);        swptr = (swptr + cnt) % s->dma_adc.dmasize;        s->dma_adc.swptr = swptr;        s->dma_adc.count -= cnt;        count -= cnt;        buffer += cnt;        ret += cnt;        start_adc(s);    }out:    spin_unlock_irqrestore(&s->lock, flags);    return ret;}static ssize_t m3_write(struct file *file, const char *buffer, size_t count, loff_t *ppos){    struct m3_state *s = (struct m3_state *)file->private_data;    ssize_t ret;    unsigned long flags;    unsigned swptr;    int cnt;        VALIDATE_STATE(s);    if (ppos != &file->f_pos)        return -ESPIPE;    if (s->dma_dac.mapped)        return -ENXIO;    if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))        return ret;    if (!access_ok(VERIFY_READ, buffer, count))        return -EFAULT;    ret = 0;    spin_lock_irqsave(&s->lock, flags);    while (count > 0) {        int timed_out;        if (s->dma_dac.count < 0) {            s->dma_dac.count = 0;            s->dma_dac.swptr = s->dma_dac.hwptr;        }        swptr = s->dma_dac.swptr;        cnt = s->dma_dac.dmasize-swptr;        if (s->dma_dac.count + cnt > s->dma_dac.dmasize)            cnt = s->dma_dac.dmasize - s->dma_dac.count;        if (cnt > count)            cnt = count;        if (cnt <= 0) {            start_dac(s);            if (file->f_flags & O_NONBLOCK) {                if(!ret) ret = -EAGAIN;                goto out;            }            spin_unlock_irqrestore(&s->lock, flags);            timed_out = interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ) == 0;            spin_lock_irqsave(&s->lock, flags);            if(timed_out) {                DPRINTK(DPCRAP,"write: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n",                       s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,                        s->dma_dac.hwptr, s->dma_dac.swptr);                stop_dac(s);                set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);                s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;            }            if (signal_pending(current)) {                if (!ret) ret = -ERESTARTSYS;                goto out;            }            continue;        }        spin_unlock_irqrestore(&s->lock, flags);        if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {            if (!ret) ret = -EFAULT;            return ret;        }        spin_lock_irqsave(&s->lock, flags);        DPRINTK(DPSYS,"wrote %6d bytes at sw: %6d cnt: %6d while hw: %6d\n",                cnt, swptr, s->dma_dac.count, s->dma_dac.hwptr);                swptr = (swptr + cnt) % s->dma_dac.dmasize;        s->dma_dac.swptr = swptr;        s->dma_dac.count += cnt;        s->dma_dac.endcleared = 0;        count -= cnt;        buffer += cnt;        ret += cnt;        start_dac(s);    }out:    spin_unlock_irqrestore(&s->lock, flags);    return ret;}static unsigned int m3_poll(struct file *file, struct poll_table_struct *wait){    struct m3_state *s = (struct m3_state *)file->private_data;    unsigned long flags;    unsigned int mask = 0;    VALIDATE_STATE(s);    if (file->f_mode & FMODE_WRITE)        poll_wait(file, &s->dma_dac.wait, wait);    if (file->f_mode & FMODE_READ)        poll_wait(file, &s->dma_adc.wait, wait);    spin_lock_irqsave(&s->lock, flags);    m3_update_ptr(s);    if (file->f_mode & FMODE_READ) {        if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)            mask |= POLLIN | POLLRDNORM;    }    if (file->f_mode & FMODE_WRITE) {        if (s->dma_dac.mapped) {            if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)                 mask |= POLLOUT | POLLWRNORM;        } else {            if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)                mask |= POLLOUT | POLLWRNORM;        }    }    spin_unlock_irqrestore(&s->lock, flags);    return mask;}static int m3_mmap(struct file *file, struct vm_area_struct *vma){    struct m3_state *s = (struct m3_state *)file->private_data;    unsigned long max_size, size, start, offset;    struct dmabuf *db;    int ret = -EINVAL;    VALIDATE_STATE(s);    if (vma->vm_flags & VM_WRITE) {        if ((ret = prog_dmabuf(s, 0)) != 0)            return ret;        db = &s->dma_dac;    } else     if (vma->vm_flags & VM_READ) {        if ((ret = prog_dmabuf(s, 1)) != 0)            return ret;        db = &s->dma_adc;    } else          return -EINVAL;    max_size = db->dmasize;    start = vma->vm_start;    offset = (vma->vm_pgoff << PAGE_SHIFT);    size = vma->vm_end - vma->vm_start;    if(size > max_size)        goto out;    if(offset > max_size - size)        goto out;    /*     * this will be ->nopage() once I can      * ask Jeff what the hell I'm doing wrong.     */    ret = -EAGAIN;    if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))        goto out;    db->mapped = 1;    ret = 0;out:    return ret;}/* * this function is a disaster.. */#define get_user_ret(x, ptr,  ret) ({ if(get_user(x, ptr)) return ret; })static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){    struct m3_state *s = (struct m3_state *)file->private_data;    unsigned long flags;    audio_buf_info abinfo;    count_info cinfo;    int val, mapped, ret;    unsigned char fmtm, fmtd;    VALIDATE_STATE(s);    mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||        ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);    DPRINTK(DPSYS,"m3_ioctl: cmd %d\n", cmd);    switch (cmd) {    case OSS_GETVERSION:        return put_user(SOUND_VERSION, (int *)arg);    case SNDCTL_DSP_SYNC:        if (file->f_mode & FMODE_WRITE)            return drain_dac(s, file->f_flags & O_NONBLOCK);        return 0;            case SNDCTL_DSP_SETDUPLEX:        /* XXX fix */        return 0;    case SNDCTL_DSP_GETCAPS:        return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);            case SNDCTL_DSP_RESET:        spin_lock_irqsave(&s->lock, flags);        if (file->f_mode & FMODE_WRITE) {            stop_dac(s);            synchronize_irq();            s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;        }        if (file->f_mode & FMODE_READ) {            stop_adc(s);            synchronize_irq();            s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;        }        spin_unlock_irqrestore(&s->lock, flags);        return 0;    case SNDCTL_DSP_SPEED:        get_user_ret(val, (int *)arg, -EFAULT);        spin_lock_irqsave(&s->lock, flags);        if (val >= 0) {            if (file->f_mode & FMODE_READ) {                stop_adc(s);                s->dma_adc.ready = 0;                set_adc_rate(s, val);            }            if (file->f_mode & FMODE_WRITE) {                stop_dac(s);                s->dma_dac.ready = 0;                set_dac_rate(s, val);            }        }        spin_unlock_irqrestore(&s->lock, flags);        return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);            case SNDCTL_DSP_STEREO:        get_user_ret(val, (int *)arg, -EFAULT);        spin_lock_irqsave(&s->lock, flags);        fmtd = 0;        fmtm = ~0;        if (file->f_mode & FMODE_READ) {            stop_adc(s);            s->dma_adc.ready = 0;            if (val)                fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;            else                fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);        }        if (file->f_mode & FMODE_WRITE) {            stop_dac(s);            s->dma_dac.ready = 0;            if (val)                fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;            else                fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);        }        set_fmt(s, fmtm, fmtd);        spin_unlock_irqrestore(&s->lock, flags);        return 0;    case SNDCTL_DSP_CHANNELS:        get_user_ret(val, (int *)arg, -EFAULT);        spin_lock_irqsave(&s->lock, flags);        if (val != 0) {            fmtd = 0;            fmtm = ~0;            if (file->f_mode & FMODE_READ) {                stop_adc(s);                s->dma_adc.ready = 0;                if (val >= 2)                    fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;                else                    fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);            }            if (file->f_mode & FMODE_WRITE) {                stop_dac(s);                s->dma_dac.ready = 0;                if (val >= 2)                    fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;                else                    fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);            }            set_fmt(s, fmtm, fmtd);        }        spin_unlock_irqrestore(&s->lock, flags);        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT)                        : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg);            case SNDCTL_DSP_GETFMTS: /* Returns a mask */        return put_user(AFMT_U8|AFMT_S16_LE, (int *)arg);            case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/        get_user_ret(val, (int *)arg, -EFAULT);        spin_lock_irqsave(&s->lock, flags);        if (val != AFMT_QUERY) {            fmtd = 0;            fmtm = ~0;            if (file->f_mode & FMODE_READ) {                stop_adc(s);                s->dma_adc.ready = 0;                if (val == AFMT_S16_LE)                    fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT;                else                    fmtm &= ~(ESS_FMT_16BIT << ESS_ADC_SHIFT);            }            if (file->f_mode & FMODE_WRITE) {                stop_dac(s);                s->dma_dac.ready = 0;                if (val == AFMT_S16_LE)                    fmtd |= ESS_FMT_16BIT << ESS_DAC_SHIFT;                else                    fmtm &= ~(ESS_FMT_16BIT << ESS_DAC_SHIFT);            }            set_fmt(s, fmtm, fmtd);        }        spin_unlock_irqrestore(&s->lock, flags);        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ?             (ESS_FMT_16BIT << ESS_ADC_SHIFT)             : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -