全部博文(404)
分类: 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 模式