我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 962|回复: 2

RK3288五点触摸  IC  FT5306的驱动  有要

[复制链接]

该用户从未签到

811

主题

399

回帖

499

积分

二级逆天

积分
499

社区居民社区明星忠实会员宣传大使奖终身成就奖特殊贡献奖

QQ
发表于 2016-10-26 16:51:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

您需要 登录 才可以下载或查看,没有账号?立即注册

×
#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 !!!!!!!!!
回复

使用道具 举报

该用户从未签到

35

主题

7586

回帖

1212

积分

二级逆天

积分
1212

社区居民忠实会员社区劳模原创达人最爱沙发终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

QQ
发表于 2016-10-27 08:42:00 | 显示全部楼层
回复

使用道具 举报

  • TA的每日心情
    开心
    2024-7-25 08:35
  • 签到天数: 1 天

    [LV.1]初来乍到

    24

    主题

    95

    回帖

    193

    积分

    二级逆天

    积分
    193

    社区居民终身成就奖

    QQ
    发表于 2016-10-27 14:37:50 | 显示全部楼层
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    每日签到,有金币领取。


    Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

    本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

    ( 闽ICP备2024076463号-1 ) 论坛技术支持QQ群171867948 ,论坛问题,充值问题请联系QQ1308068381

    平平安安
    TOP
    快速回复 返回顶部 返回列表