blob: c4a6a6a369249d31c66647f8f47262d8a351d31c [file] [log] [blame]
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
4 *
5 * Not a Contribution, Apache license notifications and license are
6 * retained for attribution purposes only.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
Naseer Ahmed72cf9762012-07-21 12:17:13 -070021#define DEBUG 0
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070022#include <ctype.h>
Naseer Ahmed72cf9762012-07-21 12:17:13 -070023#include <fcntl.h>
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070024#include <media/IAudioPolicyService.h>
25#include <media/AudioSystem.h>
26#include <utils/threads.h>
27#include <utils/Errors.h>
28#include <utils/Log.h>
29
30#include <linux/msm_mdp.h>
31#include <linux/fb.h>
32#include <sys/ioctl.h>
33#include <sys/poll.h>
Naseer Ahmed72cf9762012-07-21 12:17:13 -070034#include <sys/resource.h>
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070035#include <cutils/properties.h>
36#include "hwc_utils.h"
Naseer Ahmed72cf9762012-07-21 12:17:13 -070037#include "hwc_external.h"
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070038
39namespace qhwc {
40
41
42#define DEVICE_ROOT "/sys/devices/virtual/graphics"
43#define DEVICE_NODE "fb1"
44
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070045#define SYSFS_EDID_MODES DEVICE_ROOT "/" DEVICE_NODE "/edid_modes"
46#define SYSFS_HPD DEVICE_ROOT "/" DEVICE_NODE "/hpd"
47
48
Naseer Ahmedf8ec1622012-07-31 18:56:23 -070049ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
50 mCurrentMode(-1), mHwcContext(ctx)
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070051{
Naseer Ahmedf8ec1622012-07-31 18:56:23 -070052 memset(&mVInfo, 0, sizeof(mVInfo));
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070053 //Enable HPD for HDMI
54 writeHPDOption(1);
55}
56
Naseer Ahmed72cf9762012-07-21 12:17:13 -070057ExternalDisplay::~ExternalDisplay()
58{
Naseer Ahmedf8ec1622012-07-31 18:56:23 -070059 closeFrameBuffer();
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070060}
61
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070062struct disp_mode_timing_type {
63 int video_format;
64
65 int active_h;
66 int active_v;
67
68 int front_porch_h;
69 int pulse_width_h;
70 int back_porch_h;
71
72 int front_porch_v;
73 int pulse_width_v;
74 int back_porch_v;
75
76 int pixel_freq;
77 bool interlaced;
78
79 void set_info(struct fb_var_screeninfo &info) const;
80};
81
82void disp_mode_timing_type::set_info(struct fb_var_screeninfo &info) const
83{
84 info.reserved[0] = 0;
85 info.reserved[1] = 0;
86 info.reserved[2] = 0;
Naseer Ahmed9edd17c2012-08-15 18:16:50 -070087 info.reserved[3] = info.reserved[3] | (video_format << 16);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070088
89 info.xoffset = 0;
90 info.yoffset = 0;
91 info.xres = active_h;
92 info.yres = active_v;
93
94 info.pixclock = pixel_freq*1000;
95 info.vmode = interlaced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
96
97 info.right_margin = front_porch_h;
98 info.hsync_len = pulse_width_h;
99 info.left_margin = back_porch_h;
100 info.lower_margin = front_porch_v;
101 info.vsync_len = pulse_width_v;
102 info.upper_margin = back_porch_v;
103}
104
105/* Video formates supported by the HDMI Standard */
106/* Indicates the resolution, pix clock and the aspect ratio */
107#define m640x480p60_4_3 1
108#define m720x480p60_4_3 2
109#define m720x480p60_16_9 3
110#define m1280x720p60_16_9 4
111#define m1920x1080i60_16_9 5
112#define m1440x480i60_4_3 6
113#define m1440x480i60_16_9 7
114#define m1920x1080p60_16_9 16
115#define m720x576p50_4_3 17
116#define m720x576p50_16_9 18
117#define m1280x720p50_16_9 19
118#define m1440x576i50_4_3 21
119#define m1440x576i50_16_9 22
120#define m1920x1080p50_16_9 31
121#define m1920x1080p24_16_9 32
122#define m1920x1080p25_16_9 33
123#define m1920x1080p30_16_9 34
124
125static struct disp_mode_timing_type supported_video_mode_lut[] = {
126 {m640x480p60_4_3, 640, 480, 16, 96, 48, 10, 2, 33, 25200, false},
127 {m720x480p60_4_3, 720, 480, 16, 62, 60, 9, 6, 30, 27030, false},
128 {m720x480p60_16_9, 720, 480, 16, 62, 60, 9, 6, 30, 27030, false},
129 {m1280x720p60_16_9, 1280, 720, 110, 40, 220, 5, 5, 20, 74250, false},
130 {m1920x1080i60_16_9, 1920, 540, 88, 44, 148, 2, 5, 5, 74250, false},
131 {m1440x480i60_4_3, 1440, 240, 38, 124, 114, 4, 3, 15, 27000, true},
132 {m1440x480i60_16_9, 1440, 240, 38, 124, 114, 4, 3, 15, 27000, true},
133 {m1920x1080p60_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 148500, false},
134 {m720x576p50_4_3, 720, 576, 12, 64, 68, 5, 5, 39, 27000, false},
135 {m720x576p50_16_9, 720, 576, 12, 64, 68, 5, 5, 39, 27000, false},
136 {m1280x720p50_16_9, 1280, 720, 440, 40, 220, 5, 5, 20, 74250, false},
137 {m1440x576i50_4_3, 1440, 288, 24, 126, 138, 2, 3, 19, 27000, true},
138 {m1440x576i50_16_9, 1440, 288, 24, 126, 138, 2, 3, 19, 27000, true},
139 {m1920x1080p50_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 148500, false},
140 {m1920x1080p24_16_9, 1920, 1080, 638, 44, 148, 4, 5, 36, 74250, false},
141 {m1920x1080p25_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 74250, false},
142 {m1920x1080p30_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 74250, false},
143};
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700144
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700145int ExternalDisplay::parseResolution(char* edidStr, int* edidModes)
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700146{
147 char delim = ',';
148 int count = 0;
149 char *start, *end;
150 // EDIDs are string delimited by ','
151 // Ex: 16,4,5,3,32,34,1
152 // Parse this string to get mode(int)
153 start = (char*) edidStr;
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700154 end = &delim;
155 while(*end == delim) {
156 edidModes[count] = (int) strtol(start, &end, 10);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700157 start = end+1;
158 count++;
159 }
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700160 ALOGD_IF(DEBUG, "In %s: count = %d", __FUNCTION__, count);
161 for (int i = 0; i < count; i++)
162 ALOGD_IF(DEBUG, "Mode[%d] = %d", i, edidModes[i]);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700163 return count;
164}
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700165
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700166bool ExternalDisplay::readResolution()
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700167{
168 int hdmiEDIDFile = open(SYSFS_EDID_MODES, O_RDONLY, 0);
169 int len = -1;
170
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700171 if (hdmiEDIDFile < 0) {
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700172 ALOGE("%s: edid_modes file '%s' not found",
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700173 __FUNCTION__, SYSFS_EDID_MODES);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700174 return false;
175 } else {
176 len = read(hdmiEDIDFile, mEDIDs, sizeof(mEDIDs)-1);
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700177 ALOGD_IF(DEBUG, "%s: EDID string: %s length = %d",
178 __FUNCTION__, mEDIDs, len);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700179 if ( len <= 0) {
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700180 ALOGE("%s: edid_modes file empty '%s'",
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700181 __FUNCTION__, SYSFS_EDID_MODES);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700182 }
183 else {
184 while (len > 1 && isspace(mEDIDs[len-1]))
185 --len;
186 mEDIDs[len] = 0;
187 }
188 }
189 close(hdmiEDIDFile);
190 if(len > 0) {
191 // GEt EDID modes from the EDID strings
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700192 mModeCount = parseResolution(mEDIDs, mEDIDModes);
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700193 ALOGD_IF(DEBUG, "%s: mModeCount = %d", __FUNCTION__,
194 mModeCount);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700195 }
196
197 return (strlen(mEDIDs) > 0);
198}
199
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700200bool ExternalDisplay::openFramebuffer()
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700201{
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700202 if (mFd == -1) {
203 mFd = open("/dev/graphics/fb1", O_RDWR);
204 if (mFd < 0)
205 ALOGE("%s: /dev/graphics/fb1 not available", __FUNCTION__);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700206 }
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700207 return (mFd > 0);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700208}
209
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700210bool ExternalDisplay::closeFrameBuffer()
211{
212 int ret = 0;
213 if(mFd > 0) {
214 ret = close(mFd);
215 mFd = -1;
216 }
217 return (ret == 0);
218}
219
220// clears the vinfo, edid, best modes
221void ExternalDisplay::resetInfo()
222{
223 memset(&mVInfo, 0, sizeof(mVInfo));
224 memset(mEDIDs, 0, sizeof(mEDIDs));
225 memset(mEDIDModes, 0, sizeof(mEDIDModes));
226 mModeCount = 0;
227 mCurrentMode = -1;
228}
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700229
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700230int ExternalDisplay::getModeOrder(int mode)
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700231{
232 switch (mode) {
233 default:
234 case m1440x480i60_4_3:
235 return 1; // 480i 4:3
236 case m1440x480i60_16_9:
237 return 2; // 480i 16:9
238 case m1440x576i50_4_3:
239 return 3; // i576i 4:3
240 case m1440x576i50_16_9:
241 return 4; // 576i 16:9
242 case m640x480p60_4_3:
243 return 5; // 640x480 4:3
244 case m720x480p60_4_3:
245 return 6; // 480p 4:3
246 case m720x480p60_16_9:
247 return 7; // 480p 16:9
248 case m720x576p50_4_3:
249 return 8; // 576p 4:3
250 case m720x576p50_16_9:
251 return 9; // 576p 16:9
252 case m1920x1080i60_16_9:
253 return 10; // 1080i 16:9
254 case m1280x720p50_16_9:
255 return 11; // 720p@50Hz
256 case m1280x720p60_16_9:
257 return 12; // 720p@60Hz
258 case m1920x1080p24_16_9:
259 return 13; //1080p@24Hz
260 case m1920x1080p25_16_9:
261 return 14; //108-p@25Hz
262 case m1920x1080p30_16_9:
263 return 15; //1080p@30Hz
264 case m1920x1080p50_16_9:
265 return 16; //1080p@50Hz
266 case m1920x1080p60_16_9:
267 return 17; //1080p@60Hz
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700268 }
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700269}
270
271// Get the best mode for the current HD TV
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700272int ExternalDisplay::getBestMode() {
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700273 int bestOrder = 0;
274 int bestMode = m640x480p60_4_3;
275
276 // for all the edid read, get the best mode
277 for(int i = 0; i < mModeCount; i++) {
278 int mode = mEDIDModes[i];
279 int order = getModeOrder(mode);
280 if (order > bestOrder) {
281 bestOrder = order;
282 bestMode = mode;
283 }
284 }
285 return bestMode;
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700286}
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700287
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700288inline bool ExternalDisplay::isValidMode(int ID)
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700289{
290 return ((ID >= m640x480p60_4_3) && (ID <= m1920x1080p30_16_9));
291}
292
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700293void ExternalDisplay::setResolution(int ID)
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700294{
295 struct fb_var_screeninfo info;
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700296 int ret = 0;
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700297 if (!openFramebuffer())
298 return;
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700299 ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
300 if(ret < 0) {
301 ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
302 strerror(errno));
303 }
304
305 ALOGD_IF(DEBUG, "%s: GET Info<ID=%d %dx%d (%d,%d,%d),"
306 "(%d,%d,%d) %dMHz>", __FUNCTION__,
307 mVInfo.reserved[3], mVInfo.xres, mVInfo.yres,
308 mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin,
309 mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin,
310 mVInfo.pixclock/1000/1000);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700311 //If its a valid mode and its a new ID - update var_screeninfo
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700312 if ((isValidMode(ID)) && mCurrentMode != ID) {
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700313 const struct disp_mode_timing_type *mode =
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700314 &supported_video_mode_lut[0];
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700315 unsigned count = sizeof(supported_video_mode_lut)/sizeof
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700316 (*supported_video_mode_lut);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700317 for (unsigned int i = 0; i < count; ++i) {
318 const struct disp_mode_timing_type *cur =
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700319 &supported_video_mode_lut[i];
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700320 if (cur->video_format == ID)
321 mode = cur;
322 }
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700323 mode->set_info(mVInfo);
324 ALOGD_IF(DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx %d"
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700325 "(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, ID,
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700326 mVInfo.reserved[3], mVInfo.xres, mVInfo.yres,
327 mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin,
328 mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin,
329 mVInfo.pixclock/1000/1000);
330 mVInfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE;
331 ret = ioctl(mFd, FBIOPUT_VSCREENINFO, &mVInfo);
332 if(ret < 0) {
333 ALOGD("In %s: FBIOPUT_VSCREENINFO failed Err Str = %s",
334 __FUNCTION__, strerror(errno));
335 }
336 mCurrentMode = ID;
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700337 }
338 //Powerup
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700339 ret = ioctl(mFd, FBIOBLANK, FB_BLANK_UNBLANK);
340 if(ret < 0) {
341 ALOGD("In %s: FBIOBLANK failed Err Str = %s", __FUNCTION__,
342 strerror(errno));
343 }
344 ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
345 if(ret < 0) {
346 ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
347 strerror(errno));
348 }
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700349 //Pan_Display
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700350 ret = ioctl(mFd, FBIOPAN_DISPLAY, &mVInfo);
351 if(ret < 0) {
352 ALOGD("In %s: FBIOPAN_DISPLAY failed Err Str = %s", __FUNCTION__,
353 strerror(errno));
354 }
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700355}
356
357
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700358int ExternalDisplay::getExternalDisplay() const
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700359{
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700360 return mExternalDisplay;
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700361}
362
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700363void ExternalDisplay::setExternalDisplay(int connected)
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700364{
365
366 hwc_context_t* ctx = mHwcContext;
367 if(ctx) {
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700368 ALOGD_IF(DEBUG, "%s: status = %d", __FUNCTION__,
369 connected);
370 if(connected) {
371 readResolution();
372 //Get the best mode and set
373 // TODO: DO NOT call this for WFD
374 setResolution(getBestMode());
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700375 //enable hdmi vsync
376 enableHDMIVsync(connected);
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700377 } else {
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700378 // Disable the hdmi vsync
379 enableHDMIVsync(connected);
380 closeFrameBuffer();
381 resetInfo();
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700382 }
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700383 // Store the external display
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700384 mExternalDisplay = connected;
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700385 const char* prop = (connected) ? "1" : "0";
386 // set system property
387 property_set("hw.hdmiON", prop);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700388 //Invalidate
389 hwc_procs* proc = (hwc_procs*)ctx->device.reserved_proc[0];
390 if(!proc) {
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700391 ALOGE("%s: HWC proc not registered",
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700392 __FUNCTION__);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700393 } else {
394 /* Trigger redraw */
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700395 ALOGD_IF(DEBUG, "%s: Invalidate !!", __FUNCTION__);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700396 proc->invalidate(proc);
397 }
398 }
399 return;
400}
401
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700402bool ExternalDisplay::writeHPDOption(int userOption) const
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700403{
404 bool ret = true;
405 int hdmiHPDFile = open(SYSFS_HPD,O_RDWR, 0);
406 if (hdmiHPDFile < 0) {
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700407 ALOGE("%s: state file '%s' not found : ret%d"
408 "err str: %s", __FUNCTION__, SYSFS_HPD, hdmiHPDFile,
409 strerror(errno));
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700410 ret = false;
411 } else {
412 int err = -1;
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700413 ALOGD_IF(DEBUG, "%s: option = %d", __FUNCTION__,
414 userOption);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700415 if(userOption)
416 err = write(hdmiHPDFile, "1", 2);
417 else
418 err = write(hdmiHPDFile, "0" , 2);
419 if (err <= 0) {
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700420 ALOGE("%s: file write failed '%s'",
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700421 __FUNCTION__, SYSFS_HPD);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700422 ret = false;
423 }
424 close(hdmiHPDFile);
425 }
426 return ret;
427}
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700428
429bool ExternalDisplay::commit()
430{
431 if(mFd == -1) {
432 return false;
433 } else if(ioctl(mFd, FBIOPUT_VSCREENINFO, &mVInfo) == -1) {
434 ALOGE("%s: FBIOPUT_VSCREENINFO failed, str: %s", __FUNCTION__,
435 strerror(errno));
436 return false;
437 }
438 return true;
439}
440
441int ExternalDisplay::enableHDMIVsync(int enable)
442{
443 if(mFd > 0) {
444 int ret = ioctl(mFd, MSMFB_OVERLAY_VSYNC_CTRL, &enable);
445 if (ret<0) {
446 ALOGE("%s: enabling HDMI vsync failed, str: %s", __FUNCTION__,
447 strerror(errno));
448 }
449 }
450 return -errno;
451}
452
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700453};
454