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