1ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann/* 2ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * Copyright (C) 2013 The Android Open Source Project 3ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * 4ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * Licensed under the Apache License, Version 2.0 (the "License"); 5ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * you may not use this file except in compliance with the License. 6ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * You may obtain a copy of the License at 7ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * 8ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * http://www.apache.org/licenses/LICENSE-2.0 9ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * 10ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * Unless required by applicable law or agreed to in writing, software 11ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * distributed under the License is distributed on an "AS IS" BASIS, 12ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * See the License for the specific language governing permissions and 14ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann * limitations under the License. 15ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann */ 16ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 17ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann#include <fcntl.h> 18a744b05984a963966cec08758ffe582d241be9d7Elliott Hughes#include <malloc.h> 19ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann#include <poll.h> 20ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann#include <pthread.h> 21ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann#include <sys/resource.h> 22ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 23ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann#include <adf/adf.h> 24ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann#include <adfhwc/adfhwc.h> 25ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 26ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann#include <cutils/log.h> 27ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann#include <utils/Vector.h> 28ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 29ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannstruct adf_hwc_helper { 30ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann adf_hwc_event_callbacks const *event_cb; 31ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann void *event_cb_data; 32ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 33ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann pthread_t event_thread; 34ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 35ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann android::Vector<int> intf_fds; 36ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann android::Vector<drm_mode_modeinfo> display_configs; 37ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann}; 38ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 39ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmanntemplate<typename T> inline T min(T a, T b) { return (a < b) ? a : b; } 40ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 41ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannint adf_eventControl(struct adf_hwc_helper *dev, int disp, int event, 42ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann int enabled) 43ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann{ 44ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (enabled != !!enabled) 45ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return -EINVAL; 46ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 47ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if ((size_t)disp >= dev->intf_fds.size()) 48ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return -EINVAL; 49ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 50ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann switch (event) { 51ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann case HWC_EVENT_VSYNC: 52ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return adf_set_event(dev->intf_fds[disp], ADF_EVENT_VSYNC, enabled); 53ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 54ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 55ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return -EINVAL; 56ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann} 57ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 58ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannstatic inline int32_t dpi(uint16_t res, uint16_t size_mm) 59ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann{ 60ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (size_mm) 61ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return 1000 * (res * 25.4f) / size_mm; 62ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return 0; 63ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann} 64ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 65ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannint adf_blank(struct adf_hwc_helper *dev, int disp, int blank) 66ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann{ 67ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if ((size_t)disp >= dev->intf_fds.size()) 68ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return -EINVAL; 69ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 70ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann uint8_t dpms_mode = blank ? DRM_MODE_DPMS_OFF : DRM_MODE_DPMS_ON; 71ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return adf_interface_blank(dev->intf_fds[disp], dpms_mode); 72ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann} 73ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 74ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannint adf_query_display_types_supported(struct adf_hwc_helper *dev, int *value) 75ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann{ 76ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann *value = 0; 77ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (dev->intf_fds.size() > 0) 78ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann *value |= HWC_DISPLAY_PRIMARY_BIT; 79ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (dev->intf_fds.size() > 1) 80ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann *value |= HWC_DISPLAY_EXTERNAL_BIT; 81ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 82ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return 0; 83ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann} 84ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 85ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannint adf_getDisplayConfigs(struct adf_hwc_helper *dev, int disp, 86ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann uint32_t *configs, size_t *numConfigs) 87ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann{ 88ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if ((size_t)disp >= dev->intf_fds.size()) 89ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return -EINVAL; 90ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 91ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann adf_interface_data data; 92ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann int err = adf_get_interface_data(dev->intf_fds[disp], &data); 93ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (err < 0) { 94ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann ALOGE("failed to get ADF interface data: %s", strerror(err)); 95ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return err; 96ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 97ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 98ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (!data.hotplug_detect) 99ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return -ENODEV; 100ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 101ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann android::Vector<drm_mode_modeinfo *> unique_configs; 102ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann unique_configs.push_back(&data.current_mode); 103ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann for (size_t i = 0; i < data.n_available_modes; i++) 104ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (memcmp(&data.available_modes[i], &data.current_mode, 105ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann sizeof(data.current_mode))) 106ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann unique_configs.push_back(&data.available_modes[i]); 107ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 108ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann for (size_t i = 0; i < min(*numConfigs, unique_configs.size()); i++) { 109ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann configs[i] = dev->display_configs.size(); 110ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann dev->display_configs.push_back(*unique_configs[i]); 111ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 112ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann *numConfigs = unique_configs.size(); 113ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 114ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann adf_free_interface_data(&data); 115ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return 0; 116ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann} 117ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 118ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannstatic int32_t adf_display_attribute(const adf_interface_data &data, 119ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann const drm_mode_modeinfo &mode, const uint32_t attribute) 120ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann{ 121ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann switch (attribute) { 122ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann case HWC_DISPLAY_VSYNC_PERIOD: 123ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (mode.vrefresh) 124ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return 1000000000 / mode.vrefresh; 125ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return 0; 126ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 127ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann case HWC_DISPLAY_WIDTH: 128ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return mode.hdisplay; 129ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 130ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann case HWC_DISPLAY_HEIGHT: 131ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return mode.vdisplay; 132ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 133ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann case HWC_DISPLAY_DPI_X: 134ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return dpi(mode.hdisplay, data.width_mm); 135ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 136ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann case HWC_DISPLAY_DPI_Y: 137ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return dpi(mode.vdisplay, data.height_mm); 138ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 139ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann default: 140ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann ALOGE("unknown display attribute %u", attribute); 141ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return -EINVAL; 142ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 143ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann} 144ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 145ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannint adf_getDisplayAttributes(struct adf_hwc_helper *dev, int disp, 146ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann uint32_t config, const uint32_t *attributes, int32_t *values) 147ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann{ 148ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if ((size_t)disp >= dev->intf_fds.size()) 149ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return -EINVAL; 150ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 151ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (config >= dev->display_configs.size()) 152ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return -EINVAL; 153ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 154ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann adf_interface_data data; 155ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann int err = adf_get_interface_data(dev->intf_fds[disp], &data); 156ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (err < 0) { 157ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann ALOGE("failed to get ADF interface data: %s", strerror(err)); 158ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return err; 159ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 160ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 161ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) 162ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann values[i] = adf_display_attribute(data, dev->display_configs[config], 163ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann attributes[i]); 164ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 165ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann adf_free_interface_data(&data); 166ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return 0; 167ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann} 168ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 169ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannstatic void handle_adf_event(struct adf_hwc_helper *dev, int disp) 170ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann{ 171ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann adf_event *event; 172ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann int err = adf_read_event(dev->intf_fds[disp], &event); 173ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (err < 0) { 174ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann ALOGE("error reading event from display %d: %s", disp, strerror(err)); 175ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return; 176ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 177ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 178ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann void *vsync_temp; 179ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann adf_vsync_event *vsync; 180ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann adf_hotplug_event *hotplug; 181ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 182ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann switch (event->type) { 183ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann case ADF_EVENT_VSYNC: 184ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann vsync_temp = event; 185ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann vsync = static_cast<adf_vsync_event *>(vsync_temp); 186ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann // casting directly to adf_vsync_event * makes g++ warn about 187ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann // potential alignment issues that don't apply here 188ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann dev->event_cb->vsync(dev->event_cb_data, disp, vsync->timestamp); 189ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann break; 190ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann case ADF_EVENT_HOTPLUG: 191ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann hotplug = reinterpret_cast<adf_hotplug_event *>(event); 192ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann dev->event_cb->hotplug(dev->event_cb_data, disp, hotplug->connected); 193ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann break; 194ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann default: 195ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (event->type < ADF_EVENT_DEVICE_CUSTOM) 196ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann ALOGW("unrecognized event type %u", event->type); 197ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann else if (!dev->event_cb || !dev->event_cb->custom_event) 198ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann ALOGW("unhandled event type %u", event->type); 199ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann else 200ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann dev->event_cb->custom_event(dev->event_cb_data, disp, event); 201ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 202ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann free(event); 203ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann} 204ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 205ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannstatic void *adf_event_thread(void *data) 206ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann{ 207ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann adf_hwc_helper *dev = static_cast<adf_hwc_helper *>(data); 208ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 209ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 210ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 211ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann pollfd *fds = new pollfd[dev->intf_fds.size()]; 212ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann for (size_t i = 0; i < dev->intf_fds.size(); i++) { 213ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann fds[i].fd = dev->intf_fds[i]; 214ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann fds[i].events = POLLIN | POLLPRI; 215ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 216ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 217ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann while (true) { 218ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann int err = poll(fds, dev->intf_fds.size(), -1); 219ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 220ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (err > 0) { 221ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann for (size_t i = 0; i < dev->intf_fds.size(); i++) 222ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (fds[i].revents & (POLLIN | POLLPRI)) 223ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann handle_adf_event(dev, i); 224ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 225ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann else if (err == -1) { 226ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (errno == EINTR) 227ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann break; 228ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann ALOGE("error in event thread: %s", strerror(errno)); 229ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 230ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 231ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 232ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann delete [] fds; 233ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return NULL; 234ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann} 235ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 236ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannint adf_hwc_open(int *intf_fds, size_t n_intfs, 237ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann const struct adf_hwc_event_callbacks *event_cb, void *event_cb_data, 238ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann struct adf_hwc_helper **dev) 239ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann{ 240ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (!n_intfs) 241ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return -EINVAL; 242ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 243ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann adf_hwc_helper *dev_ret = new adf_hwc_helper; 244ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann dev_ret->event_cb = event_cb; 245ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann dev_ret->event_cb_data = event_cb_data; 246ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 247ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann int ret; 248ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 249ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann for (size_t i = 0; i < n_intfs; i++) { 250ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann int dup_intf_fd = dup(intf_fds[i]); 251ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (dup_intf_fd < 0) { 252ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann ALOGE("failed to dup interface fd: %s", strerror(errno)); 253ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann ret = -errno; 254ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann goto err; 255ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 256ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 257ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann dev_ret->intf_fds.push_back(dup_intf_fd); 258ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 259ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann ret = adf_set_event(dup_intf_fd, ADF_EVENT_HOTPLUG, 1); 260ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (ret < 0 && ret != -EINVAL) { 26118b712784558747a16dcf200818b9a48ffc606a2Greg Hackmann ALOGE("failed to enable hotplug event on display %zu: %s", 262ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann i, strerror(errno)); 263ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann goto err; 264ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 265ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 266ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 267ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann ret = pthread_create(&dev_ret->event_thread, NULL, adf_event_thread, 268ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann dev_ret); 269ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann if (ret) { 270ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann ALOGE("failed to create event thread: %s", strerror(ret)); 271ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann goto err; 272ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann } 273ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 274ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann *dev = dev_ret; 275ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return 0; 276ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 277ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannerr: 278ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann for (size_t i = 0; i < dev_ret->intf_fds.size(); i++) 279ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann close(dev_ret->intf_fds[i]); 280ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 281ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann delete dev_ret; 282ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann return ret; 283ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann} 284ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 285ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmannvoid adf_hwc_close(struct adf_hwc_helper *dev) 286ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann{ 287ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann pthread_kill(dev->event_thread, SIGTERM); 288ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann pthread_join(dev->event_thread, NULL); 289ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 290ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann for (size_t i = 0; i < dev->intf_fds.size(); i++) 291ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann close(dev->intf_fds[i]); 292ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann 293ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann delete dev; 294ebb26c71fe59c1904dc198b00948c581d31bd412Greg Hackmann} 295