external.cpp revision 97133affcb6618a547b5650771a97cd104b06405
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;
88620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    readResolution();
89620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    // TODO: Move this to activate
90c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    /* Used for changing the resolution
91c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R     * getUserMode will get the preferred
92c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R     * mode set thru adb shell */
93c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    int mode = getUserMode();
94c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    if (mode == -1) {
95c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R        //Get the best mode and set
96c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R        mode = getBestMode();
97c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    }
98c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    setResolution(mode);
99620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    setDpyHdmiAttr();
100620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    setExternalDisplay(true, mHdmiFbNum);
101620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    return 0;
102620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar}
103620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar
104620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarint ExternalDisplay::configureWFDDisplay() {
105620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    int ret = 0;
106620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    if(mConnectedFbNum == mHdmiFbNum) {
107620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        ALOGE("%s: Cannot process WFD connection while HDMI is active",
108620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar                     __FUNCTION__);
109620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        return -1;
110620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    }
111620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    openFrameBuffer(mWfdFbNum);
112620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    if(mFd == -1)
113620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        return -1;
114620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
115620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    if(ret < 0) {
116620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
117620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar                strerror(errno));
118620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    }
119620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    setDpyWfdAttr();
120620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    setExternalDisplay(true, mWfdFbNum);
121620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    return 0;
122620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar}
123620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar
124620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarint ExternalDisplay::teardownHDMIDisplay() {
125620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    if(mConnectedFbNum == mHdmiFbNum) {
126620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        // hdmi offline event..!
127620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        closeFrameBuffer();
128620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        resetInfo();
129620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        setExternalDisplay(false);
130620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    }
131620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    return 0;
132620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar}
133ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
134620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarint ExternalDisplay::teardownWFDDisplay() {
135620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    if(mConnectedFbNum == mWfdFbNum) {
136620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        // wfd offline event..!
137620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        closeFrameBuffer();
138620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        memset(&mVInfo, 0, sizeof(mVInfo));
139620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        setExternalDisplay(false);
140620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    }
141620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    return 0;
142620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar}
143ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
144620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::processUEventOnline(const char *str) {
145620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    const char *s1 = str + strlen("change@/devices/virtual/switch/");
146620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    if(!strncmp(s1,"hdmi",strlen(s1))) {
147620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        // hdmi online event..!
148620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        configureHDMIDisplay();
149df631660b7ecbcbb2c8a70753d2de26ea81a4afaArun Kumar K.R        // set system property
150df631660b7ecbcbb2c8a70753d2de26ea81a4afaArun Kumar K.R        property_set("hw.hdmiON", "1");
151620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    }else if(!strncmp(s1,"wfd",strlen(s1))) {
152620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        // wfd online event..!
153620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        configureWFDDisplay();
154620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    }
155620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar}
156ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
157620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::processUEventOffline(const char *str) {
158620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    const char *s1 = str + strlen("change@/devices/virtual/switch/");
159620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    if(!strncmp(s1,"hdmi",strlen(s1))) {
160620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        teardownHDMIDisplay();
161df631660b7ecbcbb2c8a70753d2de26ea81a4afaArun Kumar K.R        // unset system property
162df631660b7ecbcbb2c8a70753d2de26ea81a4afaArun Kumar K.R        property_set("hw.hdmiON", "0");
163620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    }else if(!strncmp(s1,"wfd",strlen(s1))) {
164620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        teardownWFDDisplay();
165620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    }
166620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar}
167ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
168080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer AhmedExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
169620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0),
170620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    mHwcContext(ctx), mHdmiFbNum(-1), mWfdFbNum(-1)
171ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{
172080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    memset(&mVInfo, 0, sizeof(mVInfo));
173620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    //Determine the fb index for external display devices.
174620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    updateExtDispDevFbIndex();
175ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}
176ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
177bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shahvoid ExternalDisplay::setEDIDMode(int resMode) {
178bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    ALOGD_IF(DEBUG,"resMode=%d ", resMode);
179bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    {
180bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah        Mutex::Autolock lock(mExtDispLock);
181620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        setExternalDisplay(false);
182620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        openFrameBuffer(mHdmiFbNum);
183bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah        setResolution(resMode);
184bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    }
185620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    setExternalDisplay(true, mHdmiFbNum);
186bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah}
187bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah
188bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shahvoid ExternalDisplay::setHPD(uint32_t startEnd) {
189bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    ALOGD_IF(DEBUG,"HPD enabled=%d", startEnd);
190bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    writeHPDOption(startEnd);
191bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah}
192bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah
193bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shahvoid ExternalDisplay::setActionSafeDimension(int w, int h) {
194bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h);
195bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    Mutex::Autolock lock(mExtDispLock);
196bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    overlay::utils::ActionSafe::getInstance()->setDimension(w, h);
197620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    setExternalDisplay(true, mHdmiFbNum);
198bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah}
199bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah
200bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shahint ExternalDisplay::getModeCount() const {
201bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    ALOGD_IF(DEBUG,"HPD mModeCount=%d", mModeCount);
202bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    Mutex::Autolock lock(mExtDispLock);
203bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    return mModeCount;
204bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah}
205bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah
206bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shahvoid ExternalDisplay::getEDIDModes(int *out) const {
207bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    Mutex::Autolock lock(mExtDispLock);
208bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    for(int i = 0;i < mModeCount;i++) {
209bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah        out[i] = mEDIDModes[i];
210bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    }
211bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah}
212bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah
2131589dee5c27293d278d3e549af8a4bda27e080f8Naseer AhmedExternalDisplay::~ExternalDisplay()
2141589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed{
215080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    closeFrameBuffer();
216ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}
217ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
218ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmedstruct disp_mode_timing_type {
219ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int  video_format;
220ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
221ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int  active_h;
222ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int  active_v;
223ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
224ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int  front_porch_h;
225ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int  pulse_width_h;
226ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int  back_porch_h;
227ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
228ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int  front_porch_v;
229ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int  pulse_width_v;
230ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int  back_porch_v;
231ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
232ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int  pixel_freq;
233ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    bool interlaced;
234ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
235ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    void set_info(struct fb_var_screeninfo &info) const;
236ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed};
237ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
238ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmedvoid disp_mode_timing_type::set_info(struct fb_var_screeninfo &info) const
239ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{
240ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.reserved[0] = 0;
241ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.reserved[1] = 0;
242ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.reserved[2] = 0;
243e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang#ifndef FB_METADATA_VIDEO_INFO_CODE_SUPPORT
244bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    info.reserved[3] = (info.reserved[3] & 0xFFFF) | (video_format << 16);
245e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang#endif
246ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.xoffset = 0;
247ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.yoffset = 0;
248ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.xres = active_h;
249ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.yres = active_v;
250ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
251ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.pixclock = pixel_freq*1000;
252ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.vmode = interlaced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
253ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
254ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.right_margin = front_porch_h;
255ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.hsync_len = pulse_width_h;
256ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.left_margin = back_porch_h;
257ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.lower_margin = front_porch_v;
258ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.vsync_len = pulse_width_v;
259ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    info.upper_margin = back_porch_v;
260ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}
261ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
262ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed/* Video formates supported by the HDMI Standard */
263ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed/* Indicates the resolution, pix clock and the aspect ratio */
264ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m640x480p60_4_3         1
265ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m720x480p60_4_3         2
266ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m720x480p60_16_9        3
267ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1280x720p60_16_9       4
268ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1920x1080i60_16_9      5
269ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1440x480i60_4_3        6
270ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1440x480i60_16_9       7
271ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1920x1080p60_16_9      16
272ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m720x576p50_4_3         17
273ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m720x576p50_16_9        18
274ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1280x720p50_16_9       19
275ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1440x576i50_4_3        21
276ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1440x576i50_16_9       22
277ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1920x1080p50_16_9      31
278ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1920x1080p24_16_9      32
279ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1920x1080p25_16_9      33
280ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#define m1920x1080p30_16_9      34
281ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
282ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmedstatic struct disp_mode_timing_type supported_video_mode_lut[] = {
283ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m640x480p60_4_3,     640,  480,  16,  96,  48, 10, 2, 33,  25200, false},
284ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m720x480p60_4_3,     720,  480,  16,  62,  60,  9, 6, 30,  27030, false},
285ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m720x480p60_16_9,    720,  480,  16,  62,  60,  9, 6, 30,  27030, false},
286ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m1280x720p60_16_9,  1280,  720, 110,  40, 220,  5, 5, 20,  74250, false},
287ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m1920x1080i60_16_9, 1920,  540,  88,  44, 148,  2, 5,  5,  74250, false},
288ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m1440x480i60_4_3,   1440,  240,  38, 124, 114,  4, 3, 15,  27000, true},
289ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m1440x480i60_16_9,  1440,  240,  38, 124, 114,  4, 3, 15,  27000, true},
290ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m1920x1080p60_16_9, 1920, 1080,  88,  44, 148,  4, 5, 36, 148500, false},
291ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m720x576p50_4_3,     720,  576,  12,  64,  68,  5, 5, 39,  27000, false},
292ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m720x576p50_16_9,    720,  576,  12,  64,  68,  5, 5, 39,  27000, false},
293ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m1280x720p50_16_9,  1280,  720, 440,  40, 220,  5, 5, 20,  74250, false},
294ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m1440x576i50_4_3,   1440,  288,  24, 126, 138,  2, 3, 19,  27000, true},
295ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m1440x576i50_16_9,  1440,  288,  24, 126, 138,  2, 3, 19,  27000, true},
296ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m1920x1080p50_16_9, 1920, 1080, 528,  44, 148,  4, 5, 36, 148500, false},
297ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m1920x1080p24_16_9, 1920, 1080, 638,  44, 148,  4, 5, 36,  74250, false},
298ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m1920x1080p25_16_9, 1920, 1080, 528,  44, 148,  4, 5, 36,  74250, false},
299ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    {m1920x1080p30_16_9, 1920, 1080,  88,  44, 148,  4, 5, 36,  74250, false},
300ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed};
3011589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
302080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmedint ExternalDisplay::parseResolution(char* edidStr, int* edidModes)
303ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{
304ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    char delim = ',';
305ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int count = 0;
306ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    char *start, *end;
307ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    // EDIDs are string delimited by ','
308ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    // Ex: 16,4,5,3,32,34,1
309ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    // Parse this string to get mode(int)
310ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    start = (char*) edidStr;
311080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    end = &delim;
312080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    while(*end == delim) {
313080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed        edidModes[count] = (int) strtol(start, &end, 10);
314ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        start = end+1;
315ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        count++;
316ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    }
317080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    ALOGD_IF(DEBUG, "In %s: count = %d", __FUNCTION__, count);
318080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    for (int i = 0; i < count; i++)
319080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed        ALOGD_IF(DEBUG, "Mode[%d] = %d", i, edidModes[i]);
320ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    return count;
321ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}
322080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed
3231589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmedbool ExternalDisplay::readResolution()
324ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{
325620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    char sysFsEDIDFilePath[255];
326620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    sprintf(sysFsEDIDFilePath , "/sys/devices/virtual/graphics/fb%d/edid_modes",
327620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar            mHdmiFbNum);
328620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar
329620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    int hdmiEDIDFile = open(sysFsEDIDFilePath, O_RDONLY, 0);
330ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int len = -1;
331ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
332ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    if (hdmiEDIDFile < 0) {
333080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed        ALOGE("%s: edid_modes file '%s' not found",
334620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar                 __FUNCTION__, sysFsEDIDFilePath);
335ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        return false;
336ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    } else {
337ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        len = read(hdmiEDIDFile, mEDIDs, sizeof(mEDIDs)-1);
3381589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ALOGD_IF(DEBUG, "%s: EDID string: %s length = %d",
3391589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                 __FUNCTION__, mEDIDs, len);
340ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        if ( len <= 0) {
341080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed            ALOGE("%s: edid_modes file empty '%s'",
342620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar                     __FUNCTION__, sysFsEDIDFilePath);
343ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        }
344ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        else {
345ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            while (len > 1 && isspace(mEDIDs[len-1]))
346ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed                --len;
347ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            mEDIDs[len] = 0;
348ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        }
349ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    }
350ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    close(hdmiEDIDFile);
351ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    if(len > 0) {
352620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        // Get EDID modes from the EDID strings
353080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed        mModeCount = parseResolution(mEDIDs, mEDIDModes);
3541589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ALOGD_IF(DEBUG, "%s: mModeCount = %d", __FUNCTION__,
3551589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                 mModeCount);
356ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    }
357ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
358ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    return (strlen(mEDIDs) > 0);
359ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}
360ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
361620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarbool ExternalDisplay::openFrameBuffer(int fbNum)
362ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{
363080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    if (mFd == -1) {
364620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        mFd = open(msmFbDevicePath[fbNum-1], O_RDWR);
365080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed        if (mFd < 0)
366620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar            ALOGE("%s: %s is not available", __FUNCTION__,
367620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar                                            msmFbDevicePath[fbNum-1]);
368620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        if(mHwcContext) {
369620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar            mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd;
370620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        }
3712e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
372080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    return (mFd > 0);
373080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed}
374080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed
375080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmedbool ExternalDisplay::closeFrameBuffer()
376080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed{
377080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    int ret = 0;
378080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    if(mFd > 0) {
379080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed        ret = close(mFd);
380080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed        mFd = -1;
381ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    }
3822e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    if(mHwcContext) {
3832e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd;
3842e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
385080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    return (ret == 0);
386ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}
387ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
388080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed// clears the vinfo, edid, best modes
389080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmedvoid ExternalDisplay::resetInfo()
390080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed{
391080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    memset(&mVInfo, 0, sizeof(mVInfo));
392080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    memset(mEDIDs, 0, sizeof(mEDIDs));
393080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    memset(mEDIDModes, 0, sizeof(mEDIDModes));
394080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    mModeCount = 0;
395080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    mCurrentMode = -1;
396080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed}
397ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
3981589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmedint ExternalDisplay::getModeOrder(int mode)
399ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{
400c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    // XXX: We dont support interlaced modes but having
401c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    // it here for for future
402ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    switch (mode) {
403ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        default:
404ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m1440x480i60_4_3:
405ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 1; // 480i 4:3
406ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m1440x480i60_16_9:
407ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 2; // 480i 16:9
408ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m1440x576i50_4_3:
409ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 3; // i576i 4:3
410ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m1440x576i50_16_9:
411ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 4; // 576i 16:9
412ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m640x480p60_4_3:
413ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 5; // 640x480 4:3
414ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m720x480p60_4_3:
415ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 6; // 480p 4:3
416ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m720x480p60_16_9:
417ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 7; // 480p 16:9
418ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m720x576p50_4_3:
419ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 8; // 576p 4:3
420ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m720x576p50_16_9:
421ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 9; // 576p 16:9
422ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m1920x1080i60_16_9:
423ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 10; // 1080i 16:9
424ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m1280x720p50_16_9:
425ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 11; // 720p@50Hz
426ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m1280x720p60_16_9:
427ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 12; // 720p@60Hz
428ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m1920x1080p24_16_9:
429ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 13; //1080p@24Hz
430ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m1920x1080p25_16_9:
431ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 14; //108-p@25Hz
432ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m1920x1080p30_16_9:
433ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 15; //1080p@30Hz
434ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m1920x1080p50_16_9:
435ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 16; //1080p@50Hz
436ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        case m1920x1080p60_16_9:
437ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            return 17; //1080p@60Hz
4381589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    }
439ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}
440ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
441c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R/// Returns the user mode set(if any) using adb shell
442c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.Rint ExternalDisplay::getUserMode() {
443c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    /* Based on the property set the resolution */
444c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    char property_value[PROPERTY_VALUE_MAX];
445c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    property_get("hdmi.resolution", property_value, "-1");
446c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    int mode = atoi(property_value);
447c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    // We dont support interlaced modes
448c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    if(isValidMode(mode) && !isInterlacedMode(mode)) {
449c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R        ALOGD_IF("%s: setting the HDMI mode = %d", __FUNCTION__, mode);
450c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R        return mode;
451c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    }
452c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    return -1;
453c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R}
454c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R
455ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed// Get the best mode for the current HD TV
4561589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmedint ExternalDisplay::getBestMode() {
457ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int bestOrder = 0;
458ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    int bestMode = m640x480p60_4_3;
459bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah    Mutex::Autolock lock(mExtDispLock);
460ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    // for all the edid read, get the best mode
461ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    for(int i = 0; i < mModeCount; i++) {
462ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        int mode = mEDIDModes[i];
463ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        int order = getModeOrder(mode);
464ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        if (order > bestOrder) {
465ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            bestOrder = order;
466ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            bestMode = mode;
467ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        }
468ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    }
469ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    return bestMode;
4701589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed}
471ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
4721589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmedinline bool ExternalDisplay::isValidMode(int ID)
473ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{
474c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    bool valid = false;
475c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    for (int i = 0; i < mModeCount; i++) {
476c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R        if(ID == mEDIDModes[i]) {
477c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R            valid = true;
478c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R            break;
479c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R        }
480c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    }
481c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    return valid;
482c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R}
483c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R
484c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R// returns true if the mode(ID) is interlaced mode format
485c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.Rbool ExternalDisplay::isInterlacedMode(int ID) {
486c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    bool interlaced = false;
487c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    switch(ID) {
488c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R        case m1440x480i60_4_3:
489c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R        case m1440x480i60_16_9:
490c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R        case m1440x576i50_4_3:
491c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R        case m1440x576i50_16_9:
492c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R        case m1920x1080i60_16_9:
493c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R            interlaced = true;
494c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R        default:
495c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R            interlaced = false;
496c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    }
497c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    return interlaced;
498ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}
499ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
5001589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmedvoid ExternalDisplay::setResolution(int ID)
501ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{
502ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    struct fb_var_screeninfo info;
503080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    int ret = 0;
504080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
505080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    if(ret < 0) {
506080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed        ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
507080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed                                                            strerror(errno));
508080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    }
509080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed
510080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    ALOGD_IF(DEBUG, "%s: GET Info<ID=%d %dx%d (%d,%d,%d),"
511080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed            "(%d,%d,%d) %dMHz>", __FUNCTION__,
512080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed            mVInfo.reserved[3], mVInfo.xres, mVInfo.yres,
513080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed            mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin,
514080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed            mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin,
515080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed            mVInfo.pixclock/1000/1000);
516c5bb51f047f080f2920994cfbd788d27800a8e89Arun Kumar K.R    //If its a new ID - update var_screeninfo
517080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    if ((isValidMode(ID)) && mCurrentMode != ID) {
518ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        const struct disp_mode_timing_type *mode =
5191589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed            &supported_video_mode_lut[0];
520ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        unsigned count =  sizeof(supported_video_mode_lut)/sizeof
5211589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed            (*supported_video_mode_lut);
522ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        for (unsigned int i = 0; i < count; ++i) {
523ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            const struct disp_mode_timing_type *cur =
5241589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                &supported_video_mode_lut[i];
525ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            if (cur->video_format == ID)
526ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed                mode = cur;
527ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        }
528080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed        mode->set_info(mVInfo);
529080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed        ALOGD_IF(DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx %d"
5301589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                 "(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, ID,
53197133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R                 mode->video_format, mVInfo.xres, mVInfo.yres,
532080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed                 mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin,
533080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed                 mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin,
534080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed                 mVInfo.pixclock/1000/1000);
535e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang#ifdef FB_METADATA_VIDEO_INFO_CODE_SUPPORT
536e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang        struct msmfb_metadata metadata;
537e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang        memset(&metadata, 0 , sizeof(metadata));
538e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang        metadata.op = metadata_op_vic;
539e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang        metadata.data.video_info_code = mode->video_format;
540e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang        if (ioctl(mFd, MSMFB_METADATA_SET, &metadata) == -1) {
541e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang            ALOGD("In %s: MSMFB_METADATA_SET failed Err Str = %s",
542e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang                                                 __FUNCTION__, strerror(errno));
543e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang        }
544e31290730a9c47d2d02b0ef1d7d766280fea17bcKen Zhang#endif
54597133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R        mVInfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE;
54697133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R        ret = ioctl(mFd, FBIOPUT_VSCREENINFO, &mVInfo);
54797133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R        if(ret < 0) {
54897133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R            ALOGD("In %s: FBIOPUT_VSCREENINFO failed Err Str = %s",
54997133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R                                                 __FUNCTION__, strerror(errno));
55097133affcb6618a547b5650771a97cd104b06405Arun Kumar K.R        }
551080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed        mCurrentMode = ID;
552ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    }
553ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}
554ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
555620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::setExternalDisplay(bool connected, int extFbNum)
556ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{
557ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    hwc_context_t* ctx = mHwcContext;
558ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    if(ctx) {
559620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        ALOGD_IF(DEBUG, "%s: connected = %d", __FUNCTION__, connected);
560ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        // Store the external display
561620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        mConnected = connected;
562620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        mConnectedFbNum = extFbNum;
563620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
564620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        // Update external fb number in Overlay context
565620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        overlay::Overlay::getInstance()->setExtFbNum(extFbNum);
566ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    }
567620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar}
568620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar
569620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarint ExternalDisplay::getExtFbNum(int &fbNum) {
570620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    int ret = -1;
571620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    if(mConnected) {
572620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        fbNum = mConnectedFbNum;
573620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        ret = 0;
574620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    }
575620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    return ret;
576ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}
577ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
5781589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmedbool ExternalDisplay::writeHPDOption(int userOption) const
579ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed{
580ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    bool ret = true;
581620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    char sysFsHPDFilePath[255];
582620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    sprintf(sysFsHPDFilePath ,"/sys/devices/virtual/graphics/fb%d/hpd",
583620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar                                mHdmiFbNum);
584620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    int hdmiHPDFile = open(sysFsHPDFilePath,O_RDWR, 0);
585ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    if (hdmiHPDFile < 0) {
586620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        ALOGE("%s: state file '%s' not found : ret%d err str: %s", __FUNCTION__,
587620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar                                sysFsHPDFilePath, hdmiHPDFile, strerror(errno));
588ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        ret = false;
589ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    } else {
590ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        int err = -1;
591620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        ALOGD_IF(DEBUG, "%s: option = %d", __FUNCTION__, userOption);
592ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        if(userOption)
593ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            err = write(hdmiHPDFile, "1", 2);
594ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        else
595ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            err = write(hdmiHPDFile, "0" , 2);
596ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        if (err <= 0) {
597620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar            ALOGE("%s: file write failed '%s'", __FUNCTION__, sysFsHPDFilePath);
598ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed            ret = false;
599ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        }
600ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed        close(hdmiHPDFile);
601ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    }
602ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed    return ret;
603ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed}
604080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed
605b4e7df4fbb0a21bb4cd0e7b7506380cbfceae729Saurabh Shah/*
606b4e7df4fbb0a21bb4cd0e7b7506380cbfceae729Saurabh Shah * commits the changes to the external display
607b4e7df4fbb0a21bb4cd0e7b7506380cbfceae729Saurabh Shah */
6082e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahbool ExternalDisplay::post()
609080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed{
61016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    if(mFd == -1)
611080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed        return false;
61216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    struct mdp_display_commit ext_commit;
613eeb2868ac7dc7f962ccaa920e73767b0c2e3585fNaseer Ahmed    memset(&ext_commit, 0, sizeof(struct mdp_display_commit));
614eeb2868ac7dc7f962ccaa920e73767b0c2e3585fNaseer Ahmed    ext_commit.flags = MDP_DISPLAY_COMMIT_OVERLAY;
61516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    if (ioctl(mFd, MSMFB_DISPLAY_COMMIT, &ext_commit) == -1) {
616620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        ALOGE("%s: MSMFB_DISPLAY_COMMIT for external failed, str: %s",
617620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar                __FUNCTION__, strerror(errno));
618620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        return false;
619080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    }
620080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    return true;
621080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed}
622080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed
623620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::setDpyWfdAttr() {
624620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    if(mHwcContext) {
625620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = mVInfo.xres;
626620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = mVInfo.yres;
627620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period =
628620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar                1000000000l /60;
629620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar        ALOGD_IF(DEBUG,"%s: wfd...connected..!",__FUNCTION__);
630620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar    }
631620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar}
632620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumar
633620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::setDpyHdmiAttr() {
6342e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    int width = 0, height = 0, fps = 0;
6352e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    getAttrForMode(width, height, fps);
6362e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    if(mHwcContext) {
63776443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        ALOGD("ExtDisplay setting xres = %d, yres = %d", width, height);
6382e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = width;
6392e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = height;
64076443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period =
64176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            1000000000l / fps;
6422e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
6432e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
6442e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
645620fc1f5f84e968c2e9b803e8580ee718c3c3f65Amara Venkata Mastan Manoj Kumarvoid ExternalDisplay::getAttrForMode(int& width, int& height, int& fps) {
6462e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    switch (mCurrentMode) {
6472e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case m640x480p60_4_3:
6482e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            width = 640;
6492e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            height = 480;
6502e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            fps = 60;
6512e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
6522e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case m720x480p60_4_3:
6532e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case m720x480p60_16_9:
6542e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            width = 720;
6552e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            height = 480;
6562e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            fps = 60;
6572e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
6582e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case m720x576p50_4_3:
6592e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case m720x576p50_16_9:
6602e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            width = 720;
6612e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            height = 576;
6622e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            fps = 50;
6632e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
6642e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case m1280x720p50_16_9:
6652e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            width = 1280;
6662e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            height = 720;
6672e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            fps = 50;
6682e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
6692e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case m1280x720p60_16_9:
6702e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            width = 1280;
6712e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            height = 720;
6722e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            fps = 60;
6732e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
6742e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case m1920x1080p24_16_9:
6752e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            width = 1920;
6762e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            height = 1080;
6772e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            fps = 24;
6782e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
6792e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case m1920x1080p25_16_9:
6802e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            width = 1920;
6812e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            height = 1080;
6822e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            fps = 25;
6832e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
6842e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case m1920x1080p30_16_9:
6852e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            width = 1920;
6862e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            height = 1080;
6872e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            fps = 30;
6882e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
6892e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case m1920x1080p50_16_9:
6902e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            width = 1920;
6912e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            height = 1080;
6922e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            fps = 50;
6932e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
6942e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case m1920x1080p60_16_9:
6952e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            width = 1920;
6962e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            height = 1080;
6972e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            fps = 60;
6982e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
699080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed    }
700080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed}
701080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed
702ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed};
703