input模型之accelerometer驱动浅析
这个驱动可是看了好长时间了,现在总结一下,只是个人理解,如有错误欢迎指正,废话就不说了啊,现在开始了
一:硬件的加载
分心硬件驱动之前首先需要把硬件和驱动加载到系统中,也就是系统在启动的时候加载这些东东(我的这个代码是基于x86架构的,硬件是加速传感器:属于input设备,即accelerometer sensor)
Kernel/arch/x86/platform/intel-mid/device_libs/platform_lsm303dlh_acc.c
static struct i2c_board_info __initdatalsm303dlh_acc_i2c_board_info = {
I2C_BOARD_INFO("LSMAC303:00", 0x19),
};
static int __initlsm303dlh_acc_platform_init(void)
{
return i2c_register_board_info(5, &lsm303dlh_acc_i2c_board_info, 1);
}
module_init(lsm303dlh_acc_platform_init);
i2c_board_info是要注册的设备信息,其中"LSMAC303:00"是设备的名称,0x19是设备的地址,最后通过系统函数i2c_register_board_info来注册。那么已经加载的内核是如何和驱动匹配的呢,是很俗的方法就是通过名字来匹配的。
二:驱动浅析
具体的驱动分析之前我们先大致了解一下input设备驱动的原理(个人见解,勿喷)
上图为输入子系统的运行结构,如上图所示,输入子系统又分为设备驱动程序和事件驱动程序,事件驱动程序是负责和用户空间的交互程序(具体一点就是上报input_event给用户空间),而设备驱动程序是负责底层输入设备的管理及与底层输入设备的通信,后获得的数据后,上报数据时就交给时间驱动程序来处理
首先我们先找到驱动的具体位置,本例的位置是在:
Kernel/drivers/input/misc/lsm303dlhc_acc.c
static struct i2c_driverlsm303dlhc_acc_driver = {
.driver = {
.owner = THIS_MODULE,
.name = LSM303DLHC_ACC_DEV_NAME,
},
.probe =lsm303dlhc_acc_probe,
.remove =lsm303dlhc_acc_remove,
.suspend =lsm303dlhc_acc_suspend,
.resume =lsm303dlhc_acc_resume,
.id_table =lsm303dlhc_acc_id,
};
static int __init lsm303dlhc_acc_init(void)
{
pr_info("%saccelerometer driver: init\n",
LSM303DLHC_ACC_DEV_NAME);
returni2c_add_driver(&lsm303dlhc_acc_driver);
}
static void __exitlsm303dlhc_acc_exit(void)
{
pr_info("%saccelerometer driver exit\n",
LSM303DLHC_ACC_DEV_NAME);
i2c_del_driver(&lsm303dlhc_acc_driver);
return;
}
module_init(lsm303dlhc_acc_init);
module_exit(lsm303dlhc_acc_exit);
我们从下往上看代码首先是调用函数module_init来初始化驱动模块,调用的是lsm303dlhc_acc_init, lsm303dlhc_acc_init函数就是初始化具体的我们的加速传感器驱动的,调用系统函数i2c_add_driver把具体的驱动加入到系统中,而驱动结构体的初始化如代码所示,我们这里看一下
* @class: What kind of i2c device weinstantiate (for detect)
* @attach_adapter: Callback for bus addition(deprecated)
* @probe: Callback for device binding加载驱动是需要调用的函数
* @remove: Callback for device unbinding
* @shutdown: Callback for device shutdown
* @suspend: Callback for device suspend
* @resume: Callback for device resume
* @alert: Alert callback, for example for theSMBus alert protocol
* @command: Callback for bus-wide signaling(optional)
* @driver: Device driver model driver
* @id_table: List of I2C devices supported bythis driver
* @detect: Callback for device detection
* @address_list: The I2C addresses to probe(for detect)
* @clients: List of detected clients wecreated (for i2c-core use only)
struct i2c_driver{
unsigned int class;
int (*attach_adapter)(struct i2c_adapter *)__deprecated;
int (*probe)(struct i2c_client *, const structi2c_device_id *);
int (*remove)(struct i2c_client *);
void (*shutdown)(struct i2c_client *);
int (*suspend)(struct i2c_client *, pm_message_tmesg);
int (*resume)(struct i2c_client *);
void (*alert)(struct i2c_client *, unsigned int data);
int (*command)(struct i2c_client *client, unsigned intcmd, void