424 lines
11 KiB
C++
424 lines
11 KiB
C++
/*
|
|
* Copyright (c) 2014 Amlogic, Inc. All rights reserved.
|
|
*
|
|
* This source code is subject to the terms and conditions defined in the
|
|
* file 'LICENSE' which is part of this source code package.
|
|
*
|
|
* Description: c++ file
|
|
*/
|
|
|
|
#define LOG_MODULE_TAG "TV"
|
|
#define LOG_CLASS_TAG "CHDMIRxManager"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <stdint.h>
|
|
#include <fcntl.h>
|
|
#include <sys/ioctl.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
|
|
#include "CHDMIRxManager.h"
|
|
#include "tvutils.h"
|
|
#include "CTvin.h"
|
|
#include "CTvLog.h"
|
|
|
|
CHDMIRxManager::CHDMIRxManager()
|
|
{
|
|
mHdmiRxDeviceId = HDMIRxOpenMoudle();
|
|
HdmiEnableSPDFifo(true);
|
|
}
|
|
|
|
CHDMIRxManager::~CHDMIRxManager()
|
|
{
|
|
HDMIRxCloseMoudle();
|
|
}
|
|
|
|
int CHDMIRxManager::HDMIRxOpenMoudle()
|
|
{
|
|
int fd = open ( CS_HDMIRX_DEV_PATH, O_RDWR );
|
|
if ( fd < 0 ) {
|
|
LOGE("Open %s error(%s)!\n", CS_HDMIRX_DEV_PATH, strerror ( errno ));
|
|
return -1;
|
|
}
|
|
|
|
return fd;
|
|
}
|
|
|
|
int CHDMIRxManager::HDMIRxCloseMoudle()
|
|
{
|
|
if ( mHdmiRxDeviceId != -1 ) {
|
|
close ( mHdmiRxDeviceId );
|
|
mHdmiRxDeviceId = -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CHDMIRxManager::HDMIRxDeviceIOCtl(int request, ...)
|
|
{
|
|
int ret = -1;
|
|
va_list ap;
|
|
void *arg;
|
|
va_start ( ap, request );
|
|
arg = va_arg ( ap, void *);
|
|
va_end ( ap );
|
|
|
|
ret = ioctl(mHdmiRxDeviceId, request, arg);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int CHDMIRxManager::HdmiRxEdidDataSwitch(int edidBinCount, char *data)
|
|
{
|
|
int ret = 0;
|
|
if (data == NULL) {
|
|
LOGE("%s: edid data is null!\n", __FUNCTION__);
|
|
ret = -1;
|
|
} else {
|
|
int edidDataCount = edidBinCount * REAL_EDID_DATA_SIZE;
|
|
unsigned char loadData[edidDataCount];
|
|
memset(loadData, 0, edidDataCount);
|
|
int LoadConut = 0;
|
|
if (edidBinCount == 1) {
|
|
loadData[0] = 'E';
|
|
loadData[1] = 'D';
|
|
loadData[2] = 'I';
|
|
loadData[3] = 'D';
|
|
memcpy(loadData + 4, data, edidDataCount);
|
|
LoadConut = (edidDataCount + 4);
|
|
} else {
|
|
memcpy(loadData, data, edidDataCount);
|
|
LoadConut = edidDataCount;
|
|
}
|
|
|
|
int dev_fd = open(HDMI_EDID_DEV_PATH, O_RDWR);
|
|
if (dev_fd < 0) {
|
|
LOGE("open edid file ERROR(%s)!!\n", strerror(errno));
|
|
ret = -1;
|
|
} else {
|
|
if (write(dev_fd, data, LoadConut) < 0) {
|
|
LOGE("write edid file ERROR(%s)!!\n", strerror(errno));
|
|
ret = -1;
|
|
}
|
|
|
|
close(dev_fd);
|
|
dev_fd = -1;
|
|
if (edidBinCount == 1) {
|
|
HDMIRxDeviceIOCtl(HDMI_IOC_EDID_UPDATE);
|
|
ret = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int CHDMIRxManager::GetHdmiRxLoadEdidType(int file14Size, int file21Size, int file20Size) {
|
|
int ret = TV_EDID_TYPE_256_PLUS_512;
|
|
if (file14Size == 256) {
|
|
if (file21Size ==256) {
|
|
if (file20Size == 256) {
|
|
ret = TV_EDID_TYPE_256_PLUS_256_PLUS_256;
|
|
} else {
|
|
ret = TV_EDID_TYPE_256_PLUS_256;
|
|
}
|
|
} else if (file21Size == 512) {
|
|
if (file20Size == 512) {
|
|
ret = TV_EDID_TYPE_256_PLUS_512_PLUS_512;
|
|
} else if (file20Size == 256) {
|
|
ret = TV_EDID_TYPE_256_PLUS_512_PLUS_256;
|
|
} else {
|
|
ret = TV_EDID_TYPE_256_PLUS_512;
|
|
}
|
|
}
|
|
} else if (file14Size == 512) {
|
|
if (file21Size == 512) {
|
|
ret = TV_EDID_TYPE_512_PLUS_512;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int CHDMIRxManager::HdmiRxLoadEdidDataWithPort(int port, int type, int dataSize, unsigned char dataBuf[]) {
|
|
int ret = -1;
|
|
LOGD("%s: port:%d, type:%d, dataSize:%d!\n", __FUNCTION__, port, type, dataSize);
|
|
int size = dataSize + 1;
|
|
unsigned char LoadBuf[size];
|
|
memset(LoadBuf, 0, sizeof(char) * size);
|
|
LoadBuf[0] = (unsigned char)(type << 4|port);
|
|
LOGD("%s: LoadBuf[0]:%#x!\n", __FUNCTION__, LoadBuf[0]);
|
|
memcpy(LoadBuf+1, dataBuf, dataSize);
|
|
|
|
int devFd = open(HDMI_EDID_DATA_DEV_PATH, O_RDWR);
|
|
if (devFd < 0) {
|
|
LOGE("%s: open ERROR(%s)!\n", __FUNCTION__, strerror(errno));
|
|
ret = -1;
|
|
} else {
|
|
if (write(devFd, LoadBuf, size) < 0) {
|
|
LOGE("%s: write ERROR(%s)!\n", __FUNCTION__, strerror(errno));
|
|
ret = -1;
|
|
} else {
|
|
ret = 0;
|
|
}
|
|
|
|
close(devFd);
|
|
devFd = -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int CHDMIRxManager::HdmiRxEdidUpdateWithPort(int port)
|
|
{
|
|
LOGD("%s, port is %d!\n", __FUNCTION__, port);
|
|
unsigned char parm = port;
|
|
int tmp_ret = HDMIRxDeviceIOCtl(HDMI_IOC_EDID_UPDATE_WITH_PORT, &parm);
|
|
if (tmp_ret < 0) {
|
|
LOGE("%s, port:%d, error: (%s)!\n", __FUNCTION__, port, strerror ( errno ));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int CHDMIRxManager::HdmiRxEdidVerSwitch(int verValue)
|
|
{
|
|
LOGD("%s: new all edid version: 0x%x\n", __FUNCTION__, verValue);
|
|
|
|
int ret = -1;
|
|
int devFd = open(HDMI_EDID_VERSION_DEV_PATH, O_RDWR);
|
|
if (devFd < 0) {
|
|
LOGE("%s: open %s ERROR(%s)!!\n", __FUNCTION__, HDMI_EDID_VERSION_DEV_PATH, strerror(errno));
|
|
ret = -1;
|
|
} else {
|
|
char tmp[32] = {0};
|
|
sprintf(tmp, "%x", verValue);
|
|
if (write(devFd, tmp, strlen(tmp)) < 0) {
|
|
LOGE("%s, write %s ERROR(%s)!!\n", __FUNCTION__, HDMI_EDID_VERSION_DEV_PATH, strerror(errno));
|
|
ret = -1;
|
|
} else {
|
|
ret = 0;
|
|
}
|
|
close(devFd);
|
|
devFd = -1;
|
|
}
|
|
|
|
//HDMIRxDeviceIOCtl(HDMI_IOC_EDID_UPDATE);
|
|
return ret;
|
|
}
|
|
|
|
int CHDMIRxManager::HdmiRxHdcpVerSwitch(tv_hdmi_hdcp_version_t version)
|
|
{
|
|
int ret = -1;
|
|
if (HDMI_HDCP_VER_14 == version) {
|
|
ret = HDMIRxDeviceIOCtl(HDMI_IOC_HDCP22_FORCE14);
|
|
} else if (HDMI_HDCP_VER_22 == version) {
|
|
ret = HDMIRxDeviceIOCtl(HDMI_IOC_HDCP22_AUTO);
|
|
} else {
|
|
LOGE("invalid hdcp version!\n");
|
|
return -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int CHDMIRxManager::HdmiRxHdcpOnOff(tv_hdmi_hdcpkey_enable_t flag)
|
|
{
|
|
int ret = -1;
|
|
if (hdcpkey_enable == flag) {
|
|
ret = HDMIRxDeviceIOCtl(HDMI_IOC_HDCP_ON);
|
|
}else if (hdcpkey_disable == flag) {
|
|
ret = HDMIRxDeviceIOCtl(HDMI_IOC_HDCP_OFF);
|
|
}else {
|
|
LOGE("invalid hdcp enable status!\n");
|
|
return -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int CHDMIRxManager::GetHdmiHdcpKeyKsvInfo(struct _hdcp_ksv *msg)
|
|
{
|
|
return HDMIRxDeviceIOCtl(HDMI_IOC_HDCP_GET_KSV, msg);
|
|
}
|
|
|
|
int CHDMIRxManager::CalHdmiPortCecPhysicAddr()
|
|
{
|
|
tv_source_input_t tmpHdmiPortCecPhysicAddr[4] = {SOURCE_MAX};
|
|
tvin_port_t tvInport[4] = {TVIN_PORT_HDMI0,TVIN_PORT_HDMI1,TVIN_PORT_HDMI2,TVIN_PORT_HDMI3};
|
|
int HdmiPortCecPhysicAddr = 0x0;
|
|
for (int i = 0; i < 4; i++) {
|
|
tmpHdmiPortCecPhysicAddr[i] = CTvin::getInstance()->Tvin_PortToSourceInput(tvInport[i]);
|
|
}
|
|
HdmiPortCecPhysicAddr |= ((tmpHdmiPortCecPhysicAddr[0] == SOURCE_MAX? 0xf:(tmpHdmiPortCecPhysicAddr[0]-4))
|
|
|((tmpHdmiPortCecPhysicAddr[1] == SOURCE_MAX? 0xf:(tmpHdmiPortCecPhysicAddr[1]-4)) << 4)
|
|
|((tmpHdmiPortCecPhysicAddr[2] == SOURCE_MAX? 0xf:(tmpHdmiPortCecPhysicAddr[2]-4)) << 8)
|
|
|((tmpHdmiPortCecPhysicAddr[3] == SOURCE_MAX? 0xf:(tmpHdmiPortCecPhysicAddr[3]-4)) << 12));
|
|
|
|
LOGD("hdmi port map: 0x%x\n", HdmiPortCecPhysicAddr);
|
|
return HdmiPortCecPhysicAddr;
|
|
}
|
|
|
|
int CHDMIRxManager::SetHdmiPortCecPhysicAddr()
|
|
{
|
|
char buf[10] = {0};
|
|
int val = CalHdmiPortCecPhysicAddr();
|
|
sprintf(buf, "%x", val);
|
|
tvWriteSysfs(HDMI_CEC_PORT_SEQUENCE, buf);
|
|
memset(buf, 0, sizeof(buf));
|
|
sprintf(buf, "%d", val);
|
|
tvWriteSysfs(HDMI_CEC_PORT_MAP,buf);
|
|
return 0;
|
|
}
|
|
|
|
int CHDMIRxManager::UpdataEdidDataWithPort(int port, unsigned char *dataBuf)
|
|
{
|
|
int ret = -1;
|
|
int size = REAL_EDID_DATA_SIZE + 1;
|
|
unsigned char LoadBuf[size];
|
|
memset(LoadBuf, 0, sizeof(char) * size);
|
|
LoadBuf[0] = (unsigned char)port;
|
|
memcpy(LoadBuf+1, dataBuf, REAL_EDID_DATA_SIZE);
|
|
/*LOGD("%s: edid data print start.\n", __FUNCTION__);
|
|
for (int i=0;i<257;i++) {
|
|
printf("0x%x ",LoadBuf[i]);
|
|
}
|
|
LOGD("%s: edid data print end.\n", __FUNCTION__);*/
|
|
int devFd = open(HDMI_EDID_DATA_DEV_PATH, O_RDWR);
|
|
if (devFd < 0) {
|
|
LOGE("%s: open ERROR(%s)!\n", __FUNCTION__, strerror(errno));
|
|
ret = -1;
|
|
} else {
|
|
if (write(devFd, LoadBuf, size) < 0) {
|
|
LOGE("%s: write ERROR(%s)!\n", __FUNCTION__, strerror(errno));
|
|
ret = -1;
|
|
} else {
|
|
ret = 0;
|
|
}
|
|
|
|
close(devFd);
|
|
devFd = -1;
|
|
}
|
|
if (ret >= 0) {
|
|
LOGD("%s: would update edid.\n", __FUNCTION__);
|
|
HDMIRxDeviceIOCtl(HDMI_IOC_EDID_UPDATE);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int CHDMIRxManager::HdmiEnableSPDFifo(bool enable)
|
|
{
|
|
unsigned int pkttype = 0x83;
|
|
int ret = -1;
|
|
//has been abort
|
|
/*
|
|
if (enable) {
|
|
ret = HDMIRxDeviceIOCtl(HDMI_IOC_PD_FIFO_PKTTYPE_EN, &pkttype);
|
|
} else {
|
|
ret = HDMIRxDeviceIOCtl(HDMI_IOC_PD_FIFO_PKTTYPE_DIS, &pkttype);
|
|
}
|
|
*/
|
|
return ret;
|
|
}
|
|
|
|
int CHDMIRxManager::HdmiRxGetSPDInfoframe(struct spd_infoframe_st* spd)
|
|
{
|
|
int ret = -1;
|
|
struct spd_infoframe_st pd;
|
|
|
|
ret = HDMIRxDeviceIOCtl(HDMI_IOC_GET_SPD_SRC_INFO, &pd);
|
|
if (ret < 0) {
|
|
LOGE("Get SPD infoframe via ioctl failed: %s.\n", strerror(errno));
|
|
} else {
|
|
memcpy(spd, &pd, sizeof(struct spd_infoframe_st));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void CHDMIRxManager::SetHDMIFeatureInit(int allmEnable, int VrrEnable, int QmsEnable)
|
|
{
|
|
char buf[8] = {0};
|
|
sprintf(buf, "%d", allmEnable);
|
|
tvWriteSysfs(HDMI_SET_ALLM_PARAM, buf);
|
|
sprintf(buf, "%d", VrrEnable);
|
|
tvWriteSysfs(HDMI_VRR_ENABLED, buf);
|
|
sprintf(buf, "%d", QmsEnable);
|
|
tvWriteSysfs(QMS_FUNC_CTRL_PATH, buf);
|
|
}
|
|
|
|
int CHDMIRxManager::SetAllmEnabled(bool enable)
|
|
{
|
|
int ret = 0;
|
|
char buf[8] = {0};
|
|
sprintf(buf, "%d", enable);
|
|
tvWriteSysfs(HDMI_SET_ALLM_PARAM, buf);
|
|
//ret = HDMIRxDeviceIOCtl(HDMI_IOC_EDID_UPDATE);
|
|
for (int i=TVIN_PORT_ID_1;i<TVIN_PORT_ID_MAX;i++) {
|
|
HdmiRxEdidUpdateWithPort(i);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool CHDMIRxManager::GetAllmEnabled()
|
|
{
|
|
char buf[32] = {0};
|
|
tvReadSysfs(HDMI_SET_ALLM_PARAM, buf);
|
|
int num;
|
|
if (sscanf(buf, "%*[^:]:%d", &num) == 1) {
|
|
return num > 0;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int CHDMIRxManager::SetVrrEnabled(bool enable)
|
|
{
|
|
int ret = 0;
|
|
char buf[8] = {0};
|
|
sprintf(buf, "%d", enable);
|
|
tvWriteSysfs(HDMI_VRR_ENABLED, buf);
|
|
//ret = HDMIRxDeviceIOCtl(HDMI_IOC_EDID_UPDATE);
|
|
for (int i=TVIN_PORT_ID_1;i<TVIN_PORT_ID_MAX;i++) {
|
|
HdmiRxEdidUpdateWithPort(i);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool CHDMIRxManager::GetVrrEnabled()
|
|
{
|
|
char buf[32] = {0};
|
|
tvReadSysfs(HDMI_VRR_ENABLED, buf);
|
|
int num;
|
|
if (sscanf(buf, "%*[^:]:%d", &num) == 1) {
|
|
return num > 0;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int CHDMIRxManager::SetQmsEnabled(bool enable)
|
|
{
|
|
int ret = 0;
|
|
char buf[8] = {0};
|
|
sprintf(buf, "%d", enable);
|
|
tvWriteSysfs(QMS_FUNC_CTRL_PATH, buf);
|
|
for (int i=TVIN_PORT_ID_1;i<TVIN_PORT_ID_MAX;i++) {
|
|
HdmiRxEdidUpdateWithPort(i);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool CHDMIRxManager::GetQmsEnabled()
|
|
{
|
|
char buf[32] = {0};
|
|
tvReadSysfs(QMS_FUNC_CTRL_PATH, buf);
|
|
int num;
|
|
if (sscanf(buf, "%*[^:]:%d", &num) == 1) {
|
|
return num > 0;
|
|
}
|
|
return false;
|
|
}
|
|
|