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

时间:2023-03-09 17:07:45
Linux设备驱动剖析之IIC(四)

558行,又重试2次。

560行,调用s3c24xx_i2c_doxfer函数:

 static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
struct i2c_msg *msgs, int num)
{
unsigned long iicstat, timeout;
int spins = ;
int ret; if (i2c->suspended)
return -EIO; ret = s3c24xx_i2c_set_master(i2c);
if (ret != ) {
dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
ret = -EAGAIN;
goto out;
} spin_lock_irq(&i2c->lock); i2c->msg = msgs;
i2c->msg_num = num;
i2c->msg_ptr = ;
i2c->msg_idx = ;
i2c->state = STATE_START; s3c24xx_i2c_enable_irq(i2c);
s3c24xx_i2c_message_start(i2c, msgs);
spin_unlock_irq(&i2c->lock); timeout = wait_event_timeout(i2c->wait, i2c->msg_num == , HZ * ); ret = i2c->msg_idx; /* having these next two as dev_err() makes life very
00000516 * noisy when doing an i2cdetect */ if (timeout == )
dev_dbg(i2c->dev, "timeout\n");
else if (ret != num)
dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret); /* ensure the stop has been through the bus */ dev_dbg(i2c->dev, "waiting for bus idle\n"); /* first, try busy waiting briefly */
do {
iicstat = readl(i2c->regs + S3C2410_IICSTAT);
} while ((iicstat & S3C2410_IICSTAT_START) && --spins); /* if that timed out sleep */
if (!spins) {
msleep();
iicstat = readl(i2c->regs + S3C2410_IICSTAT);
} if (iicstat & S3C2410_IICSTAT_START)
dev_warn(i2c->dev, "timeout waiting for bus idle\n"); out:
return ret;
}

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

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

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

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

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

 static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
struct i2c_msg *msg)
{
unsigned int addr = (msg->addr & 0x7f) << ;
unsigned long stat;
unsigned long iiccon; stat = ;
stat |= S3C2410_IICSTAT_TXRXEN; if (msg->flags & I2C_M_RD) {
stat |= S3C2410_IICSTAT_MASTER_RX;
addr |= ;
} else
stat |= S3C2410_IICSTAT_MASTER_TX; if (msg->flags & I2C_M_REV_DIR_ADDR)
addr ^= ; /* todo - check for wether ack wanted or not */
s3c24xx_i2c_enable_ack(i2c); iiccon = readl(i2c->regs + S3C2410_IICCON);
writel(stat, i2c->regs + S3C2410_IICSTAT); dev_dbg(i2c->dev, "START: %08lx to IICSTAT, %02x to DS\n", stat, addr);
writeb(addr, i2c->regs + S3C2410_IICDS); /* delay here to ensure the data byte has gotten onto the bus
00000192 * before the transaction is started */ ndelay(i2c->tx_setup); dev_dbg(i2c->dev, "iiccon, %08lx\n", iiccon);
writel(iiccon, i2c->regs + S3C2410_IICCON); stat |= S3C2410_IICSTAT_START;
writel(stat, i2c->regs + S3C2410_IICSTAT);
}

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,它的定义:

 static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)
{
struct s3c24xx_i2c *i2c = dev_id;
unsigned long status;
unsigned long tmp; status = readl(i2c->regs + S3C2410_IICSTAT); if (status & S3C2410_IICSTAT_ARBITR) {
/* deal with arbitration loss */
dev_err(i2c->dev, "deal with arbitration loss\n");
} if (i2c->state == STATE_IDLE) {
dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n"); tmp = readl(i2c->regs + S3C2410_IICCON);
tmp &= ~S3C2410_IICCON_IRQPEND;
writel(tmp, i2c->regs + S3C2410_IICCON);
goto out;
} /* pretty much this leaves us with the fact that we've
00000446 * transmitted or received whatever byte we last sent */ i2s_s3c_irq_nextbyte(i2c, status); out:
return IRQ_HANDLED;
}

429行,读取状态寄存器。

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

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

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

 static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
{
unsigned long tmp;
unsigned char byte;
int ret = ; switch (i2c->state) { case STATE_IDLE:
dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
goto out;
break; case STATE_STOP:
dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
s3c24xx_i2c_disable_irq(i2c);
goto out_ack; case STATE_START:
/* last thing we did was send a start condition on the
00000277 * bus, or started a new i2c message
00000278 */ if (iicstat & S3C2410_IICSTAT_LASTBIT &&
!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
/* ack was not received... */ dev_dbg(i2c->dev, "ack was not received\n");
s3c24xx_i2c_stop(i2c, -ENXIO);
goto out_ack;
} if (i2c->msg->flags & I2C_M_RD)
i2c->state = STATE_READ;
else
i2c->state = STATE_WRITE; /* terminate the transfer if there is nothing to do
00000295 * as this is used by the i2c probe to find devices. */ if (is_lastmsg(i2c) && i2c->msg->len == ) {
s3c24xx_i2c_stop(i2c, );
goto out_ack;
} if (i2c->state == STATE_READ)
goto prepare_read; /* fall through to the write state, as we will need to
00000306 * send a byte as well */ case STATE_WRITE:
/* we are writing data to the device... check for the
00000310 * end of the message, and if so, work out what to do
00000311 */ if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
if (iicstat & S3C2410_IICSTAT_LASTBIT) {
dev_dbg(i2c->dev, "WRITE: No Ack\n"); s3c24xx_i2c_stop(i2c, -ECONNREFUSED);
goto out_ack;
}
} retry_write: if (!is_msgend(i2c)) {
byte = i2c->msg->buf[i2c->msg_ptr++];
writeb(byte, i2c->regs + S3C2410_IICDS); /* 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 */ ndelay(i2c->tx_setup); } else if (!is_lastmsg(i2c)) {
/* we need to go to the next i2c message */ dev_dbg(i2c->dev, "WRITE: Next Message\n"); i2c->msg_ptr = ;
i2c->msg_idx++;
i2c->msg++; /* check to see if we need to do another message */
if (i2c->msg->flags & I2C_M_NOSTART) { if (i2c->msg->flags & I2C_M_RD) {
/* cannot do this, the controller
00000350 * forces us to send a new START
00000351 * when we change direction */ s3c24xx_i2c_stop(i2c, -EINVAL);
} goto retry_write;
} else {
/* send the new start */
s3c24xx_i2c_message_start(i2c, i2c->msg);
i2c->state = STATE_START;
} } else {
/* send stop */ s3c24xx_i2c_stop(i2c, );
}
break; case STATE_READ:
/* 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 */ byte = readb(i2c->regs + S3C2410_IICDS);
i2c->msg->buf[i2c->msg_ptr++] = byte; prepare_read:
if (is_msglast(i2c)) {
/* last byte of buffer */ if (is_lastmsg(i2c))
s3c24xx_i2c_disable_ack(i2c); } else if (is_msgend(i2c)) {
/* ok, we've read the entire buffer, see if there
00000388 * is anything else we need to do */ if (is_lastmsg(i2c)) {
/* last message, send stop and complete */
dev_dbg(i2c->dev, "READ: Send Stop\n"); s3c24xx_i2c_stop(i2c, );
} else {
/* go to the next transfer */
dev_dbg(i2c->dev, "READ: Next Transfer\n"); i2c->msg_ptr = ;
i2c->msg_idx++;
i2c->msg++;
}
} break;
} /* acknowlegde the IRQ and get back on with the work */ out_ack:
tmp = readl(i2c->regs + S3C2410_IICCON);
tmp &= ~S3C2410_IICCON_IRQPEND;
writel(tmp, i2c->regs + S3C2410_IICCON);
out:
return ret;
}

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

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

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

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

297行,is_lastmsg函数的定义:

 static inline int is_lastmsg(struct s3c24xx_i2c *i2c)
{
return i2c->msg_idx >= (i2c->msg_num - );
}

因为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函数的定义:

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

因为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函数,它的定义如下:

 static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
{
unsigned long iicstat = readl(i2c->regs + S3C2410_IICSTAT); dev_dbg(i2c->dev, "STOP\n"); /* stop the transfer */
iicstat &= ~S3C2410_IICSTAT_START;
writel(iicstat, i2c->regs + S3C2410_IICSTAT); i2c->state = STATE_STOP; s3c24xx_i2c_master_complete(i2c, ret);
s3c24xx_i2c_disable_irq(i2c);
}

205行,读取状态寄存器。

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

213行,i2c->state = STATE_STOP。

215行,调用s3c24xx_i2c_master_complete函数。

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

 static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)
{
dev_dbg(i2c->dev, "master_complete %d\n", ret); i2c->msg_ptr = ;
i2c->msg = NULL;
i2c->msg_idx++;
i2c->msg_num = ;
if (ret)
i2c->msg_idx = ret; wake_up(&i2c->wait);
}

113至118行,不用说了。

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

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

结束语

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