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

原文: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函数的定义:

复制代码原文:https://www.cnblogs.com/lknlfy/p/3275875.html

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的作用是很类似的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
adc-keys 是一个内核模块,用于支持通过 ADC(模拟数字转换器)读取键盘按键数据的设备驱动程序。其数据结构与分析如下: 1. struct adc_keys_platform_data 该结构体为 adc-keys 提供了硬件相关的信息,包括 ADC 通道号、键位数组以及 ADC 转换值的范围等信息。具体定义如下: ``` struct adc_keys_platform_data { int num_adc; // ADC 通道数目 u16 adc_keycodes[MAX_ADC_KEYS]; // ADC 转换值对应的键码 u16 adc_keyvals[MAX_ADC_KEYS]; // ADC 转换值的实际值 int adc_key_nsamples; // ADC 转换值的采样次数 int adc_key_hold_time; // 长按时间 int adc_key_range; // ADC 转换值的范围 int acdbank; // ACDBANK(在某些板卡上才使用) int iface; // IFACE(在某些板卡上才使用) int stby_gpio; // 待机模式时是否需要禁止 ADC 转换 enum overflow_policy overflow_policy; // ADC 转换值超出范围时的处理策略 int allow_suspend; // 是否允许系统进入 suspend 模式 int wakeup_source; // 是否允许该设备作为唤醒源 int sleep_voltage; // 系统进入 SLEEP 状态时的电压 }; ``` 2. struct adc_keys_state 该结构体为 adc-keys 驱动提供了内部状态,用于记录键位状态、长按状态等信息。具体定义如下: ``` struct adc_keys_state { struct input_dev *input; // 与该设备关联的 input_dev struct delayed_work work; // 延迟工作队列,用于判断长按状态 s32 value; // 当前 ADC 转换值 s32 last_value; // 上一个 ADC 转换值 s32 active_idx; // 当前键位的索引 s64 event_time; // 上一个事件的时间戳 int state; // 按键状态(按下、弹起等) bool hold_reported; // 是否已经上报长按事件 bool use_hold; // 是否开启长按功能 }; ``` 3. adc_keys_probe adc-keys 设备驱动的 probe 函数,在设备挂载时会被 kernel 调用。此函数会读取和分析硬件相关的数据,包括通道数目、键码和实际值之间的映射关系等,并用这些信息初始化设备状态等数据结构。 4. adc_keys_read adc-keys 设备驱动的 read 函数,用于从 ADC 通道中读取键码信息。此函数首先进行 ADC 转换,然后通过查找 adc_keycodes 和 adc_keyvals 数组来映射实际值到键码。如果转换值超出了 adc_key_range 的范围,则根据 overflow_policy 进行相应的处理。 5. adc_keys_work 该函数作为延迟工作函数,在事件到来时可以被调用。它用于判断长按状态,如果长按事件未被上报,则在相应的时机上报长按事件并打印相应的信息。 总之,adc-keys 设备驱动通过一系列的数据结构来管理硬件和内部的状态信息,并通过 read 函数读取硬件信息、通过 work 函数处理事件的机制来实现键盘按键数据的采集和上报。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值