1/*
2* Copyright (C) 2012 Invensense, Inc.
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#define FUNC_LOG LOGV("%s", __PRETTY_FUNCTION__)
18
19#include <hardware/sensors.h>
20#include <fcntl.h>
21#include <errno.h>
22#include <dirent.h>
23#include <math.h>
24#include <poll.h>
25#include <pthread.h>
26#include <stdlib.h>
27
28#include <linux/input.h>
29
30#include <utils/Atomic.h>
31#include <utils/Log.h>
32
33#include "sensors.h"
34#include "MPLSensor.h"
35#include "local_log_def.h"
36
37/*****************************************************************************/
38/* The SENSORS Module */
39
40#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
41#define LOCAL_SENSORS (numSensors + 1)
42#else
43#define LOCAL_SENSORS numSensors
44
45#endif
46
47static struct sensor_t sSensorList[LOCAL_SENSORS];
48static int sensors = LOCAL_SENSORS;
49
50static int open_sensors(const struct hw_module_t* module, const char* id,
51                        struct hw_device_t** device);
52
53static int sensors__get_sensors_list(struct sensors_module_t* module,
54                                     struct sensor_t const** list)
55{
56    *list = sSensorList;
57    return sensors;
58}
59
60static struct hw_module_methods_t sensors_module_methods = {
61        open: open_sensors
62};
63
64struct sensors_module_t HAL_MODULE_INFO_SYM = {
65        common: {
66                tag: HARDWARE_MODULE_TAG,
67                version_major: 1,
68                version_minor: 0,
69                id: SENSORS_HARDWARE_MODULE_ID,
70                name: "Invensense module",
71                author: "Invensense Inc.",
72                methods: &sensors_module_methods,
73        },
74        get_sensors_list: sensors__get_sensors_list,
75};
76
77struct sensors_poll_context_t {
78    struct sensors_poll_device_t device; // must be first
79
80    sensors_poll_context_t();
81    ~sensors_poll_context_t();
82    int activate(int handle, int enabled);
83    int setDelay(int handle, int64_t ns);
84    int pollEvents(sensors_event_t* data, int count);
85
86private:
87    enum {
88        mpl = 0,
89        compass,
90        dmpOrient,
91        numSensorDrivers,   // wake pipe goes here
92        numFds,
93    };
94
95    struct pollfd mPollFds[numSensorDrivers];
96    SensorBase *mSensor;
97};
98
99/******************************************************************************/
100
101sensors_poll_context_t::sensors_poll_context_t() {
102    VFUNC_LOG;
103
104    CompassSensor *mCompassSensor = new CompassSensor();
105    MPLSensor *mplSensor = new MPLSensor(mCompassSensor);
106
107    // setup the callback object for handing mpl callbacks
108    setCallbackObject(mplSensor);
109
110    // populate the sensor list
111    sensors =
112            mplSensor->populateSensorList(sSensorList, sizeof(sSensorList));
113
114    mSensor = mplSensor;
115    mPollFds[mpl].fd = mSensor->getFd();
116    mPollFds[mpl].events = POLLIN;
117    mPollFds[mpl].revents = 0;
118
119    mPollFds[compass].fd = mCompassSensor->getFd();
120    mPollFds[compass].events = POLLIN;
121    mPollFds[compass].revents = 0;
122
123    mPollFds[dmpOrient].fd = ((MPLSensor*) mSensor)->getDmpOrientFd();
124    mPollFds[dmpOrient].events = POLLPRI;
125    mPollFds[dmpOrient].revents = 0;
126}
127
128sensors_poll_context_t::~sensors_poll_context_t() {
129    FUNC_LOG;
130    delete mSensor;
131}
132
133int sensors_poll_context_t::activate(int handle, int enabled) {
134    FUNC_LOG;
135    return mSensor->enable(handle, enabled);
136}
137
138int sensors_poll_context_t::setDelay(int handle, int64_t ns)
139{
140    FUNC_LOG;
141    return mSensor->setDelay(handle, ns);
142}
143
144int sensors_poll_context_t::pollEvents(sensors_event_t *data, int count)
145{
146    VHANDLER_LOG;
147
148    int nbEvents = 0;
149    int nb, polltime = -1;
150
151    // look for new events
152    nb = poll(mPollFds, numSensorDrivers, polltime);
153
154    if (nb > 0) {
155        for (int i = 0; count && i < numSensorDrivers; i++) {
156            if (mPollFds[i].revents & (POLLIN | POLLPRI)) {
157                nb = 0;
158                if (i == mpl) {
159                    nb = mSensor->readEvents(data, count);
160                    mPollFds[i].revents = 0;
161                }
162                else if (i == compass) {
163                    nb = ((MPLSensor*) mSensor)->readCompassEvents(data, count);
164                    mPollFds[i].revents = 0;
165                }
166            }
167        }
168        nb = ((MPLSensor*) mSensor)->executeOnData(data, count);
169        if (nb > 0) {
170            count -= nb;
171            nbEvents += nb;
172            data += nb;
173        }
174
175        if (mPollFds[dmpOrient].revents & (POLLIN | POLLPRI)) {
176            nb = ((MPLSensor*) mSensor)->readDmpOrientEvents(data, count);
177            mPollFds[dmpOrient].revents= 0;
178            if (isDmpScreenAutoRotationOn() && nb > 0) {
179                count -= nb;
180                nbEvents += nb;
181                data += nb;
182            }
183        }
184    }
185
186    return nbEvents;
187}
188
189/******************************************************************************/
190
191static int poll__close(struct hw_device_t *dev)
192{
193    FUNC_LOG;
194    sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
195    if (ctx) {
196        delete ctx;
197    }
198    return 0;
199}
200
201static int poll__activate(struct sensors_poll_device_t *dev,
202                          int handle, int enabled)
203{
204    sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
205    return ctx->activate(handle, enabled);
206}
207
208static int poll__setDelay(struct sensors_poll_device_t *dev,
209                          int handle, int64_t ns)
210{
211    sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
212    int s= ctx->setDelay(handle, ns);
213    return s;
214}
215
216static int poll__poll(struct sensors_poll_device_t *dev,
217                      sensors_event_t* data, int count)
218{
219    sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
220    return ctx->pollEvents(data, count);
221}
222
223/******************************************************************************/
224
225/** Open a new instance of a sensor device using name */
226static int open_sensors(const struct hw_module_t* module, const char* id,
227                        struct hw_device_t** device)
228{
229    FUNC_LOG;
230    int status = -EINVAL;
231    sensors_poll_context_t *dev = new sensors_poll_context_t();
232
233    memset(&dev->device, 0, sizeof(sensors_poll_device_t));
234
235    dev->device.common.tag = HARDWARE_DEVICE_TAG;
236    dev->device.common.version  = 0;
237    dev->device.common.module   = const_cast<hw_module_t*>(module);
238    dev->device.common.close    = poll__close;
239    dev->device.activate        = poll__activate;
240    dev->device.setDelay        = poll__setDelay;
241    dev->device.poll            = poll__poll;
242
243    *device = &dev->device.common;
244    status = 0;
245
246    return status;
247}
248