ast2600 i2c framework
我们知道i2c总线操作都是master发起,slave接收。当BMC主动读取i2c slave设备的数据,比如传感器等,此时BMC为i2c master,传感器为i2c slave;当i2c外设要上报事件event时,i2c外设为master, BMC则成为了i2c slave.
本文基于aspeed ast2600全面介绍这两种情况下的i2c framework.(文章内容比较长,因为直接贴代码截图的)
/dev/i2cX是i2c总线设备驱动文件。I2C总线是一种字符设备。
先来看驱动drivers/i2c/i2c-core-base.c
驱动drivers/i2c/i2c-core-base.c注册了i2c总线类i2c_bus_type,我们说的i2c0等具体的i2c总线需要注册到这个i2c_bus_type.
再来看驱动drivers/i2c/i2c-dev.c
驱动drivers/i2c/i2c-dev.c主要是给i2c_bus_type注册了一个notifier。 当i2c0等具体的总线设备i2c adapter注册的时候,会触发这个notifier的调用。这个notifer的主要工作就是创建对应的字符设备文件I2C0、I2C1等。 我们来看一下这个notify: i2cdev_notifier_call()
i2cdev_notifier_call() -----> i2cdev_attach_adapter()
i2cdev_attach_adapter()的主要内容就是:
1. 分配设备号,主设备号为I2C_MAJOR,次设备号为 adapter->nr(就是DTS中的I2CX中的X)
2. 设置设备文件操作指针i2cdev_fops
3. 调用 cdev_device_add() -----> device_add() -----> devtmpfs_create_node()创建设备节点/dev/i2cX.
这些都是i2c base的东西和具体的i2c0、I2C1总线驱动无关。 下面,我们来分析aspeed-i2c总线驱动。
aspeed-i2c总线驱动: drivers/i2c/buses/i2c-aspeed.c(实际项目中可能不用这个驱动文件,而另写一个类似的,比如insyde BMC就重写了,用了i2c_drv/i2c-new-aspeed.c。不过没关系,我们不care具体的内容,只关注i2c框架的东西)
aspeed_i2c_probe_bus()先解析了DTS中的数据,配置i2c controller,最后调用 i2c_add_adapter()注册总线I2CX
i2c_add_adapter() -----> __i2c_add_numbered_adapter() -----> i2c_register_adapter() -----> device_register()