在完成platform_device的添加之后,i2c子系统将进行platform_driver的注册过程。
platform_driver的注册通过调用初始化函数i2c_adapter_s3c_init函数来完成。
i2c_adap_s3c_init()函数体如下:
s3c24xx_i2c_driver的工作。s3c24xx_i2c_driver如下:
platform_driver在注册到platform_bus总线的过程中会尝试将已注册的platform_driver
与已注册到platform_bus上的所有platform_device进行配对。
platform_bus总线的相关操作如下:
此处就是根据platfor_device和platform_driver的名字来实现配对。但是platform_driver有好几个名字
可以选择,通过id_table来实现配对。执行到此处,之前已注册到platform_bus的platform_device
型设备s3c_devicei2c0和现在刚注册到platform_bus总线的platfor_drver型驱动s3c24xx_i2c_drive将
实现配对成功。
成功配对之后将尝试进行probe
调用驱动中的probe,即platform_driver.drv->probe,而platform_bus本身未初始化probe方法,
所以此处调用驱动的probe方法,驱动的probe在注册过程中已被初始化
调用此驱动的probe方法,即s3c24xx_i2c_probe函数。
probe函数的功能如下:
1.首先创建struct s3c24xx_i2c *i2c。
i2c相关数据的初始化来源于s3c2_device_i2c0.dev.platdata。
2.通过i2c->adap.algo = &s3c24xx_i2c_algorithm;初始化algo方法。
在write系统调用的时候会调用到s3c24xx_i2c_algorithm函数。
3.init_waitqueue_head(&i2c->wait); 初始化一个等待队列
4.s3c24xx_i2c_init (i2c);初始化i2c控制器,主要是对s3c24xx的i2c控制
寄存器进行一些操作,比如配置s3c2440i/o功能,设置从机地址,以及
设置i2c时钟频率等相关操作。时钟频率的设置参见博文。
5.request_irq(i2c->irq, s3c24xx_i2c_irq, IRQF_DISABLED,
dev_name(&pdev->dev), i2c);
申请中断,内核中的i2c读写是通过中断来实现的,具体稍后分析
6.i2c_add_numbered_adapter(&i2c->adap);最后向系统注册一个i2c adapter
这里需要着重注意第2、5、6点。
下面先分析第6点。第2、5点待到后面读写at24c02的时候再分析。
相关阅读: