696 lines
16 KiB
C
696 lines
16 KiB
C
#include <stdio.h>
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "FreeRTOS.h"
|
|
#include "chip.h"
|
|
#include "board.h"
|
|
|
|
|
|
#ifdef TP_USE_GA657X
|
|
#if !defined(VG_ONLY) && !defined(AWTK)
|
|
#include "lvgl/lvgl.h"
|
|
#else
|
|
typedef int16_t lv_coord_t;
|
|
typedef uint8_t lv_indev_state_t;
|
|
typedef struct {
|
|
lv_coord_t x;
|
|
lv_coord_t y;
|
|
} lv_point_t;
|
|
|
|
enum { LV_INDEV_STATE_REL = 0, LV_INDEV_STATE_PR };
|
|
|
|
enum {
|
|
LV_KEY_UP = 17, /*0x11*/
|
|
LV_KEY_DOWN = 18, /*0x12*/
|
|
LV_KEY_RIGHT = 19, /*0x13*/
|
|
LV_KEY_LEFT = 20, /*0x14*/
|
|
LV_KEY_ESC = 27, /*0x1B*/
|
|
LV_KEY_DEL = 127, /*0x7F*/
|
|
LV_KEY_BACKSPACE = 8, /*0x08*/
|
|
LV_KEY_ENTER = 10, /*0x0A, '\n'*/
|
|
LV_KEY_NEXT = 9, /*0x09, '\t'*/
|
|
LV_KEY_PREV = 11, /*0x0B, '*/
|
|
LV_KEY_HOME = 2, /*0x02, STX*/
|
|
LV_KEY_END = 3, /*0x03, ETX*/
|
|
};
|
|
|
|
typedef struct {
|
|
lv_point_t point; /**< For LV_INDEV_TYPE_POINTER the currently pressed point*/
|
|
uint32_t key; /**< For LV_INDEV_TYPE_KEYPAD the currently pressed key*/
|
|
uint32_t btn_id; /**< For LV_INDEV_TYPE_BUTTON the currently pressed button*/
|
|
int16_t enc_diff; /**< For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/
|
|
|
|
lv_indev_state_t state; /**< LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/
|
|
} lv_indev_data_t;
|
|
#endif
|
|
|
|
#define GOODIX_GPIO_INT_NAME "irq"
|
|
#define GOODIX_GPIO_RST_NAME "reset"
|
|
|
|
#define GOODIX_MAX_HEIGHT 4096
|
|
#define GOODIX_MAX_WIDTH 4096
|
|
#define GOODIX_INT_TRIGGER 1// 1//ϽµÑØ 0 ÉÏÉýÑØ
|
|
#define GOODIX_CONTACT_SIZE 8
|
|
#define GOODIX_MAX_CONTACTS 10
|
|
|
|
#define GOODIX_CONFIG_MAX_LENGTH 240
|
|
#define GOODIX_CONFIG_911_LENGTH 186
|
|
#define GOODIX_CONFIG_967_LENGTH 228
|
|
|
|
/* Register defines */
|
|
#define GOODIX_REG_COMMAND 0x8040
|
|
#define GOODIX_CMD_SCREEN_OFF 0x05
|
|
|
|
#define GOODIX_READ_COOR_ADDR 0x814E
|
|
#define GOODIX_GT1X_REG_CONFIG_DATA 0x8050
|
|
#define GOODIX_GT9X_REG_CONFIG_DATA 0x8047
|
|
#define GOODIX_GT6571_REG_CONFIG_DATA 0x814E
|
|
#define GOODIX_REG_ID 0x8140
|
|
|
|
#define GOODIX_BUFFER_STATUS_READY BIT(7)
|
|
#define GOODIX_BUFFER_STATUS_TIMEOUT 20
|
|
|
|
#define RESOLUTION_LOC 1
|
|
#define MAX_CONTACTS_LOC 5
|
|
#define TRIGGER_LOC 6
|
|
|
|
#define GT657X_SLAVE_ADDR 0x5d
|
|
#define GT657X_GPIO_INT TP_GPIO_INT
|
|
#define GT657X_GPIO_RST TP_GPIO_RST
|
|
#define GT657X_INVERTED_X TP_INV_Y
|
|
#define GT657X_INVERTED_Y TP_INV_Y
|
|
#define GT657X_MT_TOUCH TP_MT_TOUCH
|
|
|
|
struct goodix_ts_data;
|
|
|
|
struct goodix_chip_data {
|
|
u16 config_addr;
|
|
int config_len;
|
|
};
|
|
|
|
struct goodix_ts_data {
|
|
struct i2c_adapter *adap;
|
|
const struct goodix_chip_data *chip;
|
|
unsigned int max_touch_num;
|
|
unsigned int x_max;
|
|
unsigned int y_max;
|
|
unsigned int int_trigger_type;
|
|
int gpio_int;
|
|
int gpio_rst;
|
|
u16 id;
|
|
u16 version;
|
|
const char cfg_name[32];
|
|
unsigned long irq_flags;
|
|
TaskHandle_t irq_task;
|
|
};
|
|
|
|
static const struct goodix_chip_data gt1x_chip_data = {
|
|
.config_addr = GOODIX_GT1X_REG_CONFIG_DATA,
|
|
.config_len = GOODIX_CONFIG_MAX_LENGTH,
|
|
};
|
|
|
|
static const struct goodix_chip_data gt911_chip_data = {
|
|
.config_addr = GOODIX_GT9X_REG_CONFIG_DATA,
|
|
.config_len = GOODIX_CONFIG_911_LENGTH,
|
|
};
|
|
|
|
static const struct goodix_chip_data gt967_chip_data = {
|
|
.config_addr = GOODIX_GT9X_REG_CONFIG_DATA,
|
|
.config_len = GOODIX_CONFIG_967_LENGTH,
|
|
};
|
|
static const struct goodix_chip_data gt6571_chip_data = {
|
|
.config_addr = GOODIX_GT6571_REG_CONFIG_DATA,
|
|
.config_len = GOODIX_CONFIG_967_LENGTH,
|
|
};
|
|
|
|
static const struct goodix_chip_data gt9x_chip_data = {
|
|
.config_addr = GOODIX_GT9X_REG_CONFIG_DATA,
|
|
.config_len = GOODIX_CONFIG_MAX_LENGTH,
|
|
};
|
|
|
|
static const unsigned long goodix_irq_flags[] = {
|
|
IRQ_TYPE_EDGE_RISING,
|
|
IRQ_TYPE_EDGE_FALLING,
|
|
IRQ_TYPE_LEVEL_LOW,
|
|
IRQ_TYPE_LEVEL_HIGH,
|
|
};
|
|
|
|
static int last_input_x, last_input_y;
|
|
|
|
extern void SendTouchInputEvent(lv_indev_data_t *indata);
|
|
|
|
#ifdef AWTK
|
|
#include <xm_base.h>
|
|
#include <xm_event.h>
|
|
#endif
|
|
|
|
static inline int get_unaligned_le16(void *p)
|
|
{
|
|
u8 *tmp = (u8*)p;
|
|
|
|
return (tmp[1] << 8) | tmp[0];
|
|
}
|
|
|
|
/**
|
|
* goodix_i2c_read - read data from a register of the i2c slave device.
|
|
*
|
|
* @adap: i2c device.
|
|
* @reg: the register to read from.
|
|
* @buf: raw write data buffer.
|
|
* @len: length of the buffer to write
|
|
*/
|
|
static int goodix_i2c_read(struct i2c_adapter *adap,
|
|
u16 reg, u8 *buf, int len)
|
|
{
|
|
struct i2c_msg msgs[2];
|
|
u8 wbuf[2];
|
|
int ret;
|
|
|
|
wbuf[0] = reg >> 8;
|
|
wbuf[1] = reg & 0xFF;
|
|
|
|
msgs[0].flags = 0;
|
|
msgs[0].addr = GT657X_SLAVE_ADDR;
|
|
msgs[0].len = 2;
|
|
msgs[0].buf = (u8 *)&wbuf;
|
|
|
|
msgs[1].flags = I2C_M_RD;
|
|
msgs[1].addr = GT657X_SLAVE_ADDR;
|
|
msgs[1].len = len;
|
|
msgs[1].buf = buf;
|
|
|
|
ret = i2c_transfer(adap, msgs, 2);
|
|
return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
|
|
}
|
|
|
|
/**
|
|
* goodix_i2c_write - write data to a register of the i2c slave device.
|
|
*
|
|
* @adap: i2c device.
|
|
* @reg: the register to write to.
|
|
* @buf: raw data buffer to write.
|
|
* @len: length of the buffer to write
|
|
*/
|
|
static int goodix_i2c_write(struct i2c_adapter *adap, u16 reg, const u8 *buf,
|
|
unsigned len)
|
|
{
|
|
u8 *addr_buf;
|
|
struct i2c_msg msg;
|
|
int ret;
|
|
|
|
addr_buf = pvPortMalloc(len + 2);
|
|
if (!addr_buf)
|
|
return -ENOMEM;
|
|
|
|
addr_buf[0] = reg >> 8;
|
|
addr_buf[1] = reg & 0xFF;
|
|
memcpy(&addr_buf[2], buf, len);
|
|
|
|
msg.flags = 0;
|
|
msg.addr = GT657X_SLAVE_ADDR;
|
|
msg.buf = addr_buf;
|
|
msg.len = len + 2;
|
|
|
|
ret = i2c_transfer(adap, &msg, 1);
|
|
vPortFree(addr_buf);
|
|
return ret < 0 ? ret : (ret != 1 ? -EIO : 0);
|
|
}
|
|
|
|
static int goodix_i2c_write_u8(struct i2c_adapter *adap, u16 reg, u8 value)
|
|
{
|
|
return goodix_i2c_write(adap, reg, &value, sizeof(value));
|
|
}
|
|
|
|
static const struct goodix_chip_data *goodix_get_chip_data(u16 id)
|
|
{
|
|
|
|
|
|
|
|
switch (id) {
|
|
case 1151:
|
|
return >1x_chip_data;
|
|
|
|
case 911:
|
|
case 9271:
|
|
case 9110:
|
|
case 927:
|
|
case 928:
|
|
return >911_chip_data;
|
|
|
|
case 912:
|
|
case 967:
|
|
return >967_chip_data;
|
|
case 6571:
|
|
|
|
return >6571_chip_data;
|
|
default:
|
|
return >9x_chip_data;
|
|
}
|
|
}
|
|
|
|
static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
|
|
{
|
|
unsigned long max_timeout;
|
|
int touch_num;
|
|
int error;
|
|
|
|
/*
|
|
* The 'buffer status' bit, which indicates that the data is valid, is
|
|
* not set as soon as the interrupt is raised, but slightly after.
|
|
* This takes around 10 ms to happen, so we poll for 20 ms.
|
|
*/
|
|
|
|
max_timeout = xTaskGetTickCount() + pdMS_TO_TICKS(GOODIX_BUFFER_STATUS_TIMEOUT);
|
|
do {
|
|
error = goodix_i2c_read(ts->adap, GOODIX_READ_COOR_ADDR,
|
|
data, GOODIX_CONTACT_SIZE + 1);
|
|
if (error) {
|
|
printf("I2C transfer error: %d\n", error);
|
|
return error;
|
|
}
|
|
|
|
|
|
|
|
|
|
if (data[0] & GOODIX_BUFFER_STATUS_READY) {
|
|
touch_num = data[0] & 0x0f;
|
|
|
|
if (touch_num > ts->max_touch_num)
|
|
return -EPROTO;
|
|
#ifdef GT9XX_MT_TOUCH
|
|
if (touch_num > 1) {
|
|
data += 1 + GOODIX_CONTACT_SIZE;
|
|
error = goodix_i2c_read(ts->adap,
|
|
GOODIX_READ_COOR_ADDR +
|
|
1 + GOODIX_CONTACT_SIZE,
|
|
data,
|
|
GOODIX_CONTACT_SIZE *
|
|
(touch_num - 1));
|
|
if (error)
|
|
return error;
|
|
}
|
|
|
|
return touch_num;
|
|
#else
|
|
|
|
return touch_num > 0 ? 1 : 0;
|
|
#endif
|
|
|
|
}
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(1)); /* Poll every 1 - 2 ms */
|
|
} while (xTaskGetTickCount() < max_timeout);
|
|
|
|
/*
|
|
* The Goodix panel will send spurious interrupts after a
|
|
* 'finger up' event, which will always cause a timeout.
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
|
|
{
|
|
int id = coor_data[0] & 0x0F;
|
|
int input_x = get_unaligned_le16(&coor_data[1]);
|
|
int input_y = get_unaligned_le16(&coor_data[3]);
|
|
int input_w = get_unaligned_le16(&coor_data[5]);
|
|
|
|
printf("id=0x%x, input_x=%d, input_y=%d, input_w=%d.\n", id, input_x,
|
|
input_y, input_w);
|
|
|
|
#if GT657X_INVERTED_X
|
|
input_x = ts->x_max - input_x;
|
|
#endif
|
|
|
|
#if GT657X_INVERTED_Y
|
|
input_y = ts->y_max - input_y;
|
|
#endif
|
|
|
|
//send press event
|
|
#ifdef AWTK
|
|
XM_TpEventProc (XM_EVENT_TOUCHDOWN, input_x, input_y, 0);
|
|
#else
|
|
lv_indev_data_t indata = {0};
|
|
indata.point.x = input_x;
|
|
indata.point.y = input_y;
|
|
indata.state = LV_INDEV_STATE_PR;
|
|
SendTouchInputEvent(&indata);
|
|
#endif
|
|
|
|
last_input_x = input_x;
|
|
last_input_y = input_y;
|
|
}
|
|
|
|
/**
|
|
* goodix_process_events - Process incoming events
|
|
*
|
|
* @ts: our goodix_ts_data pointer
|
|
*
|
|
* Called when the IRQ is triggered. Read the current device state, and push
|
|
* the input events to the user space.
|
|
*/
|
|
static void goodix_process_events(struct goodix_ts_data *ts)
|
|
{
|
|
u8 point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS];
|
|
int touch_num;
|
|
int i;
|
|
|
|
touch_num = goodix_ts_read_input_report(ts, point_data);
|
|
if (touch_num < 0)
|
|
return;
|
|
|
|
|
|
/*
|
|
* Bit 4 of the first byte reports the status of the capacitive
|
|
* Windows/Home button.
|
|
*/
|
|
//input_report_key(ts->input_dev, KEY_LEFTMETA, point_data[0] & BIT(4));
|
|
|
|
for (i = 0; i < touch_num; i++)
|
|
goodix_ts_report_touch(ts,
|
|
&point_data[1 + GOODIX_CONTACT_SIZE * i]);
|
|
|
|
if (touch_num == 0) {
|
|
//send release event
|
|
#ifdef AWTK
|
|
XM_TpEventProc (XM_EVENT_TOUCHUP, last_input_x, last_input_y, 0);
|
|
#else
|
|
lv_indev_data_t indata = {0};
|
|
indata.point.x = last_input_x;
|
|
indata.point.y = last_input_y;
|
|
indata.state = LV_INDEV_STATE_REL;
|
|
SendTouchInputEvent(&indata);
|
|
#endif
|
|
}
|
|
|
|
/* input_mt_sync_frame(ts->input_dev);
|
|
input_sync(ts->input_dev); */
|
|
}
|
|
|
|
static void goodix_ts_irq_task(void *param)
|
|
{
|
|
uint32_t ulNotifiedValue;
|
|
struct goodix_ts_data *ts;
|
|
|
|
for (;;) {
|
|
xTaskNotifyWait( 0x00, /* Don't clear any notification bits on entry. */
|
|
0xffffffff, /* Reset the notification value to 0 on exit. */
|
|
&ulNotifiedValue, /* Notified value pass out in ulNotifiedValue. */
|
|
portMAX_DELAY);
|
|
|
|
ts = (struct goodix_ts_data *)ulNotifiedValue;
|
|
|
|
goodix_process_events(ts);
|
|
if (goodix_i2c_write_u8(ts->adap, GOODIX_READ_COOR_ADDR, 0) < 0)
|
|
TRACE_ERROR("I2C write end_cmd error.\n");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* goodix_ts_irq_handler - The IRQ handler
|
|
*
|
|
* @param: private data pointer.
|
|
*/
|
|
static void goodix_ts_irq_handler(void *param)
|
|
{
|
|
struct goodix_ts_data *ts = param;
|
|
|
|
xTaskNotifyFromISR(ts->irq_task, (uint32_t)ts, eSetValueWithOverwrite, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
static int goodix_request_irq(struct goodix_ts_data *ts)
|
|
{
|
|
if (xTaskCreate(goodix_ts_irq_task, "gt9xx", 1024, ts,
|
|
10, &ts->irq_task) != pdPASS) {
|
|
printf("create gt9xx irq task fail.\n");
|
|
}
|
|
|
|
return gpio_irq_request(ts->gpio_int, ts->irq_flags, goodix_ts_irq_handler, ts);
|
|
}
|
|
|
|
static int goodix_int_sync(struct goodix_ts_data *ts)
|
|
{
|
|
gpio_direction_output(ts->gpio_int, 0);
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(50)); /* T5: 50ms */
|
|
|
|
gpio_direction_input(ts->gpio_int);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* goodix_reset - Reset device during power on
|
|
*
|
|
* @ts: goodix_ts_data pointer
|
|
*/
|
|
static int goodix_reset(struct goodix_ts_data *ts)
|
|
{
|
|
int error;
|
|
|
|
/* begin select I2C slave addr */
|
|
gpio_direction_output(ts->gpio_rst, 0);
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(50)); /* T2: > 10ms */
|
|
|
|
/* HIGH: 0x28/0x29, LOW: 0xBA/0xBB */
|
|
gpio_direction_output(ts->gpio_int, GT657X_SLAVE_ADDR == 0x14);
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(1)); /* T3: > 100us */
|
|
|
|
gpio_direction_output(ts->gpio_rst, 1);
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(30)); /* T4: > 5ms */
|
|
|
|
/* end select I2C slave addr */
|
|
gpio_direction_input(ts->gpio_rst);
|
|
|
|
error = goodix_int_sync(ts);
|
|
if (error)
|
|
return error;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* goodix_read_config - Read the embedded configuration of the panel
|
|
*
|
|
* @ts: our goodix_ts_data pointer
|
|
*
|
|
* Must be called during probe
|
|
*/
|
|
static void goodix_read_config(struct goodix_ts_data *ts)
|
|
{
|
|
u8 config[GOODIX_CONFIG_MAX_LENGTH];
|
|
int error;
|
|
|
|
error = goodix_i2c_read(ts->adap, ts->chip->config_addr,
|
|
config, ts->chip->config_len);
|
|
if (error) {
|
|
printf("Error reading config: %d\n", error);
|
|
ts->int_trigger_type = GOODIX_INT_TRIGGER;
|
|
ts->max_touch_num = GOODIX_MAX_CONTACTS;
|
|
return;
|
|
}
|
|
|
|
ts->int_trigger_type = config[TRIGGER_LOC] & 0x03;
|
|
ts->max_touch_num = GOODIX_MAX_CONTACTS;//config[MAX_CONTACTS_LOC] & 0x0f;
|
|
|
|
ts->x_max = get_unaligned_le16(&config[RESOLUTION_LOC]);
|
|
ts->y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]);
|
|
}
|
|
|
|
/**
|
|
* goodix_read_version - Read goodix touchscreen version
|
|
*
|
|
* @ts: our goodix_ts_data pointer
|
|
*/
|
|
static int goodix_read_version(struct goodix_ts_data *ts)
|
|
{
|
|
int error;
|
|
u8 buf[6];
|
|
char id_str[5];
|
|
|
|
error = goodix_i2c_read(ts->adap, GOODIX_REG_ID, buf, sizeof(buf));
|
|
if (error) {
|
|
TRACE_INFO("read version failed: %d\n", error);
|
|
return error;
|
|
}
|
|
|
|
memcpy(id_str, buf, 4);
|
|
id_str[4] = 0;
|
|
char *ptr;
|
|
ts->id = strtoul(id_str, &ptr, 10);
|
|
if (ts->id == 0xffff)
|
|
ts->id = 0x1001;
|
|
|
|
ts->version = get_unaligned_le16(&buf[4]);
|
|
|
|
TRACE_INFO("ID %d, version: %04x\n", ts->id, ts->version);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* goodix_i2c_test - I2C test function to check if the device answers.
|
|
*
|
|
* @adap: the i2c adapter
|
|
*/
|
|
static int goodix_i2c_test(struct i2c_adapter *adap)
|
|
{
|
|
int retry = 0;
|
|
int error;
|
|
u8 test;
|
|
|
|
while (retry++ < 5) {
|
|
error = goodix_i2c_read(adap, GOODIX_REG_ID,
|
|
&test, 1);
|
|
if (!error)
|
|
return 0;
|
|
|
|
TRACE_ERROR("i2c test failed attempt %d: %d\n",
|
|
retry, error);
|
|
vTaskDelay(pdMS_TO_TICKS(20));
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
/**
|
|
* goodix_configure_dev - Finish device initialization
|
|
*
|
|
* @ts: our goodix_ts_data pointer
|
|
*
|
|
* Must be called from probe to finish initialization of the device.
|
|
* Contains the common initialization code for both devices that
|
|
* declare gpio pins and devices that do not. It is either called
|
|
* directly from probe or from request_firmware_wait callback.
|
|
*/
|
|
static int goodix_configure_dev(struct goodix_ts_data *ts)
|
|
{
|
|
int error;
|
|
|
|
ts->int_trigger_type = GOODIX_INT_TRIGGER;
|
|
ts->max_touch_num = GOODIX_MAX_CONTACTS;
|
|
|
|
/* Read configuration and apply touchscreen parameters */
|
|
goodix_read_config(ts);
|
|
|
|
ts->irq_flags = goodix_irq_flags[ts->int_trigger_type];
|
|
error = goodix_request_irq(ts);
|
|
if (error) {
|
|
TRACE_ERROR("request IRQ failed: %d\n", error);
|
|
return error;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
static const unsigned char zero[2] = {0,0};
|
|
static const unsigned char cmd[186] = {
|
|
0x43,0x61,0x1C,0x1E,0x73,0x13,0x00,0x1B,0x52,0x9C,0x85,0x00,0xFF,0x5A,0x4B,0x00,0x00,0x16,0x1A,0x20,0x14,
|
|
0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x01,0x94,0x50,0x05,0x42,0x00,0x00,0x00,0xF0,0x00,0x05,0xD0,0x02,0x10,0x10,0xBB,0x15,
|
|
0x14,0x13,0x12,0x11,0x10,0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0xFF,0xFF,0xFF,
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0E,0x0F,0x10,0x11,0x12,0x13,0x19,0x1B,0x1C,
|
|
0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,
|
|
0x0F,0x32,0x8C,0xE3,0x81,0x14,0x04,0x00,0xD6,0x12,0x00,0xBF,0x18,0x00,0xAE,0x20,0x00,0x9E,0x2A,0x00,0x92,0x39,0x00,0x92,
|
|
0x00,0x00,0x00,0x6A,0x00,0xAC,0x64,0x32,0x00,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x14,0x03,0x32,0x23,0xAF,0x00,0x0F,0x32,0x09,0x01,0x3C,0xC8,0x33,0x64,0x50,0x8F,0x55,0xC8,0x00,0x00,0x30,0x01
|
|
};
|
|
//static const unsigned char buff[186] = {0};
|
|
int goodix_ts_probe(struct i2c_adapter *adap)
|
|
{
|
|
struct goodix_ts_data *ts;
|
|
int error;
|
|
//u8 i=0;
|
|
TRACE_DEBUG("I2C Address: 0x%02x\n", GT657X_SLAVE_ADDR);
|
|
|
|
ts = pvPortMalloc(sizeof(*ts));
|
|
if (!ts)
|
|
return -ENOMEM;
|
|
memset(ts, 0, sizeof(*ts));
|
|
|
|
ts->adap = adap;
|
|
ts->gpio_int = GT657X_GPIO_INT;
|
|
ts->gpio_rst = GT657X_GPIO_RST;
|
|
|
|
if (ts->gpio_int && ts->gpio_rst) {
|
|
/* reset the controller */
|
|
error = goodix_reset(ts);
|
|
if (error) {
|
|
TRACE_ERROR("Controller reset failed.\n");
|
|
return error;
|
|
}
|
|
}
|
|
|
|
error = goodix_i2c_test(adap);
|
|
if (error) {
|
|
TRACE_ERROR("I2C communication failure: %d\n", error);
|
|
return error;
|
|
}
|
|
|
|
error = goodix_read_version(ts);
|
|
if (error) {
|
|
TRACE_ERROR("Read version failed.\n");
|
|
return error;
|
|
}
|
|
printf("ts->id is %x \n ",ts->id);
|
|
ts->chip = goodix_get_chip_data(ts->id);
|
|
|
|
|
|
do{
|
|
printf("goodix_i2c_write \n ");
|
|
error= goodix_i2c_write(ts->adap, GOODIX_READ_COOR_ADDR, (unsigned char *)&zero[0],2);
|
|
}while(error!=0);
|
|
|
|
error= goodix_i2c_write(ts->adap, 0x8047, (unsigned char *)&cmd[0],sizeof(cmd));
|
|
if (error)
|
|
{
|
|
printf("goodix_i2c_write error\n");
|
|
return error;
|
|
}
|
|
|
|
|
|
#if 0
|
|
|
|
error = goodix_i2c_read(ts->adap, 0x8047,
|
|
(unsigned char *)&buff[0], 186);
|
|
for(i=0;i<186;i++)
|
|
{
|
|
if(buff[i]!=cmd[i])
|
|
{
|
|
printf("i is %x \n",i);
|
|
printf("buff is %x \n",buff[i]);
|
|
printf("cmd is %x \n",cmd[i]);
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
error = goodix_configure_dev(ts);
|
|
if (error)
|
|
{
|
|
printf("goodix_configure_dev error \n ");
|
|
return error;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int gt675x_init(void)
|
|
{
|
|
struct i2c_adapter *adap = NULL;
|
|
|
|
if (!(adap = i2c_open("i2c0"))) {
|
|
printf("open i2c0 fail.\n");
|
|
return -1;
|
|
}
|
|
|
|
goodix_ts_probe(adap);
|
|
|
|
return 0;
|
|
}
|
|
#endif
|