123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- /*
- * Copyright (c) 2017 Actions Semiconductor Co., Ltd
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /**
- * @file
- * @brief TP Keyboard driver for Actions SoC
- */
- #include <errno.h>
- #include <kernel.h>
- #include <string.h>
- #include <init.h>
- #include <irq.h>
- #include <drivers/adc.h>
- #include <drivers/input/input_dev.h>
- #include <sys/util.h>
- #include <sys/byteorder.h>
- #include <board.h>
- #include <soc_pmu.h>
- #include <logging/log.h>
- #include <device.h>
- #include <drivers/gpio.h>
- #include <soc.h>
- #include <string.h>
- #include <drivers/i2c.h>
- #include <board_cfg.h>
- #include <stdlib.h>
- #ifdef CONFIG_PANEL_OFFSET_X
- # define CONFIG_TP_LOC_X_MIN CONFIG_PANEL_OFFSET_X
- #else
- # define CONFIG_TP_LOC_X_MIN (0)
- #endif
- #ifdef CONFIG_PANEL_OFFSET_Y
- # define CONFIG_TP_LOC_Y_MIN CONFIG_PANEL_OFFSET_Y
- #else
- # define CONFIG_TP_LOC_Y_MIN (0)
- #endif
- #ifdef CONFIG_PANEL_HOR_RES
- # define CONFIG_TP_LOC_X_MAX (CONFIG_PANEL_HOR_RES - 1)
- #elif defined(CONFIG_PANEL_TIMING_HACTIVE)
- # define CONFIG_TP_LOC_X_MAX (CONFIG_PANEL_TIMING_HACTIVE - 1)
- #else
- # define CONFIG_TP_LOC_X_MAX (512 - 1)
- #endif
- #ifdef CONFIG_PANEL_VER_RES
- # define CONFIG_TP_LOC_Y_MAX (CONFIG_PANEL_VER_RES - 1)
- #elif defined(CONFIG_PANEL_TIMING_VACTIVE)
- # define CONFIG_TP_LOC_Y_MAX (CONFIG_PANEL_TIMING_VACTIVE - 1)
- #else
- # define CONFIG_TP_LOC_Y_MAX (512 - 1)
- #endif
- #define CONFIG_TP_FORECAST_LIMIT 2
- #define TP_ABS(x) (((x) >= 0) ? (x) : -(x))
- //#define CONFIG_DEBUG_TP 1
- #define MAX_CACHE_KEY_NUM 5
- #define COOR_COEF0 1
- #define COOR_COEF1 2
- #define COOR_COEF2 3
- #define COOR_COEF3 10
- /** key action type */
- enum GESTURE_TYPE
- {
- /** gesture drop down */
- GESTURE_DROP_DOWN = 1,
- /** gesture drop up */
- GESTURE_DROP_UP,
- /** gesture drop left */
- GESTURE_DROP_LEFT,
- /** gesture drop right */
- GESTURE_DROP_RIGHT,
- };
- #define COOR_COEF_TOTAL (COOR_COEF0 + COOR_COEF1 + COOR_COEF2 + COOR_COEF3)
- struct acts_tpkey_context {
- struct input_value key_value[MAX_CACHE_KEY_NUM];
- struct input_value next_point;
- uint32_t tp_point_duration;
- uint32_t last_timestamp;
- uint32_t next_timestamp;
- uint8_t key_index;
- uint8_t key_num;
- uint8_t gesture;
- uint8_t fixed_gesture;
- uint8_t gesture_speed;
- };
- static struct acts_tpkey_context key_context;
- static int gesture_fixed(int gesture, int scroll_off_x, int scroll_off_y)
- {
- int fixed_gesture = gesture;
- static const uint8_t fixed_gesture_table[] = {
- 0, GESTURE_DROP_UP, GESTURE_DROP_DOWN,
- GESTURE_DROP_RIGHT, GESTURE_DROP_LEFT,
- };
- if ((gesture == GESTURE_DROP_DOWN && scroll_off_y < -2)
- || (gesture == GESTURE_DROP_UP && scroll_off_y > 2)) {
- fixed_gesture = fixed_gesture_table[gesture];
- }
- if ((gesture == GESTURE_DROP_LEFT && scroll_off_x > 2)
- || (gesture == GESTURE_DROP_RIGHT && scroll_off_x < -2)) {
- fixed_gesture = fixed_gesture_table[gesture];
- }
- key_context.fixed_gesture = fixed_gesture;
- return fixed_gesture;
- }
- static int _tpkey_forecast_next_point(void)
- {
- uint8_t start_index = (key_context.key_index + 1) % MAX_CACHE_KEY_NUM;
- int16_t x_coor_change[MAX_CACHE_KEY_NUM] = {0};
- int16_t y_coor_change[MAX_CACHE_KEY_NUM] = {0};
- //uint16_t x_coor = 0;
- //uint16_t y_coor = 0;
- int i = 0;
- for (i = 0 ; i < key_context.key_num; i++) {
- uint8_t current_index = (start_index + i) % MAX_CACHE_KEY_NUM;
- uint8_t next_index = (start_index + i + 1) % MAX_CACHE_KEY_NUM;
- if (i == 4) {
- x_coor_change[i] = key_context.key_value[current_index].point.loc_x - key_context.key_value[next_index].point.loc_x;
- y_coor_change[i] = key_context.key_value[current_index].point.loc_y - key_context.key_value[next_index].point.loc_y;
- } else {
- x_coor_change[i] = key_context.key_value[next_index].point.loc_x - key_context.key_value[current_index].point.loc_x;
- y_coor_change[i] = key_context.key_value[next_index].point.loc_y - key_context.key_value[current_index].point.loc_y;
- }
- }
- if ((int32_t)x_coor_change[0] * x_coor_change[1] * x_coor_change[2] * x_coor_change[3] > 0) {
- x_coor_change[4] = (x_coor_change[0] * COOR_COEF0 + x_coor_change[1] * COOR_COEF1
- + x_coor_change[2] * COOR_COEF2 + x_coor_change[3] * COOR_COEF3) / COOR_COEF_TOTAL;
- #ifdef CONFIG_DEBUG_TP
- printk("x1 %d x1 %d x1 %d x1 %d COOR_COEF_TOTAL %d \n",x_coor_change[0], x_coor_change[1], x_coor_change[2], x_coor_change[3],COOR_COEF_TOTAL);
- #endif
- } else {
- x_coor_change[4] = x_coor_change[3];
- }
- if ((int32_t)y_coor_change[0] * y_coor_change[1] * y_coor_change[2] * y_coor_change[3] > 0) {
- y_coor_change[4] = (y_coor_change[0] * COOR_COEF0 + y_coor_change[1] * COOR_COEF1
- + y_coor_change[2] * COOR_COEF2 + y_coor_change[3] * COOR_COEF3) / COOR_COEF_TOTAL;
- y_coor_change[4] = (y_coor_change[0] * COOR_COEF0 + y_coor_change[1] * COOR_COEF1
- + y_coor_change[2] * COOR_COEF2 + y_coor_change[3] * COOR_COEF3) / COOR_COEF_TOTAL;
- #ifdef CONFIG_DEBUG_TP
- printk("y1 %d y2 %d y3 %d y4 %d COOR_COEF_TOTAL %d \n",y_coor_change[0], y_coor_change[1],y_coor_change[2], y_coor_change[3],COOR_COEF_TOTAL);
- #endif
- } else {
- y_coor_change[4] = y_coor_change[3];
- }
- #ifdef CONFIG_DEBUG_TP
- printk("gesture %d xcoor %d ycoor %d \n",key_context.key_value[key_context.key_index].point.gesture,abs(x_coor_change[4]), abs(y_coor_change[4]));
- #endif
- if (key_context.gesture && !key_context.fixed_gesture) {
- if (abs(x_coor_change[4]) > abs(y_coor_change[4])
- || key_context.key_value[key_context.key_index].point.loc_x < 50) {
- if (x_coor_change[4] > 0) {
- key_context.fixed_gesture = 4;
- } else {
- key_context.fixed_gesture = 3;
- }
- } else {
- key_context.fixed_gesture = 0;
- }
- }
- #ifdef CONFIG_DEBUG_TP
- printk("fixed_gesture %d\n",key_context.fixed_gesture);
- #endif
- if (key_context.fixed_gesture) {
- key_context.key_value[key_context.key_index].point.gesture = key_context.fixed_gesture;
- }
- key_context.next_point.point.loc_x = key_context.key_value[key_context.key_index].point.loc_x + x_coor_change[4];
- key_context.next_point.point.loc_y = key_context.key_value[key_context.key_index].point.loc_y + y_coor_change[4];
- key_context.next_point.point.gesture = gesture_fixed(key_context.key_value[key_context.key_index].point.gesture, x_coor_change[3], y_coor_change[3]);
- #ifdef CONFIG_DEBUG_TP
- printk(" x :");
- for (i = 0 ; i < key_context.key_num; i++) {
- printk(" %d ",x_coor_change[i]);
- }
- printk("\n");
- printk(" y :");
- for (i = 0 ; i < key_context.key_num; i++) {
- printk(" %d ",y_coor_change[i]);
- }
- printk("\n");
- #endif
- return 0;
- }
- int tpkey_put_point(struct input_value *value, uint32_t timestamp)
- {
- struct input_value *current_value = NULL;
- uint8_t prev_index = key_context.key_index;
- if (!value->point.pessure_value) {
- key_context.gesture = 0;
- key_context.key_num = 0;
- key_context.key_index = 0;
- key_context.fixed_gesture = 0;
- } else {
- #ifdef CONFIG_INPUT_DEV_ACTS_CST820_TP_KEY
- if (key_context.gesture == 0)
- #endif
- key_context.gesture = value->point.gesture;
- if (key_context.gesture == 0)
- key_context.fixed_gesture = 0;
- key_context.key_index++;
- if (key_context.key_index >= MAX_CACHE_KEY_NUM) {
- key_context.key_index = 0;
- }
- }
- current_value = &key_context.key_value[key_context.key_index];
- memcpy(current_value, value, sizeof(struct input_value));
- key_context.key_num++;
- if (key_context.key_num >= MAX_CACHE_KEY_NUM) {
- key_context.key_num = MAX_CACHE_KEY_NUM;
- }
- #ifdef CONFIG_DEBUG_TP
- printk("put gesture = %d,pessure_value = %d local:(%d,%d),index %d num %d duration %d\n"
- ,key_context.gesture,value->point.pessure_value,value->point.loc_x, value->point.loc_y,
- key_context.key_index, key_context.key_num,
- k_cyc_to_us_floor32(timestamp - key_context.last_timestamp));
- #endif
- key_context.tp_point_duration = k_cyc_to_us_floor32(timestamp - key_context.last_timestamp);
- key_context.next_timestamp = timestamp - key_context.last_timestamp;
- key_context.last_timestamp = timestamp;
- key_context.next_timestamp += key_context.last_timestamp;
- if (/*key_context.gesture && */key_context.key_num == MAX_CACHE_KEY_NUM) {
- struct input_value *prev_value = &key_context.key_value[prev_index];
- int diff_x = TP_ABS((int)current_value->point.loc_x - prev_value->point.loc_x);
- int diff_y = TP_ABS((int)current_value->point.loc_y - prev_value->point.loc_y);
- if (diff_x < CONFIG_TP_FORECAST_LIMIT && diff_y < CONFIG_TP_FORECAST_LIMIT) {
- memcpy(&key_context.next_point, current_value, sizeof(*current_value));
- } else {
- _tpkey_forecast_next_point();
- }
- }
- return 0;
- }
- int tpkey_get_last_point(struct input_value *value, uint32_t timestamp)
- {
- struct input_value *current_value = NULL;
- struct input_value *next_value = NULL;
- /* FIXME: add 6ms to compensate the duration between this and the time show on the screen. */
- uint32_t current_duration = k_cyc_to_us_floor32(timestamp - key_context.last_timestamp) + 6000;
- if (current_duration > key_context.tp_point_duration) {
- current_duration = key_context.tp_point_duration;
- }
- current_value = &key_context.key_value[key_context.key_index];
- if (k_cyc_to_us_floor32(timestamp - key_context.last_timestamp) > 20000) {
- memcpy(value, current_value, sizeof(struct input_value));
- goto exit;
- }
- next_value = &key_context.next_point;
- if (key_context.key_num == MAX_CACHE_KEY_NUM) {
- int32_t next_duration = (int32_t)(key_context.tp_point_duration - current_duration);
- if (next_value->point.loc_x != current_value->point.loc_x) {
- value->point.loc_x = (next_value->point.loc_x * (int32_t)current_duration
- + current_value->point.loc_x * next_duration)
- / (int32_t)key_context.tp_point_duration;
- } else {
- value->point.loc_x = current_value->point.loc_x;
- }
- if (next_value->point.loc_y != current_value->point.loc_y) {
- value->point.loc_y = (next_value->point.loc_y * (int32_t)current_duration
- + current_value->point.loc_y * next_duration)
- / (int32_t)key_context.tp_point_duration;
- } else {
- value->point.loc_y = current_value->point.loc_y;
- }
- value->point.gesture = current_value->point.gesture;
- value->point.pessure_value = current_value->point.pessure_value;
- } else {
- memcpy(value, current_value, sizeof(struct input_value));
- #if !CONFIG_AEM_WATCH_SUPPORT
- if (!current_value->point.pessure_value) {
- int32_t next_duration = (int32_t)(key_context.tp_point_duration - current_duration);
- if (next_value->point.loc_x != current_value->point.loc_x) {
- value->point.loc_x = (next_value->point.loc_x * (int32_t)current_duration
- + current_value->point.loc_x * next_duration)
- / (int32_t)key_context.tp_point_duration;
- } else {
- value->point.loc_x = current_value->point.loc_x;
- }
- if (next_value->point.loc_y != current_value->point.loc_y) {
- value->point.loc_y = (next_value->point.loc_y * (int32_t)current_duration
- + current_value->point.loc_y * next_duration)
- / (int32_t)key_context.tp_point_duration;
- } else {
- value->point.loc_y = current_value->point.loc_y;
- }
- }
- #endif
- }
- exit:
- value->point.loc_x = MIN(MAX(value->point.loc_x - CONFIG_TP_LOC_X_MIN, 0), CONFIG_TP_LOC_X_MAX);
- value->point.loc_y = MIN(MAX(value->point.loc_y - CONFIG_TP_LOC_Y_MIN, 0), CONFIG_TP_LOC_Y_MAX);
- #ifdef CONFIG_DEBUG_TP
- printk("duration %d, current(%d %d) next(%d %d) report(%d %d) pessure_value %d\n\n",
- current_duration, current_value->point.loc_x, current_value->point.loc_y,
- next_value->point.loc_x, next_value->point.loc_y,
- value->point.loc_x, value->point.loc_y, value->point.pessure_value);
- #endif
- return 0;
- }
|