I2C驱动

1、 I2C总线驱动

1、 dtsi配置:msm8937.dtsi
i2c_3: i2c@78b7000 { /* BLSP1 QUP3 */
compatible = “qcom,i2c-msm-v2”;
2、 驱动文件:i2c-msm-v2.c
1) 总线驱动本身是个platform设备
2) 调用I2C核心层的API,注册一个adapter
i2c_msm_probe–>i2c_msm_frmwrk_reg–>i2c_add_numbered_adapter (adap->nr=3,I2C的编号为3)—>__i2c_add_numbered_adapter–>i2c_register_adapter
3) i2c_register_adapter(I2C核心层API)
adap->dev.bus = &i2c_bus_type;
adap->dev.type = &i2c_adapter_type;
res = device_register(&adap->dev);
4.1)device_register //adapter 本身作为devices注册
4.2)of_i2c_register_devices---->of_i2c_register_device—>i2c_new_device //解析dtsi中的i2c下的子节点作为client挂在adapter下面。
在adapter下挂在client
5)i2c的adapter是通过结构体里的nr来区分的,nr的值来自于设备树里的i2c_3: i2c@78b7000… i2c_3,则nr=3
3、 文件节点信息(kobject、kset)
I2C驱动_第1张图片

2、 tp I2C设备驱动

1、 dtsi配置:zql1695-tp.dtsi
&i2c_3 {
#address-cells = <1>;
#size-cells = <0>;

status = "ok";
focaltech@38{
	compatible = "focaltech,ft5446";
	reg = <0x38>;
	status = "ok";
	interrupt-parent = <&tlmm>;
	interrupts = <65 0x2>;
	vdd-supply = <&pm8953_l10>;
	//vcc_i2c-supply = <&pm8953_l5>;
	focaltech,reset-gpio = <&tlmm 64 0x0>;
	focaltech,irq-gpio = <&tlmm 65 0x2008>;
	focaltech,max-touch-number = <10>;
	focaltech,display-coords =  <0 0 720 1520>;
};

2、 驱动文件:drivers/input/touchscreen/focaltech_touch_1695/focaltech_core.c

  1. tp 设备本身属于I2C设备
    static struct i2c_driver fts_ts_driver = {
    .probe = fts_ts_probe,
    .remove = fts_ts_remove,
    .driver = {
    .name = FTS_DRIVER_NAME,
    .owner = THIS_MODULE,
    .of_match_table = of_match_ptr(fts_dt_match),
    },
    .id_table = fts_ts_id,
    .shutdown = fts_shutdown,
    };
  2. 注册一个I2C设备驱动,如何调用到probe函数,即:fts_ts_probe
    i2c_add_driver
    —> i2c_register_driver driver->driver.bus = &i2c_bus_type 绑定总线类型
    —> driver_register
    —> bus_add_driver
    —>driver_attach
    —>bus_for_each_dev //便利总线上的device,和driver匹配
    —>__driver_attach
    —>1)driver_match_device //调用i2c_device_match(I2c-core中定义的API .match)继续调用of_driver_match_device匹配成功则返回1,失败返回0,匹配原则:cpmcompatible(优先级最高) type(优先级次之) name(优先级最低)
    —>2)driver_probe_device—>really_probe—> dev->bus->probe(dev)(如果dev所属总线定义了probe接口,则优先调用)
    —>i2c_device_probe //I2c-core中定义的API .probe —>status = driver->probe(client, i2c_match_id(driver->id_table, client));
    ---->fts_ts_probe //TP设备驱动中的probe入口函数

总结:

struct bus_type i2c_bus_type = {
	.name		= "i2c",
	.match		= i2c_device_match,
	.probe		= i2c_device_probe,
	.remove		= i2c_device_remove,
	.shutdown	= i2c_device_shutdown,
};

注册一个I2C设备驱动到调用到对应的probe函数主要分为2点:
1)调用i2c_device_match 接口,遍历adapter上的client 与driver中的compatible 是否匹配,adapter上的client是注册总线驱动的时候从dts解析出来的。
2)匹配成功则调用i2c_device_probe,进一步调用到driver中的probe接口

3、 I2C核心层

Linux I2C子系统提炼出来的一些API给I2C总线驱动和I2C设备驱动调用

你可能感兴趣的:(KERNEL)