嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程

做嵌入式驱动开发的同学都知道总线这个概念

图片[1]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

以bear手机项目为例,我们看下linux下sys文件下注册的总线:

图片[2]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

linux sys文件夹下注册的总线

platform总线

platform总线为 linux 自身虚拟出来的一种概念总线,也有 device 和 driver 的概念,分别对
应 platform_device 和 platform_driver。

I2C bus
i2c 总线由于其自身的优势, 上面挂的设备比较多, 在 Bettle 上 i2c 的 source 有 3 根 mt-i2c.0,mt-i2c.1, mt-i2c.2。在 i2c 的驱动中 device 和 driver 分别对应 i2c_client, i2c_driver

图片[3]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

以i2c-0 为例上面挂了 i2c-0/0-0018( BMA222E) , i2c-0/0-0026( mtk-tpd) , i2c-0/0-0038(ft5316), i2c-0/0-0039(TMD2771), i2c-0/0-0048( stk3x1x)。
不同的数字表示了不同的设备在 i2c bus0 上的 address,由 i2c_board_info 结构指定,如:Msg_driver.c
static struct i2c_board_info __initdata i2c_tpd={ I2C_BOARD_INFO(\"mtk-tpd\", (0x4c>>1))};
//0x4c>>1 = 26
i2c_register_board_info(0, &i2c_tpd, 1); //0 为 bus number

ft6306_driver.c
static struct i2c_board_info __initdata ft5316_i2c_tpd={ I2C_BOARD_INFO(\"ft5316\",
(0x70>>1))}; //0x70>>1 = 38
i2c_register_board_info(0, &ft5316_i2c_tpd, 1 )

在register driver 的时候, 如果是挂在 BUS 上的 driver 和 device, 都需要一个 match 的过程,match 成功后才能注册。

图片[4]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

图片[5]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

图片[6]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

可知 i2c driver 和 device 的 match 是通过 name 来匹配的(对于挂在 sdio bus 上的 device的 match 是通过 vendor_id 和 device_id 来匹配的, 以下会做说明)。 虽然 i2c 的 match 过程中
是通过 name 来匹配的,但是很多时候还是需要读出 chip id(vendor_id),根据 id 号可以做
一些操作判断。 比如在有备料的时候, 有两套驱动在代码里面, 如何判断实际使用的是那颗controller ic 就需要去读 ic 的 id。如 触摸屏ft6306:

图片[7]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

上面可以看到,如果 vendor_id 号不匹配,则直接 mask 中断,关 LDO 。其 中FT5X0X_REG_FT5316ID 寄存器的值应该是由这颗 controller ic 的 datasheet 指定的

SDIO bus

SDIO 接口(卡) 由 SD 接口(卡)发展而来。 现阶段有很多类型的 SDIO 卡( Camera,BT,WLAN等) 。

sdio 驱动中 device 和 driver 对应 sdio_func 和 sdio_driver。和 i2c 一样,也是通过 bus 的match 函数来做匹配。最终是使用下面的函数进行匹配。

图片[8]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

以下说明如何读取 sdio_func 中的 vendor_id 和 device_id。通过该过程可以熟悉下 SDIO 的Spec 规范。(以下过程以 yokoto项目为例)

图片[9]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

跳过 card detect 部分,直接从 mmc_attach_sdio()开始

图片[10]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

图片[11]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

SD卡CIS信息

图片[12]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

注意上述过程中由于 CMD52 的 response 每次只能返回一个 byte, 故有些时候需要根据 SDIO
spec 的规定,读取一定的次数才能拿到完整的值。最后通过 cistpl_manfid()函数得到vendor=0x2d0 和 device=0x4330 。

上述以最简化的步骤给出了如果读取 sdio card 的 vendor 和 device 号,以保证 chip supplier的代码能够正确地被注册,其中省略了很多读取其他寄存器组的操作。 (参加完整代码和SDIO 的 spec )。

图片[13]-嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程-趣考网

好了,简单介绍了下linux下的i2cbus,sdio bus的匹配过程。详细的代码还需要根据spec去读取linux内核源码。针对有缘人,请佛系阅读,喜欢的话,请三连,后面有时间会多写写Linux内核驱动开发、inux调试及性能优化、嵌入式开发中经常用到的软件开发技能栈,比如netlink、mmap、dma、大数据传输、中断、多线程调度优化等常用必备技能

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享