Chinaunix首页 | 论坛 | 博客
  • 博客访问: 175907
  • 博文数量: 27
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 618
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-15 09:12
文章分类
文章存档

2014年(17)

2013年(10)

我的朋友

分类: LINUX

2013-11-22 17:03:24

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的方法。
















阅读(6006) | 评论(0) | 转发(1) |
0

上一篇:USB电池充电基础

下一篇:Workqueue机制

给主人留下些什么吧!~~