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