|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/hrtimer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/async.h>
#include <linux/workqueue.h>
#include <linux/slab.h>
#include <mach/gpio.h>
#include <linux/irq.h>
#include <mach/board.h>
#include <linux/input/mt.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#define CONFIG_FT5X0X_MULTITOUCH 1
#define CONFIG_TOUCH_PANEL_KEY 1
#define NEW_PAL_DRV
#define CHECK_KEY
#define LONGPRESS_LOCK_SPECKEY //鏄惁浣跨敤闀挎寜鏌愰敭(濡俿earch閿?閿佷綇鍔熻兘閿殑鍔熻兘
#ifdef LONGPRESS_LOCK_SPECKEY
#define KEY_LOCK 195
#define ORIGIN_KEY KEY_SEARCH
#define LOCK_LONG_PRESS_CNT 100
static int Origin2LockPressCnt = 0;
static int lockflag =0;
static int touch_key_hold_press = 0;
ssize_t glock_status_show(struct device *dev, char *buf)
{
printk("lockflag === %d\n",lockflag);
return sprintf(buf, "%d", lockflag);
}
#endif
static int err_ft5X06 = 0; //w++璁拌浇鏈夋病鏈夋璁惧
static int debug1=1;
module_param(debug1, int, S_IRUGO|S_IWUSR);
static int gpress = 0;
extern void gpio_enable1();
static int Motoenble = 0;
module_param(Motoenble, int, S_IRUGO|S_IWUSR);
static int MotoStart = 0;
/*
* Added by yick @RockChip
* Compatible with both types of firmware
* default: point - only pressdown finger num
* event - both down and up event
*/
#define USE_POINT 1
#if USE_POINT
uint16_t down_table = 0;
uint16_t up_table = ~0;
#endif
#define SCREEN_MAX_X 480
#define SCREEN_MAX_Y 800
#define PRESS_MAX 255
#define FT5X0X_NAME "ft5x0x_ts"
#define MAX_CONTACTS 5
enum ft5x0x_ts_regs {
FT5X0X_REG_PMODE = 0xA5, /* Power Consume Mode */
};
#define KEY_MIN_X 800
#define KEY_NUM 4
int touch_key_press[] = {0, 0, 0, 0};
//int touch_key_code[] = { KEY_BACK,KEY_HOME, KEY_MENU};
//int touch_key_min[KEY_NUM] ={-1,59,105};
//int touch_key_max[KEY_NUM] ={2,73,121};
int touch_key_code[] = {KEY_MENU, KEY_HOMEPAGE, KEY_BACK, KEY_SEARCH};
int touch_key_min[KEY_NUM] ={30,150,270,390};
int touch_key_max[KEY_NUM] ={90,210,330,450};
//FT5X0X_REG_PMODE
#define PMODE_ACTIVE 0x00
#define PMODE_MONITOR 0x01
#define PMODE_STANDBY 0x02
#define PMODE_HIBERNATE 0x03
#ifndef ABS_MT_TOUCH_MAJOR
#define ABS_MT_TOUCH_MAJOR 0x30 /* touching ellipse */
#define ABS_MT_TOUCH_MINOR 0x31 /* (omit if circular) */
#define ABS_MT_WIDTH_MAJOR 0x32 /* approaching ellipse */
#define ABS_MT_WIDTH_MINOR 0x33 /* (omit if circular) */
#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */
#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
#define ABS_MT_BLOB_ID 0x38 /* Group set of pkts as blob */
#endif /* ABS_MT_TOUCH_MAJOR */
struct point_data {
u8 status;
u8 id;
u16 x;
u16 y;
};
struct ts_event {
u16 touch_point;
struct point_data point[5];
};
struct ft5x0x_ts_dev {
struct i2c_client *client;
struct input_dev *input_dev;
int irq;
struct ts_event event;
struct work_struct pen_event_work;
struct workqueue_struct *ts_workqueue;
struct early_suspend early_suspend;
#ifdef CHECK_KEY
struct timer_list timer;
#endif
};
static struct ft5x0x_ts_dev *g_dev;
static bool rember_point_into = true;
static ssize_t Moto_status(struct device_driver *_drv,char *_buf)
{
//printk("Moto_status Motoenble==%d\n", Motoenble);
if(Motoenble)
return sprintf(_buf, "Ledlevel is Low\n");
else
return sprintf(_buf, "Ledlevel is High\n");
}
static ssize_t Moto_control(struct device_driver *_drv, const char *_buf, size_t _count)
{
char temp[5];
//printk("Read data from Android: %s\n", _buf);
strncpy(temp, _buf, 1);
Motoenble = simple_strtol(temp, NULL, 10);
//printk("Moto_control Motoenble=%d\n", Motoenble);
}
static int ft5x0x_i2c_rxdata(char *rxdata, int length)
{
int ret;
struct i2c_msg msgs[] = {
{
.addr = g_dev->client->addr,
.flags = 0,
.len = 1,
.buf = rxdata,
.scl_rate = 200 * 1000,
},
{
.addr = g_dev->client->addr,
.flags = I2C_M_RD,
.len = length,
.buf = rxdata,
.scl_rate = 200 * 1000,
},
};
ret = i2c_transfer(g_dev->client->adapter, msgs, 2);
if (ret < 0)
pr_err("msg %s i2c read error: %d\n", __func__, ret);
return ret;
}
static int ft5x0x_i2c_txdata(char *txdata, int length)
{
int ret;
struct i2c_msg msg[] = {
{
.addr = g_dev->client->addr,
.flags = 0,
.len = length,
.buf = txdata,
.scl_rate = 200 * 1000,
},
};
ret = i2c_transfer(g_dev->client->adapter, msg, 1);
if (ret < 0)
pr_err("%s i2c write error: %d\n", __func__, ret);
return ret;
}
static int ft5x0x_set_reg(u8 addr, u8 para)
{
u8 buf[3];
int ret = -1;
buf[0] = addr;
buf[1] = para;
ret = ft5x0x_i2c_txdata(buf, 2);
if (ret < 0) {
pr_err("write reg failed! %#x ret: %d", buf[0], ret);
return -1;
}
return 0;
}
static int ft5x0x_read_data(void)
{
struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client);
struct ft5x0x_platform_data *pdata = g_dev->client->dev.platform_data;
struct ts_event *event = &data->event;
u16 i = 0;
u8 buf[32]= {0};//set send addr to 0x00 *important*
int ret = -1;
int key;
if(Motoenble)
{
if(!MotoStart)
{
//printk("the moto is enable!\n");
//gpio_enable1();
MotoStart =1;
}
}
ret = ft5x0x_i2c_rxdata(buf, 32);
if (ret < 0) {
printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret);
return ret;
}
#if 0 // Just for debug
u8 uc_ecc;
int i;
uc_ecc = buf[2];
for (i=0; i<5; i++)
{
uc_ecc ^= buf[3+6*i];
uc_ecc ^= buf[4+6*i];
uc_ecc ^= buf[5+6*i];
uc_ecc ^= buf[6+6*i];
}
// if (uc_ecc == buf[1]) break;
// }
if (uc_ecc != buf[1])
{
printk("ecc check error uc_ecc=0x%x, buf[1]=0x%x.\n",uc_ecc, buf[1]);
return 1;
}
#endif
memset(event, ~0x00, sizeof(struct ts_event));
#if USE_POINT
event->touch_point = buf[2] & 0x07;// 0000 1111
#else
event->touch_point = buf[2] >>4;// 0000 1111
#endif
if (event->touch_point == 0) {
rember_point_into = false;
#ifdef LONGPRESS_LOCK_SPECKEY
if(Origin2LockPressCnt)
{//璇存槑鎸夊埌浜唖earch閿?
if(Origin2LockPressCnt < LOCK_LONG_PRESS_CNT)
{//娌℃湁闀挎寜
if(lockflag ==0)
{//閿洏娌¢攣
input_report_key(data->input_dev,KEY_SEARCH,1); //158 //MENU
input_sync(data->input_dev);
input_report_key(data->input_dev,KEY_SEARCH,0); //158 //MENU
input_sync(data->input_dev);
//printk("menu is up ==========================\n");
}
}
else
{
//printk("release long press !!!!!!!!!!!!!!!!!\n");
input_report_key(data->input_dev, KEY_LOCK, 0);
//printk("up::KEY_LOCK: %d\n", KEY_LOCK);
input_sync(data->input_dev);
}
Origin2LockPressCnt = 0;
touch_key_hold_press = 0;
}
#endif
#ifdef NEW_PAL_DRV
if(touch_key_hold_press)
{
touch_key_hold_press = 0;
for(key=0; key<sizeof(touch_key_code)/sizeof(touch_key_code[0]); key++)
{
if(touch_key_press[key])
{
input_report_key(data->input_dev, touch_key_code[key], 0);
touch_key_press[key] = 0;
input_sync(data->input_dev);
//printk("up::KEY: %d\n", touch_key_code[key]);
}
}
}
#endif
gpress = 0;
MotoStart =0;
//printk("release point !!!!!!!!! |
|