一、设备树中I2C节点的解析流程
/* i2c 控制器节点 */
i2c0: i2c@2180000 {
compatible = "fsl,vf610-i2c";
/*reg = <address1 length2 [address2 length3] [address3 length4]..>*/
#address-cells = <1>; /* address一个32位表示*/
#size-cells = <0>; /* length位空*/
reg = <0x0 0x2180000 0x0 0x10000>;
interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;/*GIC_SPI SPI:shared processor interrupts 中断号 32 ~32+224 88号中断 IRQ_TYPE_LEVEL_HIGH触发方式 */
clock-names = "i2c";
clocks = <&platform_clk 1>; /*使用的时钟*/
status = "disabled";
};
reg = <0x0 0x2180000 0x0 0x10000>解析:
I2C地址0x2180000物理地址,映射长度0x10000,要使用这个物理地址先要在驱动中将其映射成虚拟地址。
/* i2c设备节点 */
&i2c0 {/* 引用i2c控制器0相当于它的子节点 */
status = "okay";
lm75@49 {
compatible = "ti,lm75";
reg = <0x49>;
};
lm75@4a {
compatible = "ti,lm75";
reg = <0x4a>;
};
};
/i2c0节点一般表示i2c控制器, 它会被转换为platform_device, 在内核中有对应的platform_driver;
/i2c0/lm75@49节点不会被转换为platform_device, 它被如何处理完全由父节点的platform_driver决定, 一般是被创建为一个i2c_client。
设备树的匹配流程:
platform_match:
1、match driver.of_match_table:of_driver_match_device //设备树解析
2、match driver.acpi_match_table
3、match platform_driver.id_table
4、match 设备的name和driver.name
上面四个任意匹配成功就算匹配ok。
代码流程:
static const struct of_device_id i2c_imx_dt_ids[] = {
{ .compatible = "fsl,imx1-i2c", .data = &imx1_i2c_hwdata, },
{ .compatible = "fsl,imx21-i2c", .data = &imx21_i2c_hwdata, },
{ .compatible = "fsl,vf610-i2c",/* 对应设备树compatible */ .data = &vf610_i2c_hwdata, },
{ /* sentinel */ }
};
static struct platform_driver i2c_imx_driver = {
.probe = i2c_imx_probe,
.remove = i2c_imx_remove,
.driver = {
.name = DRIVER_NAME,
.pm = I2C_IMX_PM_OPS,
.of_match_table = i2c_imx_dt_ids,
},
.id_table = imx_i2c_devtype,
};
/* 将设备树转换成platform_device后i2c_imx_probe函数被调用 */
i2c_imx_probe
i2c_add_numbered_adapter /* 添加I2C控制器 */
__i2c_add_numbered_adapter
i2c_register_adapter /* 注册I2C控制器 */
device_register /* I2C控制器设备注册 */
of_i2c_register_devices /* 查找设备树控制器下面的从设备 */
of_i2c_register_device
i2c_new_device
client->dev.bus = &i2c_bus_type;
device_register /* 添加设备I2C从设备 */
i2c_scan_static_board_info /* 查找静态表,有些I2C设备是在代码中写死的,不是通过设备树的形式 */
i2c_new_device
client->dev.bus = &i2c_bus_type;
device_register /* 添加设备I2C从设备 */
/* 添加设备成功后lm75@49几点的I2C设备将通过i2c_bus_type.i2c_device_match匹配驱动程序。*/
static const struct of_device_id lm75_of_match[] = {
{
.compatible = "ti,tmp75",
.data = (void *)tmp75
},
。。。。
}
static struct i2c_driver lm75_driver = {
.class= I2C_CLASS_HWMON,
.driver = {
.name= "lm75",
.of_match_table = of_match_ptr(lm75_of_match),
.pm= LM75_DEV_PM_OPS,
},
.probe= lm75_probe,
.id_table= lm75_ids,
.detect= lm75_detect,
.address_list= normal_i2c,
};
lm75_probe函数将被调用。
二、SPI设备树节点处理流程
xx_spi_probe
spi_bitbang_start
spi_register_master->spi_register_master
of_register_spi_devices
of_register_spi_device
spi_add_device /* 和i2c_new_device处理流程就一样了匹配设备驱动 */
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。