add touchscreen support for a22

This commit is contained in:
luowei 2011-03-24 17:44:03 +08:00
parent e130f81f1f
commit 59886919e4
5 changed files with 706 additions and 2 deletions

View File

@ -1231,6 +1231,29 @@ struct platform_device rk29_device_gps = {
};
#endif
#if defined(CONFIG_TOUCHSCREEN_ILI2102_IIC)
#include "../../../drivers/input/touchscreen/ili2102_ts.h"
#define GT801_GPIO_INT RK29_PIN4_PD5
#define GT801_GPIO_RESET RK29_PIN6_PC3
static struct ili2102_platform_data ili2102_info = {
.model = 2102,
.swap_xy = 0,
.x_min = 0,
.x_max = 480,
.y_min = 0,
.y_max = 800,
.gpio_reset = GT801_GPIO_RESET,
.gpio_reset_active_low = 1,
.gpio_pendown = GT801_GPIO_INT,
.pendown_iomux_name = GPIO4D5_CPUTRACECTL_NAME,
.resetpin_iomux_name = NULL,
.pendown_iomux_mode = GPIO4H_GPIO4D5,
.resetpin_iomux_mode = 0,
};
#endif
/*****************************************************************************************
* i2c devices
* author: kfx@rock-chips.com
@ -1409,6 +1432,15 @@ static struct i2c_board_info __initdata board_i2c1_devices[] = {
#ifdef CONFIG_I2C2_RK29
static struct i2c_board_info __initdata board_i2c2_devices[] = {
#if defined (CONFIG_TOUCHSCREEN_ILI2102_IIC)
{
.type = "ili2102_ts",
.addr = 0x41,
.flags = 0,
.irq = RK29_PIN4_PD5,
.platform_data = &ili2102_info,
},
#endif
#if defined (CONFIG_MFD_WM831X_I2C)
{
.type = "wm8310",

View File

@ -13,7 +13,7 @@ if INPUT_TOUCHSCREEN
config TOUCHSCREEN_XPT2046_SPI
tristate "XPT2046 based touchscreens:SPI Interface"
depends on SPIM_RK2818 || SPIM_RK29
depends on SPIM_RK29
config TOUCHSCREEN_XPT2046_NORMAL_SPI
tristate "normal mode"
@ -63,6 +63,31 @@ config TOUCHSCREEN_XPT2046_SPI
tristate "320X480 resolution"
depends on TOUCHSCREEN_XPT2046_CBN_SPI
#choice
# prompt "XPT2046 based touchscreens: SPI Interface"
# default TOUCHSCREEN_XPT2046_CBN_SPI
# config TOUCHSCREEN_XPT2046_SPI_NOCHOOSE
# bool "DO NOT CHOOSE TOUCHSCREEN_XPT2046"
# config TOUCHSCREEN_XPT2046_SPI
# bool "800X480 TOUCHSCREEN"
# depends on SPIM_RK2818 || SPIM_RK29
# config TOUCHSCREEN_XPT2046_CBN_SPI
# bool "800X480 CALIBRATION TOUCHSCREEN"
# depends on SPIM_RK2818 || SPIM_RK29
# config TOUCHSCREEN_XPT2046_320X480_SPI
# bool "320X480 TOUCHSCREEN"
# depends on SPIM_RK2818 || SPIM_RK29
# config TOUCHSCREEN_XPT2046_320X480_CBN_SPI
# bool "320X480 CALIBRATION TOUCHSCREEN"
# depends on SPIM_RK2818 || SPIM_RK29
#endchoice
config TOUCHSCREEN_ADS7846
tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"
depends on SPI_MASTER
@ -94,6 +119,15 @@ config TOUCHSCREEN_AD7877
To compile this driver as a module, choose M here: the
module will be called ad7877.
config TOUCHSCREEN_ILI2102_IIC
tristate "ili2102 based touchscreens: IIC Interface"
help
Say Y here if you have a touchscreen interface using the
hx8520 controller, and your board-specific initialization
code includes that in its table of IIC devices.
If unsure, say N (but it's safe to say "Y").
config RK28_I2C_TS_NTP070
tristate "NTP070 based touchscreens: NTP070 Interface"
depends on I2C_RK2818
@ -718,5 +752,4 @@ config TOUCHSCREEN_IT7260
config TOUCHSCREEN_GT801_IIC
tristate "GT801_IIC based touchscreens"
depends on I2C2_RK29
endif

View File

@ -54,4 +54,5 @@ obj-$(CONFIG_SINTEK_3FA16) += sintek_3FA16.o
obj-$(CONFIG_EETI_EGALAX) += eeti_egalax_i2c.o
obj-$(CONFIG_ATMEL_MXT224) += atmel_mxt224.o
obj-$(CONFIG_TOUCHSCREEN_GT801_IIC) += gt801_ts.o
obj-$(CONFIG_TOUCHSCREEN_ILI2102_IIC) += ili2102_ts.o

View File

@ -0,0 +1,596 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/earlysuspend.h>
#include <linux/hrtimer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <mach/iomux.h>
#include <linux/platform_device.h>
#include "ili2102_ts.h"
#if 1
#define DBG(msg...) printk(msg);
#else
#define DBG(msg...)
#endif
#define TOUCH_NUMBER 2
static int touch_state[TOUCH_NUMBER] = {TOUCH_UP,TOUCH_UP};
static struct workqueue_struct *ili2102_wq;
struct ili2102_ts_data {
u16 model; /* 801. */
bool swap_xy; /* swap x and y axes */
u16 x_min, x_max;
u16 y_min, y_max;
uint16_t addr;
int use_irq;
int gpio_pendown;
int gpio_reset;
int gpio_reset_active_low;
int pendown_iomux_mode;
int resetpin_iomux_mode;
char pendown_iomux_name[IOMUX_NAME_SIZE];
char resetpin_iomux_name[IOMUX_NAME_SIZE];
char phys[32];
char name[32];
struct i2c_client *client;
struct input_dev *input_dev;
struct hrtimer timer;
struct work_struct work;
struct early_suspend early_suspend;
};
#ifdef CONFIG_HAS_EARLYSUSPEND
static void ili2102_ts_early_suspend(struct early_suspend *h);
static void ili2102_ts_late_resume(struct early_suspend *h);
#endif
static int verify_coord(struct ili2102_ts_data *ts,unsigned int *x,unsigned int *y)
{
DBG("%s:(%d/%d)\n",__FUNCTION__,*x, *y);
if((*x< ts->x_min) || (*x > ts->x_max))
return -1;
if((*y< ts->y_min) || (*y > ts->y_max))
return -1;
return 0;
}
static int ili2102_init_panel(struct ili2102_ts_data *ts)
{
return 0;
}
static void ili2102_test(struct i2c_client *client)
{
int i;
int ret;
struct i2c_msg msg[2];
uint8_t start_reg;
uint8_t buf[4];
start_reg = 0x31;
msg[0].addr =client->addr;
msg[0].flags = 0;
msg[0].len = 1;
msg[0].buf = &start_reg;
msg[1].addr = client->addr;
msg[1].flags = I2C_M_RD;
msg[1].len = 3;
msg[1].buf = buf;
ret = i2c_transfer(client->adapter, msg, 2);
if (ret < 0) {
printk("ili2102_test:i2c_transfer fail =%d\n",ret);
}
for(i=0; i<3; i++){
printk("ili2102_test:buf[%d]=%x\n", i, buf[i]);
}
}
static void ili2102_ts_work_func(struct work_struct *work)
{
int i,ret;
int syn_flag = 0;
unsigned int x, y;
struct i2c_msg msg[2];
uint8_t start_reg;
uint32_t buf[4];
struct ili2102_ts_data *ts = container_of(work, struct ili2102_ts_data, work);
DBG("ili2102_ts_work_func\n");
start_reg = 0x86;
msg[0].addr = ts->client->addr;
msg[0].flags = 0;
msg[0].len = 1;
msg[0].buf = &start_reg;
msg[1].addr = ts->client->addr;
msg[1].flags = I2C_M_RD;
msg[1].len = 4 * TOUCH_NUMBER;
msg[1].buf = (u8*)&buf[0];
ret = i2c_transfer(ts->client->adapter, msg, 2);
if (ret < 0) {
for(i=0; i<TOUCH_NUMBER; i++) buf[i] = 0xffffffff;
printk("ili2102_ts_work_func:i2c_transfer fail =%d\n",ret);
}
for(i=0; i<TOUCH_NUMBER; i++){
if(buf[i] == 0xffffffff || buf[i] == 0){
if (touch_state[i] == TOUCH_DOWN)
{
DBG("ili2102_ts_work_func:buf[%d]=%d\n",i,buf[i]);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); //Finger Size
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); //Touch Size
input_mt_sync(ts->input_dev);
syn_flag = 1;
touch_state[i] = TOUCH_UP;
}
}
else{
x = ((buf[i] & 0xff) << 8) | ((buf[i] & 0xff00) >> 8);
y = ((buf[i] & 0xff0000) >> 8) | ((buf[i] & 0xff000000) >> 24);
if (ts->swap_xy)
swap(x, y);
if (verify_coord(ts,&x,&y))
goto out;
DBG("buf[%d]=%x X = %d, Y = %d\n", i, buf[i], x, y);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1); //Finger Size
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 5); //Touch Size
input_mt_sync(ts->input_dev);
syn_flag = 1;
touch_state[i] = TOUCH_DOWN;
}
}
if(syn_flag)
input_sync(ts->input_dev);
out:
if (ts->use_irq)
enable_irq(ts->client->irq);
return;
}
static enum hrtimer_restart ili2102_ts_timer_func(struct hrtimer *timer)
{
struct ili2102_ts_data *ts = container_of(timer, struct ili2102_ts_data, timer);
DBG("ili2102_ts_timer_func\n");
queue_work(ili2102_wq, &ts->work);
hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
return HRTIMER_NORESTART;
}
static irqreturn_t ili2102_ts_irq_handler(int irq, void *dev_id)
{
struct ili2102_ts_data *ts = dev_id;
DBG("ili2102_ts_irq_handler=%d,%d\n",ts->client->irq,ts->use_irq);
//if (ts->use_irq)
disable_irq_nosync(ts->client->irq); //disable_irq(ts->client->irq);
queue_work(ili2102_wq, &ts->work);
return IRQ_HANDLED;
}
static int __devinit setup_resetPin(struct i2c_client *client, struct ili2102_ts_data *ts)
{
struct ili2102_platform_data *pdata = client->dev.platform_data;
int err;
ts->gpio_reset = pdata->gpio_reset;
strcpy(ts->resetpin_iomux_name,pdata->resetpin_iomux_name);
ts->resetpin_iomux_mode = pdata->resetpin_iomux_mode;
ts->gpio_reset_active_low = pdata->gpio_reset_active_low;
DBG("%s=%d,%s,%d,%d\n",__FUNCTION__,ts->gpio_reset,ts->resetpin_iomux_name,ts->resetpin_iomux_mode,ts->gpio_reset_active_low);
if (!gpio_is_valid(ts->gpio_reset)) {
dev_err(&client->dev, "no gpio_reset?\n");
return -EINVAL;
}
rk29_mux_api_set(ts->resetpin_iomux_name,ts->resetpin_iomux_mode);
err = gpio_request(ts->gpio_reset, "ili2102_resetPin");
if (err) {
dev_err(&client->dev, "failed to request resetPin GPIO%d\n",
ts->gpio_reset);
return err;
}
gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_LOW:GPIO_HIGH);
err = gpio_direction_output(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_LOW:GPIO_HIGH);
if (err) {
dev_err(&client->dev, "failed to pulldown resetPin GPIO%d\n",
ts->gpio_reset);
gpio_free(ts->gpio_reset);
return err;
}
mdelay(100);
gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
mdelay(100);
return 0;
}
static int __devinit setup_pendown(struct i2c_client *client, struct ili2102_ts_data *ts)
{
int err;
struct ili2102_platform_data *pdata = client->dev.platform_data;
if (!client->irq) {
dev_dbg(&client->dev, "no IRQ?\n");
return -ENODEV;
}
if (!gpio_is_valid(pdata->gpio_pendown)) {
dev_err(&client->dev, "no gpio_pendown?\n");
return -EINVAL;
}
ts->gpio_pendown = pdata->gpio_pendown;
strcpy(ts->pendown_iomux_name,pdata->pendown_iomux_name);
ts->pendown_iomux_mode = pdata->pendown_iomux_mode;
DBG("%s=%d,%s,%d\n",__FUNCTION__,ts->gpio_pendown,ts->pendown_iomux_name,ts->pendown_iomux_mode);
if (!gpio_is_valid(ts->gpio_pendown)) {
dev_err(&client->dev, "no gpio_pendown?\n");
return -EINVAL;
}
rk29_mux_api_set(ts->pendown_iomux_name,ts->pendown_iomux_mode);
err = gpio_request(ts->gpio_pendown, "ili2102_pendown");
if (err) {
dev_err(&client->dev, "failed to request pendown GPIO%d\n",
ts->gpio_pendown);
return err;
}
err = gpio_pull_updown(ts->gpio_pendown, GPIOPullUp);
if (err) {
dev_err(&client->dev, "failed to pullup pendown GPIO%d\n",
ts->gpio_pendown);
gpio_free(ts->gpio_pendown);
return err;
}
return 0;
}
static int ili2102_chip_Init(struct i2c_client *client)
{
uint8_t buf0[6];
int ret = 0;
#if (0)
/* = */
buf0[0] = 0x71;
buf0[1] = 0x00;//30MHz
buf0[2] = 0x01;
buf0[3] = 0x07;
buf0[4] = 0x0D;
buf0[5] = 0x00;
ret = i2c_master_send(client, buf0, 6);
if(ret < 0) {
printk(KERN_ERR "i2c_master_send failed\n");
}
/* = */
buf0[0] = 0x76;
buf0[1] = 0x01;
buf0[2] = 0x1B;
ret = i2c_master_send(client, buf0, 3);
if(ret < 0) {
printk(KERN_ERR "i2c_master_send failed\n");
}
#endif /* (0) */
/* IC internal power on */
buf0[0] = 0x81;
ret = i2c_master_send(client, buf0, 1);
if(ret < 0) {
printk(KERN_ERR "i2c_master_send failed\n");
}
msleep(120);
/* MCU power on */
buf0[0] = 0x35;
buf0[1] = 0x02;
ret = i2c_master_send(client, buf0, 2);
if(ret < 0) {
printk(KERN_ERR "i2c_master_send failed\n");
}
msleep(10);
/* flash power on */
buf0[0] = 0x36;
buf0[1] = 0x01;
ret = i2c_master_send(client, buf0, 2);
if(ret < 0) {
printk(KERN_ERR "i2c_master_send failed\n");
}
msleep(10);
ili2102_test(client);
msleep(10);
/* Start touch panel sensing */
buf0[0] = 0x83;
ret = i2c_master_send(client, buf0, 1);
if(ret < 0) {
printk(KERN_ERR "i2c_master_send failed\n");
}
msleep(120);
return ret;
}
static int ili2102_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct ili2102_ts_data *ts;
struct ili2102_platform_data *pdata = client->dev.platform_data;
int ret = 0;
printk("ili2102 TS probe\n"); //[Step 1]
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
printk(KERN_ERR "ili2102_ts_probe: need I2C_FUNC_I2C\n");
ret = -ENODEV;
goto err_check_functionality_failed;
}
ts = kzalloc(sizeof(*ts), GFP_KERNEL);
if (ts == NULL) {
ret = -ENOMEM;
goto err_alloc_data_failed;
}
INIT_WORK(&ts->work, ili2102_ts_work_func);
ts->client = client;
i2c_set_clientdata(client, ts);
ret = setup_resetPin(client,ts);
if(ret)
{
printk("ili2102 TS setup_resetPin fail\n");
goto err_alloc_data_failed;
}
ret=ili2102_chip_Init(ts->client);
if(ret<0)
{
printk("%s:chips init failed\n",__FUNCTION__);
goto err_resetpin_failed;
}
/* allocate input device */
ts->input_dev = input_allocate_device();
if (ts->input_dev == NULL) {
ret = -ENOMEM;
printk(KERN_ERR "ili2102_ts_probe: Failed to allocate input device\n");
goto err_input_dev_alloc_failed;
}
ts->model = pdata->model ? : 801;
ts->swap_xy = pdata->swap_xy;
ts->x_min = pdata->x_min;
ts->x_max = pdata->x_max;
ts->y_min = pdata->y_min;
ts->y_max = pdata->y_max;
snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&client->dev));
snprintf(ts->name, sizeof(ts->name), "gt%d-touchscreen", ts->model);
ts->input_dev->phys = ts->phys;
ts->input_dev->name = ts->name;
ts->input_dev->dev.parent = &client->dev;
ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_ABS);
//ts->input_dev->absbit[0] =
//BIT(ABS_MT_POSITION_X) | BIT(ABS_MT_POSITION_Y) |
//BIT(ABS_MT_TOUCH_MAJOR) | BIT(ABS_MT_WIDTH_MAJOR); // for android
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
ts->x_min ? : 0,
ts->x_max ? : 480,
0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
ts->y_min ? : 0,
ts->y_max ? : 800,
0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 1, 0, 0); //Finger Size
input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 10, 0, 0); //Touch Size
/* ts->input_dev->name = ts->keypad_info->name; */
ret = input_register_device(ts->input_dev);
if (ret) {
printk(KERN_ERR "ili2102_ts_probe: Unable to register %s input device\n", ts->input_dev->name);
goto err_input_register_device_failed;
}
client->irq = gpio_to_irq(client->irq);
if (client->irq) {
ret = setup_pendown(client,ts);
if(ret)
{
printk("ili2102 TS setup_pendown fail\n");
goto err_input_register_device_failed;
}
ret = request_irq(client->irq, ili2102_ts_irq_handler, IRQF_DISABLED | IRQF_TRIGGER_LOW, client->name, ts);
if (ret == 0) {
DBG("ili2102 TS register ISR (irq=%d)\n", client->irq);
ts->use_irq = 1;
}
else
dev_err(&client->dev, "request_irq failed\n");
}
if (!ts->use_irq) {
hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
ts->timer.function = ili2102_ts_timer_func;
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
}
#ifdef CONFIG_HAS_EARLYSUSPEND
ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
ts->early_suspend.suspend = ili2102_ts_early_suspend;
ts->early_suspend.resume = ili2102_ts_late_resume;
register_early_suspend(&ts->early_suspend);
#endif
printk(KERN_INFO "ili2102_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
return 0;
err_input_register_device_failed:
input_free_device(ts->input_dev);
err_resetpin_failed:
gpio_free(ts->gpio_reset);
err_input_dev_alloc_failed:
kfree(ts);
err_alloc_data_failed:
err_check_functionality_failed:
return ret;
}
static int ili2102_ts_remove(struct i2c_client *client)
{
struct ili2102_ts_data *ts = i2c_get_clientdata(client);
unregister_early_suspend(&ts->early_suspend);
if (ts->use_irq)
free_irq(client->irq, ts);
else
hrtimer_cancel(&ts->timer);
input_unregister_device(ts->input_dev);
kfree(ts);
return 0;
}
static int ili2102_ts_suspend(struct i2c_client *client, pm_message_t mesg)
{
int ret;
struct ili2102_ts_data *ts = i2c_get_clientdata(client);
printk("ili2102 TS Suspend\n");
if (ts->use_irq)
disable_irq(client->irq);
else
hrtimer_cancel(&ts->timer);
ret = cancel_work_sync(&ts->work);
if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */
enable_irq(client->irq);
// TODO do suspend
return 0;
}
static int ili2102_ts_resume(struct i2c_client *client)
{
struct ili2102_ts_data *ts = i2c_get_clientdata(client);
ili2102_init_panel(ts);
//TODO do resume
printk("ili2102 TS Resume\n");
if (ts->use_irq) {
printk("enabling IRQ %d\n", client->irq);
enable_irq(client->irq);
}
else
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
return 0;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void ili2102_ts_early_suspend(struct early_suspend *h)
{
struct ili2102_ts_data *ts;
ts = container_of(h, struct ili2102_ts_data, early_suspend);
ili2102_ts_suspend(ts->client, PMSG_SUSPEND);
}
static void ili2102_ts_late_resume(struct early_suspend *h)
{
struct ili2102_ts_data *ts;
ts = container_of(h, struct ili2102_ts_data, early_suspend);
ili2102_ts_resume(ts->client);
}
#endif
#define ILI2102_TS_NAME "ili2102_ts"
static const struct i2c_device_id ili2102_ts_id[] = {
{ ILI2102_TS_NAME, 0 },
{ }
};
static struct i2c_driver ili2102_ts_driver = {
.probe = ili2102_ts_probe,
.remove = ili2102_ts_remove,
#ifndef CONFIG_HAS_EARLYSUSPEND
.suspend = ili2102_ts_suspend,
.resume = ili2102_ts_resume,
#endif
.id_table = ili2102_ts_id,
.driver = {
.name = ILI2102_TS_NAME,
},
};
static int __devinit ili2102_ts_init(void)
{
printk("ili2102 TS init\n"); //[Step 0]
ili2102_wq = create_singlethread_workqueue("ili2102_wq");
if (!ili2102_wq)
return -ENOMEM;
return i2c_add_driver(&ili2102_ts_driver);
}
static void __exit ili2102_ts_exit(void)
{
printk("ili2102 TS exit\n");
i2c_del_driver(&ili2102_ts_driver);
if (ili2102_wq)
destroy_workqueue(ili2102_wq);
}
module_init(ili2102_ts_init);
module_exit(ili2102_ts_exit);
MODULE_DESCRIPTION("ili2102 Touchscreen Driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,42 @@
/*
* drivers/input/touchscreen/xpt2046_cbn_ts.h
*
* Copyright (C) 2010 ROCKCHIP, Inc.
*
* 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.
*/
#ifndef __DRIVERS_TOUCHSCREEN_ILI2102_TS_H
#define __DRIVERS_TOUCHSCREEN_ILI2102_TS_H
#define IOMUX_NAME_SIZE 40
enum touchstate {
TOUCH_UP = 0, TOUCH_DOWN = 1,
};
struct ili2102_platform_data {
u16 model; /* 8520. */
bool swap_xy; /* swap x and y axes */
u16 x_min, x_max;
u16 y_min, y_max;
int gpio_reset;
int gpio_reset_active_low;
int gpio_pendown; /* the GPIO used to decide the pendown*/
char pendown_iomux_name[IOMUX_NAME_SIZE];
char resetpin_iomux_name[IOMUX_NAME_SIZE];
int pendown_iomux_mode;
int resetpin_iomux_mode;
int (*get_pendown_state)(void);
};
#endif