diff options
author | Jun Yu <yujun@marvell.com> | 2015-11-10 14:22:07 -0800 |
---|---|---|
committer | Mohammed Habibulla <moch@google.com> | 2015-11-16 18:57:55 -0800 |
commit | fbbff5fbe83451d26bbef9d13921dc01883bf1af (patch) | |
tree | aa556741682b6c94527c86515e74dea1960c74b2 | |
parent | e4d4703c444085be68d17a5f6317beaca36eb7b5 (diff) | |
download | marvell-fbbff5fbe83451d26bbef9d13921dc01883bf1af.tar.gz |
Added the Sensor HAL source code
BUG=25495615
Change-Id: I70528e063f1fbf7293d514098c3b78363b4f6975
-rwxr-xr-x | peripheral/sensor/Android.mk | 54 | ||||
-rw-r--r-- | peripheral/sensor/InputEventReader.cpp | 81 | ||||
-rw-r--r-- | peripheral/sensor/InputEventReader.h | 47 | ||||
-rw-r--r-- | peripheral/sensor/MrvlSensorBase.cpp | 166 | ||||
-rw-r--r-- | peripheral/sensor/MrvlSensorBase.h | 64 | ||||
-rw-r--r-- | peripheral/sensor/MrvlSensorWrapper.cpp | 86 | ||||
-rw-r--r-- | peripheral/sensor/MrvlSensorWrapper.h | 65 | ||||
-rw-r--r-- | peripheral/sensor/SensorBase.cpp | 134 | ||||
-rw-r--r-- | peripheral/sensor/SensorBase.h | 75 | ||||
-rw-r--r-- | peripheral/sensor/sensors/LightSensor.cpp | 259 | ||||
-rw-r--r-- | peripheral/sensor/sensors/LightSensor.h | 83 | ||||
-rw-r--r-- | peripheral/sensor/sensors/ProximitySensor.cpp | 261 | ||||
-rw-r--r-- | peripheral/sensor/sensors/ProximitySensor.h | 81 | ||||
-rw-r--r-- | peripheral/sensor/sensors_hal.cpp | 391 | ||||
-rw-r--r-- | peripheral/sensor/sensors_hal.h | 55 | ||||
-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 |