external.cpp revision 96b413618bcdd213927494ca85f022bc78bbc60f
1ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed/* 2ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * Copyright (C) 2010 The Android Open Source Project 3bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah * Copyright (C) 2012, The Linux Foundation. All rights reserved. 4ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * 5ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * Not a Contribution, Apache license notifications and license are 6ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * retained for attribution purposes only. 7ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * 8ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License"); 9ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * you may not use this file except in compliance with the License. 10ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * You may obtain a copy of the License at 11ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * 12ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * http://www.apache.org/licenses/LICENSE-2.0 13ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * 14ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * Unless required by applicable law or agreed to in writing, software 15ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS, 16ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * See the License for the specific language governing permissions and 18ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed * limitations under the License. 19ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed */ 20ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 211589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#define DEBUG 0 22ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include <ctype.h> 231589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#include <fcntl.h> 24ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include <media/IAudioPolicyService.h> 25ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include <media/AudioSystem.h> 26ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include <utils/threads.h> 27ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include <utils/Errors.h> 28ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include <utils/Log.h> 29ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 30ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include <linux/msm_mdp.h> 31ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include <linux/fb.h> 32ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include <sys/ioctl.h> 33ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include <sys/poll.h> 341589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#include <sys/resource.h> 35ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include <cutils/properties.h> 36ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include "hwc_utils.h" 37bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah#include "external.h" 38bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah#include "overlayUtils.h" 39620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar#include "overlay.h" 40bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah 41bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shahusing namespace android; 42ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 43ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmednamespace qhwc { 44ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 45620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar#define MAX_FRAME_BUFFER_NAME_SIZE (80) 46620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar#define MAX_DISPLAY_DEVICES (3) 47620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar 48620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar 49620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarconst char* msmFbDevicePath[] = { "/dev/graphics/fb1", 50620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar "/dev/graphics/fb2"}; 51620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar 52620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar/* 53620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar * Updates extDeviceFbIndex Array with the correct frame buffer indices 54620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar * of avaiable external devices 55620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar * 56620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar */ 57620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::updateExtDispDevFbIndex() 58620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar{ 59620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar FILE *displayDeviceFP = NULL; 60620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar char fbType[MAX_FRAME_BUFFER_NAME_SIZE]; 61620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE]; 62620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar 63620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar for(int j = 1; j < MAX_DISPLAY_DEVICES; j++) { 64620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar sprintf (msmFbTypePath,"/sys/class/graphics/fb%d/msm_fb_type", j); 65620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar displayDeviceFP = fopen(msmFbTypePath, "r"); 66620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(displayDeviceFP){ 67620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE, 68620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar displayDeviceFP); 69620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(strncmp(fbType, "dtv panel", strlen("dtv panel")) == 0){ 70620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ALOGD_IF(DEBUG,"hdmi framebuffer index is %d",j); 71620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar mHdmiFbNum = j; 72620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } else if(strncmp(fbType, "writeback panel", 73620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar strlen("writeback panel")) == 0){ 74620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ALOGD_IF(DEBUG,"wfd framebuffer index is %d",j); 75620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar mWfdFbNum = j; 76620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } 77620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar fclose(displayDeviceFP); 78620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } 79620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } 80620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ALOGD_IF(DEBUG,"%s: mHdmiFbNum: %d mWfdFbNum: %d ",__FUNCTION__, 81620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar mHdmiFbNum, mWfdFbNum); 82620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar} 83620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar 84620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarint ExternalDisplay::configureHDMIDisplay() { 85620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar openFrameBuffer(mHdmiFbNum); 86620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(mFd == -1) 87620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar return -1; 880ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R readCEUnderscanInfo(); 89620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar readResolution(); 90620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar // TODO: Move this to activate 91c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R /* Used for changing the resolution 92c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R * getUserMode will get the preferred 93c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R * mode set thru adb shell */ 94c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R int mode = getUserMode(); 95c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R if (mode == -1) { 96c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R //Get the best mode and set 97c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R mode = getBestMode(); 98c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R } 99c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R setResolution(mode); 100620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar setDpyHdmiAttr(); 101620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar setExternalDisplay(true, mHdmiFbNum); 102620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar return 0; 103620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar} 104620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar 105620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarint ExternalDisplay::configureWFDDisplay() { 106620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar int ret = 0; 107620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(mConnectedFbNum == mHdmiFbNum) { 108620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ALOGE("%s: Cannot process WFD connection while HDMI is active", 109620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar __FUNCTION__); 110620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar return -1; 111620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } 112620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar openFrameBuffer(mWfdFbNum); 113620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(mFd == -1) 114620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar return -1; 115620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo); 116620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(ret < 0) { 117620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__, 118620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar strerror(errno)); 119620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } 120620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar setDpyWfdAttr(); 121620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar setExternalDisplay(true, mWfdFbNum); 122620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar return 0; 123620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar} 124620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar 125620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarint ExternalDisplay::teardownHDMIDisplay() { 126620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(mConnectedFbNum == mHdmiFbNum) { 127620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar // hdmi offline event..! 128620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar closeFrameBuffer(); 129620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar resetInfo(); 130620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar setExternalDisplay(false); 131620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } 132620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar return 0; 133620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar} 134ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 135620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarint ExternalDisplay::teardownWFDDisplay() { 136620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(mConnectedFbNum == mWfdFbNum) { 137620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar // wfd offline event..! 138620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar closeFrameBuffer(); 139620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar memset(&mVInfo, 0, sizeof(mVInfo)); 140620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar setExternalDisplay(false); 141620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } 142620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar return 0; 143620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar} 144ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 145620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::processUEventOnline(const char *str) { 146620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar const char *s1 = str + strlen("change@/devices/virtual/switch/"); 147620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(!strncmp(s1,"hdmi",strlen(s1))) { 148620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar // hdmi online event..! 149620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar configureHDMIDisplay(); 150df631660b7ecbcbb2c8a70753d2de26ea81a4afaArun Kumar K.R // set system property 151df631660b7ecbcbb2c8a70753d2de26ea81a4afaArun Kumar K.R property_set("hw.hdmiON", "1"); 152620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar }else if(!strncmp(s1,"wfd",strlen(s1))) { 153620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar // wfd online event..! 154620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar configureWFDDisplay(); 155620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } 156620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar} 157ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 158620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::processUEventOffline(const char *str) { 159620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar const char *s1 = str + strlen("change@/devices/virtual/switch/"); 160620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(!strncmp(s1,"hdmi",strlen(s1))) { 161620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar teardownHDMIDisplay(); 162df631660b7ecbcbb2c8a70753d2de26ea81a4afaArun Kumar K.R // unset system property 163df631660b7ecbcbb2c8a70753d2de26ea81a4afaArun Kumar K.R property_set("hw.hdmiON", "0"); 164620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar }else if(!strncmp(s1,"wfd",strlen(s1))) { 165620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar teardownWFDDisplay(); 166620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } 167620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar} 168ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 169080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer AhmedExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1), 170620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0), 17190571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar mUnderscanSupported(false), mHwcContext(ctx), mHdmiFbNum(-1), 17290571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar mWfdFbNum(-1), mExtDpyNum(HWC_DISPLAY_EXTERNAL) 173ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{ 174080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed memset(&mVInfo, 0, sizeof(mVInfo)); 175620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar //Determine the fb index for external display devices. 176620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar updateExtDispDevFbIndex(); 17790571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar 178ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed} 179ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 180bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shahvoid ExternalDisplay::setEDIDMode(int resMode) { 181bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah ALOGD_IF(DEBUG,"resMode=%d ", resMode); 182bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah { 183bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah Mutex::Autolock lock(mExtDispLock); 184620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar setExternalDisplay(false); 185620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar openFrameBuffer(mHdmiFbNum); 186bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah setResolution(resMode); 187bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah } 188620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar setExternalDisplay(true, mHdmiFbNum); 189bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah} 190bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah 191bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shahvoid ExternalDisplay::setHPD(uint32_t startEnd) { 192bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah ALOGD_IF(DEBUG,"HPD enabled=%d", startEnd); 193bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah writeHPDOption(startEnd); 194bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah} 195bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah 196bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shahvoid ExternalDisplay::setActionSafeDimension(int w, int h) { 197bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h); 198bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah Mutex::Autolock lock(mExtDispLock); 1990ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R char actionsafeWidth[PROPERTY_VALUE_MAX]; 2000ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R char actionsafeHeight[PROPERTY_VALUE_MAX]; 2010ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R sprintf(actionsafeWidth, "%d", w); 2020ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R property_set("hw.actionsafe.width", actionsafeWidth); 2030ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R sprintf(actionsafeHeight, "%d", h); 2040ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R property_set("hw.actionsafe.height", actionsafeHeight); 205620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar setExternalDisplay(true, mHdmiFbNum); 206bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah} 207bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah 208bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shahint ExternalDisplay::getModeCount() const { 209bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah ALOGD_IF(DEBUG,"HPD mModeCount=%d", mModeCount); 210bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah Mutex::Autolock lock(mExtDispLock); 211bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah return mModeCount; 212bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah} 213bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah 214bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shahvoid ExternalDisplay::getEDIDModes(int *out) const { 215bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah Mutex::Autolock lock(mExtDispLock); 216bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah for(int i = 0;i < mModeCount;i++) { 217bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah out[i] = mEDIDModes[i]; 218bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah } 219bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah} 220bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah 2210ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.Rvoid ExternalDisplay::readCEUnderscanInfo() 2220ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R{ 2230ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R int hdmiScanInfoFile = -1; 2240ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R int len = -1; 2250ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R char scanInfo[17]; 2260ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R char *ce_info_str = NULL; 2270ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R const char token[] = ", \n"; 2280ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R int ce_info = -1; 2290ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R char sysFsScanInfoFilePath[128]; 2300ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R sprintf(sysFsScanInfoFilePath, "/sys/devices/virtual/graphics/fb%d/" 2310ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R "scan_info", mHdmiFbNum); 2320ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R 2330ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R memset(scanInfo, 0, sizeof(scanInfo)); 2340ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R hdmiScanInfoFile = open(sysFsScanInfoFilePath, O_RDONLY, 0); 2350ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R if (hdmiScanInfoFile < 0) { 2360ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R ALOGD_IF(DEBUG, "%s: scan_info file '%s' not found", 2370ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R __FUNCTION__, sysFsScanInfoFilePath); 2380ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R return; 2390ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R } else { 2400ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R len = read(hdmiScanInfoFile, scanInfo, sizeof(scanInfo)-1); 2410ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R ALOGD("%s: Scan Info string: %s length = %d", 2420ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R __FUNCTION__, scanInfo, len); 2430ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R if (len <= 0) { 2440ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R close(hdmiScanInfoFile); 2450ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R ALOGE("%s: Scan Info file empty '%s'", 2460ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R __FUNCTION__, sysFsScanInfoFilePath); 2470ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R return; 2480ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R } 2490ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R scanInfo[len] = '\0'; /* null terminate the string */ 2500ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R } 2510ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R close(hdmiScanInfoFile); 2520ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R 2530ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R /* 2540ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R * The scan_info contains the three fields 2550ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R * PT - preferred video format 2560ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R * IT - video format 2570ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R * CE video format - containing the underscan support information 2580ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R */ 2590ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R 2600ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R /* PT */ 2610ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R ce_info_str = strtok(scanInfo, token); 2620ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R if (ce_info_str) { 2630ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R /* IT */ 2640ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R ce_info_str = strtok(NULL, token); 2650ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R if (ce_info_str) { 2660ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R /* CE */ 2670ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R ce_info_str = strtok(NULL, token); 2680ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R if (ce_info_str) 2690ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R ce_info = atoi(ce_info_str); 2700ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R } 2710ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R } 2720ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R 2730ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R if (ce_info_str) { 2740ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R // ce_info contains the underscan information 2750ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R if (ce_info == EXT_SCAN_ALWAYS_UNDERSCANED || 2760ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R ce_info == EXT_SCAN_BOTH_SUPPORTED) 2770ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R // if TV supported underscan, then driver will always underscan 2780ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R // hence no need to apply action safe rectangle 2790ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R mUnderscanSupported = true; 2800ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R } else { 2810ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R ALOGE("%s: scan_info string error", __FUNCTION__); 2820ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R } 2830ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R 2840ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R // Store underscan support info in a system property 2850ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R const char* prop = (mUnderscanSupported) ? "1" : "0"; 2860ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R property_set("hw.underscan_supported", prop); 2870ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R return; 2880ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R} 2890ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R 2901589dee5c27293d278d3e549af8a4bda27e080f8Naseer AhmedExternalDisplay::~ExternalDisplay() 2911589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed{ 292080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed closeFrameBuffer(); 293ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed} 294ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 295ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmedstruct disp_mode_timing_type { 296ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int video_format; 297ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 298ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int active_h; 299ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int active_v; 300ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 301ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int front_porch_h; 302ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int pulse_width_h; 303ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int back_porch_h; 304ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 305ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int front_porch_v; 306ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int pulse_width_v; 307ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int back_porch_v; 308ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 309ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int pixel_freq; 310ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed bool interlaced; 311ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 312ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed void set_info(struct fb_var_screeninfo &info) const; 313ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}; 314ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 315ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmedvoid disp_mode_timing_type::set_info(struct fb_var_screeninfo &info) const 316ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{ 317ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.reserved[0] = 0; 318ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.reserved[1] = 0; 319ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.reserved[2] = 0; 320e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang#ifndef FB_METADATA_VIDEO_INFO_CODE_SUPPORT 321bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah info.reserved[3] = (info.reserved[3] & 0xFFFF) | (video_format << 16); 322e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang#endif 323ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.xoffset = 0; 324ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.yoffset = 0; 325ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.xres = active_h; 326ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.yres = active_v; 327ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 328ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.pixclock = pixel_freq*1000; 329ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.vmode = interlaced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED; 330ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 331ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.right_margin = front_porch_h; 332ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.hsync_len = pulse_width_h; 333ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.left_margin = back_porch_h; 334ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.lower_margin = front_porch_v; 335ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.vsync_len = pulse_width_v; 336ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed info.upper_margin = back_porch_v; 337ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed} 338ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 339ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed/* Video formates supported by the HDMI Standard */ 340ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed/* Indicates the resolution, pix clock and the aspect ratio */ 341ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m640x480p60_4_3 1 342ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m720x480p60_4_3 2 343ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m720x480p60_16_9 3 344ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1280x720p60_16_9 4 345ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1920x1080i60_16_9 5 346ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1440x480i60_4_3 6 347ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1440x480i60_16_9 7 348ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1920x1080p60_16_9 16 349ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m720x576p50_4_3 17 350ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m720x576p50_16_9 18 351ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1280x720p50_16_9 19 352ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1440x576i50_4_3 21 353ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1440x576i50_16_9 22 354ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1920x1080p50_16_9 31 355ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1920x1080p24_16_9 32 356ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1920x1080p25_16_9 33 357ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1920x1080p30_16_9 34 358ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 359ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmedstatic struct disp_mode_timing_type supported_video_mode_lut[] = { 360ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m640x480p60_4_3, 640, 480, 16, 96, 48, 10, 2, 33, 25200, false}, 361ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m720x480p60_4_3, 720, 480, 16, 62, 60, 9, 6, 30, 27030, false}, 362ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m720x480p60_16_9, 720, 480, 16, 62, 60, 9, 6, 30, 27030, false}, 363ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m1280x720p60_16_9, 1280, 720, 110, 40, 220, 5, 5, 20, 74250, false}, 364ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m1920x1080i60_16_9, 1920, 540, 88, 44, 148, 2, 5, 5, 74250, false}, 365ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m1440x480i60_4_3, 1440, 240, 38, 124, 114, 4, 3, 15, 27000, true}, 366ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m1440x480i60_16_9, 1440, 240, 38, 124, 114, 4, 3, 15, 27000, true}, 367ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m1920x1080p60_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 148500, false}, 368ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m720x576p50_4_3, 720, 576, 12, 64, 68, 5, 5, 39, 27000, false}, 369ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m720x576p50_16_9, 720, 576, 12, 64, 68, 5, 5, 39, 27000, false}, 370ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m1280x720p50_16_9, 1280, 720, 440, 40, 220, 5, 5, 20, 74250, false}, 371ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m1440x576i50_4_3, 1440, 288, 24, 126, 138, 2, 3, 19, 27000, true}, 372ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m1440x576i50_16_9, 1440, 288, 24, 126, 138, 2, 3, 19, 27000, true}, 373ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m1920x1080p50_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 148500, false}, 374ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m1920x1080p24_16_9, 1920, 1080, 638, 44, 148, 4, 5, 36, 74250, false}, 375ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m1920x1080p25_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 74250, false}, 376ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed {m1920x1080p30_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 74250, false}, 377ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}; 3781589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed 379080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmedint ExternalDisplay::parseResolution(char* edidStr, int* edidModes) 380ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{ 381ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed char delim = ','; 382ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int count = 0; 383ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed char *start, *end; 384ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed // EDIDs are string delimited by ',' 385ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed // Ex: 16,4,5,3,32,34,1 386ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed // Parse this string to get mode(int) 387ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed start = (char*) edidStr; 388080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed end = &delim; 389080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed while(*end == delim) { 390080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed edidModes[count] = (int) strtol(start, &end, 10); 391ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed start = end+1; 392ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed count++; 393ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 394080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed ALOGD_IF(DEBUG, "In %s: count = %d", __FUNCTION__, count); 395080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed for (int i = 0; i < count; i++) 396080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed ALOGD_IF(DEBUG, "Mode[%d] = %d", i, edidModes[i]); 397ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return count; 398ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed} 399080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed 4001589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmedbool ExternalDisplay::readResolution() 401ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{ 402620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar char sysFsEDIDFilePath[255]; 403620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar sprintf(sysFsEDIDFilePath , "/sys/devices/virtual/graphics/fb%d/edid_modes", 404620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar mHdmiFbNum); 405620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar 406620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar int hdmiEDIDFile = open(sysFsEDIDFilePath, O_RDONLY, 0); 407ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int len = -1; 408ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 409ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed if (hdmiEDIDFile < 0) { 410080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed ALOGE("%s: edid_modes file '%s' not found", 411620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar __FUNCTION__, sysFsEDIDFilePath); 412ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return false; 413ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } else { 414ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed len = read(hdmiEDIDFile, mEDIDs, sizeof(mEDIDs)-1); 4151589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed ALOGD_IF(DEBUG, "%s: EDID string: %s length = %d", 4161589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed __FUNCTION__, mEDIDs, len); 417ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed if ( len <= 0) { 418080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed ALOGE("%s: edid_modes file empty '%s'", 419620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar __FUNCTION__, sysFsEDIDFilePath); 420ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 421ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed else { 422ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed while (len > 1 && isspace(mEDIDs[len-1])) 423ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed --len; 424ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed mEDIDs[len] = 0; 425ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 426ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 427ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed close(hdmiEDIDFile); 428ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed if(len > 0) { 429620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar // Get EDID modes from the EDID strings 430080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mModeCount = parseResolution(mEDIDs, mEDIDModes); 4311589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed ALOGD_IF(DEBUG, "%s: mModeCount = %d", __FUNCTION__, 4321589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed mModeCount); 433ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 434ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 435ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return (strlen(mEDIDs) > 0); 436ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed} 437ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 438620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarbool ExternalDisplay::openFrameBuffer(int fbNum) 439ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{ 440080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed if (mFd == -1) { 441620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar mFd = open(msmFbDevicePath[fbNum-1], O_RDWR); 442080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed if (mFd < 0) 443620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ALOGE("%s: %s is not available", __FUNCTION__, 444620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar msmFbDevicePath[fbNum-1]); 445620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(mHwcContext) { 44690571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar mHwcContext->dpyAttr[mExtDpyNum].fd = mFd; 447620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } 4482e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah } 449080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed return (mFd > 0); 450080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed} 451080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed 452080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmedbool ExternalDisplay::closeFrameBuffer() 453080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed{ 454080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed int ret = 0; 45550e19d2c536783fad3c29f8ffced6ba5915e7f06Naseer Ahmed if(mFd >= 0) { 456080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed ret = close(mFd); 457080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mFd = -1; 458ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 4592e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah if(mHwcContext) { 46090571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar mHwcContext->dpyAttr[mExtDpyNum].fd = mFd; 4612e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah } 462080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed return (ret == 0); 463ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed} 464ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 465080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed// clears the vinfo, edid, best modes 466080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmedvoid ExternalDisplay::resetInfo() 467080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed{ 468080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed memset(&mVInfo, 0, sizeof(mVInfo)); 469080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed memset(mEDIDs, 0, sizeof(mEDIDs)); 470080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed memset(mEDIDModes, 0, sizeof(mEDIDModes)); 471080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mModeCount = 0; 472080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mCurrentMode = -1; 4730ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R mUnderscanSupported = false; 4740ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R // Reset the underscan supported system property 4750ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R const char* prop = "0"; 4760ae34e340382b0b3b767b844305db19e91257eddArun Kumar K.R property_set("hw.underscan_supported", prop); 477080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed} 478ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 4791589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmedint ExternalDisplay::getModeOrder(int mode) 480ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{ 481c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R // XXX: We dont support interlaced modes but having 482c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R // it here for for future 483ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed switch (mode) { 484ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed default: 485ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m1440x480i60_4_3: 486ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 1; // 480i 4:3 487ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m1440x480i60_16_9: 488ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 2; // 480i 16:9 489ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m1440x576i50_4_3: 490ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 3; // i576i 4:3 491ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m1440x576i50_16_9: 492ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 4; // 576i 16:9 493ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m640x480p60_4_3: 494ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 5; // 640x480 4:3 495ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m720x480p60_4_3: 496ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 6; // 480p 4:3 497ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m720x480p60_16_9: 498ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 7; // 480p 16:9 499ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m720x576p50_4_3: 500ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 8; // 576p 4:3 501ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m720x576p50_16_9: 502ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 9; // 576p 16:9 503ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m1920x1080i60_16_9: 504ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 10; // 1080i 16:9 505ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m1280x720p50_16_9: 506ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 11; // 720p@50Hz 507ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m1280x720p60_16_9: 508ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 12; // 720p@60Hz 509ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m1920x1080p24_16_9: 510ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 13; //1080p@24Hz 511ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m1920x1080p25_16_9: 512ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 14; //108-p@25Hz 513ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m1920x1080p30_16_9: 514ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 15; //1080p@30Hz 515ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m1920x1080p50_16_9: 516ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 16; //1080p@50Hz 517ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed case m1920x1080p60_16_9: 518ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return 17; //1080p@60Hz 5191589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed } 520ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed} 521ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 522c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R/// Returns the user mode set(if any) using adb shell 523c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.Rint ExternalDisplay::getUserMode() { 524c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R /* Based on the property set the resolution */ 525c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R char property_value[PROPERTY_VALUE_MAX]; 52696b413618bcdd213927494ca85f022bc78bbc60fArun Kumar K.R property_get("hw.hdmi.resolution", property_value, "-1"); 527c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R int mode = atoi(property_value); 528c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R // We dont support interlaced modes 529c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R if(isValidMode(mode) && !isInterlacedMode(mode)) { 53059644b2127280052ca410cb053f0a41c3181a97aNaseer Ahmed ALOGD_IF(DEBUG, "%s: setting the HDMI mode = %d", __FUNCTION__, mode); 531c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R return mode; 532c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R } 533c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R return -1; 534c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R} 535c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R 536ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed// Get the best mode for the current HD TV 5371589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmedint ExternalDisplay::getBestMode() { 538ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int bestOrder = 0; 539ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int bestMode = m640x480p60_4_3; 540bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah Mutex::Autolock lock(mExtDispLock); 541ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed // for all the edid read, get the best mode 542ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed for(int i = 0; i < mModeCount; i++) { 543ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int mode = mEDIDModes[i]; 544ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int order = getModeOrder(mode); 545ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed if (order > bestOrder) { 546ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed bestOrder = order; 547ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed bestMode = mode; 548ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 549ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 550ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return bestMode; 5511589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed} 552ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 5531589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmedinline bool ExternalDisplay::isValidMode(int ID) 554ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{ 555c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R bool valid = false; 556c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R for (int i = 0; i < mModeCount; i++) { 557c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R if(ID == mEDIDModes[i]) { 558c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R valid = true; 559c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R break; 560c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R } 561c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R } 562c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R return valid; 563c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R} 564c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R 565c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R// returns true if the mode(ID) is interlaced mode format 566c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.Rbool ExternalDisplay::isInterlacedMode(int ID) { 567c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R bool interlaced = false; 568c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R switch(ID) { 569c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R case m1440x480i60_4_3: 570c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R case m1440x480i60_16_9: 571c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R case m1440x576i50_4_3: 572c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R case m1440x576i50_16_9: 573c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R case m1920x1080i60_16_9: 574c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R interlaced = true; 575c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R default: 576c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R interlaced = false; 577c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R } 578c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R return interlaced; 579ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed} 580ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 5811589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmedvoid ExternalDisplay::setResolution(int ID) 582ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{ 583ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed struct fb_var_screeninfo info; 584080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed int ret = 0; 585080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo); 586080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed if(ret < 0) { 587080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__, 588080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed strerror(errno)); 589080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed } 590080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed 591080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed ALOGD_IF(DEBUG, "%s: GET Info<ID=%d %dx%d (%d,%d,%d)," 592080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed "(%d,%d,%d) %dMHz>", __FUNCTION__, 593080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mVInfo.reserved[3], mVInfo.xres, mVInfo.yres, 594080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin, 595080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin, 596080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mVInfo.pixclock/1000/1000); 597c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R //If its a new ID - update var_screeninfo 598080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed if ((isValidMode(ID)) && mCurrentMode != ID) { 599ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed const struct disp_mode_timing_type *mode = 6001589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed &supported_video_mode_lut[0]; 601ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed unsigned count = sizeof(supported_video_mode_lut)/sizeof 6021589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed (*supported_video_mode_lut); 603ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed for (unsigned int i = 0; i < count; ++i) { 604ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed const struct disp_mode_timing_type *cur = 6051589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed &supported_video_mode_lut[i]; 606ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed if (cur->video_format == ID) 607ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed mode = cur; 608ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 609080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mode->set_info(mVInfo); 610080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed ALOGD_IF(DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx %d" 6111589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed "(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, ID, 61297133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R mode->video_format, mVInfo.xres, mVInfo.yres, 613080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin, 614080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin, 615080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mVInfo.pixclock/1000/1000); 616e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang#ifdef FB_METADATA_VIDEO_INFO_CODE_SUPPORT 617e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang struct msmfb_metadata metadata; 618e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang memset(&metadata, 0 , sizeof(metadata)); 619e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang metadata.op = metadata_op_vic; 620e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang metadata.data.video_info_code = mode->video_format; 621e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang if (ioctl(mFd, MSMFB_METADATA_SET, &metadata) == -1) { 622e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang ALOGD("In %s: MSMFB_METADATA_SET failed Err Str = %s", 623e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang __FUNCTION__, strerror(errno)); 624e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang } 625e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang#endif 62697133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R mVInfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE; 62797133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R ret = ioctl(mFd, FBIOPUT_VSCREENINFO, &mVInfo); 62897133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R if(ret < 0) { 62997133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R ALOGD("In %s: FBIOPUT_VSCREENINFO failed Err Str = %s", 63097133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R __FUNCTION__, strerror(errno)); 63197133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R } 632080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed mCurrentMode = ID; 633ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 634ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed} 635ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 636620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::setExternalDisplay(bool connected, int extFbNum) 637ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{ 638ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed hwc_context_t* ctx = mHwcContext; 639ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed if(ctx) { 640620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ALOGD_IF(DEBUG, "%s: connected = %d", __FUNCTION__, connected); 641ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed // Store the external display 642620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar mConnected = connected; 643620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar mConnectedFbNum = extFbNum; 64490571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar mHwcContext->dpyAttr[mExtDpyNum].connected = connected; 645620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar // Update external fb number in Overlay context 646620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar overlay::Overlay::getInstance()->setExtFbNum(extFbNum); 647ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 648620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar} 649620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar 650620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarint ExternalDisplay::getExtFbNum(int &fbNum) { 651620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar int ret = -1; 652620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(mConnected) { 653620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar fbNum = mConnectedFbNum; 654620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ret = 0; 655620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } 656620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar return ret; 657ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed} 658ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed 6591589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmedbool ExternalDisplay::writeHPDOption(int userOption) const 660ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{ 661ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed bool ret = true; 662620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar char sysFsHPDFilePath[255]; 663620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar sprintf(sysFsHPDFilePath ,"/sys/devices/virtual/graphics/fb%d/hpd", 664620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar mHdmiFbNum); 665620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar int hdmiHPDFile = open(sysFsHPDFilePath,O_RDWR, 0); 666ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed if (hdmiHPDFile < 0) { 667620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ALOGE("%s: state file '%s' not found : ret%d err str: %s", __FUNCTION__, 668620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar sysFsHPDFilePath, hdmiHPDFile, strerror(errno)); 669ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed ret = false; 670ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } else { 671ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed int err = -1; 672620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ALOGD_IF(DEBUG, "%s: option = %d", __FUNCTION__, userOption); 673ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed if(userOption) 674ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed err = write(hdmiHPDFile, "1", 2); 675ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed else 676ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed err = write(hdmiHPDFile, "0" , 2); 677ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed if (err <= 0) { 678620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ALOGE("%s: file write failed '%s'", __FUNCTION__, sysFsHPDFilePath); 679ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed ret = false; 680ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 681ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed close(hdmiHPDFile); 682ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed } 683ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed return ret; 684ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed} 685080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed 686b4e7df4fbb0a21bb4cd0e7b7506380cbfceae729Saurabh Shah/* 687b4e7df4fbb0a21bb4cd0e7b7506380cbfceae729Saurabh Shah * commits the changes to the external display 688b4e7df4fbb0a21bb4cd0e7b7506380cbfceae729Saurabh Shah */ 6892e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahbool ExternalDisplay::post() 690080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed{ 69116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if(mFd == -1) 692080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed return false; 69390571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar 69416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed struct mdp_display_commit ext_commit; 695eeb2868ac7dc7f962ccaa920e73767b0c2e3585fNaseer Ahmed memset(&ext_commit, 0, sizeof(struct mdp_display_commit)); 696eeb2868ac7dc7f962ccaa920e73767b0c2e3585fNaseer Ahmed ext_commit.flags = MDP_DISPLAY_COMMIT_OVERLAY; 69716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (ioctl(mFd, MSMFB_DISPLAY_COMMIT, &ext_commit) == -1) { 698620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ALOGE("%s: MSMFB_DISPLAY_COMMIT for external failed, str: %s", 699620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar __FUNCTION__, strerror(errno)); 700620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar return false; 701080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed } 702080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed return true; 703080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed} 704080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed 705620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::setDpyWfdAttr() { 706620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar if(mHwcContext) { 70790571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar mHwcContext->dpyAttr[mExtDpyNum].xres = mVInfo.xres; 70890571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar mHwcContext->dpyAttr[mExtDpyNum].yres = mVInfo.yres; 70990571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar mHwcContext->dpyAttr[mExtDpyNum].vsync_period = 710620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar 1000000000l /60; 711620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar ALOGD_IF(DEBUG,"%s: wfd...connected..!",__FUNCTION__); 712620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar } 713620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar} 714620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar 715620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::setDpyHdmiAttr() { 7162e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah int width = 0, height = 0, fps = 0; 7172e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah getAttrForMode(width, height, fps); 7182e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah if(mHwcContext) { 71976443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah ALOGD("ExtDisplay setting xres = %d, yres = %d", width, height); 7202e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = width; 7212e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = height; 72276443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period = 72376443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah 1000000000l / fps; 7242e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah } 7252e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah} 7262e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah 727620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::getAttrForMode(int& width, int& height, int& fps) { 7282e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah switch (mCurrentMode) { 7292e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah case m640x480p60_4_3: 7302e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah width = 640; 7312e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah height = 480; 7322e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah fps = 60; 7332e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah break; 7342e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah case m720x480p60_4_3: 7352e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah case m720x480p60_16_9: 7362e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah width = 720; 7372e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah height = 480; 7382e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah fps = 60; 7392e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah break; 7402e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah case m720x576p50_4_3: 7412e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah case m720x576p50_16_9: 7422e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah width = 720; 7432e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah height = 576; 7442e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah fps = 50; 7452e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah break; 7462e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah case m1280x720p50_16_9: 7472e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah width = 1280; 7482e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah height = 720; 7492e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah fps = 50; 7502e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah break; 7512e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah case m1280x720p60_16_9: 7522e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah width = 1280; 7532e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah height = 720; 7542e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah fps = 60; 7552e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah break; 7562e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah case m1920x1080p24_16_9: 7572e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah width = 1920; 7582e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah height = 1080; 7592e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah fps = 24; 7602e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah break; 7612e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah case m1920x1080p25_16_9: 7622e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah width = 1920; 7632e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah height = 1080; 7642e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah fps = 25; 7652e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah break; 7662e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah case m1920x1080p30_16_9: 7672e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah width = 1920; 7682e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah height = 1080; 7692e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah fps = 30; 7702e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah break; 7712e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah case m1920x1080p50_16_9: 7722e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah width = 1920; 7732e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah height = 1080; 7742e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah fps = 50; 7752e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah break; 7762e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah case m1920x1080p60_16_9: 7772e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah width = 1920; 7782e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah height = 1080; 7792e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah fps = 60; 7802e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah break; 781080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed } 782080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed} 783080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed 784ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}; 785