LSM303D 是ST的G和Compass集成的传感器芯片,同时支持Temp传感功能。
设备挂在I2C设备上所以开始使用 I2C_add_driver函数注册一个I2C设备
创建一个工作队列
lsm303d_workqueue = create_workqueue("lsm303d_workqueue");
初始化G-Sensor和Compass两个计时poll函数
hrtimer_init(&stat->hr_timer_acc, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
stat->hr_timer_acc.function = &poll_function_read_acc;
hrtimer_init(&stat->hr_timer_mag, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
stat->hr_timer_mag.function = &poll_function_read_mag;
初始化一个mutex锁,上锁,准备初始化芯片
mutex_init(&stat->lock);
mutex_lock(&stat->lock);
初始化数据,如果有平台数据就用平台数据,如果没有就是用默认数据
if (client->dev.platform_data == NULL) {
.......
} else {
.......
}
检查数据有效性,如果错误,使用默认值
lsm303d_acc_validate_pdata(stat);
lsm303d_mag_validate_pdata(stat);
芯片初始化数据
stat->pdata_acc->init();
stat->pdata_mag->init();
如果有GPIO No. 就会注册GPIO号,设置GPIO输入输出
硬件初始化写寄存器
lsm303d_hw_init(stat);
启动G-sensor和Compass 写寄存器
lsm303d_acc_device_power_on(stat);
lsm303d_mag_device_power_on(stat);
配置G参数
lsm303d_acc_update_fs_range(stat, stat->pdata_acc->fs_range);
lsm303d_mag_update_fs_range(stat, stat->pdata_mag->fs_range);
lsm303d_mag_update_odr(stat, stat->pdata_mag->poll_interval);
lsm303d_acc_update_filter(stat, stat->pdata_acc->aa_filter_bandwidth);
注册input设备
lsm303d_acc_input_init(stat);
lsm303d_mag_input_init(stat);
创建文件系统
create_sysfs_interfaces(&client->dev);
关闭G-sensor和Compass
lsm303d_acc_device_power_off(stat);
lsm303d_mag_device_power_off(stat);
初始化工作队列
INIT_WORK(&stat->input_work_acc, poll_function_work_acc);
INIT_WORK(&stat->input_work_mag, poll_function_work_mag);
初始化工作完毕
工作流程如下:
input子系统将打开设备stat->input_dev_acc->open = lsm303d_acc_input_open;
lsm303d的driver执行lsm303d_acc_enable(stat);
启动计时器开始干活hrtimer_start(&stat->hr_timer_acc, stat->ktime_acc, HRTIMER_MODE_REL)
到时间后执行poll_function_read_acc函数,在里面调度一个工作在工作队列queue_work中的任务queue_work(lsm303d_workqueue, &stat->input_work_acc);
在input_work_acc工作中将report数据,最后重新计时器启动.
上面就是lsm303D的驱动,以及设计流程,这是使用input的方法结合时间计时器和工作队列实现的,并没有使用irq,以后将在升级版本的芯片驱动中使用irq的方法。
阅读(6072) | 评论(0) | 转发(1) |