summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJun Yu <yujun@marvell.com>2015-11-10 14:22:07 -0800
committerMohammed Habibulla <moch@google.com>2015-11-16 18:57:55 -0800
commitfbbff5fbe83451d26bbef9d13921dc01883bf1af (patch)
treeaa556741682b6c94527c86515e74dea1960c74b2
parente4d4703c444085be68d17a5f6317beaca36eb7b5 (diff)
downloadmarvell-fbbff5fbe83451d26bbef9d13921dc01883bf1af.tar.gz
Added the Sensor HAL source code
BUG=25495615 Change-Id: I70528e063f1fbf7293d514098c3b78363b4f6975
-rwxr-xr-xperipheral/sensor/Android.mk54
-rw-r--r--peripheral/sensor/InputEventReader.cpp81
-rw-r--r--peripheral/sensor/InputEventReader.h47
-rw-r--r--peripheral/sensor/MrvlSensorBase.cpp166
-rw-r--r--peripheral/sensor/MrvlSensorBase.h64
-rw-r--r--peripheral/sensor/MrvlSensorWrapper.cpp86
-rw-r--r--peripheral/sensor/MrvlSensorWrapper.h65
-rw-r--r--peripheral/sensor/SensorBase.cpp134
-rw-r--r--peripheral/sensor/SensorBase.h75
-rw-r--r--peripheral/sensor/sensors/LightSensor.cpp259
-rw-r--r--peripheral/sensor/sensors/LightSensor.h83
-rw-r--r--peripheral/sensor/sensors/ProximitySensor.cpp261
-rw-r--r--peripheral/sensor/sensors/ProximitySensor.h81
-rw-r--r--peripheral/sensor/sensors_hal.cpp391
-rw-r--r--peripheral/sensor/sensors_hal.h55
-rw-r--r--soc/iap140/modules/sensor_hal_module.mk (renamed from soc/iap140/modules/sensor_modules.mk)5
16 files changed, 1904 insertions, 3 deletions
diff --git a/peripheral/sensor/Android.mk b/peripheral/sensor/Android.mk
new file mode 100755
index 0000000..75a7d2b
--- /dev/null
+++ b/peripheral/sensor/Android.mk
@@ -0,0 +1,54 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+BOARD_HAVE_AVAGO=true
+BOARD_HAVE_DYNA=true
+
+COMMON_CFLAGS := -DLOG_TAG=\"Sensors\" -Wno-unused-parameter
+COMMON_C_INCLUDES += $(LOCAL_PATH)/sensors
+
+ifeq ($(BOARD_HAVE_AVAGO),true)
+COMMON_CFLAGS += -DBOARD_HAVE_AVAGO
+endif
+ifeq ($(BOARD_HAVE_DYNA),true)
+COMMON_CFLAGS += -DBOARD_HAVE_DYNA
+endif
+
+#-----------------------------------------------------------
+# Build sensors.iap140
+include $(CLEAR_VARS)
+LOCAL_MODULE := sensors.iap140
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_RELATIVE_PATH := hw
+
+LOCAL_CFLAGS := $(COMMON_CFLAGS)
+LOCAL_C_INCLUDES := $(COMMON_C_INCLUDES)
+
+LOCAL_SRC_FILES += SensorBase.cpp \
+ InputEventReader.cpp \
+ sensors/LightSensor.cpp \
+ sensors/ProximitySensor.cpp \
+ MrvlSensorBase.cpp \
+ MrvlSensorWrapper.cpp \
+ sensors_hal.cpp
+
+LOCAL_SHARED_LIBRARIES += \
+ liblog \
+ libcutils \
+ libutils
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/peripheral/sensor/InputEventReader.cpp b/peripheral/sensor/InputEventReader.cpp
new file mode 100644
index 0000000..95b9ede
--- /dev/null
+++ b/peripheral/sensor/InputEventReader.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <errno.h>
+#include <unistd.h>
+#include <poll.h>
+#include <string.h>
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#include <linux/input.h>
+
+#include <cutils/log.h>
+
+#include "InputEventReader.h"
+
+/*****************************************************************************/
+
+struct input_event;
+
+InputEventCircularReader::InputEventCircularReader(size_t numEvents)
+ : mBuffer(new input_event[numEvents * 2]),
+ mBufferEnd(mBuffer + numEvents),
+ mHead(mBuffer),
+ mCurr(mBuffer),
+ mFreeSpace(numEvents) {}
+
+InputEventCircularReader::~InputEventCircularReader() { delete[] mBuffer; }
+
+ssize_t InputEventCircularReader::fill(int fd) {
+ size_t numEventsRead = 0;
+ if (mFreeSpace) {
+ const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event));
+ if (nread < 0 || nread % sizeof(input_event)) {
+ // we got a partial event!!
+ return nread < 0 ? -errno : -EINVAL;
+ }
+
+ numEventsRead = nread / sizeof(input_event);
+ if (numEventsRead) {
+ mHead += numEventsRead;
+ mFreeSpace -= numEventsRead;
+ if (mHead > mBufferEnd) {
+ size_t s = mHead - mBufferEnd;
+ memcpy(mBuffer, mBufferEnd, s * sizeof(input_event));
+ mHead = mBuffer + s;
+ }
+ }
+ }
+
+ return numEventsRead;
+}
+
+ssize_t InputEventCircularReader::readEvent(input_event const** events) {
+ *events = mCurr;
+ ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace;
+ return available ? 1 : 0;
+}
+
+void InputEventCircularReader::next() {
+ mCurr++;
+ mFreeSpace++;
+ if (mCurr >= mBufferEnd) {
+ mCurr = mBuffer;
+ }
+}
diff --git a/peripheral/sensor/InputEventReader.h b/peripheral/sensor/InputEventReader.h
new file mode 100644
index 0000000..7891c3d
--- /dev/null
+++ b/peripheral/sensor/InputEventReader.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_INPUT_EVENT_READER_H
+#define ANDROID_INPUT_EVENT_READER_H
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+/*****************************************************************************/
+
+struct input_event;
+
+class InputEventCircularReader {
+ struct input_event* const mBuffer;
+ struct input_event* const mBufferEnd;
+ struct input_event* mHead;
+ struct input_event* mCurr;
+ ssize_t mFreeSpace;
+ int mLastFd;
+
+ public:
+ InputEventCircularReader(size_t numEvents);
+ ~InputEventCircularReader();
+ ssize_t fill(int fd);
+ ssize_t readEvent(input_event const** events);
+ void next();
+};
+
+/*****************************************************************************/
+
+#endif // ANDROID_INPUT_EVENT_READER_H
diff --git a/peripheral/sensor/MrvlSensorBase.cpp b/peripheral/sensor/MrvlSensorBase.cpp
new file mode 100644
index 0000000..b01e216
--- /dev/null
+++ b/peripheral/sensor/MrvlSensorBase.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <poll.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/select.h>
+#include <cutils/log.h>
+#include <linux/input.h>
+
+#include <cutils/properties.h>
+
+#include "MrvlSensorBase.h"
+
+/*****************************************************************************/
+
+MrvlSensorBase::MrvlSensorBase(const char *devPath, const char *devName)
+ : SensorBase(NULL, NULL), mDevPath(devPath), mDevName(devName), mDevfd(-1) {
+ memset(mClassPath, 0, PATH_MAX);
+ openInputDevice();
+}
+
+MrvlSensorBase::~MrvlSensorBase() {
+ if (mDevfd) {
+ close(mDevfd);
+ }
+}
+
+int MrvlSensorBase::setDelay(int32_t handle, int64_t ns) { return 0; }
+
+bool MrvlSensorBase::hasPendingEvents() const { return false; }
+
+int MrvlSensorBase::enable(int32_t handle, int enabled) { return 0; }
+
+int MrvlSensorBase::query(int what, int *value) { return 0; }
+
+int MrvlSensorBase::batch(int handle, int flags, int64_t period_ns,
+ int64_t timeout) {
+ return 0;
+}
+
+int MrvlSensorBase::flush(int handle) { return 0; }
+
+int MrvlSensorBase::getFd() const { return mDevfd; }
+
+int MrvlSensorBase::populateSensors(Vector<struct sensor_t> &sensorVector) {
+ return 0;
+}
+int MrvlSensorBase::ifSensorExists() {
+ if (mDevfd > 0) return 0;
+ return -1;
+}
+
+/*-------------------------------------------------------------------------------*/
+
+int MrvlSensorBase::openInputDevice() {
+ // first try open directly by input device path
+ if (mDevPath) {
+ mDevfd = openDeviceByPath();
+ }
+
+ // then try by device name
+ if (mDevfd <= 0 && mDevName) {
+ mDevfd = openDeviceByName();
+ }
+
+ return 0;
+}
+/*This function searches through /sys/class/input/inputX to
+ find matching name. If name is matched, corresponding /dev/input/eventX
+ will be opened*/
+int MrvlSensorBase::openDeviceByName() {
+ const char *dirname = "/dev/input";
+ char *filename;
+ DIR *dir;
+ struct dirent *de;
+ char sysNamePath[PATH_MAX];
+ char devName[PATH_MAX];
+ int sysfd = -1;
+ int devfd = -1;
+ int ret;
+
+ strcpy(mCalculatedDevPath, dirname);
+ filename = mCalculatedDevPath + strlen(mCalculatedDevPath);
+ *filename++ = '/';
+
+ if (!(dir = opendir(INPUT_CLASS_PATH))) {
+ LOGE("Directory %s open failed.", INPUT_CLASS_PATH);
+ return -1;
+ }
+
+ while ((de = readdir(dir))) {
+ if (strncmp(de->d_name, "input", strlen("input")) != 0) {
+ continue;
+ }
+
+ snprintf(sysNamePath, sizeof(sysNamePath), "%s/%s/name", INPUT_CLASS_PATH,
+ de->d_name);
+
+ if ((sysfd = open(sysNamePath, O_RDONLY)) < 0) {
+ LOGE("File %s open failed.", sysNamePath);
+ continue;
+ }
+
+ if ((ret = read(sysfd, devName, sizeof(devName))) <= 0) {
+ close(sysfd);
+ continue;
+ }
+ close(sysfd);
+
+ devName[ret - 1] = '\0';
+ if (strcmp(devName, mDevName) == 0) {
+ /*
+ ** found the device name under
+ ** "SYS_CLASS_PATH/inputxx/name"
+ */
+ // first save the sys path
+ snprintf(mClassPath, sizeof(mClassPath), "%s/%s", INPUT_CLASS_PATH,
+ de->d_name);
+
+ // then find and open corresponding dev path
+ char eventName[PATH_MAX];
+ if (strlen(de->d_name) > 5) {
+ sprintf(eventName, "event%s", de->d_name + 5);
+ strcpy(filename, eventName);
+ devfd = open(mCalculatedDevPath, O_RDONLY);
+ LOGI("path open %s", mCalculatedDevPath);
+ }
+ break;
+ }
+ }
+ closedir(dir);
+ return devfd;
+}
+
+int MrvlSensorBase::openDeviceByPath() {
+ mDevfd = open(mDevPath, O_RDONLY);
+ LOGE_IF(mDevfd < 0, "Couldn't open %s (%s)", mDevPath, strerror(errno));
+
+ return mDevfd;
+}
+
+int MrvlSensorBase::closeInputDevice() {
+ if (mDevfd >= 0) {
+ close(mDevfd);
+ mDevfd = -1;
+ }
+ return 0;
+}
diff --git a/peripheral/sensor/MrvlSensorBase.h b/peripheral/sensor/MrvlSensorBase.h
new file mode 100644
index 0000000..28ccfb8
--- /dev/null
+++ b/peripheral/sensor/MrvlSensorBase.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MRVL_SENSOR_BASE_H
+#define ANDROID_MRVL_SENSOR_BASE_H
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <utils/Vector.h>
+#include "hardware/sensors.h"
+#include "SensorBase.h"
+
+using namespace android;
+
+#define INPUT_CLASS_PATH "/sys/class/input"
+
+class MrvlSensorBase : public SensorBase {
+ protected:
+ char mCalculatedDevPath[PATH_MAX];
+ char mClassPath[PATH_MAX];
+ const char* mDevPath;
+ const char* mDevName;
+ int mDevfd;
+
+ int openInputDevice();
+ int openDeviceByPath();
+ int openDeviceByName();
+ int closeInputDevice();
+
+ public:
+ MrvlSensorBase(const char* dev_name, const char* data_name);
+ virtual ~MrvlSensorBase();
+
+ virtual int readEvents(sensors_event_t* data, int count) = 0;
+ virtual bool hasPendingEvents() const;
+ virtual int getFd() const;
+ virtual int setDelay(int32_t handle, int64_t ns);
+ virtual int enable(int32_t handle, int enabled);
+ virtual int query(int what, int* value);
+ virtual int batch(int handle, int flags, int64_t period_ns, int64_t timeout);
+ virtual int flush(int handle);
+
+ virtual int populateSensors(Vector<struct sensor_t>& sensorVector);
+ virtual int ifSensorExists();
+};
+
+/*****************************************************************************/
+
+#endif // ANDROID_SENSOR_BASE_H
diff --git a/peripheral/sensor/MrvlSensorWrapper.cpp b/peripheral/sensor/MrvlSensorWrapper.cpp
new file mode 100644
index 0000000..948f3b6
--- /dev/null
+++ b/peripheral/sensor/MrvlSensorWrapper.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MrvlSensorWrapper.h"
+
+/*****************************************************************************/
+
+MrvlSensorWrapper::MrvlSensorWrapper(SensorBase* sensorObj,
+ struct sensor_t* sensors_list, int num)
+ : MrvlSensorBase(NULL, NULL) {
+ mDevName = NULL;
+ mDevPath = NULL;
+ mDevfd = 0;
+ sensor_info_list = new sensor_t[num];
+ sensor_object = sensorObj;
+ memcpy(sensor_info_list, sensors_list, num * sizeof(sensor_t));
+ sensor_nums = num;
+}
+
+MrvlSensorWrapper::~MrvlSensorWrapper() {
+ delete sensor_info_list;
+ delete sensor_object;
+}
+
+int MrvlSensorWrapper::setDelay(int32_t handle, int64_t ns) {
+ return sensor_object->setDelay(handle, ns);
+}
+
+int MrvlSensorWrapper::readEvents(sensors_event_t* data, int count) {
+ return sensor_object->readEvents(data, count);
+}
+
+bool MrvlSensorWrapper::hasPendingEvents() const {
+ return sensor_object->hasPendingEvents();
+}
+
+int MrvlSensorWrapper::enable(int32_t handle, int enabled) {
+ return sensor_object->enable(handle, enabled);
+}
+
+int MrvlSensorWrapper::query(int what, int* value) {
+ return sensor_object->query(what, value);
+}
+
+int MrvlSensorWrapper::batch(int handle, int flags, int64_t period_ns,
+ int64_t timeout) {
+ return sensor_object->batch(handle, flags, period_ns, timeout);
+}
+
+int MrvlSensorWrapper::flush(int handle) {
+ return sensor_object->flush(handle);
+}
+
+int MrvlSensorWrapper::getFd() const { return sensor_object->getFd(); }
+
+int MrvlSensorWrapper::populateSensors(Vector<struct sensor_t>& sensorVector) {
+ for (int i = 0; i < sensor_nums; i++) {
+ SLOGD("populateSensors i is %d, name is %s\n", i, sensor_info_list[i].name);
+ sensorVector.push_back(sensor_info_list[i]);
+ }
+
+ return sensor_nums;
+}
+int MrvlSensorWrapper::ifSensorExists() {
+ if (sensor_object->getFd() > 0) return 0;
+ return -1;
+}
+
+/*-------------------------------------------------------------------------------*/
+
+int MrvlSensorWrapper::openInputDevice() { return 0; }
+
+int MrvlSensorWrapper::closeInputDevice() { return 0; }
diff --git a/peripheral/sensor/MrvlSensorWrapper.h b/peripheral/sensor/MrvlSensorWrapper.h
new file mode 100644
index 0000000..320351a
--- /dev/null
+++ b/peripheral/sensor/MrvlSensorWrapper.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MRVL_SENSOR_WRAPPER_H
+#define ANDROID_MRVL_SENSOR_WRAPPER_H
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <utils/Vector.h>
+#include "MrvlSensorBase.h"
+
+using namespace android;
+
+class MrvlSensorWrapper : public MrvlSensorBase {
+ protected:
+ char mCalculatedDevPath[PATH_MAX];
+ char mClassPath[PATH_MAX];
+ const char* mDevPath;
+ const char* mDevName;
+ int mDevfd;
+ SensorBase* sensor_object;
+ struct sensor_t* sensor_info_list;
+ int sensor_nums;
+
+ int openInputDevice();
+ int openDeviceByPath();
+ int openDeviceByName();
+ int closeInputDevice();
+
+ public:
+ MrvlSensorWrapper(SensorBase* sensorObj, struct sensor_t* sensors_list,
+ int num);
+ ~MrvlSensorWrapper();
+
+ virtual int readEvents(sensors_event_t* data, int count);
+ virtual bool hasPendingEvents() const;
+ virtual int getFd() const;
+ virtual int setDelay(int32_t handle, int64_t ns);
+ virtual int enable(int32_t handle, int enabled);
+ virtual int query(int what, int* value);
+ virtual int batch(int handle, int flags, int64_t period_ns, int64_t timeout);
+ virtual int flush(int handle);
+
+ virtual int populateSensors(Vector<struct sensor_t>& sensorVector);
+ virtual int ifSensorExists();
+};
+
+/*****************************************************************************/
+
+#endif // ANDROID_MRVL_SENSOR_WRAPPER_H
diff --git a/peripheral/sensor/SensorBase.cpp b/peripheral/sensor/SensorBase.cpp
new file mode 100644
index 0000000..e27d449
--- /dev/null
+++ b/peripheral/sensor/SensorBase.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <poll.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/select.h>
+#include <cutils/log.h>
+#include <linux/input.h>
+#include <string.h>
+#include <cutils/properties.h>
+
+#include "SensorBase.h"
+
+/*****************************************************************************/
+
+// static vars
+
+SensorBase::SensorBase(const char *dev_name, const char *data_name)
+ : dev_name(dev_name), data_name(data_name), dev_fd(-1), data_fd(-1) {
+ if (data_name) {
+ data_fd = openInput(data_name);
+ }
+}
+
+SensorBase::~SensorBase() {
+ if (data_fd >= 0) {
+ close(data_fd);
+ }
+ if (dev_fd >= 0) {
+ close(dev_fd);
+ }
+}
+
+int SensorBase::open_device() {
+ if (dev_fd < 0 && dev_name) {
+ dev_fd = open(dev_name, O_RDONLY);
+ LOGE_IF(dev_fd < 0, "Couldn't open %s (%s)", dev_name, strerror(errno));
+ }
+ return 0;
+}
+
+int SensorBase::close_device() {
+ if (dev_fd >= 0) {
+ close(dev_fd);
+ dev_fd = -1;
+ }
+ return 0;
+}
+
+int SensorBase::getFd() const {
+ if (!data_name) {
+ return dev_fd;
+ }
+ return data_fd;
+}
+
+int SensorBase::setDelay(int32_t handle, int64_t ns) { return 0; }
+
+bool SensorBase::hasPendingEvents() const { return false; }
+
+int64_t SensorBase::getTimestamp() {
+ struct timespec t;
+ t.tv_sec = t.tv_nsec = 0;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ return int64_t(t.tv_sec) * 1000000000LL + t.tv_nsec;
+}
+
+int SensorBase::openInput(const char *inputName) {
+ int fd = -1;
+ const char *dirname = "/dev/input";
+ char devname[PATH_MAX];
+ char *filename;
+ DIR *dir;
+ struct dirent *de;
+ dir = opendir(dirname);
+ if (dir == NULL) return -1;
+ strcpy(devname, dirname);
+ filename = devname + strlen(devname);
+ *filename++ = '/';
+ while ((de = readdir(dir))) {
+ if (de->d_name[0] == '.' &&
+ (de->d_name[1] == '\0' ||
+ (de->d_name[1] == '.' && de->d_name[2] == '\0')))
+ continue;
+ strcpy(filename, de->d_name);
+ fd = open(devname, O_RDONLY);
+ LOGI("path open %s", devname);
+ if (fd >= 0) {
+ char name[80];
+ if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
+ name[0] = '\0';
+ }
+ if (!strcmp(name, inputName)) {
+ strcpy(input_name, filename);
+ break;
+ } else {
+ close(fd);
+ fd = -1;
+ }
+ }
+ }
+ closedir(dir);
+ LOGE_IF(fd < 0, "couldn't find '%s' input device", inputName);
+ return fd;
+}
+
+int SensorBase::enable(int32_t handle, int enabled) { return 0; }
+
+int SensorBase::query(int what, int *value) { return 0; }
+
+int SensorBase::batch(int handle, int flags, int64_t period_ns,
+ int64_t timeout) {
+ return 0;
+}
+
+int SensorBase::flush(int handle) { return 0; }
diff --git a/peripheral/sensor/SensorBase.h b/peripheral/sensor/SensorBase.h
new file mode 100644
index 0000000..3631aa9
--- /dev/null
+++ b/peripheral/sensor/SensorBase.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSOR_BASE_H
+#define ANDROID_SENSOR_BASE_H
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#define LOGV_IF ALOGV_IF
+#define LOGE_IF ALOGE_IF
+#define LOGI_IF ALOGI_IF
+#define LOGI ALOGI
+#define LOGE ALOGE
+#define LOGV ALOGV
+#define LOGW ALOGW
+#define LOGD ALOGD
+
+#define MAX_SYSFS_NAME_LEN (100)
+#define IIO_BUFFER_LENGTH (480)
+
+/*****************************************************************************/
+
+struct sensors_event_t;
+
+class SensorBase {
+ public:
+ const char* dev_name;
+ const char* data_name;
+ char input_name[PATH_MAX];
+ int dev_fd;
+ int data_fd;
+ int openInput(const char* inputName);
+ static int64_t getTimestamp();
+ static int64_t timevalToNano(timeval const& t) {
+ return t.tv_sec * 1000000000LL + t.tv_usec * 1000;
+ }
+
+ int open_device();
+ int close_device();
+
+ public:
+ SensorBase(const char* dev_name, const char* data_name);
+ virtual ~SensorBase();
+
+ virtual int readEvents(sensors_event_t* data, int count) = 0;
+ int readSample(long* data, int64_t* timestamp);
+ int readRawSample(float* data, int64_t* timestamp);
+ virtual bool hasPendingEvents() const;
+ virtual int getFd() const;
+ virtual int setDelay(int32_t handle, int64_t ns);
+ virtual int enable(int32_t handle, int enabled);
+ virtual int query(int what, int* value);
+ virtual int batch(int handle, int flags, int64_t period_ns, int64_t timeout);
+ virtual int flush(int handle);
+};
+
+/*****************************************************************************/
+
+#endif // ANDROID_SENSOR_BASE_H
diff --git a/peripheral/sensor/sensors/LightSensor.cpp b/peripheral/sensor/sensors/LightSensor.cpp
new file mode 100644
index 0000000..00a1488
--- /dev/null
+++ b/peripheral/sensor/sensors/LightSensor.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <poll.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/select.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <linux/input.h>
+
+#include "LightSensor.h"
+
+#define LOG_DBG 1
+
+/*****************************************************************************/
+
+struct sensor_t IntersilLightSensor::sBaseSensorList[] = {
+ {"Intersil Light sensor",
+ "Intersil ",
+ 1,
+ ISL_SENSORS_LIGHT_HANDLE,
+ SENSOR_TYPE_LIGHT,
+ 4095.0f,
+ 50.0f,
+ 0.356f,
+ 100,
+ 0,
+ 0,
+ "",
+ "",
+ 0,
+ 0,
+ {}},
+};
+
+IntersilLightSensor::IntersilLightSensor()
+ : LightSensorSet("ISL_light_sensor") {
+ LightSensorSet::mPendingEvent.sensor = ISL_ID_L;
+}
+
+/*****************************************************************************/
+
+struct sensor_t AvagoLightSensor::sBaseSensorList[] = {
+ {"Avago Light sensor",
+ "Avago ",
+ 1,
+ AVAGO_SENSORS_LIGHT_HANDLE,
+ SENSOR_TYPE_LIGHT,
+ 30000.0f,
+ 1.0f,
+ 0.5f,
+ 100000,
+ 0,
+ 0,
+ "",
+ "",
+ 0,
+ 0,
+ {}},
+};
+
+AvagoLightSensor::AvagoLightSensor() : LightSensorSet("APDS_light_sensor") {
+ LightSensorSet::mPendingEvent.sensor = AVAGO_ID_L;
+}
+
+/**********************************************************************************************/
+struct sensor_t TSLLightSensor::sBaseSensorList[] = {
+ {"TSL2x7x Light sensor",
+ "Taos",
+ 1,
+ TSL_SENSORS_LIGHT_HANDLE,
+ SENSOR_TYPE_LIGHT,
+ 10000.0f,
+ 1.0f,
+ 0.5f,
+ 100,
+ 0,
+ 0,
+ "",
+ "",
+ 0,
+ 0,
+ {}},
+};
+
+TSLLightSensor::TSLLightSensor() : LightSensorSet("TSL_light_sensor") {
+ LightSensorSet::mPendingEvent.sensor = TSL_ID_L;
+}
+
+/**********************************************************************************************/
+struct sensor_t EplLightSensor::sBaseSensorList[] = {
+ {"ELAN Light sensor",
+ "ELAN",
+ 1,
+ ELAN_SENSORS_LIGHT_HANDLE,
+ SENSOR_TYPE_LIGHT,
+ 30000.0f,
+ 1.0f,
+ 0.5f,
+ 100000,
+ 0,
+ 0,
+ "",
+ "",
+ 0,
+ 0,
+ {}},
+};
+
+EplLightSensor::EplLightSensor() : LightSensorSet("elan_light_sensor") {
+ LightSensorSet::mPendingEvent.sensor = ELAN_ID_L;
+}
+
+/**********************************************************************************************/
+struct sensor_t DynaLightSensor::sBaseSensorList[] = {
+ {"DYNA Light sensor",
+ "DYNA",
+ 1,
+ DYNA_SENSORS_LIGHT_HANDLE,
+ SENSOR_TYPE_LIGHT,
+ 30000.0f,
+ 1.0f,
+ 0.5f,
+ 100000,
+ 0,
+ 0,
+ "",
+ "",
+ 0,
+ 0,
+ {}},
+};
+
+DynaLightSensor::DynaLightSensor() : LightSensorSet("AP3426_light_sensor") {
+ LightSensorSet::mPendingEvent.sensor = DYNA_ID_L;
+}
+
+/**********************************************************************************************/
+
+LightSensorSet::LightSensorSet(const char* name)
+ : MrvlSensorBase(NULL, name),
+ mEnabled(0),
+ mInputReader(4),
+ mHasPendingEvent(false) {
+ mPendingEvent.version = sizeof(sensors_event_t);
+ mPendingEvent.type = SENSOR_TYPE_LIGHT;
+ memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
+ if (LOG_DBG) SLOGD("LightSensor: sysfs[%s]\n", mClassPath);
+}
+
+LightSensorSet::~LightSensorSet() {}
+
+int LightSensorSet::setDelay(int32_t handle, int64_t delay_ns) {
+ if (mEnabled) {
+ int fd;
+ char intervalPath[PATH_MAX];
+ sprintf(intervalPath, "%s/%s", mClassPath, "interval");
+ fd = open(intervalPath, O_RDWR);
+ if (fd >= 0) {
+ char buf[80];
+ sprintf(buf, "%lld", delay_ns / 1000000);
+ write(fd, buf, strlen(buf) + 1);
+ close(fd);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int LightSensorSet::enable(int32_t handle, int en) {
+ int flags = en ? 1 : 0;
+ if (flags != mEnabled) {
+ int fd;
+ char enablePath[PATH_MAX];
+ sprintf(enablePath, "%s/%s", mClassPath, "active");
+ if (LOG_DBG) SLOGD("LightSensor enable path is %s", enablePath);
+ fd = open(enablePath, O_RDWR);
+ if (fd >= 0) {
+ char buf[2];
+ int err;
+ buf[1] = '\n';
+ if (flags) {
+ buf[0] = '1';
+ } else {
+ buf[0] = '0';
+ }
+ err = write(fd, buf, sizeof(buf));
+ close(fd);
+ mEnabled = flags;
+
+ return 0;
+ }
+
+ LOGE("Error while open %s", enablePath);
+ return -1;
+ }
+ return 0;
+}
+
+bool LightSensorSet::hasPendingEvents() const { return mHasPendingEvent; }
+
+int LightSensorSet::readEvents(sensors_event_t* data, int count) {
+ if (count < 1) return -EINVAL;
+
+ if (mHasPendingEvent) {
+ mHasPendingEvent = false;
+ mPendingEvent.timestamp = getTimestamp();
+ *data = mPendingEvent;
+ return mEnabled ? 1 : 0;
+ }
+
+ ssize_t n = mInputReader.fill(mDevfd);
+ if (n < 0) return n;
+
+ int numEventReceived = 0;
+ bool valid = false;
+ input_event const* event;
+
+ while (count && mInputReader.readEvent(&event)) {
+ int type = event->type;
+ if ((type == EV_ABS) && (event->value > 0)) {
+ if (event->code == ABS_PRESSURE) {
+ mPendingEvent.light = event->value;
+ valid = true;
+ if (LOG_DBG) SLOGD("LightSensor: read value = %f", mPendingEvent.light);
+ }
+ } else if ((type == EV_SYN) && valid) {
+ mPendingEvent.timestamp = timevalToNano(event->time);
+ valid = false;
+ if (mEnabled) {
+ *data++ = mPendingEvent;
+ count--;
+ numEventReceived++;
+ }
+ } else {
+ LOGE("LightSensor: unknown event (type=%d, code=%d)", type, event->code);
+ }
+ mInputReader.next();
+ }
+
+ return numEventReceived;
+}
diff --git a/peripheral/sensor/sensors/LightSensor.h b/peripheral/sensor/sensors/LightSensor.h
new file mode 100644
index 0000000..ecd0fdc
--- /dev/null
+++ b/peripheral/sensor/sensors/LightSensor.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_LIGHT_SENSOR_H
+#define ANDROID_LIGHT_SENSOR_H
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <hardware/sensors.h>
+#include "MrvlSensorBase.h"
+#include "sensors_hal.h"
+#include "InputEventReader.h"
+
+/*****************************************************************************/
+
+struct inputnevent;
+
+class LightSensorSet : public MrvlSensorBase {
+ int mEnabled;
+ InputEventCircularReader mInputReader;
+ bool mHasPendingEvent;
+ // sensors_event_t mPendingEvent;
+ int setInitialState();
+
+ public:
+ sensors_event_t mPendingEvent;
+ LightSensorSet(const char* name);
+ virtual ~LightSensorSet();
+ virtual int readEvents(sensors_event_t* data, int count);
+ virtual bool hasPendingEvents() const;
+ virtual int setDelay(int32_t handle, int64_t ns);
+ virtual int enable(int32_t handle, int enabled);
+
+ protected:
+ struct sensor_t mBaseSensorList[];
+};
+
+class IntersilLightSensor : public LightSensorSet {
+ public:
+ static struct sensor_t sBaseSensorList[];
+ IntersilLightSensor();
+};
+
+class AvagoLightSensor : public LightSensorSet {
+ public:
+ static struct sensor_t sBaseSensorList[];
+ AvagoLightSensor();
+};
+
+class TSLLightSensor : public LightSensorSet {
+ public:
+ static struct sensor_t sBaseSensorList[];
+ TSLLightSensor();
+};
+
+class EplLightSensor : public LightSensorSet {
+ public:
+ static struct sensor_t sBaseSensorList[];
+ EplLightSensor();
+};
+class DynaLightSensor : public LightSensorSet {
+ public:
+ static struct sensor_t sBaseSensorList[];
+ DynaLightSensor();
+};
+/*****************************************************************************/
+
+#endif // ANDROID_LIGHT_SENSOR_H
diff --git a/peripheral/sensor/sensors/ProximitySensor.cpp b/peripheral/sensor/sensors/ProximitySensor.cpp
new file mode 100644
index 0000000..cdae7a2
--- /dev/null
+++ b/peripheral/sensor/sensors/ProximitySensor.cpp
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <poll.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/select.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <linux/input.h>
+
+#include "ProximitySensor.h"
+#include "sensors_hal.h"
+
+/*****************************************************************************/
+
+#define LOG_DBG 1
+
+struct sensor_t IntersilProximitySensor::sBaseSensorList[] = {
+ {"Intersil tech Proximity",
+ "Intersial",
+ 1,
+ ISL_SENSORS_PROXIMITY_HANDLE,
+ SENSOR_TYPE_PROXIMITY,
+ 10.0f,
+ 1.0f,
+ 0.356f,
+ 100,
+ 0,
+ 0,
+ "",
+ "",
+ 0,
+ 0,
+ {}},
+};
+
+IntersilProximitySensor::IntersilProximitySensor()
+ : ProximitySensor("ISL_proximity_sensor") {
+ ProximitySensor::mPendingEvent.sensor = ISL_ID_PRO;
+}
+
+/************************************************************************************************************/
+struct sensor_t AvagoProximitySensor::sBaseSensorList[] = {
+ {"Avago tech Proximity",
+ "Avago",
+ 1,
+ AVAGO_SENSORS_PROXIMITY_HANDLE,
+ SENSOR_TYPE_PROXIMITY,
+ 10.0f,
+ 1.0f,
+ 0.5f,
+ 100000,
+ 0,
+ 0,
+ "",
+ "",
+ 0,
+ 0,
+ {}},
+};
+
+AvagoProximitySensor::AvagoProximitySensor()
+ : ProximitySensor("APDS_proximity_sensor") {
+ ProximitySensor::mPendingEvent.sensor = AVAGO_ID_PRO;
+}
+
+/*****************************************************************************************************************/
+struct sensor_t TSLProximitySensor::sBaseSensorList[] = {
+ {"TSL2x7x tech Proximity",
+ "Taos",
+ 1,
+ TSL_SENSORS_PROXIMITY_HANDLE,
+ SENSOR_TYPE_PROXIMITY,
+ 5.0f,
+ 1.0f,
+ 0.5f,
+ 100,
+ 0,
+ 0,
+ "",
+ "",
+ 0,
+ 0,
+ {}},
+};
+
+TSLProximitySensor::TSLProximitySensor()
+ : ProximitySensor("TSL_proximity_sensor") {
+ ProximitySensor::mPendingEvent.sensor = TSL_ID_PRO;
+}
+
+/*****************************************************************************************************************/
+struct sensor_t EplProximitySensor::sBaseSensorList[] = {
+ {"ELAN Proximity sensor",
+ "ELAN",
+ 1,
+ ELAN_SENSORS_PROXIMITY_HANDLE,
+ SENSOR_TYPE_PROXIMITY,
+ 1.0f,
+ 1.0f,
+ 0.5f,
+ 100000,
+ 0,
+ 0,
+ "",
+ "",
+ 0,
+ 0,
+ {}},
+};
+
+EplProximitySensor::EplProximitySensor()
+ : ProximitySensor("elan_proximity_sensor") {
+ ProximitySensor::mPendingEvent.sensor = ELAN_ID_PRO;
+}
+
+/*****************************************************************************************************************/
+struct sensor_t DynaProximitySensor::sBaseSensorList[] = {
+ {"DYNA Proximity sensor",
+ "DYNA",
+ 1,
+ DYNA_SENSORS_PROXIMITY_HANDLE,
+ SENSOR_TYPE_PROXIMITY,
+ 10.0f,
+ 1.0f,
+ 0.5f,
+ 100000,
+ 0,
+ 0,
+ "",
+ "",
+ 0,
+ 0,
+ {}},
+};
+
+DynaProximitySensor::DynaProximitySensor()
+ : ProximitySensor("AP3426_proximity_sensor") {
+ ProximitySensor::mPendingEvent.sensor = DYNA_ID_PRO;
+}
+
+/*****************************************************************************************************************/
+
+ProximitySensor::ProximitySensor(const char* name)
+ : MrvlSensorBase(NULL, name),
+ mEnabled(0),
+ mInputReader(4),
+ mHasPendingEvent(false) {
+ mPendingEvent.version = sizeof(sensors_event_t);
+ mPendingEvent.type = SENSOR_TYPE_PROXIMITY;
+ memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
+
+ if (LOG_DBG) SLOGD("ProximitySensor: sysfs[%s]\n", mClassPath);
+}
+
+ProximitySensor::~ProximitySensor() {}
+
+int ProximitySensor::setDelay(int32_t handle, int64_t ns) {
+ if (mEnabled) {
+ int fd;
+ char intervalPath[PATH_MAX];
+ sprintf(intervalPath, "%s/%s", mClassPath, "interval");
+ fd = open(intervalPath, O_RDWR);
+ if (fd >= 0) {
+ char buf[80];
+ sprintf(buf, "%lld", ns);
+ write(fd, buf, strlen(buf) + 1);
+ close(fd);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int ProximitySensor::enable(int32_t, int en) {
+ int flags = en ? 1 : 0;
+ if (flags != mEnabled) {
+ int fd;
+ char enablePath[PATH_MAX];
+ sprintf(enablePath, "%s/%s", mClassPath, "active");
+ if (LOG_DBG) SLOGD("ProximitySensor enable path is %s", enablePath);
+ fd = open(enablePath, O_RDWR);
+ if (fd >= 0) {
+ char buf[2];
+ buf[1] = '\n';
+ if (flags) {
+ buf[0] = '1';
+ } else {
+ buf[0] = '0';
+ }
+ write(fd, buf, sizeof(buf));
+ close(fd);
+ mEnabled = flags;
+ return 0;
+ }
+
+ LOGE("Error while open %s", enablePath);
+ return -1;
+ }
+ return 0;
+}
+
+bool ProximitySensor::hasPendingEvents() const { return mHasPendingEvent; }
+
+int ProximitySensor::readEvents(sensors_event_t* data, int count) {
+ if (count < 1) return -EINVAL;
+
+ if (mHasPendingEvent) {
+ mHasPendingEvent = false;
+ mPendingEvent.timestamp = getTimestamp();
+ *data = mPendingEvent;
+ return mEnabled ? 1 : 0;
+ }
+
+ ssize_t n = mInputReader.fill(mDevfd);
+ if (n < 0) return n;
+
+ int numEventReceived = 0;
+ input_event const* event;
+
+ while (count && mInputReader.readEvent(&event)) {
+ int type = event->type;
+ if (type == EV_ABS) {
+ if (event->code == ABS_DISTANCE) {
+ mPendingEvent.distance = event->value;
+ if (LOG_DBG)
+ SLOGD("ProximitySensor: read value = %f", mPendingEvent.distance);
+ }
+ } else if (type == EV_SYN) {
+ mPendingEvent.timestamp = timevalToNano(event->time);
+ if (mEnabled) {
+ *data++ = mPendingEvent;
+ count--;
+ numEventReceived++;
+ }
+ } else {
+ LOGE("ProximitySensor: unknown event (type=%d, code=%d)", type,
+ event->code);
+ }
+ mInputReader.next();
+ }
+
+ return numEventReceived;
+}
diff --git a/peripheral/sensor/sensors/ProximitySensor.h b/peripheral/sensor/sensors/ProximitySensor.h
new file mode 100644
index 0000000..98b21d8
--- /dev/null
+++ b/peripheral/sensor/sensors/ProximitySensor.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_PROXIMITY_SENSOR_H
+#define ANDROID_PROXIMITY_SENSOR_H
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <hardware/sensors.h>
+#include "MrvlSensorBase.h"
+#include "InputEventReader.h"
+
+/*****************************************************************************/
+
+struct input_event;
+
+class ProximitySensor : public MrvlSensorBase {
+ int mEnabled;
+ InputEventCircularReader mInputReader;
+ bool mHasPendingEvent;
+
+ public:
+ sensors_event_t mPendingEvent;
+ ProximitySensor(const char* name);
+ virtual ~ProximitySensor();
+ virtual int readEvents(sensors_event_t* data, int count);
+ virtual bool hasPendingEvents() const;
+ virtual int enable(int32_t handle, int enabled);
+ virtual int setDelay(int32_t handle, int64_t ns);
+
+ protected:
+ struct sensor_t mBaseSensorList[];
+};
+
+class IntersilProximitySensor : public ProximitySensor {
+ public:
+ static struct sensor_t sBaseSensorList[];
+ IntersilProximitySensor();
+};
+
+class AvagoProximitySensor : public ProximitySensor {
+ public:
+ static struct sensor_t sBaseSensorList[];
+ AvagoProximitySensor();
+};
+
+class TSLProximitySensor : public ProximitySensor {
+ public:
+ static struct sensor_t sBaseSensorList[];
+ TSLProximitySensor();
+};
+
+class EplProximitySensor : public ProximitySensor {
+ public:
+ static struct sensor_t sBaseSensorList[];
+ EplProximitySensor();
+};
+
+class DynaProximitySensor : public ProximitySensor {
+ public:
+ static struct sensor_t sBaseSensorList[];
+ DynaProximitySensor();
+};
+/*****************************************************************************/
+
+#endif // ANDROID_PROXIMITY_SENSOR_H
diff --git a/peripheral/sensor/sensors_hal.cpp b/peripheral/sensor/sensors_hal.cpp
new file mode 100644
index 0000000..a88405e
--- /dev/null
+++ b/peripheral/sensor/sensors_hal.cpp
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hardware/sensors.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <math.h>
+#include <poll.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+#include <linux/input.h>
+
+#include <utils/Atomic.h>
+#include <utils/Log.h>
+#include <cutils/properties.h>
+#include <utils/KeyedVector.h>
+
+#include "SensorBase.h"
+#include "MrvlSensorBase.h"
+#include "MrvlSensorWrapper.h"
+
+#include "LightSensor.h"
+#include "ProximitySensor.h"
+
+#define SENSOR_OBJS_NUM 16
+
+typedef KeyedVector<int, SensorBase *> HandleMap;
+static int sSensorNum;
+static struct sensor_t *sSensorList;
+
+static int open_sensors(const struct hw_module_t *module, const char *id,
+ struct hw_device_t **device);
+
+/*This function should fill passed in sensor_t const* list with sensor list
+ return value is the list count*/
+static int sensors__get_sensors_list(struct sensors_module_t *module,
+ struct sensor_t const **list) {
+ *list = sSensorList;
+ return sSensorNum;
+}
+
+static struct hw_module_methods_t sensors_module_methods = {
+ open : open_sensors
+};
+
+struct sensors_module_t HAL_MODULE_INFO_SYM = {
+ common : {
+ tag : HARDWARE_MODULE_TAG,
+ version_major : 1,
+ version_minor : 0,
+ id : SENSORS_HARDWARE_MODULE_ID,
+ name : "Marvell Sensor module",
+ author : "Marvell SEEDS.",
+ methods : &sensors_module_methods,
+ dso : NULL,
+ reserved : {0}
+ },
+ get_sensors_list : sensors__get_sensors_list,
+ set_operation_mode : NULL,
+};
+
+struct sensors_poll_context_t {
+ sensors_poll_device_1_t device; // must be first
+
+ sensors_poll_context_t();
+ ~sensors_poll_context_t();
+ int activate(int handle, int enabled);
+ int setDelay(int handle, int64_t ns);
+ int pollEvents(sensors_event_t *data, int count);
+ int query(int what, int *value);
+ int batch(int handle, int flags, int64_t period_ns, int64_t timeout);
+ int flush(int handle);
+
+ private:
+ enum {
+ numSensorDrivers, // wake pipe goes here
+ numFds,
+ };
+
+ int add_sensor(MrvlSensorBase *sensorObj);
+ int prepare_sensor_list();
+ SensorBase *handleToSensorObj(int handle);
+ Vector<struct sensor_t> sSensorVector;
+ HandleMap mHandleToSensor;
+ struct pollfd mPollFds[SENSOR_OBJS_NUM];
+ SensorBase *mSensorObjs[SENSOR_OBJS_NUM]; // list all sensor objects so
+ // sensor object can be easily
+ // accessed by index
+ int mSensorIndex;
+ int mSensorObjIndex;
+};
+
+/******************************************************************************/
+
+int sensors_poll_context_t::prepare_sensor_list() {
+ if (sSensorList == NULL) {
+ sSensorNum = sSensorVector.size();
+ SLOGD("prepare_sensor_list: sSensorVector size %d\n", sSensorNum);
+ sSensorList = new sensor_t[sSensorNum];
+ for (int i = 0; i < sSensorNum; i++) {
+ SLOGD("prepare_sensor_list: sSensorVector i is %d, name is %s\n", i,
+ sSensorVector[i].name);
+ memcpy(&sSensorList[i], &sSensorVector[i], sizeof(struct sensor_t));
+ }
+ }
+
+ return sSensorNum;
+}
+
+int sensors_poll_context_t::add_sensor(MrvlSensorBase *sensorObj) {
+ int index = mSensorObjIndex;
+
+ SLOGD("add_sensor called for index %d", index);
+ if (sensorObj->ifSensorExists() == -1) {
+ SLOGD("sensor NOT detected, skip...");
+ delete sensorObj;
+ return -1;
+ }
+ // first add to mSensorObjs list for later easy access
+ mSensorObjs[index] = sensorObj;
+
+ // Add sensor object's fd to polling list
+ mPollFds[index].fd = sensorObj->getFd();
+ mPollFds[index].events = POLLIN;
+ mPollFds[index].revents = 0;
+
+ mSensorObjIndex++;
+
+ SLOGD("add_sensor call populateSensors");
+ // populate sensor list, add all sensors to sSensorVector;
+ int sensorNum = sensorObj->populateSensors(sSensorVector);
+ // record map between handle and Sensor
+ for (int i = mSensorIndex; i < mSensorIndex + sensorNum; i++) {
+ // SLOGD("add to mHandleToSensor, i is %d, handle %d, sensor object %x\n",
+ // i, sSensorVector[i].handle, (unsigned int)sensorObj);
+ mHandleToSensor.add(sSensorVector[i].handle, sensorObj);
+ }
+ // update sensor index to point to the next start sensor
+ mSensorIndex = mSensorIndex + sensorNum;
+
+ return 0;
+}
+
+sensors_poll_context_t::sensors_poll_context_t() {
+ for (int i = 0; i < SENSOR_OBJS_NUM; i++) {
+ mSensorObjs[i] = NULL;
+ mPollFds[i].fd = -1;
+ mPollFds[i].events = POLLIN;
+ mPollFds[i].revents = 0;
+ }
+ memset(&device, 0, sizeof(sensors_poll_device_1));
+
+ mSensorIndex = 0;
+ mSensorObjIndex = numSensorDrivers;
+
+ MrvlSensorWrapper *lightSensor = NULL;
+
+#ifdef BOARD_HAVE_AVAGO
+ lightSensor = new MrvlSensorWrapper(new AvagoLightSensor(),
+ AvagoLightSensor::sBaseSensorList, 1);
+ add_sensor(lightSensor);
+#endif
+#ifdef BOARD_HAVE_TSL
+ lightSensor = new MrvlSensorWrapper(new TSLLightSensor(),
+ TSLLightSensor::sBaseSensorList, 1);
+ add_sensor(lightSensor);
+#endif
+#ifdef BOARD_HAVE_ELAN
+ lightSensor = new MrvlSensorWrapper(new EplLightSensor(),
+ EplLightSensor::sBaseSensorList, 1);
+ add_sensor(lightSensor);
+#endif
+#ifdef BOARD_HAVE_DYNA
+ lightSensor = new MrvlSensorWrapper(new DynaLightSensor(),
+ DynaLightSensor::sBaseSensorList, 1);
+ add_sensor(lightSensor);
+#endif
+
+ MrvlSensorWrapper *proximitySensor = NULL;
+#ifdef BOARD_HAVE_INTERSIL
+ proximitySensor =
+ new MrvlSensorWrapper(new IntersilProximitySensor(),
+ IntersilProximitySensor::sBaseSensorList, 1);
+ add_sensor(proximitySensor);
+#endif
+#ifdef BOARD_HAVE_AVAGO
+ proximitySensor = new MrvlSensorWrapper(
+ new AvagoProximitySensor(), AvagoProximitySensor::sBaseSensorList, 1);
+ add_sensor(proximitySensor);
+#endif
+#ifdef BOARD_HAVE_TSL
+ proximitySensor = new MrvlSensorWrapper(
+ new TSLProximitySensor(), TSLProximitySensor::sBaseSensorList, 1);
+ add_sensor(proximitySensor);
+#endif
+#ifdef BOARD_HAVE_ELAN
+ proximitySensor = new MrvlSensorWrapper(
+ new EplProximitySensor(), EplProximitySensor::sBaseSensorList, 1);
+ add_sensor(proximitySensor);
+#endif
+#ifdef BOARD_HAVE_DYNA
+ proximitySensor = new MrvlSensorWrapper(
+ new DynaProximitySensor(), DynaProximitySensor::sBaseSensorList, 1);
+ add_sensor(proximitySensor);
+#endif
+
+ for (unsigned int i = 0; i < sSensorVector.size(); i++) {
+ SLOGD("Final sSensorVector: i is %d, name is %s\n", i,
+ sSensorVector[i].name);
+ }
+ for (int i = 0; i < mSensorObjIndex; i++) {
+ SLOGD("mSensorObjs: i is %d, obj is %lx\n", i,
+ (unsigned long)mSensorObjs[i]);
+ }
+
+ prepare_sensor_list();
+}
+
+sensors_poll_context_t::~sensors_poll_context_t() {
+ for (int i = 0; i < mSensorObjIndex; i++) {
+ if (mSensorObjs[i] != NULL) {
+ delete mSensorObjs[i];
+ }
+ }
+ for (int i = 0; i < mSensorObjIndex; i++) {
+ if (mPollFds[i].fd > 0) {
+ close(mPollFds[i].fd);
+ }
+ }
+}
+
+SensorBase *sensors_poll_context_t::handleToSensorObj(int handle) {
+ int index = mHandleToSensor.indexOfKey(handle);
+ if (index < 0) {
+ return NULL;
+ }
+ return mHandleToSensor.valueAt(index);
+}
+
+int sensors_poll_context_t::activate(int handle, int enabled) {
+ SensorBase *sensor = handleToSensorObj(handle);
+ if (sensor == NULL) {
+ LOGE("Cannot find sensor obj for handle %d\n", handle);
+ return -1;
+ }
+ return sensor->enable(handle, enabled);
+}
+
+int sensors_poll_context_t::setDelay(int handle, int64_t ns) {
+ SensorBase *sensor = handleToSensorObj(handle);
+ if (sensor == NULL) return -1;
+ return sensor->setDelay(handle, ns);
+}
+
+int sensors_poll_context_t::pollEvents(sensors_event_t *data, int count) {
+ int nbEvents = 0;
+ int nb, polltime = -1;
+
+ nb = poll(mPollFds, mSensorObjIndex, polltime);
+ LOGI_IF(0, "poll nb=%d, count=%d, pt=%d", nb, count, polltime);
+ if (nb > 0) {
+ for (int i = 0; count && i < mSensorObjIndex; i++) {
+ if (mPollFds[i].revents & (POLLIN | POLLPRI)) {
+ nb = 0;
+ if (mSensorObjs[i] != NULL) {
+ nb = mSensorObjs[i]->readEvents(data, count);
+ if (nb < count) {
+ mPollFds[i].revents = 0;
+ }
+ count -= nb;
+ nbEvents += nb;
+ data += nb;
+ return nbEvents;
+ }
+ // }
+ }
+ }
+
+ } else if (nb == 0) {
+ LOGE("poll returned with count 0");
+ }
+ return nbEvents;
+}
+
+int sensors_poll_context_t::query(int what, int *value) { return -1; }
+
+int sensors_poll_context_t::batch(int handle, int flags, int64_t period_ns,
+ int64_t timeout) {
+ SensorBase *sensor = handleToSensorObj(handle);
+ if (sensor == NULL) {
+ LOGE("Cannot find sensor obj for handle %d\n", handle);
+ return -1;
+ }
+ return 0;
+}
+
+int sensors_poll_context_t::flush(int handle) {
+ SensorBase *sensor = handleToSensorObj(handle);
+ if (sensor == NULL) {
+ LOGE("Cannot find sensor obj for handle %d\n", handle);
+ return -1;
+ }
+ return -1;
+}
+
+/******************************************************************************/
+
+static int poll__close(struct hw_device_t *dev) {
+ sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
+ if (ctx) {
+ delete ctx;
+ }
+ return 0;
+}
+
+static int poll__activate(struct sensors_poll_device_t *dev, int handle,
+ int enabled) {
+ sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
+ return ctx->activate(handle, enabled);
+}
+
+static int poll__setDelay(struct sensors_poll_device_t *dev, int handle,
+ int64_t ns) {
+ sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
+ int s = ctx->setDelay(handle, ns);
+ return s;
+}
+
+static int poll__poll(struct sensors_poll_device_t *dev, sensors_event_t *data,
+ int count) {
+ sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
+ return ctx->pollEvents(data, count);
+}
+
+static int poll__query(struct sensors_poll_device_1 *dev, int what,
+ int *value) {
+ sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
+ return ctx->query(what, value);
+}
+
+static int poll__batch(struct sensors_poll_device_1 *dev, int handle, int flags,
+ int64_t period_ns, int64_t timeout) {
+ sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
+ return ctx->batch(handle, flags, period_ns, timeout);
+}
+
+static int poll__flush(struct sensors_poll_device_1 *dev, int handle) {
+ sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
+ return ctx->flush(handle);
+}
+
+/******************************************************************************/
+
+/** Open a new instance of a sensor device using name
+ This function should fill passed in sensors_poll_device_1_t* mSensorDevice*/
+static int open_sensors(const struct hw_module_t *module, const char *id,
+ struct hw_device_t **device) {
+ int status = -EINVAL;
+
+ sensors_poll_context_t *dev = new sensors_poll_context_t();
+
+ dev->device.common.tag = HARDWARE_DEVICE_TAG;
+ dev->device.common.version = SENSORS_DEVICE_API_VERSION_1_1;
+ dev->device.flush = poll__flush;
+ dev->device.common.module = const_cast<hw_module_t *>(module);
+ dev->device.common.close = poll__close;
+ dev->device.activate = poll__activate;
+ dev->device.setDelay = poll__setDelay;
+ dev->device.poll = poll__poll;
+ dev->device.batch = poll__batch;
+
+ *device = &dev->device.common;
+ status = 0;
+
+ return status;
+}
diff --git a/peripheral/sensor/sensors_hal.h b/peripheral/sensor/sensors_hal.h
new file mode 100644
index 0000000..86ca950
--- /dev/null
+++ b/peripheral/sensor/sensors_hal.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORS_H
+#define ANDROID_SENSORS_H
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+/* Physical parameters of the sensors supported by misc vendor */
+
+enum {
+ ISL_ID_L = 40,
+ ISL_ID_PRO,
+ AVAGO_ID_L,
+ AVAGO_ID_PRO,
+ TSL_ID_L,
+ TSL_ID_PRO,
+ ELAN_ID_PRO,
+ ELAN_ID_L,
+ DYNA_ID_PRO,
+ DYNA_ID_L
+};
+
+#define ISL_SENSORS_LIGHT_HANDLE (ISL_ID_L)
+#define ISL_SENSORS_PROXIMITY_HANDLE (ISL_ID_PRO)
+#define AVAGO_SENSORS_LIGHT_HANDLE (AVAGO_ID_L)
+#define AVAGO_SENSORS_PROXIMITY_HANDLE (AVAGO_ID_PRO)
+#define TSL_SENSORS_LIGHT_HANDLE (TSL_ID_L)
+#define TSL_SENSORS_PROXIMITY_HANDLE (TSL_ID_PRO)
+#define ELAN_SENSORS_PROXIMITY_HANDLE (ELAN_ID_PRO)
+#define ELAN_SENSORS_LIGHT_HANDLE (ELAN_ID_L)
+#define DYNA_SENSORS_PROXIMITY_HANDLE (DYNA_ID_PRO)
+#define DYNA_SENSORS_LIGHT_HANDLE (DYNA_ID_L)
+
+__END_DECLS
+
+#endif // ANDROID_SENSORS_H
diff --git a/soc/iap140/modules/sensor_modules.mk b/soc/iap140/modules/sensor_hal_module.mk
index 072c50c..b506563 100644
--- a/soc/iap140/modules/sensor_modules.mk
+++ b/soc/iap140/modules/sensor_hal_module.mk
@@ -16,6 +16,5 @@
# Sensor modules
-PRODUCT_COPY_FILES += \
- $(TOP)/vendor/bsp/marvell/hal/sensor/libsensor_hal_mrvl.so:system/lib/libsensor_hal_mrvl.so \
- $(TOP)/vendor/bsp/marvell/hal/sensor/sensors.default.so:system/lib/hw/sensors.default.so
+DEVICE_PACKAGES += \
+ sensors.iap140