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