linux驱动开发:mma7660 sensor的配置

上一章节有介绍过这颗IC,是freescale的一个低精度的重力传感器吧。我认为,可以区分8个方向。x,y,z三轴。精度6bit,采样值范围[-32,+32].还有测量shake和tap等数据。
这边的驱动没有自己写.只是有看懂它原先的驱动是如何实现和工作的.
它的驱动引入了一个 hwmon device的注册。具体的作用是在sys/class/hwmon下生成了一个目录hwmonx。
它可以添加你设备的一些属性attr,以此来方便用户去read那些属性的状态。网上也有说借此来导出内核的信息非常方便,几乎所有的sensor都喜欢这样用。我们可以借用内核导出x,y,z三轴的值,来方便查看数据.介于此,我们可以添加相关的属性,当访问这些属性文件时,实则是在调用对应的接口函数。比如读相应的寄存器,再显示给用户界面。
另外一个:传感器元件,都有一个特性。周期性的采样数据并上报数据。
我们再实现触摸屏驱动的时候,当你有手触摸时,立即便会上报一次数据,否则则没有.按键也是一样。
像有的温度传感器,基本上是每次间隔一定的时间,才能采样一次准确的数据。并不是立刻就能获得数据的.需要一定的时间。
所以这边引入了一个input子系统的扩展:input_polled_dev.

我们依旧把它作为输入子系统来实现。上报x,y,z三轴的绝对坐标.

所以整个驱动的框架没变。新多出来的功能是 属性导出功能,hwmon设备的引入,和input_polled_dev的引入。

程序我都有注释过,初始化完毕后,当有触发过中断时,程序便会更新一次TILT状态寄存器。此时我们可以去读我们需要的数据。根据读到的数据做出相应的判断.比如说是否旋转屏幕。想一想手机的自动旋转功能,当我们把屏幕横着放时,画面会对应做旋转,这里面也是通过sensor来识别当前的位置,根据位置做出画面的相应调整。

常用的传感器很多很多。温度传感器,压力传感器,靠近传感器,声音传感器,加速度传感器等等。
我们今天实现的只是很小的一类中的特定一个传感器而已。

驱动实例:

/*
 * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#ifndef __LINUX_MMA7660_H
#define __LINUX_MMA7660_H

#include <linux/types.h>

#ifdef __KERNEL__

/* MMA7760 Registers */
#define MMA7660_XOUT            0x00    // 6-bit output value X
#define MMA7660_YOUT            0x01    // 6-bit output value Y
#define MMA7660_ZOUT            0x02    // 6-bit output value Z
#define MMA7660_TILT            0x03    // Tilt status
#define MMA7660_SRST            0x04    // Sampling Rate Status
#define MMA7660_SPCNT           0x05    // Sleep Count
#define MMA7660_INTSU           0x06    // Interrupt Setup
#define MMA7660_MODE            0x07    // Mode
#define MMA7660_SR              0x08    // Auto-Wake/Sleep and Debounce Filter
#define MMA7660_PDET            0x09    // Tap Detection
#define MMA7660_PD              0x0a    // Tap Debounce Count

struct mma7660_platform_data {
    /* eint connected to chip */
    int irq;

    /* parameters for input device */
    int poll_interval;
    int input_fuzz;
    int input_flat;
};

#endif /* __KERNEL__ */

#endif /* __LINUX_MMA7660_H */

这边因为是挂在IIC总线上,同样,IIC设备的实例化我们还是按照老方法来做:

static struct mma7660_platform_data mma7660_pdata = {
    .irq            = IRQ_EINT(11),
    .poll_interval  = 100,
    .input_fuzz     = 4,
    .input_flat     = 4,
};
static struct i2c_board_info smdkv210_i2c_devs0[] __initdata = {
    { I2C_BOARD_INFO("24c08", 0x50), },  
    {
        I2C_BOARD_INFO("mma7660", 0x4c),
        .platform_data = &mma7660_pdata,
    },

};

同样,我们可以看到,在iic0上挂了两个设备,一个是24c08,一个是mma7660,因为slave addr的不同,我们可以访问到不同的从设备。
驱动代码:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/input-polldev.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/mma7660.h>
#include <mach/hardware.h>



#define MMA7660_NAME                "mma7660"   

#define POLL_INTERVAL               100
#define INPUT_FUZZ                  4
#define INPUT_FLAT                  4


#define __need_retry(__v)   (__v & (1 << 6))
#define __is_negative(__v)  (__v & (1 << 5))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值