cyb4_linux/drivers/i2c/chips/qisda_iic.c

828 lines
23 KiB
C

/*
eeprom.c - Part of lm_sensors, Linux kernel modules for hardware
monitoring
Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and
Philip Edelbrock <phil@netroedge.com>
Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
Copyright (C) 2003 IBM Corp.
2004-01-16 Jean Delvare <khali@linux-fr.org>
Divide the eeprom in 32-byte (arbitrary) slices. This significantly
speeds sensors up, as well as various scripts using the eeprom
module.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
#include<linux/delay.h>
#include "../../input/touchscreen/s3c_ts_iic.h"
//Ivan 20090608 Ivan
#define ROTATE_NAGATIVE_90
//Ivan 20090608 Ivan
//Tony test
//#define QISDA_TEST_GPIO_PROBE
#include <asm/io.h>
/*kit.mod 20090811*/
#include "../../video/epaper.h"
/*kit.end*/
/* Addresses to scan */
#define QISDA_IIC_ID 0xB8
#define DELAY_TIME_IIC_READ 8//1//8
//Aaron, add for the feature of buffered touch data
#define USE_BUFFERED_TOUCH_DATA
#ifdef USE_BUFFERED_TOUCH_DATA
//Aaron, prevent from read wrong data in touch panel of old firmware version
static int IsBufferedDataFwVersion;
#endif
#ifdef CONFIG_TOUCH_PM
//Aaron
#define AXIS_DATA(axis) \
printk(KERN_INFO"AA: show_%s():", #axis); \
if (axis < 0) \
return snprintf(buf, PAGE_SIZE, "%s\n", "read data error"); \
else { \
axis = axis; \
return snprintf(buf, PAGE_SIZE, "0x%x(%d)\n", axis, axis); \
}
#define COORD_DATA_BLOCK_NUM 8
#define X1_LSB 0x00
#define X1_MSB 0x01
#define Y1_LSB 0x02
#define Y1_MSB 0x03
#define X2_LSB 0x04
#define X2_MSB 0x05
#define Y2_LSB 0x06
#define Y2_MSB 0x07
#define X_SENSITIVITY 0x6F
#define Y_SENSITIVITY 0x70
#define INT_SETTING 0x71
#define INT_WIDTH 0x72
#define POWERMODE 0x73
#define CALIBRATION 0x78
#endif
static struct i2c_driver qisda_iic_driver;
static unsigned short normal_i2c[] = { QISDA_IIC_ID>>1 , I2C_CLIENT_END };
I2C_CLIENT_INSMOD_1(qisda_iic);
typedef struct qisda_iic_data{
struct i2c_client client;
struct mutex update_lock;
u8 valid; /* bitfield, bit!=0 if slice is valid */
unsigned long last_updated[8]; /* In jiffies, 8 slices */
};
typedef struct {
unsigned char subaddr;
unsigned char value;
}qisda_iic_t;
qisda_iic_t qisda_iics_regs_mirror[2]=
{
{0x40,0xff},
{0x41,0xff},
};
static int qisda_iic_attach_adapter(struct i2c_adapter *adapter);
static int qisda_iic_detect(struct i2c_adapter *adapter, int address, int kind);
static int qisda_iic_detach_client(struct i2c_client *client);
unsigned char qisda_iic_read(struct i2c_client *client, unsigned char subaddr);
static int qisda_iic_write(struct i2c_client *client, unsigned char subaddr, unsigned char val);
static int qisda_iic_command(struct i2c_client *client, unsigned int cmd, void *arg);
//Tony test
#ifdef QISDA_TEST_GPIO_PROBE
static void __iomem *g_pGPIOReg_GPFCON;
#endif
/* This is the driver that will be inserted */
static struct i2c_driver qisda_iic_driver = {
.driver = {
.name = "qisda_iic",
},
.id = I2C_DRIVERID_QISDA_AUO,
.attach_adapter = qisda_iic_attach_adapter,
.detach_client = qisda_iic_detach_client,
.command =qisda_iic_command
};
#define TRUE 1
#define FALSE 0
//Tony 090615 start
#define NEW_TCOM_BOARD
//Tony 090615 end
#ifdef CONFIG_TOUCH_PM
//Aaron
static ssize_t show_x1(struct device *device, struct device_attribute *attr,
char *buf)
{
#if 1
int x1;
// int x1_lsb, x1_msb;
struct qisda_iic_data *data = dev_get_drvdata(device);
x1 = i2c_smbus_read_word_data(&data->client, X1_LSB);
AXIS_DATA(x1); /* Macro */
// x1_lsb = i2c_smbus_read_byte_data(&data->client, X1_LSB);
// x1_msb = i2c_smbus_read_byte_data(&data->client, X1_MSB);
// printk(KERN_INFO"AA: show_x1():");
// if (x1_lsb < 0 || x1_msb < 0)
// return snprintf(buf, PAGE_SIZE, "%s\n", "read data error");
// else {
// x1 = (x1_lsb & 0xff) | (x1_msb << 8);
// return snprintf(buf, PAGE_SIZE, "0x%x(%d)\n", x1, x1);
// }
#else
struct qisda_iic_data *data = dev_get_drvdata(device);
u8 coordinate[COORD_DATA_BLOCK_NUM] = {0};
int ret = 0;
int x1, y1, x2, y2;
ret = i2c_smbus_read_i2c_block_data(&data->client, X1_LSB, COORD_DATA_BLOCK_NUM, coordinate);
if (ret != COORD_DATA_BLOCK_NUM)
return snprintf(buf, PAGE_SIZE, "%s\n", "read data error(number not match)");
x1 = *(coordinate ) | (*(coordinate + 1) << 8);
y1 = *(coordinate + 2) | (*(coordinate + 3) << 8);
x2 = *(coordinate + 4) | (*(coordinate + 5) << 8);
y2 = *(coordinate + 6) | (*(coordinate + 7) << 8);
return snprintf(buf, PAGE_SIZE, "(%d,%d)(%d,%d)\n", x1, y1, x2, y2);
#endif
}
static DEVICE_ATTR(x1, S_IRUGO, show_x1, NULL);
static ssize_t show_y1(struct device *device, struct device_attribute *attr,
char *buf)
{
int y1;
struct qisda_iic_data *data = dev_get_drvdata(device);
y1 = i2c_smbus_read_word_data(&data->client, Y1_LSB);
AXIS_DATA(y1); /* Macro */
/* printk(KERN_ERR"AA: show_y1(): y1_lsb=0x%x, y1_msb=0x%x \n", y1_lsb, y1_msb);
if (y1_lsb < 0 || y1_msb < 0)
return snprintf(buf, PAGE_SIZE, "%s\n", "read x1 error");
else {
y1 = (y1_lsb & 0xff) | ((y1_msb & 0x3) << 8);
return snprintf(buf, PAGE_SIZE, "0x%x(%d)\n", x1, x1);
}
*/
//return snprintf(buf, PAGE_SIZE, "0x%x\n", );
}
static DEVICE_ATTR(y1, S_IRUGO, show_y1, NULL);
static ssize_t show_x2(struct device *device, struct device_attribute *attr,
char *buf)
{
int x2;
struct qisda_iic_data *data = dev_get_drvdata(device);
#if 0
x2 = i2c_smbus_read_word_data(&data->client, X2_LSB);
#else
x2 = i2c_smbus_read_word_data(&data->client, 0xC0);
#endif
AXIS_DATA(x2); /* Macro */
}
static DEVICE_ATTR(x2, S_IRUGO, show_x2, NULL);
static ssize_t show_y2(struct device *device, struct device_attribute *attr,
char *buf)
{
int y2;
struct qisda_iic_data *data = dev_get_drvdata(device);
#if 0
y2 = i2c_smbus_read_word_data(&data->client, Y2_LSB);
#else
y2 = i2c_smbus_read_byte_data(&data->client, 0x77);
#endif
AXIS_DATA(y2); /* Macro */
}
static DEVICE_ATTR(y2, S_IRUGO, show_y2, NULL);
static ssize_t show_x_sensitivity(struct device *device, struct device_attribute *attr,
char *buf)
{
struct qisda_iic_data *data = dev_get_drvdata(device);
int value;
value = i2c_smbus_read_byte_data(&data->client, X_SENSITIVITY);
if (value < 0 || value > 255)
return snprintf(buf, PAGE_SIZE, "0x%x(error data)\n", value);
else
return snprintf(buf, PAGE_SIZE, "0x%x\n", value);
}
static ssize_t store_x_sensitivity(struct device *device,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct qisda_iic_data *data = dev_get_drvdata(device);
int value = 0;
sscanf(buf, "%x", &value);
/* check whether data is correct */
if (value < 0 || value > 255)
return -EINVAL;
if (i2c_smbus_write_byte_data(&data->client, X_SENSITIVITY, value) < 0)
return -EIO;
return count;
}
static DEVICE_ATTR(x_sensitivity, S_IWUSR | S_IRUGO, show_x_sensitivity, store_x_sensitivity);
static ssize_t show_y_sensitivity(struct device *device, struct device_attribute *attr,
char *buf)
{
struct qisda_iic_data *data = dev_get_drvdata(device);
int value;
value = i2c_smbus_read_byte_data(&data->client, Y_SENSITIVITY);
if (value < 0 || value > 255)
return snprintf(buf, PAGE_SIZE, "0x%x(error)\n", value);
else
return snprintf(buf, PAGE_SIZE, "0x%x\n", value);
}
static ssize_t store_y_sensitivity(struct device *device,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct qisda_iic_data *data = dev_get_drvdata(device);
int value = 0;
sscanf(buf, "%x", &value);
/* check whether data is correct */
if (value < 0 || value > 255)
return -EINVAL;
if (i2c_smbus_write_byte_data(&data->client, Y_SENSITIVITY, value) < 0)
return -EIO;
return count;
}
static DEVICE_ATTR(y_sensitivity, S_IWUSR | S_IRUGO, show_y_sensitivity, store_y_sensitivity);
static ssize_t show_int_setting(struct device *device, struct device_attribute *attr,
char *buf)
{
struct qisda_iic_data *data = dev_get_drvdata(device);
return snprintf(buf, PAGE_SIZE, "0x%x\n", i2c_smbus_read_byte_data(&data->client, INT_SETTING));
}
static ssize_t store_int_setting(struct device *device,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct qisda_iic_data *data = dev_get_drvdata(device);
int setting_data = 0;
sscanf(buf, "%x", &setting_data);
/* check whether data is correct */
if (setting_data < 0 || setting_data > 0xf)
return -EINVAL;
if (i2c_smbus_write_byte_data(&data->client, INT_SETTING, setting_data) < 0)
return -EIO;
return count;
}
static DEVICE_ATTR(int_setting, S_IWUSR | S_IRUGO, show_int_setting, store_int_setting);
static ssize_t show_int_width(struct device *device, struct device_attribute *attr,
char *buf)
{
struct qisda_iic_data *data = dev_get_drvdata(device);
int value;
value = i2c_smbus_read_byte_data(&data->client, INT_WIDTH);
if (value < 0 || value > 255)
return snprintf(buf, PAGE_SIZE, "0x%x(error)\n", value);
else
return snprintf(buf, PAGE_SIZE, "0x%x\n", value);
}
static ssize_t store_int_width(struct device *device,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct qisda_iic_data *data = dev_get_drvdata(device);
int value = 0;
sscanf(buf, "%x", &value);
/* check whether data is correct */
if (value < 0 || value > 255)
return -EINVAL;
if (i2c_smbus_write_byte_data(&data->client, INT_WIDTH, value) < 0)
return -EIO;
return count;
}
static DEVICE_ATTR(int_width, S_IWUSR | S_IRUGO, show_int_width, store_int_width);
static ssize_t show_powermode(struct device *device, struct device_attribute *attr,
char *buf)
{
struct qisda_iic_data *data = dev_get_drvdata(device);
int value;
value = i2c_smbus_read_byte_data(&data->client, POWERMODE);
if (value < 0 || value & 0x08)
return snprintf(buf, PAGE_SIZE, "0x%x(error)\n", value);
else
return snprintf(buf, PAGE_SIZE, "0x%x\n", value);
}
static ssize_t store_powermode(struct device *device,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct qisda_iic_data *data = dev_get_drvdata(device);
int value = 0;
sscanf(buf, "%x", &value);
/* check whether data is correct */
if ((value < 0) || (value > (0xff -0x08)) || (value & 0x08))
return -EINVAL;
if (i2c_smbus_write_byte_data(&data->client, POWERMODE, value) < 0)
return -EIO;
return count;
}
static DEVICE_ATTR(powermode, S_IWUSR | S_IRUGO, show_powermode, store_powermode);
//TODO: add for calibration register.
static ssize_t show_calibration(struct device *device, struct device_attribute *attr,
char *buf)
{
struct qisda_iic_data *data = dev_get_drvdata(device);
int value;
value = i2c_smbus_read_byte_data(&data->client, CALIBRATION);
if (value < 0)
return snprintf(buf, PAGE_SIZE, "0x%x(error)\n", value);
else
return snprintf(buf, PAGE_SIZE, "0x%x\n", value);
}
static ssize_t store_calibration(struct device *device,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct qisda_iic_data *data = dev_get_drvdata(device);
int value = 0;
//int value2 = -1;
sscanf(buf, "%x", &value);
/* check whether data is correct */
if ((value < 0) || (value & (0xff - 0x03)))
return -EINVAL;
if (i2c_smbus_write_byte_data(&data->client, CALIBRATION, value) < 0)
return -EIO;
return count;
}
static DEVICE_ATTR(calibration, S_IWUSR | S_IRUGO, show_calibration, store_calibration);
static struct attribute *multitouch_attributes[] = {
&dev_attr_x1.attr,
&dev_attr_y1.attr,
&dev_attr_x2.attr,
&dev_attr_y2.attr,
&dev_attr_x_sensitivity.attr,
&dev_attr_y_sensitivity.attr,
&dev_attr_int_setting.attr,
&dev_attr_int_width.attr,
&dev_attr_powermode.attr,
&dev_attr_calibration.attr,
NULL
};
static const struct attribute_group multitouch_group = {
.attrs = multitouch_attributes,
};
#endif
unsigned char qisda_iic_read(struct i2c_client *client, unsigned char subaddr)
{
int ret;
unsigned char buf[1];
struct i2c_msg msg = { client->addr, 0, 1, buf };
buf[0] = subaddr;
//Tony test
#ifdef QISDA_TEST_GPIO_PROBE
writel(readl(g_pGPIOReg_GPFCON+0x04) & (0x0<<0), g_pGPIOReg_GPFCON+0x04);
#endif
ret = i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
if (ret == -EIO) {
printk(" I2C read Error, subaddr: 0x%x \n", subaddr);
return 0;
}
//Tony test
#ifdef QISDA_TEST_GPIO_PROBE
writel(readl(g_pGPIOReg_GPFCON+0x04) | (0x1<<0), g_pGPIOReg_GPFCON+0x04);
#endif
msg.flags = I2C_M_RD ;
ret = i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
//Tony test
#ifdef QISDA_TEST_GPIO_PROBE
writel(readl(g_pGPIOReg_GPFCON+0x04) & (0x0<<0), g_pGPIOReg_GPFCON+0x04);
#endif
return buf[0];
}
/*kit.add 2009/12/02*/
unsigned char i2c_buf1[1];
unsigned char i2c_buf2[4];
int qisda_iic_read_pos(struct i2c_client *client, unsigned char subaddr)
{
int ret;
int i;
struct i2c_msg msg[] =
{
{client->addr, 0, 1, i2c_buf1},
{client->addr, I2C_M_RD, 4, i2c_buf2},
};
for(i=0; i<4; i++)
i2c_buf2[i] = 0;
i2c_buf1[0] = subaddr;
i2c_buf2[0] = subaddr;
ret = i2c_transfer(client->adapter, msg, 2) == 1 ? 0 : -EIO;
/*if (ret == -EIO) {
printk(" I2C read Error, subaddr: 0x%x \n", subaddr);
return 0;
}*/
return 0;
}
/*kit.end*/
static int qisda_iic_write(struct i2c_client *client, unsigned char subaddr, unsigned char val)
{
unsigned char buf[2];
int ret;
struct i2c_msg msg = { client->addr, 0, 2, buf };
buf[0] = subaddr;
buf[1] = val;
ret = i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
if(ret == -EIO){
printk(" I2C write Error, subaddr: 0x%x \n", subaddr);
}
return ret;
}
static int qisda_iic_attach_adapter(struct i2c_adapter *adapter)
{
return i2c_probe(adapter, &addr_data, qisda_iic_detect);
}
/* This function is called by i2c_probe */
static int qisda_iic_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct qisda_iic_data *data;
int err = 0;
if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) goto exit;
if (!(data = kzalloc(sizeof(struct qisda_iic_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &qisda_iic_driver;
new_client->flags = 0;
/* Fill in the remaining client fields */
strlcpy(new_client->name, "qisda_iic", I2C_NAME_SIZE);
data->valid = 0;
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client))) goto exit_kfree;
//Tell the s3c_ts_iic. It is ready to initialize the panel by setting interrupt mode.
//Then it will callback to the command
if ((err = s3c_ts_iic_port_init(new_client))) goto exit_kfree;;
#ifdef CONFIG_TOUCH_PM
/* Aaron: create sysfs group */
if (sysfs_create_group(&new_client->dev.kobj, &multitouch_group) < 0) {
printk(KERN_ERR "qisda_iic_detect: Unable to create sysfs group\n");
//goto err_sysfs_create_group_failed;
}
//Aaron: powermode with allow_sleep
if(qisda_iic_write(new_client, 0x73, 0x54) < 0)
printk(KERN_ERR "qisda_iic_detect: fail to set powermode with allow_sleep\n");
#endif
return err;
exit_kfree:
i2c_detach_client(new_client);
kfree(data);
exit:
printk(KERN_INFO "qisda_iic_detect return error\n");
return err;
}
static int qisda_iic_detach_client(struct i2c_client *client)
{
int err;
err = i2c_detach_client(client);
if (err)
return err;
kfree(i2c_get_clientdata(client));
return 0;
}
static int qisda_iic_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
unsigned char u8return,u8x1,u8x0,u8y1,u8y0;
unsigned int *pos;
#define INT_MODE_ENABLE (1<<3)
#define INT_MODE_HIGH_ACTIVE (1<<2)
#define INT_MODE_TOUCH_INDICATE (1<<1)
#define INT_MODE_DIFFERENCE (1<<0)
switch(cmd)
{
case QISDA_IIC_INIT:
//Set interrupt mode. Enable interrupt, Low active.
//Tony test
#ifdef QISDA_TEST_GPIO_PROBE
g_pGPIOReg_GPFCON = ioremap(0x56000050, 0x00100000);
writel(readl(g_pGPIOReg_GPFCON) | (0x1<<0), g_pGPIOReg_GPFCON);
writel(readl(g_pGPIOReg_GPFCON+0x04) | (0x1<<0), g_pGPIOReg_GPFCON+0x04);
writel(readl(g_pGPIOReg_GPFCON+0x08) | (0x2<<0), g_pGPIOReg_GPFCON+0x08);
#endif
#ifdef NEW_TCOM_BOARD
//printk(KERN_INFO "qisda_iic_detect INIT 1111\n");
//mdelay(300);
//if(qisda_iic_write(client, 0x78, 0x3) < 0) return -EIO;
//mdelay(250);
//printk(KERN_INFO "qisda_iic_command INIT 2222\n");
if(qisda_iic_write(client, 0x71, 0xA) < 0) return -EIO;
udelay(DELAY_TIME_IIC_READ);
u8return= qisda_iic_read(client, 0x71);
//printk(KERN_INFO "qisda_iic_command INIT =0x%x\n",u8return);
qisda_iic_write(client, 0x6F, 0x22);
qisda_iic_write(client, 0x70, 0x22);
#ifdef USE_BUFFERED_TOUCH_DATA
//Aaron: add for buffered data
/* enable buffered data, because default is disabled (0x0) */
if(qisda_iic_write(client, 0xBE, 0x01) < 0) return -EIO;
udelay(DELAY_TIME_IIC_READ);
u8return= qisda_iic_read(client, 0xBE);
//printk(KERN_INFO "qisda_iic_command: points interval =0x%x\n",u8return);
u8return= qisda_iic_read(client, 0x77); //read firmware version of touch panel
//printk(KERN_INFO "qisda_iic_command: firmware version =0x%x\n",u8return);
if (u8return < 0x13)
IsBufferedDataFwVersion = 0;
else
IsBufferedDataFwVersion = 1;
#endif
#else // old
//printk(KERN_INFO "qisda_iic_command INIT 1111\n");
mdelay(6000);
qisda_iic_write(client, 0x78, 0x3);
//printk(KERN_INFO "qisda_iic_command INIT 2222\n");
qisda_iic_write(client, 0x71,INT_MODE_ENABLE | INT_MODE_TOUCH_INDICATE);
udelay(DELAY_TIME_IIC_READ);
u8return= qisda_iic_read(client, 0x71);
//printk(KERN_INFO "qisda_iic_command INIT =0x%x\n",u8return);
#endif
break;
case QISDA_IIC_READ_POSITION:
pos = arg;
#ifdef NEW_TCOM_BOARD
/*kit.mod 2009/12/02*/
/*u8x0= qisda_iic_read(client, 0x00);
udelay(DELAY_TIME_IIC_READ);
u8x1= qisda_iic_read(client, 0x01);
udelay(DELAY_TIME_IIC_READ);
u8y0= qisda_iic_read(client, 0x02);
udelay(DELAY_TIME_IIC_READ);
u8y1= qisda_iic_read(client, 0x03);
udelay(DELAY_TIME_IIC_READ);*/
qisda_iic_read_pos(client, 0x00);
u8x0 = i2c_buf2[0];
u8x1 = i2c_buf2[1];
u8y0 = i2c_buf2[2];
u8y1 = i2c_buf2[3];
/*kit.end*/
#else
u8x0= qisda_iic_read(client, 0x54);
udelay(DELAY_TIME_IIC_READ);
u8x1= qisda_iic_read(client, 0x58);
udelay(DELAY_TIME_IIC_READ);
u8y0= qisda_iic_read(client, 0x55);
udelay(DELAY_TIME_IIC_READ);
u8y1= qisda_iic_read(client, 0x59);
#endif
udelay(DELAY_TIME_IIC_READ);
u8x1 &= 0x3;
u8y1 &= 0x3;
#ifdef ROTATE_NAGATIVE_90
pos[0] = (unsigned int)u8x1*256 + u8x0;
pos[1] = (unsigned int)u8y1*256+ u8y0;
if(!((pos[0] ==0) && (pos[1]==0)))
{
pos[1] = (unsigned int)u8x1*256 + u8x0 -1;
pos[0] = (unsigned int)u8y1*256+ u8y0;
/*kit.mod 20090811*/
#if defined(AUO_EPAPER_6_INCH)
pos[0] = 601 - pos[0] -1;
#elif defined(AUO_EPAPER_9_INCH)
pos[0] = 769 - pos[0] -1;
#endif
/*kit.end*/
}
#else
pos[0] = (unsigned int)u8x1*256 + u8x0;
pos[1] = (unsigned int)u8y1*256+ u8y0;
#endif
//printk("X: %d, Y: %d\n", pos[0], pos[1]);
break;
#ifdef USE_BUFFERED_TOUCH_DATA
/* Aaron,20091224, add for buffered data read */
case QISDA_IIC_READ_BUFFERED_POSITION:
{
int coordinate[2] = {0}; /*[0]=x, [1]=y*/
int *data = (int *)arg;
int index, len, i, j, offset, *point_data;
/* prevent from using the panel of old firmware version */
if (!IsBufferedDataFwVersion) {
printk("qisda_iic_command():buffered data(Not supported firmware version)\n");
break;
}
index = data[0];
len = data[1];
point_data = data + (2 + index * len * 2); /* each point is made of two coordinate data*/
offset = len * index * 4;
/* read buffered data for each check length */
for (i = 0; i < len; i++) {
/* read coordinates for x & y (two words), as one point data */
for (j = 0; j < 2; j++) {
coordinate[j] = i2c_smbus_read_word_data(client, (0xC0 + offset + j*2));
if (coordinate[j] < 0) {
printk("qisda_iic_command():read word data error(%d),i=%d,j=%d\n", coordinate[j], i, j);
break;
}
}
offset += 4; /* there are 4 bytes in each point data*/
//Aaron: //TODO: maybe should change from "<" to "<="
/* if either of x/y is zero, we think they are both zero. */
//TODO: need to feedback the status of no more read?????????
if (coordinate[0] <= 0 || coordinate[1] <= 0)
break;
#ifdef ROTATE_NAGATIVE_90
#if defined(AUO_EPAPER_6_INCH)
point_data[i*2] = 600 - coordinate[1];
#elif defined(AUO_EPAPER_9_INCH)
point_data[i*2] = 768 - coordinate[1];
#else
/* error: shall not go into this configuration */
point_data[i*2] = coordinate[1];
#endif
point_data[i*2 + 1] = coordinate[0];
#else
point_data[i*2] = coordinate[0];
point_data[i*2 + 1] = coordinate[1];
#endif
//printk("qisda_iic_command():buffered data(%d,%d)\n", point_data[i*2],point_data[i*2 + 1]);
}
}
break;
#endif //#ifdef USE_BUFFERED_TOUCH_DATA
case QISDA_IIC_CALIBRATION:
if(qisda_iic_write(client, 0x78, 0x3) < 0){
printk("CALIBRATION ERROR!");
return -EIO;
}
msleep(300);
break;
#ifdef CONFIG_TOUCH_PM
case QISDA_IIC_ACTIVE_MODE:
//printk("ACTIVE MODE\n");
qisda_iic_write(client, 0x73, 0x54);
msleep(5);
break;
case QISDA_IIC_SLEEP_MODE:
//printk("SLEEP MODE\n");
qisda_iic_write(client, 0x73, 0x55);
msleep(5);
break;
case QISDA_IIC_DEEPSLEEP_MODE:
//printk("ALSO SLEEP MODE\n");
qisda_iic_write(client, 0x73, 0x55);
msleep(5);
break;
#else
case QISDA_IIC_ACTIVE_MODE:
//printk("ACTIVE MODE\n");
qisda_iic_write(client, 0x73, 0x50);
msleep(5);
break;
case QISDA_IIC_SLEEP_MODE:
//printk("SLEEP MODE\n");
qisda_iic_write(client, 0x73, 0x51);
msleep(5);
break;
case QISDA_IIC_DEEPSLEEP_MODE:
//printk("DEEP SLEEP MODE\n");
qisda_iic_write(client, 0x73, 0x52);
msleep(5);
break;
#endif
default:
break;
}
return 0;
}
static int __init qisda_iic_init(void) { return i2c_add_driver(&qisda_iic_driver); }
static void __exit qisda_iic_exit(void) { i2c_del_driver(&qisda_iic_driver); }
MODULE_AUTHOR("Tony YC Huang@qisda.com");
MODULE_DESCRIPTION("IIC interface for Qisda");
MODULE_LICENSE("GPL");
module_init(qisda_iic_init);
module_exit(qisda_iic_exit);