1. init/exit
module_init(lm49350_i2c_init);
module_exit(lm49350_i2c_exit);
static int __init lm49350_i2c_init(void)
{
return i2c_add_driver(&lm49350_driver);
}
static void __exit lm49350_i2c_exit(void)
{
i2c_del_driver(&lm49350_driver);
}
2. lm49350_driver 内容:
MODULE_DEVICE_TABLE(i2c, lm49350_id);
/* This is the driver that will be inserted */
static struct i2c_driver lm49350_driver = {
.driver = {
.name = "lm49350",
},
.probe = lm49350_probe,
.remove = lm49350_remove,
.id_table = lm49350_id,
};
3. lm49350_probe()
/* This function is called by i2c_probe */
static int lm49350_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lm49350_data *data; //lm49350_data 代表该芯片 i2c功能的数据
printk(KERN_INFO"lm49350 probe\n");
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA
| I2C_FUNC_SMBUS_READ_BYTE)) //核查 client->adapter 支持那些功能
return 0;
if (!(data = kzalloc(sizeof(struct lm49350_data), GFP_KERNEL))) //kzalloc分配内存并置0
return -ENOMEM;
lm49350_client = client; //如果匹配到数据,则赋值client给全局变量lm49350_client.
/* Init real i2c_client */
i2c_set_clientdata(client, data); //把data传给client,初始化数据
mutex_init(&data->update_lock); //初始化互斥锁
return 0;
}
lm49350_data
/* Each client has this additional data */
struct lm49350_data {
struct i2c_client client;
struct mutex update_lock;
u32 valid;
};
lm49350_remove
/* Will be called for both the real client and the fake client */
static int lm49350_remove(struct i2c_client *client)
{
struct lm49350_data *data = i2c_get_clientdata(client);
if (data) /* real client */
kfree(data);
return 0;
}
4. probe结束后,就会开始添加各种功能型函数。表示该I2C设备所具有的功能,供内核调用。并用EXPORT_SYMBOL()引出。
EXPORT_SYMBOL(lm49350_i2c_read);
EXPORT_SYMBOL(lm49350_i2c_write);
EXPORT_SYMBOL(lm49350_i2c_setbit);
EXPORT_SYMBOL(lm49350_i2c_getbit);
EXPORT_SYMBOL(lm49350_i2c_clrbit);
int lm49350_i2c_read(u8 reg)
{
int ret;
ret = i2c_smbus_read_byte_data(lm49350_client, reg);
return ret;
}
int lm49350_i2c_write(u8 value, u8 reg)
{
int ret;
ret = i2c_smbus_write_byte_data(lm49350_client, reg, value);
udelay(500);
return ret;
}
int lm49350_i2c_getbit(u8 reg, u8 bit)
{
int value;
value = i2c_smbus_read_byte_data(lm49350_client, reg);
return (value & (1 << bit));
}
int lm49350_i2c_setbit(u8 reg, u8 bit)
{
int ret;
int value;
value = i2c_smbus_read_byte_data(lm49350_client, reg);
value |= (1 << bit);
ret = i2c_smbus_write_byte_data(lm49350_client, reg, value);
udelay(500);
return ret;
}
int lm49350_i2c_clrbit(u8 reg, u8 bit)
{
int ret;
int value;
value = i2c_smbus_read_byte_data(lm49350_client, reg);
value &= ~(1 << bit);
ret = i2c_smbus_write_byte_data(lm49350_client, reg, value);
return ret;
}