免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 728 | 回复: 0
打印 上一主题 下一主题

2.6内核IIC驱动程序源码(3) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-26 11:08 |只看该作者 |倒序浏览

int IIC_read(struct file *file, char* buf, size_t count, loff_t *f_pos)
{
        struct IIC_dev *dev = file->private_data;
        size_t val = DATA_LEN;
        while( dev->index  val )
        {
                if( file->f_flags & O_NONBLOCK )
                        return -EAGAIN;
                // 在这里准备睡眠,等待条件为真
                if( wait_event_interruptible(dev->rq, (dev->index >= val)) )
                        return -ERESTARTSYS; // 返回非0表示被信号中断
        }
        if( copy_to_user(buf, dev->buffer, val) )
                return -EFAULT;
        memset( dev->buffer, 0, dev->size );
        dev->index = 0;
        set_slave_recv_mode();
        return val;
}
int IIC_release(struct inode *inode, struct file *file)
{
        struct IIC_dev *dev = file->private_data;
        iowrite8( 0x0, R_IICCON );
        iowrite8( 0x0, R_IICADD );
        iowrite8( 0x0, R_IICSTAT);
        barrier(); // 强制写入寄存器
        memset( dev->buffer, 0, dev->size );
        dev->index = 0;
        free_irq( IRQ_IIC, NULL );
        up(&dev->sem);
        return 0;
}
unsigned int IIC_poll(struct file* file, poll_table* wait)
{
        struct IIC_dev *dev = file->private_data;
        unsigned int mask = 0, val = DATA_LEN;
        poll_wait(file,&dev->rq,wait);
        if( dev->index >= val )
                mask |= POLLIN | POLLRDNORM;
        return mask;
}
irqreturn_t interrupt_handle( int irq, void* dev_id, struct pt_regs* regs )
{
        struct IIC_dev *dev = dev_id;
        int val = DATA_LEN;
        uint8_t ch = ioread8( R_IICDS );
        if( dev->index == 0 && ch == 0xAA )
                goto ret;
        dev->buffer[dev->index++] = ch;
        if( dev->index >= val )
        {
                wake_up_interruptible( &dev->rq );
                // 直接退出 Slave Receiver 模式
                return IRQ_HANDLED;
        }
ret:
        iowrite8( 0xEF, R_IICCON );
        return IRQ_HANDLED;
}
module_init(IIC_init);
module_exit(IIC_exit);
MODULE_AUTHOR("kf701.ye AT gmail.com");
MODULE_DESCRIPTION("Study");
MODULE_SUPPORTED_DEVICE(DEVICE);
MODULE_LICENSE("GPL");

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/78225/showart_1226020.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP