Android 模拟触摸事件I2C driver demo

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q1183345443/article/details/81457161
/******************************************************************************

Copyright (C), 2015-2025, SHARPNOW Co., Ltd.

*******************************************************************************/
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 * Copyright (C) Juven, 2016
 */

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/delay.h>



#define VIDOOTS_DEVICE_NAME "vidoo_ts"
#define WIDTH 1400
#define HEIGHT 2550
#define PERCENT (30*100/1440) //1440*2560
//#define VIDOO_TAP "vidoo_tap"

/* Per-touchscreen data. */

/**
 * struct vidoo ts - driver touchscreen state.
 * @dev: The device we are bound to.
 * @input: The input device we registered with the input subsystem.
 * @xp: The accumulated X position data.
 * @yp: The accumulated Y position data.
 * @count: The number of samples collected.
 */
struct vidoo_ts_info {
    struct i2c_client *client;
    struct input_dev *input;
    unsigned long xp;
    unsigned long yp;
    int count;
};

static struct input_dev *g_input_dev = NULL;
static struct timer_list   s_timer;
#ifdef VIDOO_TAP
static bool g_bHome = true;
#else
static bool g_bLeft = false;
#endif


#ifdef VIDOO_TAP
static void tapTouch(unsigned long ulData);
#else
static void swipeTouch(unsigned long ulData);
static void swipeLeftOrRight(int nX, int nY);
#endif
static void set_timer(void);

static int vidoots_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
    struct input_dev *input_dev;
    struct vidoo_ts_info *info;
    struct device *dev;
    struct device_node *dnode;
    int ret = -EINVAL;

    pr_info("%s\n", __func__);
    info = kzalloc(sizeof(struct vidoo_ts_info), GFP_KERNEL);
    input_dev = input_allocate_device();
    if (!info || !input_dev) {
        dev_err(&client->dev, "%s [ERROR]\n", __func__);
        ret = -ENOMEM;
        goto err_inputdev;
    }

#ifdef CONFIG_OF
    dev = &client->dev;
    dnode = dev->of_node;
#endif

    info->client = client;
    info->input = input_dev;
    g_input_dev = input_dev;

    /*info->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
    info->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
    input_set_abs_params(info->input, ABS_X, 0, 0x5A0, 0, 0);
    input_set_abs_params(info->input, ABS_Y, 0, 0xA00, 0, 0);*/
    info->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | BIT_MASK(EV_SYN);
    info->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

    __set_bit(INPUT_PROP_DIRECT, info->input->propbit);

    input_set_abs_params(info->input, ABS_MT_POSITION_X, 0, 0x5A0, 0, 0);
    input_set_abs_params(info->input, ABS_MT_POSITION_Y, 0, 0xA00, 0, 0);
    input_set_abs_params(info->input, ABS_MT_WIDTH_MAJOR, 0, 0xff, 0, 0);//255
    input_set_abs_params(info->input, ABS_MT_TOUCH_MAJOR, 0, 0xff, 0, 0);
    input_set_abs_params(info->input, ABS_MT_TRACKING_ID, 0, 0xffff, 0, 0);
    input_set_abs_params(info->input, ABS_MT_SLOT, 0, 9, 0, 0);

    info->input->name = VIDOOTS_DEVICE_NAME;
    info->input->dev.parent = &client->dev;
    info->input->id.bustype = BUS_I2C;
    info->input->id.vendor = 0xAABB;
    info->input->id.product = 0xCCDD;
    info->input->id.version = 0x1222;

    input_set_drvdata(input_dev, info);
    i2c_set_clientdata(client, info);

    pr_info("register vidoo virtual touch: %s\n", VIDOOTS_DEVICE_NAME);

    /* All went ok, so register to the input system */
    ret = input_register_device(info->input);
    if (ret < 0) {
        dev_err(dev, "failed to register input device\n");
        ret = -EIO;
        goto err_inputdev;
    }
    /* BEGIN: test touch */
    set_timer();

    dev_info(&client->dev, "Sharpnow " VIDOOTS_DEVICE_NAME " Touchscreen is initialized successfully.\n");
    return 0;

 err_inputdev:
    input_free_device(info->input);
    return ret;
}

/**
 * vidoots_remove - device core removal entry point
 * @pdev: The device we are being removed from.
 *
 * Free up our state ready to be removed.
 */
static int vidoots_remove(struct i2c_client *client)
{
    struct vidoo_ts_info *info = i2c_get_clientdata(client);

    input_unregister_device(info->input);
    kfree(info);

    return 0;
}

/**
* Device tree match table
*/
#ifdef CONFIG_OF
static const struct of_device_id vidoots_match_table[] = {
    { .compatible = "sharpnow,vidoo_ts",},
    {},
};
MODULE_DEVICE_TABLE(of, vidoots_match_table);
#endif

/**
* I2C Device ID
*/
static const struct i2c_device_id vidoots_id[] = {
    {VIDOOTS_DEVICE_NAME, 0},
};

/**
* I2C driver info
*/
static struct i2c_driver vidoots_driver = {
    .id_table = vidoots_id,
    .probe = vidoots_probe,
    .remove = vidoots_remove,
    .driver = {
        .name = VIDOOTS_DEVICE_NAME,
        .owner = THIS_MODULE,
#ifdef CONFIG_OF
        .of_match_table = vidoots_match_table,
#endif
    },
};

#ifdef VIDOO_TAP
/*****************************************************************************
 Prototype    : tapTouch
 Description  : vidoo Tap func
 Input        : unsigned long ulData
 Output       : None
 Return Value : static
 Calls        :
 Called By    :

  History        :
  1.Date         : 2017/1/17
    Author       : dk
    Modification : Created function

*****************************************************************************/
static void tapTouch(/*unsigned long ulData*/)
{
    struct input_dev *input_dev = g_input_dev;
    int nX  = 700;
    int nY = 2300;

    if(g_bHome)
    {
        input_report_key(input_dev, BTN_TOUCH, 1);// 1 down,0 up

        input_report_abs(input_dev, ABS_MT_POSITION_X, nX);
        input_report_abs(input_dev, ABS_MT_POSITION_Y, nY + 200);//go to home

        input_sync(input_dev);

        input_report_key(input_dev, BTN_TOUCH, 0);// 1 down,0 up
        input_sync(input_dev);

        pr_info("---report input event---x = %d,----y = %d\n", nX, nY);
        g_bHome = false;

    }
    else
    {
        input_report_key(input_dev, BTN_TOUCH, 1);// 1 down,0 up

        input_report_abs(input_dev, ABS_MT_POSITION_X, nX);
        input_report_abs(input_dev, ABS_MT_POSITION_Y, nY);

        input_sync(input_dev);

        input_report_key(input_dev, BTN_TOUCH, 0);// 1 down,0 up
        input_sync(input_dev);
        g_bHome = true;

    }

    s_timer.expires = jiffies + 2*HZ;//2s do
    s_timer.function = &tapTouch;//timer handler

    add_timer(&s_timer);
}
#else
/*****************************************************************************
 Prototype    : swipeTouch
 Description  : vidoo touch swipe
 Input        : unsigned long ulData
 Output       : None
 Return Value : static
 Calls        :
 Called By    :

  History        :
  1.Date         : 2017/1/17
    Author       : dk
    Modification : Created function


exmaple:
input_report_key(input_dev, BTN_TOUCH, 1);// 1 down,0 up
input_report_abs(input_dev, ABS_MT_POSITION_X, nX);
input_report_abs(input_dev, ABS_MT_POSITION_Y, nY);
input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, 1);
input_report_abs(input_dev, ABS_MT_WIDTH_MAJOR, 1);
input_report_abs(input_dev, ABS_MT_TRACKING_ID, 1);
input_sync(input_dev);

input_report_key(input_dev, BTN_TOUCH, 0);// 1 down,0 up
input_sync(input_dev);

*****************************************************************************/
static void swipeTouch(unsigned long ulData)
{
    //struct input_dev *input_dev = g_input_dev;
    int nX = 10;//700;//2300;
    int nY = 600;//1400;//1200;

    //slide to the left or right
    swipeLeftOrRight(nX, nY);

    s_timer.expires = jiffies + 3*HZ;
    s_timer.function = &swipeTouch;

    add_timer(&s_timer);
}

static int g_ntracking_id = 0;

static void swipeLeftOrRight(int nX, int nY)
{
    struct input_dev *input_dev = g_input_dev;
    int j = 0;
    int nPrecision = (PERCENT)*(WIDTH)/100;
    g_ntracking_id = g_ntracking_id + 1;

    input_report_abs(input_dev, ABS_MT_TRACKING_ID, g_ntracking_id);
    input_report_key(input_dev, BTN_TOUCH, 1);// 1 down,0 up
    pr_info("---report input down\n");

    for(j=0; j<100; j++)
    {
        input_report_abs(input_dev, ABS_MT_POSITION_X, nX);
        input_report_abs(input_dev, ABS_MT_POSITION_Y, nY);
        //input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, 5);
        //input_report_abs(input_dev, ABS_MT_WIDTH_MAJOR, 5);
        //input_report_abs(input_dev, ABS_MT_PRESSURE, 5);

        input_sync(input_dev);

        if(((nX < WIDTH)&&(nX > 0)) && ((nY < HEIGHT)&&(nY > 0)))//1440*2560
        {
            (g_bLeft)?(nX = nX - nPrecision):(nX = nX + nPrecision);
            //(g_bLeft)?(nY = nY - 10):(nY = nY + 1);
            (g_bLeft)?(nY = nY - 10):(nY = nY + 10);

            //nX = nX - 200;
            //nY = nY - 60;

            pr_info("---report input nX: %d, nY: %d, nPrecision:%d\n", nX, nY, nPrecision);
        }
    }
    //(g_bLeft)?(g_bLeft = false):(g_bLeft = true);

    input_report_abs(input_dev, ABS_MT_TRACKING_ID, 0xffffffff);

    input_report_key(input_dev, BTN_TOUCH, 0);// 1 down,0 up
    pr_info("---report input up,g_ntracking_id : %d\n", g_ntracking_id);
    input_sync(input_dev);

    //test
    if(0/*(g_ntracking_id%3) == 0*/)
    {
        input_report_key(input_dev, BTN_TOUCH, 1);// 1 down,0 up

        input_report_abs(input_dev, ABS_MT_POSITION_X, 700);
        input_report_abs(input_dev, ABS_MT_POSITION_Y, 2300);//go to home

        input_sync(input_dev);

        input_report_key(input_dev, BTN_TOUCH, 0);// 1 down,0 up
        input_sync(input_dev);
        pr_info("-----------------clear view");

        if(g_ntracking_id == 12)
            g_ntracking_id = 0;
    }
}
#endif

static void set_timer(void)
{
    init_timer(&s_timer);

    s_timer.expires = jiffies + 2*HZ;//2s do
#ifdef VIDOO_TAP
    s_timer.function = &tapTouch;//timer handler
#else
    s_timer.function = &swipeTouch;
#endif

    add_timer(&s_timer);
}



static int __init vidoots_init(void)
{
    printk(KERN_ERR "vidoots_init\n");
    return i2c_add_driver(&vidoots_driver);
}

static void __exit vidoots_exit(void)
{
    printk(KERN_ERR "vidoots_exit\n");
    del_timer(&s_timer);/* test */
    i2c_del_driver(&vidoots_driver);
}

module_init(vidoots_init);
module_exit(vidoots_exit);

MODULE_AUTHOR("Juven <[email protected]>");
MODULE_DESCRIPTION("vidoo Touchscreen driver");
MODULE_LICENSE("GPL v2");

猜你喜欢

转载自blog.csdn.net/q1183345443/article/details/81457161
今日推荐