SmartAudio/lichee/brandy/u-boot-2011.09/drivers/input/gt82x_ts.c

601 lines
15 KiB
C
Raw Normal View History

2018-07-13 01:31:50 +00:00
/*--------------------------------------------------------------------------
* driver/input/gt82x_ts.c
*
*
*
* Change Date:
* 2013.03.05, create.
*
*--------------------------------------------------------------------------*/
#include <common.h>
#include <asm/arch/eint.h>
#include <asm/arch/twi.h>
#include <sys_config.h>
#include <asm/arch/gt82x_ts.h>
#include <asm/arch/cpu.h>
#include <asm/arch/gic.h>
extern int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len);
extern int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len);
extern void i2c_init(int speed, int slaveaddr);
static const int chip_id_value[3] = {0x13,0x27,0x28};
static uchar read_chip_value;
struct ctp_config_info config_info;
static int gpio_wakeup_hdle = 0;
static int gpio_wakeup_enable = 1;
static u32 pio_handle;
static u32 port = 0;
static u32 port_num= 0;
struct info_x_y {
s32 x[5];
s32 y[5];
};
struct info_x_y info_x_y = {
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}};
static void ctp_wakeup(void);
/*******************************************************
Function:
write i2c end cmd.
return value:
= 0; success;
< 0; err
*******************************************************/
static int i2c_end_cmd(void)
{
int ret = -1;
uchar temp = 0;
ret = i2c_write(0x5d, 0x8000, 2, &temp, 0);
return ret;
}
/*******************************************************
Function:
Read data from the i2c slave device.
Input:.
addr:operate address.
buf:read data buffer.
len:operate length.
return value:
= 0; success;
< 0; err
*********************************************************/
static int i2c_read_bytes(uint addr, uchar *buf, int len)
{
int ret = -1;
ret = i2c_read(0x5d, addr, 2, buf, len);
return ret;
}
/*******************************************************
Function:
write data to the i2c slave device.
Input:
addr:operate address.
buf:write data buffer.
len:operate length.
return value:
= 0; success;
< 0; err
*********************************************************/
static int i2c_write_bytes(uint addr, uchar *buf, int len)
{
int ret = -1;
ret = i2c_write(0x5d, addr, 2, buf, len);
return ret;
}
/*******************************************************
Function:
read chip id function.
Input:
return value:
= 0; success;
< 0; err
*********************************************************/
static int goodix_read_id(void)
{
int ret=-1;
ctp_wakeup();
ret=i2c_read_bytes(0x0f7d, &read_chip_value, 1);
if (0 > ret)
tpdbg("%s: read id failed %d\n", __func__, ret);
tpdbg("chip_id_value:0x%x\n",read_chip_value);
return ret;
}
/*******************************************************
Function:
CTP initialize function.
Input:
nothing.
return value:
= 0; success;
< 0; err
*******************************************************/
static int goodix_init_panel(void)
{
int ret=-1;
int i = 0;
uchar config_info1[112];
uchar data_info0[] = {
0x02,0x11,0x03,0x12,0x04,0x13,0x05,0x14,
0x06,0x15,0x07,0x16,0x08,0x17,0x09,0x18,
0x0A,0x19,0x0B,0x1A,0xFF,0x15,0x16,0x17,
0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x03,0x0D,
0x04,0x0E,0x05,0x0F,0x06,0x10,0x07,0x11,
0x08,0x12,0xFF,0x0D,0xFF,0x0F,0x10,0x11,
0x12,0x13,0x0F,0x03,0x10,0x88,0x88,0x20,
0x00,0x00,0x06,0x00,0x00,0x02,0x50,0x3C,
0x35,0x03,0x00,0x05,0x00,0x03,0x20,0x05,
0x00,0x5A,0x5A,0x46,0x46,0x08,0x00,0x03,
0x19,0x05,0x14,0x10,0x00,0x07,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01
};
uchar data_info1[] = {
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,0x0E,0x1D,0x13,0x09,
0x12,0x08,0x11,0x07,0x10,0x06,0x0F,0x05,
0x0E,0x04,0x0D,0x03,0x0C,0x02,0x0B,0x01,
0x0A,0x00,0x0B,0x03,0x10,0x00,0x00,0x2C,
0x00,0x00,0x03,0x00,0x00,0x02,0x40,0x30,
0x60,0x03,0x00,0x05,0x00,0x03,0x20,0x05,
0x00,0x66,0x4E,0x60,0x49,0x06,0x00,0x23,
0x19,0x05,0x14,0x10,0x03,0xFC,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01
};
tpdbg("init panel\n");
if (read_chip_value == 0x13) { //813
ret = i2c_write_bytes(0x0F80, data_info0, 112);
if(0 > ret)
tpdbg("write reg failed %d\n", ret);
} else if(read_chip_value == 0x28) { //828
ret = i2c_write_bytes(0x0F80, data_info1, 112);
}
i2c_end_cmd();
udelay(10000);
tpdbg("init panel ret = %d\n",ret);
if (ret < 0)
return ret;
udelay(100000);
ret = i2c_read_bytes(0x0F80, config_info1, 112);
for ( i = 0;i<112;i++) {
tpdbg("i = %d config_info1[i] = %x \n",i,config_info1[i]);
}
udelay(10000);
return 0;
}
/*******************************************************
Function:
Touch down report function.
Input:
ts:private data.
id:tracking id.
x:input x.
y:input y.
w:input weight.
return value:
*******************************************************/
static void goodix_touch_down(s32 id,s32 x,s32 y,s32 w)
{
tpdbg("source data:ID:%d, X:%d, Y:%d, W:%d\n", id, x, y, w);
if (1 == config_info.exchange_x_y_flag) {
swap(x, y);
}
if (1 == config_info.revert_x_flag) {
x = config_info.screen_max_x - x;
}
if (1 == config_info.revert_y_flag) {
y = config_info.screen_max_y - y;
}
info_x_y.x[id] = x;
info_x_y.y[id] = y;
tpdbg("report data:ID:%d, X:%d, Y:%d, W:%d\n", id, x, y, w);
return;
}
/*******************************************************
Function:
Touch up report function.
Input:
return value:
*******************************************************/
static void goodix_touch_up(void)
{
}
/*******************************************************
Function:
CTP irq sevice function.
Input:
irq sevice data.
return value:
*******************************************************/
static void goodix_ts_irq_hanbler(void)
{
u8* coor_data = NULL;
uchar point_data[2 + 5 * MAX_FINGER_NUM + 1]={0};
u8 check_sum = 0;
u8 touch_num = 0;
u8 finger = 0;
u8 key_value = 0;
s32 input_x = 0;
s32 input_y = 0;
s32 input_w = 0;
s32 idx = 0;
s32 ret = -1;
//s32 i = 0;
tpdbg("===enter goodix_ts_irq_hanbler===\n");
ret = i2c_read_bytes(0x0f40, point_data, 8);
if (ret < 0) {
printf("I2C read error!");
}
finger = point_data[0];
touch_num = (finger & 0x01) + !!(finger & 0x02) + !!(finger & 0x04) + !!(finger & 0x08) + !!(finger & 0x10);
if (touch_num > 1) {
uchar buf[23];
ret = i2c_read_bytes(0x0f48, buf, 5 * (touch_num - 1));
if (ret < 0){
printf("I2C read error!/n");
}
memcpy(&point_data[8], &buf, 5 * (touch_num - 1));
}
i2c_end_cmd();
if (ret < 0) {
printf("I2C read error!");
goto exit_work_func;
}
if((finger & 0xC0) != 0x80) {
printf("Data not ready!");
goto exit_work_func;
}
key_value = point_data[1]&0x0f; // 1, 2, 4, 8
if ((key_value & 0x0f) == 0x0f) {
if (goodix_init_panel()){
printf("Reload config failed!\n");
}
goto exit_work_func;
}
coor_data = &point_data[2];
check_sum = 0;
for ( idx = 0; idx < 5 * touch_num; idx++) {
check_sum += coor_data[idx];
}
if (check_sum != coor_data[5 * touch_num]) {
printf("Check sum error!");
goto exit_work_func;
}
if (touch_num) {
s32 pos = 0;
for (idx = 0; idx < MAX_FINGER_NUM; idx++){
if (!(finger & (0x01 << idx))){
continue;
}
input_x = coor_data[pos] << 8;
input_x |= coor_data[pos + 1];
input_y = coor_data[pos + 2] << 8;
input_y |= coor_data[pos + 3];
input_w = coor_data[pos + 4];
pos += 5;
goodix_touch_down(idx, input_x, input_y, input_w);
}
}else{
tpdbg("Touch Release!");
goodix_touch_up();
}
exit_work_func:
return;
}
/* add by guoyingyang */
void gpio_handle_irq(void * pio_handle)
{
unsigned int reg_value = 0;
volatile unsigned int *reg_addr = NULL;
reg_addr = SUNXI_PIO_EINT_STATUS(port);
reg_value = *reg_addr;
printf("===== enter gpio_irq =======\n");
//ƥ<><C6A5>gpio<69>жϺţ<CFBA><C5A3><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>gpio<69>жϺ<D0B6><CFBA><EFBFBD>
if(reg_value & (0x01 << port_num))
{
goodix_ts_irq_hanbler();
//<2F><><EFBFBD><EFBFBD>gpio<69>ж<EFBFBD>pendingλ
reg_value |= ( 0x01 << port_num );
*reg_addr = reg_value ;
printf("clear pending_bit \n ");
}
return ;
}
/*******************************************************
Function:
ctp_wakeup - function.
Input:
return value:
*********************************************************/
static void ctp_wakeup(void)
{
printf("ctp_wakeup. \n");
if (1 == gpio_wakeup_enable) {
if(EGPIO_SUCCESS != gpio_write_one_pin_value(gpio_wakeup_hdle, 0, "ctp_wakeup")){
printf("err when operate gpio. \n");
}
udelay(2000);
if(EGPIO_SUCCESS != gpio_write_one_pin_value(gpio_wakeup_hdle, 1, "ctp_wakeup")){
printf("err when operate gpio. \n");
}
udelay(20000);
}
return;
}
/*******************************************************
Function:
ctp_free_platform_irq.
Input:
return value:
*******************************************************/
static void ctp_free_platform_irq(void)
{
eint_irq_disable(port,port_num);
if (pio_handle) {
gpio_release(pio_handle, 2);
}
return;
}
/*******************************************************
Function:
ctp_init_platform_irq.
Input:
return value:
= 0; success;
< 0; err
*******************************************************/
static int ctp_init_platform_irq(void)
{
int ret = -1;
user_gpio_set_t *tmp = NULL;
pio_handle = gpio_request_ex("ctp_para", "ctp_int_port");
if (!pio_handle) {
printf("[%s] gpio_request_ex fail! %d\n",__func__,__LINE__);
return ret;
}
tmp = (user_gpio_set_t *)((char *)pio_handle + 16);
//ret = eint_irq_request(0, 3, goodix_ts_irq_hanbler, EINT_TRIGGER_STATUS_NEG, &test_a);
//if (ret)
// printf("request gpio irq err!\n");
irq_install_handler(AW_IRQ_EINTB, (interrupt_handler_t *)gpio_handle_irq, (void*)&pio_handle);
port = tmp->port;
port_num = tmp->port_num;
ret = eint_irq_enable(port,port_num);
if (ret)
printf("enable irq err!\n");
return ret;
}
/*******************************************************
Function:
ctp_free_platform_resource.
Input:
return value:
*******************************************************/
static void ctp_free_platform_resource(void)
{
if (gpio_wakeup_hdle) {
gpio_release(gpio_wakeup_hdle, 2);
}
return;
}
/*******************************************************
Function:
initialize platform related resource.
Input:
return value:
= 0; success;
< 0; err
*******************************************************/
static int ctp_init_platform_resource(void)
{
int ret = 0;
gpio_wakeup_hdle = gpio_request_ex("ctp_para", "ctp_wakeup");
if (!gpio_wakeup_hdle) {
tpdbg("tp_wakeup request gpio fail!\n");
gpio_wakeup_enable = 0;
}
return ret;
}
/*******************************************************
Function:
CTP print config info function.
Input:
CTP config info
return value:
*******************************************************/
void ctp_print_info(struct ctp_config_info info)
{
tpdbg("info.ctp_used:%d\n",info.ctp_used);
tpdbg("info.twi_id:%d\n",info.twi_id);
tpdbg("info.screen_max_x:%d\n",info.screen_max_x);
tpdbg("info.screen_max_y:%d\n",info.screen_max_y);
tpdbg("info.revert_x_flag:%d\n",info.revert_x_flag);
tpdbg("info.revert_y_flag:%d\n",info.revert_y_flag);
tpdbg("info.exchange_x_y_flag:%d\n",info.exchange_x_y_flag);
tpdbg("info.irq_gpio_number:%d\n",info.irq_gpio_number);
tpdbg("info.wakeup_gpio_number:%d\n",info.wakeup_gpio_number);
}
/*******************************************************
Function:
get config info from sysconfig.fex file.
Input:
return value:
= 0; success;
< 0; err
*******************************************************/
static int ctp_fetch_sysconfig_para(void)
{
int ret = -1;
if (SCRIPT_PARSER_OK != script_parser_fetch("ctp_para", "ctp_used", &config_info.ctp_used, 1)) {
tpdbg("ctp_used script_get_item err. \n");
goto script_get_item_err;
}
if(1 != config_info.ctp_used){
tpdbg("ctp_unused. \n");
return ret;
}
if (SCRIPT_PARSER_OK != script_parser_fetch ("ctp_para", "ctp_twi_id",
&config_info.twi_id, 1)){
tpdbg("ctp_twi_id script_get_item err. \n");
goto script_get_item_err;
}
if (SCRIPT_PARSER_OK != script_parser_fetch("ctp_para", "ctp_screen_max_x", &config_info.screen_max_x, 1)) {
tpdbg("ctp_screen_max_x script_get_item err. \n");
goto script_get_item_err;
}
if (SCRIPT_PARSER_OK != script_parser_fetch("ctp_para", "ctp_screen_max_y", &config_info.screen_max_y, 1)) {
tpdbg("ctp_screen_max_y script_get_item err. \n");
goto script_get_item_err;
}
if (SCRIPT_PARSER_OK != script_parser_fetch("ctp_para", "ctp_revert_x_flag", &config_info.revert_x_flag, 1)) {
tpdbg("ctp_revert_x_flag script_get_item err. \n");
goto script_get_item_err;
}
if (SCRIPT_PARSER_OK != script_parser_fetch("ctp_para", "ctp_revert_y_flag", &config_info.revert_y_flag, 1)) {
tpdbg("ctp_revert_y_flag script_get_item err. \n");
goto script_get_item_err;
}
if (SCRIPT_PARSER_OK != script_parser_fetch("ctp_para", "ctp_exchange_x_y_flag", &config_info.exchange_x_y_flag, 1)) {
tpdbg("ctp_exchange_x_y_flag script_get_item err. \n");
goto script_get_item_err;
}
ctp_print_info(config_info);
return 0;
script_get_item_err:
tpdbg("=========script_get_item_err============\n");
return ret;
}
/*******************************************************
Function:
goodix ctp load function.
Input:
return value:
= 0; success;
< 0; err
*******************************************************/
int goodix_init(void)
{
int err = -1;
i2c_init(40000,0);
printf("%s.enter\n", __func__);
if (ctp_fetch_sysconfig_para()) {
printf("ctp_fetch_sysconfig_para err.\n");
return -1;
}
err = ctp_init_platform_resource();
if (0 != err) {
printf("ctp_init_platform_resource err. \n");
}
goodix_read_id();
goodix_init_panel();
err = ctp_init_platform_irq();
if (0 != err) {
printf("ctp_init_platform_irq err. \n");
}
printf("%s.over\n", __func__);
return err;
}
/*******************************************************
Function:
goodix ctp remove function.
Input:
return value:
*******************************************************/
int goodix_remove(void)
{
ctp_free_platform_resource();
ctp_free_platform_irq();
return 0;
}