`

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

 
阅读更多

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;
00000178 
00000179     if (msg->flags & I2C_M_REV_DIR_ADDR)
00000180         addr ^= 1;
00000181 
00000182     /* todo - check for wether ack wanted or not */
00000183     s3c24xx_i2c_enable_ack(i2c);
00000184 
00000185     iiccon = readl(i2c->regs + S3C2410_IICCON);
00000186     writel(stat, i2c->regs + S3C2410_IICSTAT);
00000187 
00000188     dev_dbg(i2c->dev, "START: %08lx to IICSTAT, %02x to DS\n", stat, addr);
00000189     writeb(addr, i2c->regs + S3C2410_IICDS);
00000190 
00000191     /* delay here to ensure the data byte has gotten onto the bus
00000192      * before the transaction is started */
00000193 
00000194     ndelay(i2c->tx_setup);
00000195 
00000196     dev_dbg(i2c->dev, "iiccon, %08lx\n", iiccon);
00000197     writel(iiccon, i2c->regs + S3C2410_IICCON);
00000198 
00000199     stat |= S3C2410_IICSTAT_START;
00000200     writel(stat, i2c->regs + S3C2410_IICSTAT);
00000201 }

166行,高7位表示从机地址,最低1位表示读或写操作,0表示写,1表示读。

171行,IIC控制器发送和接收使能。

173行,条件不成立,所以执行177行,主机发送使能。

179行,与读操作相关的,因此if条件不成立。

183行,使能IIC控制器ACK应答。

剩下那些语句基本上都是在操作IIC控制器的寄存器,具体含义请看s3c6410的数据手册。

189行,将从机地址写入移位寄存器。

        s3c24xx_i2c_message_start函数执行完后硬件就开始进行数据传输,回到s3c24xx_i2c_doxfer函数的第509行,释放锁,与499行是配对使用的。

511行,等待,等待传输操作完成,等待,只因曾经承若。有两种情况会唤醒它,一是超时,二是传输完成。

      程序是在等待了,但我们的步伐却不会因此而停留,前面还有很长的路等着我们呢,还等什么,继续前进!

接下来看等待过程中发生的事情,没错,就是在中断里。中断处理函数是s3c24xx_i2c_irq,它的定义:

00000423 static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)
00000424 {
00000425     struct s3c24xx_i2c *i2c = dev_id;
00000426     unsigned long status;
00000427     unsigned long tmp;
00000428 
00000429     status = readl(i2c->regs + S3C2410_IICSTAT);
00000430 
00000431     if (status & S3C2410_IICSTAT_ARBITR) {
00000432         /* deal with arbitration loss */
00000433         dev_err(i2c->dev, "deal with arbitration loss\n");
00000434     }
00000435 
00000436     if (i2c->state == STATE_IDLE) {
00000437         dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n");
00000438 
00000439         tmp = readl(i2c->regs + S3C2410_IICCON);
00000440         tmp &= ~S3C2410_IICCON_IRQPEND;
00000441         writel(tmp, i2c->regs +  S3C2410_IICCON);
00000442         goto out;
00000443     }
00000444 
00000445     /* pretty much this leaves us with the fact that we've
00000446      * transmitted or received whatever byte we last sent */
00000447 
00000448     i2s_s3c_irq_nextbyte(i2c, status);
00000449 
00000450  out:
00000451     return IRQ_HANDLED;
00000452 }

429行,读取状态寄存器。

431至434行,如果总线仲裁失败就打印错误信息。

436至443行,我们知道i2c->state是等于STATE_START的,因此这里的if条件不成立。

448行,i2s_s3c_irq_nextbyte函数执行具体中断处理,i2s_s3c_irq_nextbyte函数的定义:

00000257 static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
00000258 {
00000259     unsigned long tmp;
00000260     unsigned char byte;
00000261     int ret = 0;
00000262 
00000263     switch (i2c->state) {
00000264 
00000265     case STATE_IDLE:
00000266         dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
00000267         goto out;
00000268         break;
00000269 
00000270     case STATE_STOP:
00000271         dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
00000272         s3c24xx_i2c_disable_irq(i2c);
00000273         goto out_ack;
00000274 
00000275     case STATE_START:
00000276         /* last thing we did was send a start condition on the
00000277          * bus, or started a new i2c message
00000278          */
00000279 
00000280         if (iicstat & S3C2410_IICSTAT_LASTBIT &&
00000281             !(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
00000282             /* ack was not received... */
00000283 
00000284             dev_dbg(i2c->dev, "ack was not received\n");
00000285             s3c24xx_i2c_stop(i2c, -ENXIO);
00000286             goto out_ack;
00000287         }
00000288 
00000289         if (i2c->msg->flags & I2C_M_RD)
00000290             i2c->state = STATE_READ;
00000291         else
00000292             i2c->state = STATE_WRITE;
00000293 
00000294         /* terminate the transfer if there is nothing to do
00000295          * as this is used by the i2c probe to find devices. */
00000296 
00000297         if (is_lastmsg(i2c) && i2c->msg->len == 0) {
00000298             s3c24xx_i2c_stop(i2c, 0);
00000299             goto out_ack;
00000300         }
00000301 
00000302         if (i2c->state == STATE_READ)
00000303             goto prepare_read;
00000304 
00000305         /* fall through to the write state, as we will need to
00000306          * send a byte as well */
00000307 
00000308     case STATE_WRITE:
00000309         /* we are writing data to the device... check for the
00000310          * end of the message, and if so, work out what to do
00000311          */
00000312 
00000313         if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
00000314             if (iicstat & S3C2410_IICSTAT_LASTBIT) {
00000315                 dev_dbg(i2c->dev, "WRITE: No Ack\n");
00000316 
00000317                 s3c24xx_i2c_stop(i2c, -ECONNREFUSED);
00000318                 goto out_ack;
00000319             }
00000320         }
00000321 
00000322  retry_write:
00000323 
00000324         if (!is_msgend(i2c)) {
00000325             byte = i2c->msg->buf[i2c->msg_ptr++];
00000326             writeb(byte, i2c->regs + S3C2410_IICDS);
00000327 
00000328             /* delay after writing the byte to allow the
00000329              * data setup time on the bus, as writing the
00000330              * data to the register causes the first bit
00000331              * to appear on SDA, and SCL will change as
00000332              * soon as the interrupt is acknowledged */
00000333 
00000334             ndelay(i2c->tx_setup);
00000335 
00000336         } else if (!is_lastmsg(i2c)) {
00000337             /* we need to go to the next i2c message */
00000338 
00000339             dev_dbg(i2c->dev, "WRITE: Next Message\n");
00000340 
00000341             i2c->msg_ptr = 0;
00000342             i2c->msg_idx++;
00000343             i2c->msg++;
00000344 
00000345             /* check to see if we need to do another message */
00000346             if (i2c->msg->flags & I2C_M_NOSTART) {
00000347 
00000348                 if (i2c->msg->flags & I2C_M_RD) {
00000349                     /* cannot do this, the controller
00000350                      * forces us to send a new START
00000351                      * when we change direction */
00000352 
00000353                     s3c24xx_i2c_stop(i2c, -EINVAL);
00000354                 }
00000355 
00000356                 goto retry_write;
00000357             } else {
00000358                 /* send the new start */
00000359                 s3c24xx_i2c_message_start(i2c, i2c->msg);
00000360                 i2c->state = STATE_START;
00000361             }
00000362 
00000363         } else {
00000364             /* send stop */
00000365 
00000366             s3c24xx_i2c_stop(i2c, 0);
00000367         }
00000368         break;
00000369 
00000370     case STATE_READ:
00000371         /* we have a byte of data in the data register, do
00000372          * something with it, and then work out wether we are
00000373          * going to do any more read/write
00000374          */
00000375 
00000376         byte = readb(i2c->regs + S3C2410_IICDS);
00000377         i2c->msg->buf[i2c->msg_ptr++] = byte;
00000378 
00000379  prepare_read:
00000380         if (is_msglast(i2c)) {
00000381             /* last byte of buffer */
00000382 
00000383             if (is_lastmsg(i2c))
00000384                 s3c24xx_i2c_disable_ack(i2c);
00000385 
00000386         } else if (is_msgend(i2c)) {
00000387             /* ok, we've read the entire buffer, see if there
00000388              * is anything else we need to do */
00000389 
00000390             if (is_lastmsg(i2c)) {
00000391                 /* last message, send stop and complete */
00000392                 dev_dbg(i2c->dev, "READ: Send Stop\n");
00000393 
00000394                 s3c24xx_i2c_stop(i2c, 0);
00000395             } else {
00000396                 /* go to the next transfer */
00000397                 dev_dbg(i2c->dev, "READ: Next Transfer\n");
00000398 
00000399                 i2c->msg_ptr = 0;
00000400                 i2c->msg_idx++;
00000401                 i2c->msg++;
00000402             }
00000403         }
00000404 
00000405         break;
00000406     }
00000407 
00000408     /* acknowlegde the IRQ and get back on with the work */
00000409 
00000410  out_ack:
00000411     tmp = readl(i2c->regs + S3C2410_IICCON);
00000412     tmp &= ~S3C2410_IICCON_IRQPEND;
00000413     writel(tmp, i2c->regs + S3C2410_IICCON);
00000414  out:
00000415     return ret;
00000416 }

函数够长的,不过一路走来,早就已经习惯了。

263行,因为i2c->state=STATE_START,因此忽略其他case,直接从275行开始看。

280行,如果没有收到ACK信号并且没有设置忽略ACK则停止这次传输。

289行,if条件不成立,执行292行,i2c->state = STATE_WRITE。

297行,is_lastmsg函数的定义:

00000227 static inline int is_lastmsg(struct s3c24xx_i2c *i2c)
00000228 {
00000229     return i2c->msg_idx >= (i2c->msg_num - 1);
00000230 }

因为i2c->msg_idx=0,i2c->msg_num=1,所以返回1。但是i2c->msg->len=2不为0,所以297行的if条件不成立。

302行,if条件不成立。

注意,这个case里没有并没有break,因此会继续往下执行。

313至320行,也是没收到ACK条件才会成立的。

324行,is_msgend函数的定义:

00000247 static inline int is_msgend(struct s3c24xx_i2c *i2c)
00000248 {
00000249     return i2c->msg_ptr >= i2c->msg->len;
00000250 }

因为i2c->msg_ptr=0,i2c->msg->len=2,因此返回0。324行的if条件成立。

325行,读取第一个要写的字节数据,然后i2c->msg_ptr= i2c->msg_ptr +1。

326行,将数据写入移位寄存器。

334行,延时一下。

368行,跳出switch,到411行。

411至413行,清除pending标志,恢复IIC传输。

      下一次进中断的时候会进入308行的case,经过313至320行的判断后来到324行,这次is_msgend函数还是会返回0。325行,读取下一个字节数据,326行,将数据写入移位寄存器,过程和前面的一样。

     当第三次进中断的时候,324行的条件就不会成立了,并且336行的if条件也不会成立,因此就会执行366行的s3c24xx_i2c_stop函数,它的定义如下:

00000203 static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
00000204 {
00000205     unsigned long iicstat = readl(i2c->regs + S3C2410_IICSTAT);
00000206 
00000207     dev_dbg(i2c->dev, "STOP\n");
00000208 
00000209     /* stop the transfer */
00000210     iicstat &= ~S3C2410_IICSTAT_START;
00000211     writel(iicstat, i2c->regs + S3C2410_IICSTAT);
00000212 
00000213     i2c->state = STATE_STOP;
00000214 
00000215     s3c24xx_i2c_master_complete(i2c, ret);
00000216     s3c24xx_i2c_disable_irq(i2c);
00000217 }

205行,读取状态寄存器。

210、211行,发送停止信号。

213行,i2c->state = STATE_STOP。

215行,调用s3c24xx_i2c_master_complete函数。

216行,禁止IIC控制器中断。下面看s3c24xx_i2c_master_complete函数的定义:

00000109 static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)
00000110 {
00000111     dev_dbg(i2c->dev, "master_complete %d\n", ret);
00000112 
00000113     i2c->msg_ptr = 0;
00000114     i2c->msg = NULL;
00000115     i2c->msg_idx++;
00000116     i2c->msg_num = 0;
00000117     if (ret)
00000118         i2c->msg_idx = ret;
00000119 
00000120     wake_up(&i2c->wait);
00000121 }

113至118行,不用说了。

120行,唤醒那个睡着了的她,谁?就是那个“承若”。忘记了的话就回去看看呗。

     至此,可以说ioctl的整个写过程已经说完了,至于读过程就不说了。累,确实有点累。

 

结束语

     i2c-dev.c提供了一套不依赖于具体平台的驱动,让具体的驱动逻辑放在应用程序中,和SPI中的spidev.c的作用是很类似的。

 

0
3
分享到:
评论

相关推荐

    IIC-linux-driver-analysis.rar_Linux IIC驱动_linux iic

    对linux设备驱动中如何编写IIC驱动进行了详细分析。

    linux-iic.rar_Linux IIC驱动_linux iic

    LINUX I2C驱动源码分析,使你更加了解在驱动中IIC的使用

    linux下IIC驱动开发分析.doc

    linux 下 IIC 驱动 开发 分析.doc

    IIC体系结构

    linux操作系统中的,IIC设备驱动分析。

    ARM-Linux-IIC设备的添加与驱动实现

    分析了ARM-Linux下IIC总线及其设备驱动的层次结构,指出了IIC设备添加与驱动实现的途径,详细阐述了如何采用通用i2c-dev.c驱动常规IIC设备、如何编写特定IIC设备的probe方式驱动、怎样设计动态加载的简易IIC“客服-...

    linux驱动分析

    驱动分析, 各种驱动代码,lcd ,usb ,课程中的重点

    s3c2410驱动分析

    linux 培训课程中的各种分析资源,iic ,lcd,nand,spi的过程

    毕设&课设&项目&竞赛-基于STM32的模拟IIC驱动OLED显示屏,可直接使用.zip

    单片机设计,工具源码,...云计算与大数据:数据集、包括云计算平台、大数据分析、人工智能、机器学习等,云计算是一种基于互联网的计算方式,通过这种方式,共享的软硬件资源和信息可以按需提供给计算机和其他设备。

    i2c源代码情景分析

    IIC源代码分析实例,非常详细地介绍了linux下IIC的驱动接口编程,大家可以好好看看

    unix分析关于UNIX的一些浅析

    下图即为Linux 2.6中引入的设备驱动模型的结构图(只是个总体框架,并不是指这的platform总线,设备和驱动)。 总线上包括设备和驱动的集合,总线上所有设备组成双向循环链表,包含在platform_device...

    linux基础实验篇

    3.5 Armlinux系统分析...........................................................................................................18 第四章 ICETEK_ARM9_SS2410说明............................................

    嵌入式红绿灯控制系统

    对于输出电流有一定离散性的驱动芯片必选在出厂或投入生产线前分档,调整PCB 板上电流设定电阻(Rs)的阻值大小,使之生产的LED 灯具恒流驱动板对同类LED 光源的发光亮度一致,保持最终产品的一致性。 4)驱动芯片...

    ARM 实验指导书第一册UCOS-II.doc

    实验十四 LCD驱动实验 119 实验十五 触摸屏实验 126 实验十六 WDT看门狗实验 135 实验十七 实时时钟实验 139 实验十八 RS485接口实验 144 实验十九 CAN及SPI接口实验 150 实验二十 利用SPI接口与FPGA通讯实验 157 ...

Global site tag (gtag.js) - Google Analytics