drivers/input: remove unused auto touchscreen support

Change-Id: Idc012f66abfcad6e5d601f97bded60f230b6fdcc
Signed-off-by: Tao Huang <huangtao@rock-chips.com>
This commit is contained in:
Tao Huang 2018-11-02 19:54:37 +08:00
parent a6b0594c19
commit fbadf313ef
14 changed files with 0 additions and 3696 deletions

View File

@ -1,16 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
#
# all auto touch screen drivers configuration
#
menuconfig TS_AUTO
bool "auto touch screen driver support"
default n
if TS_AUTO
source "drivers/input/ts/chips/Kconfig"
endif

View File

@ -1,7 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
# auto touch screen drivers
obj-$(CONFIG_TS_AUTO_I2C) += ts-i2c.o
obj-$(CONFIG_TS_AUTO_SPI) += ts-spi.o
obj-$(CONFIG_TS_AUTO_SERIAL) += ts-serial.o
obj-$(CONFIG_TS_AUTO) += chips/
obj-$(CONFIG_TS_AUTO) += ts-auto.o

View File

@ -1,40 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
menuconfig TS_AUTO_I2C
bool "Support auto touch screen with I2C"
default n
if TS_AUTO_I2C
config TS_FT5306
bool "touch screen ft5306"
default n
config TS_GT8110
bool "touch screen gt8110"
default n
config TS_GT828
bool "touch screen gt828"
default n
config TS_CT360
bool "touch screen ct360"
default n
endif
config TS_AUTO_SPI
bool "Support auto touch screen with SPI"
depends on SPI_MASTER
if TS_AUTO_SPI
endif
config TS_AUTO_SERIAL
bool "Support auto touch screen with UART"
if TS_AUTO_SERIAL
endif

View File

@ -1,5 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_TS_FT5306) += ft5306.o
obj-$(CONFIG_TS_GT8110) += gt8110.o
obj-$(CONFIG_TS_CT360) += ct360.o
obj-$(CONFIG_TS_GT828) += gt828.o

View File

@ -1,497 +0,0 @@
/* drivers/input/ts/chips/ct360.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/freezer.h>
#include <linux/input/mt.h>
#include <mach/gpio.h>
#include <mach/board.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/ts-auto.h>
#include "ct360_firmware.h"
static struct i2c_client *this_client;
#if 0
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
#define CT360_ID_REG 0x00
#define CT360_DEVID 0x00
#define CT360_DATA_REG 0x00
/****************operate according to ts chip:start************/
static int ts_active(struct ts_private_data *ts, int enable)
{
int result = 0;
if(enable)
{
gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);
msleep(10);
gpio_direction_output(ts->pdata->reset_pin, GPIO_HIGH);
msleep(100);
}
else
{
gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);
}
return result;
}
static int ts_firmware(struct ts_private_data *ts)
{
int i = 0, j = 0;
unsigned int ver_chk_cnt = 0;
unsigned int flash_addr = 0;
unsigned char CheckSum[16];
unsigned char buf[32];
char slave_addr = ts->ops->slave_addr;
int ret = 0;
ret = ts_bulk_read_normal(ts, 1, buf, 200*1000);
if (Binary_Data_Ct360[16372] <= buf[0] )
{
printk("%s:%s,firmware is new\n",__func__,ts->ops->name);
return 0;
}
ts->ops->slave_addr = 0x7F;
//------------------------------
// Step1 --> initial BootLoader
// Note. 0x7F -> 0x00 -> 0xA5 ;
// MCU goto idle
//------------------------------
printk("%s() Set mcu to idle \n", __FUNCTION__);
buf[0] = 0x00;
buf[1] = 0xA5;
ts_bulk_write_normal(ts, 2, buf, 200*1000);
mdelay(10);
//------------------------------
// Reset I2C Offset address
// Note. 0x7F -> 0x00
//------------------------------
printk("%s() Reset i2c offset address \n", __FUNCTION__);
buf[0] = 0x00;
ts_bulk_write_normal(ts, 1, buf, 200*1000);
mdelay(10);
//------------------------------
// Read I2C Bus status
//------------------------------
printk("%s() Read i2c bus status \n", __FUNCTION__);
ts_bulk_read_normal(ts, 1, buf, 200*1000);
mdelay(10); // Delay 1 ms
// if return "AAH" then going next step
if (buf[0] != 0xAA)
{
printk("%s() i2c bus status: 0x%x \n", __FUNCTION__, buf[0]);
goto exit;
}
//------------------------------
// Check incomplete flash erase
//------------------------------
printk("%s() Flash erase verify \n", __FUNCTION__);
buf[0] = 0x00;
buf[1] = 0x99; // Generate check sum command -->read flash, set addr
buf[2] = 0x00; // define a flash address for CT36x to generate check sum
buf[3] = 0x00; //
buf[4] = 0x08; // Define a data length for CT36x to generate check sum
// Write Genertate check sum command to CT36x
ts_bulk_write_normal(ts, 5, buf, 200*1000);
mdelay(10); // Delay 10 ms
ts_bulk_read_normal(ts, 13, buf, 200*1000);
mdelay(10); // Delay 10 ms
CheckSum[0] = buf[5];
CheckSum[1] = buf[6];
buf[0] = 0x00;
buf[1] = 0x99; // Generate check sum command -->read flash, set addr
buf[2] = 0x3F; // define a flash address for CT36x to generate check sum
buf[3] = 0xE0; //
buf[4] = 0x08; // Define a data length for CT36x to generate check sum
// Write Genertate check sum command to CT36x
ts_bulk_write_normal(ts, 5, buf, 200*1000);
mdelay(10); // Delay 10 ms
ts_bulk_read_normal(ts, 13, buf, 200*1000);
mdelay(10);
CheckSum[2] = buf[5];
CheckSum[3] = buf[6];
if ( (CheckSum[0] ^ CheckSum[2]) == 0xFF && (CheckSum[1] ^ CheckSum[3]) == 0xFF )
goto FLASH_ERASE;
//------------------------------
// check valid Vendor ID
//------------------------------
printk("%s() Vendor ID Check \n", __FUNCTION__);
buf[0] = 0x00;
buf[1] = 0x99; // Generate check sum command -->read flash, set addr
buf[2] = 0x00; // define a flash address for CT365 to generate check sum
buf[3] = 0x44; //
buf[4] = 0x08; // Define a data length for CT365 to generate check sum
// Write Genertate check sum command to CT36x
ts_bulk_write_normal(ts, 5, buf, 200*1000);
mdelay(10); // Delay 10 ms
ts_bulk_read_normal(ts, 13, buf, 200*1000);
mdelay(10); // Delay 10 ms
// Read check sum and flash data from CT36x
if ( (buf[5] != 'V') || (buf[9] != 'T') )
ver_chk_cnt++;
buf[0] = 0x00;
buf[1] = 0x99; // Generate check sum command -->read flash,set addr
buf[2] = 0x00; // define a flash address for CT365 to generate check sum
buf[3] = 0xA4; //
buf[4] = 0x08; // Define a data length for CT365 to generate check sum
// Write Genertate check sum command to CT365
ts_bulk_write_normal(ts, 5, buf, 200*1000);
mdelay(10); // Delay 10 ms
ts_bulk_read_normal(ts, 13, buf, 200*1000);
mdelay(10); // Delay 10 ms
if ((buf[5] != 'V') || (buf[9] != 'T'))
ver_chk_cnt++;
if ( ver_chk_cnt >= 2 ) {
printk("%s() Invalid FW Version \n", __FUNCTION__);
goto exit;
}
FLASH_ERASE:
//-----------------------------------------------------
// Step 2 : Erase 32K flash memory via Mass Erase (33H)
// 0x7F --> 0x00 --> 0x33 --> 0x00;
//-----------------------------------------------------
printk("%s() Erase flash \n", __FUNCTION__);
for(i = 0; i < 8; i++ ) {
buf[0] = 0x00; // Offset address
buf[1] = 0x33; // Mass Erase command
buf[2] = 0x00 + (i * 8);
ts_bulk_write_normal(ts, 3, buf, 200*1000);
mdelay(120); // Delay 10 mS
//------------------------------
// Reset I2C Offset address
// Note. 0x7F -> 0x00
//------------------------------
buf[0] = 0x00;
ts_bulk_write_normal(ts, 1, buf, 200*1000);
mdelay(120); // Delay 10 mS
//------------------------------
// Read I2C Bus status
//------------------------------
ts_bulk_read_normal(ts, 1, buf, 200*1000);
mdelay(10); // Delay 1 ms
// if return "AAH" then going next step
if( buf[0] != 0xAA )
{
goto exit;
}
}
//----------------------------------------
// Step3. Host write 128 bytes to CT36x
// Step4. Host read checksum to verify ;
// Write/Read for 256 times ( 32k Bytes )
//----------------------------------------
printk("%s() flash FW start \n", __FUNCTION__);
for ( flash_addr = 0; flash_addr < 0x3FFF; flash_addr+=8 ) {
// Step 3 : write binary data to CT36x
buf[0] = 0x00; // Offset address
buf[1] = 0x55; // Flash write command
buf[2] = (char)(flash_addr >> 8); // Flash address [15:8]
buf[3] = (char)(flash_addr & 0xFF); // Flash address [7:0]
buf[4] = 0x08; // Data Length
if( flash_addr == 160 || flash_addr == 168 ) {
buf[6] = ~Binary_Data_Ct360[flash_addr + 0]; // Binary data 1
buf[7] = ~Binary_Data_Ct360[flash_addr + 1]; // Binary data 2
buf[8] = ~Binary_Data_Ct360[flash_addr + 2]; // Binary data 3
buf[9] = ~Binary_Data_Ct360[flash_addr + 3]; // Binary data 4
buf[10] = ~Binary_Data_Ct360[flash_addr + 4]; // Binary data 5
buf[11] = ~Binary_Data_Ct360[flash_addr + 5]; // Binary data 6
buf[12] = ~Binary_Data_Ct360[flash_addr + 6]; // Binary data 7
buf[13] = ~Binary_Data_Ct360[flash_addr + 7]; // Binary data 8
} else {
buf[6] = Binary_Data_Ct360[flash_addr + 0]; // Binary data 1
buf[7] = Binary_Data_Ct360[flash_addr + 1]; // Binary data 2
buf[8] = Binary_Data_Ct360[flash_addr + 2]; // Binary data 3
buf[9] = Binary_Data_Ct360[flash_addr + 3]; // Binary data 4
buf[10] = Binary_Data_Ct360[flash_addr + 4]; // Binary data 5
buf[11] = Binary_Data_Ct360[flash_addr + 5]; // Binary data 6
buf[12] = Binary_Data_Ct360[flash_addr + 6]; // Binary data 7
buf[13] = Binary_Data_Ct360[flash_addr + 7]; // Binary data 8
}
// Calculate a check sum by Host controller.
// Checksum = / (FLASH_ADRH+FLASH_ADRL+LENGTH+
// Binary_Data_Ct3601+Binary_Data_Ct3602+Binary_Data_Ct3603+Binary_Data_Ct3604+
// Binary_Data_Ct3605+Binary_Data_Ct3606+Binary_Data_Ct3607+Binary_Data_Ct3608) + 1
CheckSum[0] = ~(buf[2] + buf[3] + buf[4] + buf[6] + buf[7] +
buf[8] + buf[9] + buf[10] + buf[11] + buf[12] +
buf[13]) + 1;
buf[5] = CheckSum[0]; // Load check sum to I2C Buffer
ts_bulk_write_normal(ts, 14, buf, 200*1000); // Host write I2C_Buf[0?K12] to CT365.
mdelay(1); // 8 Bytes program --> Need 1 ms delay time
// Step4. Verify process
//printk("%s(flash_addr:0x%04x) Verify FW \n", __FUNCTION__, flash_addr);
//Step 4 : Force CT365 generate check sum for host to compare data.
//Prepare get check sum from CT36x
buf[0] = 0x00;
buf[1] = 0x99; // Generate check sum command
buf[2] = (char)(flash_addr >> 8); // define a flash address for NT1100x to generate check sum
buf[3] = (char)(flash_addr & 0xFF); //
buf[4] = 0x08; // Define a data length for CT36x to generate check sum
ts_bulk_write_normal(ts, 5, buf, 200*1000); // Write Genertate check sum command to CT365
mdelay(1); // Delay 1 ms
ts_bulk_read_normal(ts, 13, buf, 200*1000); // Read check sum and flash data from CT365
// Compare host check sum with CT365 check sum(I2C_Buf[4])
if ( buf[4] != CheckSum[0] ) {
goto exit;
}
}
printk("%s() flash FW complete \n", __FUNCTION__);
exit:
ts->ops->slave_addr = slave_addr;
if(ts->ops->active)
ts->ops->active(ts, 0);
if(ts->ops->active)
ts->ops->active(ts, 1);
return 0;
}
static int ts_init(struct ts_private_data *ts)
{
int irq_pin = irq_to_gpio(ts->pdata->irq);
int result = 0;
int uc_reg_value ;
char loader_buf[3] = {0xfF,0x0f,0x2A};
gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);
mdelay(10);
gpio_direction_output(ts->pdata->reset_pin, GPIO_HIGH);
msleep(300);
//init some register
//to do
ts_bulk_write_normal(ts, 3, loader_buf, 200*1000);
return result;
}
static int ts_report_value(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
struct ts_event *event = &ts->event;
unsigned char buf[20] = {0};
int result = 0 , i = 0, off = 0, id = 0;
int syn_flag = 0;
result = ts_bulk_read(ts, (unsigned short)ts->ops->read_reg, ts->ops->read_len, buf);
if(result < 0)
{
printk("%s:fail to init ts\n",__func__);
return result;
}
//for(i=0; i<ts->ops->read_len; i++)
//DBG("buf[%d]=0x%x\n",i,buf[i]);
for(i = 0; i<ts->ops->max_point; i++)
{
off = i*4;
id = buf[off] >> 4;
event->point[id].id = id;
event->point[id].status = buf[off+0] & 0x0f;
event->point[id].x = (((s16)buf[i+1] << 4)|((s16)buf[i+3] >> 4));
event->point[id].y = (((s16)buf[i+2] << 4)|((s16)buf[i+3] & 0x0f));
if(ts->ops->xy_swap)
{
swap(event->point[id].x, event->point[id].y);
}
if(ts->ops->x_revert)
{
event->point[id].x = ts->ops->range[0] - event->point[id].x;
}
if(ts->ops->y_revert)
{
event->point[id].y = ts->ops->range[1] - event->point[id].y;
}
if((event->point[id].status == 1) || (event->point[id].status == 2))
{
input_mt_slot(ts->input_dev, event->point[id].id);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, event->point[id].id);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, event->point[id].x);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, event->point[id].y);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 1);
syn_flag = 1;
DBG("%s:%s press down,id=%d,x=%d,y=%d\n",__func__,ts->ops->name, event->point[id].id, event->point[id].x,event->point[id].y);
}
else if ((event->point[id].status == 3) || (event->point[id].status == 0))
{
input_mt_slot(ts->input_dev, event->point[id].id);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
syn_flag = 1;
DBG("%s:%s press up,id=%d\n",__func__,ts->ops->name, event->point[id].id);
}
event->point[id].last_status = event->point[id].status;
}
if(syn_flag)
{
syn_flag = 0;
input_sync(ts->input_dev);
}
return 0;
}
static int ts_suspend(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
if(ts->ops->active)
ts->ops->active(ts, 0);
return 0;
}
static int ts_resume(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
if(ts->ops->active)
ts->ops->active(ts, 1);
return 0;
}
struct ts_operate ts_ct360_ops = {
.name = "ct360",
.slave_addr = 0x01,
.ts_id = TS_ID_CT360, //i2c id number
.bus_type = TS_BUS_TYPE_I2C,
.reg_size = 1,
.id_reg = CT360_ID_REG,
.id_data = TS_UNKNOW_DATA,
.version_reg = TS_UNKNOW_DATA,
.version_len = 0,
.version_data = NULL,
.read_reg = CT360_DATA_REG, //read data
.read_len = 4*5, //data length
.trig = IRQF_TRIGGER_FALLING,
.max_point = 5,
.xy_swap = 0,
.x_revert = 0,
.y_revert = 0,
.range = {800,480},
.irq_enable = 1,
.poll_delay_ms = 0,
.active = ts_active,
.init = ts_init,
.check_irq = NULL,
.report = ts_report_value,
.firmware = ts_firmware,
.suspend = ts_suspend,
.resume = ts_resume,
};
/****************operate according to ts chip:end************/
//function name should not be changed
static struct ts_operate *ts_get_ops(void)
{
return &ts_ct360_ops;
}
static int __init ts_ct360_init(void)
{
struct ts_operate *ops = ts_get_ops();
int result = 0;
result = ts_register_slave(NULL, NULL, ts_get_ops);
DBG("%s\n",__func__);
return result;
}
static void __exit ts_ct360_exit(void)
{
struct ts_operate *ops = ts_get_ops();
ts_unregister_slave(NULL, NULL, ts_get_ops);
}
subsys_initcall(ts_ct360_init);
module_exit(ts_ct360_exit);

File diff suppressed because it is too large Load Diff

View File

@ -1,270 +0,0 @@
/* drivers/input/ts/chips/ts_ft5306.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/freezer.h>
#include <linux/input/mt.h>
#include <mach/gpio.h>
#include <mach/board.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/ts-auto.h>
#if 0
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
#define FT5306_ID_REG 0x00
#define FT5306_DEVID 0x00
#define FT5306_DATA_REG 0x00
/****************operate according to ts chip:start************/
static int ts_active(struct ts_private_data *ts, int enable)
{
int result = 0;
if(enable)
{
gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);
msleep(10);
gpio_direction_output(ts->pdata->reset_pin, GPIO_HIGH);
msleep(100);
}
else
{
gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);
}
return result;
}
static int ts_init(struct ts_private_data *ts)
{
int irq_pin = irq_to_gpio(ts->pdata->irq);
int result = 0;
gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);
mdelay(10);
gpio_direction_output(ts->pdata->reset_pin, GPIO_HIGH);
msleep(100);
//init some register
//to do
return result;
}
static int ts_report_value(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
struct ts_event *event = &ts->event;
unsigned char buf[32] = {0};
int result = 0 , i = 0, off = 0, id = 0;
result = ts_bulk_read(ts, (unsigned short)ts->ops->read_reg, ts->ops->read_len, (unsigned short *)buf);
if(result < 0)
{
printk("%s:fail to init ts\n",__func__);
return result;
}
//for(i=0; i<ts->ops->read_len; i++)
//DBG("buf[%d]=0x%x\n",i,buf[i]);
event->touch_point = buf[2] & 0x07;// 0000 1111
for(i=0; i<ts->ops->max_point; i++)
{
event->point[i].status = 0;
event->point[i].x = 0;
event->point[i].y = 0;
}
if(event->touch_point == 0)
{
for(i=0; i<ts->ops->max_point; i++)
{
if(event->point[i].last_status != 0)
{
event->point[i].last_status = 0;
input_mt_slot(ts->input_dev, event->point[i].id);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
DBG("%s:%s press up,id=%d\n",__func__,ts->ops->name, event->point[i].id);
}
}
input_sync(ts->input_dev);
memset(event, 0x00, sizeof(struct ts_event));
return 0;
}
for(i = 0; i<event->touch_point; i++)
{
off = i*6+3;
id = (buf[off+2] & 0xf0) >> 4;
event->point[id].id = id;
event->point[id].status = (buf[off+0] & 0xc0) >> 6;
event->point[id].x = ((buf[off+0] & 0x0f)<<8) | buf[off+1];
event->point[id].y = ((buf[off+2] & 0x0f)<<8) | buf[off+3];
if(ts->ops->xy_swap)
{
swap(event->point[id].x, event->point[id].y);
}
if(ts->ops->x_revert)
{
event->point[id].x = ts->ops->range[0] - event->point[id].x;
}
if(ts->ops->y_revert)
{
event->point[id].y = ts->ops->range[1] - event->point[id].y;
}
}
for(i=0; i<ts->ops->max_point; i++)
{
if(event->point[i].status != 0)
{
input_mt_slot(ts->input_dev, event->point[i].id);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, event->point[i].id);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, event->point[i].x);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, event->point[i].y);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 1);
DBG("%s:%s press down,id=%d,x=%d,y=%d\n",__func__,ts->ops->name, event->point[id].id, event->point[id].x,event->point[id].y);
}
else if ((event->point[i].status == 0) && (event->point[i].last_status != 0))
{
input_mt_slot(ts->input_dev, event->point[i].id);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
DBG("%s:%s press up1,id=%d\n",__func__,ts->ops->name, event->point[i].id);
}
event->point[i].last_status = event->point[i].status;
}
input_sync(ts->input_dev);
return 0;
}
static int ts_suspend(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
if(ts->ops->active)
ts->ops->active(ts, 0);
return 0;
}
static int ts_resume(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
if(ts->ops->active)
ts->ops->active(ts, 1);
return 0;
}
struct ts_operate ts_ft5306_ops = {
.name = "ft5306",
.slave_addr = 0x3e,
.ts_id = TS_ID_FT5306, //i2c id number
.bus_type = TS_BUS_TYPE_I2C,
.reg_size = 1,
.id_reg = FT5306_ID_REG,
.id_data = TS_UNKNOW_DATA,
.version_reg = TS_UNKNOW_DATA,
.version_len = 0,
.version_data = NULL,
.read_reg = FT5306_DATA_REG, //read data
.read_len = 32, //data length
.trig = IRQF_TRIGGER_FALLING,
.max_point = 5,
.xy_swap = 1,
.x_revert = 1,
.y_revert = 0,
.range = {1024,768},
.irq_enable = 1,
.poll_delay_ms = 0,
.active = ts_active,
.init = ts_init,
.check_irq = NULL,
.report = ts_report_value,
.firmware = NULL,
.suspend = ts_suspend,
.resume = ts_resume,
};
/****************operate according to ts chip:end************/
//function name should not be changed
static struct ts_operate *ts_get_ops(void)
{
return &ts_ft5306_ops;
}
static int __init ts_ft5306_init(void)
{
struct ts_operate *ops = ts_get_ops();
int result = 0;
result = ts_register_slave(NULL, NULL, ts_get_ops);
DBG("%s\n",__func__);
return result;
}
static void __exit ts_ft5306_exit(void)
{
struct ts_operate *ops = ts_get_ops();
ts_unregister_slave(NULL, NULL, ts_get_ops);
}
subsys_initcall(ts_ft5306_init);
module_exit(ts_ft5306_exit);

View File

@ -1,374 +0,0 @@
/* drivers/input/ts/chips/gt8110.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/freezer.h>
#include <linux/input/mt.h>
#include <mach/gpio.h>
#include <mach/board.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/ts-auto.h>
#if 0
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
#define PEN_DOWN 1
#define PEN_RELEASE 0
#define PEN_DOWN_UP 2 //from down to up
#define GT8110_ID_REG 0x00
#define GT8110_DATA_REG 0x00
/****************operate according to ts chip:start************/
static int ts_active(struct ts_private_data *ts, int enable)
{
unsigned char buf_suspend[2] = {0x38, 0x56}; //suspend cmd
int result = 0;
if(enable)
{
gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);
mdelay(10);
gpio_direction_output(ts->pdata->reset_pin, GPIO_HIGH);
msleep(200);
}
else
{
result = ts_bulk_write(ts, (unsigned short )buf_suspend[0], 2, (unsigned short *)&buf_suspend[1]);
if(result < 0)
{
printk("%s:fail to init ts\n",__func__);
return result;
}
gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);
}
return result;
}
static int ts_init(struct ts_private_data *ts)
{
int irq_pin = irq_to_gpio(ts->pdata->irq);
char version_data[18] = {240};
char init_data[95] = {
0x65,0x02,0x00,0x10,0x00,0x10,0x0A,0x62,0x4A,0x00,
0x0F,0x28,0x02,0x10,0x10,0x00,0x00,0x20,0x00,0x00,
0x10,0x10,0x10,0x00,0x37,0x00,0x00,0x00,0x01,0x02,
0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,
0x0D,0xFF,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
0x07,0x08,0x09,0x0A,0x0B,0x0C,0xFF,0xFF,0xFF,0x00,
0x00,0x3C,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00
};
int result = 0, i = 0;
//read version
result = ts_bulk_read(ts, (unsigned short)version_data[0], 16, (unsigned short *)&version_data[1]);
if(result < 0)
{
printk("%s:fail to init ts\n",__func__);
return result;
}
version_data[17]='\0';
printk("%s:%s version is %s\n",__func__,ts->ops->name, version_data);
#if 1
//init some register
result = ts_bulk_write(ts, (unsigned short )init_data[0], 94, (unsigned short *)&init_data[1]);
if(result < 0)
{
printk("%s:fail to init ts\n",__func__);
return result;
}
#endif
result = ts_bulk_read(ts, (unsigned short)init_data[0], 94, (unsigned short *)&init_data[1]);
if(result < 0)
{
printk("%s:fail to init ts\n",__func__);
return result;
}
DBG("%s:rx:",__func__);
for(i=0; i<95; i++)
DBG("0x%x,",init_data[i]);
DBG("\n");
return result;
}
static bool goodix_get_status(int *p1,int*p2)
{
bool status = PEN_DOWN;
if((*p2==PEN_DOWN) && (*p1==PEN_RELEASE))
{
*p2 = PEN_DOWN_UP; //¸Õ¸Õµ¯Æð
status = PEN_RELEASE;
}
else if((*p2==PEN_RELEASE) && (*p1==PEN_RELEASE))
{
*p2 = PEN_RELEASE;
status = PEN_RELEASE;
}
else
{
*p2 = PEN_DOWN;
}
return status;
}
static int ts_check_irq(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
struct ts_event *event = &ts->event;
int gpio_level_no_int = GPIO_HIGH;
int id = 0, i = 0;
if((ts->ops->trig & IRQF_TRIGGER_LOW) || (ts->ops->trig & IRQF_TRIGGER_FALLING))
gpio_level_no_int = GPIO_HIGH;
else
gpio_level_no_int = GPIO_LOW;
if(gpio_get_value(ts->pdata->irq) == gpio_level_no_int)
{
for(i = 0; i<ts->ops->max_point; i++)
{
id = i;
if(event->point[id].last_status != 0)
{
event->point[i].last_status = PEN_RELEASE;
input_mt_slot(ts->input_dev, event->point[i].id);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
DBG("%s:%s press up,id=%d\n\n",__func__,ts->ops->name, event->point[i].id);
}
}
input_sync(ts->input_dev);
memset(event, 0x00, sizeof(struct ts_event));
enable_irq(ts->irq);
}
else
schedule_delayed_work(&ts->delaywork, msecs_to_jiffies(ts->ops->poll_delay_ms));
return 0;
}
static int ts_report_value(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
struct ts_event *event = &ts->event;
unsigned char buf[54] = {0};
int result = 0 , i = 0, j = 0, off = 0, id = 0;
int temp = 0, num = 0;
result = ts_bulk_read(ts, ts->ops->read_reg, ts->ops->read_len, (unsigned short *)buf);
if(result < 0)
{
printk("%s:fail to init ts\n",__func__);
return result;
}
//for(i=0; i<ts->ops->read_len; i++)
//DBG("buf[%d]=0x%x\n",i,buf[i]);
temp = (buf[1] << 8) | buf[0];
for(i=0; i<ts->ops->max_point; i++)
{
if(temp & (1 << i))
{
event->point[i].status = PEN_DOWN;
num++;
}
}
if(num > event->touch_point)
event->touch_point = num;
for(i = 0; i<event->touch_point; i++)
{
off = 2 + i*4;
id = i;
event->point[id].id = id;
if(goodix_get_status(&event->point[id].status,&event->point[id].last_status))
{
event->point[id].x = (unsigned int)(buf[off+1]<<8) + (unsigned int)buf[off+0];
event->point[id].y = (unsigned int)(buf[off+3]<<8) + (unsigned int)buf[off+2];
}
if((event->point[id].x <= 0) || (event->point[id].x >= ts->ops->range[0]) || (event->point[id].y <= 0) || (event->point[id].y >= ts->ops->range[1]))
{
event->point[id].status = 0;
continue;
}
//for(j=0; j<(2 + (i+1)*4); j++)
//DBG("buf[%d]=0x%x\n",j,buf[j]);
if(ts->ops->xy_swap)
{
swap(event->point[id].x, event->point[id].y);
}
if(ts->ops->x_revert)
{
event->point[id].x = ts->ops->range[0] - event->point[id].x;
}
if(ts->ops->y_revert)
{
event->point[id].y = ts->ops->range[1] - event->point[id].y;
}
if(event->point[id].status==PEN_DOWN_UP)
{
event->point[id].status=PEN_RELEASE;
input_mt_slot(ts->input_dev, event->point[i].id);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
DBG("%s:%s press is uping,id=%d\n\n",__func__,ts->ops->name, event->point[i].id);
continue;
}
if(event->point[id].status==PEN_DOWN)
{
input_mt_slot(ts->input_dev, event->point[id].id);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, event->point[id].id);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, event->point[id].x);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, event->point[id].y);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 1);
DBG("%s:%s press down,id=%d,x=%d,y=%d\n\n",__func__,ts->ops->name, event->point[id].id, event->point[id].x,event->point[id].y);
}
event->point[id].last_status = event->point[id].status;
}
input_sync(ts->input_dev);
return 0;
}
static int ts_suspend(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
if(ts->ops->active)
ts->ops->active(ts, 0);
return 0;
}
static int ts_resume(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
if(ts->ops->active)
ts->ops->active(ts, 1);
return 0;
}
struct ts_operate ts_gt8110_ops = {
.name = "gt8110",
.slave_addr = 0x5c,
.ts_id = TS_ID_GT8110, //i2c id number
.bus_type = TS_BUS_TYPE_I2C,
.reg_size = 1,
.id_reg = GT8110_ID_REG,
.id_data = TS_UNKNOW_DATA,
.version_reg = TS_UNKNOW_DATA,
.version_len = 0,
.version_data = NULL,
.read_reg = GT8110_DATA_REG, //read data
.read_len = 5*10+3+1, //data length
.trig = IRQ_TYPE_LEVEL_LOW,
.max_point = 10,
.xy_swap = 0,
.x_revert = 0,
.y_revert = 0,
.range = {4096,4096},
.irq_enable = 1,
.poll_delay_ms = 30,
.active = ts_active,
.init = ts_init,
.check_irq = ts_check_irq,
.report = ts_report_value,
.firmware = NULL,
.suspend = ts_suspend,
.resume = ts_resume,
};
/****************operate according to ts chip:end************/
//function name should not be changed
static struct ts_operate *ts_get_ops(void)
{
return &ts_gt8110_ops;
}
static int __init ts_gt8110_init(void)
{
struct ts_operate *ops = ts_get_ops();
int result = 0;
result = ts_register_slave(NULL, NULL, ts_get_ops);
DBG("%s\n",__func__);
return result;
}
static void __exit ts_gt8110_exit(void)
{
struct ts_operate *ops = ts_get_ops();
ts_unregister_slave(NULL, NULL, ts_get_ops);
}
subsys_initcall(ts_gt8110_init);
module_exit(ts_gt8110_exit);

View File

@ -1,391 +0,0 @@
/* drivers/input/ts/chips/gt828.c
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/freezer.h>
#include <linux/input/mt.h>
#include <mach/gpio.h>
#include <mach/board.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/ts-auto.h>
#if 0
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
//Register define
#define GTP_READ_COOR_ADDR 0x0F40
#define GTP_REG_SLEEP 0x0FF2
#define GTP_REG_SENSOR_ID 0x0FF5
#define GTP_REG_CONFIG_DATA 0x0F80
#define GTP_REG_VERSION 0x0F7D
#define GTP_CONFIG_LENGTH 112
#define TRIGGER_LOC 64
//STEP_1(REQUIRED):Change config table.
/*TODO: puts the config info corresponded to your TP here, the following is just
a sample config, send this config should cause the chip cannot work normally*/
//default or float
u8 cfg_info_group[][GTP_CONFIG_LENGTH] =
{
{
0x00,0x0F,0x01,0x10,0x02,0x11,0x03,0x12,0x04,0x13,
0x05,0x14,0x06,0x15,0x07,0x16,0x08,0x17,0x09,0x18,
0x0A,0x19,0x0B,0x1A,0x0C,0x1B,0x0D,0x1C,0xFF,0xFF,
0x02,0x0C,0x03,0x0D,0x04,0x0E,0x05,0x0F,0x06,0x10,
0x07,0x11,0x08,0x12,0x09,0x13,0xFF,0x11,0x12,0x13,
0x0F,0x03,0x88,0x10,0x10,0x2A,0x00,0x00,0x00,0x00,
0x00,0x0E,0x45,0x30,0x58,0x03,0x00,0x05,0x00,0x02,
0x58,0x03,0x20,0x55,0x5E,0x50,0x58,0x27,0x00,0x05,
0x19,0x05,0x14,0x10,0x00,0x05,0x00,0x00,0x00,0x00,
0x00,0x00,0x40,0x30,0x30,0x3C,0x00,0x00,0x00,0x00,
0x0F,0x88,0x28,0x05,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01
},
{
0x00,0x0F,0x01,0x10,0x02,0x11,0x03,0x12,0x04,0x13,
0x05,0x14,0x06,0x15,0x07,0x16,0x08,0x17,0x09,0x18,
0x0A,0x19,0x0B,0x1A,0x0C,0x1B,0x0D,0x1C,0xFF,0xFF,
0x02,0x0C,0x03,0x0D,0x04,0x0E,0x05,0x0F,0x06,0x10,
0x07,0x11,0x08,0x12,0x09,0x13,0xFF,0x11,0x12,0x13,
0x0F,0x03,0x88,0x10,0x10,0x2A,0x00,0x00,0x00,0x00,
0x00,0x0E,0x45,0x30,0x58,0x03,0x00,0x05,0x00,0x02,
0x58,0x03,0x20,0x55,0x5E,0x50,0x58,0x27,0x00,0x05,
0x19,0x05,0x14,0x10,0x00,0x05,0x00,0x00,0x00,0x00,
0x00,0x00,0x40,0x30,0x30,0x3C,0x00,0x00,0x00,0x00,
0x0F,0x88,0x28,0x05,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01
},
{
0x00,0x0F,0x01,0x10,0x02,0x11,0x03,0x12,0x04,0x13,
0x05,0x14,0x06,0x15,0x07,0x16,0x08,0x17,0x09,0x18,
0x0A,0x19,0x0B,0x1A,0x0C,0x1B,0x0D,0x1C,0xFF,0xFF,
0x02,0x0C,0x03,0x0D,0x04,0x0E,0x05,0x0F,0x06,0x10,
0x07,0x11,0x08,0x12,0x09,0x13,0xFF,0x11,0x12,0x13,
0x0F,0x03,0x88,0x10,0x10,0x2A,0x00,0x00,0x00,0x00,
0x00,0x0E,0x45,0x30,0x58,0x03,0x00,0x05,0x00,0x02,
0x58,0x03,0x20,0x55,0x5E,0x50,0x58,0x27,0x00,0x05,
0x19,0x05,0x14,0x10,0x00,0x05,0x00,0x00,0x00,0x00,
0x00,0x00,0x40,0x30,0x30,0x3C,0x00,0x00,0x00,0x00,
0x0F,0x88,0x28,0x05,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01
}
};
static u8 config[GTP_CONFIG_LENGTH+2] = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff};
/****************operate according to ts chip:start************/
int ts_i2c_end_cmd(struct ts_private_data *ts)
{
int result = -1;
char end_cmd_data[2]={0x80, 0x00};
result = ts_reg_write(ts, end_cmd_data[0], end_cmd_data[1]);
if(result < 0)
{
printk("%s:fail to init ts\n",__func__);
return result;
}
return result;
}
static int ts_active(struct ts_private_data *ts, int enable)
{
int result = 0;
if(enable)
{
gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);
msleep(10);
gpio_direction_output(ts->pdata->reset_pin, GPIO_HIGH);
msleep(100);
}
else
{
gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);
}
return result;
}
static int ts_init(struct ts_private_data *ts)
{
int result = 0;
char version_data[5] = {ts->ops->version_reg >> 8, ts->ops->version_reg & 0xff};
u8 rd_cfg_buf[2];
//init some register
result = ts_bulk_read(ts, ts->ops->version_reg, 1, rd_cfg_buf);
if(result < 0)
{
printk("%s:fail to read rd_cfg_buf\n",__func__);
return result;
}
result = ts_i2c_end_cmd(ts);
if(result < 0)
{
printk("%s:fail to end cmd\n",__func__);
rd_cfg_buf[0] = 0;
//return result;
}
rd_cfg_buf[0] &= 0x03;
printk("%s:%s id is %d\n",__func__,ts->ops->name, rd_cfg_buf[0]);
memcpy(&config[2], cfg_info_group[rd_cfg_buf[0]], GTP_CONFIG_LENGTH);
if((ts->ops->trig & IRQF_TRIGGER_FALLING) || (ts->ops->trig & IRQF_TRIGGER_LOW)) //FALLING
{
config[TRIGGER_LOC+2] &= 0xf7;
}
else if((ts->ops->trig & IRQF_TRIGGER_RISING) || (ts->ops->trig & IRQF_TRIGGER_HIGH)) //RISING
{
config[TRIGGER_LOC+2] |= 0x08;
}
result = ts_bulk_write(ts, GTP_REG_CONFIG_DATA, GTP_CONFIG_LENGTH, config);
if(result < 0)
{
printk("%s:fail to send config data\n",__func__);
return result;
}
result = ts_i2c_end_cmd(ts);
if(result < 0)
{
printk("%s:fail to end cmd\n",__func__);
//return result;
}
//read version
result = ts_bulk_read(ts, ts->ops->version_reg, 4, version_data);
if(result < 0)
{
printk("%s:fail to init ts\n",__func__);
return result;
}
version_data[4]='\0';
result = ts_i2c_end_cmd(ts);
if(result < 0)
{
printk("%s:fail to end cmd\n",__func__);
//return result;
}
printk("%s:%s version is %s\n",__func__,ts->ops->name, version_data);
return result;
}
static int ts_report_value(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
struct ts_event *event = &ts->event;
unsigned char buf[2 + 2 + 5 * 5 + 1] = {0};
int result = 0 , i = 0, off = 0, id = 0;
int finger = 0;
int checksum = 0;
result = ts_bulk_read(ts, ts->ops->read_reg, ts->ops->read_len, buf);
if(result < 0)
{
printk("%s:fail to init ts\n",__func__);
return result;
}
result = ts_i2c_end_cmd(ts);
if(result < 0)
{
printk("%s:fail to end ts\n",__func__);
return result;
}
//for(i=0; i<ts->ops->read_len; i++)
//DBG("buf[%d]=0x%x\n",i,buf[i]);
finger = buf[0];
if((finger & 0x80) != 0x80)
{
DBG("%s:data not ready!,finger=0x%x\n",__func__,finger);
//return -1;
}
for(i = 0; i<ts->ops->max_point; i++)
{
off = i*5+2;
id = i;
event->point[id].id = id;
event->point[id].status = !!(finger & (1 << i));
event->point[id].x = (buf[off+0]<<8) | buf[off+1];
event->point[id].y = (buf[off+2]<<8) | buf[off+3];
event->point[id].press = buf[off+4];
DBG("data:0x%x,0x%x,0x%x,0x%x\n",buf[off+0],buf[off+1],buf[off+2],buf[off+3]);
if(ts->ops->xy_swap)
{
swap(event->point[id].x, event->point[id].y);
}
if(ts->ops->x_revert)
{
event->point[id].x = ts->ops->range[0] - event->point[id].x;
}
if(ts->ops->y_revert)
{
event->point[id].y = ts->ops->range[1] - event->point[id].y;
}
if(event->point[id].status != 0)
{
input_mt_slot(ts->input_dev, event->point[id].id);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, event->point[id].id);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, event->point[id].press);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, event->point[id].x);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, event->point[id].y);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 1);
DBG("%s:%s press down,id=%d,x=%d,y=%d\n",__func__,ts->ops->name, event->point[id].id, event->point[id].x,event->point[id].y);
}
else if ((event->point[id].status == 0) && (event->point[id].last_status != 0))
{
input_mt_slot(ts->input_dev, event->point[i].id);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
DBG("%s:%s press up,id=%d\n",__func__,ts->ops->name, event->point[i].id);
}
event->point[i].last_status = event->point[i].status;
}
input_sync(ts->input_dev);
return 0;
}
static int ts_suspend(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
if(ts->ops->active)
ts->ops->active(ts, 0);
return 0;
}
static int ts_resume(struct ts_private_data *ts)
{
struct ts_platform_data *pdata = ts->pdata;
if(ts->ops->active)
ts->ops->active(ts, 1);
return 0;
}
struct ts_operate ts_gt828_ops = {
.name = "gt828",
.slave_addr = 0x5d,
.ts_id = TS_ID_GT828, //i2c id number
.bus_type = TS_BUS_TYPE_I2C,
.reg_size = 2,
.id_reg = GTP_REG_SENSOR_ID,
.id_data = TS_UNKNOW_DATA,
.version_reg = 0x0F7D,
.version_len = 0,
.version_data = NULL,
.read_reg = GTP_READ_COOR_ADDR, //read data
.read_len = 2 + 2 + 5 * 5 + 1, //data length
.trig = IRQF_TRIGGER_FALLING,
.max_point = 5,
.xy_swap = 0,
.x_revert = 0,
.y_revert = 0,
.range = {800,1280},
.irq_enable = 1,
.poll_delay_ms = 0,
.active = ts_active,
.init = ts_init,
.check_irq = NULL,
.report = ts_report_value,
.firmware = NULL,
.suspend = ts_suspend,
.resume = ts_resume,
};
/****************operate according to ts chip:end************/
//function name should not be changed
static struct ts_operate *ts_get_ops(void)
{
return &ts_gt828_ops;
}
static int __init ts_gt828_init(void)
{
struct ts_operate *ops = ts_get_ops();
int result = 0;
result = ts_register_slave(NULL, NULL, ts_get_ops);
DBG("%s\n",__func__);
return result;
}
static void __exit ts_gt828_exit(void)
{
struct ts_operate *ops = ts_get_ops();
ts_unregister_slave(NULL, NULL, ts_get_ops);
}
subsys_initcall(ts_gt828_init);
module_exit(ts_gt828_exit);

View File

@ -1,610 +0,0 @@
/* drivers/input/ts/ts-auto.c - handle all touchscreen in this file
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/freezer.h>
#include <linux/input/mt.h>
#include <mach/gpio.h>
#include <mach/board.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/ts-auto.h>
#if 0
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
struct ts_private_data *g_ts;
static struct class *g_ts_class;
static struct ts_operate *g_ts_ops[TS_NUM_ID];
/**
* ts_reg_read: Read a single ts register.
*
* @ts: Device to read from.
* @reg: Register to read.
*/
int ts_reg_read(struct ts_private_data *ts, unsigned short reg)
{
unsigned short val;
int ret;
mutex_lock(&ts->io_lock);
ret = ts->read_dev(ts, reg, ts->ops->reg_size, &val, ts->ops->reg_size);
mutex_unlock(&ts->io_lock);
if (ret < 0)
return ret;
else
return val;
}
EXPORT_SYMBOL_GPL(ts_reg_read);
/**
* ts_bulk_read: Read multiple ts registers
*
* @ts: Device to read from
* @reg: First register
* @count: Number of registers
* @buf: Buffer to fill.
*/
int ts_bulk_read(struct ts_private_data *ts, unsigned short reg,
int count, unsigned char *buf)
{
int ret;
mutex_lock(&ts->io_lock);
ret = ts->read_dev(ts, reg, count, buf, ts->ops->reg_size);
mutex_unlock(&ts->io_lock);
return ret;
}
EXPORT_SYMBOL_GPL(ts_bulk_read);
/**
* ts_reg_write: Write a single ts register.
*
* @ts: Device to write to.
* @reg: Register to write to.
* @val: Value to write.
*/
int ts_reg_write(struct ts_private_data *ts, unsigned short reg,
unsigned short val)
{
int ret;
mutex_lock(&ts->io_lock);
ret = ts->write_dev(ts, reg, ts->ops->reg_size, &val, ts->ops->reg_size);
mutex_unlock(&ts->io_lock);
return ret;
}
EXPORT_SYMBOL_GPL(ts_reg_write);
int ts_bulk_write(struct ts_private_data *ts, unsigned short reg,
int count, unsigned char *buf)
{
int ret;
mutex_lock(&ts->io_lock);
ret = ts->write_dev(ts, reg, count, buf, ts->ops->reg_size);
mutex_unlock(&ts->io_lock);
return ret;
}
EXPORT_SYMBOL_GPL(ts_bulk_write);
/**
* ts_set_bits: Set the value of a bitfield in a ts register
*
* @ts: Device to write to.
* @reg: Register to write to.
* @mask: Mask of bits to set.
* @val: Value to set (unshifted)
*/
int ts_set_bits(struct ts_private_data *ts, unsigned short reg,
unsigned short mask, unsigned short val)
{
int ret;
u16 r;
mutex_lock(&ts->io_lock);
ret = ts->read_dev(ts, reg, ts->ops->reg_size, &r, ts->ops->reg_size);
if (ret < 0)
goto out;
r &= ~mask;
r |= val;
ret = ts->write_dev(ts, reg, ts->ops->reg_size, &r, ts->ops->reg_size);
out:
mutex_unlock(&ts->io_lock);
return ret;
}
EXPORT_SYMBOL_GPL(ts_set_bits);
static int ts_get_id(struct ts_operate *ops, struct ts_private_data *ts, int *value)
{
int result = 0;
char temp[4] = {ops->id_reg & 0xff};
int i = 0;
DBG("%s:start\n",__func__);
if(ops->id_reg >= 0)
{
for(i=0; i<2; i++)
{
if(ops->reg_size == 2)
{
temp[0] = ops->id_reg >> 8;
temp[1] = ops->id_reg & 0xff;
result = ts->read_dev(ts, ops->id_reg, 2, temp, ops->reg_size);
*value = (temp[0] << 8) | temp[1];
}
else
{
result = ts->read_dev(ts, ops->id_reg, 1, temp, ops->reg_size);
*value = temp[0];
}
if(!result)
break;
}
if(result)
return result;
if((ops->id_data != TS_UNKNOW_DATA)&&(ops->id_data != *value))
{
printk("%s:id=0x%x is not 0x%x\n",__func__,*value, ops->id_data);
result = -1;
}
DBG("%s:devid=0x%x\n",__func__,*value);
}
return result;
}
static int ts_get_version(struct ts_operate *ops, struct ts_private_data *ts)
{
int result = 0;
char temp[TS_MAX_VER_LEN + 1] = {0};
int i = 0;
DBG("%s:start\n",__func__);
if(ops->version_reg >= 0)
{
if((ops->version_len < 0) || (ops->version_len > TS_MAX_VER_LEN))
{
printk("%s:version_len %d is error\n",__func__,ops->version_len);
ops->version_len = TS_MAX_VER_LEN;
}
result = ts->read_dev(ts, ops->version_reg, ops->version_len, temp, ops->reg_size);
if(result)
return result;
if(ops->version_data)
{
for(i=0; i<ops->version_len; i++)
{
if(temp[i] == ops->version_data[i])
continue;
printk("%s:version %s is not %s\n",__func__,temp, ops->version_data);
result = -1;
}
}
DBG("%s:%s version: %s\n",__func__,ops->name, temp);
}
return result;
}
static int ts_chip_init(struct ts_private_data *ts, int type)
{
struct ts_operate *ops = NULL;
int result = 0;
int i = 0;
if((type <= TS_BUS_TYPE_INVALID) || (type >= TS_BUS_TYPE_NUM_ID))
{
printk("%s:type=%d is error\n",__func__,type);
return -1;
}
if(ts->pdata->init_platform_hw)
ts->pdata->init_platform_hw();
for(i=TS_ID_INVALID+1; i<TS_NUM_ID; i++)
{
ops = g_ts_ops[i];
if(!ops)
{
printk("%s:error:%p\n",__func__,ops);
result = -1;
continue;
}
if(ops->bus_type == type)
{
if(!ops->init || !ops->report)
{
printk("%s:error:%p,%p\n",__func__,ops->init,ops->report);
result = -1;
continue;
}
ts->ops = ops; //save ops
result = ts_get_id(ops, ts, &ts->devid);//get id
if(result < 0)
{
printk("%s:fail to read %s devid:0x%x\n",__func__, ops->name, ts->devid);
continue;
}
result = ts_get_version(ops, ts); //get version
if(result < 0)
{
printk("%s:fail to read %s version\n",__func__, ops->name);
continue;
}
result = ops->init(ts);
if(result < 0)
{
printk("%s:fail to init ts\n",__func__);
continue;
}
if(ops->firmware)
{
result = ops->firmware(ts);
if(result < 0)
{
printk("%s:fail to updata firmware ts\n",__func__);
return result;
}
}
printk("%s:%s devid:0x%x\n",__func__, ts->ops->name, ts->devid);
}
break;
}
return result;
}
static int ts_get_data(struct ts_private_data *ts)
{
return ts->ops->report(ts);
}
static void ts_delaywork_func(struct work_struct *work)
{
struct delayed_work *delaywork = container_of(work, struct delayed_work, work);
struct ts_private_data *ts = container_of(delaywork, struct ts_private_data, delaywork);
mutex_lock(&ts->ts_lock);
if (ts_get_data(ts) < 0)
DBG(KERN_ERR "%s: Get data failed\n",__func__);
if(!ts->ops->irq_enable)//restart work while polling
schedule_delayed_work(&ts->delaywork, msecs_to_jiffies(ts->ops->poll_delay_ms));
else
{
if(ts->ops->check_irq)
{
ts->ops->check_irq(ts);
}
else
{
if((ts->ops->trig & IRQF_TRIGGER_LOW) || (ts->ops->trig & IRQF_TRIGGER_HIGH))
enable_irq(ts->irq);
}
}
mutex_unlock(&ts->ts_lock);
DBG("%s:%s\n",__func__,ts->i2c_id->name);
}
/*
* This is a threaded IRQ handler so can access I2C/SPI. Since all
* interrupts are clear on read the IRQ line will be reasserted and
* the physical IRQ will be handled again if another interrupt is
* asserted while we run - in the normal course of events this is a
* rare occurrence so we save I2C/SPI reads. We're also assuming that
* it's rare to get lots of interrupts firing simultaneously so try to
* minimise I/O.
*/
static irqreturn_t ts_interrupt(int irq, void *dev_id)
{
struct ts_private_data *ts = (struct ts_private_data *)dev_id;
//use threaded IRQ
//if (ts_get_data(ts->client) < 0)
// DBG(KERN_ERR "%s: Get data failed\n",__func__);
//msleep(ts->ops->poll_delay_ms);
if(ts->ops->check_irq)
{
disable_irq_nosync(irq);
}
else
{
if((ts->ops->trig & IRQF_TRIGGER_LOW) || (ts->ops->trig & IRQF_TRIGGER_HIGH))
disable_irq_nosync(irq);
}
schedule_delayed_work(&ts->delaywork, msecs_to_jiffies(ts->ops->poll_delay_ms));
DBG("%s:irq=%d\n",__func__,irq);
return IRQ_HANDLED;
}
static int ts_irq_init(struct ts_private_data *ts)
{
int result = 0;
int irq;
if((ts->ops->irq_enable)&&(ts->ops->trig != TS_UNKNOW_DATA))
{
INIT_DELAYED_WORK(&ts->delaywork, ts_delaywork_func);
if(ts->ops->poll_delay_ms < 0)
ts->ops->poll_delay_ms = 30;
//result = gpio_request(ts->irq, ts->i2c_id->name);
//if (result)
//{
// printk("%s:fail to request gpio :%d\n",__func__,ts->irq);
//}
gpio_pull_updown(ts->irq, PullEnable);
irq = gpio_to_irq(ts->irq);
result = request_irq(irq, ts_interrupt, ts->ops->trig, ts->ops->name, ts);
//result = request_threaded_irq(irq, NULL, ts_interrupt, ts->ops->trig, ts->ops->name, ts);
if (result) {
printk(KERN_ERR "%s:fail to request irq = %d, ret = 0x%x\n",__func__, irq, result);
goto error;
}
ts->irq = irq;
printk("%s:use irq=%d\n",__func__,irq);
}
else if(!ts->ops->irq_enable)
{
INIT_DELAYED_WORK(&ts->delaywork, ts_delaywork_func);
if(ts->ops->poll_delay_ms < 0)
ts->ops->poll_delay_ms = 30;
schedule_delayed_work(&ts->delaywork, msecs_to_jiffies(ts->ops->poll_delay_ms));
printk("%s:use polling,delay=%d ms\n",__func__,ts->ops->poll_delay_ms);
}
error:
return result;
}
int ts_device_init(struct ts_private_data *ts, int type, int irq)
{
struct ts_platform_data *pdata = ts->dev->platform_data;
int result = -1, i;
mutex_init(&ts->io_lock);
mutex_init(&ts->ts_lock);
dev_set_drvdata(ts->dev, ts);
ts->pdata = pdata;
result = ts_chip_init(ts, type);
if(result < 0)
{
printk("%s:touch screen with bus type %d is not exist\n",__func__,type);
goto out_free_memory;
}
ts->input_dev = input_allocate_device();
if (!ts->input_dev) {
result = -ENOMEM;
dev_err(ts->dev,
"Failed to allocate input device %s\n", ts->input_dev->name);
goto out_free_memory;
}
ts->input_dev->dev.parent = ts->dev;
ts->input_dev->name = ts->ops->name;
result = input_register_device(ts->input_dev);
if (result) {
dev_err(ts->dev,
"Unable to register input device %s\n", ts->input_dev->name);
goto out_input_register_device_failed;
}
result = ts_irq_init(ts);
if (result) {
dev_err(ts->dev,
"fail to init ts irq,ret=%d\n",result);
goto out_input_register_device_failed;
}
__set_bit(EV_ABS, ts->input_dev->evbit);
__set_bit(EV_KEY, ts->input_dev->evbit);
__set_bit(EV_REP, ts->input_dev->evbit);
__set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
set_bit(ABS_MT_POSITION_X, ts->input_dev->absbit);
set_bit(ABS_MT_POSITION_Y, ts->input_dev->absbit);
set_bit(ABS_MT_TOUCH_MAJOR, ts->input_dev->absbit);
set_bit(ABS_MT_WIDTH_MAJOR, ts->input_dev->absbit);
if(ts->ops->max_point <= 0)
ts->ops->max_point = 1;
input_mt_init_slots(ts->input_dev, ts->ops->max_point);
if((ts->ops->range[0] <= 0) || (ts->ops->range[1] <= 0))
{
ts->ops->range[0] = 1024;
ts->ops->range[1] = 600;
}
input_set_abs_params(ts->input_dev,ABS_MT_POSITION_X, 0, ts->ops->range[0], 0, 0);
input_set_abs_params(ts->input_dev,ABS_MT_POSITION_Y, 0, ts->ops->range[1], 0, 0);
input_set_abs_params(ts->input_dev,ABS_MT_TOUCH_MAJOR, 0, 10, 0, 0);
input_set_abs_params(ts->input_dev,ABS_MT_WIDTH_MAJOR, 0, 10, 0, 0);
g_ts = ts;
printk("%s:initialized ok,ts name:%s,devid=%d\n\n",__func__,ts->ops->name,ts->devid);
return result;
out_misc_device_register_device_failed:
input_unregister_device(ts->input_dev);
out_input_register_device_failed:
input_free_device(ts->input_dev);
out_free_memory:
kfree(ts);
printk("%s:line=%d\n",__func__,__LINE__);
return result;
}
void ts_device_exit(struct ts_private_data *ts)
{
if(!ts->ops->irq_enable)
cancel_delayed_work_sync(&ts->delaywork);
input_unregister_device(ts->input_dev);
input_free_device(ts->input_dev);
#ifdef CONFIG_HAS_EARLYSUSPEND
if((ts->ops->suspend) && (ts->ops->resume))
unregister_early_suspend(&ts->early_suspend);
#endif
kfree(ts);
}
int ts_device_suspend(struct ts_private_data *ts)
{
if(ts->ops->suspend)
ts->ops->suspend(ts);
if(ts->ops->irq_enable)
disable_irq_nosync(ts->irq);
else
cancel_delayed_work_sync(&ts->delaywork);
return 0;
}
int ts_device_resume(struct ts_private_data *ts)
{
if(ts->ops->resume)
ts->ops->resume(ts);
if(ts->ops->irq_enable)
enable_irq(ts->irq);
else
{
PREPARE_DELAYED_WORK(&ts->delaywork, ts_delaywork_func);
schedule_delayed_work(&ts->delaywork, msecs_to_jiffies(ts->ops->poll_delay_ms));
}
return 0;
}
int ts_register_slave(struct ts_private_data *ts,
struct ts_platform_data *slave_pdata,
struct ts_operate *(*get_ts_ops)(void))
{
int result = 0;
struct ts_operate *ops = get_ts_ops();
if((ops->ts_id >= TS_NUM_ID) || (ops->ts_id <= TS_ID_INVALID))
{
printk("%s:%s id is error %d\n", __func__, ops->name, ops->ts_id);
return -1;
}
g_ts_ops[ops->ts_id] = ops;
printk("%s:%s,id=%d\n",__func__,g_ts_ops[ops->ts_id]->name, ops->ts_id);
return result;
}
int ts_unregister_slave(struct ts_private_data *ts,
struct ts_platform_data *slave_pdata,
struct ts_operate *(*get_ts_ops)(void))
{
int result = 0;
struct ts_operate *ops = get_ts_ops();
if((ops->ts_id >= TS_NUM_ID) || (ops->ts_id <= TS_ID_INVALID))
{
printk("%s:%s id is error %d\n", __func__, ops->name, ops->ts_id);
return -1;
}
printk("%s:%s,id=%d\n",__func__,g_ts_ops[ops->ts_id]->name, ops->ts_id);
g_ts_ops[ops->ts_id] = NULL;
return result;
}
MODULE_AUTHOR("ROCKCHIP Corporation:lw@rock-chips.com");
MODULE_DESCRIPTION("device interface for auto touch screen");
MODULE_LICENSE("GPL");

View File

@ -1,302 +0,0 @@
/* drivers/input/ts/ts-i2c.c - touchscreen i2c handle
*
* Copyright (C) 2012-2015 ROCKCHIP.
* Author: luowei <lw@rock-chips.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/freezer.h>
#include <mach/gpio.h>
#include <mach/board.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/ts-auto.h>
#define TS_I2C_RATE 200*1000
#if 0
#define TS_DEBUG_ENABLE
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
static int ts_i2c_read_device(struct ts_private_data *ts, unsigned short reg,
int bytes, void *dest, int reg_size)
{
struct i2c_client *client = ts->control_data;
struct i2c_adapter *i2c_adap = client->adapter;
struct i2c_msg msgs[2];
int i,res;
if (!dest || !i2c_adap) {
printk("%s:line=%d,error\n",__func__,__LINE__);
return -EINVAL;
}
client->addr = ts->ops->slave_addr;
msgs[0].addr = client->addr;
msgs[0].flags = 0; /* write */
msgs[0].buf = (unsigned char *)&reg;
if(reg_size == 2)
msgs[0].len = 2;
else
msgs[0].len = 1;
msgs[0].scl_rate = TS_I2C_RATE;
msgs[1].addr = client->addr;
msgs[1].flags = I2C_M_RD;
msgs[1].buf = dest;
msgs[1].len = bytes;
msgs[1].scl_rate = TS_I2C_RATE;
res = i2c_transfer(i2c_adap, msgs, 2);
if (res == 2)
return 0;
else if(res == 0)
return -EBUSY;
else
return res;
#ifdef TS_DEBUG_ENABLE
DBG("%s:reg=0x%x,len=%d,rxdata:",__func__, reg, bytes);
for(i=0; i<bytes; i++)
DBG("0x%x,",(unsigned char *)dest[i]);
DBG("\n");
#endif
}
/* Currently we allocate the write buffer on the stack; this is OK for
* small writes - if we need to do large writes this will need to be
* revised.
*/
static int ts_i2c_write_device(struct ts_private_data *ts, unsigned short reg,
int bytes, void *src, int reg_size)
{
struct i2c_client *client = ts->control_data;
struct i2c_adapter *i2c_adap = client->adapter;
struct i2c_msg msgs[1];
int res;
unsigned char buf[bytes + 2];
if (!src || !i2c_adap) {
printk("%s:line=%d,error\n",__func__,__LINE__);
return -EINVAL;
}
client->addr = ts->ops->slave_addr;
if(ts->ops->reg_size == 2)
{
buf[0] = (reg & 0xff00) >> 8;
buf[1] = (reg & 0x00ff) & 0xff;
memcpy(&buf[2], src, bytes);
}
else
{
buf[0] = reg & 0xff;
memcpy(&buf[1], src, bytes);
}
#ifdef TS_DEBUG_ENABLE
int i = 0;
DBG("%s:reg=0x%x,len=%d,txdata:",__func__, reg, bytes);
for(i=0; i<length; i++)
DBG("0x%x,",buf[i]);
DBG("\n");
#endif
if (!src || !i2c_adap) {
printk("%s:line=%d,error\n",__func__,__LINE__);
return -EINVAL;
}
msgs[0].addr = client->addr;
msgs[0].flags = 0; /* write */
msgs[0].buf = buf;
if(ts->ops->reg_size == 2)
msgs[0].len = bytes+2;
else
msgs[0].len = bytes+1;
msgs[0].scl_rate = TS_I2C_RATE;
res = i2c_transfer(i2c_adap, msgs, 1);
if (res == 1)
return 0;
else if(res == 0)
return -EBUSY;
else
return res;
}
int ts_bulk_read_normal(struct ts_private_data *ts,
int count, unsigned char *buf, int rate)
{
int ret;
unsigned short reg;
struct i2c_client *client = ts->control_data;
client->addr = ts->ops->slave_addr;
mutex_lock(&ts->io_lock);
ret = i2c_master_normal_recv(client, buf, count, rate);
if(ret == 1)
ret = 0;
mutex_unlock(&ts->io_lock);
return ret;
}
EXPORT_SYMBOL_GPL(ts_bulk_read_normal);
int ts_bulk_write_normal(struct ts_private_data *ts, int count, unsigned char *buf, int rate)
{
int ret;
unsigned short reg;
struct i2c_client *client = ts->control_data;
client->addr = ts->ops->slave_addr;
mutex_lock(&ts->io_lock);
ret = i2c_master_normal_send(client, buf, count, rate);
if(ret == 1)
ret = 0;
mutex_unlock(&ts->io_lock);
return ret;
}
EXPORT_SYMBOL_GPL(ts_bulk_write_normal);
#ifdef CONFIG_HAS_EARLYSUSPEND
static void ts_suspend(struct early_suspend *h)
{
struct ts_private_data *ts =
container_of(h, struct ts_private_data, early_suspend);
return ts_device_suspend(ts);
}
static void ts_resume(struct early_suspend *h)
{
struct ts_private_data *ts =
container_of(h, struct ts_private_data, early_suspend);
return ts_device_resume(ts);
}
#endif
static int ts_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct ts_private_data *ts;
int ret,gpio,irq;
int type = TS_BUS_TYPE_I2C;
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
dev_err(&i2c->adapter->dev, "%s failed\n", __func__);
return -ENODEV;
}
ts = kzalloc(sizeof(struct ts_private_data), GFP_KERNEL);
if (ts == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c, ts);
ts->irq = i2c->irq;
ts->dev = &i2c->dev;
ts->control_data = i2c;
ts->read_dev = ts_i2c_read_device;
ts->write_dev = ts_i2c_write_device;
ret = ts_device_init(ts, type, ts->irq);
if(ret)
{
printk("%s:fail to regist touch, type is %d\n",__func__, type);
return -1;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
if((ts->ops->suspend) && (ts->ops->resume))
{
ts->early_suspend.suspend = ts_suspend;
ts->early_suspend.resume = ts_resume;
ts->early_suspend.level = 0x02;
register_early_suspend(&ts->early_suspend);
}
#endif
return 0;
}
static int ts_i2c_remove(struct i2c_client *i2c)
{
struct ts_private_data *ts = i2c_get_clientdata(i2c);
ts_device_exit(ts);
return 0;
}
static const struct i2c_device_id ts_i2c_id[] = {
{"auto_ts_i2c", 0},
{},
};
MODULE_DEVICE_TABLE(i2c, ts_i2c_id);
static struct i2c_driver ts_i2c_driver = {
.driver = {
.name = "auto_ts_i2c",
.owner = THIS_MODULE,
},
.probe = ts_i2c_probe,
.remove = ts_i2c_remove,
.id_table = ts_i2c_id,
};
static int __init ts_i2c_init(void)
{
int ret;
printk("%s\n", __FUNCTION__);
ret = i2c_add_driver(&ts_i2c_driver);
if (ret != 0)
pr_err("Failed to register ts I2C driver: %d\n", ret);
return ret;
}
subsys_initcall_sync(ts_i2c_init);
static void __exit ts_i2c_exit(void)
{
i2c_del_driver(&ts_i2c_driver);
}
module_exit(ts_i2c_exit);

View File

@ -1,2 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
//to do

View File

@ -1,2 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
//to do

View File

@ -1,152 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __TS_AUTO_H
#define __TS_AUTO_H
#include <linux/miscdevice.h>
#define TS_ENABLE 1
#define TS_DISABLE 0
#define TS_UNKNOW_DATA -1
#define TS_MAX_POINT 20
#define TS_MAX_VER_LEN 64
struct ts_private_data;
enum ts_bus_type{
TS_BUS_TYPE_INVALID = 0,
TS_BUS_TYPE_I2C,
TS_BUS_TYPE_SPI,
TS_BUS_TYPE_SERIAL,
TS_BUS_TYPE_NUM_ID,
};
enum ts_id {
TS_ID_INVALID = 0,
TS_ID_FT5306,
TS_ID_CT360,
TS_ID_GT8110,
TS_ID_GT828,
TS_ID_GT8005,
TS_NUM_ID,
};
struct point_data {
int status;
int id;
int x;
int y;
int press;
int last_status;
};
struct ts_event {
int touch_point;
struct point_data point[TS_MAX_POINT];
};
/* Platform data for the auto touchscreen */
struct ts_platform_data {
unsigned char slave_addr;
int irq;
int power_pin;
int reset_pin;
int (*init_platform_hw)(void);
};
struct ts_max_pixel{
int max_x;
int max_y;
};
struct ts_operate {
char *name;
char slave_addr;
int ts_id;
int bus_type;
struct ts_max_pixel pixel;
int reg_size;
int id_reg;
int id_data;
int version_reg;
char *version_data;
int version_len; //<64
int read_reg;
int read_len;
int trig; //intterupt trigger
int max_point;
int xy_swap;
int x_revert;
int y_revert;
int range[2];
int irq_enable; //if irq_enable=1 then use irq else use polling
int poll_delay_ms; //polling
int gpio_level_no_int;
int (*active)(struct ts_private_data *ts, int enable);
int (*init)(struct ts_private_data *ts);
int (*check_irq)(struct ts_private_data *ts);
int (*report)(struct ts_private_data *ts);
int (*firmware)(struct ts_private_data *ts);
int (*suspend)(struct ts_private_data *ts);
int (*resume)(struct ts_private_data *ts);
struct miscdevice *misc_dev;
};
struct ts_private_data {
struct mutex io_lock;
struct device *dev;
int (*read_dev)(struct ts_private_data *ts, unsigned short reg,
int bytes, void *dest, int reg_size);
int (*write_dev)(struct ts_private_data *ts, unsigned short reg,
int bytes, void *src, int reg_size);
void *control_data;
int irq;
//struct i2c_client *client;
struct input_dev *input_dev;
struct ts_event event;
struct work_struct work;
struct delayed_work delaywork; /*report second event*/
struct delayed_work poll_work; /*poll at last*/
char ts_data[40]; //max support40 bytes data
struct mutex data_mutex;
struct mutex ts_lock;
int devid;
struct i2c_device_id *i2c_id;
struct ts_platform_data *pdata;
struct ts_operate *ops;
struct file_operations fops;
struct miscdevice miscdev;
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
#endif
};
extern int ts_device_init(struct ts_private_data *ts, int type, int irq);
extern void ts_device_exit(struct ts_private_data *ts);
extern int ts_register_slave(struct ts_private_data *ts,
struct ts_platform_data *slave_pdata,
struct ts_operate *(*get_ts_ops)(void));
extern int ts_unregister_slave(struct ts_private_data *ts,
struct ts_platform_data *slave_pdata,
struct ts_operate *(*get_ts_ops)(void));
extern int ts_reg_read(struct ts_private_data *ts, unsigned short reg);
extern int ts_reg_write(struct ts_private_data *ts, unsigned short reg,
unsigned short val);
extern int ts_bulk_read(struct ts_private_data *ts, unsigned short reg,
int count, unsigned char *buf);
extern int ts_bulk_read_normal(struct ts_private_data *ts, int count, unsigned char *buf, int rate);
extern int ts_bulk_write(struct ts_private_data *ts, unsigned short reg,
int count, unsigned char *buf);
extern int ts_bulk_write_normal(struct ts_private_data *ts, int count, unsigned char *buf, int rate);
extern int ts_set_bits(struct ts_private_data *ts, unsigned short reg,
unsigned short mask, unsigned short val);
extern int ts_device_suspend(struct ts_private_data *ts);
extern int ts_device_resume(struct ts_private_data *ts);
#endif