external.cpp revision 0c8b7b5c841a7fad5df11b7e02d7cd792cfcc734
10c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed/* 20c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * Copyright (C) 2010 The Android Open Source Project 30c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * Copyright (C) 2012, Code Aurora Forum. All rights reserved. 40c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * 50c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * Not a Contribution, Apache license notifications and license are 60c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * retained for attribution purposes only. 70c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * 80c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License"); 90c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * you may not use this file except in compliance with the License. 100c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * You may obtain a copy of the License at 110c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * 120c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * http://www.apache.org/licenses/LICENSE-2.0 130c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * 140c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * Unless required by applicable law or agreed to in writing, software 150c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS, 160c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 170c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * See the License for the specific language governing permissions and 180c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed * limitations under the License. 190c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed */ 200c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 210c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define EXT_OBSERVER_DEBUG 0 220c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <ctype.h> 230c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <binder/IPCThreadState.h> 240c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <binder/IServiceManager.h> 250c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <media/IAudioPolicyService.h> 260c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <media/AudioSystem.h> 270c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <utils/threads.h> 280c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <utils/Errors.h> 290c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <utils/Log.h> 300c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 310c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <linux/msm_mdp.h> 320c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <linux/fb.h> 330c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <sys/ioctl.h> 340c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <sys/poll.h> 350c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 360c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <hardware_legacy/uevent.h> 370c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include <cutils/properties.h> 380c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include "hwc_utils.h" 390c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#include "hwc_ext_observer.h" 400c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 410c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmednamespace qhwc { 420c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 430c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 440c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define DEVICE_ROOT "/sys/devices/virtual/graphics" 450c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define DEVICE_NODE "fb1" 460c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 470c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define SYSFS_CONNECTED DEVICE_ROOT "/" DEVICE_NODE "/connected" 480c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define SYSFS_EDID_MODES DEVICE_ROOT "/" DEVICE_NODE "/edid_modes" 490c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define SYSFS_HPD DEVICE_ROOT "/" DEVICE_NODE "/hpd" 500c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 510c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 520c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedandroid::sp<ExtDisplayObserver> ExtDisplayObserver:: 530c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed sExtDisplayObserverInstance(0); 540c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 550c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer AhmedExtDisplayObserver::ExtDisplayObserver() : Thread(false), 560c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed fd(-1), mCurrentID(-1), mHwcContext(NULL) 570c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed{ 580c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed //Enable HPD for HDMI 590c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed writeHPDOption(1); 600c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 610c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 620c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer AhmedExtDisplayObserver::~ExtDisplayObserver() { 630c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if (fd > 0) 640c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed close(fd); 650c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 660c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 670c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer AhmedExtDisplayObserver *ExtDisplayObserver::getInstance() { 680c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s ", __FUNCTION__); 690c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if(sExtDisplayObserverInstance.get() == NULL) 700c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed sExtDisplayObserverInstance = new ExtDisplayObserver(); 710c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return sExtDisplayObserverInstance.get(); 720c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 730c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 740c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedvoid ExtDisplayObserver::setHwcContext(hwc_context_t* hwcCtx) { 750c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s", __FUNCTION__); 760c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if(hwcCtx) { 770c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed mHwcContext = hwcCtx; 780c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 790c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return; 800c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 810c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedvoid ExtDisplayObserver::onFirstRef() { 820c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s", __FUNCTION__); 830c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed run("ExtDisplayObserver", ANDROID_PRIORITY_DISPLAY); 840c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 850c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 860c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedint ExtDisplayObserver::readyToRun() { 870c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed //Initialize the uevent 880c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed uevent_init(); 890c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: success", __FUNCTION__); 900c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return android::NO_ERROR; 910c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 920c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 930c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedvoid ExtDisplayObserver::handleUEvent(char* str){ 940c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int connected = 0; 950c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // TODO: check for fb2(WFD) driver also 960c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if(!strcasestr(str, DEVICE_NODE)) 970c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed { 980c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__); 990c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return; 1000c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 1010c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // Event will be of the form: 1020c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // change@/devices/virtual/graphics/fb1 ACTION=change 1030c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // DEVPATH=/devices/virtual/graphics/fb1 1040c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // SUBSYSTEM=graphics HDCP_STATE=FAIL MAJOR=29 1050c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // for now just parse the online or offline are important for us. 1060c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if(!(strncmp(str,"online@",strlen("online@")))) { 1070c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: external disp online", __FUNCTION__); 1080c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed connected = 1; 1090c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed readResolution(); 1100c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed //Get the best mode and set 1110c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // TODO: DO NOT call this for WFD 1120c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed setResolution(getBestMode()); 1130c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } else if(!(strncmp(str,"offline@",strlen("offline@")))) { 1140c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: external disp online", __FUNCTION__); 1150c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed connected = 0; 1160c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed close(fd); 1170c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 1180c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed setExternalDisplayStatus(connected); 1190c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 1200c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1210c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedbool ExtDisplayObserver::threadLoop() 1220c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed{ 1230c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed static char uEventString[1024]; 1240c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed memset(uEventString, 0, sizeof(uEventString)); 1250c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int count = uevent_next_event(uEventString, sizeof(uEventString)); 1260c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if(count) { 1270c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: UeventString: %s len = %d", 1280c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed __FUNCTION__, uEventString, count); 1290c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed handleUEvent(uEventString); 1300c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 1310c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return true; 1320c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 1330c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1340c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedstruct disp_mode_timing_type { 1350c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int video_format; 1360c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1370c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int active_h; 1380c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int active_v; 1390c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1400c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int front_porch_h; 1410c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int pulse_width_h; 1420c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int back_porch_h; 1430c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1440c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int front_porch_v; 1450c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int pulse_width_v; 1460c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int back_porch_v; 1470c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1480c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int pixel_freq; 1490c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed bool interlaced; 1500c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1510c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed void set_info(struct fb_var_screeninfo &info) const; 1520c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed}; 1530c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1540c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedvoid disp_mode_timing_type::set_info(struct fb_var_screeninfo &info) const 1550c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed{ 1560c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.reserved[0] = 0; 1570c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.reserved[1] = 0; 1580c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.reserved[2] = 0; 1590c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.reserved[3] = video_format; 1600c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1610c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.xoffset = 0; 1620c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.yoffset = 0; 1630c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.xres = active_h; 1640c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.yres = active_v; 1650c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1660c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.pixclock = pixel_freq*1000; 1670c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.vmode = interlaced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED; 1680c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1690c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.right_margin = front_porch_h; 1700c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.hsync_len = pulse_width_h; 1710c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.left_margin = back_porch_h; 1720c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.lower_margin = front_porch_v; 1730c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.vsync_len = pulse_width_v; 1740c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.upper_margin = back_porch_v; 1750c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 1760c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1770c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed/* Video formates supported by the HDMI Standard */ 1780c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed/* Indicates the resolution, pix clock and the aspect ratio */ 1790c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m640x480p60_4_3 1 1800c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m720x480p60_4_3 2 1810c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m720x480p60_16_9 3 1820c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m1280x720p60_16_9 4 1830c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m1920x1080i60_16_9 5 1840c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m1440x480i60_4_3 6 1850c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m1440x480i60_16_9 7 1860c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m1920x1080p60_16_9 16 1870c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m720x576p50_4_3 17 1880c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m720x576p50_16_9 18 1890c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m1280x720p50_16_9 19 1900c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m1440x576i50_4_3 21 1910c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m1440x576i50_16_9 22 1920c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m1920x1080p50_16_9 31 1930c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m1920x1080p24_16_9 32 1940c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m1920x1080p25_16_9 33 1950c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed#define m1920x1080p30_16_9 34 1960c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 1970c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedstatic struct disp_mode_timing_type supported_video_mode_lut[] = { 1980c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m640x480p60_4_3, 640, 480, 16, 96, 48, 10, 2, 33, 25200, false}, 1990c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m720x480p60_4_3, 720, 480, 16, 62, 60, 9, 6, 30, 27030, false}, 2000c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m720x480p60_16_9, 720, 480, 16, 62, 60, 9, 6, 30, 27030, false}, 2010c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m1280x720p60_16_9, 1280, 720, 110, 40, 220, 5, 5, 20, 74250, false}, 2020c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m1920x1080i60_16_9, 1920, 540, 88, 44, 148, 2, 5, 5, 74250, false}, 2030c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m1440x480i60_4_3, 1440, 240, 38, 124, 114, 4, 3, 15, 27000, true}, 2040c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m1440x480i60_16_9, 1440, 240, 38, 124, 114, 4, 3, 15, 27000, true}, 2050c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m1920x1080p60_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 148500, false}, 2060c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m720x576p50_4_3, 720, 576, 12, 64, 68, 5, 5, 39, 27000, false}, 2070c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m720x576p50_16_9, 720, 576, 12, 64, 68, 5, 5, 39, 27000, false}, 2080c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m1280x720p50_16_9, 1280, 720, 440, 40, 220, 5, 5, 20, 74250, false}, 2090c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m1440x576i50_4_3, 1440, 288, 24, 126, 138, 2, 3, 19, 27000, true}, 2100c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m1440x576i50_16_9, 1440, 288, 24, 126, 138, 2, 3, 19, 27000, true}, 2110c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m1920x1080p50_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 148500, false}, 2120c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m1920x1080p24_16_9, 1920, 1080, 638, 44, 148, 4, 5, 36, 74250, false}, 2130c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m1920x1080p25_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 74250, false}, 2140c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed {m1920x1080p30_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 74250, false}, 2150c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed}; 2160c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedint ExtDisplayObserver::parseResolution(char* edidStr, int* edidModes, int len) 2170c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed{ 2180c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed char delim = ','; 2190c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int count = 0; 2200c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed char *start, *end; 2210c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // EDIDs are string delimited by ',' 2220c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // Ex: 16,4,5,3,32,34,1 2230c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // Parse this string to get mode(int) 2240c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed start = (char*) edidStr; 2250c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed for(int i=0; i<len; i++) { 2260c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed edidModes[i] = (int) strtol(start, &end, 10); 2270c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if(*end != delim) { 2280c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // return as we reached end of string 2290c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return count; 2300c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 2310c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed start = end+1; 2320c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed count++; 2330c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 2340c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return count; 2350c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 2360c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedbool ExtDisplayObserver::readResolution() 2370c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed{ 2380c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int hdmiEDIDFile = open(SYSFS_EDID_MODES, O_RDONLY, 0); 2390c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int len = -1; 2400c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 2410c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed memset(mEDIDs, 0, sizeof(mEDIDs)); 2420c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed memset(mEDIDModes, 0, sizeof(mEDIDModes)); 2430c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed mModeCount = 0; 2440c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if (hdmiEDIDFile < 0) { 2450c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: edid_modes file '%s' not found", 2460c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed __FUNCTION__, SYSFS_EDID_MODES); 2470c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return false; 2480c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } else { 2490c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed len = read(hdmiEDIDFile, mEDIDs, sizeof(mEDIDs)-1); 2500c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: EDID string: %s length = %d", 2510c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed __FUNCTION__, mEDIDs, len); 2520c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if ( len <= 0) { 2530c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: edid_modes file empty '%s'", 2540c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed __FUNCTION__, SYSFS_EDID_MODES); 2550c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 2560c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed else { 2570c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed while (len > 1 && isspace(mEDIDs[len-1])) 2580c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed --len; 2590c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed mEDIDs[len] = 0; 2600c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 2610c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 2620c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed close(hdmiEDIDFile); 2630c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if(len > 0) { 2640c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // GEt EDID modes from the EDID strings 2650c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed mModeCount = parseResolution(mEDIDs, mEDIDModes, len); 2660c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: mModeCount = %d", __FUNCTION__, 2670c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed mModeCount); 2680c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 2690c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 2700c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return (strlen(mEDIDs) > 0); 2710c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 2720c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 2730c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedbool ExtDisplayObserver::openFramebuffer() 2740c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed{ 2750c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if (fd == -1) { 2760c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed fd = open("/dev/graphics/fb1", O_RDWR); 2770c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if (fd < 0) 2780c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: /dev/graphics/fb1 not available" 2790c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed "\n", __FUNCTION__); 2800c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 2810c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return (fd > 0); 2820c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 2830c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 2840c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 2850c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedint ExtDisplayObserver::getModeOrder(int mode) 2860c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed{ 2870c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed switch (mode) { 2880c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed default: 2890c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m1440x480i60_4_3: 2900c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 1; // 480i 4:3 2910c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m1440x480i60_16_9: 2920c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 2; // 480i 16:9 2930c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m1440x576i50_4_3: 2940c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 3; // i576i 4:3 2950c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m1440x576i50_16_9: 2960c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 4; // 576i 16:9 2970c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m640x480p60_4_3: 2980c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 5; // 640x480 4:3 2990c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m720x480p60_4_3: 3000c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 6; // 480p 4:3 3010c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m720x480p60_16_9: 3020c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 7; // 480p 16:9 3030c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m720x576p50_4_3: 3040c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 8; // 576p 4:3 3050c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m720x576p50_16_9: 3060c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 9; // 576p 16:9 3070c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m1920x1080i60_16_9: 3080c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 10; // 1080i 16:9 3090c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m1280x720p50_16_9: 3100c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 11; // 720p@50Hz 3110c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m1280x720p60_16_9: 3120c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 12; // 720p@60Hz 3130c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m1920x1080p24_16_9: 3140c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 13; //1080p@24Hz 3150c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m1920x1080p25_16_9: 3160c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 14; //108-p@25Hz 3170c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m1920x1080p30_16_9: 3180c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 15; //1080p@30Hz 3190c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m1920x1080p50_16_9: 3200c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 16; //1080p@50Hz 3210c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed case m1920x1080p60_16_9: 3220c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return 17; //1080p@60Hz 3230c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 3240c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 3250c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 3260c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed// Get the best mode for the current HD TV 3270c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedint ExtDisplayObserver::getBestMode() { 3280c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int bestOrder = 0; 3290c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int bestMode = m640x480p60_4_3; 3300c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 3310c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // for all the edid read, get the best mode 3320c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed for(int i = 0; i < mModeCount; i++) { 3330c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int mode = mEDIDModes[i]; 3340c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int order = getModeOrder(mode); 3350c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if (order > bestOrder) { 3360c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed bestOrder = order; 3370c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed bestMode = mode; 3380c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 3390c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 3400c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return bestMode; 3410c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 3420c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 3430c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedinline bool ExtDisplayObserver::isValidMode(int ID) 3440c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed{ 3450c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return ((ID >= m640x480p60_4_3) && (ID <= m1920x1080p30_16_9)); 3460c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 3470c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 3480c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedvoid ExtDisplayObserver::setResolution(int ID) 3490c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed{ 3500c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed struct fb_var_screeninfo info; 3510c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if (!openFramebuffer()) 3520c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return; 3530c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed //If its a valid mode and its a new ID - update var_screeninfo 3540c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if ((isValidMode(ID)) && mCurrentID != ID) { 3550c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed const struct disp_mode_timing_type *mode = 3560c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed &supported_video_mode_lut[0]; 3570c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed unsigned count = sizeof(supported_video_mode_lut)/sizeof 3580c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed (*supported_video_mode_lut); 3590c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed for (unsigned int i = 0; i < count; ++i) { 3600c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed const struct disp_mode_timing_type *cur = 3610c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed &supported_video_mode_lut[i]; 3620c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if (cur->video_format == ID) 3630c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed mode = cur; 3640c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 3650c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ioctl(fd, FBIOGET_VSCREENINFO, &info); 3660c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: GET Info<ID=%d %dx%d (%d,%d,%d)," 3670c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed "(%d,%d,%d) %dMHz>", __FUNCTION__, 3680c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.reserved[3], info.xres, info.yres, 3690c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.right_margin, info.hsync_len, info.left_margin, 3700c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.lower_margin, info.vsync_len, info.upper_margin, 3710c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.pixclock/1000/1000); 3720c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed mode->set_info(info); 3730c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx%d" 3740c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed "(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, ID, 3750c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.reserved[3], info.xres, info.yres, 3760c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.right_margin, info.hsync_len, info.left_margin, 3770c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.lower_margin, info.vsync_len, info.upper_margin, 3780c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.pixclock/1000/1000); 3790c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed info.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE; 3800c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ioctl(fd, FBIOPUT_VSCREENINFO, &info); 3810c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed mCurrentID = ID; 3820c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 3830c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed //Powerup 3840c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ioctl(fd, FBIOBLANK, FB_BLANK_UNBLANK); 3850c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ioctl(fd, FBIOGET_VSCREENINFO, &info); 3860c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed //Pan_Display 3870c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ioctl(fd, FBIOPAN_DISPLAY, &info); 3880c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed property_set("hw.hdmiON", "1"); 3890c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 3900c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 3910c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 3920c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedint ExtDisplayObserver::getExternalDisplay() const 3930c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed{ 3940c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return mExternalDisplay; 3950c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 3960c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 3970c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedvoid ExtDisplayObserver::setExternalDisplayStatus(int connected) 3980c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed{ 3990c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 4000c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed hwc_context_t* ctx = mHwcContext; 4010c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if(ctx) { 4020c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: status = %d", __FUNCTION__, 4030c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed connected); 4040c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed // Store the external display 4050c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed mExternalDisplay = connected;//(external_display_type)value; 4060c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed //Invalidate 4070c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed hwc_procs* proc = (hwc_procs*)ctx->device.reserved_proc[0]; 4080c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if(!proc) { 4090c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: HWC proc not registered", 4100c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed __FUNCTION__); 4110c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } else { 4120c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed /* Trigger redraw */ 4130c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: Invalidate !!", __FUNCTION__); 4140c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed proc->invalidate(proc); 4150c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 4160c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 4170c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return; 4180c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 4190c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 4200c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmedbool ExtDisplayObserver::writeHPDOption(int userOption) const 4210c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed{ 4220c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed bool ret = true; 4230c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int hdmiHPDFile = open(SYSFS_HPD,O_RDWR, 0); 4240c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if (hdmiHPDFile < 0) { 4250c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: state file '%s' not found : ret%d" 4260c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed "err str: %s", __FUNCTION__, SYSFS_HPD, hdmiHPDFile, strerror(errno)); 4270c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ret = false; 4280c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } else { 4290c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed int err = -1; 4300c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: option = %d", __FUNCTION__, 4310c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed userOption); 4320c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if(userOption) 4330c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed err = write(hdmiHPDFile, "1", 2); 4340c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed else 4350c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed err = write(hdmiHPDFile, "0" , 2); 4360c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed if (err <= 0) { 4370c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ALOGD_IF(EXT_OBSERVER_DEBUG, "%s: file write failed '%s'", 4380c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed __FUNCTION__, SYSFS_HPD); 4390c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed ret = false; 4400c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 4410c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed close(hdmiHPDFile); 4420c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed } 4430c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed return ret; 4440c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed} 4450c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed}; 4460c8b7b5c841a7fad5df11b7e02d7cd792cfcc734Naseer Ahmed 447