Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1264330
  • 博文数量: 404
  • 博客积分: 10011
  • 博客等级: 上将
  • 技术积分: 5382
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-03 16:29
文章存档

2010年(40)

2009年(140)

2008年(224)

我的朋友

分类: LINUX

2008-09-26 11:08:01

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");
阅读(710) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~