上一篇,我介绍了如何在uboot中添加i2c设备,以及移植i2c的读写接口。简单来说uboot阶段使用i2c设备和平台关联性比较大,但不同平台套路是差不多的。你可以将uboot阶段看作是引导android系统起来的另外一个系统。而系统起来后在kenerl中添加i2c设备就和uboot阶段差别非常大,内容要多很多。我仍然不会贴一大段一大段的代码上来,这没什么意义。我的目的更多的是给没玩过i2c的小伙伴看完这篇介绍后,能有个方向。
内容主要分两个方面,第一有关i2c的概念。第二在内核中添加i2c设备并实现读写的方法和流程。
首先来看第一方面,这涉及到几个点:
1. 设备树概念。
2. i2c总线概念。
3. i2c驱动
4. i2c控制器adapter
以上三点自行百度可以找到很详细的资料,在这里我只简单说明下:
1. 设备树你可以理解为它是用来专门保存板子上各个硬件设备信息的一个文件。比如某个设备GPIO口是多少,状态是否为打开,寄存器地址多少等等。你可能需要这这里添加你的设备信息。
2. i2c驱动你可以简单理解为对于应用层来说,驱动就是应用层沟通底层硬件设备的桥梁(i2c-内核层),应用层会调用驱动层的接口来沟通底层硬件。驱动主要负责拿到上层要对硬件操作的数据,然后提供给i2c控制器对硬件进行读写。
3. 总线就是负责匹配驱动与设备树硬件信息及adapter信息。
4. i2c控制器adapter和硬件相关,比如amlogic平台有5组i2c控制器。它的作用是从驱动中拿到数据后负责将数据写入硬件中。
我没有仔细去研究底层代码,大概的看了下,总的来说我的理解是设备树中包含设备信息还有当前设备所在的adapter。在加载kernel的过程中会被拿出来,通过总线匹配到相对应的i2c驱动(匹配的方式是compatible name), 匹配完后,客户就可以通过i2c驱动中提供的接口,利用匹配的i2c adapter对i2c设备进行读写。
概念简单介绍完了,接下来就是重点如何在内核中添加i2c设备并实现读写。
通常在kernel中添加i2c设备的方式一般有两种:
方式一:(不推荐) 自己在kernel中写一个驱动,然后给接口上层去调用。如果你打算自己写个驱动,那么kernel目录下的Documentation\i2c中的文件说明可以帮助你。写完驱动后你还需要在dts中,需要配置硬件的信息如下:(参考dts文件路径,内核目录下:arch\arm64\boot\dts\amlogic)
&i2c_ao {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&d_i2c_master>;
at24 {
dev_name = "at24";
reg = <0x50>;
pagesize = <8>;
........
};
};
这个dts的意思是,在i2c d组下,挂载了at24这个设备,kernel中的at24的驱动,会调用到这个dts。
对于i2c控制器本身信息也要在添加在dtsi文件中如下:(参考路径:arch/arm64/boot/dts/amlogic/mesongxl.dtsi 注意文件名是dtsi我没有写错)
i2c_ao: i2c@c8100500{
compatible = "amlogic, meson-i2c";
dev_name