Linux设备驱动剖析之IIC(四)

本文深入剖析Linux设备驱动中的IIC(Inter-Integrated Circuit)控制器,详细讲解了从启动传输、中断处理到数据传输的完整过程,包括s3c24xx_i2c_doxfer和s3c24xx_i2c_irq等关键函数的功能和工作原理。通过分析,揭示了IIC控制器如何处理总线仲裁、ACK信号和数据传输。
摘要由CSDN通过智能技术生成

558行,又重试2次。

560行,调用s3c24xx_i2c_doxfer函数:

00000482 static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
00000483                   struct i2c_msg *msgs, int num)
00000484 {
00000485     unsigned long iicstat, timeout;
00000486     int spins = 20;
00000487     int ret;
00000488 
00000489     if (i2c->suspended)
00000490         return -EIO;
00000491 
00000492     ret = s3c24xx_i2c_set_master(i2c);
00000493     if (ret != 0) {
00000494         dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
00000495         ret = -EAGAIN;
00000496         goto out;
00000497     }
00000498 
00000499     spin_lock_irq(&i2c->lock);
00000500 
00000501     i2c->msg     = msgs;
00000502     i2c->msg_num = num;
00000503     i2c->msg_ptr = 0;
00000504     i2c->msg_idx = 0;
00000505     i2c->state   = STATE_START;
00000506 
00000507     s3c24xx_i2c_enable_irq(i2c);
00000508     s3c24xx_i2c_message_start(i2c, msgs);
00000509     spin_unlock_irq(&i2c->lock);
00000510 
00000511     timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
00000512 
00000513     ret = i2c->msg_idx;
00000514 
00000515     /* having these next two as dev_err() makes life very
00000516      * noisy when doing an i2cdetect */
00000517 
00000518     if (timeout == 0)
00000519         dev_dbg(i2c->dev, "timeout\n");
00000520     else if (ret != num)
00000521         dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
00000522 
00000523     /* ensure the stop has been through the bus */
00000524 
00000525     dev_dbg(i2c->dev, "waiting for bus idle\n");
00000526 
00000527     /* first, try busy waiting briefly */
00000528     do {
00000529         iicstat = readl(i2c->regs + S3C2410_IICSTAT);
00000530     } while ((iicstat & S3C2410_IICSTAT_START) && --spins);
00000531 
00000532     /* if that timed out sleep */
00000533     if (!spins) {
00000534         msleep(1);
00000535         iicstat = readl(i2c->regs + S3C2410_IICSTAT);
00000536     }
00000537 
00000538     if (iicstat & S3C2410_IICSTAT_START)
00000539         dev_warn(i2c->dev, "timeout waiting for bus idle\n");
00000540 
00000541  out:
00000542     return ret;
00000543 }

489行,如果IIC控制器挂起了的话就不用往下走了,返回出错。

492至497行,调用s3c24xx_i2c_set_master函数,读取IICSTAT寄存器,等待IIC总线空闲。

501至505行,记住这些变量的值,后面的分析会遇到。

507行,使能IIC控制器中断。

508行,调用s3c24xx_i2c_message_start函数开始读写操作,它的定义如下:

00000163 static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
00000164                       struct i2c_msg *msg)
00000165 {
00000166     unsigned int addr = (msg->addr & 0x7f) << 1;
00000167     unsigned long stat;
00000168     unsigned long iiccon;
00000169 
00000170     stat = 0;
00000171     stat |=  S3C2410_IICSTAT_TXRXEN;
00000172 
00000173     if (msg->flags & I2C_M_RD) {
00000174         stat |= S3C2410_IICSTAT_MASTER_RX;
00000175         addr |= 1;
00000176     } else
00000177         stat |= S3C2410_IICSTAT_MASTER_TX;
0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值