2024-04-28 06:49:01 -07:00
|
|
|
/* tui/stui_inf.c
|
|
|
|
*
|
|
|
|
* Samsung TUI HW Handler driver.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2015 Samsung Electronics
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
|
|
* published by the Free Software Foundation.
|
2024-04-28 06:51:13 -07:00
|
|
|
*/
|
2024-04-28 06:49:01 -07:00
|
|
|
|
|
|
|
#include <linux/atomic.h>
|
|
|
|
#include <linux/delay.h>
|
|
|
|
#include <linux/fb.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/reboot.h>
|
|
|
|
#include <linux/spinlock.h>
|
|
|
|
#include <linux/types.h>
|
|
|
|
#ifdef USE_TEE_CLIENT_API
|
|
|
|
#include <tee_client_api.h>
|
|
|
|
#endif /* USE_TEE_CLIENT_API */
|
|
|
|
#include "stui_inf.h"
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
#define TUI_REE_EXTERNAL_EVENT 42
|
|
|
|
#define SESSION_CANCEL_DELAY 150
|
|
|
|
#define MAX_WAIT_CNT 10
|
2024-04-28 06:49:01 -07:00
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
#define TUIHW_LOG_TAG "tuill_hw"
|
2024-04-28 06:49:01 -07:00
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
static enum tui_version tui_version = TUI_NOPE;
|
2024-04-28 06:49:01 -07:00
|
|
|
static int tui_mode = STUI_MODE_OFF;
|
2024-04-28 06:51:13 -07:00
|
|
|
static int stui_touch_type;
|
2024-04-28 06:49:01 -07:00
|
|
|
static DEFINE_SPINLOCK(tui_lock);
|
|
|
|
|
|
|
|
#ifdef USE_TEE_CLIENT_API
|
|
|
|
static TEEC_UUID uuid = {
|
|
|
|
.timeLow = 0x0,
|
|
|
|
.timeMid = 0x0,
|
|
|
|
.timeHiAndVersion = 0x0,
|
|
|
|
.clockSeqAndNode = {0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x81},
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
#ifdef CONFIG_SAMSUNG_TUI_LOWLEVEL
|
|
|
|
static DEFINE_SPINLOCK(iwdf_lock);
|
2024-04-28 06:49:01 -07:00
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
struct iwd_functions {
|
|
|
|
int (*cancel_session)(void);
|
|
|
|
};
|
2024-04-28 06:49:01 -07:00
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
struct iwd_functions iwdf = {
|
|
|
|
.cancel_session = NULL
|
|
|
|
};
|
2024-04-28 06:49:01 -07:00
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
void register_iwd_functions(struct iwd_functions *f)
|
2024-04-28 06:49:01 -07:00
|
|
|
{
|
|
|
|
unsigned long fls;
|
2024-04-28 06:51:13 -07:00
|
|
|
spin_lock_irqsave(&iwdf_lock, fls);
|
|
|
|
iwdf.cancel_session = f->cancel_session;
|
|
|
|
spin_unlock_irqrestore(&iwdf_lock, fls);
|
2024-04-28 06:49:01 -07:00
|
|
|
}
|
2024-04-28 06:51:13 -07:00
|
|
|
EXPORT_SYMBOL(register_iwd_functions);
|
2024-04-28 06:49:01 -07:00
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
void unregister_iwd_functions(void)
|
2024-04-28 06:49:01 -07:00
|
|
|
{
|
|
|
|
unsigned long fls;
|
2024-04-28 06:51:13 -07:00
|
|
|
spin_lock_irqsave(&iwdf_lock, fls);
|
|
|
|
iwdf.cancel_session = NULL;
|
|
|
|
spin_unlock_irqrestore(&iwdf_lock, fls);
|
2024-04-28 06:49:01 -07:00
|
|
|
}
|
2024-04-28 06:51:13 -07:00
|
|
|
EXPORT_SYMBOL(unregister_iwd_functions);
|
|
|
|
#endif /* CONFIG_SAMSUNG_TUI_LOWLEVEL */
|
2024-04-28 06:49:01 -07:00
|
|
|
|
|
|
|
int stui_get_mode(void)
|
|
|
|
{
|
|
|
|
unsigned long fls;
|
|
|
|
int ret_mode;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&tui_lock, fls);
|
|
|
|
ret_mode = tui_mode;
|
|
|
|
spin_unlock_irqrestore(&tui_lock, fls);
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_debug(TUIHW_LOG_TAG " %s << ret_mode=%#X\n", __func__, ret_mode);
|
2024-04-28 06:49:01 -07:00
|
|
|
return ret_mode;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(stui_get_mode);
|
|
|
|
|
|
|
|
void stui_set_mode(int mode)
|
|
|
|
{
|
|
|
|
unsigned long fls;
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_debug(TUIHW_LOG_TAG " %s >> mode=%#X\n", __func__, mode);
|
2024-04-28 06:49:01 -07:00
|
|
|
spin_lock_irqsave(&tui_lock, fls);
|
|
|
|
tui_mode = mode;
|
|
|
|
spin_unlock_irqrestore(&tui_lock, fls);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(stui_set_mode);
|
|
|
|
|
|
|
|
int stui_set_mask(int mask)
|
|
|
|
{
|
|
|
|
unsigned long fls;
|
|
|
|
int ret_mode;
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_debug(TUIHW_LOG_TAG " %s >> mask=%#X\n", __func__, mask);
|
2024-04-28 06:49:01 -07:00
|
|
|
spin_lock_irqsave(&tui_lock, fls);
|
|
|
|
ret_mode = (tui_mode |= mask);
|
|
|
|
spin_unlock_irqrestore(&tui_lock, fls);
|
|
|
|
return ret_mode;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(stui_set_mask);
|
|
|
|
|
|
|
|
int stui_clear_mask(int mask)
|
|
|
|
{
|
|
|
|
unsigned long fls;
|
|
|
|
int ret_mode;
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_debug(TUIHW_LOG_TAG " %s >> mask=%#X\n", __func__, mask);
|
2024-04-28 06:49:01 -07:00
|
|
|
spin_lock_irqsave(&tui_lock, fls);
|
|
|
|
ret_mode = (tui_mode &= ~mask);
|
|
|
|
spin_unlock_irqrestore(&tui_lock, fls);
|
|
|
|
return ret_mode;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(stui_clear_mask);
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
void stui_set_touch_type(uint32_t type)
|
|
|
|
{
|
|
|
|
stui_touch_type = type;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(stui_set_touch_type);
|
|
|
|
|
|
|
|
int stui_get_touch_type(void)
|
|
|
|
{
|
|
|
|
return stui_touch_type;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(stui_get_touch_type);
|
|
|
|
|
|
|
|
void stui_set_tui_version(enum tui_version version)
|
|
|
|
{
|
|
|
|
tui_version = version;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(stui_set_tui_version);
|
|
|
|
|
|
|
|
enum tui_version stui_get_tui_version(void)
|
|
|
|
{
|
|
|
|
return tui_version;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(stui_get_tui_version);
|
|
|
|
|
2024-04-28 06:49:01 -07:00
|
|
|
#ifdef USE_TEE_CLIENT_API
|
|
|
|
static atomic_t canceling = ATOMIC_INIT(0);
|
|
|
|
int stui_cancel_session(void)
|
|
|
|
{
|
|
|
|
TEEC_Context context;
|
|
|
|
TEEC_Session session;
|
2024-04-28 06:51:13 -07:00
|
|
|
int result = 0;
|
2024-04-28 06:49:01 -07:00
|
|
|
TEEC_Operation operation;
|
|
|
|
int ret = -1;
|
|
|
|
int count = 0;
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_debug(TUIHW_LOG_TAG " %s >>\n", __func__);
|
2024-04-28 06:49:01 -07:00
|
|
|
|
|
|
|
if (!(STUI_MODE_ALL & stui_get_mode())) {
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_debug(TUIHW_LOG_TAG " session cancel is not needed\n");
|
2024-04-28 06:49:01 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
#ifdef CONFIG_SAMSUNG_TUI_LOWLEVEL
|
|
|
|
if (tui_version == TUI_LL) {
|
|
|
|
unsigned long fls;
|
|
|
|
spin_lock_irqsave(&iwdf_lock, fls);
|
|
|
|
if (iwdf.cancel_session != NULL)
|
|
|
|
result = iwdf.cancel_session();
|
|
|
|
spin_unlock_irqrestore(&iwdf_lock, fls);
|
|
|
|
if (result != 0)
|
|
|
|
pr_err(TUIHW_LOG_TAG " iwd_cancel_session returned: 0x%x\n", result);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_SAMSUNG_TUI_LOWLEVEL */
|
|
|
|
|
2024-04-28 06:49:01 -07:00
|
|
|
if (atomic_cmpxchg(&canceling, 0, 1) != 0) {
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_debug(TUIHW_LOG_TAG " already canceling.\n");
|
2024-04-28 06:49:01 -07:00
|
|
|
|
|
|
|
while ((STUI_MODE_ALL & stui_get_mode()) && (count < MAX_WAIT_CNT)) {
|
|
|
|
msleep(SESSION_CANCEL_DELAY);
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
if (STUI_MODE_ALL & stui_get_mode())
|
|
|
|
pr_err(TUIHW_LOG_TAG " session was not cancelled yet\n");
|
|
|
|
else {
|
|
|
|
pr_info(TUIHW_LOG_TAG " session was cancelled successfully\n");
|
2024-04-28 06:49:01 -07:00
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = TEEC_InitializeContext(NULL, &context);
|
|
|
|
if (result != TEEC_SUCCESS) {
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_err(TUIHW_LOG_TAG " TEEC_InitializeContext returned: 0x%x\n", result);
|
2024-04-28 06:49:01 -07:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = TEEC_OpenSession(&context, &session, &uuid, TEEC_LOGIN_PUBLIC, NULL, NULL, NULL);
|
|
|
|
if (result != TEEC_SUCCESS) {
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_err(TUIHW_LOG_TAG " TEEC_OpenSession returned: 0x%x\n", result);
|
2024-04-28 06:49:01 -07:00
|
|
|
goto finalize_context;
|
|
|
|
}
|
|
|
|
|
|
|
|
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
|
|
|
|
|
|
|
|
result = TEEC_InvokeCommand(&session, TUI_REE_EXTERNAL_EVENT, &operation, NULL);
|
|
|
|
if (result != TEEC_SUCCESS) {
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_err(TUIHW_LOG_TAG " TEEC_InvokeCommand returned: 0x%x\n", result);
|
2024-04-28 06:49:01 -07:00
|
|
|
goto close_session;
|
2024-04-28 06:51:13 -07:00
|
|
|
} else
|
|
|
|
pr_debug(TUIHW_LOG_TAG " invoked cancel cmd\n");
|
2024-04-28 06:49:01 -07:00
|
|
|
|
|
|
|
TEEC_CloseSession(&session);
|
|
|
|
TEEC_FinalizeContext(&context);
|
|
|
|
|
|
|
|
while ((STUI_MODE_ALL & stui_get_mode()) && (count < MAX_WAIT_CNT)) {
|
|
|
|
msleep(SESSION_CANCEL_DELAY);
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
if (STUI_MODE_ALL & stui_get_mode())
|
|
|
|
pr_err(TUIHW_LOG_TAG " session was not cancelled yet\n");
|
|
|
|
else {
|
|
|
|
pr_debug(TUIHW_LOG_TAG " session was cancelled successfully\n");
|
2024-04-28 06:49:01 -07:00
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
atomic_set(&canceling, 0);
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
close_session:
|
|
|
|
TEEC_CloseSession(&session);
|
|
|
|
finalize_context:
|
|
|
|
TEEC_FinalizeContext(&context);
|
|
|
|
out:
|
|
|
|
atomic_set(&canceling, 0);
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_err(TUIHW_LOG_TAG " %s << ret=%d, result=0x%x\n", __func__, ret, result);
|
2024-04-28 06:49:01 -07:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#else /* USE_TEE_CLIENT_API */
|
|
|
|
int stui_cancel_session(void)
|
|
|
|
{
|
2024-04-28 06:51:13 -07:00
|
|
|
#ifdef CONFIG_SAMSUNG_TUI_LOWLEVEL
|
|
|
|
int ret = -1;
|
|
|
|
if (tui_version == TUI_LL) {
|
|
|
|
unsigned long fls;
|
2024-04-28 06:49:01 -07:00
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
if (!(STUI_MODE_ALL & stui_get_mode())) {
|
|
|
|
pr_debug(TUIHW_LOG_TAG " session cancel is not needed\n");
|
|
|
|
return 0;
|
2024-04-28 06:49:01 -07:00
|
|
|
}
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
spin_lock_irqsave(&iwdf_lock, fls);
|
|
|
|
if (iwdf.cancel_session != NULL)
|
|
|
|
ret = iwdf.cancel_session();
|
|
|
|
spin_unlock_irqrestore(&iwdf_lock, fls);
|
|
|
|
} else {
|
|
|
|
pr_debug(TUIHW_LOG_TAG " old tui session\n");
|
2024-04-28 06:49:01 -07:00
|
|
|
}
|
|
|
|
return ret;
|
2024-04-28 06:51:13 -07:00
|
|
|
#else /* CONFIG_SAMSUNG_TUI_LOWLEVEL */
|
|
|
|
pr_err(TUIHW_LOG_TAG " %s not supported\n", __func__);
|
|
|
|
return -1;
|
|
|
|
#endif /* CONFIG_SAMSUNG_TUI_LOWLEVEL */
|
2024-04-28 06:49:01 -07:00
|
|
|
}
|
2024-04-28 06:51:13 -07:00
|
|
|
#endif /* USE_TEE_CLIENT_API */
|
|
|
|
EXPORT_SYMBOL(stui_cancel_session);
|
2024-04-28 06:49:01 -07:00
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
static int __init teegris_tui_inf_init(void)
|
2024-04-28 06:49:01 -07:00
|
|
|
{
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_info(TUIHW_LOG_TAG "=============== Running TEEgris TUI Inf ===============");
|
|
|
|
return 0;
|
2024-04-28 06:49:01 -07:00
|
|
|
}
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
static void __exit teegris_tui_inf_exit(void)
|
2024-04-28 06:49:01 -07:00
|
|
|
{
|
2024-04-28 06:51:13 -07:00
|
|
|
pr_info(TUIHW_LOG_TAG "Unloading teegris tui inf module.");
|
2024-04-28 06:49:01 -07:00
|
|
|
}
|
|
|
|
|
2024-04-28 06:51:13 -07:00
|
|
|
module_init(teegris_tui_inf_init);
|
|
|
|
module_exit(teegris_tui_inf_exit);
|
|
|
|
|
|
|
|
MODULE_AUTHOR("TUI Teegris");
|
|
|
|
MODULE_LICENSE("GPL v2");
|
|
|
|
MODULE_DESCRIPTION("TEEGRIS TUI");
|