2021-06-07

#include<linux/init.h>
#include<linux/module.h>

#include<linux/i2c.h>
#include<linux/gpio.h>
#include<linux/of_gpio.h>
#include<linux/interrupt.h>
#include<linux/of_irq.h>
#include<linux/input.h>
#include<linux/delay.h>
#include<linux/workqueue.h>

#define DEVICE_MODE 0x00
static struct device_node *ft5x06_device_node;
int irq;
static void ft5x06_func(struct work_struct *work);
DECLARE_WORK(ft5x06_work,ft5x06_func);
static struct input_dev *ft5x06_dev;
static struct i2c_client *ft5x06_client;
static int ft5x06_read_reg(u8 reg_addr);
static int ft5x06_write_reg(u8 reg_addr,u8 data,u8 len);
static int ft5x06_write_reg(u8 reg_addr,u8 data,u8 len)
{
u8 buff[256];
struct i2c_msg msgs[]={
[0]={
.addr=ft5x06_client->addr,
.flags=0,
.len=len+1,
.buf=buff,
}

};
buff[0]=reg_addr;
memcpy(&buff[1],&data,len);
i2c_transfer(ft5x06_client->adapter,msgs,1);
return 0;

}

static int ft5x06_read_reg(u8 reg_addr)
{
u8 data;
struct i2c_msg msgs[]={
[0]={
.addr=ft5x06_client->addr,
.flags=0,
.len=sizeof(reg_addr),
.buf=&reg_addr,
},
[1]={
.addr=ft5x06_client->addr,
.flags=1,
.len=sizeof(data),
.buf=&data,
},
};
i2c_transfer(ft5x06_client->adapter,msgs,2);
return data;
}
static void ft5x06_func(struct work_struct *work)
{
int TOUCH1_XH,TOUCH1_XL,x;
int TOUCH1_YH,TOUCH1_YL,y;
int TD_STATUS;

TOUCH1_XH=ft5x06_read_reg(0x03);
TOUCH1_XL=ft5x06_read_reg(0x04);
x=((TOUCH1_XH<<8)|TOUCH1_XL)&0x0fff;

TOUCH1_YH=ft5x06_read_reg(0x05);
TOUCH1_YL=ft5x06_read_reg(0x06);
y=((TOUCH1_YH<<8)|TOUCH1_YL)&0x0fff;

TD_STATUS=ft5x06_read_reg(0x02);
TD_STATUS=TD_STATUS&0xf;
if(!TD_STATUS)
{
	input_report_key(ft5x06_dev,BTN_TOUCH,0);
	input_sync(ft5x06_dev);
}
else{
	input_report_key(ft5x06_dev,BTN_TOUCH,1);
	input_report_abs(ft5x06_dev,ABS_X,x);
	input_report_abs(ft5x06_dev,ABS_Y,y);
	input_sync(ft5x06_dev);
}

}
static irqreturn_t ft5x06_handler(int irq,void *args)
{
//printk(“this is ft5x06_handler\n”);
schedule_work(&ft5x06_work);
return IRQ_HANDLED;
}
int ft5x06_probe(struct i2c_client *client,const struct i2c_device_id *id)
{
int ret;
int ft5x06_irq_gpio;
int ft5x06_reset_gpio;
printk(“this is ft5x06_probe\n”);
ft5x06_client=client;
//获得触摸芯片节点
ft5x06_device_node=of_find_node_by_path("/soc/aips-bus@02100000/i2c@021a4000/edt-ft5x06@38");
if(ft5x06_device_node==NULL)
{
printk(“find node error\n”);
return -1;
}
printk(“ft5x06_device_node is %s\n”,ft5x06_device_node->name);
//获得中断引脚的GPIO标号
ft5x06_irq_gpio=of_get_named_gpio(ft5x06_device_node,“irq-gpios”,0);
if(ft5x06_irq_gpio<0)
{
printk(“ft5x06_irq_gpio error\n”);
return -2;
}
//获得复位引脚的GPIO标号
ft5x06_reset_gpio=of_get_named_gpio(ft5x06_device_node,“reset-gpios”,0);
if(ft5x06_reset_gpio<0)
{
printk(“ft5x06_irq_gpio error\n”);
return -3;
}
printk(“ft5x06_irq_gpio is %d\n”,ft5x06_irq_gpio);
printk(“ft5x06_reset_gpio is %d\n”,ft5x06_reset_gpio);

gpio_free(ft5x06_irq_gpio);
//中断引脚请求
ret=gpio_request(ft5x06_irq_gpio,"irq_gpio");
if(ret<0)
{
	printk("request_irq_gpio error\n");
	return -4;
}

gpio_free(ft5x06_reset_gpio);
//复位引脚请求
ret=gpio_request(ft5x06_reset_gpio,"reset_gpio");
if(ret<0)
{
	printk("ft5x06_reset_gpio error\n");
	return -5;
}
//设置中断的引脚设置为输入
gpio_direction_input(ft5x06_irq_gpio);
//设置复位引脚的方向为输出,然后输出高电平,停止复位
gpio_direction_output(ft5x06_reset_gpio,0);
msleep(5);
gpio_set_value(ft5x06_reset_gpio,1);

irq=gpio_to_irq(ft5x06_irq_gpio);//获得中断号
//申请中断
ret=request_irq(irq,ft5x06_handler,IRQ_TYPE_EDGE_FALLING|IRQF_ONESHOT,"ft5x06_irq",NULL);
if(ret<0)
{
	printk("request_irq error\n");
	goto err_request_irq;
}

ft5x06_write_reg(DEVICE_MODE,0x00,1);//设置工作模式

ft5x06_write_reg(0xa4,1,1);

//ret=ft5x06_read_reg(0x80);//读的是0x02寄存器的数据
//printk("data is %#x\n\n",ret);

ft5x06_dev=input_allocate_device();
ft5x06_dev->name="ft5x06_input_test";

_set_bit(EV_KEY,ft5x06_dev->evbit);//支持按键事件
_set_bit(EV_ABS,ft5x06_dev->evbit);//支持绝对坐标事件
_set_bit(BTN_TOUCH,ft5x06_dev->keybit);//支持按键检测

_set_bit(ABS_X,ft5x06_dev->absbit);//支持X坐标
_set_bit(ABS_Y,ft5x06_dev->absbit);//支持Y坐标
_set_bit(ABS_PRESSURE,ft5x06_dev->keybit);//支持压力检测


input_set_abs_params(ft5x06_dev,ABS_X,0,850,0,0);//设置X坐标值的范围
input_set_abs_params(ft5x06_dev,ABS_Y,0,480,0,0);//设置Y坐标值的范围
input_set_abs_params(ft5x06_dev,ABS_PRESSURE,0,255,0,0);//设置压力值值的范围

ret=input_register_device(ft5x06_dev);
if(ret)
{
	printk("input_register_device error\n");
	goto err_input_register;
}
return 0;

err_request_irq:
free_irq(irq,NULL);

err_input_register:
free_irq(irq,NULL);
input_unregister_device(ft5x06_dev);
input_free_device(ft5x06_dev);
return ret;
}
int ft5x06_remove(struct i2c_client *i2c_client)
{
printk(“this is ft5x06_remove\n”);
return 0;
}

static const struct i2c_device_id ft5x06_id_ts[]={
{“xxx”,0,},
{}
};
static const struct of_device_id ft5x06_id[]={
{.compatible=“edt,edt-ft5306”,},
{.compatible=“edt,edt-ft5x06”,},
{.compatible=“edt,edt-ft5426”,},
{}

};

struct i2c_driver ft5x06_driver ={

.probe=ft5x06_probe,
.remove=ft5x06_remove,
.driver={
	.owner=THIS_MODULE,
	.name="ft5x06_test",
	.of_match_table=ft5x06_id,
},

.id_table=ft5x06_id_ts

};

static int ft5x06_driver_init(void)
{
int ret;
ret=i2c_add_driver(&ft5x06_driver);
if(ret<0)
{
printk(“fail to add ret=%d\r\n”,ret);
return ret;
}

printk("ft5x06_driver_init ret=%d\r\n",ret);
return 0;

}
static void ft5x06_driver_exit(void)
{

i2c_del_driver(&ft5x06_driver);
free_irq(irq,NULL);
input_unregister_device(ft5x06_dev);
input_free_device(ft5x06_dev);
printk("exit \r\n");

}

module_init(ft5x06_driver_init);
module_exit(ft5x06_driver_exit);
MODULE_LICENSE(“GPL”);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值