| /* |
| * Copyright@ Samsung Electronics Co. LTD |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| //#define LOG_NDEBUG 0 |
| //#define LOG_TAG "libhdmi" |
| //#define DEBUG_HDMI_HW_LEVEL |
| #include <cutils/log.h> |
| |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <sys/ioctl.h> |
| #include <sys/mman.h> |
| #include <fcntl.h> |
| #include <ctype.h> |
| #include <unistd.h> |
| #include <string.h> |
| #include <errno.h> |
| #include <signal.h> |
| |
| #include "sec_utils_v4l2.h" |
| #include "s5p_tvout_v4l2.h" |
| |
| #include "videodev2.h" |
| |
| #if defined(BOARD_USES_HDMI_FIMGAPI) |
| #include "sec_g2d_4x.h" |
| #include "FimgApi.h" |
| #endif |
| |
| #include "audio.h" |
| #include "video.h" |
| #include "../libhdmi/libsForhdmi/libedid/libedid.h" |
| #include "../libhdmi/libsForhdmi/libcec/libcec.h" |
| |
| #include "SecGscaler.h" |
| #include "SecHdmiCommon.h" |
| #include "SecHdmiV4L2Utils.h" |
| |
| namespace android { |
| |
| unsigned int output_type = V4L2_OUTPUT_TYPE_DIGITAL; |
| v4l2_std_id t_std_id = V4L2_STD_1080P_30; |
| int g_hpd_state = HPD_CABLE_OUT; |
| unsigned int g_hdcp_en = 0; |
| |
| #if defined(BOARD_USES_HDMI_FIMGAPI) |
| unsigned int g2d_reserved_memory0 = 0; |
| unsigned int g2d_reserved_memory1 = 0; |
| unsigned int g2d_reserved_memory_size = 0; |
| unsigned int cur_g2d_address = 0; |
| #endif |
| |
| void display_menu(void) |
| { |
| struct HDMIVideoParameter video; |
| struct HDMIAudioParameter audio; |
| |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| |
| audio.formatCode = LPCM_FORMAT; |
| audio.outPacket = HDMI_ASP; |
| audio.channelNum = CH_2; |
| audio.sampleFreq = SF_44KHZ; |
| |
| LOGI("=============== HDMI Audio =============\n"); |
| |
| if (EDIDAudioModeSupport(&audio)) |
| LOGI("= 2CH_PCM 44100Hz audio supported =\n"); |
| |
| LOGI("========= HDMI Mode & Color Space =======\n"); |
| |
| video.mode = HDMI; |
| if (EDIDHDMIModeSupport(&video)) { |
| video.colorSpace = HDMI_CS_YCBCR444; |
| if (EDIDColorSpaceSupport(&video)) |
| LOGI("= 1. HDMI(YCbCr) =\n"); |
| |
| video.colorSpace = HDMI_CS_RGB; |
| if (EDIDColorSpaceSupport(&video)) |
| LOGI("= 2. HDMI(RGB) =\n"); |
| } else { |
| video.mode = DVI; |
| if (EDIDHDMIModeSupport(&video)) |
| LOGI("= 3. DVI =\n"); |
| } |
| |
| LOGI("=========== HDMI Rseolution ========\n"); |
| |
| /* 480P */ |
| video.resolution = v720x480p_60Hz; |
| video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= 4. 480P_60_16_9 (0x04000000) =\n"); |
| |
| video.resolution = v640x480p_60Hz; |
| video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= 5. 480P_60_4_3 (0x05000000) =\n"); |
| |
| /* 576P */ |
| video.resolution = v720x576p_50Hz; |
| video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= 6. 576P_50_16_9 (0x06000000) =\n"); |
| |
| video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= 7. 576P_50_4_3 (0x07000000) =\n"); |
| |
| /* 720P 60 */ |
| video.resolution = v1280x720p_60Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= 8. 720P_60 (0x08000000) =\n"); |
| |
| /* 720P_50 */ |
| video.resolution = v1280x720p_50Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= 9. 720P_50 (0x09000000) =\n"); |
| |
| /* 1080P_60 */ |
| video.resolution = v1920x1080p_60Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= a. 1080P_60 (0x0a000000) =\n"); |
| |
| /* 1080P_50 */ |
| video.resolution = v1920x1080p_50Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= b. 1080P_50 (0x0b000000) =\n"); |
| |
| /* 1080I_60 */ |
| video.resolution = v1920x1080i_60Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= c. 1080I_60 (0x0c000000) =\n"); |
| |
| /* 1080I_50 */ |
| video.resolution = v1920x1080i_50Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= d. 1080I_50 (0x0d000000) =\n"); |
| |
| /* 1080P_30 */ |
| video.resolution = v1920x1080p_30Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= e. 1080P_30 (0x12000000) =\n"); |
| |
| LOGI("=========== HDMI 3D Format ========\n"); |
| |
| /* 720P_60_SBS_HALF */ |
| video.resolution = v1280x720p_60Hz; |
| video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= f. 720P_60_SBS_HALF (0x13000000) =\n"); |
| |
| /* 720P_59_SBS_HALF */ |
| video.resolution = v1280x720p_60Hz; |
| video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= 10. 720P_59_SBS_HALF (0x14000000) =\n"); |
| |
| /* 720P_50_TB */ |
| video.resolution = v1280x720p_50Hz; |
| video.hdmi_3d_format = HDMI_3D_TB_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= 11. 720P_50_TB (0x15000000) =\n"); |
| |
| /* 1080P_24_TB */ |
| video.resolution = v1920x1080p_24Hz; |
| video.hdmi_3d_format = HDMI_3D_TB_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= 12. 1080P_24_TB (0x16000000) =\n"); |
| |
| /* 1080P_23_TB */ |
| video.resolution = v1920x1080p_24Hz; |
| video.hdmi_3d_format = HDMI_3D_TB_FORMAT; |
| if (EDIDVideoResolutionSupport(&video)) |
| LOGI("= 13. 1080P_24_TB (0x17000000) =\n"); |
| LOGI("=========================================\n"); |
| } |
| |
| int tvout_init(int fd_tvout, __u32 preset_id) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s::preset_id = 0x%x", __func__, preset_id); |
| #endif |
| |
| int ret; |
| struct v4l2_output output; |
| struct v4l2_dv_preset preset; |
| |
| unsigned int matched = 0, i = 0; |
| int output_index; |
| |
| if (fd_tvout <= 0) { |
| fd_tvout = open(TVOUT0_DEV_G0, O_RDWR); |
| if (fd_tvout < 0) { |
| LOGE("%s::fd_tvout open failed", __func__); |
| return -1; |
| } |
| } |
| /* |
| if (output_type >= V4L2_OUTPUT_TYPE_DIGITAL && |
| output_type <= V4L2_OUTPUT_TYPE_DVI) |
| if (ioctl(fd_tvout, VIDIOC_HDCP_ENABLE, g_hdcp_en) < 0) |
| LOGE("%s::VIDIOC_HDCP_ENABLE failed %d", __func__, errno); |
| */ |
| i = 0; |
| |
| do { |
| output.index = i; |
| ret = tvout_v4l2_enum_output(fd_tvout, &output); |
| LOGV("%s::output_type=%d output.index=%d .name=%s", __func__, output_type, output.index, output.name); |
| if (output.type == output_type) { |
| matched = 1; |
| break; |
| } |
| i++; |
| } while (ret >=0); |
| /* |
| if (!matched) { |
| LOGE("%s::no matched output type [type=0x%08x]", __func__, output_type); |
| return -1; |
| } |
| |
| tvout_v4l2_s_output(fd_tvout, output.index); |
| output_index = 0; |
| tvout_v4l2_g_output(fd_tvout, &output_index); |
| */ |
| |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s::input preset_id=0x%08x", __func__, preset_id); |
| #endif |
| |
| if (output.capabilities & V4L2_OUT_CAP_PRESETS) { |
| tvout_std_v4l2_enum_dv_presets(fd_tvout); |
| preset.preset = preset_id; |
| if (tvout_std_v4l2_s_dv_preset(fd_tvout, &preset) < 0 ) { |
| LOGE("%s::tvout_std_v4l2_s_dv_preset failed", __func__); |
| return -1; |
| } |
| } |
| |
| return fd_tvout; |
| } |
| |
| int tvout_deinit() |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| |
| return 0; |
| } |
| |
| int tvout_std_v4l2_querycap(int fd, char *node) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| struct v4l2_capability v4l2cap; |
| |
| if (ioctl(fd, VIDIOC_QUERYCAP, &v4l2cap) < 0) { |
| LOGE("%s::VIDIOC_QUERYCAP failed", __func__); |
| return -1; |
| } |
| |
| if (!(v4l2cap.capabilities & V4L2_CAP_STREAMING)) { |
| LOGE("%s::%s is not support streaming", __func__, node); |
| return -1; |
| } |
| |
| if (!(v4l2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE)) { |
| LOGE("%s::%s is not support video output mplane", __func__, node); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int 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) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| |
| struct v4l2_format fmt; |
| |
| fmt.type = type; |
| if (ioctl(fd, VIDIOC_G_FMT, &fmt) < 0) { |
| LOGE("%s::VIDIOC_G_FMT failed", __func__); |
| return -1; |
| } |
| |
| switch (fmt.type) { |
| case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
| case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
| fmt.fmt.pix.width = w; |
| fmt.fmt.pix.height = h; |
| fmt.fmt.pix.pixelformat = colorformat; |
| fmt.fmt.pix.field = field; |
| break; |
| case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
| case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
| fmt.fmt.pix_mp.width = w; |
| fmt.fmt.pix_mp.height = h; |
| fmt.fmt.pix_mp.pixelformat = colorformat; |
| fmt.fmt.pix_mp.field = field; |
| fmt.fmt.pix_mp.num_planes = num_planes; |
| break; |
| default: |
| LOGE("%s::invalid buffer type", __func__); |
| return -1; |
| break; |
| } |
| |
| if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { |
| LOGE("%s::VIDIOC_S_FMT failed", __func__); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int tvout_std_v4l2_s_crop(int fd, enum v4l2_buf_type type, enum v4l2_field, int x, int y, int w, int h) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| struct v4l2_crop crop; |
| |
| crop.type = type; |
| crop.c.left = x; |
| crop.c.top = y; |
| crop.c.width = w; |
| crop.c.height = h; |
| |
| if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) { |
| LOGE("%s::VIDIOC_S_CROP (x=%d, y=%d, w=%d, h=%d) failed", |
| __func__, x, y, w, h); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int tvout_std_v4l2_s_ctrl(int fd, int id, int value) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| struct v4l2_control vc; |
| |
| vc.id = id; |
| vc.value = value; |
| |
| if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) { |
| LOGE("%s::VIDIOC_S_CTRL (id=%d,value=%d) failed", __func__, id, value); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int tvout_std_v4l2_reqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int num_bufs) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| struct v4l2_requestbuffers reqbuf; |
| |
| reqbuf.type = type; |
| reqbuf.memory = memory; |
| reqbuf.count = num_bufs; |
| |
| if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0) { |
| LOGE("%s::VIDIOC_REQBUFS failed", __func__); |
| return -1; |
| } |
| |
| if (reqbuf.count < num_bufs) { |
| LOGE("%s::VIDIOC_REQBUFS failed ((reqbuf.count(%d) < num_bufs(%d))", |
| __func__, reqbuf.count, num_bufs); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int 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) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| struct v4l2_buffer buf; |
| struct v4l2_plane planes[MAX_PLANES_MIXER]; |
| |
| memset(&buf, 0, sizeof(struct v4l2_buffer)); |
| |
| for (int i = 0; i < MAX_PLANES_MIXER; i++) |
| memset(&planes[i], 0, sizeof(struct v4l2_plane)); |
| |
| if (MAX_BUFFERS_MIXER <= buf_index || MAX_PLANES_MIXER <= num_planes) { |
| LOGE("%s::exceed MAX! : buf_index=%d, num_plane=%d", __func__, buf_index, num_planes); |
| return -1; |
| } |
| |
| buf.type = type; |
| buf.memory = V4L2_MEMORY_MMAP; |
| buf.index = buf_index; |
| buf.length = num_planes; |
| buf.m.planes = planes; |
| |
| if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) { |
| LOGE("%s::VIDIOC_QUERYBUF failed, plane_cnt=%d", __func__, buf.length); |
| return -1; |
| } |
| |
| for (unsigned int i = 0; i < num_planes; i++) { |
| if ((secBuf->virt.extP[i] = (char *)mmap(0, buf.m.planes[i].length, |
| PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.planes[i].m.mem_offset)) < 0) { |
| LOGE("%s::mmap failed", __func__); |
| LOGE("%s::Offset = 0x%x", __func__, buf.m.planes[i].m.mem_offset); |
| LOGE("%s::Legnth = %d" , __func__, buf.m.planes[i].length); |
| LOGE("%s::vaddr[%d][%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]); |
| return -1; |
| } |
| secBuf->size.extS[i] = buf.m.planes[i].length; |
| |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s::vaddr[bufindex=%d][planeidx=%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]); |
| LOGD("%s::Legnth = %d" , __func__, buf.m.planes[i].length); |
| #endif |
| } |
| |
| return 0; |
| } |
| |
| int tvout_std_v4l2_qbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int buf_index, int num_planes, SecBuffer *secBuf) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| struct v4l2_buffer buf; |
| struct v4l2_plane planes[MAX_PLANES_MIXER]; |
| |
| memset(&buf, 0, sizeof(struct v4l2_buffer)); |
| |
| for (int i = 0; i < MAX_PLANES_MIXER; i++) |
| memset(&planes[i], 0, sizeof(struct v4l2_plane)); |
| |
| buf.type = type; |
| buf.memory = memory; |
| buf.length = num_planes; |
| buf.index = buf_index; |
| buf.m.planes = planes; |
| |
| for (unsigned int i = 0; i < buf.length; i++) { |
| buf.m.planes[i].m.userptr = (unsigned long)secBuf->virt.extP[i]; |
| buf.m.planes[i].length = secBuf->size.extS[i]; |
| buf.m.planes[i].bytesused = buf.m.planes[i].length; |
| |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s::buf.index=%d", __func__, buf.index); |
| LOGD("%s::buf.m.planes[%d].m.userptr=0x%08x", __func__, i, (unsigned int)buf.m.planes[i].m.userptr); |
| LOGD("%s::buf.m.planes[%d].length =0x%08x", __func__, i, buf.m.planes[i].length); |
| LOGD("%s::buf.m.planes[%d].bytesused=0x%08x", __func__, i, buf.m.planes[i].bytesused); |
| #endif |
| } |
| |
| if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) { |
| LOGE("%s::VIDIOC_QBUF failed", __func__); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int tvout_std_v4l2_dqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int *buf_index, int num_planes) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| struct v4l2_buffer buf; |
| struct v4l2_plane planes[MAX_PLANES_MIXER]; |
| |
| memset(&buf, 0, sizeof(struct v4l2_buffer)); |
| |
| for (int i = 0; i < MAX_PLANES_GSCALER; i++) |
| memset(&planes[i], 0, sizeof(struct v4l2_plane)); |
| |
| |
| buf.type = type; |
| buf.memory = memory; |
| buf.length = num_planes; |
| buf.m.planes = planes; |
| |
| if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) { |
| LOGE("%s::VIDIOC_DQBUF failed", __func__); |
| return -1; |
| } |
| *buf_index = buf.index; |
| |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s::buf.index=%d", __func__, buf.index); |
| #endif |
| |
| return 0; |
| } |
| |
| int tvout_std_v4l2_streamon(int fd, enum v4l2_buf_type type) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| if (ioctl(fd, VIDIOC_STREAMON, &type) < 0) { |
| LOGE("%s::VIDIOC_STREAMON failed", __func__); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int tvout_std_v4l2_streamoff(int fd, enum v4l2_buf_type type) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0) { |
| LOGE("%s::VIDIOC_STREAMOFF failed", __func__); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int tvout_v4l2_enum_output(int fd, struct v4l2_output *output) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| int ret = -1 ; |
| ret = ioctl(fd, VIDIOC_ENUMOUTPUT, output); |
| |
| if (ret < 0) { |
| if (errno == EINVAL) |
| return -1; |
| LOGE("%s::VIDIOC_ENUMOUTPUT", __func__); |
| return -1; |
| } |
| LOGD("%s::index=%d, type=0x%08x, name=%s", |
| __func__, output->index, output->type, output->name); |
| |
| return ret; |
| } |
| |
| int tvout_v4l2_s_output(int fd, int index) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| if (ioctl(fd, VIDIOC_S_OUTPUT, &index) < 0) { |
| LOGE("%s::VIDIOC_S_OUTPUT failed", __func__); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int tvout_v4l2_g_output(int fd, int *index) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| if (ioctl(fd, VIDIOC_G_OUTPUT, index) < 0) { |
| LOGE("%s::VIDIOC_G_OUTPUT failed", __func__); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int tvout_std_v4l2_enum_dv_presets(int fd) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| struct v4l2_dv_enum_preset enum_preset; |
| int ret = -1; |
| |
| for (int index = 0; ; index++) { |
| enum_preset.index = index; |
| ret = ioctl(fd, VIDIOC_ENUM_DV_PRESETS, &enum_preset); |
| |
| if (ret < 0) { |
| if (errno == EINVAL) |
| break; |
| LOGE("%s::VIDIOC_ENUM_DV_PRESETS", __func__); |
| return -1; |
| } |
| LOGD("%s::index=%d, preset=0x%08x, name=%s, w=%d, h=%d", |
| __func__, enum_preset.index, enum_preset.preset, enum_preset.name, enum_preset.width, enum_preset.height); |
| } |
| |
| return 0; |
| } |
| |
| int tvout_std_v4l2_s_dv_preset(int fd, struct v4l2_dv_preset *preset) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| if (ioctl(fd, VIDIOC_S_DV_PRESET, preset) < 0) { |
| LOGE("%s::VIDIOC_S_DV_PRESET failed preset_id=%d", __func__, preset->preset); |
| return -1; |
| } |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s::preset_id=%d", __func__, preset->preset); |
| #endif |
| return 0; |
| } |
| |
| int tvout_std_subdev_s_fmt(int fd, unsigned int pad, int w, int h, enum v4l2_mbus_pixelcode code) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| struct v4l2_subdev_format fmt; |
| |
| fmt.pad = pad; |
| fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; |
| fmt.format.width = w; |
| fmt.format.height = h; |
| fmt.format.code = code; |
| |
| if (ioctl(fd, VIDIOC_SUBDEV_S_FMT, &fmt) < 0) { |
| LOGE("%s::VIDIOC_SUBDEV_S_FMT", __func__); |
| return -1; |
| } |
| |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s::format w=%d, h=%d", __func__, fmt.format.width, fmt.format.height); |
| #endif |
| return 0; |
| } |
| int tvout_std_subdev_s_crop(int fd, unsigned int pad, int x, int y, int w, int h) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s::pad=%d, crop x=%d, y=%d, w=%d, h=%d", __func__, pad, x, y, w, h); |
| #endif |
| |
| struct v4l2_subdev_crop crop; |
| |
| crop.pad = pad; |
| crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; |
| crop.rect.left = x; |
| crop.rect.top = y; |
| crop.rect.width = w; |
| crop.rect.height = h; |
| |
| if (ioctl(fd, VIDIOC_SUBDEV_S_CROP, &crop) < 0) { |
| LOGE("%s::VIDIOC_SUBDEV_S_CROP", __func__); |
| return -1; |
| } |
| |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%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); |
| #endif |
| |
| return 0; |
| } |
| |
| #define ROUND_UP(value, boundary) ((((uint32_t)(value)) + \ |
| (((uint32_t) boundary)-1)) & \ |
| (~(((uint32_t) boundary)-1))) |
| |
| void hdmi_cal_rect(int src_w, int src_h, int dst_w, int dst_h, struct v4l2_rect *dst_rect) |
| { |
| if (dst_w * src_h <= dst_h * src_w) { |
| dst_rect->left = 0; |
| dst_rect->top = (dst_h - ((dst_w * src_h) / src_w)) >> 1; |
| dst_rect->width = dst_w; |
| dst_rect->height = ((dst_w * src_h) / src_w); |
| } else { |
| dst_rect->left = (dst_w - ((dst_h * src_w) / src_h)) >> 1; |
| dst_rect->top = 0; |
| dst_rect->width = ((dst_h * src_w) / src_h); |
| dst_rect->height = dst_h; |
| } |
| } |
| |
| int hdmi_set_videolayer(int fd, int hdmiW, int hdmiH, struct v4l2_rect * rect) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| if (tvout_std_subdev_s_fmt(fd, MIXER_V_SUBDEV_PAD_SINK, hdmiW, hdmiH, V4L2_MBUS_FMT_YUV8_1X24) < 0) { |
| LOGE("%s::tvout_std_subdev_s_fmt(PAD=%d)[videolayer] failed", __func__, MIXER_V_SUBDEV_PAD_SINK); |
| return -1; |
| } |
| |
| if (tvout_std_subdev_s_crop(fd, MIXER_V_SUBDEV_PAD_SINK, 0, 0, rect->width, rect->height) < 0) { |
| LOGE("%s::tvout_std_subdev_s_crop(PAD=%d)[videolayer] failed", __func__, MIXER_V_SUBDEV_PAD_SINK); |
| return -1; |
| } |
| |
| if (tvout_std_subdev_s_crop(fd, MIXER_V_SUBDEV_PAD_SOURCE, rect->left, rect->top, rect->width, rect->height) < 0) { |
| LOGE("%s::tvout_std_subdev_s_crop(PAD=%d)[videolayer] failed", __func__, MIXER_V_SUBDEV_PAD_SOURCE); |
| return -1; |
| } |
| return 0; |
| } |
| |
| int hdmi_set_graphiclayer(int fd_subdev, int fd_videodev,int layer, |
| int srcColorFormat, |
| int src_w, int src_h, |
| unsigned int src_address, SecBuffer * dstBuffer, |
| int dst_x, int dst_y, int dst_w, int dst_h, |
| int rotVal) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| #if defined(BOARD_USES_HDMI_FIMGAPI) |
| int dst_color_format; |
| int dst_bpp; |
| unsigned char *dst_addr; |
| fimg2d_blit BlitParam; |
| rotation g2d_rotation; |
| |
| fimg2d_addr srcAddr; |
| fimg2d_image srcImage; |
| fimg2d_rect srcRect; |
| |
| fimg2d_addr dstAddr; |
| fimg2d_image dstImage; |
| fimg2d_rect dstRect; |
| |
| fimg2d_clip dstClip; |
| fimg2d_scale Scaling; |
| |
| switch (t_std_id) { |
| case V4L2_STD_1080P_60: |
| case V4L2_STD_1080P_30: |
| case V4L2_STD_1080I_60: |
| case V4L2_STD_TVOUT_720P_60_SBS_HALF: |
| case V4L2_STD_TVOUT_720P_59_SBS_HALF: |
| case V4L2_STD_TVOUT_1080P_24_TB: |
| case V4L2_STD_TVOUT_1080P_23_TB: |
| dst_color_format = CF_ARGB_8888; |
| dst_bpp = 4; |
| break; |
| case V4L2_STD_480P_60_16_9: |
| case V4L2_STD_576P_50_16_9: |
| case V4L2_STD_720P_60: |
| case V4L2_STD_TVOUT_720P_50_TB: |
| default: |
| dst_color_format = CF_ARGB_4444; |
| dst_bpp = 2; |
| break; |
| } |
| |
| static unsigned int prev_src_addr = 0; |
| |
| if ((cur_g2d_address == 0) || (src_address != prev_src_addr)) { |
| if ((cur_g2d_address == 0) || (cur_g2d_address == g2d_reserved_memory1)) |
| dst_addr = (unsigned char *)g2d_reserved_memory0; |
| else |
| dst_addr = (unsigned char *)g2d_reserved_memory1; |
| |
| cur_g2d_address = (unsigned int)dst_addr; |
| prev_src_addr = src_address; |
| |
| srcAddr = {(addr_space)ADDR_USER, (unsigned long)src_address, src_w*src_h*4, 1, 0}; |
| srcImage = {srcAddr, srcAddr, src_w, src_h, src_w*4, AX_RGB, CF_ARGB_8888}; |
| srcRect = {0, 0, src_w, src_h}; |
| |
| dstAddr = {(addr_space)ADDR_USER, (unsigned long)dst_addr, dst_w*dst_h*dst_bpp, 1, 0}; |
| dstImage = {dstAddr, dstAddr, dst_w, dst_h, dst_w*dst_bpp, AX_RGB, (color_format)dst_color_format}; |
| dstRect = {0, 0, dst_w, dst_h}; |
| dstClip = {0, 0, 0, dst_w, dst_h}; |
| |
| if (rotVal == 0 || rotVal == 180) |
| Scaling = {SCALING_BILINEAR, SCALING_PIXELS, 0, 0, src_w, src_h, dst_w, dst_h}; |
| else |
| Scaling = {SCALING_BILINEAR, SCALING_PIXELS, 0, 0, src_w, src_h, dst_h, dst_w}; |
| |
| switch (rotVal) { |
| case 0: |
| g2d_rotation = ORIGIN; |
| break; |
| case 90: |
| g2d_rotation = ROT_90; |
| break; |
| case 180: |
| g2d_rotation = ROT_180; |
| break; |
| case 270: |
| g2d_rotation = ROT_270; |
| break; |
| default: |
| LOGE("%s::invalid rotVal(%d) : failed", __func__, rotVal); |
| return -1; |
| break; |
| } |
| |
| BlitParam = {BLIT_OP_SRC, NON_PREMULTIPLIED, 0xff, 0, g2d_rotation, &Scaling, 0, 0, &dstClip, 0, &srcImage, &dstImage, NULL, &srcRect, &dstRect, NULL, 0}; |
| |
| if (stretchFimgApi(&BlitParam) < 0) { |
| LOGE("%s::stretchFimgApi() failed", __func__); |
| return -1; |
| } |
| |
| dstBuffer->virt.p = (char *)dst_addr; |
| } |
| #else |
| dstBuffer->virt.p = (char *)src_address; |
| #endif |
| |
| return 0; |
| } |
| |
| int hdmi_set_g_Params(int fd_subdev, int fd_videodev, int layer, |
| int srcColorFormat, |
| int src_w, int src_h, |
| int dst_x, int dst_y, int dst_w, int dst_h) |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| struct v4l2_rect rect; |
| int src_pad = 0; |
| int sink_pad = 0; |
| int v4l2ColorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(srcColorFormat); |
| |
| switch (layer) { |
| case HDMI_LAYER_GRAPHIC_0: |
| sink_pad = MIXER_G0_SUBDEV_PAD_SINK; |
| src_pad = MIXER_G0_SUBDEV_PAD_SOURCE; |
| break; |
| case HDMI_LAYER_GRAPHIC_1: |
| sink_pad = MIXER_G1_SUBDEV_PAD_SINK; |
| src_pad = MIXER_G1_SUBDEV_PAD_SOURCE; |
| break; |
| default: |
| LOGE("%s::invalid layer(%d)", __func__, layer); |
| break; |
| }; |
| |
| rect.left = dst_x; |
| rect.top = dst_y; |
| |
| #if defined(BOARD_USES_HDMI_FIMGAPI) |
| rect.width = dst_w; |
| rect.height = dst_h; |
| #else |
| rect.width = src_w; |
| rect.height = src_h; |
| #endif |
| |
| /* set sub device for mixer graphic layer input */ |
| if (tvout_std_subdev_s_fmt(fd_subdev, sink_pad, rect.width, rect.height, V4L2_MBUS_FMT_XRGB8888_4X8_LE) < 0) { |
| LOGE("%s::tvout_std_subdev_s_fmt(PAD=%d)[graphic layer] failed", __func__, sink_pad); |
| return -1; |
| } |
| |
| if (tvout_std_subdev_s_crop(fd_subdev, sink_pad, 0, 0, rect.width, rect.height) < 0) { |
| LOGE("%s::tvout_std_subdev_s_crop(PAD=%d)[graphic layer] failed", __func__, sink_pad); |
| return -1; |
| } |
| |
| if (tvout_std_subdev_s_crop(fd_subdev, src_pad, rect.left, rect.top, rect.width, rect.height) < 0) { |
| LOGE("%s::tvout_std_subdev_s_crop(PAD=%d)[graphic layer] failed", __func__, src_pad); |
| return -1; |
| } |
| |
| /* set format for mixer graphic layer input device*/ |
| if (tvout_std_v4l2_s_fmt(fd_videodev, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_FIELD_ANY, rect.width, rect.height, v4l2ColorFormat, 1) < 0) { |
| LOGE("%s::tvout_std_v4l2_s_fmt()[graphic layer] failed", __func__); |
| return -1; |
| } |
| |
| 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) { |
| LOGE("%s::tvout_std_v4l2_s_crop()[graphic layer] failed", __func__); |
| return -1; |
| } |
| |
| /* request buffer for mixer graphic layer input device */ |
| if (tvout_std_v4l2_reqbuf(fd_videodev, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, 2) < 0) { |
| LOGE("%s::tvout_std_v4l2_reqbuf(buf_num=%d)[graphic layer] failed", __func__, 2); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int hdmi_cable_status() |
| { |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("%s", __func__); |
| #endif |
| |
| int cable_status = 0; |
| int fd = 0; |
| struct v4l2_control ctrl; |
| |
| fd = open(TVOUT0_DEV_G0, O_RDWR); |
| if (fd <= 0) { |
| LOGE("%s: graphic layer 0 drv open failed", __func__); |
| return -1; |
| } |
| |
| ctrl.id = V4L2_CID_TV_HPD_STATUS; |
| |
| if (ioctl(fd, VIDIOC_S_CTRL, &ctrl) < 0) { |
| LOGE("Get HPD_STATUS fail"); |
| cable_status = -1; |
| } else { |
| cable_status = ctrl.value; |
| } |
| |
| #ifdef DEBUG_HDMI_HW_LEVEL |
| LOGD("HPD_STATUS = %d", cable_status); |
| #endif |
| |
| close(fd); |
| |
| return cable_status; |
| } |
| |
| int hdmi_outputmode_2_v4l2_output_type(int output_mode) |
| { |
| int v4l2_output_type = -1; |
| |
| switch (output_mode) { |
| case HDMI_OUTPUT_MODE_YCBCR: |
| v4l2_output_type = V4L2_OUTPUT_TYPE_DIGITAL; |
| break; |
| case HDMI_OUTPUT_MODE_RGB: |
| v4l2_output_type = V4L2_OUTPUT_TYPE_HDMI_RGB; |
| break; |
| case HDMI_OUTPUT_MODE_DVI: |
| v4l2_output_type = V4L2_OUTPUT_TYPE_DVI; |
| break; |
| case COMPOSITE_OUTPUT_MODE: |
| v4l2_output_type = V4L2_OUTPUT_TYPE_COMPOSITE; |
| break; |
| default: |
| LOGE("%s::unmathced HDMI_mode(%d)", __func__, output_mode); |
| v4l2_output_type = -1; |
| break; |
| } |
| |
| return v4l2_output_type; |
| } |
| |
| int hdmi_v4l2_output_type_2_outputmode(int v4l2_output_type) |
| { |
| int outputMode = -1; |
| |
| switch (v4l2_output_type) { |
| case V4L2_OUTPUT_TYPE_DIGITAL: |
| outputMode = HDMI_OUTPUT_MODE_YCBCR; |
| break; |
| case V4L2_OUTPUT_TYPE_HDMI_RGB: |
| outputMode = HDMI_OUTPUT_MODE_RGB; |
| break; |
| case V4L2_OUTPUT_TYPE_DVI: |
| outputMode = HDMI_OUTPUT_MODE_DVI; |
| break; |
| case V4L2_OUTPUT_TYPE_COMPOSITE: |
| outputMode = COMPOSITE_OUTPUT_MODE; |
| break; |
| default: |
| LOGE("%s::unmathced v4l2_output_type(%d)", __func__, v4l2_output_type); |
| outputMode = -1; |
| break; |
| } |
| |
| return outputMode; |
| } |
| |
| int composite_std_2_v4l2_std_id(int std) |
| { |
| int std_id = -1; |
| |
| switch (std) { |
| case COMPOSITE_STD_NTSC_M: |
| std_id = V4L2_STD_NTSC_M; |
| break; |
| case COMPOSITE_STD_NTSC_443: |
| std_id = V4L2_STD_NTSC_443; |
| break; |
| case COMPOSITE_STD_PAL_BDGHI: |
| std_id = V4L2_STD_PAL_BDGHI; |
| break; |
| case COMPOSITE_STD_PAL_M: |
| std_id = V4L2_STD_PAL_M; |
| break; |
| case COMPOSITE_STD_PAL_N: |
| std_id = V4L2_STD_PAL_N; |
| break; |
| case COMPOSITE_STD_PAL_Nc: |
| std_id = V4L2_STD_PAL_Nc; |
| break; |
| case COMPOSITE_STD_PAL_60: |
| std_id = V4L2_STD_PAL_60; |
| break; |
| default: |
| LOGE("%s::unmathced composite_std(%d)", __func__, std); |
| break; |
| } |
| |
| return std_id; |
| } |
| |
| int hdmi_check_output_mode(int v4l2_output_type) |
| { |
| struct HDMIVideoParameter video; |
| struct HDMIAudioParameter audio; |
| int calbirate_v4l2_mode = v4l2_output_type; |
| |
| audio.formatCode = LPCM_FORMAT; |
| audio.outPacket = HDMI_ASP; |
| audio.channelNum = CH_2; |
| audio.sampleFreq = SF_44KHZ; |
| |
| switch (v4l2_output_type) { |
| case V4L2_OUTPUT_TYPE_DIGITAL : |
| video.mode = HDMI; |
| if (!EDIDHDMIModeSupport(&video)) { |
| calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DVI; |
| LOGI("Change mode into DVI\n"); |
| break; |
| } |
| |
| video.colorSpace = HDMI_CS_YCBCR444; |
| if (!EDIDColorSpaceSupport(&video)) { |
| calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_HDMI_RGB; |
| LOGI("Change mode into HDMI_RGB\n"); |
| } |
| break; |
| |
| case V4L2_OUTPUT_TYPE_HDMI_RGB: |
| video.mode = HDMI; |
| if (!EDIDHDMIModeSupport(&video)) { |
| calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DVI; |
| LOGI("Change mode into DVI\n"); |
| break; |
| } |
| |
| video.colorSpace = HDMI_CS_RGB; |
| if (!EDIDColorSpaceSupport(&video)) { |
| calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DIGITAL; |
| LOGI("Change mode into HDMI_YCBCR\n"); |
| } |
| break; |
| |
| case V4L2_OUTPUT_TYPE_DVI: |
| video.mode = DVI; |
| if (!EDIDHDMIModeSupport(&video)) { |
| video.colorSpace = HDMI_CS_YCBCR444; |
| if (!EDIDColorSpaceSupport(&video)) { |
| calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_HDMI_RGB; |
| LOGI("Change mode into HDMI_RGB\n"); |
| } else { |
| calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DIGITAL; |
| LOGI("Change mode into HDMI_YCBCR\n"); |
| } |
| break; |
| } |
| |
| break; |
| |
| default: |
| break; |
| } |
| return calbirate_v4l2_mode; |
| } |
| |
| int hdmi_check_resolution(v4l2_std_id std_id) |
| { |
| struct HDMIVideoParameter video; |
| struct HDMIAudioParameter audio; |
| |
| switch (std_id) { |
| case V4L2_STD_480P_60_16_9: |
| video.resolution = v720x480p_60Hz; |
| video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_480P_60_4_3: |
| video.resolution = v640x480p_60Hz; |
| video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_576P_50_16_9: |
| video.resolution = v720x576p_50Hz; |
| video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_576P_50_4_3: |
| video.resolution = v720x576p_50Hz; |
| video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_720P_60: |
| video.resolution = v1280x720p_60Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_720P_50: |
| video.resolution = v1280x720p_50Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_1080P_60: |
| video.resolution = v1920x1080p_60Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_1080P_50: |
| video.resolution = v1920x1080p_50Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_1080I_60: |
| video.resolution = v1920x1080i_60Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_1080I_50: |
| video.resolution = v1920x1080i_50Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_480P_59: |
| video.resolution = v720x480p_60Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_720P_59: |
| video.resolution = v1280x720p_60Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_1080I_59: |
| video.resolution = v1920x1080i_60Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_1080P_59: |
| video.resolution = v1920x1080p_60Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_1080P_30: |
| video.resolution = v1920x1080p_30Hz; |
| video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; |
| break; |
| case V4L2_STD_TVOUT_720P_60_SBS_HALF: |
| video.resolution = v1280x720p_60Hz; |
| video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; |
| break; |
| case V4L2_STD_TVOUT_720P_59_SBS_HALF: |
| video.resolution = v1280x720p_60Hz; |
| video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; |
| break; |
| case V4L2_STD_TVOUT_720P_50_TB: |
| video.resolution = v1280x720p_50Hz; |
| video.hdmi_3d_format = HDMI_3D_TB_FORMAT; |
| break; |
| case V4L2_STD_TVOUT_1080P_24_TB: |
| video.resolution = v1920x1080p_24Hz; |
| video.hdmi_3d_format = HDMI_3D_TB_FORMAT; |
| break; |
| case V4L2_STD_TVOUT_1080P_23_TB: |
| video.resolution = v1920x1080p_24Hz; |
| video.hdmi_3d_format = HDMI_3D_TB_FORMAT; |
| break; |
| default: |
| LOGE("%s::unmathced std_id(%lld)", __func__, std_id); |
| return -1; |
| break; |
| } |
| |
| if (!EDIDVideoResolutionSupport(&video)) { |
| #ifdef DEBUG_MSG_ENABLE |
| LOGD("%s::EDIDVideoResolutionSupport(%llx) fail (not suppoted std_id) \n", __func__, std_id); |
| #endif |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int hdmi_resolution_2_std_id(unsigned int resolution, int * w, int * h, v4l2_std_id * std_id, __u32 *preset_id) |
| { |
| int ret = 0; |
| |
| switch (resolution) { |
| case 1080960: |
| *std_id = V4L2_STD_1080P_60; |
| *w = 1920; |
| *h = 1080; |
| *preset_id = V4L2_DV_1080P60; |
| break; |
| case 1080950: |
| *std_id = V4L2_STD_1080P_50; |
| *w = 1920; |
| *h = 1080; |
| *preset_id = V4L2_DV_1080P50; |
| break; |
| case 1080930: |
| *std_id = V4L2_STD_1080P_30; |
| *w = 1920; |
| *h = 1080; |
| *preset_id = V4L2_DV_1080P30; |
| break; |
| case 1080924: |
| *std_id = V4L2_STD_TVOUT_1080P_24_TB; |
| *w = 1920; |
| *h = 1080; |
| *preset_id = V4L2_DV_1080P24_TB; |
| break; |
| case 1080160: |
| *std_id = V4L2_STD_1080I_60; |
| *w = 1920; |
| *h = 1080; |
| *preset_id = V4L2_DV_1080I60; |
| break; |
| case 1080150: |
| *std_id = V4L2_STD_1080I_50; |
| *w = 1920; |
| *h = 1080; |
| *preset_id = V4L2_DV_1080I50; |
| break; |
| case 720960: |
| *std_id = V4L2_STD_720P_60; |
| *w = 1280; |
| *h = 720; |
| *preset_id = V4L2_DV_720P60; |
| break; |
| case 7209601: |
| *std_id = V4L2_STD_TVOUT_720P_60_SBS_HALF; |
| *w = 1280; |
| *h = 720; |
| *preset_id = V4L2_DV_720P60_SB_HALF; |
| break; |
| case 720950: |
| *std_id = V4L2_STD_720P_50; |
| *w = 1280; |
| *h = 720; |
| *preset_id = V4L2_DV_720P50; |
| break; |
| case 7209501: |
| *std_id = V4L2_STD_TVOUT_720P_50_TB; |
| *w = 1280; |
| *h = 720; |
| *preset_id = V4L2_DV_720P50_TB; |
| break; |
| case 5769501: |
| *std_id = V4L2_STD_576P_50_16_9; |
| *w = 720; |
| *h = 576; |
| *preset_id = V4L2_DV_576P50; |
| break; |
| case 5769502: |
| *std_id = V4L2_STD_576P_50_4_3; |
| *w = 720; |
| *h = 576; |
| *preset_id = V4L2_DV_576P50; |
| break; |
| case 4809601: |
| *std_id = V4L2_STD_480P_60_16_9; |
| *w = 720; |
| *h = 480; |
| *preset_id = V4L2_DV_480P60; |
| break; |
| case 4809602: |
| *std_id = V4L2_STD_480P_60_4_3; |
| *w = 720; |
| *h = 480; |
| *preset_id = V4L2_DV_480P60; |
| break; |
| default: |
| LOGE("%s::unmathced resolution(%d)", __func__, resolution); |
| ret = -1; |
| break; |
| } |
| |
| return ret; |
| } |
| |
| int hdmi_enable_hdcp(int fd, unsigned int hdcp_en) |
| { |
| if (ioctl(fd, VIDIOC_HDCP_ENABLE, hdcp_en) < 0) { |
| LOGD("%s::VIDIOC_HDCP_ENABLE(%d) fail \n", __func__, hdcp_en); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int hdmi_check_audio(int fd) |
| { |
| struct HDMIAudioParameter audio; |
| enum state audio_state = ON; |
| int ret = 0; |
| |
| audio.formatCode = LPCM_FORMAT; |
| audio.outPacket = HDMI_ASP; |
| audio.channelNum = CH_2; |
| audio.sampleFreq = SF_44KHZ; |
| |
| #if defined(BOARD_USES_EDID) |
| if (!EDIDAudioModeSupport(&audio)) |
| audio_state = NOT_SUPPORT; |
| else |
| audio_state = ON; |
| #endif |
| if (audio_state == ON) { |
| if (ioctl(fd, VIDIOC_INIT_AUDIO, 1) < 0) { |
| LOGE("%s::VIDIOC_INIT_AUDIO(1) failed", __func__); |
| ret = -1; |
| } |
| } else { |
| if (ioctl(fd, VIDIOC_INIT_AUDIO, 0) < 0) { |
| LOGE("%s::VIDIOC_INIT_AUDIO(0) failed", __func__); |
| ret = -1; |
| } |
| } |
| |
| return ret; |
| } |
| |
| } |