一、tmd26353驱动编写思路:
基于i2c设备驱动框架,首先参考原理图配置dts设备树,挂载在哪个i2c总线下面,阅读规格书去确定此器件的器件地址是0x39(也可以使用i2ctools查看器件挂载情况,i2c-tools使用及调试);测试i2c通讯成功与否,可以去读DEVICE_ID这个寄存器值,然后初始化tmd26353,最后在线程里读接近传感器ADC的值(之前编写是使用中断去获取ADC值,查阅资料发现,在内核里中断处理程序里不能操作I2C操作接口,因为操作I2C_transfer时transfer内部也会有中断产生的。所以中断套中断这样就会死锁),ADC值变化范围与POFFSET寄存器值相关,可设置范围是±255,要根据实际需求设置该值,然后通过写节点接口,将ADC值反馈给应用层去读取。
二、代码分析:
dts配置如下:
&i2c5 {
status = "okay";
tmd26353:tmd26353@39{
compatible = "p-sensor,tmd26353";
reg = <0x39>;
//irq-gpios = <&gpio3 RK_PC3 IRQ_TYPE_LEVEL_LOW>;
status = "okay";
};
};
tmd26353驱动源码如下:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/of_device.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
/*********************************************
Register
**********************************************/
#define TMD26353_ENABLE_PROXIMITY 0x80
#define TMD26353_PRATE 0x82 //采样时间PRATE
#define TMD26353_PCFG0 0x8E //增益
#define TMD26353_PCFG1 0x8F
#define TMD26353_DEVICE_ID 0x92
#define TMD26353_PDATAL 0x9C //ADC
#define TMD26353_PDATAH 0x9D
#define TMD26353_CFG6_APC 0xAE //使能APC
#define TMD26353_POFFSETL 0xC0 自动校准
#define TMD26353_POFFSETH 0xC1
#define TMD26353_CALIBCFG 0xD9 //样本数量CALIBCFG
struct tmd26353_data {
struct i2c_client *client;
struct mutex lock;
int irq_pin;
unsigned int irq_111 ;
unsigned int irq_num;
u32 read_adc;
};
static struct tmd26353_data tmd26353;
static struct task_struct *p_data_task;
enum tmd26353_register_name {
REG_PDATA = 0,
REG_DEVICE_ID,
REG_ENABLE,
REG_POFFSET,
REG_PRATE,
REG_CALIBCFG,
REG_CFG6_APC,
REG_PCFG0,
REG_PCFG1,
};
struct tmd26353_register_desc {
u8 msb;
u8 lsb;
};
static const struct tmd26353_register_desc tmd26353_registers[] = {
[REG_PDATA] = {
.msb = TMD26353_PDATAH,
.lsb = TMD26353_PDATAL,
},
[REG_DEVICE_ID