touchscreen:add calibration for touchscreen ili2102 to support it's APK

This commit is contained in:
root
2011-05-04 23:29:22 +08:00
parent 8524310483
commit d51debf3e1
2 changed files with 444 additions and 29 deletions

View File

@@ -10,6 +10,11 @@
#include <linux/types.h>
#include <mach/iomux.h>
#include <linux/platform_device.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/irq.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include "ili2102_ts.h"
@@ -42,6 +47,7 @@ struct ili2102_ts_data {
char resetpin_iomux_name[IOMUX_NAME_SIZE];
char phys[32];
char name[32];
int valid_i2c_register;
struct i2c_client *client;
struct input_dev *input_dev;
struct hrtimer timer;
@@ -55,6 +61,216 @@ static void ili2102_ts_early_suspend(struct early_suspend *h);
static void ili2102_ts_late_resume(struct early_suspend *h);
#endif
#define ILI2102_TS_APK_SUPPORT 1
#if ILI2102_TS_APK_SUPPORT
// device data
struct dev_data {
// device number
dev_t devno;
// character device
struct cdev cdev;
// class device
struct class *class;
};
// global variables
static struct ili2102_ts_data *g_ts;
static struct dev_data g_dev;
// definitions
#define ILITEK_I2C_RETRY_COUNT 3
#define ILITEK_FILE_DRIVER_NAME "ilitek_file"
#define ILITEK_DEBUG_LEVEL KERN_INFO
#define ILITEK_ERROR_LEVEL KERN_ALERT
// i2c command for ilitek touch screen
#define ILITEK_TP_CMD_READ_DATA 0x10
#define ILITEK_TP_CMD_READ_SUB_DATA 0x11
#define ILITEK_TP_CMD_GET_RESOLUTION 0x20
#define ILITEK_TP_CMD_GET_FIRMWARE_VERSION 0x40
#define ILITEK_TP_CMD_GET_PROTOCOL_VERSION 0x42
#define ILITEK_TP_CMD_CALIBRATION 0xCC
#define ILITEK_TP_CMD_ERASE_BACKGROUND 0xCE
// define the application command
#define ILITEK_IOCTL_BASE 100
#define ILITEK_IOCTL_I2C_WRITE_DATA _IOWR(ILITEK_IOCTL_BASE, 0, unsigned char*)
#define ILITEK_IOCTL_I2C_WRITE_LENGTH _IOWR(ILITEK_IOCTL_BASE, 1, int)
#define ILITEK_IOCTL_I2C_READ_DATA _IOWR(ILITEK_IOCTL_BASE, 2, unsigned char*)
#define ILITEK_IOCTL_I2C_READ_LENGTH _IOWR(ILITEK_IOCTL_BASE, 3, int)
#define ILITEK_IOCTL_USB_WRITE_DATA _IOWR(ILITEK_IOCTL_BASE, 4, unsigned char*)
#define ILITEK_IOCTL_USB_WRITE_LENGTH _IOWR(ILITEK_IOCTL_BASE, 5, int)
#define ILITEK_IOCTL_USB_READ_DATA _IOWR(ILITEK_IOCTL_BASE, 6, unsigned char*)
#define ILITEK_IOCTL_USB_READ_LENGTH _IOWR(ILITEK_IOCTL_BASE, 7, int)
#define ILITEK_IOCTL_I2C_UPDATE_RESOLUTION _IOWR(ILITEK_IOCTL_BASE, 8, int)
#define ILITEK_IOCTL_USB_UPDATE_RESOLUTION _IOWR(ILITEK_IOCTL_BASE, 9, int)
#define ILITEK_IOCTL_I2C_SET_ADDRESS _IOWR(ILITEK_IOCTL_BASE, 10, int)
#define ILITEK_IOCTL_I2C_UPDATE _IOWR(ILITEK_IOCTL_BASE, 11, int)
#define ILITEK_IOCTL_STOP_READ_DATA _IOWR(ILITEK_IOCTL_BASE, 12, int)
#define ILITEK_IOCTL_START_READ_DATA _IOWR(ILITEK_IOCTL_BASE, 13, int)
static int ilitek_file_open(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t ilitek_file_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
int ret;
unsigned char buffer[128]={0};
struct i2c_msg msg[2];
msg[0].addr = g_ts->client->addr;
msg[0].flags = g_ts->client->flags;
msg[0].len = count;
msg[0].buf = buffer;
msg[0].scl_rate = 400*1000;
msg[0].udelay = 80;
printk("%s:count=0x%x\n",__FUNCTION__,count);
// before sending data to touch device, we need to check whether the device is working or not
if(g_ts->valid_i2c_register == 0){
printk(ILITEK_ERROR_LEVEL "%s, i2c device driver doesn't be registered\n", __func__);
return -1;
}
// check the buffer size whether it exceeds the local buffer size or not
if(count > 128){
printk(ILITEK_ERROR_LEVEL "%s, buffer exceed 128 bytes\n", __func__);
return -1;
}
// copy data from user space
ret = copy_from_user(buffer, buf, count-1);
if(ret < 0){
printk(ILITEK_ERROR_LEVEL "%s, copy data from user space, failed", __func__);
return -1;
}
// parsing command
if(strcmp(buffer, "calibrate") == 0){
buffer[0] = ILITEK_TP_CMD_ERASE_BACKGROUND;
msg[0].len = 1;
ret = i2c_transfer(g_ts->client->adapter, msg, 1);
if(ret < 0){
printk(ILITEK_DEBUG_LEVEL "%s, i2c erase background, failed\n", __func__);
}
else{
printk(ILITEK_DEBUG_LEVEL "%s, i2c erase background, success\n", __func__);
}
buffer[0] = ILITEK_TP_CMD_CALIBRATION;
msg[0].len = 1;
msleep(2000);
ret = i2c_transfer(g_ts->client->adapter, msg, 1);
if(ret < 0){
printk(ILITEK_DEBUG_LEVEL "%s, i2c calibration, failed\n", __func__);
}
else{
printk(ILITEK_DEBUG_LEVEL "%s, i2c calibration, success\n", __func__);
}
msleep(1000);
return count;
}
return -1;
}
static int ilitek_file_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
static unsigned char buffer[64]={0};
static int len=0;
int ret;
struct i2c_msg msg[2];
msg[0].addr = g_ts->client->addr;
msg[0].flags = g_ts->client->flags;
msg[0].len = len;
msg[0].buf = buffer;
msg[0].scl_rate = 400*1000;
msg[0].udelay = 80;
// parsing ioctl command
switch(cmd){
case ILITEK_IOCTL_I2C_WRITE_DATA:
ret = copy_from_user(buffer, (unsigned char*)arg, len);
if(ret < 0){
printk(ILITEK_ERROR_LEVEL "%s, copy data from user space, failed\n", __func__);
return -1;
}
ret = i2c_transfer(g_ts->client->adapter, msg, 1);
if(ret < 0){
printk(ILITEK_ERROR_LEVEL "%s, i2c write, failed\n", __func__);
return -1;
}
break;
case ILITEK_IOCTL_I2C_READ_DATA:
msg[0].addr = g_ts->client->addr;
msg[0].flags = g_ts->client->flags | I2C_M_RD;
msg[0].len = len;
msg[0].buf = buffer;
msg[0].scl_rate = 400*1000;
msg[0].udelay = 80;
ret = i2c_transfer(g_ts->client->adapter, msg, 1);
if(ret < 0){
printk(ILITEK_ERROR_LEVEL "%s, i2c read, failed\n", __func__);
return -1;
}
ret = copy_to_user((unsigned char*)arg, buffer, len);
if(ret < 0){
printk(ILITEK_ERROR_LEVEL "%s, copy data to user space, failed\n", __func__);
return -1;
}
break;
case ILITEK_IOCTL_I2C_WRITE_LENGTH:
case ILITEK_IOCTL_I2C_READ_LENGTH:
len = arg;
break;
case ILITEK_IOCTL_I2C_UPDATE_RESOLUTION:
case ILITEK_IOCTL_I2C_SET_ADDRESS:
case ILITEK_IOCTL_I2C_UPDATE:
break;
case ILITEK_IOCTL_START_READ_DATA:
//g_ts.stop_polling = 0;
break;
case ILITEK_IOCTL_STOP_READ_DATA:
//g_ts.stop_polling = 1;
break;
default:
return -1;
}
printk("%s:cmd=0x%x\n",__FUNCTION__,cmd);
return 0;
}
static ssize_t ilitek_file_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
return 0;
}
static int ilitek_file_close(struct inode *inode, struct file *filp)
{
return 0;
}
// declare file operations
struct file_operations ilitek_fops = {
.ioctl = ilitek_file_ioctl,
.read = ilitek_file_read,
.write = ilitek_file_write,
.open = ilitek_file_open,
.release = ilitek_file_close,
};
#endif
static int verify_coord(struct ili2102_ts_data *ts,unsigned int *x,unsigned int *y)
{
@@ -102,7 +318,7 @@ static void ili2102_ts_work_func(struct work_struct *work)
msg[1].addr = ts->client->addr;
msg[1].flags = ts->client->flags | I2C_M_RD;
msg[1].len = 9;
msg[1].buf = buf;//msg[1].buf = (u8*)&buf[0];
msg[1].buf = buf;
msg[1].scl_rate = 400*1000;
msg[1].udelay = 80;
@@ -218,12 +434,12 @@ static int __devinit setup_resetPin(struct i2c_client *client, struct ili2102_ts
ts->gpio_reset);
return err;
}
gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
gpio_direction_output(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
mdelay(100);
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",
dev_err(&client->dev, "failed to set resetPin GPIO%d\n",
ts->gpio_reset);
gpio_free(ts->gpio_reset);
return err;
@@ -272,7 +488,7 @@ static int __devinit setup_pendown(struct i2c_client *client, struct ili2102_ts_
return err;
}
err = gpio_pull_updown(ts->gpio_pendown, GPIOPullUp);
err = gpio_pull_updown(ts->gpio_pendown, PullDisable);
if (err) {
dev_err(&client->dev, "failed to pullup pendown GPIO%d\n",
ts->gpio_pendown);
@@ -295,23 +511,30 @@ static int ili2102_chip_Init(struct i2c_client *client)
msg[0].flags = client->flags;
msg[0].len = 1;
msg[0].buf = &start_reg;
msg[0].scl_rate = 200*1000;
msg[0].udelay = 500;
msg[0].scl_rate = 400*1000;
msg[0].udelay = 200;
msg[1].addr = client->addr;
msg[1].flags = client->flags |I2C_M_RD;
msg[1].len = 6;
msg[1].buf = (u8*)&buf[0];
msg[1].scl_rate = 200*1000;
msg[1].udelay = 500;
ret = i2c_transfer(client->adapter, msg, 1);
if (ret < 0) {
printk("%s:err\n",__FUNCTION__);
}
mdelay(5);//tp need delay
msg[0].addr = client->addr;
msg[0].flags = client->flags |I2C_M_RD;
msg[0].len = 6;
msg[0].buf = (u8*)&buf[0];
msg[0].scl_rate = 400*1000;
msg[0].udelay = 200;
ret = i2c_transfer(client->adapter, msg, 2);
ret = i2c_transfer(client->adapter, msg, 1);
if (ret < 0) {
printk("%s:err\n",__FUNCTION__);
}
printk("%s:b[0]=0x%x,b[1]=0x%x,b[2]=0x%x,b[3]=0x%x,b[4]=0x%x,b[5]=0x%x\n",
__FUNCTION__,buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
printk("%s:max_x=%d,max_y=%d,b[4]=0x%x,b[5]=0x%x\n",
__FUNCTION__,buf[0]|(buf[1]<<8),buf[2]|(buf[3]<<8),buf[4],buf[5]);
/*get firmware version:3bytes */
start_reg = 0x40;
@@ -319,24 +542,31 @@ static int ili2102_chip_Init(struct i2c_client *client)
msg[0].flags = client->flags;
msg[0].len = 1;
msg[0].buf = &start_reg;
msg[0].scl_rate = 200*1000;
msg[0].udelay = 500;
msg[0].scl_rate = 400*1000;
msg[0].udelay = 200;
msg[1].addr = client->addr;
msg[1].flags = client->flags | I2C_M_RD;
msg[1].len = 3;
msg[1].buf = (u8*)&buf[0];
msg[1].scl_rate =200*1000;
msg[1].udelay = 500;
ret = i2c_transfer(client->adapter, msg, 1);
if (ret < 0) {
printk("%s:err\n",__FUNCTION__);
}
mdelay(5);//tp need delay
msg[0].addr = client->addr;
msg[0].flags = client->flags | I2C_M_RD;
msg[0].len = 3;
msg[0].buf = (u8*)&buf[0];
msg[0].scl_rate =400*1000;
msg[0].udelay = 200;
ret = i2c_transfer(client->adapter, msg, 2);
ret = i2c_transfer(client->adapter, msg, 1);
if (ret < 0) {
printk("%s:err\n",__FUNCTION__);
}
printk("%s:Ver %d.%d.%d\n",__FUNCTION__,buf[0],buf[1],buf[2]);
return 0;
return ret;
}
@@ -405,6 +635,7 @@ static int ili2102_ts_probe(struct i2c_client *client, const struct i2c_device_i
ts->input_dev->name = ts->name;
ts->input_dev->dev.parent = &client->dev;
ts->pendown = 0;
ts->valid_i2c_register = 1;
ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_ABS);
//ts->input_dev->absbit[0] =
@@ -444,7 +675,36 @@ static int ili2102_ts_probe(struct i2c_client *client, const struct i2c_device_i
}
else
dev_err(&client->dev, "request_irq failed\n");
}
#if ILI2102_TS_APK_SUPPORT
// initialize global variable
g_ts = ts;
memset(&g_dev, 0, sizeof(struct dev_data));
// allocate character device driver buffer
ret = alloc_chrdev_region(&g_dev.devno, 0, 1, ILITEK_FILE_DRIVER_NAME);
if(ret){
printk(ILITEK_ERROR_LEVEL "%s, can't allocate chrdev\n", __func__);
return ret;
}
printk(ILITEK_DEBUG_LEVEL "%s, register chrdev(%d, %d)\n", __func__, MAJOR(g_dev.devno), MINOR(g_dev.devno));
// initialize character device driver
cdev_init(&g_dev.cdev, &ilitek_fops);
g_dev.cdev.owner = THIS_MODULE;
ret = cdev_add(&g_dev.cdev, g_dev.devno, 1);
if(ret < 0){
printk(ILITEK_ERROR_LEVEL "%s, add character device error, ret %d\n", __func__, ret);
return ret;
}
g_dev.class = class_create(THIS_MODULE, ILITEK_FILE_DRIVER_NAME);
if(IS_ERR(g_dev.class)){
printk(ILITEK_ERROR_LEVEL "%s, create class, error\n", __func__);
return ret;
}
device_create(g_dev.class, NULL, g_dev.devno, NULL, "ilitek_ctrl");
#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
@@ -480,6 +740,15 @@ static int ili2102_ts_remove(struct i2c_client *client)
if (ts->ts_wq)
cancel_delayed_work_sync(&ts->work);
kfree(ts);
#if ILI2102_TS_APK_SUPPORT
// delete character device driver
cdev_del(&g_dev.cdev);
unregister_chrdev_region(g_dev.devno, 1);
device_destroy(g_dev.class, g_dev.devno);
class_destroy(g_dev.class);
#endif
return 0;
}

View File

@@ -1401,6 +1401,151 @@ else if(OUT_FACE == OUT_P666)
}
void resume_nt35510(void)
{
WriteCommand(0X1100);
mdelay(120);
WriteCommand(0X1300);
WriteCommand(0XF000);
WriteParameter(0x55);
WriteCommand(0XF001);
WriteParameter(0xAA);
WriteCommand(0XF002);
WriteParameter(0x52);
WriteCommand(0XF003);
WriteParameter(0x08);
WriteCommand(0XF004);
WriteParameter(0x01);
/**************/
WriteCommand(0XBA00);
WriteParameter(0x14);
WriteCommand(0XBA01);
WriteParameter(0x14);
WriteCommand(0XBA02);
WriteParameter(0x14);
WriteCommand(0XBF00);
WriteParameter(0x01);
WriteCommand(0XB300);
WriteParameter(0x07);
WriteCommand(0XB301);
WriteParameter(0x07);
WriteCommand(0XB302);
WriteParameter(0x07);
WriteCommand(0XB900);
WriteParameter(0x25);
WriteCommand(0XB901);
WriteParameter(0x25);
WriteCommand(0XB902);
WriteParameter(0x25);
WriteCommand(0XBC01);
WriteParameter(0xA0);
WriteCommand(0XBC02);
WriteParameter(0x00);
WriteCommand(0XBD01);
WriteParameter(0xA0);
WriteCommand(0XBD02);
WriteParameter(0x00);
WriteCommand(0XF000);
WriteParameter(0x55);
WriteCommand(0XF001);
WriteParameter(0xAA);
WriteCommand(0XF002);
WriteParameter(0x52);
WriteCommand(0XF003);
WriteParameter(0x08);
WriteCommand(0XF004);
WriteParameter(0x00);
WriteCommand(0XB100);
WriteParameter(0xCC);
WriteCommand(0XBC00);
WriteParameter(0x05);
WriteCommand(0XBC01);
WriteParameter(0x05);
WriteCommand(0XBC02);
WriteParameter(0x05);
WriteCommand(0XBD02);
WriteParameter(0x07);
WriteCommand(0XBD03);
WriteParameter(0x31);
WriteCommand(0XBE02);
WriteParameter(0x07);
WriteCommand(0XBE03);
WriteParameter(0x31);
WriteCommand(0XBF02);
WriteParameter(0x07);
WriteCommand(0XBF03);
WriteParameter(0x31);
WriteCommand(0XFF00);
WriteParameter(0xAA);
WriteCommand(0XFF01);
WriteParameter(0x55);
WriteCommand(0XFF02);
WriteParameter(0x25);
WriteCommand(0XFF03);
WriteParameter(0x01);
WriteCommand(0X3500);
WriteParameter(0x00);
WriteCommand(0X3a00);
if(OUT_FACE == OUT_P888)
WriteParameter(0x70); //24bit
else if(OUT_FACE == OUT_P666)
WriteParameter(0x60);//18bit
WriteCommand(0X3600);
WriteParameter(0x00);//R<->B
WriteCommand(0X2000); //
WriteCommand(0X1100);
mdelay(120);
WriteCommand(0X2900);
mdelay(100);
WriteCommand(0X2C00);
}
int init(void)
{
@@ -1438,11 +1583,12 @@ int standby(u8 enable) //***enable =1 means suspend, 0 means resume
mdelay(100);
WriteCommand(0X1000);
} else {
WriteCommand(0X1100);
mdelay(120);
WriteCommand(0X2900);
mdelay(100);
//WriteCommand(0X1100);
//mdelay(120);
//WriteCommand(0X2900);
//mdelay(100);
//set_backlight(255);
resume_nt35510();//may be fail to wake up LCD some time,so change to init lcd again
}
if(gLcd_info)