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 #include <cutils/log.h> 25 26 #include "sensors.h" 27 #include "LightSensor.h" 28 29 #define ABS_LIGHT 0x29 30 31 LightSensor::LightSensor() 32 : SensorBase(NULL, LIGHT_DATA), 33 mEnabled(0), 34 mEventsSinceEnable(0), 35 mInputReader(4), 36 mHasPendingEvent(false) 37 { 38 mPendingEvent.sensor = ID_L; 39 mPendingEvent.type = SENSOR_TYPE_LIGHT; 40 memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); 41 } 42 43 LightSensor::~LightSensor() 44 { 45 } 46 47 int LightSensor::setInitialState() 48 { 49 return 0; 50 } 51 52 int LightSensor::setDelay(int32_t handle, int64_t ns) 53 { 54 int fd; 55 char sysfs[PATH_MAX]; 56 57 strcpy(sysfs, I2C); 58 strcat(sysfs, "als_poll_delay"); 59 60 fd = open(sysfs, O_RDWR); 61 if (fd >= 0) { 62 char buf[16] = {0,}; 63 snprintf(buf, sizeof(buf), "%lld", ns); 64 write(fd, buf, sizeof(buf)); 65 close(fd); 66 return 0; 67 } 68 return -1; 69 } 70 71 int LightSensor::enable(int32_t handle, int en) 72 { 73 int newState = en ? 1 : 0; 74 int err = 0; 75 76 if (newState != mEnabled) { 77 if (!mEnabled && dev_name != NULL) { 78 open_device(); 79 } 80 81 char sysfs[PATH_MAX]; 82 83 strcpy(sysfs, I2C); 84 strcat(sysfs, "enable_als_sensor"); 85 86 ALOGI_IF(DEBUG, "enable.open(%s), en(%d)", sysfs, en); 87 88 int fd = open(sysfs, O_RDWR); 89 if (fd < 0) { 90 ALOGE("couldn't open '%s' input device", sysfs); 91 err = -1; 92 } else { 93 char buf[2]; 94 95 buf[0] = newState ? '1' : '0'; 96 buf[1] = '\0'; 97 98 write(fd, buf, sizeof(buf)); 99 close(fd); 100 setInitialState(); 101 } 102 103 mEnabled = newState; 104 105 if (!mEnabled && dev_name != NULL) { 106 close_device(); 107 } 108 } 109 return err; 110 } 111 112 bool LightSensor::hasPendingEvents() const 113 { 114 return mHasPendingEvent; 115 } 116 117 int LightSensor::readEvents(sensors_event_t* data, int count) 118 { 119 if (count < 1) 120 return -EINVAL; 121 122 if (mHasPendingEvent) { 123 mHasPendingEvent = false; 124 mPendingEvent.timestamp = getTimestamp(); 125 *data = mPendingEvent; 126 return mEnabled ? 1 : 0; 127 } 128 129 ssize_t n = mInputReader.fill(data_fd); 130 if (n < 0) 131 return n; 132 133 int numEventReceived = 0; 134 input_event const* event; 135 136 while (count && mInputReader.readEvent(&event)) { 137 int type = event->type; 138 if (type == EV_ABS) { 139 if (event->code == ABS_LIGHT) { 140 mPendingEvent.sensor = ID_L; 141 mPendingEvent.type = SENSOR_TYPE_LIGHT; 142 mPendingEvent.light = (float)event->value; 143 } 144 } else if (type == EV_SYN) { 145 mPendingEvent.timestamp = timevalToNano(event->time); 146 if (mEnabled && (mPendingEvent.light != mPreviousLight) ) { 147 *data++ = mPendingEvent; 148 count--; 149 numEventReceived++; 150 mPreviousLight = mPendingEvent.light; 151 } 152 } else { 153 ALOGE("LightSensor: unknown event (type=%d, code=%d)", 154 type, event->code); 155 } 156 mInputReader.next(); 157 } 158 159 return numEventReceived; 160 } 161 162 float LightSensor::indexToValue(size_t index) const 163 { 164 return 0.0; 165 } 166