• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "drv_hdmi_intf_k.h"
19 #include "drv_hdmi_intf.h"
20 #include "hdmi_hal.h"
21 #include "drv_hdmi_edid.h"
22 #include "drv_hdmi_event.h"
23 #include "hdmi_product_define.h"
24 #include "drv_hdmi_ioctl.h"
25 
hdmi_ext_ioctl(unsigned int cmd,void * argp)26 static hi_s32 hdmi_ext_ioctl(unsigned int cmd, void *argp)
27 {
28     hi_s32 ret;
29     ret = drv_hdmi_cmd_process(cmd, argp, HI_FALSE);
30     return ret;
31 }
32 
hdmi_hot_plug_process(hdmi_device_id hdmi_id)33 static hi_void hdmi_hot_plug_process(hdmi_device_id hdmi_id)
34 {
35     hi_s32 ret;
36     drv_hdmi_status       status   = {0};
37     drv_hdmi_property     property = {0};
38     hdmi_device          *hdmi_dev = HI_NULL;
39     hdmi_sink_capability *sink_cap = HI_NULL;
40 
41     hdmi_info("\n---HDMI kernel event(no user_call_back): HOTPLUG. --- \n");
42 
43     hdmi_dev = get_hdmi_device(hdmi_id);
44     hdmi_if_null_return_void(hdmi_dev);
45 
46     get_hdmi_default_action_set(hdmi_dev, HDMI_DEFAULT_ACTION_HDMI);
47     ret = drv_hdmi_edid_capability_get(&hdmi_dev->edid_info, &sink_cap);
48     if (ret == HDMI_EDID_DATA_INVALID) {
49         hdmi_warn("get sink capability err!\n");
50     }
51 
52     status.hdmi_id = hdmi_id;
53     ret = hdmi_ext_ioctl(CMD_HDMI_GET_STATUS, &status);
54     if (ret != HI_SUCCESS) {
55         hdmi_err("get HDMI status err!\n");
56         return;
57     }
58     if (status.status.connected == HI_FALSE) {
59         hdmi_err("no connect!\n");
60         return;
61     }
62     hdmi_info("connected !\n");
63     property.hdmi_id = hdmi_id;
64     ret = hdmi_ext_ioctl(CMD_HDMI_GET_ATTR, &property);
65     if (ret != HI_SUCCESS) {
66         hdmi_err("get hdmi attr err!\n");
67         return;
68     }
69     hdmi_info("CMD_HDMI_GET_ATTR ok! \n");
70     ret = hdmi_ext_ioctl(CMD_HDMI_SET_ATTR, &property);
71     if (ret != HI_SUCCESS) {
72         hdmi_err("set attr err!:0x%x\n", ret);
73     }
74     hdmi_info("CMD_HDMI_SET_ATTR ok! \n");
75     ret = hdmi_ext_ioctl(CMD_HDMI_START, &hdmi_id);
76     if (ret != HI_SUCCESS) {
77         hdmi_err("hdmi start err!:0x%x\n", ret);
78         return;
79     }
80     hdmi_info("CMD_HDMI_START ok! \n");
81 
82     return;
83 }
84 
hdmi_hot_unplug_process(hdmi_device_id hdmi_id)85 static hi_void hdmi_hot_unplug_process(hdmi_device_id hdmi_id)
86 {
87     hi_s32 ret;
88 
89     ret = hdmi_ext_ioctl(CMD_HDMI_STOP, &hdmi_id);
90     if (ret != HI_SUCCESS) {
91         hdmi_err("hdmi stop  err!:0x%x\n", ret);
92         return;
93     }
94     hdmi_info("CMD_HDMI_STOP ok! \n");
95 
96     return;
97 }
98 
hi_drv_hdmi_kernel_event_callback(hi_void * data,hdmi_event event)99 hi_s32 hi_drv_hdmi_kernel_event_callback(hi_void *data, hdmi_event event)
100 {
101     hdmi_device_id hdmi_id;
102     hi_u32 need_hpd_process;
103     hdmi_device *hdmi_dev = HI_NULL;
104 
105     hdmi_if_null_return(data, HI_FAILURE);
106 
107     hdmi_id = *(hdmi_device_id *)data;
108     hdmi_dev = get_hdmi_device(hdmi_id);
109     hdmi_if_null_return(hdmi_dev, HI_FAILURE);
110 
111     need_hpd_process = ((hi_u32)hdmi_dev->run_state & HDMI_RUN_STATE_START) ||
112         ((hi_u32)hdmi_dev->run_state & HDMI_RUN_STATE_STOP);
113     if (need_hpd_process) {
114         if (event == HDMI_EVENT_HOTPLUG) {
115             hdmi_hot_plug_process(hdmi_id);
116         } else if (event == HDMI_EVENT_HOTUNPLUG) {
117             hdmi_hot_unplug_process(hdmi_id);
118         }
119     }
120 
121     return HI_SUCCESS;
122 }
123 
124 #if (defined(CONFIG_HI_PLATFORM_H8))
csc_param_check(const hdmi_csc_param * csc_param)125 static hi_s32 csc_param_check(const hdmi_csc_param *csc_param)
126 {
127     if (csc_param->colorimetry != HI_HDMI_COLORIMETRY_ITU601 &&
128         csc_param->colorimetry != HI_HDMI_COLORIMETRY_ITU709 &&
129         csc_param->colorimetry != HI_HDMI_COLORIMETRY_2020_CONST_LUMINOUS &&
130         csc_param->colorimetry != HI_HDMI_COLORIMETRY_2020_NON_CONST_LUMINOUS) {
131         hdmi_err("colorimetry err!\n");
132         return HI_FAILURE;
133     }
134 
135     if (csc_param->quantization != HI_HDMI_QUANT_RANGE_LIMITED &&
136         csc_param->quantization != HI_HDMI_QUANT_RANGE_FULL) {
137         hdmi_err("quantization err!\n");
138         return HI_FAILURE;
139     }
140 
141     return HI_SUCCESS;
142 }
143 
video_param_check(const hdmi_video_param * video_param)144 static hi_s32 video_param_check(const hdmi_video_param *video_param)
145 {
146     if (video_param->pixel_encoding != HI_HDMI_COLORSPACE_RGB &&
147         video_param->pixel_encoding != HI_HDMI_COLORSPACE_YCBCR444) {
148         hdmi_err("pixel_encoding err!\n");
149         return HI_FAILURE;
150     }
151 
152     return HI_SUCCESS;
153 }
154 
hi_drv_hdmi_csc_param_set(hdmi_dev_id hdmi,const hdmi_csc_param * csc_param)155 hi_s32 hi_drv_hdmi_csc_param_set(hdmi_dev_id hdmi, const hdmi_csc_param *csc_param)
156 {
157     hi_s32 ret;
158     hdmi_device *hdmi_dev = HI_NULL;
159     drv_hdmi_vo_attr video_attr = {0};
160 
161     hdmi_info("in...\n");
162 
163     if (get_hdmi_device(hdmi) == HI_NULL) {
164         hdmi_err("device id is wrong\n");
165         return HI_FAILURE;
166     }
167 
168     hdmi_dev = get_hdmi_device(hdmi);
169     hdmi_if_null_return(csc_param, HI_FAILURE);
170 
171     /* param check */
172     ret = csc_param_check(csc_param);
173     if (ret != HI_SUCCESS) {
174         hdmi_err("csc_param_check fail... \n");
175         return ret;
176     }
177 
178     hdmi_dev->csc_param.colorimetry  = csc_param->colorimetry;
179     hdmi_dev->csc_param.quantization = csc_param->quantization;
180     /* HDMI not open */
181     if (hdmi_dev->kernel_cnt == 0 && hdmi_dev->user_cnt == 0) {
182         hdmi_warn("device not open! save param to dev. colorimetry=%u, quantization=%u\n",
183             csc_param->colorimetry, csc_param->quantization);
184         return HI_SUCCESS;
185     } else {
186         hdmi_dev->attr.app_attr.out_csc_quantization = csc_param->quantization;
187         ret = hdmi_ext_ioctl(CMD_HDMI_GET_VO_ATTR, &video_attr);
188         if (ret != HI_SUCCESS) {
189             hdmi_err("get vo attr fail... \n");
190             return ret;
191         }
192         video_attr.hdmi_id = hdmi;
193         video_attr.vo_attr.colorimetry = csc_param->colorimetry;
194         ret = hdmi_ext_ioctl(CMD_HDMI_SET_VO_ATTR, &video_attr);
195         if (ret != HI_SUCCESS) {
196             hdmi_err("set attr fail... \n");
197             return ret;
198         }
199     }
200     hdmi_info("out...\n");
201 
202     return ret;
203 }
204 
hi_drv_hdmi_video_param_set(hdmi_dev_id hdmi,const hdmi_video_param * video_param)205 hi_s32 hi_drv_hdmi_video_param_set(hdmi_dev_id hdmi, const hdmi_video_param *video_param)
206 {
207     hi_s32 ret;
208     hdmi_device *hdmi_dev = HI_NULL;
209     drv_hdmi_vo_attr vid_attr = {0};
210 
211     hdmi_info("in...\n");
212 
213     if (get_hdmi_device(hdmi) == HI_NULL) {
214         hdmi_err("device id is wrong\n");
215         return HI_FAILURE;
216     }
217 
218     hdmi_dev = get_hdmi_device(hdmi);
219     hdmi_if_null_return(hdmi_dev, HI_FAILURE);
220     hdmi_if_null_return(video_param, HI_FAILURE);
221 
222     /* param check */
223     ret = video_param_check(video_param);
224     if (ret != HI_SUCCESS) {
225         hdmi_err("video_param_check fail... \n");
226         return ret;
227     }
228 
229     hdmi_dev->csc_param.pixel_encoding = video_param->pixel_encoding;
230 
231     /* HDMI not open */
232     if (hdmi_dev->kernel_cnt == 0 && hdmi_dev->user_cnt == 0) {
233         hdmi_warn("device not open! save param to dev. pixel_encoding = %u\n", video_param->pixel_encoding);
234         return HI_SUCCESS;
235     } else {
236         hdmi_dev->attr.app_attr.out_color_space = video_param->pixel_encoding;
237         hdmi_dev->attr.vo_attr.in_color_space = video_param->pixel_encoding;
238         ret = hdmi_ext_ioctl(CMD_HDMI_GET_VO_ATTR, &vid_attr);
239         if (ret != HI_SUCCESS) {
240             hdmi_err("get vo attr fail... \n");
241             return ret;
242         }
243         vid_attr.hdmi_id = hdmi;
244         ret = hdmi_ext_ioctl(CMD_HDMI_SET_VO_ATTR, &vid_attr);
245         if (ret != HI_SUCCESS) {
246             hdmi_err("set attr fail... \n");
247             return ret;
248         }
249     }
250     hdmi_info("out...\n");
251 
252     return ret;
253 }
254 #endif
255 
hi_drv_hdmi_stop(hdmi_dev_id hdmi)256 hi_s32 hi_drv_hdmi_stop(hdmi_dev_id hdmi)
257 {
258     hi_s32 ret;
259 
260     hdmi_info("in...\n");
261     ret = drv_hdmi_cmd_process(CMD_HDMI_STOP, (hi_void *)(&hdmi), HI_FALSE);
262     if (ret != HI_SUCCESS) {
263         hdmi_err("stop hdmi err!:0x%x\n", ret);
264         return ret;
265     }
266     hdmi_info("out...\n");
267 
268     return ret;
269 }
270 
271 #ifdef HDMI_HDR_SUPPORT
disp_to_hdmi_hdr_attr(const hdmi_device * hdmi_dev,drv_hdmi_hdr_attr * drv_hdr_attr,const hdmi_hdr_attr * hdr_attr)272 static hi_void disp_to_hdmi_hdr_attr(const hdmi_device *hdmi_dev, drv_hdmi_hdr_attr *drv_hdr_attr,
273     const hdmi_hdr_attr *hdr_attr)
274 {
275     errno_t ret;
276     hdmi_if_null_return_void(hdmi_dev);
277     hdmi_if_null_return_void(drv_hdr_attr);
278 
279     drv_hdr_attr->hdr_mode      = hdr_attr->hdr_mode;
280     drv_hdr_attr->user_hdr_mode = hdmi_dev->attr.hdr_attr.user_hdr_mode;
281     drv_hdr_attr->colorimetry   = hdr_attr->colorimetry;
282     drv_hdr_attr->eotf_type     = hdr_attr->eotf_type;
283     drv_hdr_attr->metadata_id   = hdr_attr->metadata_id;
284     ret = memcpy_s(&(drv_hdr_attr->un_descriptor), sizeof(drv_hdr_attr->un_descriptor),
285         &(hdr_attr->descriptor), sizeof(hdmi_meta_descriptor));
286     hdmi_unequal_eok_return_void(ret);
287 
288     return;
289 }
290 
hi_drv_hdmi_set_hdr_attr(hdmi_dev_id hdmi,const hdmi_hdr_attr * hdr_attr)291 hi_s32 hi_drv_hdmi_set_hdr_attr(hdmi_dev_id hdmi, const hdmi_hdr_attr *hdr_attr)
292 {
293     hi_s32             ret;
294     drv_hdmi_hdr       drv_hdr      = {0};
295     hdmi_device       *hdmi_dev     = HI_NULL;
296     drv_hdmi_hdr_attr *drv_hdr_attr = HI_NULL;
297 
298     hdmi_dev = get_hdmi_device(hdmi);
299     if (hdmi_dev == HI_NULL) {
300         hdmi_warn("device id is wrong\n");
301         return HI_FAILURE;
302     }
303     if (hdmi_dev->kernel_cnt == 0 && hdmi_dev->user_cnt == 0) {
304         hdmi_warn("device not open\n");
305         return HI_FAILURE;
306     }
307 
308     hdmi_info("in...\n");
309     hdmi_if_null_return(hdr_attr, HI_FAILURE);
310 
311     if (hdr_attr->hdr_mode == HI_HDMI_HDR_MODE_BUTT) {
312         return HI_FAILURE;
313     }
314     drv_hdr_attr = &drv_hdr.hdr_attr;
315     drv_hdr.hdmi_id = hdmi;
316     disp_to_hdmi_hdr_attr(hdmi_dev, drv_hdr_attr, hdr_attr);
317     ret = hdmi_ext_ioctl(CMD_HDMI_SET_HDR_ATTR, &drv_hdr);
318     if (ret != HI_SUCCESS) {
319         hdmi_info("set HDR attr fail... \n");
320         return ret;
321     }
322     hdmi_info("out...\n");
323 
324     return ret;
325 }
326 #endif
327 
328