现在很多外设都会用到IIC来进行通讯,记录iic写驱动的写法,以g-sensor操作为例
首先需要将IIC操作的设备挂载的IIC总线上去,有两种写法
1.在arch/arm/mach-s5pv210/mach-x210.c中添加设备到相应的IIC总线上,示例如下
static struct i2c_board_info s5k4ba_i2c_info = {
I2C_BOARD_INFO("S5K4BA", 0x2d),
.platform_data = &s5k4ba_plat,
};
/* I2C2 */
static struct i2c_board_info i2c_devs2[] __initdata = {
{
#if defined(CONFIG_SMDKC110_REV03) || defined(CONFIG_SMDKV210_REV02)
/* The address is 0xCC used since SRAD = 0 */
I2C_BOARD_INFO("max8998", (0xCC >> 1)),
.platform_data = &max8998_pdata,
#else
/* The address is 0xCC used since SRAD = 0 */
I2C_BOARD_INFO("max8698", (0xCC >> 1)),
.platform_data = &max8698_pdata,
#endif
},
};
这样在IIC总线初始化过程中就会为我们的iic设备分配相应的client结构体并自动注册,我们只需要实现我们的驱动程序即可。
2.直接在驱动里面来添加我们的iIC设备,虽然这不是正规的设备和驱动分离思想,但是还是应该知道如何去在驱动中添加IIC设备,这样能看懂其他不是正规做法的代码。
在驱动程序中添加IIC设备如下代码示例:
static int KXTF9_i2c_register(void)
{
struct i2c_board_info info;
struct i2c_adapter *adapter; //adapter 即iic总线
struct i2c_client *client; //client 即iIC设备
//分配设置一个 i2c_board_info
memset(&info, 0, sizeof(struct i2c_board_info));
info.addr = KXTF9_I2C_ADDRESS;
strlcpy(info.type, "s3c-Gsensor-kxtf9", I2C_NAME_SIZE); //I2C_NAME_SIZE 20
adapter = i2c_get_adapter(I2C_BUS); //I2C_BUS 0 获得IIC0 总线adapter
if (!adapter)
{
sensor_dbg(KERN_ERR "can't get i2c adapter 0 for s3c-Gsensor-kxtf9\n");
return -ENODEV;
}
client = i2c_new_device(adapter, &info); //在iIC0 总线上添加刚才构造的i2c_board_info 得到一个client
i2c_put_adapter(adapter);
if (!client)
{
sensor_dbg(KERN_ERR "can't add i2c device at 0x%x\n", (unsigned int)info.addr);
return -ENODEV;
}
sensor_i2c_client = client;
return 0;
}
在驱动注册中匹配到设备相应的probe函数会被执行
static const struct i2c_device_id sensor_i2c_id[] = {
{ "s3c-Gsensor-kxtf9", 0, },
{ }
};
static struct i2c_driver sensor_i2c_driver = {
.driver = {
.name = "s3c-Gsensor-kxtf9",
.owner = THIS_MODULE,
},
.probe = sensor_i2c_probe,
.remove = sensor_i2c_remove,
//.suspend = sensor_i2c_suspend,
//.resume = sensor_i2c_resume,
.id_table = sensor_i2c_id, //driver name匹配上面的i2c_board_info 里面的type名称 执行probe函数
};
static int sensor_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct sensor_i2c_chip_info *chip;
chip = kzalloc(sizeof(struct sensor_i2c_chip_info), GFP_KERNEL);
if(chip == NULL)
{
sensor_dbg("\n tcc_sensor_i2c : no chip info. \n");
return -ENOMEM;
}
chip->client = client;
i2c_set_clientdata(client, chip);
//sensor_i2c_client = client;
return 0;
}