blob: e3f0f30d25e1383691744ddd9fc9d37f73d1e14d [file] [log] [blame]
codeworkx62f02ba2012-05-20 12:00:36 +02001/*
2 * Copyright@ Samsung Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020017//#define ALOG_NDEBUG 0
18//#define ALOG_TAG "libhdmi"
codeworkx62f02ba2012-05-20 12:00:36 +020019//#define DEBUG_HDMI_HW_LEVEL
20#include <cutils/log.h>
21
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <sys/ioctl.h>
25#include <sys/mman.h>
26#include <fcntl.h>
27#include <ctype.h>
28#include <unistd.h>
29#include <string.h>
30#include <errno.h>
31#include <signal.h>
32
33#include "sec_utils_v4l2.h"
34#include "s5p_tvout_v4l2.h"
35
36#include "videodev2.h"
37
38#if defined(BOARD_USES_HDMI_FIMGAPI)
39#include "sec_g2d_4x.h"
40#include "FimgApi.h"
41#endif
42
43#include "audio.h"
44#include "video.h"
45#include "../libhdmi/libsForhdmi/libedid/libedid.h"
46#include "../libhdmi/libsForhdmi/libcec/libcec.h"
47
48#include "SecGscaler.h"
49#include "SecHdmiCommon.h"
50#include "SecHdmiV4L2Utils.h"
51
52namespace android {
53
54unsigned int output_type = V4L2_OUTPUT_TYPE_DIGITAL;
55v4l2_std_id t_std_id = V4L2_STD_1080P_30;
56int g_hpd_state = HPD_CABLE_OUT;
57unsigned int g_hdcp_en = 0;
58
59#if defined(BOARD_USES_HDMI_FIMGAPI)
60unsigned int g2d_reserved_memory0 = 0;
61unsigned int g2d_reserved_memory1 = 0;
62unsigned int g2d_reserved_memory_size = 0;
63unsigned int cur_g2d_address = 0;
64#endif
65
66void display_menu(void)
67{
68 struct HDMIVideoParameter video;
69 struct HDMIAudioParameter audio;
70
71#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020072 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +020073#endif
74
75 audio.formatCode = LPCM_FORMAT;
76 audio.outPacket = HDMI_ASP;
77 audio.channelNum = CH_2;
78 audio.sampleFreq = SF_44KHZ;
79
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020080 ALOGI("=============== HDMI Audio =============\n");
codeworkx62f02ba2012-05-20 12:00:36 +020081
82 if (EDIDAudioModeSupport(&audio))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020083 ALOGI("= 2CH_PCM 44100Hz audio supported =\n");
codeworkx62f02ba2012-05-20 12:00:36 +020084
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020085 ALOGI("========= HDMI Mode & Color Space =======\n");
codeworkx62f02ba2012-05-20 12:00:36 +020086
87 video.mode = HDMI;
88 if (EDIDHDMIModeSupport(&video)) {
89 video.colorSpace = HDMI_CS_YCBCR444;
90 if (EDIDColorSpaceSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020091 ALOGI("= 1. HDMI(YCbCr) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +020092
93 video.colorSpace = HDMI_CS_RGB;
94 if (EDIDColorSpaceSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020095 ALOGI("= 2. HDMI(RGB) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +020096 } else {
97 video.mode = DVI;
98 if (EDIDHDMIModeSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020099 ALOGI("= 3. DVI =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200100 }
101
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200102 ALOGI("=========== HDMI Rseolution ========\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200103
104 /* 480P */
105 video.resolution = v720x480p_60Hz;
106 video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9;
107 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
108 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200109 ALOGI("= 4. 480P_60_16_9 (0x04000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200110
111 video.resolution = v640x480p_60Hz;
112 video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3;
113 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
114 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200115 ALOGI("= 5. 480P_60_4_3 (0x05000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200116
117 /* 576P */
118 video.resolution = v720x576p_50Hz;
119 video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9;
120 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
121 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200122 ALOGI("= 6. 576P_50_16_9 (0x06000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200123
124 video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3;
125 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
126 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200127 ALOGI("= 7. 576P_50_4_3 (0x07000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200128
129 /* 720P 60 */
130 video.resolution = v1280x720p_60Hz;
131 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
132 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200133 ALOGI("= 8. 720P_60 (0x08000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200134
135 /* 720P_50 */
136 video.resolution = v1280x720p_50Hz;
137 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
138 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200139 ALOGI("= 9. 720P_50 (0x09000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200140
141 /* 1080P_60 */
142 video.resolution = v1920x1080p_60Hz;
143 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
144 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200145 ALOGI("= a. 1080P_60 (0x0a000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200146
147 /* 1080P_50 */
148 video.resolution = v1920x1080p_50Hz;
149 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
150 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200151 ALOGI("= b. 1080P_50 (0x0b000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200152
153 /* 1080I_60 */
154 video.resolution = v1920x1080i_60Hz;
155 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
156 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200157 ALOGI("= c. 1080I_60 (0x0c000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200158
159 /* 1080I_50 */
160 video.resolution = v1920x1080i_50Hz;
161 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
162 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200163 ALOGI("= d. 1080I_50 (0x0d000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200164
165 /* 1080P_30 */
166 video.resolution = v1920x1080p_30Hz;
167 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
168 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200169 ALOGI("= e. 1080P_30 (0x12000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200170
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200171 ALOGI("=========== HDMI 3D Format ========\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200172
173 /* 720P_60_SBS_HALF */
174 video.resolution = v1280x720p_60Hz;
175 video.hdmi_3d_format = HDMI_3D_SSH_FORMAT;
176 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200177 ALOGI("= f. 720P_60_SBS_HALF (0x13000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200178
179 /* 720P_59_SBS_HALF */
180 video.resolution = v1280x720p_60Hz;
181 video.hdmi_3d_format = HDMI_3D_SSH_FORMAT;
182 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200183 ALOGI("= 10. 720P_59_SBS_HALF (0x14000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200184
185 /* 720P_50_TB */
186 video.resolution = v1280x720p_50Hz;
187 video.hdmi_3d_format = HDMI_3D_TB_FORMAT;
188 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200189 ALOGI("= 11. 720P_50_TB (0x15000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200190
191 /* 1080P_24_TB */
192 video.resolution = v1920x1080p_24Hz;
193 video.hdmi_3d_format = HDMI_3D_TB_FORMAT;
194 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200195 ALOGI("= 12. 1080P_24_TB (0x16000000) =\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200196
197 /* 1080P_23_TB */
198 video.resolution = v1920x1080p_24Hz;
199 video.hdmi_3d_format = HDMI_3D_TB_FORMAT;
200 if (EDIDVideoResolutionSupport(&video))
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200201 ALOGI("= 13. 1080P_24_TB (0x17000000) =\n");
202 ALOGI("=========================================\n");
codeworkx62f02ba2012-05-20 12:00:36 +0200203}
204
205int tvout_init(int fd_tvout, __u32 preset_id)
206{
207#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200208 ALOGD("%s::preset_id = 0x%x", __func__, preset_id);
codeworkx62f02ba2012-05-20 12:00:36 +0200209#endif
210
211 int ret;
212 struct v4l2_output output;
213 struct v4l2_dv_preset preset;
214
215 unsigned int matched = 0, i = 0;
216 int output_index;
217
218 if (fd_tvout <= 0) {
219 fd_tvout = open(TVOUT0_DEV_G0, O_RDWR);
220 if (fd_tvout < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200221 ALOGE("%s::fd_tvout open failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200222 return -1;
223 }
224 }
225/*
226 if (output_type >= V4L2_OUTPUT_TYPE_DIGITAL &&
227 output_type <= V4L2_OUTPUT_TYPE_DVI)
228 if (ioctl(fd_tvout, VIDIOC_HDCP_ENABLE, g_hdcp_en) < 0)
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200229 ALOGE("%s::VIDIOC_HDCP_ENABLE failed %d", __func__, errno);
codeworkx62f02ba2012-05-20 12:00:36 +0200230*/
231 i = 0;
232
233 do {
234 output.index = i;
235 ret = tvout_v4l2_enum_output(fd_tvout, &output);
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200236 ALOGV("%s::output_type=%d output.index=%d .name=%s", __func__, output_type, output.index, output.name);
codeworkx62f02ba2012-05-20 12:00:36 +0200237 if (output.type == output_type) {
238 matched = 1;
239 break;
240 }
241 i++;
242 } while (ret >=0);
243/*
244 if (!matched) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200245 ALOGE("%s::no matched output type [type=0x%08x]", __func__, output_type);
codeworkx62f02ba2012-05-20 12:00:36 +0200246 return -1;
247 }
248
249 tvout_v4l2_s_output(fd_tvout, output.index);
250 output_index = 0;
251 tvout_v4l2_g_output(fd_tvout, &output_index);
252*/
253
254#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200255 ALOGD("%s::input preset_id=0x%08x", __func__, preset_id);
codeworkx62f02ba2012-05-20 12:00:36 +0200256#endif
257
258 if (output.capabilities & V4L2_OUT_CAP_PRESETS) {
259 tvout_std_v4l2_enum_dv_presets(fd_tvout);
260 preset.preset = preset_id;
261 if (tvout_std_v4l2_s_dv_preset(fd_tvout, &preset) < 0 ) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200262 ALOGE("%s::tvout_std_v4l2_s_dv_preset failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200263 return -1;
264 }
265 }
266
267 return fd_tvout;
268}
269
270int tvout_deinit()
271{
272#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200273 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200274#endif
275
276 return 0;
277}
278
279int tvout_std_v4l2_querycap(int fd, char *node)
280{
281#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200282 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200283#endif
284 struct v4l2_capability v4l2cap;
285
286 if (ioctl(fd, VIDIOC_QUERYCAP, &v4l2cap) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200287 ALOGE("%s::VIDIOC_QUERYCAP failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200288 return -1;
289 }
290
291 if (!(v4l2cap.capabilities & V4L2_CAP_STREAMING)) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200292 ALOGE("%s::%s is not support streaming", __func__, node);
codeworkx62f02ba2012-05-20 12:00:36 +0200293 return -1;
294 }
295
296 if (!(v4l2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE)) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200297 ALOGE("%s::%s is not support video output mplane", __func__, node);
codeworkx62f02ba2012-05-20 12:00:36 +0200298 return -1;
299 }
300
301 return 0;
302}
303
304int tvout_std_v4l2_s_fmt(int fd, enum v4l2_buf_type type, enum v4l2_field field, int w, int h, int colorformat, int num_planes)
305{
306#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200307 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200308#endif
309
310 struct v4l2_format fmt;
311
312 fmt.type = type;
313 if (ioctl(fd, VIDIOC_G_FMT, &fmt) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200314 ALOGE("%s::VIDIOC_G_FMT failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200315 return -1;
316 }
317
318 switch (fmt.type) {
319 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
320 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
321 fmt.fmt.pix.width = w;
322 fmt.fmt.pix.height = h;
323 fmt.fmt.pix.pixelformat = colorformat;
324 fmt.fmt.pix.field = field;
325 break;
326 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
327 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
328 fmt.fmt.pix_mp.width = w;
329 fmt.fmt.pix_mp.height = h;
330 fmt.fmt.pix_mp.pixelformat = colorformat;
331 fmt.fmt.pix_mp.field = field;
332 fmt.fmt.pix_mp.num_planes = num_planes;
333 break;
334 default:
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200335 ALOGE("%s::invalid buffer type", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200336 return -1;
337 break;
338 }
339
340 if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200341 ALOGE("%s::VIDIOC_S_FMT failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200342 return -1;
343 }
344
345 return 0;
346}
347
348int tvout_std_v4l2_s_crop(int fd, enum v4l2_buf_type type, enum v4l2_field, int x, int y, int w, int h)
349{
350#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200351 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200352#endif
353 struct v4l2_crop crop;
354
355 crop.type = type;
356 crop.c.left = x;
357 crop.c.top = y;
358 crop.c.width = w;
359 crop.c.height = h;
360
361 if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200362 ALOGE("%s::VIDIOC_S_CROP (x=%d, y=%d, w=%d, h=%d) failed",
codeworkx62f02ba2012-05-20 12:00:36 +0200363 __func__, x, y, w, h);
364 return -1;
365 }
366
367 return 0;
368}
369
370int tvout_std_v4l2_s_ctrl(int fd, int id, int value)
371{
372#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200373 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200374#endif
375 struct v4l2_control vc;
376
377 vc.id = id;
378 vc.value = value;
379
380 if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200381 ALOGE("%s::VIDIOC_S_CTRL (id=%d,value=%d) failed", __func__, id, value);
codeworkx62f02ba2012-05-20 12:00:36 +0200382 return -1;
383 }
384
385 return 0;
386}
387
388int tvout_std_v4l2_reqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int num_bufs)
389{
390#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200391 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200392#endif
393 struct v4l2_requestbuffers reqbuf;
394
395 reqbuf.type = type;
396 reqbuf.memory = memory;
397 reqbuf.count = num_bufs;
398
399 if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200400 ALOGE("%s::VIDIOC_REQBUFS failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200401 return -1;
402 }
403
404 if (reqbuf.count < num_bufs) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200405 ALOGE("%s::VIDIOC_REQBUFS failed ((reqbuf.count(%d) < num_bufs(%d))",
codeworkx62f02ba2012-05-20 12:00:36 +0200406 __func__, reqbuf.count, num_bufs);
407 return -1;
408 }
409
410 return 0;
411}
412
413int tvout_std_v4l2_querybuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int buf_index, unsigned int num_planes, SecBuffer *secBuf)
414{
415#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200416 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200417#endif
418 struct v4l2_buffer buf;
419 struct v4l2_plane planes[MAX_PLANES_MIXER];
420
421 memset(&buf, 0, sizeof(struct v4l2_buffer));
422
423 for (int i = 0; i < MAX_PLANES_MIXER; i++)
424 memset(&planes[i], 0, sizeof(struct v4l2_plane));
425
426 if (MAX_BUFFERS_MIXER <= buf_index || MAX_PLANES_MIXER <= num_planes) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200427 ALOGE("%s::exceed MAX! : buf_index=%d, num_plane=%d", __func__, buf_index, num_planes);
codeworkx62f02ba2012-05-20 12:00:36 +0200428 return -1;
429 }
430
431 buf.type = type;
432 buf.memory = V4L2_MEMORY_MMAP;
433 buf.index = buf_index;
434 buf.length = num_planes;
435 buf.m.planes = planes;
436
437 if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200438 ALOGE("%s::VIDIOC_QUERYBUF failed, plane_cnt=%d", __func__, buf.length);
codeworkx62f02ba2012-05-20 12:00:36 +0200439 return -1;
440 }
441
442 for (unsigned int i = 0; i < num_planes; i++) {
443 if ((secBuf->virt.extP[i] = (char *)mmap(0, buf.m.planes[i].length,
444 PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.planes[i].m.mem_offset)) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200445 ALOGE("%s::mmap failed", __func__);
446 ALOGE("%s::Offset = 0x%x", __func__, buf.m.planes[i].m.mem_offset);
447 ALOGE("%s::Legnth = %d" , __func__, buf.m.planes[i].length);
448 ALOGE("%s::vaddr[%d][%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]);
codeworkx62f02ba2012-05-20 12:00:36 +0200449 return -1;
450 }
451 secBuf->size.extS[i] = buf.m.planes[i].length;
452
453#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200454 ALOGD("%s::vaddr[bufindex=%d][planeidx=%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]);
455 ALOGD("%s::Legnth = %d" , __func__, buf.m.planes[i].length);
codeworkx62f02ba2012-05-20 12:00:36 +0200456#endif
457 }
458
459 return 0;
460}
461
462int tvout_std_v4l2_qbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int buf_index, int num_planes, SecBuffer *secBuf)
463{
464#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200465 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200466#endif
467 struct v4l2_buffer buf;
468 struct v4l2_plane planes[MAX_PLANES_MIXER];
469
470 memset(&buf, 0, sizeof(struct v4l2_buffer));
471
472 for (int i = 0; i < MAX_PLANES_MIXER; i++)
473 memset(&planes[i], 0, sizeof(struct v4l2_plane));
474
475 buf.type = type;
476 buf.memory = memory;
477 buf.length = num_planes;
478 buf.index = buf_index;
479 buf.m.planes = planes;
480
481 for (unsigned int i = 0; i < buf.length; i++) {
482 buf.m.planes[i].m.userptr = (unsigned long)secBuf->virt.extP[i];
483 buf.m.planes[i].length = secBuf->size.extS[i];
484 buf.m.planes[i].bytesused = buf.m.planes[i].length;
485
486#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200487 ALOGD("%s::buf.index=%d", __func__, buf.index);
488 ALOGD("%s::buf.m.planes[%d].m.userptr=0x%08x", __func__, i, (unsigned int)buf.m.planes[i].m.userptr);
489 ALOGD("%s::buf.m.planes[%d].length =0x%08x", __func__, i, buf.m.planes[i].length);
490 ALOGD("%s::buf.m.planes[%d].bytesused=0x%08x", __func__, i, buf.m.planes[i].bytesused);
codeworkx62f02ba2012-05-20 12:00:36 +0200491#endif
492 }
493
494 if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200495 ALOGE("%s::VIDIOC_QBUF failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200496 return -1;
497 }
498
499 return 0;
500}
501
502int tvout_std_v4l2_dqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int *buf_index, int num_planes)
503{
504#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200505 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200506#endif
507 struct v4l2_buffer buf;
508 struct v4l2_plane planes[MAX_PLANES_MIXER];
509
510 memset(&buf, 0, sizeof(struct v4l2_buffer));
511
512 for (int i = 0; i < MAX_PLANES_GSCALER; i++)
513 memset(&planes[i], 0, sizeof(struct v4l2_plane));
514
515
516 buf.type = type;
517 buf.memory = memory;
518 buf.length = num_planes;
519 buf.m.planes = planes;
520
521 if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200522 ALOGE("%s::VIDIOC_DQBUF failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200523 return -1;
524 }
525 *buf_index = buf.index;
526
527#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200528 ALOGD("%s::buf.index=%d", __func__, buf.index);
codeworkx62f02ba2012-05-20 12:00:36 +0200529#endif
530
531 return 0;
532}
533
534int tvout_std_v4l2_streamon(int fd, enum v4l2_buf_type type)
535{
536#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200537 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200538#endif
539 if (ioctl(fd, VIDIOC_STREAMON, &type) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200540 ALOGE("%s::VIDIOC_STREAMON failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200541 return -1;
542 }
543
544 return 0;
545}
546
547int tvout_std_v4l2_streamoff(int fd, enum v4l2_buf_type type)
548{
549#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200550 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200551#endif
552 if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200553 ALOGE("%s::VIDIOC_STREAMOFF failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200554 return -1;
555 }
556
557 return 0;
558}
559
560int tvout_v4l2_enum_output(int fd, struct v4l2_output *output)
561{
562#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200563 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200564#endif
565 int ret = -1 ;
566 ret = ioctl(fd, VIDIOC_ENUMOUTPUT, output);
567
568 if (ret < 0) {
569 if (errno == EINVAL)
570 return -1;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200571 ALOGE("%s::VIDIOC_ENUMOUTPUT", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200572 return -1;
573 }
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200574 ALOGD("%s::index=%d, type=0x%08x, name=%s",
codeworkx62f02ba2012-05-20 12:00:36 +0200575 __func__, output->index, output->type, output->name);
576
577 return ret;
578}
579
580int tvout_v4l2_s_output(int fd, int index)
581{
582#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200583 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200584#endif
585 if (ioctl(fd, VIDIOC_S_OUTPUT, &index) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200586 ALOGE("%s::VIDIOC_S_OUTPUT failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200587 return -1;
588 }
589
590 return 0;
591}
592
593int tvout_v4l2_g_output(int fd, int *index)
594{
595#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200596 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200597#endif
598 if (ioctl(fd, VIDIOC_G_OUTPUT, index) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200599 ALOGE("%s::VIDIOC_G_OUTPUT failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200600 return -1;
601 }
602
603 return 0;
604}
605
606int tvout_std_v4l2_enum_dv_presets(int fd)
607{
608#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200609 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200610#endif
611 struct v4l2_dv_enum_preset enum_preset;
612 int ret = -1;
613
614 for (int index = 0; ; index++) {
615 enum_preset.index = index;
616 ret = ioctl(fd, VIDIOC_ENUM_DV_PRESETS, &enum_preset);
617
618 if (ret < 0) {
619 if (errno == EINVAL)
620 break;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200621 ALOGE("%s::VIDIOC_ENUM_DV_PRESETS", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200622 return -1;
623 }
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200624 ALOGD("%s::index=%d, preset=0x%08x, name=%s, w=%d, h=%d",
codeworkx62f02ba2012-05-20 12:00:36 +0200625 __func__, enum_preset.index, enum_preset.preset, enum_preset.name, enum_preset.width, enum_preset.height);
626 }
627
628 return 0;
629}
630
631int tvout_std_v4l2_s_dv_preset(int fd, struct v4l2_dv_preset *preset)
632{
633#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200634 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200635#endif
636 if (ioctl(fd, VIDIOC_S_DV_PRESET, preset) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200637 ALOGE("%s::VIDIOC_S_DV_PRESET failed preset_id=%d", __func__, preset->preset);
codeworkx62f02ba2012-05-20 12:00:36 +0200638 return -1;
639 }
640#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200641 ALOGD("%s::preset_id=%d", __func__, preset->preset);
codeworkx62f02ba2012-05-20 12:00:36 +0200642#endif
643 return 0;
644}
645
646int tvout_std_subdev_s_fmt(int fd, unsigned int pad, int w, int h, enum v4l2_mbus_pixelcode code)
647{
648#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200649 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200650#endif
651 struct v4l2_subdev_format fmt;
652
653 fmt.pad = pad;
654 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
655 fmt.format.width = w;
656 fmt.format.height = h;
657 fmt.format.code = code;
658
659 if (ioctl(fd, VIDIOC_SUBDEV_S_FMT, &fmt) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200660 ALOGE("%s::VIDIOC_SUBDEV_S_FMT", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200661 return -1;
662 }
663
664#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200665 ALOGD("%s::format w=%d, h=%d", __func__, fmt.format.width, fmt.format.height);
codeworkx62f02ba2012-05-20 12:00:36 +0200666#endif
667 return 0;
668}
669int tvout_std_subdev_s_crop(int fd, unsigned int pad, int x, int y, int w, int h)
670{
671#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200672 ALOGD("%s::pad=%d, crop x=%d, y=%d, w=%d, h=%d", __func__, pad, x, y, w, h);
codeworkx62f02ba2012-05-20 12:00:36 +0200673#endif
674
675 struct v4l2_subdev_crop crop;
676
677 crop.pad = pad;
678 crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
679 crop.rect.left = x;
680 crop.rect.top = y;
681 crop.rect.width = w;
682 crop.rect.height = h;
683
684 if (ioctl(fd, VIDIOC_SUBDEV_S_CROP, &crop) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200685 ALOGE("%s::VIDIOC_SUBDEV_S_CROP", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200686 return -1;
687 }
688
689#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200690 ALOGD("%s::pad=%d, crop x=%d, y=%d, w=%d, h=%d", __func__, pad, crop.rect.left, crop.rect.top, crop.rect.width, crop.rect.height);
codeworkx62f02ba2012-05-20 12:00:36 +0200691#endif
692
693 return 0;
694}
695
696#define ROUND_UP(value, boundary) ((((uint32_t)(value)) + \
697 (((uint32_t) boundary)-1)) & \
698 (~(((uint32_t) boundary)-1)))
699
700void hdmi_cal_rect(int src_w, int src_h, int dst_w, int dst_h, struct v4l2_rect *dst_rect)
701{
702 if (dst_w * src_h <= dst_h * src_w) {
703 dst_rect->left = 0;
704 dst_rect->top = (dst_h - ((dst_w * src_h) / src_w)) >> 1;
705 dst_rect->width = dst_w;
706 dst_rect->height = ((dst_w * src_h) / src_w);
707 } else {
708 dst_rect->left = (dst_w - ((dst_h * src_w) / src_h)) >> 1;
709 dst_rect->top = 0;
710 dst_rect->width = ((dst_h * src_w) / src_h);
711 dst_rect->height = dst_h;
712 }
713}
714
715int hdmi_set_videolayer(int fd, int hdmiW, int hdmiH, struct v4l2_rect * rect)
716{
717#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200718 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200719#endif
720 if (tvout_std_subdev_s_fmt(fd, MIXER_V_SUBDEV_PAD_SINK, hdmiW, hdmiH, V4L2_MBUS_FMT_YUV8_1X24) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200721 ALOGE("%s::tvout_std_subdev_s_fmt(PAD=%d)[videolayer] failed", __func__, MIXER_V_SUBDEV_PAD_SINK);
codeworkx62f02ba2012-05-20 12:00:36 +0200722 return -1;
723 }
724
725 if (tvout_std_subdev_s_crop(fd, MIXER_V_SUBDEV_PAD_SINK, 0, 0, rect->width, rect->height) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200726 ALOGE("%s::tvout_std_subdev_s_crop(PAD=%d)[videolayer] failed", __func__, MIXER_V_SUBDEV_PAD_SINK);
codeworkx62f02ba2012-05-20 12:00:36 +0200727 return -1;
728 }
729
730 if (tvout_std_subdev_s_crop(fd, MIXER_V_SUBDEV_PAD_SOURCE, rect->left, rect->top, rect->width, rect->height) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200731 ALOGE("%s::tvout_std_subdev_s_crop(PAD=%d)[videolayer] failed", __func__, MIXER_V_SUBDEV_PAD_SOURCE);
codeworkx62f02ba2012-05-20 12:00:36 +0200732 return -1;
733 }
734 return 0;
735}
736
737int hdmi_set_graphiclayer(int fd_subdev, int fd_videodev,int layer,
738 int srcColorFormat,
739 int src_w, int src_h,
740 unsigned int src_address, SecBuffer * dstBuffer,
741 int dst_x, int dst_y, int dst_w, int dst_h,
742 int rotVal)
743{
744#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200745 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200746#endif
747#if defined(BOARD_USES_HDMI_FIMGAPI)
748 int dst_color_format;
749 int dst_bpp;
750 unsigned char *dst_addr;
751 fimg2d_blit BlitParam;
752 rotation g2d_rotation;
753
754 fimg2d_addr srcAddr;
755 fimg2d_image srcImage;
756 fimg2d_rect srcRect;
757
758 fimg2d_addr dstAddr;
759 fimg2d_image dstImage;
760 fimg2d_rect dstRect;
761
762 fimg2d_clip dstClip;
763 fimg2d_scale Scaling;
764
765 switch (t_std_id) {
766 case V4L2_STD_1080P_60:
767 case V4L2_STD_1080P_30:
768 case V4L2_STD_1080I_60:
769 case V4L2_STD_TVOUT_720P_60_SBS_HALF:
770 case V4L2_STD_TVOUT_720P_59_SBS_HALF:
771 case V4L2_STD_TVOUT_1080P_24_TB:
772 case V4L2_STD_TVOUT_1080P_23_TB:
773 dst_color_format = CF_ARGB_8888;
774 dst_bpp = 4;
775 break;
776 case V4L2_STD_480P_60_16_9:
777 case V4L2_STD_576P_50_16_9:
778 case V4L2_STD_720P_60:
779 case V4L2_STD_TVOUT_720P_50_TB:
780 default:
781 dst_color_format = CF_ARGB_4444;
782 dst_bpp = 2;
783 break;
784 }
785
786 static unsigned int prev_src_addr = 0;
787
788 if ((cur_g2d_address == 0) || (src_address != prev_src_addr)) {
789 if ((cur_g2d_address == 0) || (cur_g2d_address == g2d_reserved_memory1))
790 dst_addr = (unsigned char *)g2d_reserved_memory0;
791 else
792 dst_addr = (unsigned char *)g2d_reserved_memory1;
793
794 cur_g2d_address = (unsigned int)dst_addr;
795 prev_src_addr = src_address;
796
797 srcAddr = {(addr_space)ADDR_USER, (unsigned long)src_address, src_w*src_h*4, 1, 0};
798 srcImage = {srcAddr, srcAddr, src_w, src_h, src_w*4, AX_RGB, CF_ARGB_8888};
799 srcRect = {0, 0, src_w, src_h};
800
801 dstAddr = {(addr_space)ADDR_USER, (unsigned long)dst_addr, dst_w*dst_h*dst_bpp, 1, 0};
802 dstImage = {dstAddr, dstAddr, dst_w, dst_h, dst_w*dst_bpp, AX_RGB, (color_format)dst_color_format};
803 dstRect = {0, 0, dst_w, dst_h};
804 dstClip = {0, 0, 0, dst_w, dst_h};
805
806 if (rotVal == 0 || rotVal == 180)
807 Scaling = {SCALING_BILINEAR, SCALING_PIXELS, 0, 0, src_w, src_h, dst_w, dst_h};
808 else
809 Scaling = {SCALING_BILINEAR, SCALING_PIXELS, 0, 0, src_w, src_h, dst_h, dst_w};
810
811 switch (rotVal) {
812 case 0:
813 g2d_rotation = ORIGIN;
814 break;
815 case 90:
816 g2d_rotation = ROT_90;
817 break;
818 case 180:
819 g2d_rotation = ROT_180;
820 break;
821 case 270:
822 g2d_rotation = ROT_270;
823 break;
824 default:
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200825 ALOGE("%s::invalid rotVal(%d) : failed", __func__, rotVal);
codeworkx62f02ba2012-05-20 12:00:36 +0200826 return -1;
827 break;
828 }
829
830 BlitParam = {BLIT_OP_SRC, NON_PREMULTIPLIED, 0xff, 0, g2d_rotation, &Scaling, 0, 0, &dstClip, 0, &srcImage, &dstImage, NULL, &srcRect, &dstRect, NULL, 0};
831
832 if (stretchFimgApi(&BlitParam) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200833 ALOGE("%s::stretchFimgApi() failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200834 return -1;
835 }
836
837 dstBuffer->virt.p = (char *)dst_addr;
838 }
839#else
840 dstBuffer->virt.p = (char *)src_address;
841#endif
842
843 return 0;
844}
845
846int hdmi_set_g_Params(int fd_subdev, int fd_videodev, int layer,
847 int srcColorFormat,
848 int src_w, int src_h,
849 int dst_x, int dst_y, int dst_w, int dst_h)
850{
851#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200852 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200853#endif
854 struct v4l2_rect rect;
855 int src_pad = 0;
856 int sink_pad = 0;
857 int v4l2ColorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(srcColorFormat);
858
859 switch (layer) {
860 case HDMI_LAYER_GRAPHIC_0:
861 sink_pad = MIXER_G0_SUBDEV_PAD_SINK;
862 src_pad = MIXER_G0_SUBDEV_PAD_SOURCE;
863 break;
864 case HDMI_LAYER_GRAPHIC_1:
865 sink_pad = MIXER_G1_SUBDEV_PAD_SINK;
866 src_pad = MIXER_G1_SUBDEV_PAD_SOURCE;
867 break;
868 default:
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200869 ALOGE("%s::invalid layer(%d)", __func__, layer);
codeworkx62f02ba2012-05-20 12:00:36 +0200870 break;
871 };
872
873 rect.left = dst_x;
874 rect.top = dst_y;
875
876#if defined(BOARD_USES_HDMI_FIMGAPI)
877 rect.width = dst_w;
878 rect.height = dst_h;
879#else
880 rect.width = src_w;
881 rect.height = src_h;
882#endif
883
884 /* set sub device for mixer graphic layer input */
885 if (tvout_std_subdev_s_fmt(fd_subdev, sink_pad, rect.width, rect.height, V4L2_MBUS_FMT_XRGB8888_4X8_LE) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200886 ALOGE("%s::tvout_std_subdev_s_fmt(PAD=%d)[graphic layer] failed", __func__, sink_pad);
codeworkx62f02ba2012-05-20 12:00:36 +0200887 return -1;
888 }
889
890 if (tvout_std_subdev_s_crop(fd_subdev, sink_pad, 0, 0, rect.width, rect.height) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200891 ALOGE("%s::tvout_std_subdev_s_crop(PAD=%d)[graphic layer] failed", __func__, sink_pad);
codeworkx62f02ba2012-05-20 12:00:36 +0200892 return -1;
893 }
894
895 if (tvout_std_subdev_s_crop(fd_subdev, src_pad, rect.left, rect.top, rect.width, rect.height) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200896 ALOGE("%s::tvout_std_subdev_s_crop(PAD=%d)[graphic layer] failed", __func__, src_pad);
codeworkx62f02ba2012-05-20 12:00:36 +0200897 return -1;
898 }
899
900 /* set format for mixer graphic layer input device*/
901 if (tvout_std_v4l2_s_fmt(fd_videodev, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_FIELD_ANY, rect.width, rect.height, v4l2ColorFormat, 1) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200902 ALOGE("%s::tvout_std_v4l2_s_fmt()[graphic layer] failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200903 return -1;
904 }
905
906 if (tvout_std_v4l2_s_crop(fd_videodev, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_FIELD_ANY, rect.left, rect.top, rect.width, rect.height) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200907 ALOGE("%s::tvout_std_v4l2_s_crop()[graphic layer] failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200908 return -1;
909 }
910
911 /* request buffer for mixer graphic layer input device */
912 if (tvout_std_v4l2_reqbuf(fd_videodev, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, 2) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200913 ALOGE("%s::tvout_std_v4l2_reqbuf(buf_num=%d)[graphic layer] failed", __func__, 2);
codeworkx62f02ba2012-05-20 12:00:36 +0200914 return -1;
915 }
916
917 return 0;
918}
919
920int hdmi_cable_status()
921{
922#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200923 ALOGD("%s", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200924#endif
925
926 int cable_status = 0;
927 int fd = 0;
928 struct v4l2_control ctrl;
929
930 fd = open(TVOUT0_DEV_G0, O_RDWR);
931 if (fd <= 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200932 ALOGE("%s: graphic layer 0 drv open failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200933 return -1;
934 }
935
936 ctrl.id = V4L2_CID_TV_HPD_STATUS;
937
938 if (ioctl(fd, VIDIOC_S_CTRL, &ctrl) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200939 ALOGE("Get HPD_STATUS fail");
codeworkx62f02ba2012-05-20 12:00:36 +0200940 cable_status = -1;
941 } else {
942 cable_status = ctrl.value;
943 }
944
945#ifdef DEBUG_HDMI_HW_LEVEL
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200946 ALOGD("HPD_STATUS = %d", cable_status);
codeworkx62f02ba2012-05-20 12:00:36 +0200947#endif
948
949 close(fd);
950
951 return cable_status;
952}
953
954int hdmi_outputmode_2_v4l2_output_type(int output_mode)
955{
956 int v4l2_output_type = -1;
957
958 switch (output_mode) {
959 case HDMI_OUTPUT_MODE_YCBCR:
960 v4l2_output_type = V4L2_OUTPUT_TYPE_DIGITAL;
961 break;
962 case HDMI_OUTPUT_MODE_RGB:
963 v4l2_output_type = V4L2_OUTPUT_TYPE_HDMI_RGB;
964 break;
965 case HDMI_OUTPUT_MODE_DVI:
966 v4l2_output_type = V4L2_OUTPUT_TYPE_DVI;
967 break;
968 case COMPOSITE_OUTPUT_MODE:
969 v4l2_output_type = V4L2_OUTPUT_TYPE_COMPOSITE;
970 break;
971 default:
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200972 ALOGE("%s::unmathced HDMI_mode(%d)", __func__, output_mode);
codeworkx62f02ba2012-05-20 12:00:36 +0200973 v4l2_output_type = -1;
974 break;
975 }
976
977 return v4l2_output_type;
978}
979
980int hdmi_v4l2_output_type_2_outputmode(int v4l2_output_type)
981{
982 int outputMode = -1;
983
984 switch (v4l2_output_type) {
985 case V4L2_OUTPUT_TYPE_DIGITAL:
986 outputMode = HDMI_OUTPUT_MODE_YCBCR;
987 break;
988 case V4L2_OUTPUT_TYPE_HDMI_RGB:
989 outputMode = HDMI_OUTPUT_MODE_RGB;
990 break;
991 case V4L2_OUTPUT_TYPE_DVI:
992 outputMode = HDMI_OUTPUT_MODE_DVI;
993 break;
994 case V4L2_OUTPUT_TYPE_COMPOSITE:
995 outputMode = COMPOSITE_OUTPUT_MODE;
996 break;
997 default:
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200998 ALOGE("%s::unmathced v4l2_output_type(%d)", __func__, v4l2_output_type);
codeworkx62f02ba2012-05-20 12:00:36 +0200999 outputMode = -1;
1000 break;
1001 }
1002
1003 return outputMode;
1004}
1005
1006int composite_std_2_v4l2_std_id(int std)
1007{
1008 int std_id = -1;
1009
1010 switch (std) {
1011 case COMPOSITE_STD_NTSC_M:
1012 std_id = V4L2_STD_NTSC_M;
1013 break;
1014 case COMPOSITE_STD_NTSC_443:
1015 std_id = V4L2_STD_NTSC_443;
1016 break;
1017 case COMPOSITE_STD_PAL_BDGHI:
1018 std_id = V4L2_STD_PAL_BDGHI;
1019 break;
1020 case COMPOSITE_STD_PAL_M:
1021 std_id = V4L2_STD_PAL_M;
1022 break;
1023 case COMPOSITE_STD_PAL_N:
1024 std_id = V4L2_STD_PAL_N;
1025 break;
1026 case COMPOSITE_STD_PAL_Nc:
1027 std_id = V4L2_STD_PAL_Nc;
1028 break;
1029 case COMPOSITE_STD_PAL_60:
1030 std_id = V4L2_STD_PAL_60;
1031 break;
1032 default:
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001033 ALOGE("%s::unmathced composite_std(%d)", __func__, std);
codeworkx62f02ba2012-05-20 12:00:36 +02001034 break;
1035 }
1036
1037 return std_id;
1038}
1039
1040int hdmi_check_output_mode(int v4l2_output_type)
1041{
1042 struct HDMIVideoParameter video;
1043 struct HDMIAudioParameter audio;
1044 int calbirate_v4l2_mode = v4l2_output_type;
1045
1046 audio.formatCode = LPCM_FORMAT;
1047 audio.outPacket = HDMI_ASP;
1048 audio.channelNum = CH_2;
1049 audio.sampleFreq = SF_44KHZ;
1050
1051 switch (v4l2_output_type) {
1052 case V4L2_OUTPUT_TYPE_DIGITAL :
1053 video.mode = HDMI;
1054 if (!EDIDHDMIModeSupport(&video)) {
1055 calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DVI;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001056 ALOGI("Change mode into DVI\n");
codeworkx62f02ba2012-05-20 12:00:36 +02001057 break;
1058 }
1059
1060 video.colorSpace = HDMI_CS_YCBCR444;
1061 if (!EDIDColorSpaceSupport(&video)) {
1062 calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_HDMI_RGB;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001063 ALOGI("Change mode into HDMI_RGB\n");
codeworkx62f02ba2012-05-20 12:00:36 +02001064 }
1065 break;
1066
1067 case V4L2_OUTPUT_TYPE_HDMI_RGB:
1068 video.mode = HDMI;
1069 if (!EDIDHDMIModeSupport(&video)) {
1070 calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DVI;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001071 ALOGI("Change mode into DVI\n");
codeworkx62f02ba2012-05-20 12:00:36 +02001072 break;
1073 }
1074
1075 video.colorSpace = HDMI_CS_RGB;
1076 if (!EDIDColorSpaceSupport(&video)) {
1077 calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DIGITAL;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001078 ALOGI("Change mode into HDMI_YCBCR\n");
codeworkx62f02ba2012-05-20 12:00:36 +02001079 }
1080 break;
1081
1082 case V4L2_OUTPUT_TYPE_DVI:
1083 video.mode = DVI;
1084 if (!EDIDHDMIModeSupport(&video)) {
1085 video.colorSpace = HDMI_CS_YCBCR444;
1086 if (!EDIDColorSpaceSupport(&video)) {
1087 calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_HDMI_RGB;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001088 ALOGI("Change mode into HDMI_RGB\n");
codeworkx62f02ba2012-05-20 12:00:36 +02001089 } else {
1090 calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DIGITAL;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001091 ALOGI("Change mode into HDMI_YCBCR\n");
codeworkx62f02ba2012-05-20 12:00:36 +02001092 }
1093 break;
1094 }
1095
1096 break;
1097
1098 default:
1099 break;
1100 }
1101 return calbirate_v4l2_mode;
1102}
1103
1104int hdmi_check_resolution(v4l2_std_id std_id)
1105{
1106 struct HDMIVideoParameter video;
1107 struct HDMIAudioParameter audio;
1108
1109 switch (std_id) {
1110 case V4L2_STD_480P_60_16_9:
1111 video.resolution = v720x480p_60Hz;
1112 video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9;
1113 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1114 break;
1115 case V4L2_STD_480P_60_4_3:
1116 video.resolution = v640x480p_60Hz;
1117 video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3;
1118 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1119 break;
1120 case V4L2_STD_576P_50_16_9:
1121 video.resolution = v720x576p_50Hz;
1122 video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9;
1123 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1124 break;
1125 case V4L2_STD_576P_50_4_3:
1126 video.resolution = v720x576p_50Hz;
1127 video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3;
1128 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1129 break;
1130 case V4L2_STD_720P_60:
1131 video.resolution = v1280x720p_60Hz;
1132 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1133 break;
1134 case V4L2_STD_720P_50:
1135 video.resolution = v1280x720p_50Hz;
1136 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1137 break;
1138 case V4L2_STD_1080P_60:
1139 video.resolution = v1920x1080p_60Hz;
1140 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1141 break;
1142 case V4L2_STD_1080P_50:
1143 video.resolution = v1920x1080p_50Hz;
1144 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1145 break;
1146 case V4L2_STD_1080I_60:
1147 video.resolution = v1920x1080i_60Hz;
1148 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1149 break;
1150 case V4L2_STD_1080I_50:
1151 video.resolution = v1920x1080i_50Hz;
1152 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1153 break;
1154 case V4L2_STD_480P_59:
1155 video.resolution = v720x480p_60Hz;
1156 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1157 break;
1158 case V4L2_STD_720P_59:
1159 video.resolution = v1280x720p_60Hz;
1160 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1161 break;
1162 case V4L2_STD_1080I_59:
1163 video.resolution = v1920x1080i_60Hz;
1164 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1165 break;
1166 case V4L2_STD_1080P_59:
1167 video.resolution = v1920x1080p_60Hz;
1168 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1169 break;
1170 case V4L2_STD_1080P_30:
1171 video.resolution = v1920x1080p_30Hz;
1172 video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT;
1173 break;
1174 case V4L2_STD_TVOUT_720P_60_SBS_HALF:
1175 video.resolution = v1280x720p_60Hz;
1176 video.hdmi_3d_format = HDMI_3D_SSH_FORMAT;
1177 break;
1178 case V4L2_STD_TVOUT_720P_59_SBS_HALF:
1179 video.resolution = v1280x720p_60Hz;
1180 video.hdmi_3d_format = HDMI_3D_SSH_FORMAT;
1181 break;
1182 case V4L2_STD_TVOUT_720P_50_TB:
1183 video.resolution = v1280x720p_50Hz;
1184 video.hdmi_3d_format = HDMI_3D_TB_FORMAT;
1185 break;
1186 case V4L2_STD_TVOUT_1080P_24_TB:
1187 video.resolution = v1920x1080p_24Hz;
1188 video.hdmi_3d_format = HDMI_3D_TB_FORMAT;
1189 break;
1190 case V4L2_STD_TVOUT_1080P_23_TB:
1191 video.resolution = v1920x1080p_24Hz;
1192 video.hdmi_3d_format = HDMI_3D_TB_FORMAT;
1193 break;
1194 default:
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001195 ALOGE("%s::unmathced std_id(%lld)", __func__, std_id);
codeworkx62f02ba2012-05-20 12:00:36 +02001196 return -1;
1197 break;
1198 }
1199
1200 if (!EDIDVideoResolutionSupport(&video)) {
1201#ifdef DEBUG_MSG_ENABLE
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001202 ALOGD("%s::EDIDVideoResolutionSupport(%llx) fail (not suppoted std_id) \n", __func__, std_id);
codeworkx62f02ba2012-05-20 12:00:36 +02001203#endif
1204 return -1;
1205 }
1206
1207 return 0;
1208}
1209
1210int hdmi_resolution_2_std_id(unsigned int resolution, int * w, int * h, v4l2_std_id * std_id, __u32 *preset_id)
1211{
1212 int ret = 0;
1213
1214 switch (resolution) {
1215 case 1080960:
1216 *std_id = V4L2_STD_1080P_60;
1217 *w = 1920;
1218 *h = 1080;
1219 *preset_id = V4L2_DV_1080P60;
1220 break;
1221 case 1080950:
1222 *std_id = V4L2_STD_1080P_50;
1223 *w = 1920;
1224 *h = 1080;
1225 *preset_id = V4L2_DV_1080P50;
1226 break;
1227 case 1080930:
1228 *std_id = V4L2_STD_1080P_30;
1229 *w = 1920;
1230 *h = 1080;
1231 *preset_id = V4L2_DV_1080P30;
1232 break;
1233 case 1080924:
1234 *std_id = V4L2_STD_TVOUT_1080P_24_TB;
1235 *w = 1920;
1236 *h = 1080;
1237 *preset_id = V4L2_DV_1080P24_TB;
1238 break;
1239 case 1080160:
1240 *std_id = V4L2_STD_1080I_60;
1241 *w = 1920;
1242 *h = 1080;
1243 *preset_id = V4L2_DV_1080I60;
1244 break;
1245 case 1080150:
1246 *std_id = V4L2_STD_1080I_50;
1247 *w = 1920;
1248 *h = 1080;
1249 *preset_id = V4L2_DV_1080I50;
1250 break;
1251 case 720960:
1252 *std_id = V4L2_STD_720P_60;
1253 *w = 1280;
1254 *h = 720;
1255 *preset_id = V4L2_DV_720P60;
1256 break;
1257 case 7209601:
1258 *std_id = V4L2_STD_TVOUT_720P_60_SBS_HALF;
1259 *w = 1280;
1260 *h = 720;
1261 *preset_id = V4L2_DV_720P60_SB_HALF;
1262 break;
1263 case 720950:
1264 *std_id = V4L2_STD_720P_50;
1265 *w = 1280;
1266 *h = 720;
1267 *preset_id = V4L2_DV_720P50;
1268 break;
1269 case 7209501:
1270 *std_id = V4L2_STD_TVOUT_720P_50_TB;
1271 *w = 1280;
1272 *h = 720;
1273 *preset_id = V4L2_DV_720P50_TB;
1274 break;
1275 case 5769501:
1276 *std_id = V4L2_STD_576P_50_16_9;
1277 *w = 720;
1278 *h = 576;
1279 *preset_id = V4L2_DV_576P50;
1280 break;
1281 case 5769502:
1282 *std_id = V4L2_STD_576P_50_4_3;
1283 *w = 720;
1284 *h = 576;
1285 *preset_id = V4L2_DV_576P50;
1286 break;
1287 case 4809601:
1288 *std_id = V4L2_STD_480P_60_16_9;
1289 *w = 720;
1290 *h = 480;
1291 *preset_id = V4L2_DV_480P60;
1292 break;
1293 case 4809602:
1294 *std_id = V4L2_STD_480P_60_4_3;
1295 *w = 720;
1296 *h = 480;
1297 *preset_id = V4L2_DV_480P60;
1298 break;
1299 default:
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001300 ALOGE("%s::unmathced resolution(%d)", __func__, resolution);
codeworkx62f02ba2012-05-20 12:00:36 +02001301 ret = -1;
1302 break;
1303 }
1304
1305 return ret;
1306}
1307
1308int hdmi_enable_hdcp(int fd, unsigned int hdcp_en)
1309{
1310 if (ioctl(fd, VIDIOC_HDCP_ENABLE, hdcp_en) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001311 ALOGD("%s::VIDIOC_HDCP_ENABLE(%d) fail \n", __func__, hdcp_en);
codeworkx62f02ba2012-05-20 12:00:36 +02001312 return -1;
1313 }
1314
1315 return 0;
1316}
1317
1318int hdmi_check_audio(int fd)
1319{
1320 struct HDMIAudioParameter audio;
1321 enum state audio_state = ON;
1322 int ret = 0;
1323
1324 audio.formatCode = LPCM_FORMAT;
1325 audio.outPacket = HDMI_ASP;
1326 audio.channelNum = CH_2;
1327 audio.sampleFreq = SF_44KHZ;
1328
1329#if defined(BOARD_USES_EDID)
1330 if (!EDIDAudioModeSupport(&audio))
1331 audio_state = NOT_SUPPORT;
1332 else
1333 audio_state = ON;
1334#endif
1335 if (audio_state == ON) {
1336 if (ioctl(fd, VIDIOC_INIT_AUDIO, 1) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001337 ALOGE("%s::VIDIOC_INIT_AUDIO(1) failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001338 ret = -1;
1339 }
1340 } else {
1341 if (ioctl(fd, VIDIOC_INIT_AUDIO, 0) < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +02001342 ALOGE("%s::VIDIOC_INIT_AUDIO(0) failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +02001343 ret = -1;
1344 }
1345 }
1346
1347 return ret;
1348}
1349
1350}