一.I2C核心
I2C核心提供I2C总线驱动和设备的注册、注销方法,I2C通信方法。在Linux驱动中对应driver/i2c/i2c-core.c文件。主要函数:
int i2c_add_adapter(struct i2c_adapter *adapter); //添加I2C总线驱动(不在芯片上)
int i2c_add_numbered_adapter(struct i2c_adapter *adap); //添加I2C总线驱动(在芯片上的)
i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info); //添加I2C设备
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); //I2C传输数据函数
二.I2C总线驱动
不同的芯片提供不同的I2C驱动,在Linux内核中,driver/i2c/busses/目录提高了许多芯片厂商的对应驱动,在这里列举下davinci芯片的I2C总线驱动,对应文件i2c-davinci.c。
流程:
1)在arch/arm/mach-davinci/device.c中添加I2C总线设备
static struct platform_device davinci_i2c_device = {
.name = "i2c_davinci",
.id = 1,
.num_resources = ARRAY_SIZE(i2c_resources),
.resource = i2c_resources,
};
void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
{
......
(void) platform_device_register(&davinci_i2c_device);
}
2)在drivers/i2c/busses/i2c-davinci.c中添加I2C总线驱动
static struct platform_driver davinci_i2c_driver = {
.probe = davinci_i2c_probe,
.remove = davinci_i2c_remove,
.driver = {
.name = "i2c_davinci",
.owner = THIS_MODULE,
},
};
static int __init davinci_i2c_init_driver(void)
{
return platform_driver_register(&davinci_i2c_driver);
}
static int davinci_i2c_probe(struct platform_device *pdev);//流程:1.获取平台设备所需要的各种资源;2.将I2C总线驱动添加到系统上,并设置I2C总线驱动的算法;
三.I2C设备驱动
以ds1307型号的RTC驱动为例
流程:
1)在arch/arm/mach-davinci/board-dm646x-evm.c中添加RTC对应的设备:
static struct i2c_board_info __initdata i2c_info[] = {
...
{
I2C_BOARD_INFO("ds1307", 0x68),//参数2为设备的地址
}
}
static void __init evm_init_i2c(void)
{
......
i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
}
2)在drivers/rtc/rtc-ds1307.c中添加RTC驱动
static struct i2c_driver ds1307_driver = {
.driver = {
.name = "rtc-ds1307",
.owner = THIS_MODULE,
},
.probe = ds1307_probe,
.remove = __devexit_p(ds1307_remove),
.id_table = ds1307_id,
};
static int __init ds1307_init(void)
{
return i2c_add_driver(&ds1307_driver);
}
//重要函数
static int __devinit ds1307_probe(struct i2c_client *client,
const struct i2c_device_id *id);
实现功能:
1.实现RTC设备初始化的步骤
2.对设备的读写函数进行赋值