MID 驱动之二: G-sensor

G-sensor驱动和TP驱动基本是一样的,因为他们都是通过i2c来传输命令和数据,另外都将数据解析后,上报到输入子系统中。整个驱动的流程和TP驱动是一样的,我还是讲整个驱动流程分析一下。

驱动入口函数:late_initcall(BMA250_init);

进入BMA250_init()函数,开头非常明显定义了三个重要变量

struct i2c_board_info info;

struct i2c_adapter *adapter;

struct i2c_client *client;

紧接着就是info和adapter收集资源,注册i2c_clint,函数为client = i2c_new_device(adapter, &info);接下来是注册i2c_driver,函数为i2c_add_driver(&bma250_driver);根据匹配过程,probe函数被调用,进入到bma250_probe()函数。

bma250_probe()函数开头定义了一个重要的指针,struct bma250_data *data;看到这个,我们会觉得和TP的驱动如此相似,有一点不一样的话,bma250_data结构体中有一个regulator指针,应该可以通过编程控制电源供应。有关regulator的详细资料,可以参考:

http://lhsblog01.blog.163.com/blog/static/1020045192010221104120218/

regulator =regulator_get(&client->dev, buf);

err = regulator_set_voltage(regulator,2800000, 2800000);

err = regulator_enable(regulator);

设置电源管理

接着会检查adapter,分配structbma250_data的空间:

i2c_check_functionality(client->adapter, I2C_FUNC_I2C)

data = kzalloc(sizeof(struct bma250_data), GFP_KERNEL);

然后读取芯片id同时检查i2c能否正常通信

tempvalue= i2c_smbus_read_byte_data(client, BMA250_CHIP_ID_REG);

对structbma250_data结构体进行设置和初始化工作

i2c_set_clientdata(client,data);

data->bma250_client = client;

mutex_init(&data->value_mutex);

mutex_init(&data->mode_mutex);

mutex_init(&data->enable_mutex);

bma250_set_bandwidth(client,BMA250_BW_SET);

bma250_set_range(client,BMA250_RANGE_SET);

INIT_WORK(&data->irq_work,bma250_irq_work_func);

data->IRQ = client->irq;

然后会去注册中断

err= request_irq(data->IRQ, bma250_irq_handler, IRQF_TRIGGER_RISING,

"bma250",data);

接下来我们会发现一个很有趣的代码:

INIT_DELAYED_WORK(&data->work,bma250_work_func);

atomic_set(&data->delay,BMA250_MAX_DELAY);

atomic_set(&data->enable, 0);

这里会去初始化一个延时任务,设置延时时间。

原来在structbma250_data结构体中,有一个work_struct,就是中断处理下半部的任务,同时有一个delayed_work是用来定时上报G-sensor的xyz坐标的,我去查看了bma150中的代码,发现bma150中并没有采用中断的方式,而是直接采用延时任务,应该是bma250添加了中断处理。

还剩下的事情就是输入子系统的申请,绑定和注册了

dev= input_allocate_device();

input_set_drvdata(dev,data);

data->input= dev;

err= input_register_device(dev);

除了在内核中注册中断子系统以外,还要将它映射到用户空间,供用户空间使用,下面这个函数会实现:

err =sysfs_create_group(&data->input->dev.kobj,&bma250_attribute_group);

有关sysfs的更多知识可以参考:

http://blog.csdn.net/suwenqiang2011/article/details/8613818

关于G-sensor的处理流程,我们到中断处理函数bma250_irq_handler()以及延时任务函数bma250_work_func()中去看看就知道了

bma250_irq_handler()的内容仅仅有一个函数

schedule_work(&data->irq_work);

为什么这里和TP驱动中的中断处理函数内容:queue_work(ts->elan_wq,&ts->work);有所不一样呢,原来在TP驱动中,申请了一个工作队列,而G-sensor驱动使用的是默认工作队列,在每个cpu核上,都有一个默认的工作队列。

进入中断下半部,bma250_irq_work_func()主要就是接受数据,解析,然后上报,和TP的流程是一样的。

另外延时任务函数bma250_work_func()的内容也很简单,时间到了就读取G-sensor的当前值,然后上报:

bma250_read_accel_xyz(bma250->bma250_client,&acc);

input_report_abs(bma250->input,ABS_X, acc.x);

input_report_abs(bma250->input,ABS_Y, acc.y);

input_report_abs(bma250->input,ABS_Z, acc.z);

input_sync(bma250->input);

重新调度延时任务:

schedule_delayed_work(&bma250->work,delay);

整个G-sensor驱动的分析就完成了,主要使用到了i2c设备驱动,中断下半部-工作队列,延时任务,中断,输入子系统等知识。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值