touch: goodix: enable TUI using QTS on kalama

Add changes to enable secure touch on goodix through
QTS framework.

Change-Id: I403bd9bc296b40ad97f6a0d066958d48b53d701e
Signed-off-by: Raviteja Tamatam <quic_travitej@quicinc.com>
Этот коммит содержится в:
Raviteja Tamatam
2022-04-06 18:35:12 -07:00
коммит произвёл Gerrit - the friendly Code Review server
родитель 7e0bf2f396
Коммит 0e0d02e94c
5 изменённых файлов: 225 добавлений и 9 удалений

5
Kbuild
Просмотреть файл

@@ -88,6 +88,8 @@ endif
ifeq ($(CONFIG_TOUCHSCREEN_GOODIX_BRL), y)
LINUX_INC += -include $(TOUCH_ROOT)/goodix_berlin_driver/goodix_ts_core.h
LINUX_INC += -include $(TOUCH_ROOT)/qts/qts_core.h
LINUX_INC += -include $(TOUCH_ROOT)/qts/qts_core_common.h
goodix_ts-y := \
./goodix_berlin_driver/goodix_ts_core.o \
@@ -99,7 +101,8 @@ ifeq ($(CONFIG_TOUCHSCREEN_GOODIX_BRL), y)
./goodix_berlin_driver/goodix_ts_gesture.o \
./goodix_berlin_driver/goodix_ts_inspect.o \
./goodix_berlin_driver/goodix_brl_spi.o \
./goodix_berlin_driver/goodix_brl_i2c.o
./goodix_berlin_driver/goodix_brl_i2c.o \
./qts/qts_core.o
obj-$(CONFIG_MSM_TOUCH) += goodix_ts.o
endif

Просмотреть файл

@@ -167,9 +167,12 @@ static int goodix_i2c_probe(struct i2c_client *client,
int ret = 0;
ts_info("goodix i2c probe in");
#ifndef CONFIG_ARCH_QTI_VM
ret = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
if (!ret)
return -EIO;
#endif
/* get ic type */
ret = goodix_get_ic_type(client->dev.of_node);

Просмотреть файл

@@ -35,6 +35,7 @@
static struct drm_panel *active_panel;
static void goodix_panel_notifier_callback(enum panel_event_notifier_tag tag,
struct panel_event_notification *event, void *client_data);
static irqreturn_t goodix_irq_handler(int irq, void *data);
static void goodix_register_for_panel_events(struct device_node *dp,
struct goodix_ts_core *cd)
@@ -1023,6 +1024,7 @@ static int goodix_parse_dt(struct device_node *node,
board_data->iovdd_gpio = r;
}
#ifndef CONFIG_ARCH_QTI_VM
r = of_get_named_gpio(node, "goodix,reset-gpio", 0);
if (r < 0) {
ts_err("invalid reset-gpio in dt: %d", r);
@@ -1045,6 +1047,7 @@ static int goodix_parse_dt(struct device_node *node,
ts_err("invalid irq-flags");
return -EINVAL;
}
#endif
memset(board_data->avdd_name, 0, sizeof(board_data->avdd_name));
r = of_property_read_string(node, "goodix,avdd-name", &name_tmp);
@@ -1294,7 +1297,7 @@ static int goodix_ts_irq_setup(struct goodix_ts_core *core_data)
ts_info("IRQ:%u,flags:%d", core_data->irq, (int)ts_bdata->irq_flags);
ret = devm_request_threaded_irq(&core_data->pdev->dev,
core_data->irq, NULL,
goodix_ts_threadirq_func,
goodix_irq_handler,
ts_bdata->irq_flags | IRQF_ONESHOT,
GOODIX_CORE_DRIVER_NAME,
core_data);
@@ -2012,6 +2015,9 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd)
goto err_finger;
}
}
#ifdef CONFIG_ARCH_QTI_VM
goto skip_goodix_ts_irq_setup;
#endif
/* request irq line */
ret = goodix_ts_irq_setup(cd);
if (ret < 0) {
@@ -2028,6 +2034,10 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd)
cd->fb_notifier.notifier_call = goodix_ts_fb_notifier_callback;
if (fb_register_client(&cd->fb_notifier))
ts_err("Failed to register fb notifier client:%d", ret);
#endif
#ifdef CONFIG_ARCH_QTI_VM
skip_goodix_ts_irq_setup:
#endif
/* create sysfs files */
goodix_ts_sysfs_init(cd);
@@ -2093,6 +2103,10 @@ static int goodix_later_init_thread(void *data)
struct goodix_ts_core *cd = data;
struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
#ifdef CONFIG_ARCH_QTI_VM
goto skip_to_stage2_init;
#endif
/* step 1: read version */
ret = cd->hw_ops->read_version(cd, &cd->fw_version);
if (ret < 0) {
@@ -2142,7 +2156,9 @@ upgrade:
* if not we will send config with interactive mode
*/
goodix_send_ic_config(cd, CONFIG_TYPE_NORMAL);
#ifdef CONFIG_ARCH_QTI_VM
skip_to_stage2_init:
#endif
/* init other resources */
ret = goodix_ts_stage2_init(cd);
if (ret) {
@@ -2250,6 +2266,165 @@ out:
}
#endif
static int goodix_ts_suspend_helper(void *data)
{
struct goodix_ts_core *core_data = data;
return goodix_ts_suspend(core_data);
}
static int goodix_ts_resume_helper(void *data)
{
struct goodix_ts_core *core_data = data;
return goodix_ts_resume(core_data);
}
static int goodix_ts_enable_touch_irq(void *data, bool enable)
{
struct goodix_ts_core *core_data = data;
struct goodix_ts_hw_ops *hw_ops = core_data->hw_ops;
hw_ops->irq_enable(core_data, enable);
return 0;
}
static int goodix_ts_pre_la_tui_enable(void *data)
{
struct goodix_ts_core *core_data = data;
struct goodix_ts_esd *ts_esd = &core_data->ts_esd;
mutex_lock(&core_data->tui_transition_lock);
atomic_set(&ts_esd->esd_on, 0);
return 0;
}
static int goodix_ts_post_la_tui_enable(void *data)
{
struct goodix_ts_core *core_data = data;
goodix_ts_release_connects(core_data);
mutex_unlock(&core_data->tui_transition_lock);
return 0;
}
static int goodix_ts_post_la_tui_disable(void *data)
{
struct goodix_ts_core *core_data = data;
struct goodix_ts_esd *ts_esd = &core_data->ts_esd;
atomic_set(&ts_esd->esd_on, 1);
return 0;
}
static int goodix_ts_post_le_tui_enable(void *data)
{
int ret;
struct goodix_ts_core *cd = data;
struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
ret = hw_ops->read_version(cd, &cd->fw_version);
if (ret) {
ts_err("invalid fw version, abort");
return -EINVAL;
}
ret = hw_ops->get_ic_info(cd, &cd->ic_info);
if (ret) {
ts_err("invalid ic info, abort");
return -EINVAL;
}
return 0;
}
static int goodix_ts_post_le_tui_disable(void *data)
{
struct goodix_ts_core *core_data = data;
goodix_ts_release_connects(core_data);
return 0;
}
static int goodix_ts_get_irq_num(void *data)
{
struct goodix_ts_core *core_data = data;
return core_data->irq;
}
static irqreturn_t goodix_irq_handler(int irq, void *data)
{
struct goodix_ts_core *core_data = data;
if (!mutex_trylock(&core_data->tui_transition_lock))
return IRQ_HANDLED;
goodix_ts_threadirq_func(irq, data);
mutex_unlock(&core_data->tui_transition_lock);
return IRQ_HANDLED;
}
static void goodix_ts_fill_qts_vendor_data(struct qts_vendor_data *qts_vendor_data,
struct goodix_ts_core *core_data)
{
struct goodix_bus_interface *bus_interface;
struct device_node *node;
const char *touch_type;
int rc = 0;
bus_interface = core_data->bus;
node = bus_interface->dev->of_node;
rc = of_property_read_string(node, "goodix,touch-type", &touch_type);
if (rc) {
ts_err("No touch type\n");
return;
}
if (!strcmp(touch_type, "primary"))
qts_vendor_data->client_type = QTS_CLIENT_PRIMARY_TOUCH;
else
qts_vendor_data->client_type = QTS_CLIENT_SECONDARY_TOUCH;
switch (bus_interface->bus_type) {
case GOODIX_BUS_TYPE_I2C:
qts_vendor_data->client = to_i2c_client(bus_interface->dev);
qts_vendor_data->spi = NULL;
qts_vendor_data->bus_type = QTS_BUS_TYPE_I2C;
break;
case GOODIX_BUS_TYPE_SPI:
qts_vendor_data->client = NULL;
qts_vendor_data->spi = to_spi_device(bus_interface->dev);
qts_vendor_data->bus_type = QTS_BUS_TYPE_SPI;
break;
default:
ts_err("Invalid bus type :%d\n",
bus_interface->bus_type);
break;
}
qts_vendor_data->vendor_data = core_data;
qts_vendor_data->schedule_suspend = false;
qts_vendor_data->schedule_resume = false;
qts_vendor_data->qts_vendor_ops.suspend = goodix_ts_suspend_helper;
qts_vendor_data->qts_vendor_ops.resume = goodix_ts_resume_helper;
qts_vendor_data->qts_vendor_ops.enable_touch_irq = goodix_ts_enable_touch_irq;
qts_vendor_data->qts_vendor_ops.get_irq_num = goodix_ts_get_irq_num;
qts_vendor_data->qts_vendor_ops.pre_la_tui_enable = goodix_ts_pre_la_tui_enable;
qts_vendor_data->qts_vendor_ops.post_la_tui_enable = goodix_ts_post_la_tui_enable;
qts_vendor_data->qts_vendor_ops.pre_la_tui_disable = NULL;
qts_vendor_data->qts_vendor_ops.post_la_tui_disable = goodix_ts_post_la_tui_disable;
qts_vendor_data->qts_vendor_ops.pre_le_tui_enable = NULL;
qts_vendor_data->qts_vendor_ops.post_le_tui_enable = goodix_ts_post_le_tui_enable;
qts_vendor_data->qts_vendor_ops.pre_le_tui_disable = NULL;
qts_vendor_data->qts_vendor_ops.post_le_tui_disable = goodix_ts_post_le_tui_disable;
qts_vendor_data->qts_vendor_ops.irq_handler = goodix_irq_handler;
}
/**
* goodix_ts_probe - called by kernel when Goodix touch
* platform driver is added.
@@ -2260,6 +2435,8 @@ static int goodix_ts_probe(struct platform_device *pdev)
struct goodix_bus_interface *bus_interface;
int ret;
struct device_node *node;
bool qts_en = false;
struct qts_vendor_data qts_vendor_data;
ts_info("goodix_ts_probe IN");
@@ -2293,12 +2470,27 @@ static int goodix_ts_probe(struct platform_device *pdev)
return -ENOMEM;
}
core_data->bus = bus_interface;
qts_en = of_property_read_bool(node, "goodix,qts_en");
if (qts_en) {
mutex_init(&core_data->tui_transition_lock);
goodix_ts_fill_qts_vendor_data(&qts_vendor_data, core_data);
ret = qts_client_register(qts_vendor_data);
if (ret) {
pr_err("qts client register failed, rc %d\n", ret);
goto err_out;
}
core_data->qts_en = qts_en;
}
if (IS_ENABLED(CONFIG_OF) && bus_interface->dev->of_node) {
/* parse devicetree property */
ret = goodix_parse_dt(node, &core_data->board_data);
if (ret) {
ts_err("failed parse device info form dts, %d", ret);
return -EINVAL;
ret = -EINVAL;
goto err_out;
}
#if defined(CONFIG_DRM)
of_property_read_string(node, "qcom,touch-environment",
@@ -2306,22 +2498,25 @@ static int goodix_ts_probe(struct platform_device *pdev)
#endif
} else {
ts_err("no valid device tree node found");
return -ENODEV;
ret = -ENODEV;
goto err_out;
}
core_data->hw_ops = goodix_get_hw_ops();
if (!core_data->hw_ops) {
ts_err("hw ops is NULL");
core_module_prob_sate = CORE_MODULE_PROB_FAILED;
return -EINVAL;
ret = -EINVAL;
goto err_out;
}
goodix_core_module_init();
/* touch core layer is a platform driver */
core_data->pdev = pdev;
core_data->bus = bus_interface;
platform_set_drvdata(pdev, core_data);
/* get GPIO resource */
#ifdef CONFIG_ARCH_QTI_VM
goto skip_to_power_gpio_setup;
#endif
ret = goodix_ts_gpio_setup(core_data);
if (ret) {
ts_err("failed init gpio");
@@ -2340,6 +2535,10 @@ static int goodix_ts_probe(struct platform_device *pdev)
goto err_out;
}
#ifdef CONFIG_ARCH_QTI_VM
skip_to_power_gpio_setup:
#endif
/* generic notifier callback */
core_data->ts_notifier.notifier_call = goodix_generic_noti_callback;
goodix_ts_register_notifier(&core_data->ts_notifier);
@@ -2358,6 +2557,7 @@ static int goodix_ts_probe(struct platform_device *pdev)
return 0;
err_out:
devm_kfree(&pdev->dev, core_data);
core_data->init_stage = CORE_INIT_FAIL;
core_module_prob_sate = CORE_MODULE_PROB_FAILED;
ts_err("goodix_ts_core failed, ret:%d", ret);
@@ -2453,7 +2653,11 @@ static void __exit goodix_ts_core_exit(void)
goodix_i2c_bus_exit();
}
#ifdef CONFIG_ARCH_QTI_VM
module_init(goodix_ts_core_init);
#else
late_initcall(goodix_ts_core_init);
#endif
module_exit(goodix_ts_core_exit);
MODULE_DESCRIPTION("Goodix Touchscreen Core Module");

Просмотреть файл

@@ -39,6 +39,9 @@
#include <linux/notifier.h>
#include <linux/fb.h>
#endif
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include "../qts/qts_core_common.h"
#define GOODIX_CORE_DRIVER_NAME "goodix_ts"
#define GOODIX_PEN_DRIVER_NAME "goodix_ts,pen"
@@ -524,6 +527,8 @@ struct goodix_ts_core {
atomic_t delayed_vm_probe_pending;
atomic_t trusted_touch_mode;
#endif
bool qts_en;
struct mutex tui_transition_lock;
};
/* external module structures */

Просмотреть файл

@@ -72,6 +72,7 @@ static int32_t *RawData_FW_CC = NULL;
static struct proc_dir_entry *NVT_proc_selftest_entry = NULL;
static int8_t nvt_mp_test_result_printed = 0;
static uint8_t fw_ver = 0;
unsigned char mpcriteria[PAGE_SIZE]; //novatek-mp-criteria-default
extern void nvt_change_mode(uint8_t mode);
extern uint8_t nvt_get_fw_pipe(void);
@@ -1054,8 +1055,8 @@ return:
static int32_t nvt_selftest_open(struct inode *inode, struct file *file)
{
struct device_node *np = ts->client->dev.of_node;
unsigned char mpcriteria[PAGE_SIZE] = {0}; //novatek-mp-criteria-default
memset(mpcriteria, 0, PAGE_SIZE * sizeof(mpcriteria[0]));
TestResult_Short = 0;
TestResult_Open = 0;
TestResult_FW_Rawdata = 0;