1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18 #include "hdmi_hal_machine.h"
19 #include "hdmi_osal.h"
20 #include "drv_hdmi_common.h"
21
22 #define MACHINE_MAX_ID_NUM 19
23 #define MACHIME_NULL_TINTERVAL 20
24 #define MACHIME_MIN_TINTERVAL 5
25
26 typedef struct {
27 osal_semaphore_t mach_mutex;
28 hi_bool init;
29 hi_u32 total;
30 hdmi_mach_elem mach_elem[MACHINE_MAX_ID_NUM];
31 } hdmi_mach_info;
32
33 static hdmi_mach_info g_machine_info;
34
hal_hdmi_mach_init(hi_void)35 hi_s32 hal_hdmi_mach_init(hi_void)
36 {
37 hdmi_mach_info *mach_info = &g_machine_info;
38
39 if (!mach_info->init) {
40 osal_sema_init(&mach_info->mach_mutex, 1);
41 (hi_void)memset_s(mach_info->mach_elem, MACHINE_MAX_ID_NUM * sizeof(hdmi_mach_elem), 0,
42 MACHINE_MAX_ID_NUM * sizeof(hdmi_mach_elem));
43 mach_info->total = 0;
44 mach_info->init = HI_TRUE;
45 }
46
47 return HI_SUCCESS;
48 }
49
hal_hdmi_mach_deinit(hi_void)50 hi_s32 hal_hdmi_mach_deinit(hi_void)
51 {
52 hdmi_mach_info *mach_info = &g_machine_info;
53
54 hdmi_if_false_return(mach_info->init, HI_FAILURE);
55
56 hdmi_mutex_lock(mach_info->mach_mutex);
57 (hi_void)memset_s(mach_info->mach_elem, sizeof(mach_info->mach_elem), 0, sizeof(mach_info->mach_elem));
58 mach_info->total = 0;
59 mach_info->init = HI_FALSE;
60 hdmi_mutex_unlock(mach_info->mach_mutex);
61 osal_sema_destroy(&mach_info->mach_mutex);
62
63 return HI_SUCCESS;
64 }
65
hal_hdmi_mach_invoke(hi_void)66 hi_s32 hal_hdmi_mach_invoke(hi_void)
67 {
68 hi_u32 i;
69 hdmi_mach_elem *tmp_elem = HI_NULL;
70 hdmi_mach_info *mach_info = &g_machine_info;
71
72 hdmi_if_false_return(mach_info->init, HI_FAILURE);
73
74 if (mach_info->total == 0) {
75 osal_msleep(MACHIME_NULL_TINTERVAL);
76 } else {
77 for (i = 0; i < MACHINE_MAX_ID_NUM; ++i) {
78 tmp_elem = &mach_info->mach_elem[i];
79 if (!(tmp_elem->mach_run.valid_id) || !(tmp_elem->mach_run.enable) ||
80 ((hdmi_osal_get_time_in_ms() - tmp_elem->mach_run.last_time) <= tmp_elem->mach_ctrl.interval)) {
81 continue;
82 }
83 if (tmp_elem->mach_ctrl.callback != HI_NULL) {
84 tmp_elem->mach_ctrl.callback(tmp_elem->mach_ctrl.data);
85 }
86 hdmi_mutex_lock(mach_info->mach_mutex);
87 tmp_elem->mach_run.last_time = hdmi_osal_get_time_in_ms();
88 tmp_elem->mach_run.timestamp[tmp_elem->mach_run.stamp_idx] = hdmi_osal_get_time_in_ms();
89 tmp_elem->mach_run.stamp_idx = (tmp_elem->mach_run.stamp_idx + 1) % HDMI_MACH_MAX_STAMPE_NUM;
90 tmp_elem->mach_run.run_cnt++;
91 hdmi_mutex_unlock(mach_info->mach_mutex);
92 }
93 }
94
95 return HI_SUCCESS;
96 }
97
hal_hdmi_mach_register(const hdmi_mach_ctrl * mach_ctrl,hi_u32 * mach_id)98 hi_s32 hal_hdmi_mach_register(const hdmi_mach_ctrl *mach_ctrl, hi_u32 *mach_id)
99 {
100 errno_t errnumber;
101 hi_u32 i;
102 hi_s32 name_len, ret;
103 hdmi_mach_elem *tmp_elem = HI_NULL;
104 hdmi_mach_info *mach_info = &g_machine_info;
105
106 hdmi_if_null_return(mach_ctrl, HI_FAILURE);
107 hdmi_if_null_return(mach_id, HI_FAILURE);
108 hdmi_if_false_return(mach_info->init, HI_FAILURE);
109
110 if (mach_info->total >= MACHINE_MAX_ID_NUM) {
111 hdmi_warn("FULL num=%u! register machine fail! \n", MACHINE_MAX_ID_NUM);
112 ret = HI_FAILURE;
113 } else {
114 hdmi_mutex_lock(mach_info->mach_mutex);
115 for (i = 0; i < MACHINE_MAX_ID_NUM; ++i) {
116 tmp_elem = &mach_info->mach_elem[i];
117 if (!tmp_elem->mach_run.valid_id) {
118 (hi_void)memset_s(&tmp_elem->mach_run, sizeof(tmp_elem->mach_run), 0, sizeof(hdmi_mach_run));
119 errnumber = memcpy_s(&tmp_elem->mach_ctrl, sizeof(tmp_elem->mach_ctrl),
120 mach_ctrl, sizeof(hdmi_mach_ctrl));
121 hdmi_unlock_unequal_eok_return(errnumber, mach_info->mach_mutex, HI_ERR_HDMI_INVALID_PARA);
122 hdmi_unlock_if_null_return(tmp_elem->mach_ctrl.name, mach_info->mach_mutex, HI_FAILURE);
123 name_len = osal_strlen(tmp_elem->mach_ctrl.name);
124 name_len = (name_len < HDMI_MACH_MAX_NAME_SIZE) ? name_len : (HDMI_MACH_MAX_NAME_SIZE - 1);
125 ret = strncpy_s(tmp_elem->mach_run.name, HDMI_MACH_MAX_NAME_SIZE, tmp_elem->mach_ctrl.name, name_len);
126 hdmi_unlock_unequal_eok_return(ret, mach_info->mach_mutex, HI_ERR_HDMI_INVALID_PARA);
127 tmp_elem->mach_run.name[name_len] = '\0';
128 tmp_elem->mach_ctrl.name = tmp_elem->mach_run.name;
129 mach_info->total++;
130 tmp_elem->mach_run.valid_id = HI_TRUE;
131 *mach_id = i;
132 break;
133 }
134 }
135 hdmi_mutex_unlock(mach_info->mach_mutex);
136
137 if (i < MACHINE_MAX_ID_NUM) {
138 hdmi_info("register new machine id=%u success!\n", *mach_id);
139 ret = HI_SUCCESS;
140 } else {
141 hdmi_info("register new machine id=%u fail!\n", *mach_id);
142 ret = HI_FAILURE;
143 }
144 }
145
146 return ret;
147 }
148
hal_hdmi_mach_unregister(hi_u32 mach_id)149 hi_s32 hal_hdmi_mach_unregister(hi_u32 mach_id)
150 {
151 hdmi_mach_elem *tmp_elem = HI_NULL;
152 hdmi_mach_info *mach_info = &g_machine_info;
153
154 hdmi_if_false_return(mach_info->init, HI_FAILURE);
155 hdmi_check_max_return(mach_id, MACHINE_MAX_ID_NUM - 1, HI_FAILURE);
156
157 hdmi_mutex_lock(mach_info->mach_mutex);
158 tmp_elem = &mach_info->mach_elem[mach_id];
159 (hi_void)memset_s(&tmp_elem->mach_run, sizeof(tmp_elem->mach_run), 0, sizeof(hdmi_mach_run));
160 (hi_void)memset_s(&tmp_elem->mach_ctrl, sizeof(tmp_elem->mach_ctrl), 0, sizeof(hdmi_mach_ctrl));
161 mach_info->total--;
162 hdmi_mutex_unlock(mach_info->mach_mutex);
163
164 return HI_SUCCESS;
165 }
166
hal_hdmi_mach_cfg_get(hi_u32 mach_id,hdmi_mach_ctrl * mach_ctrl)167 hi_s32 hal_hdmi_mach_cfg_get(hi_u32 mach_id, hdmi_mach_ctrl *mach_ctrl)
168 {
169 errno_t errnumber;
170 hdmi_mach_elem *tmp_elem = HI_NULL;
171 hdmi_mach_info *mach_info = &g_machine_info;
172
173 hdmi_if_null_return(mach_ctrl, HI_FAILURE);
174 hdmi_if_false_return(mach_info->init, HI_FAILURE);
175 hdmi_check_max_return(mach_id, MACHINE_MAX_ID_NUM - 1, HI_FAILURE);
176
177 hdmi_mutex_lock(mach_info->mach_mutex);
178 tmp_elem = &mach_info->mach_elem[mach_id];
179 errnumber = memcpy_s(mach_ctrl, sizeof(hdmi_mach_ctrl), &tmp_elem->mach_ctrl, sizeof(hdmi_mach_ctrl));
180 hdmi_unlock_unequal_eok_return(errnumber, mach_info->mach_mutex, HI_ERR_HDMI_INVALID_PARA);
181 hdmi_mutex_unlock(mach_info->mach_mutex);
182
183 return HI_SUCCESS;
184 }
185
hal_hdmi_mach_cfg_set(hi_u32 mach_id,const hdmi_mach_ctrl * mach_ctrl)186 hi_s32 hal_hdmi_mach_cfg_set(hi_u32 mach_id, const hdmi_mach_ctrl *mach_ctrl)
187 {
188 errno_t errnumber;
189 hdmi_mach_elem *tmp_elem = HI_NULL;
190 hdmi_mach_info *mach_info = &g_machine_info;
191
192 hdmi_if_null_return(mach_ctrl, HI_FAILURE);
193 hdmi_if_false_return(mach_info->init, HI_FAILURE);
194 hdmi_check_max_return(mach_id, MACHINE_MAX_ID_NUM - 1, HI_FAILURE);
195
196 hdmi_mutex_lock(mach_info->mach_mutex);
197 tmp_elem = &mach_info->mach_elem[mach_id];
198 errnumber = memcpy_s(&tmp_elem->mach_ctrl, sizeof(hdmi_mach_ctrl), mach_ctrl, sizeof(hdmi_mach_ctrl));
199 hdmi_unlock_unequal_eok_return(errnumber, mach_info->mach_mutex, HI_ERR_HDMI_INVALID_PARA);
200 hdmi_mutex_unlock(mach_info->mach_mutex);
201
202 return HI_SUCCESS;
203 }
204
hal_hdmi_mach_start(hi_u32 mach_id)205 hi_s32 hal_hdmi_mach_start(hi_u32 mach_id)
206 {
207 hdmi_mach_elem *tmp_elem = HI_NULL;
208 hdmi_mach_info *mach_info = &g_machine_info;
209
210 hdmi_if_false_return(mach_info->init, HI_FAILURE);
211 hdmi_check_max_return(mach_id, MACHINE_MAX_ID_NUM - 1, HI_FAILURE);
212
213 hdmi_mutex_lock(mach_info->mach_mutex);
214 tmp_elem = &mach_info->mach_elem[mach_id];
215 tmp_elem->mach_run.enable = HI_TRUE;
216 tmp_elem->mach_run.enable_time = hdmi_osal_get_time_in_ms();
217 hdmi_mutex_unlock(mach_info->mach_mutex);
218
219 return HI_SUCCESS;
220 }
221
hal_hdmi_mach_stop(hi_u32 mach_id)222 hi_s32 hal_hdmi_mach_stop(hi_u32 mach_id)
223 {
224 hdmi_mach_elem *tmp_elem = HI_NULL;
225 hdmi_mach_info *mach_info = &g_machine_info;
226
227 hdmi_if_false_return(mach_info->init, HI_FAILURE);
228 hdmi_check_max_return(mach_id, MACHINE_MAX_ID_NUM - 1, HI_FAILURE);
229
230 hdmi_mutex_lock(mach_info->mach_mutex);
231 tmp_elem = &mach_info->mach_elem[mach_id];
232 tmp_elem->mach_run.enable = HI_FALSE;
233 tmp_elem->mach_run.disable_time = hdmi_osal_get_time_in_ms();
234 hdmi_mutex_unlock(mach_info->mach_mutex);
235
236 return HI_SUCCESS;
237 }
238
hal_hdmi_mach_status_get(hdmi_mach_status * status)239 hi_s32 hal_hdmi_mach_status_get(hdmi_mach_status *status)
240 {
241 hdmi_mach_info *mach_info = &g_machine_info;
242
243 hdmi_if_null_return(status, HI_FAILURE);
244 hdmi_if_false_return(mach_info->init, HI_FAILURE);
245
246 hdmi_mutex_lock(mach_info->mach_mutex);
247 status->init = mach_info->init;
248 status->total = mach_info->total;
249 hdmi_mutex_unlock(mach_info->mach_mutex);
250
251 return HI_SUCCESS;
252 }
253
hal_hdmi_mach_elem_status_get(hi_u32 mach_id,hdmi_mach_elem_status * status)254 hi_s32 hal_hdmi_mach_elem_status_get(hi_u32 mach_id, hdmi_mach_elem_status *status)
255 {
256 errno_t errnumber;
257 hdmi_mach_elem *tmp_elem = HI_NULL;
258 hdmi_mach_info *mach_info = &g_machine_info;
259
260 hdmi_if_null_return(status, HI_FAILURE);
261 hdmi_if_false_return(mach_info->init, HI_FAILURE);
262 hdmi_check_max_return(mach_id, MACHINE_MAX_ID_NUM - 1, HI_FAILURE);
263
264 hdmi_mutex_lock(mach_info->mach_mutex);
265 tmp_elem = &mach_info->mach_elem[mach_id];
266 errnumber = memcpy_s(&status->mach_ctrl, sizeof(hdmi_mach_ctrl), &tmp_elem->mach_ctrl, sizeof(hdmi_mach_ctrl));
267 hdmi_unlock_unequal_eok_return(errnumber, mach_info->mach_mutex, HI_ERR_HDMI_INVALID_PARA);
268 errnumber = memcpy_s(&status->mach_run, sizeof(hdmi_mach_run), &tmp_elem->mach_run, sizeof(hdmi_mach_run));
269 hdmi_unlock_unequal_eok_return(errnumber, mach_info->mach_mutex, HI_ERR_HDMI_INVALID_PARA);
270 hdmi_mutex_unlock(mach_info->mach_mutex);
271
272 return HI_SUCCESS;
273 }
274
hal_hdmi_mach_ms_get(hi_void)275 hi_u64 hal_hdmi_mach_ms_get(hi_void)
276 {
277 return (hi_u64)hdmi_osal_get_time_in_ms();
278 }
279
280