1/* 2 * Copyright 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <fcntl.h> 18#include <errno.h> 19#include <math.h> 20#include <poll.h> 21#include <unistd.h> 22#include <dirent.h> 23#include <sys/select.h> 24 25#include <cutils/log.h> 26 27#include "sensors.h" 28#include "ProximitySensor.h" 29 30/*****************************************************************************/ 31 32ProximitySensor::ProximitySensor() 33 : SensorBase(NULL, PROXIMITY_DATA), 34 mEnabled(0), 35 mInputReader(4), 36 mHasPendingEvent(false) 37{ 38 mPendingEvent.sensor = ID_PX; 39 mPendingEvent.type = SENSOR_TYPE_PROXIMITY; 40 memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); 41} 42 43ProximitySensor::~ProximitySensor() 44{ 45} 46 47int ProximitySensor::setInitialState() 48{ 49 return 0; 50} 51 52int ProximitySensor::enable(int32_t, int en) 53{ 54 int newState = en ? 1 : 0; 55 int err = 0; 56 57 if (newState != mEnabled) { 58 if (!mEnabled && dev_name != NULL) { 59 open_device(); 60 } 61 62 char sysfs[PATH_MAX]; 63 64 strcpy(sysfs, I2C); 65 strcat(sysfs, "enable_ps_sensor"); 66 67 ALOGI_IF(DEBUG, "enable.open(%s), en(%d)", sysfs, en); 68 69 int fd = open(sysfs, O_RDWR); 70 if (fd < 0) { 71 ALOGE("couldn't open '%s' input device", sysfs); 72 err = -1; 73 } else { 74 char buf[2]; 75 76 buf[0] = newState ? '1' : '0'; 77 buf[1] = '\0'; 78 79 write(fd, buf, sizeof(buf)); 80 close(fd); 81 setInitialState(); 82 } 83 84 mEnabled = newState; 85 86 if (!mEnabled && dev_name != NULL) { 87 close_device(); 88 } 89 } 90 return err; 91} 92 93bool ProximitySensor::hasPendingEvents() const 94{ 95 return mHasPendingEvent; 96} 97 98int ProximitySensor::readEvents(sensors_event_t* data, int count) 99{ 100 if (count < 1) 101 return -EINVAL; 102 103 if (mHasPendingEvent) { 104 mHasPendingEvent = false; 105 mPendingEvent.timestamp = getTimestamp(); 106 *data = mPendingEvent; 107 return mEnabled ? 1 : 0; 108 } 109 110 ssize_t n = mInputReader.fill(data_fd); 111 if (n < 0) 112 return n; 113 114 int numEventReceived = 0; 115 input_event const* event; 116 117 while (count && mInputReader.readEvent(&event)) { 118 int type = event->type; 119 if (type == EV_ABS) { 120 if (event->code == ABS_DISTANCE) { 121 mPendingEvent.sensor = ID_PX; 122 mPendingEvent.type = SENSOR_TYPE_PROXIMITY; 123 mPendingEvent.distance = (float) event->value; 124 } 125 } else if (type == EV_SYN) { 126 mPendingEvent.timestamp = timevalToNano(event->time); 127 128 if (mEnabled) { 129 *data++ = mPendingEvent; 130 count--; 131 numEventReceived++; 132 } 133 } else { 134 ALOGE("ProximitySensor: unknown event (type=%d, code=%d)", 135 type, event->code); 136 } 137 mInputReader.next(); 138 } 139 140 return numEventReceived; 141} 142 143float ProximitySensor::indexToValue(size_t index) const 144{ 145 //return index * PROXIMITY_THRESHOLD_CM; 146 return index; 147} 148