1b166940edca6e312463461438e2aa66e9852c26aBenoit Goby/* 2b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Copyright (C) 2010 The Android Open Source Project 3b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Copyright (C) 2012, The Linux Foundation. All rights reserved. 4b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * 5b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Not a Contribution, Apache license notifications and license are 6b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * retained for attribution purposes only. 7b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * 8b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Licensed under the Apache License, Version 2.0 (the "License"); 9b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * you may not use this file except in compliance with the License. 10b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * You may obtain a copy of the License at 11b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * 12b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * http://www.apache.org/licenses/LICENSE-2.0 13b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * 14b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Unless required by applicable law or agreed to in writing, software 15b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * distributed under the License is distributed on an "AS IS" BASIS, 16b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * See the License for the specific language governing permissions and 18b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * limitations under the License. 19b166940edca6e312463461438e2aa66e9852c26aBenoit Goby */ 20b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 21b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define DEBUG 0 22b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <ctype.h> 23b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <fcntl.h> 24b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <media/IAudioPolicyService.h> 25b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <media/AudioSystem.h> 26b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <utils/threads.h> 27b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <utils/Errors.h> 28b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <utils/Log.h> 29b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 30b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <linux/msm_mdp.h> 31b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <linux/fb.h> 32b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <sys/ioctl.h> 33b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <sys/poll.h> 34b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <sys/resource.h> 35b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <cutils/properties.h> 36b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "hwc_utils.h" 37b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "external.h" 38b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "overlayUtils.h" 39b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "overlay.h" 40b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 41b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyusing namespace android; 42b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 43b166940edca6e312463461438e2aa66e9852c26aBenoit Gobynamespace qhwc { 44b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 45b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define MAX_FRAME_BUFFER_NAME_SIZE (80) 46b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define MAX_DISPLAY_DEVICES (3) 47b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 48b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 49b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyconst char* msmFbDevicePath[] = { "/dev/graphics/fb1", 50b166940edca6e312463461438e2aa66e9852c26aBenoit Goby "/dev/graphics/fb2"}; 51b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 52b166940edca6e312463461438e2aa66e9852c26aBenoit Goby/* 53b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Updates extDeviceFbIndex Array with the correct frame buffer indices 54b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * of avaiable external devices 55b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * 56b166940edca6e312463461438e2aa66e9852c26aBenoit Goby */ 57b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::updateExtDispDevFbIndex() 58b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 59b166940edca6e312463461438e2aa66e9852c26aBenoit Goby FILE *displayDeviceFP = NULL; 60b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char fbType[MAX_FRAME_BUFFER_NAME_SIZE]; 61b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE]; 62b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 63b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for(int j = 1; j < MAX_DISPLAY_DEVICES; j++) { 64b166940edca6e312463461438e2aa66e9852c26aBenoit Goby sprintf (msmFbTypePath,"/sys/class/graphics/fb%d/msm_fb_type", j); 65b166940edca6e312463461438e2aa66e9852c26aBenoit Goby displayDeviceFP = fopen(msmFbTypePath, "r"); 66b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(displayDeviceFP){ 67b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE, 68b166940edca6e312463461438e2aa66e9852c26aBenoit Goby displayDeviceFP); 69b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(strncmp(fbType, "dtv panel", strlen("dtv panel")) == 0){ 70b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG,"hdmi framebuffer index is %d",j); 71b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHdmiFbNum = j; 72b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else if(strncmp(fbType, "writeback panel", 73b166940edca6e312463461438e2aa66e9852c26aBenoit Goby strlen("writeback panel")) == 0){ 74b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG,"wfd framebuffer index is %d",j); 75b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mWfdFbNum = j; 76b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 77b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fclose(displayDeviceFP); 78b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 79b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 80b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG,"%s: mHdmiFbNum: %d mWfdFbNum: %d ",__FUNCTION__, 81b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHdmiFbNum, mWfdFbNum); 82b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 83b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 84b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint ExternalDisplay::configureHDMIDisplay() { 85b166940edca6e312463461438e2aa66e9852c26aBenoit Goby openFrameBuffer(mHdmiFbNum); 86b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mFd == -1) 87b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -1; 88b166940edca6e312463461438e2aa66e9852c26aBenoit Goby readCEUnderscanInfo(); 89b166940edca6e312463461438e2aa66e9852c26aBenoit Goby readResolution(); 90b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // TODO: Move this to activate 91b166940edca6e312463461438e2aa66e9852c26aBenoit Goby /* Used for changing the resolution 92b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * getUserMode will get the preferred 93b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * mode set thru adb shell */ 94b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int mode = getUserMode(); 95b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (mode == -1) { 96b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Get the best mode and set 97b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mode = getBestMode(); 98b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 99b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setResolution(mode); 100b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setDpyHdmiAttr(); 101b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setExternalDisplay(true, mHdmiFbNum); 102b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 0; 103b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 104b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 105b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint ExternalDisplay::configureWFDDisplay() { 106b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int ret = 0; 107b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mConnectedFbNum == mHdmiFbNum) { 108b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: Cannot process WFD connection while HDMI is active", 109b166940edca6e312463461438e2aa66e9852c26aBenoit Goby __FUNCTION__); 110b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -1; 111b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 112b166940edca6e312463461438e2aa66e9852c26aBenoit Goby openFrameBuffer(mWfdFbNum); 113b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mFd == -1) 114b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -1; 115b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo); 116b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ret < 0) { 117b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__, 118b166940edca6e312463461438e2aa66e9852c26aBenoit Goby strerror(errno)); 119b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 120b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setDpyWfdAttr(); 121b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setExternalDisplay(true, mWfdFbNum); 122b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 0; 123b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 124b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 125b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint ExternalDisplay::teardownHDMIDisplay() { 126b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mConnectedFbNum == mHdmiFbNum) { 127b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // hdmi offline event..! 128b166940edca6e312463461438e2aa66e9852c26aBenoit Goby closeFrameBuffer(); 129b166940edca6e312463461438e2aa66e9852c26aBenoit Goby resetInfo(); 130b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setExternalDisplay(false); 131b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 132b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 0; 133b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 134b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 135b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint ExternalDisplay::teardownWFDDisplay() { 136b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mConnectedFbNum == mWfdFbNum) { 137b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // wfd offline event..! 138b166940edca6e312463461438e2aa66e9852c26aBenoit Goby closeFrameBuffer(); 139b166940edca6e312463461438e2aa66e9852c26aBenoit Goby memset(&mVInfo, 0, sizeof(mVInfo)); 140b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setExternalDisplay(false); 141b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 142b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 0; 143b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 144b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 145b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::processUEventOnline(const char *str) { 146b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const char *s1 = str + strlen("change@/devices/virtual/switch/"); 147b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(!strncmp(s1,"hdmi",strlen(s1))) { 148b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // hdmi online event..! 149b166940edca6e312463461438e2aa66e9852c26aBenoit Goby configureHDMIDisplay(); 150b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // set system property 151b166940edca6e312463461438e2aa66e9852c26aBenoit Goby property_set("hw.hdmiON", "1"); 152b166940edca6e312463461438e2aa66e9852c26aBenoit Goby }else if(!strncmp(s1,"wfd",strlen(s1))) { 153b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // wfd online event..! 154b166940edca6e312463461438e2aa66e9852c26aBenoit Goby configureWFDDisplay(); 155b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 156b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 157b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 158b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::processUEventOffline(const char *str) { 159b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const char *s1 = str + strlen("change@/devices/virtual/switch/"); 160b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(!strncmp(s1,"hdmi",strlen(s1))) { 161b166940edca6e312463461438e2aa66e9852c26aBenoit Goby teardownHDMIDisplay(); 162b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // unset system property 163b166940edca6e312463461438e2aa66e9852c26aBenoit Goby property_set("hw.hdmiON", "0"); 164b166940edca6e312463461438e2aa66e9852c26aBenoit Goby }else if(!strncmp(s1,"wfd",strlen(s1))) { 165b166940edca6e312463461438e2aa66e9852c26aBenoit Goby teardownWFDDisplay(); 166b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 167b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 168b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 169b166940edca6e312463461438e2aa66e9852c26aBenoit GobyExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1), 170b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0), 171b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mUnderscanSupported(false), mHwcContext(ctx), mHdmiFbNum(-1), 172b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mWfdFbNum(-1), mExtDpyNum(HWC_DISPLAY_EXTERNAL) 173b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 174b166940edca6e312463461438e2aa66e9852c26aBenoit Goby memset(&mVInfo, 0, sizeof(mVInfo)); 175b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Determine the fb index for external display devices. 176b166940edca6e312463461438e2aa66e9852c26aBenoit Goby updateExtDispDevFbIndex(); 177b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // disable HPD at start, it will be enabled later 178b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // when the display powers on 179b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // This helps for framework reboot or adb shell stop/start 180b166940edca6e312463461438e2aa66e9852c26aBenoit Goby writeHPDOption(0); 181b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 182b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 183b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 184b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::setEDIDMode(int resMode) { 185b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG,"resMode=%d ", resMode); 186b166940edca6e312463461438e2aa66e9852c26aBenoit Goby { 187b166940edca6e312463461438e2aa66e9852c26aBenoit Goby Mutex::Autolock lock(mExtDispLock); 188b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setExternalDisplay(false); 189b166940edca6e312463461438e2aa66e9852c26aBenoit Goby openFrameBuffer(mHdmiFbNum); 190b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setResolution(resMode); 191b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 192b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setExternalDisplay(true, mHdmiFbNum); 193b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 194b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 195b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::setHPD(uint32_t startEnd) { 196b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG,"HPD enabled=%d", startEnd); 197b166940edca6e312463461438e2aa66e9852c26aBenoit Goby writeHPDOption(startEnd); 198b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 199b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 200b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::setActionSafeDimension(int w, int h) { 201b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h); 202b166940edca6e312463461438e2aa66e9852c26aBenoit Goby Mutex::Autolock lock(mExtDispLock); 203b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char actionsafeWidth[PROPERTY_VALUE_MAX]; 204b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char actionsafeHeight[PROPERTY_VALUE_MAX]; 205b166940edca6e312463461438e2aa66e9852c26aBenoit Goby sprintf(actionsafeWidth, "%d", w); 206b166940edca6e312463461438e2aa66e9852c26aBenoit Goby property_set("hw.actionsafe.width", actionsafeWidth); 207b166940edca6e312463461438e2aa66e9852c26aBenoit Goby sprintf(actionsafeHeight, "%d", h); 208b166940edca6e312463461438e2aa66e9852c26aBenoit Goby property_set("hw.actionsafe.height", actionsafeHeight); 209b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setExternalDisplay(true, mHdmiFbNum); 210b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 211b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 212b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint ExternalDisplay::getModeCount() const { 213b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG,"HPD mModeCount=%d", mModeCount); 214b166940edca6e312463461438e2aa66e9852c26aBenoit Goby Mutex::Autolock lock(mExtDispLock); 215b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return mModeCount; 216b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 217b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 218b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::getEDIDModes(int *out) const { 219b166940edca6e312463461438e2aa66e9852c26aBenoit Goby Mutex::Autolock lock(mExtDispLock); 220b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for(int i = 0;i < mModeCount;i++) { 221b166940edca6e312463461438e2aa66e9852c26aBenoit Goby out[i] = mEDIDModes[i]; 222b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 223b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 224b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 225b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::readCEUnderscanInfo() 226b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 227b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int hdmiScanInfoFile = -1; 228b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int len = -1; 229b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char scanInfo[17]; 230b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char *ce_info_str = NULL; 231b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const char token[] = ", \n"; 232b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int ce_info = -1; 233b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char sysFsScanInfoFilePath[128]; 234b166940edca6e312463461438e2aa66e9852c26aBenoit Goby sprintf(sysFsScanInfoFilePath, "/sys/devices/virtual/graphics/fb%d/" 235b166940edca6e312463461438e2aa66e9852c26aBenoit Goby "scan_info", mHdmiFbNum); 236b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 237b166940edca6e312463461438e2aa66e9852c26aBenoit Goby memset(scanInfo, 0, sizeof(scanInfo)); 238b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hdmiScanInfoFile = open(sysFsScanInfoFilePath, O_RDONLY, 0); 239b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (hdmiScanInfoFile < 0) { 240b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG, "%s: scan_info file '%s' not found", 241b166940edca6e312463461438e2aa66e9852c26aBenoit Goby __FUNCTION__, sysFsScanInfoFilePath); 242b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return; 243b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else { 244b166940edca6e312463461438e2aa66e9852c26aBenoit Goby len = read(hdmiScanInfoFile, scanInfo, sizeof(scanInfo)-1); 245b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD("%s: Scan Info string: %s length = %d", 246b166940edca6e312463461438e2aa66e9852c26aBenoit Goby __FUNCTION__, scanInfo, len); 247b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (len <= 0) { 248b166940edca6e312463461438e2aa66e9852c26aBenoit Goby close(hdmiScanInfoFile); 249b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: Scan Info file empty '%s'", 250b166940edca6e312463461438e2aa66e9852c26aBenoit Goby __FUNCTION__, sysFsScanInfoFilePath); 251b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return; 252b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 253b166940edca6e312463461438e2aa66e9852c26aBenoit Goby scanInfo[len] = '\0'; /* null terminate the string */ 254b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 255b166940edca6e312463461438e2aa66e9852c26aBenoit Goby close(hdmiScanInfoFile); 256b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 257b166940edca6e312463461438e2aa66e9852c26aBenoit Goby /* 258b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * The scan_info contains the three fields 259b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * PT - preferred video format 260b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * IT - video format 261b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * CE video format - containing the underscan support information 262b166940edca6e312463461438e2aa66e9852c26aBenoit Goby */ 263b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 264b166940edca6e312463461438e2aa66e9852c26aBenoit Goby /* PT */ 265b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ce_info_str = strtok(scanInfo, token); 266b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (ce_info_str) { 267b166940edca6e312463461438e2aa66e9852c26aBenoit Goby /* IT */ 268b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ce_info_str = strtok(NULL, token); 269b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (ce_info_str) { 270b166940edca6e312463461438e2aa66e9852c26aBenoit Goby /* CE */ 271b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ce_info_str = strtok(NULL, token); 272b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (ce_info_str) 273b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ce_info = atoi(ce_info_str); 274b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 275b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 276b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 277b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (ce_info_str) { 278b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // ce_info contains the underscan information 279b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (ce_info == EXT_SCAN_ALWAYS_UNDERSCANED || 280b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ce_info == EXT_SCAN_BOTH_SUPPORTED) 281b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // if TV supported underscan, then driver will always underscan 282b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // hence no need to apply action safe rectangle 283b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mUnderscanSupported = true; 284b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else { 285b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: scan_info string error", __FUNCTION__); 286b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 287b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 288b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // Store underscan support info in a system property 289b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const char* prop = (mUnderscanSupported) ? "1" : "0"; 290b166940edca6e312463461438e2aa66e9852c26aBenoit Goby property_set("hw.underscan_supported", prop); 291b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return; 292b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 293b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 294b166940edca6e312463461438e2aa66e9852c26aBenoit GobyExternalDisplay::~ExternalDisplay() 295b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 296b166940edca6e312463461438e2aa66e9852c26aBenoit Goby closeFrameBuffer(); 297b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 298b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 299b166940edca6e312463461438e2aa66e9852c26aBenoit Gobystruct disp_mode_timing_type { 300b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int video_format; 301b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 302b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int active_h; 303b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int active_v; 304b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 305b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int front_porch_h; 306b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int pulse_width_h; 307b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int back_porch_h; 308b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 309b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int front_porch_v; 310b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int pulse_width_v; 311b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int back_porch_v; 312b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 313b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int pixel_freq; 314b166940edca6e312463461438e2aa66e9852c26aBenoit Goby bool interlaced; 315b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 316b166940edca6e312463461438e2aa66e9852c26aBenoit Goby void set_info(struct fb_var_screeninfo &info) const; 317b166940edca6e312463461438e2aa66e9852c26aBenoit Goby}; 318b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 319b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid disp_mode_timing_type::set_info(struct fb_var_screeninfo &info) const 320b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 321b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.reserved[0] = 0; 322b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.reserved[1] = 0; 323b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.reserved[2] = 0; 324b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#ifndef FB_METADATA_VIDEO_INFO_CODE_SUPPORT 325b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.reserved[3] = (info.reserved[3] & 0xFFFF) | (video_format << 16); 326b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#endif 327b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.xoffset = 0; 328b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.yoffset = 0; 329b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.xres = active_h; 330b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.yres = active_v; 331b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 332b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.pixclock = pixel_freq*1000; 333b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.vmode = interlaced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED; 334b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 335b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.right_margin = front_porch_h; 336b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.hsync_len = pulse_width_h; 337b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.left_margin = back_porch_h; 338b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.lower_margin = front_porch_v; 339b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.vsync_len = pulse_width_v; 340b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.upper_margin = back_porch_v; 341b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 342b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 343b166940edca6e312463461438e2aa66e9852c26aBenoit Goby/* Video formates supported by the HDMI Standard */ 344b166940edca6e312463461438e2aa66e9852c26aBenoit Goby/* Indicates the resolution, pix clock and the aspect ratio */ 345b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m640x480p60_4_3 1 346b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m720x480p60_4_3 2 347b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m720x480p60_16_9 3 348b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m1280x720p60_16_9 4 349b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m1920x1080i60_16_9 5 350b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m1440x480i60_4_3 6 351b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m1440x480i60_16_9 7 352b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m1920x1080p60_16_9 16 353b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m720x576p50_4_3 17 354b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m720x576p50_16_9 18 355b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m1280x720p50_16_9 19 356b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m1440x576i50_4_3 21 357b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m1440x576i50_16_9 22 358b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m1920x1080p50_16_9 31 359b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m1920x1080p24_16_9 32 360b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m1920x1080p25_16_9 33 361b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define m1920x1080p30_16_9 34 362b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 363b166940edca6e312463461438e2aa66e9852c26aBenoit Gobystatic struct disp_mode_timing_type supported_video_mode_lut[] = { 364b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m640x480p60_4_3, 640, 480, 16, 96, 48, 10, 2, 33, 25200, false}, 365b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m720x480p60_4_3, 720, 480, 16, 62, 60, 9, 6, 30, 27030, false}, 366b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m720x480p60_16_9, 720, 480, 16, 62, 60, 9, 6, 30, 27030, false}, 367b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m1280x720p60_16_9, 1280, 720, 110, 40, 220, 5, 5, 20, 74250, false}, 368b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m1920x1080i60_16_9, 1920, 540, 88, 44, 148, 2, 5, 5, 74250, false}, 369b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m1440x480i60_4_3, 1440, 240, 38, 124, 114, 4, 3, 15, 27000, true}, 370b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m1440x480i60_16_9, 1440, 240, 38, 124, 114, 4, 3, 15, 27000, true}, 371b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m1920x1080p60_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 148500, false}, 372b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m720x576p50_4_3, 720, 576, 12, 64, 68, 5, 5, 39, 27000, false}, 373b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m720x576p50_16_9, 720, 576, 12, 64, 68, 5, 5, 39, 27000, false}, 374b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m1280x720p50_16_9, 1280, 720, 440, 40, 220, 5, 5, 20, 74250, false}, 375b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m1440x576i50_4_3, 1440, 288, 24, 126, 138, 2, 3, 19, 27000, true}, 376b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m1440x576i50_16_9, 1440, 288, 24, 126, 138, 2, 3, 19, 27000, true}, 377b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m1920x1080p50_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 148500, false}, 378b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m1920x1080p24_16_9, 1920, 1080, 638, 44, 148, 4, 5, 36, 74250, false}, 379b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m1920x1080p25_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 74250, false}, 380b166940edca6e312463461438e2aa66e9852c26aBenoit Goby {m1920x1080p30_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 74250, false}, 381b166940edca6e312463461438e2aa66e9852c26aBenoit Goby}; 382b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 383b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint ExternalDisplay::parseResolution(char* edidStr, int* edidModes) 384b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 385b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char delim = ','; 386b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int count = 0; 387b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char *start, *end; 388b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // EDIDs are string delimited by ',' 389b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // Ex: 16,4,5,3,32,34,1 390b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // Parse this string to get mode(int) 391b166940edca6e312463461438e2aa66e9852c26aBenoit Goby start = (char*) edidStr; 392b166940edca6e312463461438e2aa66e9852c26aBenoit Goby end = &delim; 393b166940edca6e312463461438e2aa66e9852c26aBenoit Goby while(*end == delim) { 394b166940edca6e312463461438e2aa66e9852c26aBenoit Goby edidModes[count] = (int) strtol(start, &end, 10); 395b166940edca6e312463461438e2aa66e9852c26aBenoit Goby start = end+1; 396b166940edca6e312463461438e2aa66e9852c26aBenoit Goby count++; 397b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 398b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG, "In %s: count = %d", __FUNCTION__, count); 399b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for (int i = 0; i < count; i++) 400b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG, "Mode[%d] = %d", i, edidModes[i]); 401b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return count; 402b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 403b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 404b166940edca6e312463461438e2aa66e9852c26aBenoit Gobybool ExternalDisplay::readResolution() 405b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 406b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char sysFsEDIDFilePath[255]; 407b166940edca6e312463461438e2aa66e9852c26aBenoit Goby sprintf(sysFsEDIDFilePath , "/sys/devices/virtual/graphics/fb%d/edid_modes", 408b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHdmiFbNum); 409b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 410b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int hdmiEDIDFile = open(sysFsEDIDFilePath, O_RDONLY, 0); 411b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int len = -1; 412b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 413b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (hdmiEDIDFile < 0) { 414b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: edid_modes file '%s' not found", 415b166940edca6e312463461438e2aa66e9852c26aBenoit Goby __FUNCTION__, sysFsEDIDFilePath); 416b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return false; 417b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else { 418b166940edca6e312463461438e2aa66e9852c26aBenoit Goby len = read(hdmiEDIDFile, mEDIDs, sizeof(mEDIDs)-1); 419b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG, "%s: EDID string: %s length = %d", 420b166940edca6e312463461438e2aa66e9852c26aBenoit Goby __FUNCTION__, mEDIDs, len); 421b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if ( len <= 0) { 422b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: edid_modes file empty '%s'", 423b166940edca6e312463461438e2aa66e9852c26aBenoit Goby __FUNCTION__, sysFsEDIDFilePath); 424b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 425b166940edca6e312463461438e2aa66e9852c26aBenoit Goby else { 426b166940edca6e312463461438e2aa66e9852c26aBenoit Goby while (len > 1 && isspace(mEDIDs[len-1])) 427b166940edca6e312463461438e2aa66e9852c26aBenoit Goby --len; 428b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mEDIDs[len] = 0; 429b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 430b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 431b166940edca6e312463461438e2aa66e9852c26aBenoit Goby close(hdmiEDIDFile); 432b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(len > 0) { 433b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // Get EDID modes from the EDID strings 434b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mModeCount = parseResolution(mEDIDs, mEDIDModes); 435b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG, "%s: mModeCount = %d", __FUNCTION__, 436b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mModeCount); 437b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 438b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 439b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return (strlen(mEDIDs) > 0); 440b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 441b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 442b166940edca6e312463461438e2aa66e9852c26aBenoit Gobybool ExternalDisplay::openFrameBuffer(int fbNum) 443b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 444b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (mFd == -1) { 445b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mFd = open(msmFbDevicePath[fbNum-1], O_RDWR); 446b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (mFd < 0) 447b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: %s is not available", __FUNCTION__, 448b166940edca6e312463461438e2aa66e9852c26aBenoit Goby msmFbDevicePath[fbNum-1]); 449b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mHwcContext) { 450b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHwcContext->dpyAttr[mExtDpyNum].fd = mFd; 451b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 452b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 453b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return (mFd > 0); 454b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 455b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 456b166940edca6e312463461438e2aa66e9852c26aBenoit Gobybool ExternalDisplay::closeFrameBuffer() 457b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 458b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int ret = 0; 459b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mFd >= 0) { 460b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ret = close(mFd); 461b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mFd = -1; 462b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 463b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mHwcContext) { 464b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHwcContext->dpyAttr[mExtDpyNum].fd = mFd; 465b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 466b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return (ret == 0); 467b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 468b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 469b166940edca6e312463461438e2aa66e9852c26aBenoit Goby// clears the vinfo, edid, best modes 470b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::resetInfo() 471b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 472b166940edca6e312463461438e2aa66e9852c26aBenoit Goby memset(&mVInfo, 0, sizeof(mVInfo)); 473b166940edca6e312463461438e2aa66e9852c26aBenoit Goby memset(mEDIDs, 0, sizeof(mEDIDs)); 474b166940edca6e312463461438e2aa66e9852c26aBenoit Goby memset(mEDIDModes, 0, sizeof(mEDIDModes)); 475b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mModeCount = 0; 476b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mCurrentMode = -1; 477b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mUnderscanSupported = false; 478b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // Reset the underscan supported system property 479b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const char* prop = "0"; 480b166940edca6e312463461438e2aa66e9852c26aBenoit Goby property_set("hw.underscan_supported", prop); 481b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 482b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 483b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint ExternalDisplay::getModeOrder(int mode) 484b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 485b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // XXX: We dont support interlaced modes but having 486b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // it here for for future 487b166940edca6e312463461438e2aa66e9852c26aBenoit Goby switch (mode) { 488b166940edca6e312463461438e2aa66e9852c26aBenoit Goby default: 489b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1440x480i60_4_3: 490b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 1; // 480i 4:3 491b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1440x480i60_16_9: 492b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 2; // 480i 16:9 493b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1440x576i50_4_3: 494b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 3; // i576i 4:3 495b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1440x576i50_16_9: 496b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 4; // 576i 16:9 497b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m640x480p60_4_3: 498b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 5; // 640x480 4:3 499b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m720x480p60_4_3: 500b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 6; // 480p 4:3 501b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m720x480p60_16_9: 502b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 7; // 480p 16:9 503b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m720x576p50_4_3: 504b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 8; // 576p 4:3 505b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m720x576p50_16_9: 506b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 9; // 576p 16:9 507b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1920x1080i60_16_9: 508b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 10; // 1080i 16:9 509b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1280x720p50_16_9: 510b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 11; // 720p@50Hz 511b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1280x720p60_16_9: 512b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 12; // 720p@60Hz 513b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1920x1080p24_16_9: 514b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 13; //1080p@24Hz 515b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1920x1080p25_16_9: 516b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 14; //108-p@25Hz 517b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1920x1080p30_16_9: 518b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 15; //1080p@30Hz 519b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1920x1080p50_16_9: 520b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 16; //1080p@50Hz 521b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1920x1080p60_16_9: 522b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 17; //1080p@60Hz 523b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 524b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 525b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 526b166940edca6e312463461438e2aa66e9852c26aBenoit Goby/// Returns the user mode set(if any) using adb shell 527b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint ExternalDisplay::getUserMode() { 528b166940edca6e312463461438e2aa66e9852c26aBenoit Goby /* Based on the property set the resolution */ 529b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char property_value[PROPERTY_VALUE_MAX]; 530b166940edca6e312463461438e2aa66e9852c26aBenoit Goby property_get("hw.hdmi.resolution", property_value, "-1"); 531b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int mode = atoi(property_value); 532b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // We dont support interlaced modes 533b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(isValidMode(mode) && !isInterlacedMode(mode)) { 534b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG, "%s: setting the HDMI mode = %d", __FUNCTION__, mode); 535b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return mode; 536b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 537b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -1; 538b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 539b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 540b166940edca6e312463461438e2aa66e9852c26aBenoit Goby// Get the best mode for the current HD TV 541b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint ExternalDisplay::getBestMode() { 542b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int bestOrder = 0; 543b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int bestMode = m640x480p60_4_3; 544b166940edca6e312463461438e2aa66e9852c26aBenoit Goby Mutex::Autolock lock(mExtDispLock); 545b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // for all the edid read, get the best mode 546b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for(int i = 0; i < mModeCount; i++) { 547b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int mode = mEDIDModes[i]; 548b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int order = getModeOrder(mode); 549b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (order > bestOrder) { 550b166940edca6e312463461438e2aa66e9852c26aBenoit Goby bestOrder = order; 551b166940edca6e312463461438e2aa66e9852c26aBenoit Goby bestMode = mode; 552b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 553b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 554b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return bestMode; 555b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 556b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 557b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyinline bool ExternalDisplay::isValidMode(int ID) 558b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 559b166940edca6e312463461438e2aa66e9852c26aBenoit Goby bool valid = false; 560b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for (int i = 0; i < mModeCount; i++) { 561b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ID == mEDIDModes[i]) { 562b166940edca6e312463461438e2aa66e9852c26aBenoit Goby valid = true; 563b166940edca6e312463461438e2aa66e9852c26aBenoit Goby break; 564b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 565b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 566b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return valid; 567b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 568b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 569b166940edca6e312463461438e2aa66e9852c26aBenoit Goby// returns true if the mode(ID) is interlaced mode format 570b166940edca6e312463461438e2aa66e9852c26aBenoit Gobybool ExternalDisplay::isInterlacedMode(int ID) { 571b166940edca6e312463461438e2aa66e9852c26aBenoit Goby bool interlaced = false; 572b166940edca6e312463461438e2aa66e9852c26aBenoit Goby switch(ID) { 573b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1440x480i60_4_3: 574b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1440x480i60_16_9: 575b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1440x576i50_4_3: 576b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1440x576i50_16_9: 577b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1920x1080i60_16_9: 578b166940edca6e312463461438e2aa66e9852c26aBenoit Goby interlaced = true; 579b166940edca6e312463461438e2aa66e9852c26aBenoit Goby default: 580b166940edca6e312463461438e2aa66e9852c26aBenoit Goby interlaced = false; 581b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 582b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return interlaced; 583b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 584b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 585b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::setResolution(int ID) 586b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 587b166940edca6e312463461438e2aa66e9852c26aBenoit Goby struct fb_var_screeninfo info; 588b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int ret = 0; 589b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo); 590b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ret < 0) { 591b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__, 592b166940edca6e312463461438e2aa66e9852c26aBenoit Goby strerror(errno)); 593b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 594b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 595b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG, "%s: GET Info<ID=%d %dx%d (%d,%d,%d)," 596b166940edca6e312463461438e2aa66e9852c26aBenoit Goby "(%d,%d,%d) %dMHz>", __FUNCTION__, 597b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mVInfo.reserved[3], mVInfo.xres, mVInfo.yres, 598b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin, 599b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin, 600b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mVInfo.pixclock/1000/1000); 601b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //If its a new ID - update var_screeninfo 602b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if ((isValidMode(ID)) && mCurrentMode != ID) { 603b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const struct disp_mode_timing_type *mode = 604b166940edca6e312463461438e2aa66e9852c26aBenoit Goby &supported_video_mode_lut[0]; 605b166940edca6e312463461438e2aa66e9852c26aBenoit Goby unsigned count = sizeof(supported_video_mode_lut)/sizeof 606b166940edca6e312463461438e2aa66e9852c26aBenoit Goby (*supported_video_mode_lut); 607b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for (unsigned int i = 0; i < count; ++i) { 608b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const struct disp_mode_timing_type *cur = 609b166940edca6e312463461438e2aa66e9852c26aBenoit Goby &supported_video_mode_lut[i]; 610b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (cur->video_format == ID) 611b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mode = cur; 612b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 613b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mode->set_info(mVInfo); 614b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx %d" 615b166940edca6e312463461438e2aa66e9852c26aBenoit Goby "(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, ID, 616b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mode->video_format, mVInfo.xres, mVInfo.yres, 617b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin, 618b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin, 619b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mVInfo.pixclock/1000/1000); 620b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#ifdef FB_METADATA_VIDEO_INFO_CODE_SUPPORT 621b166940edca6e312463461438e2aa66e9852c26aBenoit Goby struct msmfb_metadata metadata; 622b166940edca6e312463461438e2aa66e9852c26aBenoit Goby memset(&metadata, 0 , sizeof(metadata)); 623b166940edca6e312463461438e2aa66e9852c26aBenoit Goby metadata.op = metadata_op_vic; 624b166940edca6e312463461438e2aa66e9852c26aBenoit Goby metadata.data.video_info_code = mode->video_format; 625b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (ioctl(mFd, MSMFB_METADATA_SET, &metadata) == -1) { 626b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD("In %s: MSMFB_METADATA_SET failed Err Str = %s", 627b166940edca6e312463461438e2aa66e9852c26aBenoit Goby __FUNCTION__, strerror(errno)); 628b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 629b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#endif 630b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mVInfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE; 631b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ret = ioctl(mFd, FBIOPUT_VSCREENINFO, &mVInfo); 632b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ret < 0) { 633b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD("In %s: FBIOPUT_VSCREENINFO failed Err Str = %s", 634b166940edca6e312463461438e2aa66e9852c26aBenoit Goby __FUNCTION__, strerror(errno)); 635b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 636b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mCurrentMode = ID; 637b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 638b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 639b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 640b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::setExternalDisplay(bool connected, int extFbNum) 641b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 642b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_context_t* ctx = mHwcContext; 643b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx) { 644b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG, "%s: connected = %d", __FUNCTION__, connected); 645b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // Store the external display 646b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mConnected = connected; 647b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mConnectedFbNum = extFbNum; 648b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHwcContext->dpyAttr[mExtDpyNum].connected = connected; 649b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // Update external fb number in Overlay context 650b166940edca6e312463461438e2aa66e9852c26aBenoit Goby overlay::Overlay::getInstance()->setExtFbNum(extFbNum); 651b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 652b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 653b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 654b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint ExternalDisplay::getExtFbNum(int &fbNum) { 655b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int ret = -1; 656b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mConnected) { 657b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fbNum = mConnectedFbNum; 658b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ret = 0; 659b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 660b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return ret; 661b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 662b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 663b166940edca6e312463461438e2aa66e9852c26aBenoit Gobybool ExternalDisplay::writeHPDOption(int userOption) const 664b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 665b166940edca6e312463461438e2aa66e9852c26aBenoit Goby bool ret = true; 666b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char sysFsHPDFilePath[255]; 667b166940edca6e312463461438e2aa66e9852c26aBenoit Goby sprintf(sysFsHPDFilePath ,"/sys/devices/virtual/graphics/fb%d/hpd", 668b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHdmiFbNum); 669b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int hdmiHPDFile = open(sysFsHPDFilePath,O_RDWR, 0); 670b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (hdmiHPDFile < 0) { 671b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: state file '%s' not found : ret%d err str: %s", __FUNCTION__, 672b166940edca6e312463461438e2aa66e9852c26aBenoit Goby sysFsHPDFilePath, hdmiHPDFile, strerror(errno)); 673b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ret = false; 674b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else { 675b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int err = -1; 676b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG, "%s: option = %d", __FUNCTION__, userOption); 677b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(userOption) 678b166940edca6e312463461438e2aa66e9852c26aBenoit Goby err = write(hdmiHPDFile, "1", 2); 679b166940edca6e312463461438e2aa66e9852c26aBenoit Goby else 680b166940edca6e312463461438e2aa66e9852c26aBenoit Goby err = write(hdmiHPDFile, "0" , 2); 681b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (err <= 0) { 682b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: file write failed '%s'", __FUNCTION__, sysFsHPDFilePath); 683b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ret = false; 684b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 685b166940edca6e312463461438e2aa66e9852c26aBenoit Goby close(hdmiHPDFile); 686b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 687b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return ret; 688b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 689b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 690b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::setDpyWfdAttr() { 691b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mHwcContext) { 692b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHwcContext->dpyAttr[mExtDpyNum].xres = mVInfo.xres; 693b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHwcContext->dpyAttr[mExtDpyNum].yres = mVInfo.yres; 694b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHwcContext->dpyAttr[mExtDpyNum].vsync_period = 695b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1000000000l /60; 696b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(DEBUG,"%s: wfd...connected..!",__FUNCTION__); 697b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 698b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 699b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 700b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::setDpyHdmiAttr() { 701b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int width = 0, height = 0, fps = 0; 702b166940edca6e312463461438e2aa66e9852c26aBenoit Goby getAttrForMode(width, height, fps); 703b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mHwcContext) { 704b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD("ExtDisplay setting xres = %d, yres = %d", width, height); 705b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = width; 706b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = height; 707b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period = 708b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1000000000l / fps; 709b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 710b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 711b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 712b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid ExternalDisplay::getAttrForMode(int& width, int& height, int& fps) { 713b166940edca6e312463461438e2aa66e9852c26aBenoit Goby switch (mCurrentMode) { 714b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m640x480p60_4_3: 715b166940edca6e312463461438e2aa66e9852c26aBenoit Goby width = 640; 716b166940edca6e312463461438e2aa66e9852c26aBenoit Goby height = 480; 717b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fps = 60; 718b166940edca6e312463461438e2aa66e9852c26aBenoit Goby break; 719b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m720x480p60_4_3: 720b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m720x480p60_16_9: 721b166940edca6e312463461438e2aa66e9852c26aBenoit Goby width = 720; 722b166940edca6e312463461438e2aa66e9852c26aBenoit Goby height = 480; 723b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fps = 60; 724b166940edca6e312463461438e2aa66e9852c26aBenoit Goby break; 725b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m720x576p50_4_3: 726b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m720x576p50_16_9: 727b166940edca6e312463461438e2aa66e9852c26aBenoit Goby width = 720; 728b166940edca6e312463461438e2aa66e9852c26aBenoit Goby height = 576; 729b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fps = 50; 730b166940edca6e312463461438e2aa66e9852c26aBenoit Goby break; 731b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1280x720p50_16_9: 732b166940edca6e312463461438e2aa66e9852c26aBenoit Goby width = 1280; 733b166940edca6e312463461438e2aa66e9852c26aBenoit Goby height = 720; 734b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fps = 50; 735b166940edca6e312463461438e2aa66e9852c26aBenoit Goby break; 736b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1280x720p60_16_9: 737b166940edca6e312463461438e2aa66e9852c26aBenoit Goby width = 1280; 738b166940edca6e312463461438e2aa66e9852c26aBenoit Goby height = 720; 739b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fps = 60; 740b166940edca6e312463461438e2aa66e9852c26aBenoit Goby break; 741b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1920x1080p24_16_9: 742b166940edca6e312463461438e2aa66e9852c26aBenoit Goby width = 1920; 743b166940edca6e312463461438e2aa66e9852c26aBenoit Goby height = 1080; 744b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fps = 24; 745b166940edca6e312463461438e2aa66e9852c26aBenoit Goby break; 746b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1920x1080p25_16_9: 747b166940edca6e312463461438e2aa66e9852c26aBenoit Goby width = 1920; 748b166940edca6e312463461438e2aa66e9852c26aBenoit Goby height = 1080; 749b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fps = 25; 750b166940edca6e312463461438e2aa66e9852c26aBenoit Goby break; 751b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1920x1080p30_16_9: 752b166940edca6e312463461438e2aa66e9852c26aBenoit Goby width = 1920; 753b166940edca6e312463461438e2aa66e9852c26aBenoit Goby height = 1080; 754b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fps = 30; 755b166940edca6e312463461438e2aa66e9852c26aBenoit Goby break; 756b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1920x1080p50_16_9: 757b166940edca6e312463461438e2aa66e9852c26aBenoit Goby width = 1920; 758b166940edca6e312463461438e2aa66e9852c26aBenoit Goby height = 1080; 759b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fps = 50; 760b166940edca6e312463461438e2aa66e9852c26aBenoit Goby break; 761b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case m1920x1080p60_16_9: 762b166940edca6e312463461438e2aa66e9852c26aBenoit Goby width = 1920; 763b166940edca6e312463461438e2aa66e9852c26aBenoit Goby height = 1080; 764b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fps = 60; 765b166940edca6e312463461438e2aa66e9852c26aBenoit Goby break; 766b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 767b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 768b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 769b166940edca6e312463461438e2aa66e9852c26aBenoit Goby}; 770