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
LightSensor()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
~LightSensor()43 LightSensor::~LightSensor()
44 {
45 }
46
setInitialState()47 int LightSensor::setInitialState()
48 {
49 return 0;
50 }
51
setDelay(int32_t handle,int64_t ns)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
enable(int32_t handle,int en)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
hasPendingEvents() const112 bool LightSensor::hasPendingEvents() const
113 {
114 return mHasPendingEvent;
115 }
116
readEvents(sensors_event_t * data,int count)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
indexToValue(size_t index) const162 float LightSensor::indexToValue(size_t index) const
163 {
164 return 0.0;
165 }
166