1419b0af8Sopenharmony_ci/*
2419b0af8Sopenharmony_ci * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3419b0af8Sopenharmony_ci * Decription: tui agent for tui display and interact
4419b0af8Sopenharmony_ci *
5419b0af8Sopenharmony_ci * This software is licensed under the terms of the GNU General Public
6419b0af8Sopenharmony_ci * License version 2, as published by the Free Software Foundation, and
7419b0af8Sopenharmony_ci * may be copied, distributed, and modified under those terms.
8419b0af8Sopenharmony_ci *
9419b0af8Sopenharmony_ci * This program is distributed in the hope that it will be useful,
10419b0af8Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
11419b0af8Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12419b0af8Sopenharmony_ci * GNU General Public License for more details.
13419b0af8Sopenharmony_ci */
14419b0af8Sopenharmony_ci#include "tui.h"
15419b0af8Sopenharmony_ci#include <linux/kthread.h>
16419b0af8Sopenharmony_ci#include <linux/sched.h>
17419b0af8Sopenharmony_ci#if (KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE)
18419b0af8Sopenharmony_ci#include <linux/sched/types.h>
19419b0af8Sopenharmony_ci#include <uapi/linux/sched/types.h>
20419b0af8Sopenharmony_ci#else
21419b0af8Sopenharmony_ci#include <linux/sched/types.h>
22419b0af8Sopenharmony_ci#endif
23419b0af8Sopenharmony_ci#include <linux/sched/rt.h>
24419b0af8Sopenharmony_ci#include <linux/printk.h>
25419b0af8Sopenharmony_ci#include <linux/slab.h>
26419b0af8Sopenharmony_ci#include <linux/spinlock.h>
27419b0af8Sopenharmony_ci#include <linux/debugfs.h>
28419b0af8Sopenharmony_ci#include <linux/string.h>
29419b0af8Sopenharmony_ci#include <linux/kernel.h>
30419b0af8Sopenharmony_ci#include <linux/atomic.h>
31419b0af8Sopenharmony_ci#include <linux/time.h>
32419b0af8Sopenharmony_ci#include <linux/timer.h>
33419b0af8Sopenharmony_ci#include <linux/wait.h>
34419b0af8Sopenharmony_ci#include <linux/version.h>
35419b0af8Sopenharmony_ci#ifndef CONFIG_DMABUF_MM
36419b0af8Sopenharmony_ci#include <linux/ion.h>
37419b0af8Sopenharmony_ci#endif
38419b0af8Sopenharmony_ci#include <linux/cma.h>
39419b0af8Sopenharmony_ci#include <linux/module.h>
40419b0af8Sopenharmony_ci#include <linux/init.h>
41419b0af8Sopenharmony_ci#include <linux/workqueue.h>
42419b0af8Sopenharmony_ci#include <linux/sysfs.h>
43419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_MTK
44419b0af8Sopenharmony_ci#include <linux/sched/task.h>
45419b0af8Sopenharmony_ci#include <linux/uaccess.h>
46419b0af8Sopenharmony_ci#include <linux/scatterlist.h>
47419b0af8Sopenharmony_ci#endif
48419b0af8Sopenharmony_ci/* add for CMA malloc framebuffer */
49419b0af8Sopenharmony_ci#include <linux/of.h>
50419b0af8Sopenharmony_ci#include <linux/of_fdt.h>
51419b0af8Sopenharmony_ci#include <linux/of_reserved_mem.h>
52419b0af8Sopenharmony_ci#include <linux/fs.h>
53419b0af8Sopenharmony_ci#include <linux/mm.h>
54419b0af8Sopenharmony_ci#include <asm/tlbflush.h>
55419b0af8Sopenharmony_ci#include <asm/cacheflush.h>
56419b0af8Sopenharmony_ci#include <linux/kmemleak.h>
57419b0af8Sopenharmony_ci#include <securec.h>
58419b0af8Sopenharmony_ci#include "teek_client_constants.h"
59419b0af8Sopenharmony_ci#include "agent.h"
60419b0af8Sopenharmony_ci#include "mem.h"
61419b0af8Sopenharmony_ci#include "teek_ns_client.h"
62419b0af8Sopenharmony_ci#include "smc_smp.h"
63419b0af8Sopenharmony_ci#include "tc_ns_client.h"
64419b0af8Sopenharmony_ci#include "tc_ns_log.h"
65419b0af8Sopenharmony_ci#include "mailbox_mempool.h"
66419b0af8Sopenharmony_ci#ifndef CONFIG_TEE_TUI_MTK
67419b0af8Sopenharmony_ci#include <platform_include/basicplatform/linux/powerkey_event.h>
68419b0af8Sopenharmony_ci#ifdef CONFIG_DMABUF_MM
69419b0af8Sopenharmony_ci#include <linux/dmabuf/mm_dma_heap.h>
70419b0af8Sopenharmony_ci#else
71419b0af8Sopenharmony_ci#include <linux/ion/mm_ion.h>
72419b0af8Sopenharmony_ci#endif
73419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_DISPLAY_3_0
74419b0af8Sopenharmony_ci#include "dpu_comp_mgr.h"
75419b0af8Sopenharmony_ci#else
76419b0af8Sopenharmony_ci#include <hisi_fb.h>
77419b0af8Sopenharmony_ci#endif
78419b0af8Sopenharmony_ci#endif
79419b0af8Sopenharmony_ci#include "dynamic_ion_mem.h"
80419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_MTK
81419b0af8Sopenharmony_ci#include "teek_client_type.h"
82419b0af8Sopenharmony_ci#include "teek_client_api.h"
83419b0af8Sopenharmony_ci#include <memory_ssmr.h>
84419b0af8Sopenharmony_ci#include <linux/dma-mapping.h>
85419b0af8Sopenharmony_ci#ifdef CONFIG_HW_SECMEM
86419b0af8Sopenharmony_ci#include "secmem_api.h"
87419b0af8Sopenharmony_ci#endif
88419b0af8Sopenharmony_ci#ifdef CONFIG_ITRUSTEE_TRUSTED_UI
89419b0af8Sopenharmony_ci#include <mtk_debug.h>
90419b0af8Sopenharmony_ci#endif
91419b0af8Sopenharmony_ci
92419b0af8Sopenharmony_ci#ifdef CONFIG_HW_COMB_KEY
93419b0af8Sopenharmony_ci#include <huawei_platform/comb_key/power_key_event.h>
94419b0af8Sopenharmony_ci#endif
95419b0af8Sopenharmony_ci
96419b0af8Sopenharmony_ci#ifndef CONFIG_ITRUSTEE_TRUSTED_UI
97419b0af8Sopenharmony_ci#include <lcd_kit_utils.h>
98419b0af8Sopenharmony_cistruct mtk_fb_data_type {
99419b0af8Sopenharmony_ci	bool panel_power_on;
100419b0af8Sopenharmony_ci	struct mtk_panel_info panel_info;
101419b0af8Sopenharmony_ci};
102419b0af8Sopenharmony_ci#endif
103419b0af8Sopenharmony_ci#endif
104419b0af8Sopenharmony_ci#include "internal_functions.h"
105419b0af8Sopenharmony_ci
106419b0af8Sopenharmony_cistatic void tui_poweroff_work_func(struct work_struct *work);
107419b0af8Sopenharmony_cistatic ssize_t tui_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf);
108419b0af8Sopenharmony_cistatic void tui_msg_del(const char *name);
109419b0af8Sopenharmony_cistatic DECLARE_DELAYED_WORK(tui_poweroff_work, tui_poweroff_work_func);
110419b0af8Sopenharmony_cistatic struct kobject *g_tui_kobj = NULL;
111419b0af8Sopenharmony_cistatic struct kobj_attribute tui_attribute =
112419b0af8Sopenharmony_ci	__ATTR(c_state, 0440, tui_status_show, NULL);
113419b0af8Sopenharmony_cistatic struct attribute *attrs[] = {
114419b0af8Sopenharmony_ci	&tui_attribute.attr,
115419b0af8Sopenharmony_ci	NULL,
116419b0af8Sopenharmony_ci};
117419b0af8Sopenharmony_ci
118419b0af8Sopenharmony_cistatic struct attribute_group g_tui_attr_group = {
119419b0af8Sopenharmony_ci	.attrs = attrs,
120419b0af8Sopenharmony_ci};
121419b0af8Sopenharmony_ci
122419b0af8Sopenharmony_ciDEFINE_MUTEX(g_tui_drv_lock);
123419b0af8Sopenharmony_cistatic struct task_struct *g_tui_task  = NULL;
124419b0af8Sopenharmony_cistatic struct tui_ctl_shm *g_tui_ctl   = NULL;
125419b0af8Sopenharmony_cistatic atomic_t g_tui_usage			= ATOMIC_INIT(0);
126419b0af8Sopenharmony_cistatic atomic_t g_tui_state			= ATOMIC_INIT(TUI_STATE_UNUSED);
127419b0af8Sopenharmony_cistatic struct list_head g_tui_drv_head = LIST_HEAD_INIT(g_tui_drv_head);
128419b0af8Sopenharmony_cistatic atomic_t g_tui_attached_device  = ATOMIC_INIT(TUI_PID_CLEAR);
129419b0af8Sopenharmony_cistatic atomic_t g_tui_pid			  = ATOMIC_INIT(TUI_PID_CLEAR);
130419b0af8Sopenharmony_cistatic bool g_normal_load_flag		 = false;
131419b0af8Sopenharmony_ci
132419b0af8Sopenharmony_cistatic spinlock_t g_tui_msg_lock;
133419b0af8Sopenharmony_cistatic struct list_head g_tui_msg_head;
134419b0af8Sopenharmony_cistatic wait_queue_head_t g_tui_state_wq;
135419b0af8Sopenharmony_cistatic int g_tui_state_flag;
136419b0af8Sopenharmony_cistatic wait_queue_head_t g_tui_msg_wq;
137419b0af8Sopenharmony_cistatic int32_t g_tui_msg_flag;
138419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_MTK
139419b0af8Sopenharmony_cistatic struct mtk_fb_data_type *g_dss_fd;
140419b0af8Sopenharmony_ci#elif defined CONFIG_TEE_TUI_DISPLAY_3_0
141419b0af8Sopenharmony_cistatic struct dpu_composer *g_dss_fd;
142419b0af8Sopenharmony_ci#else
143419b0af8Sopenharmony_cistatic struct hisi_fb_data_type *g_dss_fd;
144419b0af8Sopenharmony_ci#endif
145419b0af8Sopenharmony_ci#define TUI_DSS_NAME	   "DSS"
146419b0af8Sopenharmony_ci#define TUI_GPIO_NAME	  "fff0d000.gpio"
147419b0af8Sopenharmony_ci#define TUI_TP_NAME		"tp"
148419b0af8Sopenharmony_ci#define TUI_FP_NAME		"fp"
149419b0af8Sopenharmony_ci
150419b0af8Sopenharmony_ci/* EMUI 11.1 need use the ttf of HarmonyOSHans.ttf */
151419b0af8Sopenharmony_ci#define TTF_NORMAL_BUFF_SIZE (20 * 1024 * 1024)
152419b0af8Sopenharmony_ci
153419b0af8Sopenharmony_ci#ifdef TUI_DAEMON_UID_IN_OH
154419b0af8Sopenharmony_ci#define TTF_NORMAL_FILE_PATH "/system/fonts/HarmonyOS_Sans_SC_Regular.ttf"
155419b0af8Sopenharmony_ci#else
156419b0af8Sopenharmony_ci#define TTF_NORMAL_FILE_PATH "/system/fonts/HarmonyOS_Sans_SC.ttf"
157419b0af8Sopenharmony_ci#endif
158419b0af8Sopenharmony_ci
159419b0af8Sopenharmony_ci/* 2M memory size is 2^21 */
160419b0af8Sopenharmony_ci#define ALIGN_SIZE			  21
161419b0af8Sopenharmony_ci#define ALIGN_M				 (1 << 21)
162419b0af8Sopenharmony_ci#define MAX_SCREEN_RESOLUTION   8192
163419b0af8Sopenharmony_ci#define TP_BASE_VALUE		   10
164419b0af8Sopenharmony_ci
165419b0af8Sopenharmony_ci/* dss and tp couple mode: 0 is init dss and tp; 1 is only init dss; 2 is only init tp */
166419b0af8Sopenharmony_ci#define DSS_TP_COUPLE_MODE	  0
167419b0af8Sopenharmony_ci#define NORMAL_MODE			 0 /* init all driver */
168419b0af8Sopenharmony_ci#define ONLY_INIT_DSS		   1 /* only init dss */
169419b0af8Sopenharmony_ci#define ONLY_INIT_TP			2 /* only init tp */
170419b0af8Sopenharmony_ci
171419b0af8Sopenharmony_ci/*
172419b0af8Sopenharmony_ci * do fp init(disable fp irq) before gpio init in order not response
173419b0af8Sopenharmony_ci * sensor in normal world(when gpio secure status is set)
174419b0af8Sopenharmony_ci */
175419b0af8Sopenharmony_ci#if ONLY_INIT_DSS == DSS_TP_COUPLE_MODE
176419b0af8Sopenharmony_ci#define DRIVER_NUM 1
177419b0af8Sopenharmony_cistatic char *g_init_driver[DRIVER_NUM]   = {TUI_DSS_NAME};
178419b0af8Sopenharmony_cistatic char *g_deinit_driver[DRIVER_NUM] = {TUI_DSS_NAME};
179419b0af8Sopenharmony_ci#endif
180419b0af8Sopenharmony_ci
181419b0af8Sopenharmony_ci#if ONLY_INIT_TP == DSS_TP_COUPLE_MODE
182419b0af8Sopenharmony_ci#define DRIVER_NUM 3
183419b0af8Sopenharmony_cistatic char *g_init_driver[DRIVER_NUM]   = {TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME};
184419b0af8Sopenharmony_cistatic char *g_deinit_driver[DRIVER_NUM] = {TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME};
185419b0af8Sopenharmony_ci#endif
186419b0af8Sopenharmony_ci
187419b0af8Sopenharmony_ci#if NORMAL_MODE == DSS_TP_COUPLE_MODE
188419b0af8Sopenharmony_ci#define DRIVER_NUM 4
189419b0af8Sopenharmony_cistatic char *g_init_driver[DRIVER_NUM]   = {TUI_DSS_NAME, TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME};
190419b0af8Sopenharmony_cistatic char *g_deinit_driver[DRIVER_NUM] = {TUI_DSS_NAME, TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME};
191419b0af8Sopenharmony_ci#endif
192419b0af8Sopenharmony_ci
193419b0af8Sopenharmony_ci#define TIME_OUT_FOWER_ON	100
194419b0af8Sopenharmony_ci#define DOWN_VAL			 22 /* 4M */
195419b0af8Sopenharmony_ci#define UP_VAL			   27 /* 64M */
196419b0af8Sopenharmony_ci#define COLOR_TYPE		   4  /* ARGB */
197419b0af8Sopenharmony_ci#define BUFFER_NUM		   2
198419b0af8Sopenharmony_ci#define UID_MAX_VAL		  1000
199419b0af8Sopenharmony_ci#define HIGH_VALUES		  32
200419b0af8Sopenharmony_ci#define ION_NENTS_FLAG	   1
201419b0af8Sopenharmony_ci#define INVALID_CFG_NAME	 (-2)
202419b0af8Sopenharmony_ci
203419b0af8Sopenharmony_cistatic tui_ion_mem g_tui_display_mem;
204419b0af8Sopenharmony_cistatic tui_ion_mem g_normal_font_mem;
205419b0af8Sopenharmony_ci
206419b0af8Sopenharmony_ciunsigned int get_frame_size(unsigned int num)
207419b0af8Sopenharmony_ci{
208419b0af8Sopenharmony_ci	if (num % ALIGN_M != 0)
209419b0af8Sopenharmony_ci		return (((num >> ALIGN_SIZE) + 1) << ALIGN_SIZE);
210419b0af8Sopenharmony_ci	else
211419b0af8Sopenharmony_ci		return num;
212419b0af8Sopenharmony_ci}
213419b0af8Sopenharmony_ci
214419b0af8Sopenharmony_ciunsigned int get_tui_size(unsigned int num)
215419b0af8Sopenharmony_ci{
216419b0af8Sopenharmony_ci	unsigned int i;
217419b0af8Sopenharmony_ci	for (i = DOWN_VAL; i < UP_VAL; i++)
218419b0af8Sopenharmony_ci		if ((num >> i) == 0)
219419b0af8Sopenharmony_ci			break;
220419b0af8Sopenharmony_ci	return (unsigned int)1 << i;
221419b0af8Sopenharmony_ci}
222419b0af8Sopenharmony_ci
223419b0af8Sopenharmony_ci/*
224419b0af8Sopenharmony_ci * alloc order: 4M-font, framebuffer, 20M-unusualfont
225419b0af8Sopenharmony_ci * 1.4M alloc when boot so from ION_TUI_HEAP_ID
226419b0af8Sopenharmony_ci * 2.20M and frambuffer alloc when tui init so from ION_MISC_HEAP_ID
227419b0af8Sopenharmony_ci */
228419b0af8Sopenharmony_cistatic size_t get_tui_font_file_size(void)
229419b0af8Sopenharmony_ci{
230419b0af8Sopenharmony_ci	int ret;
231419b0af8Sopenharmony_ci	struct kstat ttf_file_stat;
232419b0af8Sopenharmony_ci	mm_segment_t old_fs;
233419b0af8Sopenharmony_ci
234419b0af8Sopenharmony_ci	old_fs = get_fs();
235419b0af8Sopenharmony_ci	set_fs(KERNEL_DS);
236419b0af8Sopenharmony_ci	/* get ttf file size */
237419b0af8Sopenharmony_ci	ret = vfs_stat(TTF_NORMAL_FILE_PATH, &ttf_file_stat);
238419b0af8Sopenharmony_ci	if (ret < 0) {
239419b0af8Sopenharmony_ci		tloge("Failed to get ttf extend file size, ret is %d\n", ret);
240419b0af8Sopenharmony_ci		set_fs(old_fs);
241419b0af8Sopenharmony_ci		return 0;
242419b0af8Sopenharmony_ci	}
243419b0af8Sopenharmony_ci	set_fs(old_fs);
244419b0af8Sopenharmony_ci
245419b0af8Sopenharmony_ci	return ttf_file_stat.size;
246419b0af8Sopenharmony_ci}
247419b0af8Sopenharmony_ci
248419b0af8Sopenharmony_cistatic int check_ion_sg_table(const struct sg_table *sg_table)
249419b0af8Sopenharmony_ci{
250419b0af8Sopenharmony_ci	if (sg_table == NULL) {
251419b0af8Sopenharmony_ci		tloge("invalid sgtable\n");
252419b0af8Sopenharmony_ci		return -1;
253419b0af8Sopenharmony_ci	}
254419b0af8Sopenharmony_ci
255419b0af8Sopenharmony_ci	/* nent must be 1, because ion addr for tui is continuous */
256419b0af8Sopenharmony_ci	if (sg_table->nents != ION_NENTS_FLAG) {
257419b0af8Sopenharmony_ci		tloge("nent is invalid\n");
258419b0af8Sopenharmony_ci		return -1;
259419b0af8Sopenharmony_ci	}
260419b0af8Sopenharmony_ci	return 0;
261419b0af8Sopenharmony_ci}
262419b0af8Sopenharmony_ci
263419b0af8Sopenharmony_cistatic int get_tui_ion_sglist(tui_ion_mem *tui_mem)
264419b0af8Sopenharmony_ci{
265419b0af8Sopenharmony_ci	struct sglist *tmp_tui_sglist = NULL;
266419b0af8Sopenharmony_ci	struct scatterlist *tui_sg = NULL;
267419b0af8Sopenharmony_ci	struct page *tui_page = NULL;
268419b0af8Sopenharmony_ci	uint32_t tui_sglist_size;
269419b0af8Sopenharmony_ci	uint32_t i = 0;
270419b0af8Sopenharmony_ci
271419b0af8Sopenharmony_ci	struct sg_table *tui_ion_sg_table = tui_mem->tui_sg_table;
272419b0af8Sopenharmony_ci	if (check_ion_sg_table(tui_ion_sg_table) != 0)
273419b0af8Sopenharmony_ci		return -1;
274419b0af8Sopenharmony_ci
275419b0af8Sopenharmony_ci	tui_sglist_size = sizeof(struct ion_page_info) * tui_ion_sg_table->nents +
276419b0af8Sopenharmony_ci		sizeof(struct sglist);
277419b0af8Sopenharmony_ci	tmp_tui_sglist = (struct sglist *)mailbox_alloc(tui_sglist_size, MB_FLAG_ZERO);
278419b0af8Sopenharmony_ci	if (tmp_tui_sglist == NULL) {
279419b0af8Sopenharmony_ci		tloge("in %s err: mailbox_alloc failed\n", __func__);
280419b0af8Sopenharmony_ci		return -1;
281419b0af8Sopenharmony_ci	}
282419b0af8Sopenharmony_ci
283419b0af8Sopenharmony_ci	tmp_tui_sglist->sglist_size = (uint64_t)tui_sglist_size;
284419b0af8Sopenharmony_ci	tmp_tui_sglist->ion_size = (uint64_t)tui_mem->len;
285419b0af8Sopenharmony_ci	tmp_tui_sglist->info_length = (uint64_t)tui_ion_sg_table->nents;
286419b0af8Sopenharmony_ci	tui_mem->info_length = (uint64_t)tui_ion_sg_table->nents;
287419b0af8Sopenharmony_ci
288419b0af8Sopenharmony_ci	/* get tui_sg to fetch ion for tui */
289419b0af8Sopenharmony_ci	for_each_sg(tui_ion_sg_table->sgl, tui_sg, tui_ion_sg_table->nents, i) {
290419b0af8Sopenharmony_ci		if (tui_sg == NULL) {
291419b0af8Sopenharmony_ci			tloge("tui sg is NULL");
292419b0af8Sopenharmony_ci			mailbox_free(tmp_tui_sglist);
293419b0af8Sopenharmony_ci			return -1;
294419b0af8Sopenharmony_ci		}
295419b0af8Sopenharmony_ci		tui_page = sg_page(tui_sg);
296419b0af8Sopenharmony_ci		tmp_tui_sglist->page_info[0].phys_addr = page_to_phys(tui_page);
297419b0af8Sopenharmony_ci		tmp_tui_sglist->page_info[0].npages = tui_sg->length / PAGE_SIZE;
298419b0af8Sopenharmony_ci		tui_mem->npages = tmp_tui_sglist->page_info[0].npages;
299419b0af8Sopenharmony_ci		tui_mem->tui_ion_virt_addr = phys_to_virt(tmp_tui_sglist->page_info[0].phys_addr);
300419b0af8Sopenharmony_ci		tui_mem->fb_phys_addr = tmp_tui_sglist->page_info[0].phys_addr;
301419b0af8Sopenharmony_ci	}
302419b0af8Sopenharmony_ci
303419b0af8Sopenharmony_ci	tui_mem->tui_ion_phys_addr = mailbox_virt_to_phys((uintptr_t)(void *)tmp_tui_sglist); // sglist phys-addr
304419b0af8Sopenharmony_ci	if (tui_mem->tui_ion_phys_addr == 0) {
305419b0af8Sopenharmony_ci		tloge("Failed to get tmp_tui_sglist physaddr, configid=%d\n",
306419b0af8Sopenharmony_ci		tui_mem->configid);
307419b0af8Sopenharmony_ci		mailbox_free(tmp_tui_sglist);
308419b0af8Sopenharmony_ci		return -1;
309419b0af8Sopenharmony_ci	}
310419b0af8Sopenharmony_ci	tui_mem->size = tui_sglist_size;
311419b0af8Sopenharmony_ci	return 0;
312419b0af8Sopenharmony_ci}
313419b0af8Sopenharmony_ci
314419b0af8Sopenharmony_cistatic int alloc_ion_mem(tui_ion_mem *tui_mem)
315419b0af8Sopenharmony_ci{
316419b0af8Sopenharmony_ci	struct sg_table *tui_ion_sg_table = NULL;
317419b0af8Sopenharmony_ci	if (tui_mem == NULL) {
318419b0af8Sopenharmony_ci		tloge("bad input params\n");
319419b0af8Sopenharmony_ci		return -1;
320419b0af8Sopenharmony_ci	}
321419b0af8Sopenharmony_ci#ifdef CONFIG_HW_SECMEM
322419b0af8Sopenharmony_ci	tui_ion_sg_table = cma_secmem_alloc(SEC_TUI, tui_mem->len);
323419b0af8Sopenharmony_ci#endif
324419b0af8Sopenharmony_ci#ifndef CONFIG_TEE_TUI_MTK
325419b0af8Sopenharmony_ci	tui_ion_sg_table = mm_secmem_alloc(SEC_TUI, tui_mem->len);
326419b0af8Sopenharmony_ci#endif
327419b0af8Sopenharmony_ci	if (tui_ion_sg_table == NULL) {
328419b0af8Sopenharmony_ci		tloge("failed to get ion page for tui, configid is %d\n", tui_mem->configid);
329419b0af8Sopenharmony_ci		return -1;
330419b0af8Sopenharmony_ci	}
331419b0af8Sopenharmony_ci	tui_mem->tui_sg_table = tui_ion_sg_table;
332419b0af8Sopenharmony_ci	return 0;
333419b0af8Sopenharmony_ci}
334419b0af8Sopenharmony_ci
335419b0af8Sopenharmony_cistatic void free_ion_mem(tui_ion_mem *tui_mem)
336419b0af8Sopenharmony_ci{
337419b0af8Sopenharmony_ci	if (tui_mem->tui_sg_table == NULL || tui_mem->tui_ion_phys_addr == 0) {
338419b0af8Sopenharmony_ci		tloge("bad input params\n");
339419b0af8Sopenharmony_ci		return;
340419b0af8Sopenharmony_ci	}
341419b0af8Sopenharmony_ci#ifdef CONFIG_HW_SECMEM
342419b0af8Sopenharmony_ci	cma_secmem_free(SEC_TUI, tui_mem->tui_sg_table);
343419b0af8Sopenharmony_ci#endif
344419b0af8Sopenharmony_ci#ifndef CONFIG_TEE_TUI_MTK
345419b0af8Sopenharmony_ci	mm_secmem_free(SEC_TUI, tui_mem->tui_sg_table);
346419b0af8Sopenharmony_ci#endif
347419b0af8Sopenharmony_ci	tui_mem->tui_ion_phys_addr = 0;
348419b0af8Sopenharmony_ci	return;
349419b0af8Sopenharmony_ci}
350419b0af8Sopenharmony_ci
351419b0af8Sopenharmony_cistatic void free_tui_font_mem(void)
352419b0af8Sopenharmony_ci{
353419b0af8Sopenharmony_ci	free_ion_mem(&g_normal_font_mem);
354419b0af8Sopenharmony_ci	g_normal_load_flag = false;
355419b0af8Sopenharmony_ci	tloge("normal tui font file freed\n");
356419b0af8Sopenharmony_ci}
357419b0af8Sopenharmony_ci
358419b0af8Sopenharmony_cistatic int get_tui_font_mem(tui_ion_mem *tui_font_mem)
359419b0af8Sopenharmony_ci{
360419b0af8Sopenharmony_ci	int ret;
361419b0af8Sopenharmony_ci
362419b0af8Sopenharmony_ci	ret = alloc_ion_mem(tui_font_mem);
363419b0af8Sopenharmony_ci	if (ret < 0) {
364419b0af8Sopenharmony_ci		tloge("Failed to alloc cma mem for tui font lib\n");
365419b0af8Sopenharmony_ci		return -ENOMEM;
366419b0af8Sopenharmony_ci	}
367419b0af8Sopenharmony_ci
368419b0af8Sopenharmony_ci	return 0;
369419b0af8Sopenharmony_ci}
370419b0af8Sopenharmony_ci
371419b0af8Sopenharmony_ci/* size is calculated dynamically according to the screen resolution */
372419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_DISPLAY_3_0
373419b0af8Sopenharmony_cistatic phys_addr_t get_frame_addr(void)
374419b0af8Sopenharmony_ci{
375419b0af8Sopenharmony_ci	int screen_r;
376419b0af8Sopenharmony_ci	int ret;
377419b0af8Sopenharmony_ci	bool check_params = false;
378419b0af8Sopenharmony_ci	if (g_dss_fd == NULL)
379419b0af8Sopenharmony_ci		return 0;
380419b0af8Sopenharmony_ci
381419b0af8Sopenharmony_ci	check_params = (g_dss_fd->comp.base.xres > MAX_SCREEN_RESOLUTION) ||
382419b0af8Sopenharmony_ci		(g_dss_fd->comp.base.yres > MAX_SCREEN_RESOLUTION);
383419b0af8Sopenharmony_ci	if (check_params) {
384419b0af8Sopenharmony_ci		tloge("Horizontal resolution or Vertical resolution is too large\n");
385419b0af8Sopenharmony_ci		return 0;
386419b0af8Sopenharmony_ci	}
387419b0af8Sopenharmony_ci	screen_r = g_dss_fd->comp.base.xres * g_dss_fd->comp.base.yres * COLOR_TYPE * BUFFER_NUM;
388419b0af8Sopenharmony_ci	g_tui_display_mem.len = get_frame_size(screen_r);
389419b0af8Sopenharmony_ci	ret = alloc_ion_mem(&g_tui_display_mem);
390419b0af8Sopenharmony_ci	if (ret) {
391419b0af8Sopenharmony_ci		tloge("Failed to alloc mem for tui display\n");
392419b0af8Sopenharmony_ci		return 0;
393419b0af8Sopenharmony_ci	}
394419b0af8Sopenharmony_ci
395419b0af8Sopenharmony_ci	if (get_tui_ion_sglist(&g_tui_display_mem)) {
396419b0af8Sopenharmony_ci		tloge("get sglist failed\n");
397419b0af8Sopenharmony_ci		free_ion_mem(&g_tui_display_mem);
398419b0af8Sopenharmony_ci		return 0;
399419b0af8Sopenharmony_ci	}
400419b0af8Sopenharmony_ci
401419b0af8Sopenharmony_ci	return g_tui_display_mem.fb_phys_addr;
402419b0af8Sopenharmony_ci}
403419b0af8Sopenharmony_ci#else
404419b0af8Sopenharmony_cistatic phys_addr_t get_frame_addr(void)
405419b0af8Sopenharmony_ci{
406419b0af8Sopenharmony_ci	int screen_r;
407419b0af8Sopenharmony_ci	int ret;
408419b0af8Sopenharmony_ci	bool check_params = false;
409419b0af8Sopenharmony_ci	if (g_dss_fd == NULL)
410419b0af8Sopenharmony_ci		return 0;
411419b0af8Sopenharmony_ci
412419b0af8Sopenharmony_ci	check_params = (g_dss_fd->panel_info.xres > MAX_SCREEN_RESOLUTION) ||
413419b0af8Sopenharmony_ci		(g_dss_fd->panel_info.yres > MAX_SCREEN_RESOLUTION);
414419b0af8Sopenharmony_ci	if (check_params) {
415419b0af8Sopenharmony_ci		tloge("Horizontal resolution or Vertical resolution is too large\n");
416419b0af8Sopenharmony_ci		return 0;
417419b0af8Sopenharmony_ci	}
418419b0af8Sopenharmony_ci	screen_r = g_dss_fd->panel_info.xres * g_dss_fd->panel_info.yres * COLOR_TYPE * BUFFER_NUM;
419419b0af8Sopenharmony_ci	g_tui_display_mem.len = get_frame_size(screen_r);
420419b0af8Sopenharmony_ci	ret = alloc_ion_mem(&g_tui_display_mem);
421419b0af8Sopenharmony_ci	if (ret != 0) {
422419b0af8Sopenharmony_ci		tloge("Failed to alloc mem for tui display\n");
423419b0af8Sopenharmony_ci		return 0;
424419b0af8Sopenharmony_ci	}
425419b0af8Sopenharmony_ci
426419b0af8Sopenharmony_ci	if (get_tui_ion_sglist(&g_tui_display_mem) != 0) {
427419b0af8Sopenharmony_ci		tloge("get sglist failed\n");
428419b0af8Sopenharmony_ci		free_ion_mem(&g_tui_display_mem);
429419b0af8Sopenharmony_ci		return 0;
430419b0af8Sopenharmony_ci	}
431419b0af8Sopenharmony_ci
432419b0af8Sopenharmony_ci	return g_tui_display_mem.fb_phys_addr;
433419b0af8Sopenharmony_ci}
434419b0af8Sopenharmony_ci#endif
435419b0af8Sopenharmony_ci
436419b0af8Sopenharmony_civoid free_frame_addr(void)
437419b0af8Sopenharmony_ci{
438419b0af8Sopenharmony_ci	mailbox_free(phys_to_virt(g_tui_display_mem.tui_ion_phys_addr));
439419b0af8Sopenharmony_ci	free_ion_mem(&g_tui_display_mem);
440419b0af8Sopenharmony_ci	return;
441419b0af8Sopenharmony_ci}
442419b0af8Sopenharmony_ci
443419b0af8Sopenharmony_cistatic int32_t tc_ns_register_tui_font_mem(tui_ion_mem *tui_font_mem,
444419b0af8Sopenharmony_ci	size_t font_file_size)
445419b0af8Sopenharmony_ci{
446419b0af8Sopenharmony_ci	struct tc_ns_smc_cmd smc_cmd = { {0}, 0};
447419b0af8Sopenharmony_ci	int ret = 0;
448419b0af8Sopenharmony_ci	struct mb_cmd_pack *mb_pack = NULL;
449419b0af8Sopenharmony_ci
450419b0af8Sopenharmony_ci	mb_pack = mailbox_alloc_cmd_pack();
451419b0af8Sopenharmony_ci	if (!mb_pack) {
452419b0af8Sopenharmony_ci		tloge("alloc cmd pack failed\n");
453419b0af8Sopenharmony_ci		return -ENOMEM;
454419b0af8Sopenharmony_ci	}
455419b0af8Sopenharmony_ci
456419b0af8Sopenharmony_ci	smc_cmd.cmd_type = CMD_TYPE_GLOBAL;
457419b0af8Sopenharmony_ci	smc_cmd.cmd_id = GLOBAL_CMD_ID_REGISTER_TTF_MEM;
458419b0af8Sopenharmony_ci
459419b0af8Sopenharmony_ci	mb_pack->operation.paramtypes = teec_param_types(
460419b0af8Sopenharmony_ci		TEEC_MEMREF_TEMP_INPUT,
461419b0af8Sopenharmony_ci		TEEC_VALUE_INPUT,
462419b0af8Sopenharmony_ci		TEEC_NONE,
463419b0af8Sopenharmony_ci		TEEC_NONE
464419b0af8Sopenharmony_ci	);
465419b0af8Sopenharmony_ci
466419b0af8Sopenharmony_ci	mb_pack->operation.params[0].memref.size = (uint32_t)(tui_font_mem->size);
467419b0af8Sopenharmony_ci	mb_pack->operation.params[0].memref.buffer = (uint32_t)(tui_font_mem->tui_ion_phys_addr & 0xFFFFFFFF);
468419b0af8Sopenharmony_ci	mb_pack->operation.buffer_h_addr[0] = tui_font_mem->tui_ion_phys_addr >> HIGH_VALUES;
469419b0af8Sopenharmony_ci	mb_pack->operation.params[1].value.a = font_file_size;
470419b0af8Sopenharmony_ci
471419b0af8Sopenharmony_ci	smc_cmd.operation_phys = (unsigned int)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation);
472419b0af8Sopenharmony_ci	smc_cmd.operation_h_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> HIGH_VALUES;
473419b0af8Sopenharmony_ci	if (tc_ns_smc(&smc_cmd)) {
474419b0af8Sopenharmony_ci		ret = -EPERM;
475419b0af8Sopenharmony_ci		tloge("send ttf mem info failed. ret = 0x%x\n", smc_cmd.ret_val);
476419b0af8Sopenharmony_ci	}
477419b0af8Sopenharmony_ci	mailbox_free(mb_pack);
478419b0af8Sopenharmony_ci
479419b0af8Sopenharmony_ci	return ret;
480419b0af8Sopenharmony_ci}
481419b0af8Sopenharmony_ci
482419b0af8Sopenharmony_cistatic int32_t copy_tui_font_file(size_t font_file_size, const void *font_virt_addr)
483419b0af8Sopenharmony_ci{
484419b0af8Sopenharmony_ci	struct file *filep = NULL;
485419b0af8Sopenharmony_ci	mm_segment_t old_fs;
486419b0af8Sopenharmony_ci	loff_t pos = 0;
487419b0af8Sopenharmony_ci	unsigned int count;
488419b0af8Sopenharmony_ci	int ret = 0;
489419b0af8Sopenharmony_ci
490419b0af8Sopenharmony_ci	if (font_virt_addr == NULL)
491419b0af8Sopenharmony_ci		return -1;
492419b0af8Sopenharmony_ci
493419b0af8Sopenharmony_ci	filep = filp_open(TTF_NORMAL_FILE_PATH, O_RDONLY, 0);
494419b0af8Sopenharmony_ci	if (IS_ERR(filep) || filep == NULL) {
495419b0af8Sopenharmony_ci		tloge("Failed to open ttf file\n");
496419b0af8Sopenharmony_ci		return -1;
497419b0af8Sopenharmony_ci	}
498419b0af8Sopenharmony_ci
499419b0af8Sopenharmony_ci	old_fs = get_fs();
500419b0af8Sopenharmony_ci	set_fs(KERNEL_DS);
501419b0af8Sopenharmony_ci
502419b0af8Sopenharmony_ci	count = (unsigned int)vfs_read(filep, (char __user *)font_virt_addr, font_file_size, &pos);
503419b0af8Sopenharmony_ci
504419b0af8Sopenharmony_ci	if (font_file_size != count) {
505419b0af8Sopenharmony_ci		tloge("read ttf file failed\n");
506419b0af8Sopenharmony_ci		ret = -1;
507419b0af8Sopenharmony_ci	}
508419b0af8Sopenharmony_ci
509419b0af8Sopenharmony_ci	set_fs(old_fs);
510419b0af8Sopenharmony_ci	filp_close(filep, 0);
511419b0af8Sopenharmony_ci	filep = NULL;
512419b0af8Sopenharmony_ci	return ret;
513419b0af8Sopenharmony_ci}
514419b0af8Sopenharmony_ci
515419b0af8Sopenharmony_cistatic int32_t send_ttf_mem(tui_ion_mem *tui_ttf_mem)
516419b0af8Sopenharmony_ci{
517419b0af8Sopenharmony_ci	int ret;
518419b0af8Sopenharmony_ci	size_t tui_font_file_size;
519419b0af8Sopenharmony_ci	bool check_params = false;
520419b0af8Sopenharmony_ci
521419b0af8Sopenharmony_ci	tui_font_file_size = get_tui_font_file_size();
522419b0af8Sopenharmony_ci	check_params = (tui_font_file_size == 0) || (tui_font_file_size > tui_ttf_mem->len);
523419b0af8Sopenharmony_ci	if (check_params) {
524419b0af8Sopenharmony_ci		tloge("Failed to get the tui font file size or the tui_font_file_size is too big\n");
525419b0af8Sopenharmony_ci		return -1;
526419b0af8Sopenharmony_ci	}
527419b0af8Sopenharmony_ci
528419b0af8Sopenharmony_ci	__dma_map_area(tui_ttf_mem->tui_ion_virt_addr, tui_ttf_mem->len, DMA_BIDIRECTIONAL);
529419b0af8Sopenharmony_ci	ret = copy_tui_font_file(tui_font_file_size, tui_ttf_mem->tui_ion_virt_addr);
530419b0af8Sopenharmony_ci	if (ret < 0) {
531419b0af8Sopenharmony_ci		tloge("Failed to do ttf file copy\n");
532419b0af8Sopenharmony_ci		return -1;
533419b0af8Sopenharmony_ci	}
534419b0af8Sopenharmony_ci
535419b0af8Sopenharmony_ci	__dma_map_area(tui_ttf_mem->tui_ion_virt_addr, tui_ttf_mem->len, DMA_BIDIRECTIONAL);
536419b0af8Sopenharmony_ci	__dma_map_area(tui_ttf_mem->tui_ion_virt_addr, tui_ttf_mem->len, DMA_FROM_DEVICE);
537419b0af8Sopenharmony_ci
538419b0af8Sopenharmony_ci	ret = tc_ns_register_tui_font_mem(tui_ttf_mem, tui_font_file_size);
539419b0af8Sopenharmony_ci	if (ret != 0) {
540419b0af8Sopenharmony_ci		tloge("Failed to do ttf file register ret is 0x%x\n", ret);
541419b0af8Sopenharmony_ci		return -1;
542419b0af8Sopenharmony_ci	}
543419b0af8Sopenharmony_ci
544419b0af8Sopenharmony_ci	return 0;
545419b0af8Sopenharmony_ci}
546419b0af8Sopenharmony_ci
547419b0af8Sopenharmony_cistatic int32_t load_tui_font_file(void)
548419b0af8Sopenharmony_ci{
549419b0af8Sopenharmony_ci	int ret = 0;
550419b0af8Sopenharmony_ci	tui_ion_mem *tui_ttf_mem = NULL;
551419b0af8Sopenharmony_ci
552419b0af8Sopenharmony_ci	tloge("====load ttf start =====\n");
553419b0af8Sopenharmony_ci
554419b0af8Sopenharmony_ci	mutex_lock(&g_tui_drv_lock);
555419b0af8Sopenharmony_ci	if (g_normal_load_flag) {
556419b0af8Sopenharmony_ci		tloge("normal tui font file has been loaded\n");
557419b0af8Sopenharmony_ci		mutex_unlock(&g_tui_drv_lock);
558419b0af8Sopenharmony_ci		return 0;
559419b0af8Sopenharmony_ci	}
560419b0af8Sopenharmony_ci
561419b0af8Sopenharmony_ci	g_normal_font_mem.len = TTF_NORMAL_BUFF_SIZE;
562419b0af8Sopenharmony_ci	ret = get_tui_font_mem(&g_normal_font_mem);
563419b0af8Sopenharmony_ci	tui_ttf_mem = &g_normal_font_mem;
564419b0af8Sopenharmony_ci	if (ret != 0) {
565419b0af8Sopenharmony_ci		tloge("Failed to get tui font memory\n");
566419b0af8Sopenharmony_ci		mutex_unlock(&g_tui_drv_lock);
567419b0af8Sopenharmony_ci		return -1;
568419b0af8Sopenharmony_ci	}
569419b0af8Sopenharmony_ci
570419b0af8Sopenharmony_ci	if (get_tui_ion_sglist(tui_ttf_mem) != 0) {
571419b0af8Sopenharmony_ci		tloge("get tui sglist failed\n");
572419b0af8Sopenharmony_ci		free_tui_font_mem();
573419b0af8Sopenharmony_ci		mutex_unlock(&g_tui_drv_lock);
574419b0af8Sopenharmony_ci		return -1;
575419b0af8Sopenharmony_ci	}
576419b0af8Sopenharmony_ci
577419b0af8Sopenharmony_ci	ret = send_ttf_mem(tui_ttf_mem);
578419b0af8Sopenharmony_ci	if (ret != 0) {
579419b0af8Sopenharmony_ci		mailbox_free(phys_to_virt(tui_ttf_mem->tui_ion_phys_addr));
580419b0af8Sopenharmony_ci		free_tui_font_mem();
581419b0af8Sopenharmony_ci		mutex_unlock(&g_tui_drv_lock);
582419b0af8Sopenharmony_ci		return -1;
583419b0af8Sopenharmony_ci	}
584419b0af8Sopenharmony_ci
585419b0af8Sopenharmony_ci	tloge("normal tui font file loaded\n");
586419b0af8Sopenharmony_ci	g_normal_load_flag = true;
587419b0af8Sopenharmony_ci	mutex_unlock(&g_tui_drv_lock);
588419b0af8Sopenharmony_ci
589419b0af8Sopenharmony_ci	mailbox_free(phys_to_virt(tui_ttf_mem->tui_ion_phys_addr));
590419b0af8Sopenharmony_ci	tloge("=====load ttf end=====\n");
591419b0af8Sopenharmony_ci	return ret;
592419b0af8Sopenharmony_ci}
593419b0af8Sopenharmony_ci
594419b0af8Sopenharmony_ciint register_tui_driver(tui_drv_init fun, const char *name,
595419b0af8Sopenharmony_ci	void *pdata)
596419b0af8Sopenharmony_ci{
597419b0af8Sopenharmony_ci	struct tui_drv_node *tui_drv = NULL;
598419b0af8Sopenharmony_ci	struct tui_drv_node *pos = NULL;
599419b0af8Sopenharmony_ci
600419b0af8Sopenharmony_ci	/* Return error if name is invalid */
601419b0af8Sopenharmony_ci	if (name == NULL || fun == NULL) {
602419b0af8Sopenharmony_ci		tloge("name or func is null");
603419b0af8Sopenharmony_ci		return -EINVAL;
604419b0af8Sopenharmony_ci	}
605419b0af8Sopenharmony_ci
606419b0af8Sopenharmony_ci	if (strncmp(name, TUI_DSS_NAME, (size_t)TUI_DRV_NAME_MAX) == 0) {
607419b0af8Sopenharmony_ci		if (pdata == NULL)
608419b0af8Sopenharmony_ci			return -1;
609419b0af8Sopenharmony_ci		else
610419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_MTK
611419b0af8Sopenharmony_ci			g_dss_fd = (struct mtk_fb_data_type *)pdata;
612419b0af8Sopenharmony_ci#elif defined CONFIG_TEE_TUI_DISPLAY_3_0
613419b0af8Sopenharmony_ci			g_dss_fd = (struct dpu_composer *)pdata;
614419b0af8Sopenharmony_ci#else
615419b0af8Sopenharmony_ci			g_dss_fd = (struct hisi_fb_data_type *)pdata;
616419b0af8Sopenharmony_ci#endif
617419b0af8Sopenharmony_ci	}
618419b0af8Sopenharmony_ci
619419b0af8Sopenharmony_ci	if ((strncmp(name, TUI_TP_NAME, (size_t)TUI_DRV_NAME_MAX) == 0) && pdata == NULL)
620419b0af8Sopenharmony_ci		return -1;
621419b0af8Sopenharmony_ci
622419b0af8Sopenharmony_ci	mutex_lock(&g_tui_drv_lock);
623419b0af8Sopenharmony_ci
624419b0af8Sopenharmony_ci	/* name should not have been registered */
625419b0af8Sopenharmony_ci	list_for_each_entry(pos, &g_tui_drv_head, list) {
626419b0af8Sopenharmony_ci		if (!strncmp(pos->name, name, TUI_DRV_NAME_MAX - 1)) {
627419b0af8Sopenharmony_ci			tloge("this drv(%s) have registered\n", name);
628419b0af8Sopenharmony_ci			mutex_unlock(&g_tui_drv_lock);
629419b0af8Sopenharmony_ci			return -EINVAL;
630419b0af8Sopenharmony_ci		}
631419b0af8Sopenharmony_ci	}
632419b0af8Sopenharmony_ci	mutex_unlock(&g_tui_drv_lock);
633419b0af8Sopenharmony_ci
634419b0af8Sopenharmony_ci	/* Alllovate memory for tui_drv */
635419b0af8Sopenharmony_ci	tui_drv = kzalloc(sizeof(struct tui_drv_node), GFP_KERNEL);
636419b0af8Sopenharmony_ci	if (tui_drv == NULL)
637419b0af8Sopenharmony_ci		return -ENOMEM;
638419b0af8Sopenharmony_ci
639419b0af8Sopenharmony_ci	if (memset_s(tui_drv, sizeof(struct tui_drv_node), 0, sizeof(struct tui_drv_node)) != 0) {
640419b0af8Sopenharmony_ci		tloge("tui_drv memset failed");
641419b0af8Sopenharmony_ci		kfree(tui_drv);
642419b0af8Sopenharmony_ci		return -1;
643419b0af8Sopenharmony_ci	}
644419b0af8Sopenharmony_ci	/* Assign content for tui_drv */
645419b0af8Sopenharmony_ci	tui_drv->init_func = fun;
646419b0af8Sopenharmony_ci	tui_drv->pdata = pdata;
647419b0af8Sopenharmony_ci
648419b0af8Sopenharmony_ci	if (strncpy_s(tui_drv->name, TUI_DRV_NAME_MAX, name, TUI_DRV_NAME_MAX - 1) != 0) {
649419b0af8Sopenharmony_ci		tloge("strncpy_s error\n");
650419b0af8Sopenharmony_ci		kfree(tui_drv);
651419b0af8Sopenharmony_ci		return -1;
652419b0af8Sopenharmony_ci	}
653419b0af8Sopenharmony_ci
654419b0af8Sopenharmony_ci	INIT_LIST_HEAD(&tui_drv->list);
655419b0af8Sopenharmony_ci
656419b0af8Sopenharmony_ci	/* link the new tui_drv to the list */
657419b0af8Sopenharmony_ci	mutex_lock(&g_tui_drv_lock);
658419b0af8Sopenharmony_ci	list_add_tail(&tui_drv->list, &g_tui_drv_head);
659419b0af8Sopenharmony_ci	mutex_unlock(&g_tui_drv_lock);
660419b0af8Sopenharmony_ci
661419b0af8Sopenharmony_ci	return 0;
662419b0af8Sopenharmony_ci}
663419b0af8Sopenharmony_ciEXPORT_SYMBOL(register_tui_driver);
664419b0af8Sopenharmony_ci
665419b0af8Sopenharmony_civoid unregister_tui_driver(const char *name)
666419b0af8Sopenharmony_ci{
667419b0af8Sopenharmony_ci	struct tui_drv_node *pos = NULL, *tmp = NULL;
668419b0af8Sopenharmony_ci
669419b0af8Sopenharmony_ci	/* Return error if name is invalid */
670419b0af8Sopenharmony_ci	if (name == NULL) {
671419b0af8Sopenharmony_ci		tloge("name is null");
672419b0af8Sopenharmony_ci		return;
673419b0af8Sopenharmony_ci	}
674419b0af8Sopenharmony_ci
675419b0af8Sopenharmony_ci	mutex_lock(&g_tui_drv_lock);
676419b0af8Sopenharmony_ci	list_for_each_entry_safe(pos, tmp, &g_tui_drv_head, list) {
677419b0af8Sopenharmony_ci		if (!strncmp(pos->name, name, TUI_DRV_NAME_MAX)) {
678419b0af8Sopenharmony_ci			list_del(&pos->list);
679419b0af8Sopenharmony_ci			kfree(pos);
680419b0af8Sopenharmony_ci			break;
681419b0af8Sopenharmony_ci		}
682419b0af8Sopenharmony_ci	}
683419b0af8Sopenharmony_ci	mutex_unlock(&g_tui_drv_lock);
684419b0af8Sopenharmony_ci}
685419b0af8Sopenharmony_ciEXPORT_SYMBOL(unregister_tui_driver);
686419b0af8Sopenharmony_ci
687419b0af8Sopenharmony_cistatic int add_tui_msg(int type, int val, void *data)
688419b0af8Sopenharmony_ci{
689419b0af8Sopenharmony_ci	struct tui_msg_node *tui_msg = NULL;
690419b0af8Sopenharmony_ci	unsigned long flags;
691419b0af8Sopenharmony_ci
692419b0af8Sopenharmony_ci	/* Return error if pdata is invalid */
693419b0af8Sopenharmony_ci	if (data == NULL) {
694419b0af8Sopenharmony_ci		tloge("data is null");
695419b0af8Sopenharmony_ci		return -EINVAL;
696419b0af8Sopenharmony_ci	}
697419b0af8Sopenharmony_ci
698419b0af8Sopenharmony_ci	/* Allocate memory for tui_msg */
699419b0af8Sopenharmony_ci	tui_msg = kzalloc(sizeof(*tui_msg), GFP_KERNEL);
700419b0af8Sopenharmony_ci	if (tui_msg == NULL)
701419b0af8Sopenharmony_ci		return -ENOMEM;
702419b0af8Sopenharmony_ci
703419b0af8Sopenharmony_ci	if (memset_s(tui_msg, sizeof(*tui_msg), 0, sizeof(*tui_msg)) != 0) {
704419b0af8Sopenharmony_ci		tloge("tui_msg memset failed");
705419b0af8Sopenharmony_ci		kfree(tui_msg);
706419b0af8Sopenharmony_ci		return -1;
707419b0af8Sopenharmony_ci	}
708419b0af8Sopenharmony_ci
709419b0af8Sopenharmony_ci	/* Assign the content of tui_msg */
710419b0af8Sopenharmony_ci	tui_msg->type = type;
711419b0af8Sopenharmony_ci	tui_msg->val = val;
712419b0af8Sopenharmony_ci	tui_msg->data = data;
713419b0af8Sopenharmony_ci	INIT_LIST_HEAD(&tui_msg->list);
714419b0af8Sopenharmony_ci
715419b0af8Sopenharmony_ci	/* Link the new tui_msg to the list */
716419b0af8Sopenharmony_ci	spin_lock_irqsave(&g_tui_msg_lock, flags);
717419b0af8Sopenharmony_ci	list_add_tail(&tui_msg->list, &g_tui_msg_head);
718419b0af8Sopenharmony_ci	g_tui_msg_flag = 1;
719419b0af8Sopenharmony_ci	spin_unlock_irqrestore(&g_tui_msg_lock, flags);
720419b0af8Sopenharmony_ci	return 0;
721419b0af8Sopenharmony_ci}
722419b0af8Sopenharmony_ci
723419b0af8Sopenharmony_cistatic int32_t init_each_tui_driver(struct tui_drv_node *pos, int32_t secure)
724419b0af8Sopenharmony_ci{
725419b0af8Sopenharmony_ci	if (secure == 0) {
726419b0af8Sopenharmony_ci		tlogi("drv(%s) state=%d,%d\n", pos->name, secure, pos->state);
727419b0af8Sopenharmony_ci		if (pos->state == 0)
728419b0af8Sopenharmony_ci			return 0;
729419b0af8Sopenharmony_ci		if (pos->init_func(pos->pdata, secure) != 0)
730419b0af8Sopenharmony_ci			pos->state = -1; /* Process init_func() fail */
731419b0af8Sopenharmony_ci
732419b0af8Sopenharmony_ci		/* set secure state will be proceed in tui msg */
733419b0af8Sopenharmony_ci		pos->state = 0;
734419b0af8Sopenharmony_ci	} else {
735419b0af8Sopenharmony_ci		tlogi("init tui drv(%s) state=%d\n", pos->name, secure);
736419b0af8Sopenharmony_ci		/* when init, tp and dss should be async */
737419b0af8Sopenharmony_ci		if (pos->init_func(pos->pdata, secure) != 0) {
738419b0af8Sopenharmony_ci			pos->state = -1;
739419b0af8Sopenharmony_ci			return -1;
740419b0af8Sopenharmony_ci		} else {
741419b0af8Sopenharmony_ci#ifndef CONFIG_TEE_TUI_MTK
742419b0af8Sopenharmony_ci			if (strncmp(TUI_DSS_NAME, pos->name, TUI_DRV_NAME_MAX) != 0)
743419b0af8Sopenharmony_ci#endif
744419b0af8Sopenharmony_ci				pos->state = 1;
745419b0af8Sopenharmony_ci		}
746419b0af8Sopenharmony_ci	}
747419b0af8Sopenharmony_ci	return 0;
748419b0af8Sopenharmony_ci}
749419b0af8Sopenharmony_ci
750419b0af8Sopenharmony_cienum tui_driver_env {
751419b0af8Sopenharmony_ci	UNSECURE_ENV = 0,
752419b0af8Sopenharmony_ci	SECURE_ENV = 1,
753419b0af8Sopenharmony_ci};
754419b0af8Sopenharmony_ci
755419b0af8Sopenharmony_ci#define WAIT_POWER_ON_SLEEP_SPAN 20
756419b0af8Sopenharmony_cistatic int init_tui_dss_msg(const struct tui_drv_node *pos, int secure, int *count)
757419b0af8Sopenharmony_ci{
758419b0af8Sopenharmony_ci	if ((strncmp(TUI_DSS_NAME, pos->name, TUI_DRV_NAME_MAX) == 0) && (secure != 0)) {
759419b0af8Sopenharmony_ci		tloge("init_tui_driver wait power on status---\n");
760419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_DISPLAY_3_0
761419b0af8Sopenharmony_ci		while (!g_dss_fd->comp.power_on && (*count) < TIME_OUT_FOWER_ON) {
762419b0af8Sopenharmony_ci#else
763419b0af8Sopenharmony_ci		while (!g_dss_fd->panel_power_on && (*count) < TIME_OUT_FOWER_ON) {
764419b0af8Sopenharmony_ci#endif
765419b0af8Sopenharmony_ci			(*count)++;
766419b0af8Sopenharmony_ci			msleep(WAIT_POWER_ON_SLEEP_SPAN);
767419b0af8Sopenharmony_ci		}
768419b0af8Sopenharmony_ci		if ((*count) == TIME_OUT_FOWER_ON) {
769419b0af8Sopenharmony_ci			/* Time out. So return error. */
770419b0af8Sopenharmony_ci			tloge("wait status time out\n");
771419b0af8Sopenharmony_ci			return -1;
772419b0af8Sopenharmony_ci		}
773419b0af8Sopenharmony_ci		spin_lock(&g_tui_msg_lock);
774419b0af8Sopenharmony_ci		tui_msg_del(TUI_DSS_NAME);
775419b0af8Sopenharmony_ci		spin_unlock(&g_tui_msg_lock);
776419b0af8Sopenharmony_ci	}
777419b0af8Sopenharmony_ci	return 0;
778419b0af8Sopenharmony_ci}
779419b0af8Sopenharmony_ci
780419b0af8Sopenharmony_cistatic bool is_dss_registered(void)
781419b0af8Sopenharmony_ci{
782419b0af8Sopenharmony_ci	struct tui_drv_node *pos = NULL;
783419b0af8Sopenharmony_ci#if ONLY_INIT_TP == DSS_TP_COUPLE_MODE
784419b0af8Sopenharmony_ci	return true;
785419b0af8Sopenharmony_ci#endif
786419b0af8Sopenharmony_ci	list_for_each_entry(pos, &g_tui_drv_head, list) {
787419b0af8Sopenharmony_ci		if (strncmp(TUI_DSS_NAME, pos->name, TUI_DRV_NAME_MAX) == 0)
788419b0af8Sopenharmony_ci			return true;
789419b0af8Sopenharmony_ci	}
790419b0af8Sopenharmony_ci	return false;
791419b0af8Sopenharmony_ci}
792419b0af8Sopenharmony_ci
793419b0af8Sopenharmony_ci/* WARNING: Too many leading tabs - consider code refactoring */
794419b0af8Sopenharmony_ci/* secure : 0-unsecure, 1-secure */
795419b0af8Sopenharmony_cistatic int init_tui_driver(int secure)
796419b0af8Sopenharmony_ci{
797419b0af8Sopenharmony_ci	struct tui_drv_node *pos = NULL;
798419b0af8Sopenharmony_ci	char *drv_name = NULL;
799419b0af8Sopenharmony_ci	char **drv_array = g_deinit_driver;
800419b0af8Sopenharmony_ci	int count = 0;
801419b0af8Sopenharmony_ci	int i = 0;
802419b0af8Sopenharmony_ci	int ret = 0;
803419b0af8Sopenharmony_ci	if (g_dss_fd == NULL)
804419b0af8Sopenharmony_ci		return -1;
805419b0af8Sopenharmony_ci
806419b0af8Sopenharmony_ci	if (secure != 0)
807419b0af8Sopenharmony_ci		drv_array = g_init_driver;
808419b0af8Sopenharmony_ci
809419b0af8Sopenharmony_ci	while (i < DRIVER_NUM) {
810419b0af8Sopenharmony_ci		drv_name = drv_array[i];
811419b0af8Sopenharmony_ci		i++;
812419b0af8Sopenharmony_ci		mutex_lock(&g_tui_drv_lock);
813419b0af8Sopenharmony_ci
814419b0af8Sopenharmony_ci		if (!is_dss_registered()) {
815419b0af8Sopenharmony_ci			tloge("dss not registered\n");
816419b0af8Sopenharmony_ci			mutex_unlock(&g_tui_drv_lock);
817419b0af8Sopenharmony_ci			return -1;
818419b0af8Sopenharmony_ci		}
819419b0af8Sopenharmony_ci
820419b0af8Sopenharmony_ci		/* Search all the tui_drv in their list */
821419b0af8Sopenharmony_ci		list_for_each_entry(pos, &g_tui_drv_head, list) {
822419b0af8Sopenharmony_ci			if (strncmp(drv_name, pos->name, TUI_DRV_NAME_MAX) != 0)
823419b0af8Sopenharmony_ci				continue;
824419b0af8Sopenharmony_ci
825419b0af8Sopenharmony_ci			if (!strncmp(TUI_TP_NAME, pos->name, TUI_DRV_NAME_MAX)) {
826419b0af8Sopenharmony_ci				/* If the name is "tp", assign pos->pdata to g_tui_ctl */
827419b0af8Sopenharmony_ci				g_tui_ctl->n2s.tp_info = (int)virt_to_phys(pos->pdata);
828419b0af8Sopenharmony_ci				g_tui_ctl->n2s.tp_info_h_addr = virt_to_phys(pos->pdata) >> HIGH_VALUES;
829419b0af8Sopenharmony_ci			}
830419b0af8Sopenharmony_ci			if (pos->init_func == 0)
831419b0af8Sopenharmony_ci				continue;
832419b0af8Sopenharmony_ci
833419b0af8Sopenharmony_ci			ret = init_tui_dss_msg(pos, secure, &count);
834419b0af8Sopenharmony_ci			if (ret != 0) {
835419b0af8Sopenharmony_ci				mutex_unlock(&g_tui_drv_lock);
836419b0af8Sopenharmony_ci				return ret;
837419b0af8Sopenharmony_ci			}
838419b0af8Sopenharmony_ci
839419b0af8Sopenharmony_ci			if (init_each_tui_driver(pos, secure) != 0) {
840419b0af8Sopenharmony_ci				mutex_unlock(&g_tui_drv_lock);
841419b0af8Sopenharmony_ci				return -1;
842419b0af8Sopenharmony_ci			}
843419b0af8Sopenharmony_ci		}
844419b0af8Sopenharmony_ci		mutex_unlock(&g_tui_drv_lock);
845419b0af8Sopenharmony_ci	}
846419b0af8Sopenharmony_ci
847419b0af8Sopenharmony_ci	return 0;
848419b0af8Sopenharmony_ci}
849419b0af8Sopenharmony_ci
850419b0af8Sopenharmony_ci/* Only after all drivers cfg ok or some one failed, it need
851419b0af8Sopenharmony_ci * to add_tui_msg.
852419b0af8Sopenharmony_ci * ret val:  1 - all cfg ok
853419b0af8Sopenharmony_ci *		   0 - cfg is not complete, or have done
854419b0af8Sopenharmony_ci *		  -1 - cfg failed
855419b0af8Sopenharmony_ci *		  -2 - invalid name
856419b0af8Sopenharmony_ci */
857419b0af8Sopenharmony_cistatic int tui_cfg_filter(const char *name, bool ok)
858419b0af8Sopenharmony_ci{
859419b0af8Sopenharmony_ci	struct tui_drv_node *pos = NULL;
860419b0af8Sopenharmony_ci	int find = 0;
861419b0af8Sopenharmony_ci	int lock_flag = 0;
862419b0af8Sopenharmony_ci
863419b0af8Sopenharmony_ci	/* Return error if name is invalid */
864419b0af8Sopenharmony_ci	if (name == NULL) {
865419b0af8Sopenharmony_ci		tloge("name is null");
866419b0af8Sopenharmony_ci		return INVALID_CFG_NAME;
867419b0af8Sopenharmony_ci	}
868419b0af8Sopenharmony_ci
869419b0af8Sopenharmony_ci	/* some drivers may call send_tui_msg_config at the end
870419b0af8Sopenharmony_ci	 * of drv_init_func which had got the lock.
871419b0af8Sopenharmony_ci	 */
872419b0af8Sopenharmony_ci	if (mutex_is_locked(&g_tui_drv_lock))
873419b0af8Sopenharmony_ci		lock_flag = 1;
874419b0af8Sopenharmony_ci	if (!lock_flag)
875419b0af8Sopenharmony_ci		mutex_lock(&g_tui_drv_lock);
876419b0af8Sopenharmony_ci	list_for_each_entry(pos, &g_tui_drv_head, list) {
877419b0af8Sopenharmony_ci		if (strncmp(pos->name, name, TUI_DRV_NAME_MAX) != 0)
878419b0af8Sopenharmony_ci			continue;
879419b0af8Sopenharmony_ci
880419b0af8Sopenharmony_ci		find = 1;
881419b0af8Sopenharmony_ci		if (ok) {
882419b0af8Sopenharmony_ci			pos->state = 1;
883419b0af8Sopenharmony_ci		} else {
884419b0af8Sopenharmony_ci			if (!lock_flag)
885419b0af8Sopenharmony_ci				mutex_unlock(&g_tui_drv_lock);
886419b0af8Sopenharmony_ci			return -1;
887419b0af8Sopenharmony_ci		}
888419b0af8Sopenharmony_ci	}
889419b0af8Sopenharmony_ci	if (!lock_flag)
890419b0af8Sopenharmony_ci		mutex_unlock(&g_tui_drv_lock);
891419b0af8Sopenharmony_ci
892419b0af8Sopenharmony_ci	if (find == 0)
893419b0af8Sopenharmony_ci		return INVALID_CFG_NAME;
894419b0af8Sopenharmony_ci
895419b0af8Sopenharmony_ci	return 1;
896419b0af8Sopenharmony_ci}
897419b0af8Sopenharmony_ci
898419b0af8Sopenharmony_cienum poll_class {
899419b0af8Sopenharmony_ci	CLASS_POLL_CONFIG,
900419b0af8Sopenharmony_ci	CLASS_POLL_RUNNING,
901419b0af8Sopenharmony_ci	CLASS_POLL_COMMON,
902419b0af8Sopenharmony_ci	CLASS_POLL_INVALID
903419b0af8Sopenharmony_ci};
904419b0af8Sopenharmony_ci
905419b0af8Sopenharmony_cistatic enum poll_class tui_poll_class(int event_type)
906419b0af8Sopenharmony_ci{
907419b0af8Sopenharmony_ci	enum poll_class class = CLASS_POLL_INVALID;
908419b0af8Sopenharmony_ci
909419b0af8Sopenharmony_ci	switch (event_type) {
910419b0af8Sopenharmony_ci	case TUI_POLL_CFG_OK:
911419b0af8Sopenharmony_ci	case TUI_POLL_CFG_FAIL:
912419b0af8Sopenharmony_ci	case TUI_POLL_RESUME_TUI:
913419b0af8Sopenharmony_ci		class = CLASS_POLL_CONFIG;
914419b0af8Sopenharmony_ci		break;
915419b0af8Sopenharmony_ci	case TUI_POLL_TP:
916419b0af8Sopenharmony_ci	case TUI_POLL_TICK:
917419b0af8Sopenharmony_ci	case TUI_POLL_DELAYED_WORK:
918419b0af8Sopenharmony_ci		class = CLASS_POLL_RUNNING;
919419b0af8Sopenharmony_ci		break;
920419b0af8Sopenharmony_ci	case TUI_POLL_CANCEL:
921419b0af8Sopenharmony_ci		class = CLASS_POLL_COMMON;
922419b0af8Sopenharmony_ci		break;
923419b0af8Sopenharmony_ci	default:
924419b0af8Sopenharmony_ci		break;
925419b0af8Sopenharmony_ci	}
926419b0af8Sopenharmony_ci	return class;
927419b0af8Sopenharmony_ci}
928419b0af8Sopenharmony_ci
929419b0af8Sopenharmony_ciint send_tui_msg_config(int type, int val, void *data)
930419b0af8Sopenharmony_ci{
931419b0af8Sopenharmony_ci	int ret;
932419b0af8Sopenharmony_ci
933419b0af8Sopenharmony_ci	if (type >= TUI_POLL_MAX || type < 0 || data == NULL) {
934419b0af8Sopenharmony_ci		tloge("invalid tui event type\n");
935419b0af8Sopenharmony_ci		return -EINVAL;
936419b0af8Sopenharmony_ci	}
937419b0af8Sopenharmony_ci
938419b0af8Sopenharmony_ci	/* The g_tui_state should be CONFIG */
939419b0af8Sopenharmony_ci	if (atomic_read(&g_tui_state) != TUI_STATE_CONFIG) {
940419b0af8Sopenharmony_ci		tloge("failed to send tui msg(%s)\n", poll_event_type_name[type]);
941419b0af8Sopenharmony_ci		return -EINVAL;
942419b0af8Sopenharmony_ci	}
943419b0af8Sopenharmony_ci
944419b0af8Sopenharmony_ci	if (tui_poll_class(type) == CLASS_POLL_RUNNING) {
945419b0af8Sopenharmony_ci		tloge("invalid tui event type(%s) in config state\n", poll_event_type_name[type]);
946419b0af8Sopenharmony_ci		return -EINVAL;
947419b0af8Sopenharmony_ci	}
948419b0af8Sopenharmony_ci
949419b0af8Sopenharmony_ci	tlogi("send config event type %s(%s)\n", poll_event_type_name[type], (char *)data);
950419b0af8Sopenharmony_ci
951419b0af8Sopenharmony_ci	if (type == TUI_POLL_CFG_OK || type == TUI_POLL_CFG_FAIL) {
952419b0af8Sopenharmony_ci		int cfg_ret;
953419b0af8Sopenharmony_ci
954419b0af8Sopenharmony_ci		cfg_ret = tui_cfg_filter((const char *)data, TUI_POLL_CFG_OK == type);
955419b0af8Sopenharmony_ci		tlogd("tui driver(%s) cfg ret = %d\n", (char *)data, cfg_ret);
956419b0af8Sopenharmony_ci		if (cfg_ret == INVALID_CFG_NAME) {
957419b0af8Sopenharmony_ci			tloge("tui cfg filter failed, cfg_ret = %d\n", cfg_ret);
958419b0af8Sopenharmony_ci			return -EINVAL;
959419b0af8Sopenharmony_ci		}
960419b0af8Sopenharmony_ci	}
961419b0af8Sopenharmony_ci
962419b0af8Sopenharmony_ci	ret = add_tui_msg(type, val, data);
963419b0af8Sopenharmony_ci	if (ret != 0) {
964419b0af8Sopenharmony_ci		tloge("add tui msg ret=%d\n", ret);
965419b0af8Sopenharmony_ci		return ret;
966419b0af8Sopenharmony_ci	}
967419b0af8Sopenharmony_ci
968419b0af8Sopenharmony_ci	tlogi("add config msg type %s\n", poll_event_type_name[type]);
969419b0af8Sopenharmony_ci
970419b0af8Sopenharmony_ci	/* wake up tui kthread */
971419b0af8Sopenharmony_ci	wake_up(&g_tui_msg_wq);
972419b0af8Sopenharmony_ci
973419b0af8Sopenharmony_ci	return 0;
974419b0af8Sopenharmony_ci}
975419b0af8Sopenharmony_ci
976419b0af8Sopenharmony_ci#define make32(high, low) ((((uint32_t)(high)) << 16) | (uint16_t)(low))
977419b0af8Sopenharmony_ci
978419b0af8Sopenharmony_cistatic bool package_notch_msg(struct mb_cmd_pack *mb_pack, uint8_t **buf_to_tee,
979419b0af8Sopenharmony_ci	struct teec_tui_parameter *tui_param)
980419b0af8Sopenharmony_ci{
981419b0af8Sopenharmony_ci	uint32_t buf_len = sizeof(*tui_param) - sizeof(tui_param->event_type);
982419b0af8Sopenharmony_ci	*buf_to_tee = mailbox_alloc(buf_len, 0);
983419b0af8Sopenharmony_ci	if (*buf_to_tee == NULL) {
984419b0af8Sopenharmony_ci		tloge("failed to alloc memory!\n");
985419b0af8Sopenharmony_ci		return false;
986419b0af8Sopenharmony_ci	}
987419b0af8Sopenharmony_ci	if (memcpy_s(*buf_to_tee, buf_len, &tui_param->value,
988419b0af8Sopenharmony_ci			sizeof(*tui_param) - sizeof(tui_param->event_type)) != EOK) {
989419b0af8Sopenharmony_ci		tloge("copy notch data failed");
990419b0af8Sopenharmony_ci		mailbox_free(*buf_to_tee);
991419b0af8Sopenharmony_ci		return false;
992419b0af8Sopenharmony_ci	}
993419b0af8Sopenharmony_ci	mb_pack->operation.paramtypes =
994419b0af8Sopenharmony_ci		TEE_PARAM_TYPE_VALUE_INPUT |
995419b0af8Sopenharmony_ci		(TEE_PARAM_TYPE_VALUE_INPUT << TEE_PARAM_NUM);
996419b0af8Sopenharmony_ci	mb_pack->operation.params[0].value.a =
997419b0af8Sopenharmony_ci		(uint32_t)mailbox_virt_to_phys((uintptr_t)*buf_to_tee);
998419b0af8Sopenharmony_ci	mb_pack->operation.params[0].value.b =
999419b0af8Sopenharmony_ci		(uint64_t)mailbox_virt_to_phys((uintptr_t)*buf_to_tee) >> ADDR_TRANS_NUM;
1000419b0af8Sopenharmony_ci	mb_pack->operation.params[1].value.a = buf_len;
1001419b0af8Sopenharmony_ci	return true;
1002419b0af8Sopenharmony_ci}
1003419b0af8Sopenharmony_ci
1004419b0af8Sopenharmony_cistatic void package_fold_msg(struct mb_cmd_pack *mb_pack,
1005419b0af8Sopenharmony_ci	const struct teec_tui_parameter *tui_param)
1006419b0af8Sopenharmony_ci{
1007419b0af8Sopenharmony_ci	mb_pack->operation.paramtypes = teec_param_types(TEE_PARAM_TYPE_VALUE_INPUT,
1008419b0af8Sopenharmony_ci		TEE_PARAM_TYPE_VALUE_INPUT,
1009419b0af8Sopenharmony_ci		TEE_PARAM_TYPE_VALUE_INPUT,
1010419b0af8Sopenharmony_ci		TEE_PARAM_TYPE_VALUE_INPUT);
1011419b0af8Sopenharmony_ci	mb_pack->operation.params[0].value.a = tui_param->notch;
1012419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_DISPLAY_3_0
1013419b0af8Sopenharmony_ci	mb_pack->operation.params[0].value.b = make32(g_dss_fd->comp.base.xres, g_dss_fd->comp.base.yres);
1014419b0af8Sopenharmony_ci#else
1015419b0af8Sopenharmony_ci	mb_pack->operation.params[0].value.b = make32(g_dss_fd->panel_info.xres, g_dss_fd->panel_info.yres);
1016419b0af8Sopenharmony_ci#endif
1017419b0af8Sopenharmony_ci	mb_pack->operation.params[1].value.a = tui_param->phy_width;
1018419b0af8Sopenharmony_ci	mb_pack->operation.params[1].value.b = tui_param->phy_height;
1019419b0af8Sopenharmony_ci	mb_pack->operation.params[2].value.a = tui_param->width;
1020419b0af8Sopenharmony_ci	mb_pack->operation.params[2].value.b = tui_param->height;
1021419b0af8Sopenharmony_ci	mb_pack->operation.params[3].value.a = tui_param->fold_state;
1022419b0af8Sopenharmony_ci	mb_pack->operation.params[3].value.b = tui_param->display_state;
1023419b0af8Sopenharmony_ci}
1024419b0af8Sopenharmony_ci
1025419b0af8Sopenharmony_cistatic bool check_uid_valid(uint32_t uid)
1026419b0af8Sopenharmony_ci{
1027419b0af8Sopenharmony_ci#ifdef TUI_DAEMON_UID_IN_OH
1028419b0af8Sopenharmony_ci	return (uid == TUI_DAEMON_UID_IN_OH || uid == 0);
1029419b0af8Sopenharmony_ci#else
1030419b0af8Sopenharmony_ci	return uid <= UID_MAX_VAL;
1031419b0af8Sopenharmony_ci#endif
1032419b0af8Sopenharmony_ci}
1033419b0af8Sopenharmony_ci
1034419b0af8Sopenharmony_cistatic int32_t tui_send_smc_cmd(int32_t event, struct mb_cmd_pack *mb_pack, struct tc_ns_smc_cmd smc_cmd)
1035419b0af8Sopenharmony_ci{
1036419b0af8Sopenharmony_ci	uint32_t uid;
1037419b0af8Sopenharmony_ci	kuid_t kuid;
1038419b0af8Sopenharmony_ci
1039419b0af8Sopenharmony_ci	kuid = current_uid();
1040419b0af8Sopenharmony_ci	uid = kuid.val;
1041419b0af8Sopenharmony_ci
1042419b0af8Sopenharmony_ci	if (check_uid_valid(uid) == false) {
1043419b0af8Sopenharmony_ci		tloge("get invalid uid = %d\n", uid);
1044419b0af8Sopenharmony_ci		return -1;
1045419b0af8Sopenharmony_ci	}
1046419b0af8Sopenharmony_ci
1047419b0af8Sopenharmony_ci	if ((event != TUI_POLL_CANCEL) && (event != TUI_POLL_NOTCH) && (event != TUI_POLL_FOLD)) {
1048419b0af8Sopenharmony_ci		tloge("no permission to send msg\n");
1049419b0af8Sopenharmony_ci		return -1;
1050419b0af8Sopenharmony_ci	}
1051419b0af8Sopenharmony_ci
1052419b0af8Sopenharmony_ci	smc_cmd.cmd_type = CMD_TYPE_GLOBAL;
1053419b0af8Sopenharmony_ci	smc_cmd.operation_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation);
1054419b0af8Sopenharmony_ci	smc_cmd.operation_h_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> HIGH_VALUES;
1055419b0af8Sopenharmony_ci	smc_cmd.agent_id = event;
1056419b0af8Sopenharmony_ci	smc_cmd.uid = uid;
1057419b0af8Sopenharmony_ci	livepatch_down_read_sem();
1058419b0af8Sopenharmony_ci	int32_t ret = tc_ns_smc(&smc_cmd);
1059419b0af8Sopenharmony_ci	livepatch_up_read_sem();
1060419b0af8Sopenharmony_ci	if (ret != 0) {
1061419b0af8Sopenharmony_ci		tloge("tc ns smc fail 0x%x", ret);
1062419b0af8Sopenharmony_ci		return ret;
1063419b0af8Sopenharmony_ci	}
1064419b0af8Sopenharmony_ci
1065419b0af8Sopenharmony_ci	return 0;
1066419b0af8Sopenharmony_ci}
1067419b0af8Sopenharmony_ci
1068419b0af8Sopenharmony_ci/* Send tui event by smc_cmd */
1069419b0af8Sopenharmony_ciint tui_send_event(int event, struct teec_tui_parameter *tui_param)
1070419b0af8Sopenharmony_ci{
1071419b0af8Sopenharmony_ci	int status_temp;
1072419b0af8Sopenharmony_ci	bool check_value = false;
1073419b0af8Sopenharmony_ci	uint8_t *buf_to_tee = NULL;
1074419b0af8Sopenharmony_ci
1075419b0af8Sopenharmony_ci	if (tui_param == NULL)
1076419b0af8Sopenharmony_ci		return -1;
1077419b0af8Sopenharmony_ci
1078419b0af8Sopenharmony_ci	if (event == TUI_POLL_NOTCH) {
1079419b0af8Sopenharmony_ci		check_value = true;
1080419b0af8Sopenharmony_ci	} else {
1081419b0af8Sopenharmony_ci		if (g_dss_fd == NULL)
1082419b0af8Sopenharmony_ci			return -1;
1083419b0af8Sopenharmony_ci
1084419b0af8Sopenharmony_ci		status_temp = atomic_read(&g_tui_state);
1085419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_DISPLAY_3_0
1086419b0af8Sopenharmony_ci		check_value = (status_temp != TUI_STATE_UNUSED && g_dss_fd->comp.power_on) || event == TUI_POLL_FOLD;
1087419b0af8Sopenharmony_ci#else
1088419b0af8Sopenharmony_ci		check_value = (status_temp != TUI_STATE_UNUSED && g_dss_fd->panel_power_on) || event == TUI_POLL_FOLD;
1089419b0af8Sopenharmony_ci#endif
1090419b0af8Sopenharmony_ci	}
1091419b0af8Sopenharmony_ci
1092419b0af8Sopenharmony_ci	if (check_value) {
1093419b0af8Sopenharmony_ci		struct tc_ns_smc_cmd smc_cmd = { {0}, 0 };
1094419b0af8Sopenharmony_ci		struct mb_cmd_pack *mb_pack = NULL;
1095419b0af8Sopenharmony_ci		int ret = 0;
1096419b0af8Sopenharmony_ci
1097419b0af8Sopenharmony_ci		mb_pack = mailbox_alloc_cmd_pack();
1098419b0af8Sopenharmony_ci		if (mb_pack == NULL) {
1099419b0af8Sopenharmony_ci			tloge("alloc cmd pack failed\n");
1100419b0af8Sopenharmony_ci			return -1;
1101419b0af8Sopenharmony_ci		}
1102419b0af8Sopenharmony_ci
1103419b0af8Sopenharmony_ci		switch (event) {
1104419b0af8Sopenharmony_ci		case TUI_POLL_CANCEL:
1105419b0af8Sopenharmony_ci			smc_cmd.cmd_id = GLOBAL_CMD_ID_TUI_EXCEPTION;
1106419b0af8Sopenharmony_ci			break;
1107419b0af8Sopenharmony_ci		case TUI_POLL_NOTCH:
1108419b0af8Sopenharmony_ci			if (!package_notch_msg(mb_pack, &buf_to_tee,
1109419b0af8Sopenharmony_ci				tui_param)) {
1110419b0af8Sopenharmony_ci					mailbox_free(mb_pack);
1111419b0af8Sopenharmony_ci					tloge("package notch msg failed\n");
1112419b0af8Sopenharmony_ci					return -1;
1113419b0af8Sopenharmony_ci			}
1114419b0af8Sopenharmony_ci			smc_cmd.cmd_id = GLOBAL_CMD_ID_TUI_NOTCH;
1115419b0af8Sopenharmony_ci			break;
1116419b0af8Sopenharmony_ci		case TUI_POLL_FOLD:
1117419b0af8Sopenharmony_ci			package_fold_msg(mb_pack, tui_param);
1118419b0af8Sopenharmony_ci			smc_cmd.cmd_id = GLOBAL_CMD_ID_TUI_FOLD;
1119419b0af8Sopenharmony_ci			break;
1120419b0af8Sopenharmony_ci		default:
1121419b0af8Sopenharmony_ci			tloge("invalid event type : %d\n", event);
1122419b0af8Sopenharmony_ci			break;
1123419b0af8Sopenharmony_ci		}
1124419b0af8Sopenharmony_ci
1125419b0af8Sopenharmony_ci		ret = tui_send_smc_cmd(event, mb_pack, smc_cmd);
1126419b0af8Sopenharmony_ci		if (ret != 0)
1127419b0af8Sopenharmony_ci			tloge("tui_send_smc_cmd error 0x%x", ret);
1128419b0af8Sopenharmony_ci
1129419b0af8Sopenharmony_ci		mailbox_free(mb_pack);
1130419b0af8Sopenharmony_ci		if (buf_to_tee != NULL)
1131419b0af8Sopenharmony_ci			mailbox_free(buf_to_tee);
1132419b0af8Sopenharmony_ci		return ret;
1133419b0af8Sopenharmony_ci	} else {
1134419b0af8Sopenharmony_ci		tlogi("tui unused no need send tui event!\n");
1135419b0af8Sopenharmony_ci		return 0;
1136419b0af8Sopenharmony_ci	}
1137419b0af8Sopenharmony_ci}
1138419b0af8Sopenharmony_ci
1139419b0af8Sopenharmony_cistatic void tui_poweroff_work_func(struct work_struct *work)
1140419b0af8Sopenharmony_ci{
1141419b0af8Sopenharmony_ci	struct teec_tui_parameter tui_param = {0};
1142419b0af8Sopenharmony_ci	tui_send_event(TUI_POLL_CANCEL, &tui_param);
1143419b0af8Sopenharmony_ci}
1144419b0af8Sopenharmony_ci
1145419b0af8Sopenharmony_civoid tui_poweroff_work_start(void)
1146419b0af8Sopenharmony_ci{
1147419b0af8Sopenharmony_ci	tlogi("tui_poweroff_work_start----------\n");
1148419b0af8Sopenharmony_ci	if (g_dss_fd == NULL)
1149419b0af8Sopenharmony_ci		return;
1150419b0af8Sopenharmony_ci
1151419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_DISPLAY_3_0
1152419b0af8Sopenharmony_ci		if (atomic_read(&g_tui_state) != TUI_STATE_UNUSED && g_dss_fd->comp.power_on) {
1153419b0af8Sopenharmony_ci#else
1154419b0af8Sopenharmony_ci		if (atomic_read(&g_tui_state) != TUI_STATE_UNUSED && g_dss_fd->panel_power_on) {
1155419b0af8Sopenharmony_ci#endif
1156419b0af8Sopenharmony_ci		tlogi("come in tui_poweroff_work_start state=%d--\n",
1157419b0af8Sopenharmony_ci		atomic_read(&g_tui_state));
1158419b0af8Sopenharmony_ci		queue_work(system_wq, &tui_poweroff_work.work);
1159419b0af8Sopenharmony_ci	}
1160419b0af8Sopenharmony_ci}
1161419b0af8Sopenharmony_ci
1162419b0af8Sopenharmony_cistatic void wait_tui_msg(void)
1163419b0af8Sopenharmony_ci{
1164419b0af8Sopenharmony_ci#ifndef CONFIG_TEE_TUI_MTK
1165419b0af8Sopenharmony_ci	if (wait_event_interruptible(g_tui_msg_wq, g_tui_msg_flag))
1166419b0af8Sopenharmony_ci		tloge("get tui state is interrupted\n");
1167419b0af8Sopenharmony_ci#endif
1168419b0af8Sopenharmony_ci	/* mtk is sync mess, don't need wait */
1169419b0af8Sopenharmony_ci}
1170419b0af8Sopenharmony_ci
1171419b0af8Sopenharmony_cistatic int valid_msg(int msg_type)
1172419b0af8Sopenharmony_ci{
1173419b0af8Sopenharmony_ci	switch (msg_type) {
1174419b0af8Sopenharmony_ci	case TUI_POLL_RESUME_TUI:
1175419b0af8Sopenharmony_ci		if (atomic_read(&g_tui_state) == TUI_STATE_RUNNING)
1176419b0af8Sopenharmony_ci			return 0;
1177419b0af8Sopenharmony_ci		break;
1178419b0af8Sopenharmony_ci	case TUI_POLL_CANCEL:
1179419b0af8Sopenharmony_ci		if (atomic_read(&g_tui_state) == TUI_STATE_UNUSED)
1180419b0af8Sopenharmony_ci			return 0;
1181419b0af8Sopenharmony_ci		break;
1182419b0af8Sopenharmony_ci	default:
1183419b0af8Sopenharmony_ci		break;
1184419b0af8Sopenharmony_ci	}
1185419b0af8Sopenharmony_ci
1186419b0af8Sopenharmony_ci	return 1;
1187419b0af8Sopenharmony_ci}
1188419b0af8Sopenharmony_ci
1189419b0af8Sopenharmony_ci/*
1190419b0af8Sopenharmony_ci * 1: init ok
1191419b0af8Sopenharmony_ci * 0: still do init
1192419b0af8Sopenharmony_ci * -1: init failed
1193419b0af8Sopenharmony_ci */
1194419b0af8Sopenharmony_cistatic int get_cfg_state(const char *name)
1195419b0af8Sopenharmony_ci{
1196419b0af8Sopenharmony_ci	const struct tui_msg_node *tui_msg = NULL;
1197419b0af8Sopenharmony_ci
1198419b0af8Sopenharmony_ci	/* Return error if name is invalid */
1199419b0af8Sopenharmony_ci	if (name == NULL) {
1200419b0af8Sopenharmony_ci		tloge("name is null");
1201419b0af8Sopenharmony_ci		return -1;
1202419b0af8Sopenharmony_ci	}
1203419b0af8Sopenharmony_ci
1204419b0af8Sopenharmony_ci	list_for_each_entry(tui_msg, &g_tui_msg_head, list) {
1205419b0af8Sopenharmony_ci		/* Names match */
1206419b0af8Sopenharmony_ci		if (!strncmp(tui_msg->data, name, TUI_DRV_NAME_MAX)) {
1207419b0af8Sopenharmony_ci			if (TUI_POLL_CFG_OK == tui_msg->type)
1208419b0af8Sopenharmony_ci				return 1;
1209419b0af8Sopenharmony_ci			else if (TUI_POLL_CFG_FAIL == tui_msg->type)
1210419b0af8Sopenharmony_ci				return -1;
1211419b0af8Sopenharmony_ci			else
1212419b0af8Sopenharmony_ci				tloge("other state\n");
1213419b0af8Sopenharmony_ci		}
1214419b0af8Sopenharmony_ci	}
1215419b0af8Sopenharmony_ci
1216419b0af8Sopenharmony_ci	return 0;
1217419b0af8Sopenharmony_ci}
1218419b0af8Sopenharmony_ci
1219419b0af8Sopenharmony_cistatic void tui_msg_del(const char *name)
1220419b0af8Sopenharmony_ci{
1221419b0af8Sopenharmony_ci	struct tui_msg_node *tui_msg = NULL, *tmp = NULL;
1222419b0af8Sopenharmony_ci
1223419b0af8Sopenharmony_ci	/* Return error if name is invalid */
1224419b0af8Sopenharmony_ci	if (name == NULL) {
1225419b0af8Sopenharmony_ci		tloge("name is null");
1226419b0af8Sopenharmony_ci		return;
1227419b0af8Sopenharmony_ci	}
1228419b0af8Sopenharmony_ci
1229419b0af8Sopenharmony_ci	list_for_each_entry_safe(tui_msg, tmp, &g_tui_msg_head, list) {
1230419b0af8Sopenharmony_ci		/* Names match */
1231419b0af8Sopenharmony_ci		if (!strncmp(tui_msg->data, name, TUI_DRV_NAME_MAX)) {
1232419b0af8Sopenharmony_ci			list_del(&tui_msg->list);
1233419b0af8Sopenharmony_ci			kfree(tui_msg);
1234419b0af8Sopenharmony_ci		}
1235419b0af8Sopenharmony_ci	}
1236419b0af8Sopenharmony_ci}
1237419b0af8Sopenharmony_ci#define DSS_CONFIG_INDEX 1
1238419b0af8Sopenharmony_ci#define TP_CONFIG_INDEX  2
1239419b0af8Sopenharmony_ci
1240419b0af8Sopenharmony_cistatic int32_t process_tui_poll_cfg(int32_t type)
1241419b0af8Sopenharmony_ci{
1242419b0af8Sopenharmony_ci	/* pre-process tui poll event if needed */
1243419b0af8Sopenharmony_ci	switch(type) {
1244419b0af8Sopenharmony_ci	case TUI_POLL_CFG_OK:
1245419b0af8Sopenharmony_ci		if (DSS_CONFIG_INDEX == g_tui_ctl->s2n.value) {
1246419b0af8Sopenharmony_ci			phys_addr_t tui_addr_t;
1247419b0af8Sopenharmony_ci			tui_addr_t = get_frame_addr();
1248419b0af8Sopenharmony_ci			if (tui_addr_t == 0)
1249419b0af8Sopenharmony_ci				tloge("get frame addr error\n");
1250419b0af8Sopenharmony_ci
1251419b0af8Sopenharmony_ci			g_tui_ctl->n2s.addr = (unsigned int)tui_addr_t;
1252419b0af8Sopenharmony_ci			g_tui_ctl->n2s.addr_h = tui_addr_t >> HIGH_VALUES;
1253419b0af8Sopenharmony_ci			g_tui_ctl->n2s.npages = g_tui_display_mem.npages;
1254419b0af8Sopenharmony_ci			g_tui_ctl->n2s.info_length = g_tui_display_mem.info_length;
1255419b0af8Sopenharmony_ci			g_tui_ctl->n2s.phy_size = g_tui_display_mem.len;
1256419b0af8Sopenharmony_ci			if (g_tui_ctl->n2s.addr == 0)
1257419b0af8Sopenharmony_ci				return -1;
1258419b0af8Sopenharmony_ci		}
1259419b0af8Sopenharmony_ci		break;
1260419b0af8Sopenharmony_ci	default:
1261419b0af8Sopenharmony_ci		break;
1262419b0af8Sopenharmony_ci	}
1263419b0af8Sopenharmony_ci
1264419b0af8Sopenharmony_ci	return 0;
1265419b0af8Sopenharmony_ci}
1266419b0af8Sopenharmony_ci
1267419b0af8Sopenharmony_cistatic int32_t process_tui_msg_dss(void)
1268419b0af8Sopenharmony_ci{
1269419b0af8Sopenharmony_ci	int32_t type = TUI_POLL_CFG_OK;
1270419b0af8Sopenharmony_ci
1271419b0af8Sopenharmony_ci#if ONLY_INIT_TP != DSS_TP_COUPLE_MODE
1272419b0af8Sopenharmony_ci	/* Wait, until DSS init finishs */
1273419b0af8Sopenharmony_ci	spin_lock(&g_tui_msg_lock);
1274419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_MTK
1275419b0af8Sopenharmony_ci	if (get_cfg_state(TUI_DSS_NAME) == 0) {
1276419b0af8Sopenharmony_ci#else
1277419b0af8Sopenharmony_ci	while (get_cfg_state(TUI_DSS_NAME) == 0) {
1278419b0af8Sopenharmony_ci#endif
1279419b0af8Sopenharmony_ci		tlogi("waiting for dss tui msg\n");
1280419b0af8Sopenharmony_ci		g_tui_msg_flag = 0;
1281419b0af8Sopenharmony_ci		spin_unlock(&g_tui_msg_lock);
1282419b0af8Sopenharmony_ci		wait_tui_msg();
1283419b0af8Sopenharmony_ci		tlogi("get dss init ok tui msg\n");
1284419b0af8Sopenharmony_ci		spin_lock(&g_tui_msg_lock);
1285419b0af8Sopenharmony_ci	}
1286419b0af8Sopenharmony_ci	if (get_cfg_state(TUI_DSS_NAME) == -1) {
1287419b0af8Sopenharmony_ci		tloge("dss init failed\n");
1288419b0af8Sopenharmony_ci		type = TUI_POLL_CFG_FAIL;
1289419b0af8Sopenharmony_ci	}
1290419b0af8Sopenharmony_ci	/* Delete DSS msg from g_tui_msg_head */
1291419b0af8Sopenharmony_ci	tui_msg_del(TUI_DSS_NAME);
1292419b0af8Sopenharmony_ci	spin_unlock(&g_tui_msg_lock);
1293419b0af8Sopenharmony_ci#endif
1294419b0af8Sopenharmony_ci
1295419b0af8Sopenharmony_ci	return type;
1296419b0af8Sopenharmony_ci}
1297419b0af8Sopenharmony_ci
1298419b0af8Sopenharmony_cistatic int32_t process_tui_msg_tp(void)
1299419b0af8Sopenharmony_ci{
1300419b0af8Sopenharmony_ci	int32_t type = 0;
1301419b0af8Sopenharmony_ci
1302419b0af8Sopenharmony_ci	spin_lock(&g_tui_msg_lock);
1303419b0af8Sopenharmony_ci#if ONLY_INIT_DSS != DSS_TP_COUPLE_MODE
1304419b0af8Sopenharmony_ci	while (get_cfg_state(TUI_TP_NAME) == 0) {
1305419b0af8Sopenharmony_ci		tlogi("waiting for tp tui msg\n");
1306419b0af8Sopenharmony_ci		g_tui_msg_flag = 0;
1307419b0af8Sopenharmony_ci		spin_unlock(&g_tui_msg_lock);
1308419b0af8Sopenharmony_ci		wait_tui_msg();
1309419b0af8Sopenharmony_ci		tlogi("get tp init ok tui msg\n");
1310419b0af8Sopenharmony_ci		spin_lock(&g_tui_msg_lock);
1311419b0af8Sopenharmony_ci	}
1312419b0af8Sopenharmony_ci	if (get_cfg_state(TUI_TP_NAME) == -1) {
1313419b0af8Sopenharmony_ci		tloge("tp failed to do init\n");
1314419b0af8Sopenharmony_ci		tui_msg_del(TUI_TP_NAME);
1315419b0af8Sopenharmony_ci		spin_unlock(&g_tui_msg_lock);
1316419b0af8Sopenharmony_ci		return TUI_POLL_CFG_FAIL;
1317419b0af8Sopenharmony_ci	}
1318419b0af8Sopenharmony_ci	tui_msg_del(TUI_TP_NAME);
1319419b0af8Sopenharmony_ci#if defined CONFIG_TEE_TUI_FP
1320419b0af8Sopenharmony_ci	if (init_tui_driver(1) == 0) {
1321419b0af8Sopenharmony_ci		while (get_cfg_state(TUI_GPIO_NAME) == 0 ||
1322419b0af8Sopenharmony_ci			   get_cfg_state(TUI_FP_NAME) == 0) {
1323419b0af8Sopenharmony_ci			tlogd("waiting for gpio/fp tui msg\n");
1324419b0af8Sopenharmony_ci			g_tui_msg_flag = 0;
1325419b0af8Sopenharmony_ci			spin_unlock(&g_tui_msg_lock);
1326419b0af8Sopenharmony_ci			wait_tui_msg();
1327419b0af8Sopenharmony_ci			tlogd("get gpio/fp init ok tui msg\n");
1328419b0af8Sopenharmony_ci			spin_lock(&g_tui_msg_lock);
1329419b0af8Sopenharmony_ci		}
1330419b0af8Sopenharmony_ci		if (get_cfg_state(TUI_GPIO_NAME) == -1 ||
1331419b0af8Sopenharmony_ci			get_cfg_state(TUI_FP_NAME) == -1) {
1332419b0af8Sopenharmony_ci			tloge("one of gpio/fp failed to do init\n");
1333419b0af8Sopenharmony_ci			type = TUI_POLL_CFG_FAIL;
1334419b0af8Sopenharmony_ci		}
1335419b0af8Sopenharmony_ci	}
1336419b0af8Sopenharmony_ci	tui_msg_del(TUI_GPIO_NAME);
1337419b0af8Sopenharmony_ci	tui_msg_del(TUI_FP_NAME);
1338419b0af8Sopenharmony_ci#endif
1339419b0af8Sopenharmony_ci	tlogd("tp/gpio/fp is config result:type = 0x%x\n", type);
1340419b0af8Sopenharmony_ci#endif
1341419b0af8Sopenharmony_ci	spin_unlock(&g_tui_msg_lock);
1342419b0af8Sopenharmony_ci	return type;
1343419b0af8Sopenharmony_ci}
1344419b0af8Sopenharmony_ci
1345419b0af8Sopenharmony_cistatic void process_tui_msg(void)
1346419b0af8Sopenharmony_ci{
1347419b0af8Sopenharmony_ci	int32_t val = 0;
1348419b0af8Sopenharmony_ci	int32_t type = TUI_POLL_CFG_OK;
1349419b0af8Sopenharmony_ci
1350419b0af8Sopenharmony_cifetch_msg:
1351419b0af8Sopenharmony_ci	if (g_tui_ctl->s2n.value == DSS_CONFIG_INDEX)
1352419b0af8Sopenharmony_ci		type = process_tui_msg_dss();
1353419b0af8Sopenharmony_ci	else if (g_tui_ctl->s2n.value == TP_CONFIG_INDEX)
1354419b0af8Sopenharmony_ci		type = process_tui_msg_tp();
1355419b0af8Sopenharmony_ci	else
1356419b0af8Sopenharmony_ci		tloge("wait others dev\n");
1357419b0af8Sopenharmony_ci
1358419b0af8Sopenharmony_ci	val = process_tui_poll_cfg(type);
1359419b0af8Sopenharmony_ci
1360419b0af8Sopenharmony_ci	g_tui_ctl->n2s.event_type = type;
1361419b0af8Sopenharmony_ci	g_tui_ctl->n2s.value = val;
1362419b0af8Sopenharmony_ci
1363419b0af8Sopenharmony_ci	if (!valid_msg(g_tui_ctl->n2s.event_type)) {
1364419b0af8Sopenharmony_ci		tlogi("refetch tui msg\n");
1365419b0af8Sopenharmony_ci		goto fetch_msg;
1366419b0af8Sopenharmony_ci	}
1367419b0af8Sopenharmony_ci}
1368419b0af8Sopenharmony_ci
1369419b0af8Sopenharmony_cistatic int init_tui_agent(void)
1370419b0af8Sopenharmony_ci{
1371419b0af8Sopenharmony_ci	int ret;
1372419b0af8Sopenharmony_ci
1373419b0af8Sopenharmony_ci	ret = tc_ns_register_agent(NULL, TEE_TUI_AGENT_ID, SZ_4K, (void **)(&g_tui_ctl), false);
1374419b0af8Sopenharmony_ci	if (ret != 0) {
1375419b0af8Sopenharmony_ci		tloge("register tui agent failed, ret = 0x%x\n", ret);
1376419b0af8Sopenharmony_ci		g_tui_ctl = NULL;
1377419b0af8Sopenharmony_ci		return -EFAULT;
1378419b0af8Sopenharmony_ci	}
1379419b0af8Sopenharmony_ci
1380419b0af8Sopenharmony_ci	return 0;
1381419b0af8Sopenharmony_ci}
1382419b0af8Sopenharmony_ci
1383419b0af8Sopenharmony_cistatic void exit_tui_agent(void)
1384419b0af8Sopenharmony_ci{
1385419b0af8Sopenharmony_ci	if (tc_ns_unregister_agent(TEE_TUI_AGENT_ID) != 0)
1386419b0af8Sopenharmony_ci		tloge("unregister tui agent failed\n");
1387419b0af8Sopenharmony_ci
1388419b0af8Sopenharmony_ci	g_tui_ctl = NULL;
1389419b0af8Sopenharmony_ci}
1390419b0af8Sopenharmony_ci
1391419b0af8Sopenharmony_cistatic void set_tui_state(int state)
1392419b0af8Sopenharmony_ci{
1393419b0af8Sopenharmony_ci	if (state < TUI_STATE_UNUSED || state > TUI_STATE_ERROR) {
1394419b0af8Sopenharmony_ci		tloge("state=%d is invalid\n", state);
1395419b0af8Sopenharmony_ci		return;
1396419b0af8Sopenharmony_ci	}
1397419b0af8Sopenharmony_ci	if (atomic_read(&g_tui_state) != state) {
1398419b0af8Sopenharmony_ci		atomic_set(&g_tui_state, state);
1399419b0af8Sopenharmony_ci		tloge("set ree tui state is %d, 0: unused, 1:config, 2:running\n", state);
1400419b0af8Sopenharmony_ci		g_tui_state_flag = 1;
1401419b0af8Sopenharmony_ci		wake_up(&g_tui_state_wq);
1402419b0af8Sopenharmony_ci	}
1403419b0af8Sopenharmony_ci}
1404419b0af8Sopenharmony_ci
1405419b0af8Sopenharmony_ciint is_tui_in_use(int pid_value)
1406419b0af8Sopenharmony_ci{
1407419b0af8Sopenharmony_ci	if (pid_value == atomic_read(&g_tui_pid))
1408419b0af8Sopenharmony_ci		return 1;
1409419b0af8Sopenharmony_ci	return 0;
1410419b0af8Sopenharmony_ci}
1411419b0af8Sopenharmony_ci
1412419b0af8Sopenharmony_civoid free_tui_caller_info(void)
1413419b0af8Sopenharmony_ci{
1414419b0af8Sopenharmony_ci	atomic_set(&g_tui_attached_device, TUI_PID_CLEAR);
1415419b0af8Sopenharmony_ci	atomic_set(&g_tui_pid, TUI_PID_CLEAR);
1416419b0af8Sopenharmony_ci}
1417419b0af8Sopenharmony_ci
1418419b0af8Sopenharmony_cistatic int agent_process_work_tui(void)
1419419b0af8Sopenharmony_ci{
1420419b0af8Sopenharmony_ci	struct smc_event_data *event_data = NULL;
1421419b0af8Sopenharmony_ci
1422419b0af8Sopenharmony_ci	event_data = find_event_control(TEE_TUI_AGENT_ID);
1423419b0af8Sopenharmony_ci	if (event_data == NULL || atomic_read(&event_data->agent_ready) == AGENT_CRASHED) {
1424419b0af8Sopenharmony_ci		/* if return, the pending task in S can't be resumed!! */
1425419b0af8Sopenharmony_ci		tloge("tui agent is not exist\n");
1426419b0af8Sopenharmony_ci		put_agent_event(event_data);
1427419b0af8Sopenharmony_ci		return TEEC_ERROR_GENERIC;
1428419b0af8Sopenharmony_ci	}
1429419b0af8Sopenharmony_ci
1430419b0af8Sopenharmony_ci	isb();
1431419b0af8Sopenharmony_ci	wmb();
1432419b0af8Sopenharmony_ci	event_data->ret_flag = 1;
1433419b0af8Sopenharmony_ci	/* Wake up tui agent that will process the command */
1434419b0af8Sopenharmony_ci	wake_up(&event_data->wait_event_wq);
1435419b0af8Sopenharmony_ci
1436419b0af8Sopenharmony_ci	tlogi("agent 0x%x request, goto sleep, pe->run=%d\n",
1437419b0af8Sopenharmony_ci		TEE_TUI_AGENT_ID, atomic_read(&event_data->ca_run));
1438419b0af8Sopenharmony_ci	wait_event(event_data->ca_pending_wq, atomic_read(&event_data->ca_run));
1439419b0af8Sopenharmony_ci	atomic_set(&event_data->ca_run, 0);
1440419b0af8Sopenharmony_ci	put_agent_event(event_data);
1441419b0af8Sopenharmony_ci
1442419b0af8Sopenharmony_ci	return TEEC_SUCCESS;
1443419b0af8Sopenharmony_ci}
1444419b0af8Sopenharmony_ci
1445419b0af8Sopenharmony_civoid do_ns_tui_release(void)
1446419b0af8Sopenharmony_ci{
1447419b0af8Sopenharmony_ci	if (atomic_read(&g_tui_state) != TUI_STATE_UNUSED) {
1448419b0af8Sopenharmony_ci		g_tui_ctl->s2n.command = TUI_CMD_EXIT;
1449419b0af8Sopenharmony_ci		g_tui_ctl->s2n.ret = -1;
1450419b0af8Sopenharmony_ci		tloge("exec tui do_ns_tui_release\n");
1451419b0af8Sopenharmony_ci		if (agent_process_work_tui() != 0)
1452419b0af8Sopenharmony_ci			tloge("wake up tui agent error\n");
1453419b0af8Sopenharmony_ci	}
1454419b0af8Sopenharmony_ci}
1455419b0af8Sopenharmony_ci
1456419b0af8Sopenharmony_cistatic int32_t do_tui_ttf_work(void)
1457419b0af8Sopenharmony_ci{
1458419b0af8Sopenharmony_ci	int ret = 0;
1459419b0af8Sopenharmony_ci	switch (g_tui_ctl->s2n.command) {
1460419b0af8Sopenharmony_ci	case TUI_CMD_LOAD_TTF:
1461419b0af8Sopenharmony_ci		ret = load_tui_font_file();
1462419b0af8Sopenharmony_ci		if (ret == 0) {
1463419b0af8Sopenharmony_ci			tlogi("=======succeed to load ttf\n");
1464419b0af8Sopenharmony_ci			g_tui_ctl->n2s.event_type = TUI_POLL_CFG_OK;
1465419b0af8Sopenharmony_ci		} else {
1466419b0af8Sopenharmony_ci			tloge("Failed to load normal ttf ret is 0x%x\n", ret);
1467419b0af8Sopenharmony_ci			g_tui_ctl->n2s.event_type = TUI_POLL_CFG_FAIL;
1468419b0af8Sopenharmony_ci		}
1469419b0af8Sopenharmony_ci		break;
1470419b0af8Sopenharmony_ci	case TUI_CMD_EXIT:
1471419b0af8Sopenharmony_ci		if (atomic_read(&g_tui_state) != TUI_STATE_UNUSED &&
1472419b0af8Sopenharmony_ci			atomic_dec_and_test(&g_tui_usage)) {
1473419b0af8Sopenharmony_ci			tlogi("tui disable\n");
1474419b0af8Sopenharmony_ci			(void)init_tui_driver(UNSECURE_ENV);
1475419b0af8Sopenharmony_ci			free_frame_addr();
1476419b0af8Sopenharmony_ci			free_tui_font_mem();
1477419b0af8Sopenharmony_ci			free_tui_caller_info();
1478419b0af8Sopenharmony_ci			set_tui_state(TUI_STATE_UNUSED);
1479419b0af8Sopenharmony_ci		}
1480419b0af8Sopenharmony_ci		break;
1481419b0af8Sopenharmony_ci	case TUI_CMD_FREE_TTF_MEM:
1482419b0af8Sopenharmony_ci		free_tui_font_mem();
1483419b0af8Sopenharmony_ci		ret = 0;
1484419b0af8Sopenharmony_ci		break;
1485419b0af8Sopenharmony_ci	default:
1486419b0af8Sopenharmony_ci		ret = -EINVAL;
1487419b0af8Sopenharmony_ci		tloge("get error ttf tui command(0x%x)\n", g_tui_ctl->s2n.command);
1488419b0af8Sopenharmony_ci		break;
1489419b0af8Sopenharmony_ci	}
1490419b0af8Sopenharmony_ci	return ret;
1491419b0af8Sopenharmony_ci}
1492419b0af8Sopenharmony_ci
1493419b0af8Sopenharmony_cistatic void process_tui_enable(void)
1494419b0af8Sopenharmony_ci{
1495419b0af8Sopenharmony_ci	if (atomic_read(&g_tui_state) == TUI_STATE_CONFIG)
1496419b0af8Sopenharmony_ci		return;
1497419b0af8Sopenharmony_ci
1498419b0af8Sopenharmony_ci	tlogi("tui enable\n");
1499419b0af8Sopenharmony_ci	set_tui_state(TUI_STATE_CONFIG);
1500419b0af8Sopenharmony_ci	/* do dss and tp init */
1501419b0af8Sopenharmony_ci	if (init_tui_driver(SECURE_ENV) != 0) {
1502419b0af8Sopenharmony_ci		g_tui_ctl->s2n.ret = -1;
1503419b0af8Sopenharmony_ci		set_tui_state(TUI_STATE_ERROR);
1504419b0af8Sopenharmony_ci		(void)init_tui_driver(UNSECURE_ENV);
1505419b0af8Sopenharmony_ci		free_tui_caller_info();
1506419b0af8Sopenharmony_ci		set_tui_state(TUI_STATE_UNUSED);
1507419b0af8Sopenharmony_ci		return;
1508419b0af8Sopenharmony_ci	}
1509419b0af8Sopenharmony_ci	atomic_inc(&g_tui_usage);
1510419b0af8Sopenharmony_ci}
1511419b0af8Sopenharmony_ci
1512419b0af8Sopenharmony_cistatic void process_tui_disable(void)
1513419b0af8Sopenharmony_ci{
1514419b0af8Sopenharmony_ci	if (atomic_read(&g_tui_state) == TUI_STATE_UNUSED ||
1515419b0af8Sopenharmony_ci		!atomic_dec_and_test(&g_tui_usage))
1516419b0af8Sopenharmony_ci		return;
1517419b0af8Sopenharmony_ci
1518419b0af8Sopenharmony_ci	tlogi("tui disable\n");
1519419b0af8Sopenharmony_ci	(void)init_tui_driver(UNSECURE_ENV);
1520419b0af8Sopenharmony_ci	free_frame_addr();
1521419b0af8Sopenharmony_ci	free_tui_caller_info();
1522419b0af8Sopenharmony_ci	set_tui_state(TUI_STATE_UNUSED);
1523419b0af8Sopenharmony_ci}
1524419b0af8Sopenharmony_ci
1525419b0af8Sopenharmony_cistatic void process_tui_pause(void)
1526419b0af8Sopenharmony_ci{
1527419b0af8Sopenharmony_ci	if (atomic_read(&g_tui_state) == TUI_STATE_UNUSED)
1528419b0af8Sopenharmony_ci		return;
1529419b0af8Sopenharmony_ci
1530419b0af8Sopenharmony_ci	tlogi("tui pause\n");
1531419b0af8Sopenharmony_ci	(void)init_tui_driver(UNSECURE_ENV);
1532419b0af8Sopenharmony_ci	set_tui_state(TUI_STATE_CONFIG);
1533419b0af8Sopenharmony_ci}
1534419b0af8Sopenharmony_ci
1535419b0af8Sopenharmony_cistatic int do_tui_config_work(void)
1536419b0af8Sopenharmony_ci{
1537419b0af8Sopenharmony_ci	int ret = 0;
1538419b0af8Sopenharmony_ci
1539419b0af8Sopenharmony_ci	switch (g_tui_ctl->s2n.command) {
1540419b0af8Sopenharmony_ci	case TUI_CMD_ENABLE:
1541419b0af8Sopenharmony_ci		process_tui_enable();
1542419b0af8Sopenharmony_ci		break;
1543419b0af8Sopenharmony_ci	case TUI_CMD_DISABLE:
1544419b0af8Sopenharmony_ci		process_tui_disable();
1545419b0af8Sopenharmony_ci		break;
1546419b0af8Sopenharmony_ci	case TUI_CMD_PAUSE:
1547419b0af8Sopenharmony_ci		process_tui_pause();
1548419b0af8Sopenharmony_ci		break;
1549419b0af8Sopenharmony_ci	case TUI_CMD_POLL:
1550419b0af8Sopenharmony_ci		process_tui_msg();
1551419b0af8Sopenharmony_ci		break;
1552419b0af8Sopenharmony_ci	case TUI_CMD_DO_SYNC:
1553419b0af8Sopenharmony_ci		tlogd("enable tp irq cmd\n");
1554419b0af8Sopenharmony_ci		break;
1555419b0af8Sopenharmony_ci	case TUI_CMD_SET_STATE:
1556419b0af8Sopenharmony_ci		tlogi("tui set state %d\n", g_tui_ctl->s2n.value);
1557419b0af8Sopenharmony_ci		set_tui_state(g_tui_ctl->s2n.value);
1558419b0af8Sopenharmony_ci		break;
1559419b0af8Sopenharmony_ci	case TUI_CMD_START_DELAY_WORK:
1560419b0af8Sopenharmony_ci		tlogd("start delay work\n");
1561419b0af8Sopenharmony_ci		break;
1562419b0af8Sopenharmony_ci	case TUI_CMD_CANCEL_DELAY_WORK:
1563419b0af8Sopenharmony_ci		tlogd("cancel delay work\n");
1564419b0af8Sopenharmony_ci		break;
1565419b0af8Sopenharmony_ci	default:
1566419b0af8Sopenharmony_ci		ret = -EINVAL;
1567419b0af8Sopenharmony_ci		tloge("get error config tui command(0x%x)\n", g_tui_ctl->s2n.command);
1568419b0af8Sopenharmony_ci		break;
1569419b0af8Sopenharmony_ci	}
1570419b0af8Sopenharmony_ci	return ret;
1571419b0af8Sopenharmony_ci}
1572419b0af8Sopenharmony_ci
1573419b0af8Sopenharmony_cistatic int do_tui_work(void)
1574419b0af8Sopenharmony_ci{
1575419b0af8Sopenharmony_ci	int ret = 0;
1576419b0af8Sopenharmony_ci
1577419b0af8Sopenharmony_ci	/* clear s2n cmd ret */
1578419b0af8Sopenharmony_ci	g_tui_ctl->s2n.ret = 0;
1579419b0af8Sopenharmony_ci	switch (g_tui_ctl->s2n.command) {
1580419b0af8Sopenharmony_ci	case TUI_CMD_ENABLE:
1581419b0af8Sopenharmony_ci	case TUI_CMD_DISABLE:
1582419b0af8Sopenharmony_ci	case TUI_CMD_PAUSE:
1583419b0af8Sopenharmony_ci	case TUI_CMD_POLL:
1584419b0af8Sopenharmony_ci	case TUI_CMD_DO_SYNC:
1585419b0af8Sopenharmony_ci	case TUI_CMD_SET_STATE:
1586419b0af8Sopenharmony_ci	case TUI_CMD_START_DELAY_WORK:
1587419b0af8Sopenharmony_ci	case TUI_CMD_CANCEL_DELAY_WORK:
1588419b0af8Sopenharmony_ci		ret = do_tui_config_work();
1589419b0af8Sopenharmony_ci		break;
1590419b0af8Sopenharmony_ci	case TUI_CMD_LOAD_TTF:
1591419b0af8Sopenharmony_ci	case TUI_CMD_EXIT:
1592419b0af8Sopenharmony_ci	case TUI_CMD_FREE_TTF_MEM:
1593419b0af8Sopenharmony_ci		ret = do_tui_ttf_work();
1594419b0af8Sopenharmony_ci		break;
1595419b0af8Sopenharmony_ci	default:
1596419b0af8Sopenharmony_ci		ret = -EINVAL;
1597419b0af8Sopenharmony_ci		tloge("get error tui command\n");
1598419b0af8Sopenharmony_ci		break;
1599419b0af8Sopenharmony_ci	}
1600419b0af8Sopenharmony_ci	return ret;
1601419b0af8Sopenharmony_ci}
1602419b0af8Sopenharmony_ci
1603419b0af8Sopenharmony_civoid set_tui_caller_info(unsigned int devid, int pid)
1604419b0af8Sopenharmony_ci{
1605419b0af8Sopenharmony_ci	atomic_set(&g_tui_attached_device, (int)devid);
1606419b0af8Sopenharmony_ci	atomic_set(&g_tui_pid, pid);
1607419b0af8Sopenharmony_ci}
1608419b0af8Sopenharmony_ci
1609419b0af8Sopenharmony_ciunsigned int tui_attach_device(void)
1610419b0af8Sopenharmony_ci{
1611419b0af8Sopenharmony_ci	return (unsigned int)atomic_read(&g_tui_attached_device);
1612419b0af8Sopenharmony_ci}
1613419b0af8Sopenharmony_ci
1614419b0af8Sopenharmony_cistatic int tui_kthread_work_fn(void *data)
1615419b0af8Sopenharmony_ci{
1616419b0af8Sopenharmony_ci	int ret;
1617419b0af8Sopenharmony_ci	ret = init_tui_agent();
1618419b0af8Sopenharmony_ci	if (ret != 0) {
1619419b0af8Sopenharmony_ci		tloge("init tui agent error, ret = %d\n", ret);
1620419b0af8Sopenharmony_ci		return ret;
1621419b0af8Sopenharmony_ci	}
1622419b0af8Sopenharmony_ci
1623419b0af8Sopenharmony_ci	while (1) {
1624419b0af8Sopenharmony_ci		tc_ns_wait_event(TEE_TUI_AGENT_ID);
1625419b0af8Sopenharmony_ci
1626419b0af8Sopenharmony_ci		if (kthread_should_stop())
1627419b0af8Sopenharmony_ci			break;
1628419b0af8Sopenharmony_ci
1629419b0af8Sopenharmony_ci		do_tui_work();
1630419b0af8Sopenharmony_ci
1631419b0af8Sopenharmony_ci		if (tc_ns_send_event_response(TEE_TUI_AGENT_ID) != 0)
1632419b0af8Sopenharmony_ci			tloge("send event response error\n");
1633419b0af8Sopenharmony_ci	}
1634419b0af8Sopenharmony_ci
1635419b0af8Sopenharmony_ci	exit_tui_agent();
1636419b0af8Sopenharmony_ci
1637419b0af8Sopenharmony_ci	return 0;
1638419b0af8Sopenharmony_ci}
1639419b0af8Sopenharmony_ci
1640419b0af8Sopenharmony_ci#define READ_BUF 128
1641419b0af8Sopenharmony_cistatic ssize_t tui_dbg_state_read(struct file *filp, char __user *ubuf,
1642419b0af8Sopenharmony_ci					size_t cnt, loff_t *ppos)
1643419b0af8Sopenharmony_ci{
1644419b0af8Sopenharmony_ci	char buf[READ_BUF] = {0};
1645419b0af8Sopenharmony_ci	unsigned int r;
1646419b0af8Sopenharmony_ci	int ret;
1647419b0af8Sopenharmony_ci	struct tui_drv_node *pos = NULL;
1648419b0af8Sopenharmony_ci
1649419b0af8Sopenharmony_ci	if (filp == NULL || ubuf == NULL || ppos == NULL)
1650419b0af8Sopenharmony_ci		return -EINVAL;
1651419b0af8Sopenharmony_ci
1652419b0af8Sopenharmony_ci	ret = snprintf_s(buf, READ_BUF, READ_BUF - 1, "tui state:%s\n",
1653419b0af8Sopenharmony_ci			state_name[atomic_read(&g_tui_state)]);
1654419b0af8Sopenharmony_ci	if (ret < 0) {
1655419b0af8Sopenharmony_ci		tloge("tui dbg state read 1 snprintf is failed, ret = 0x%x\n", ret);
1656419b0af8Sopenharmony_ci		return -EINVAL;
1657419b0af8Sopenharmony_ci	}
1658419b0af8Sopenharmony_ci	r = (unsigned int)ret;
1659419b0af8Sopenharmony_ci
1660419b0af8Sopenharmony_ci	ret = snprintf_s(buf + r, READ_BUF - r, READ_BUF - r - 1, "%s", "drv config state:");
1661419b0af8Sopenharmony_ci	if (ret < 0) {
1662419b0af8Sopenharmony_ci		tloge("tui dbg state read 2 snprintf is failed, ret = 0x%x\n", ret);
1663419b0af8Sopenharmony_ci		return -EINVAL;
1664419b0af8Sopenharmony_ci	}
1665419b0af8Sopenharmony_ci	r += (unsigned int)ret;
1666419b0af8Sopenharmony_ci
1667419b0af8Sopenharmony_ci	mutex_lock(&g_tui_drv_lock);
1668419b0af8Sopenharmony_ci	list_for_each_entry(pos, &g_tui_drv_head, list) {
1669419b0af8Sopenharmony_ci		ret = snprintf_s(buf + r, READ_BUF - r, READ_BUF - r - 1, "%s-%s,", pos->name, 1 == pos->state ? "ok" : "no ok");
1670419b0af8Sopenharmony_ci		if (ret < 0) {
1671419b0af8Sopenharmony_ci			tloge("tui dbg state read 3 snprintf is failed, ret = 0x%x\n", ret);
1672419b0af8Sopenharmony_ci			mutex_unlock(&g_tui_drv_lock);
1673419b0af8Sopenharmony_ci			return -EINVAL;
1674419b0af8Sopenharmony_ci		}
1675419b0af8Sopenharmony_ci		r += (unsigned int)ret;
1676419b0af8Sopenharmony_ci	}
1677419b0af8Sopenharmony_ci	mutex_unlock(&g_tui_drv_lock);
1678419b0af8Sopenharmony_ci	if (r < READ_BUF)
1679419b0af8Sopenharmony_ci		buf[r - 1] = '\n';
1680419b0af8Sopenharmony_ci
1681419b0af8Sopenharmony_ci	return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
1682419b0af8Sopenharmony_ci}
1683419b0af8Sopenharmony_ci
1684419b0af8Sopenharmony_cistatic const struct file_operations tui_dbg_state_fops = {
1685419b0af8Sopenharmony_ci	.owner = THIS_MODULE,
1686419b0af8Sopenharmony_ci	.read = tui_dbg_state_read,
1687419b0af8Sopenharmony_ci};
1688419b0af8Sopenharmony_ci
1689419b0af8Sopenharmony_ci#define MAX_SHOW_BUFF_LEN 32
1690419b0af8Sopenharmony_cistatic ssize_t tui_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
1691419b0af8Sopenharmony_ci{
1692419b0af8Sopenharmony_ci	int r;
1693419b0af8Sopenharmony_ci	size_t buf_len = 0;
1694419b0af8Sopenharmony_ci	if (kobj == NULL || attr == NULL || buf == NULL)
1695419b0af8Sopenharmony_ci		return -EINVAL;
1696419b0af8Sopenharmony_ci
1697419b0af8Sopenharmony_ci	g_tui_state_flag = 0;
1698419b0af8Sopenharmony_ci	r = wait_event_interruptible(g_tui_state_wq, g_tui_state_flag);
1699419b0af8Sopenharmony_ci	if (r != 0) {
1700419b0af8Sopenharmony_ci		tloge("get tui state is interrupted\n");
1701419b0af8Sopenharmony_ci		return r;
1702419b0af8Sopenharmony_ci	}
1703419b0af8Sopenharmony_ci	buf_len = MAX_SHOW_BUFF_LEN;
1704419b0af8Sopenharmony_ci	r = snprintf_s(buf, buf_len, buf_len - 1, "%s", state_name[atomic_read(&g_tui_state)]);
1705419b0af8Sopenharmony_ci	if (r < 0) {
1706419b0af8Sopenharmony_ci		tloge("tui status show snprintf is failed, ret = 0x%x\n", r);
1707419b0af8Sopenharmony_ci		return -1;
1708419b0af8Sopenharmony_ci	}
1709419b0af8Sopenharmony_ci
1710419b0af8Sopenharmony_ci	return r;
1711419b0af8Sopenharmony_ci}
1712419b0af8Sopenharmony_ci
1713419b0af8Sopenharmony_ci#define MSG_BUF 512
1714419b0af8Sopenharmony_cistatic ssize_t tui_dbg_msg_read(struct file *filp, char __user *ubuf,
1715419b0af8Sopenharmony_ci				size_t cnt, loff_t *ppos)
1716419b0af8Sopenharmony_ci{
1717419b0af8Sopenharmony_ci	char buf[MSG_BUF] = {0};
1718419b0af8Sopenharmony_ci	int ret;
1719419b0af8Sopenharmony_ci	int i;
1720419b0af8Sopenharmony_ci	struct tui_drv_node *pos = NULL;
1721419b0af8Sopenharmony_ci
1722419b0af8Sopenharmony_ci	if (filp == NULL || ubuf == NULL || ppos == NULL)
1723419b0af8Sopenharmony_ci		return -EINVAL;
1724419b0af8Sopenharmony_ci
1725419b0af8Sopenharmony_ci	ret = snprintf_s(buf, MSG_BUF, MSG_BUF - 1, "%s", "event format: event_type:val\n"
1726419b0af8Sopenharmony_ci			"event type:\n");
1727419b0af8Sopenharmony_ci	if (ret < 0)
1728419b0af8Sopenharmony_ci		return -EINVAL;
1729419b0af8Sopenharmony_ci
1730419b0af8Sopenharmony_ci	unsigned int r = (unsigned int)ret;
1731419b0af8Sopenharmony_ci
1732419b0af8Sopenharmony_ci	/* event type list */
1733419b0af8Sopenharmony_ci	for (i = 0; i < TUI_POLL_MAX - 1; i++) {
1734419b0af8Sopenharmony_ci		ret = snprintf_s(buf + r, MSG_BUF - r, MSG_BUF - r - 1, "%s, ",
1735419b0af8Sopenharmony_ci				poll_event_type_name[i]);
1736419b0af8Sopenharmony_ci		if (ret < 0) {
1737419b0af8Sopenharmony_ci			tloge("tui db msg read 2 snprint is error, ret = 0x%x\n", ret);
1738419b0af8Sopenharmony_ci			return -EINVAL;
1739419b0af8Sopenharmony_ci		}
1740419b0af8Sopenharmony_ci		r += (unsigned int)ret;
1741419b0af8Sopenharmony_ci	}
1742419b0af8Sopenharmony_ci	ret = snprintf_s(buf + r, MSG_BUF - r, MSG_BUF - r - 1, "%s\n", poll_event_type_name[i]);
1743419b0af8Sopenharmony_ci	if (ret < 0) {
1744419b0af8Sopenharmony_ci		tloge("tui db msg read 3 snprint is error, ret = 0x%x\n", ret);
1745419b0af8Sopenharmony_ci		return -EINVAL;
1746419b0af8Sopenharmony_ci	}
1747419b0af8Sopenharmony_ci	r += (unsigned int)ret;
1748419b0af8Sopenharmony_ci
1749419b0af8Sopenharmony_ci	/* cfg drv type list */
1750419b0af8Sopenharmony_ci	ret = snprintf_s(buf + r, MSG_BUF - r, MSG_BUF - r - 1, "val type for %s or %s:\n",
1751419b0af8Sopenharmony_ci		poll_event_type_name[TUI_POLL_CFG_OK], poll_event_type_name[TUI_POLL_CFG_FAIL]);
1752419b0af8Sopenharmony_ci	if (ret < 0) {
1753419b0af8Sopenharmony_ci		tloge("tui db msg read 4 snprint is error, ret = 0x%x\n", ret);
1754419b0af8Sopenharmony_ci		return -EINVAL;
1755419b0af8Sopenharmony_ci	}
1756419b0af8Sopenharmony_ci	r += (unsigned int)ret;
1757419b0af8Sopenharmony_ci
1758419b0af8Sopenharmony_ci	mutex_lock(&g_tui_drv_lock);
1759419b0af8Sopenharmony_ci	list_for_each_entry(pos, &g_tui_drv_head, list) {
1760419b0af8Sopenharmony_ci		ret = snprintf_s(buf + r, MSG_BUF - r, MSG_BUF - r - 1, "%s,", pos->name);
1761419b0af8Sopenharmony_ci		if (ret < 0) {
1762419b0af8Sopenharmony_ci			tloge("tui db msg read 5 snprint is error, ret = 0x%x\n", ret);
1763419b0af8Sopenharmony_ci			mutex_unlock(&g_tui_drv_lock);
1764419b0af8Sopenharmony_ci			return -EINVAL;
1765419b0af8Sopenharmony_ci		}
1766419b0af8Sopenharmony_ci		r += (unsigned int)ret;
1767419b0af8Sopenharmony_ci	}
1768419b0af8Sopenharmony_ci	mutex_unlock(&g_tui_drv_lock);
1769419b0af8Sopenharmony_ci	if (r < MSG_BUF)
1770419b0af8Sopenharmony_ci		buf[r - 1] = '\n';
1771419b0af8Sopenharmony_ci
1772419b0af8Sopenharmony_ci	return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
1773419b0af8Sopenharmony_ci}
1774419b0af8Sopenharmony_ci
1775419b0af8Sopenharmony_cistatic ssize_t tui_dbg_process_tp(const char *tokens, char **begins)
1776419b0af8Sopenharmony_ci{
1777419b0af8Sopenharmony_ci	long value = 0;
1778419b0af8Sopenharmony_ci	int base = TP_BASE_VALUE;
1779419b0af8Sopenharmony_ci
1780419b0af8Sopenharmony_ci	/* simple_strtol is obsolete, use kstrtol instead */
1781419b0af8Sopenharmony_ci	int32_t ret = kstrtol(tokens, base, &value);
1782419b0af8Sopenharmony_ci	if (ret != 0)
1783419b0af8Sopenharmony_ci		return -EFAULT;
1784419b0af8Sopenharmony_ci	g_tui_ctl->n2s.status = (int)value;
1785419b0af8Sopenharmony_ci
1786419b0af8Sopenharmony_ci	tokens = strsep(begins, ":");
1787419b0af8Sopenharmony_ci	if (tokens == NULL)
1788419b0af8Sopenharmony_ci		return -EFAULT;
1789419b0af8Sopenharmony_ci
1790419b0af8Sopenharmony_ci	ret = kstrtol(tokens, base, &value);
1791419b0af8Sopenharmony_ci	if (ret != 0)
1792419b0af8Sopenharmony_ci		return -EFAULT;
1793419b0af8Sopenharmony_ci	g_tui_ctl->n2s.x = (int)value;
1794419b0af8Sopenharmony_ci
1795419b0af8Sopenharmony_ci	tokens = strsep(begins, ":");
1796419b0af8Sopenharmony_ci	if (tokens == NULL)
1797419b0af8Sopenharmony_ci		return -EFAULT;
1798419b0af8Sopenharmony_ci
1799419b0af8Sopenharmony_ci	int32_t ret = kstrtol(tokens, base, &value);
1800419b0af8Sopenharmony_ci	if (ret != 0)
1801419b0af8Sopenharmony_ci		return -EINVAL;
1802419b0af8Sopenharmony_ci	g_tui_ctl->n2s.y = (int)value;
1803419b0af8Sopenharmony_ci	return 0;
1804419b0af8Sopenharmony_ci}
1805419b0af8Sopenharmony_ci
1806419b0af8Sopenharmony_cistatic ssize_t tui_dbg_msg_write(struct file *filp,
1807419b0af8Sopenharmony_ci				const char __user *ubuf, size_t cnt,
1808419b0af8Sopenharmony_ci				loff_t *ppos)
1809419b0af8Sopenharmony_ci{
1810419b0af8Sopenharmony_ci	char buf[64];
1811419b0af8Sopenharmony_ci	int i;
1812419b0af8Sopenharmony_ci	int event_type = -1;
1813419b0af8Sopenharmony_ci	char *tokens = NULL, *begins = NULL;
1814419b0af8Sopenharmony_ci	struct teec_tui_parameter tui_param = {0};
1815419b0af8Sopenharmony_ci
1816419b0af8Sopenharmony_ci	if (ubuf == NULL || filp == NULL || ppos == NULL)
1817419b0af8Sopenharmony_ci		return -EINVAL;
1818419b0af8Sopenharmony_ci
1819419b0af8Sopenharmony_ci	if (cnt >= sizeof(buf)/sizeof(char))
1820419b0af8Sopenharmony_ci		return -EINVAL;
1821419b0af8Sopenharmony_ci
1822419b0af8Sopenharmony_ci	if (copy_from_user(buf, ubuf, cnt) != 0)
1823419b0af8Sopenharmony_ci		return -EFAULT;
1824419b0af8Sopenharmony_ci
1825419b0af8Sopenharmony_ci	buf[cnt] = 0;
1826419b0af8Sopenharmony_ci	begins = buf;
1827419b0af8Sopenharmony_ci
1828419b0af8Sopenharmony_ci	/* event type */
1829419b0af8Sopenharmony_ci	tokens = strsep(&begins, ":");
1830419b0af8Sopenharmony_ci	if (tokens == NULL)
1831419b0af8Sopenharmony_ci		return -EFAULT;
1832419b0af8Sopenharmony_ci
1833419b0af8Sopenharmony_ci	tlogd("1: tokens:%s\n", tokens);
1834419b0af8Sopenharmony_ci	for (i = 0; i < TUI_POLL_MAX; i++) {
1835419b0af8Sopenharmony_ci		if (strncmp(tokens, poll_event_type_name[i], strlen(poll_event_type_name[i])) == 0) {
1836419b0af8Sopenharmony_ci			event_type = i;
1837419b0af8Sopenharmony_ci			break;
1838419b0af8Sopenharmony_ci		}
1839419b0af8Sopenharmony_ci	}
1840419b0af8Sopenharmony_ci
1841419b0af8Sopenharmony_ci	/* only for tp and cancel */
1842419b0af8Sopenharmony_ci	if (event_type != TUI_POLL_TP && event_type != TUI_POLL_CANCEL)
1843419b0af8Sopenharmony_ci		return -EFAULT;
1844419b0af8Sopenharmony_ci	/* drv type */
1845419b0af8Sopenharmony_ci	tokens = strsep(&begins, ":");
1846419b0af8Sopenharmony_ci	if (tokens == NULL)
1847419b0af8Sopenharmony_ci		return -EFAULT;
1848419b0af8Sopenharmony_ci
1849419b0af8Sopenharmony_ci	tlogd("2: tokens:%s\n", tokens);
1850419b0af8Sopenharmony_ci	if (event_type == TUI_POLL_TP) {
1851419b0af8Sopenharmony_ci		if (tui_dbg_process_tp((const char *)tokens, &begins) != 0)
1852419b0af8Sopenharmony_ci			return -EFAULT;
1853419b0af8Sopenharmony_ci	}
1854419b0af8Sopenharmony_ci	tlogd("status=%d x=%d y=%d\n", g_tui_ctl->n2s.status, g_tui_ctl->n2s.x, g_tui_ctl->n2s.y);
1855419b0af8Sopenharmony_ci
1856419b0af8Sopenharmony_ci	if (tui_send_event(event_type, &tui_param))
1857419b0af8Sopenharmony_ci		return -EFAULT;
1858419b0af8Sopenharmony_ci
1859419b0af8Sopenharmony_ci	*ppos += cnt;
1860419b0af8Sopenharmony_ci
1861419b0af8Sopenharmony_ci	return cnt;
1862419b0af8Sopenharmony_ci}
1863419b0af8Sopenharmony_ci
1864419b0af8Sopenharmony_cistatic const struct file_operations tui_dbg_msg_fops = {
1865419b0af8Sopenharmony_ci	.owner = THIS_MODULE,
1866419b0af8Sopenharmony_ci	.read = tui_dbg_msg_read,
1867419b0af8Sopenharmony_ci	.write = tui_dbg_msg_write,
1868419b0af8Sopenharmony_ci};
1869419b0af8Sopenharmony_ci
1870419b0af8Sopenharmony_cistatic struct dentry *g_dbg_dentry = NULL;
1871419b0af8Sopenharmony_ci
1872419b0af8Sopenharmony_cistatic int tui_powerkey_notifier_call(struct notifier_block *powerkey_nb, unsigned long event, void *data)
1873419b0af8Sopenharmony_ci{
1874419b0af8Sopenharmony_ci#ifndef CONFIG_TEE_TUI_MTK
1875419b0af8Sopenharmony_ci	if (event == PRESS_KEY_DOWN) {
1876419b0af8Sopenharmony_ci		tui_poweroff_work_start();
1877419b0af8Sopenharmony_ci	} else if (event == PRESS_KEY_UP) {
1878419b0af8Sopenharmony_ci	} else if (event == PRESS_KEY_1S) {
1879419b0af8Sopenharmony_ci	} else if (event == PRESS_KEY_6S) {
1880419b0af8Sopenharmony_ci	} else if (event == PRESS_KEY_8S) {
1881419b0af8Sopenharmony_ci	} else if (event == PRESS_KEY_10S) {
1882419b0af8Sopenharmony_ci	} else {
1883419b0af8Sopenharmony_ci		tloge("[%s]invalid event %ld !\n", __func__, event);
1884419b0af8Sopenharmony_ci	}
1885419b0af8Sopenharmony_ci#endif
1886419b0af8Sopenharmony_ci#ifdef CONFIG_HW_COMB_KEY
1887419b0af8Sopenharmony_ci	if (event == POWER_KEY_PRESS_DOWN) {
1888419b0af8Sopenharmony_ci		tui_poweroff_work_start();
1889419b0af8Sopenharmony_ci	} else {
1890419b0af8Sopenharmony_ci		tloge("[%s]invalid event %ld !\n", __func__, event);
1891419b0af8Sopenharmony_ci	}
1892419b0af8Sopenharmony_ci#endif
1893419b0af8Sopenharmony_ci	return 0;
1894419b0af8Sopenharmony_ci}
1895419b0af8Sopenharmony_ci
1896419b0af8Sopenharmony_cistatic struct notifier_block tui_powerkey_nb;
1897419b0af8Sopenharmony_ciint register_tui_powerkey_listener(void)
1898419b0af8Sopenharmony_ci{
1899419b0af8Sopenharmony_ci	tui_powerkey_nb.notifier_call = tui_powerkey_notifier_call;
1900419b0af8Sopenharmony_ci#ifdef CONFIG_HW_COMB_KEY
1901419b0af8Sopenharmony_ci	return power_key_register_notifier(&tui_powerkey_nb);
1902419b0af8Sopenharmony_ci#else
1903419b0af8Sopenharmony_ci	return powerkey_register_notifier(&tui_powerkey_nb);
1904419b0af8Sopenharmony_ci#endif
1905419b0af8Sopenharmony_ci}
1906419b0af8Sopenharmony_ci
1907419b0af8Sopenharmony_ciint unregister_tui_powerkey_listener(void)
1908419b0af8Sopenharmony_ci{
1909419b0af8Sopenharmony_ci	tui_powerkey_nb.notifier_call = tui_powerkey_notifier_call;
1910419b0af8Sopenharmony_ci#ifdef CONFIG_HW_COMB_KEY
1911419b0af8Sopenharmony_ci	return power_key_unregister_notifier(&tui_powerkey_nb);
1912419b0af8Sopenharmony_ci#else
1913419b0af8Sopenharmony_ci	return powerkey_unregister_notifier(&tui_powerkey_nb);
1914419b0af8Sopenharmony_ci#endif
1915419b0af8Sopenharmony_ci}
1916419b0af8Sopenharmony_ci
1917419b0af8Sopenharmony_ciint __init init_tui(const struct device *class_dev)
1918419b0af8Sopenharmony_ci{
1919419b0af8Sopenharmony_ci	int retval;
1920419b0af8Sopenharmony_ci	struct sched_param param;
1921419b0af8Sopenharmony_ci	param.sched_priority = MAX_RT_PRIO - 1;
1922419b0af8Sopenharmony_ci
1923419b0af8Sopenharmony_ci	if (class_dev == NULL)
1924419b0af8Sopenharmony_ci		return -1;
1925419b0af8Sopenharmony_ci
1926419b0af8Sopenharmony_ci	g_tui_task = kthread_create(tui_kthread_work_fn, NULL, "tuid");
1927419b0af8Sopenharmony_ci	if (IS_ERR_OR_NULL(g_tui_task)) {
1928419b0af8Sopenharmony_ci		tloge("kthread create is error\n");
1929419b0af8Sopenharmony_ci		return PTR_ERR(g_tui_task);
1930419b0af8Sopenharmony_ci	}
1931419b0af8Sopenharmony_ci
1932419b0af8Sopenharmony_ci	sched_setscheduler_nocheck(g_tui_task, SCHED_FIFO, &param);
1933419b0af8Sopenharmony_ci	get_task_struct(g_tui_task);
1934419b0af8Sopenharmony_ci
1935419b0af8Sopenharmony_ci	tz_kthread_bind_mask(g_tui_task);
1936419b0af8Sopenharmony_ci	wake_up_process(g_tui_task);
1937419b0af8Sopenharmony_ci
1938419b0af8Sopenharmony_ci	INIT_LIST_HEAD(&g_tui_msg_head);
1939419b0af8Sopenharmony_ci	spin_lock_init(&g_tui_msg_lock);
1940419b0af8Sopenharmony_ci
1941419b0af8Sopenharmony_ci	init_waitqueue_head(&g_tui_state_wq);
1942419b0af8Sopenharmony_ci	init_waitqueue_head(&g_tui_msg_wq);
1943419b0af8Sopenharmony_ci	g_dbg_dentry = debugfs_create_dir("tui", NULL);
1944419b0af8Sopenharmony_ci#ifdef DEBUG_TUI
1945419b0af8Sopenharmony_ci	debugfs_create_file("message", 0440, g_dbg_dentry, NULL, &tui_dbg_msg_fops);
1946419b0af8Sopenharmony_ci#endif
1947419b0af8Sopenharmony_ci	debugfs_create_file("d_state", 0440, g_dbg_dentry, NULL, &tui_dbg_state_fops);
1948419b0af8Sopenharmony_ci	g_tui_kobj = kobject_create_and_add("tui", kernel_kobj);
1949419b0af8Sopenharmony_ci	if (g_tui_kobj == NULL) {
1950419b0af8Sopenharmony_ci		tloge("tui kobj create error\n");
1951419b0af8Sopenharmony_ci		retval = -ENOMEM;
1952419b0af8Sopenharmony_ci		goto error2;
1953419b0af8Sopenharmony_ci	}
1954419b0af8Sopenharmony_ci	retval = sysfs_create_group(g_tui_kobj, &g_tui_attr_group);
1955419b0af8Sopenharmony_ci
1956419b0af8Sopenharmony_ci	if (retval) {
1957419b0af8Sopenharmony_ci		tloge("sysfs_create_group error, retval = 0x%x\n", retval);
1958419b0af8Sopenharmony_ci		goto error1;
1959419b0af8Sopenharmony_ci	}
1960419b0af8Sopenharmony_ci
1961419b0af8Sopenharmony_ci	retval = register_tui_powerkey_listener();
1962419b0af8Sopenharmony_ci	if (retval != 0) {
1963419b0af8Sopenharmony_ci		tloge("tui register failed, retval = 0x%x\n", retval);
1964419b0af8Sopenharmony_ci		goto error1;
1965419b0af8Sopenharmony_ci	}
1966419b0af8Sopenharmony_ci	return 0;
1967419b0af8Sopenharmony_cierror1:
1968419b0af8Sopenharmony_ci	kobject_put(g_tui_kobj);
1969419b0af8Sopenharmony_cierror2:
1970419b0af8Sopenharmony_ci	kthread_stop(g_tui_task);
1971419b0af8Sopenharmony_ci	return retval;
1972419b0af8Sopenharmony_ci}
1973419b0af8Sopenharmony_ci
1974419b0af8Sopenharmony_civoid free_tui(void)
1975419b0af8Sopenharmony_ci{
1976419b0af8Sopenharmony_ci	if (unregister_tui_powerkey_listener() < 0)
1977419b0af8Sopenharmony_ci		tloge("tui power key unregister failed\n");
1978419b0af8Sopenharmony_ci	kthread_stop(g_tui_task);
1979419b0af8Sopenharmony_ci	put_task_struct(g_tui_task);
1980419b0af8Sopenharmony_ci	debugfs_remove(g_dbg_dentry);
1981419b0af8Sopenharmony_ci	sysfs_remove_group(g_tui_kobj, &g_tui_attr_group);
1982419b0af8Sopenharmony_ci	kobject_put(g_tui_kobj);
1983419b0af8Sopenharmony_ci}
1984419b0af8Sopenharmony_ci
1985419b0af8Sopenharmony_ciint tc_ns_tui_event(struct tc_ns_dev_file *dev_file, const void *argp)
1986419b0af8Sopenharmony_ci{
1987419b0af8Sopenharmony_ci	struct teec_tui_parameter tui_param = {0};
1988419b0af8Sopenharmony_ci	int ret;
1989419b0af8Sopenharmony_ci
1990419b0af8Sopenharmony_ci	if (!dev_file || !argp) {
1991419b0af8Sopenharmony_ci		tloge("argp or dev is NULL\n");
1992419b0af8Sopenharmony_ci		return -EINVAL;
1993419b0af8Sopenharmony_ci	}
1994419b0af8Sopenharmony_ci
1995419b0af8Sopenharmony_ci	if (copy_from_user(&tui_param, argp, sizeof(tui_param))) {
1996419b0af8Sopenharmony_ci		tloge("copy from user failed\n");
1997419b0af8Sopenharmony_ci		return -ENOMEM;
1998419b0af8Sopenharmony_ci	}
1999419b0af8Sopenharmony_ci
2000419b0af8Sopenharmony_ci	if (tui_param.event_type == TUI_POLL_CANCEL ||
2001419b0af8Sopenharmony_ci		tui_param.event_type == TUI_POLL_NOTCH ||
2002419b0af8Sopenharmony_ci		tui_param.event_type == TUI_POLL_FOLD) {
2003419b0af8Sopenharmony_ci			ret = tui_send_event(tui_param.event_type, &tui_param);
2004419b0af8Sopenharmony_ci	} else {
2005419b0af8Sopenharmony_ci		tloge("no permission to send event\n");
2006419b0af8Sopenharmony_ci		ret = -EACCES;
2007419b0af8Sopenharmony_ci	}
2008419b0af8Sopenharmony_ci
2009419b0af8Sopenharmony_ci	return ret;
2010419b0af8Sopenharmony_ci}
2011419b0af8Sopenharmony_ci
2012419b0af8Sopenharmony_cibool is_tui_agent(unsigned int agent_id)
2013419b0af8Sopenharmony_ci{
2014419b0af8Sopenharmony_ci	return agent_id == TEE_TUI_AGENT_ID;
2015419b0af8Sopenharmony_ci}