啊啊啊
2016-02-21 16:59
204 查看
static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat){unsigned long tmp;unsigned char byte;int ret = 0;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 * bus, or started a new i2c message *//**I2C_M_IGNORE_NAK :当前i2c_msg 忽略i2c器件的ack、nack信号如果没有收到ack信号,并且没有设置忽略ack,那么就停止这次传输*/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;}// I2C_M_RD : 读操作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 * as this is used by the i2c probe to find devices. */if (is_lastmsg(i2c) && i2c->msg->len == 0) {s3c24xx_i2c_stop(i2c, 0);goto out_ack;}if (i2c->state == STATE_READ)goto
prepare_read;/* fall through to the write state, as we will need to * send a byte as well */case STATE_WRITE:/* we are writing data to the device... check for the * end of the message, and if so, work out what to do */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 * data setup time on the bus, as writing the * data to the register causes the first bit * to appear on SDA, and SCL will change as * 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 = 0;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 * forces us to send a new START * 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,
0);}break;case STATE_READ:/* we have a byte of data in the data register, do * something with it, and then work out wether we are * going to do any more read/write */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 * 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, 0);} else {/* go to the next transfer */dev_dbg(i2c->dev, "READ: Next Transfer\n");i2c->msg_ptr = 0;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;}
"%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 * bus, or started a new i2c message *//**I2C_M_IGNORE_NAK :当前i2c_msg 忽略i2c器件的ack、nack信号如果没有收到ack信号,并且没有设置忽略ack,那么就停止这次传输*/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;}// I2C_M_RD : 读操作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 * as this is used by the i2c probe to find devices. */if (is_lastmsg(i2c) && i2c->msg->len == 0) {s3c24xx_i2c_stop(i2c, 0);goto out_ack;}if (i2c->state == STATE_READ)goto
prepare_read;/* fall through to the write state, as we will need to * send a byte as well */case STATE_WRITE:/* we are writing data to the device... check for the * end of the message, and if so, work out what to do */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 * data setup time on the bus, as writing the * data to the register causes the first bit * to appear on SDA, and SCL will change as * 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 = 0;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 * forces us to send a new START * 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,
0);}break;case STATE_READ:/* we have a byte of data in the data register, do * something with it, and then work out wether we are * going to do any more read/write */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 * 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, 0);} else {/* go to the next transfer */dev_dbg(i2c->dev, "READ: Next Transfer\n");i2c->msg_ptr = 0;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;}
相关文章推荐
- Flex和Servlet结合上传文件报错(二)
- HDU4292-Food-网络流
- Max Sum of Max-K-sub-sequence(单调队列)
- Presents(CodeForces 136A)
- i2s_s3c_irq_nextbyte
- POJ 2288 Islands and Bridge 状压DP
- python:python对象属性及属性函数property()
- python类:属性
- 28. Implement strStr()
- 何为Java引用
- 杭电1175——连连看(DFS)
- spark_3:spark的基础
- 高精度模板总结(string 实现加、减、乘、除)常用版
- JSP内置对象
- Windows命令行视频教程-01-简介命令提示符
- 点击某一个cell中的button,确定这个button所在的行(找superview)
- g++编译时默认支持C++11的几个配置小方法
- android 网络框架性能优化分析
- CodeForces512C-Pluses everywhere-模拟/数学/排列组合模板
- c++的坚持