aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Bestas <mkbestas@lineageos.org>2017-08-27 20:06:59 +0530
committerdev-harsh1998 <harshitjain6751@gmail.com>2017-10-18 12:39:06 +0530
commit2c7dd131bb7f6d3a2ff051792b4f5b35ae31a996 (patch)
tree04231d37b77d7d13f5de73ebc6d7d5f8a2d147a8
parent3fd4450191c4a22059940fa4f454ef9ca5238bd8 (diff)
a6000: sensors: cleanup & update for O
-> @dev-harsh1998: remove algo sensor data & calibration files -> @dev-harsh1998: Kanged a lot of goodies from oppo 8939 common -> @dev-harsh1998: Bring sensor stack bit closer to lettuce -> @dev-harsh1998: Bringback, update compass & gyro sensor for Lenovo K30-'X' series -> @dev-harsh1998: cleanup while we are at this -> @dev-harsh1998: Updated the sensors to the latest avilable CAF tag as of now Change-Id: I278e6cce18faa7a98a52572a822e148fe27b5d3f
-rw-r--r--sensors/AccelSensor.h3
-rw-r--r--sensors/Accelerometer.cpp131
-rw-r--r--sensors/AkmSensor.h61
-rw-r--r--sensors/Android.mk90
-rw-r--r--sensors/CalibrationManager.cpp30
-rw-r--r--sensors/CalibrationModule.h12
-rw-r--r--sensors/CompassSensor.cpp120
-rw-r--r--sensors/CompassSensor.h3
-rw-r--r--sensors/GyroSensor.h5
-rw-r--r--sensors/Gyroscope.cpp113
-rw-r--r--sensors/LightSensor.cpp54
-rw-r--r--sensors/LightSensor.h3
-rw-r--r--sensors/NativeSensorManager.cpp740
-rw-r--r--sensors/NativeSensorManager.h23
-rw-r--r--sensors/ProximitySensor.cpp307
-rw-r--r--sensors/ProximitySensor.h10
-rw-r--r--sensors/SensorBase.cpp120
-rw-r--r--sensors/SensorBase.h14
-rw-r--r--sensors/VirtualSensor.cpp56
-rw-r--r--sensors/VirtualSensor.h8
-rw-r--r--sensors/algo/akm/AKFS_AOC.c333
-rw-r--r--sensors/algo/akm/AKFS_AOC.h53
-rw-r--r--sensors/algo/akm/AKFS_Configure.h37
-rw-r--r--sensors/algo/akm/AKFS_Decomp.c51
-rw-r--r--sensors/algo/akm/AKFS_Decomp.h58
-rw-r--r--sensors/algo/akm/AKFS_Device.c150
-rw-r--r--sensors/algo/akm/AKFS_Device.h112
-rw-r--r--sensors/algo/akm/AKFS_Direction.c166
-rw-r--r--sensors/algo/akm/AKFS_Direction.h39
-rw-r--r--sensors/algo/akm/AKFS_Math.h47
-rw-r--r--sensors/algo/akm/AKFS_VNorm.c123
-rw-r--r--sensors/algo/akm/AKFS_VNorm.h46
-rw-r--r--sensors/algo/akm/NOTICE202
-rw-r--r--sensors/algo/akm/README.md34
-rw-r--r--sensors/algo/akm/akm_wrapper.c269
-rw-r--r--sensors/algo/common/common_wrapper.c86
-rw-r--r--sensors/calmodule.cfg5
-rw-r--r--sensors/sensors.cpp59
-rw-r--r--sensors/sensors.h18
-rw-r--r--sensors/sensors_XML.cpp240
-rw-r--r--sensors/sensors_XML.h10
41 files changed, 1613 insertions, 2428 deletions
diff --git a/sensors/AccelSensor.h b/sensors/AccelSensor.h
index b85a9bd..c388af6 100644
--- a/sensors/AccelSensor.h
+++ b/sensors/AccelSensor.h
@@ -31,12 +31,9 @@
struct input_event;
class AccelSensor : public SensorBase {
- int mEnabled;
InputEventCircularReader mInputReader;
sensors_event_t mPendingEvent;
bool mHasPendingEvent;
- char input_sysfs_path[PATH_MAX];
- int input_sysfs_path_len;
int64_t mEnabledTime;
int setInitialState();
diff --git a/sensors/Accelerometer.cpp b/sensors/Accelerometer.cpp
index faf1050..1bda2c2 100644
--- a/sensors/Accelerometer.cpp
+++ b/sensors/Accelerometer.cpp
@@ -44,12 +44,13 @@
#define SYSFS_I2C_SLAVE_PATH "/device/device/"
#define SYSFS_INPUT_DEV_PATH "/device/"
+#define ARRAY 3
+
/*****************************************************************************/
AccelSensor::AccelSensor()
: SensorBase(NULL, "accelerometer"),
- mEnabled(0),
- mInputReader(6),
+ mInputReader(4),
mHasPendingEvent(false),
mEnabledTime(0)
{
@@ -57,28 +58,20 @@ AccelSensor::AccelSensor()
mPendingEvent.sensor = SENSORS_ACCELERATION_HANDLE;
mPendingEvent.type = SENSOR_TYPE_ACCELEROMETER;
memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
+ mPendingEvent.acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
if (data_fd) {
strlcpy(input_sysfs_path, "/sys/class/input/", sizeof(input_sysfs_path));
strlcat(input_sysfs_path, input_name, sizeof(input_sysfs_path));
strlcat(input_sysfs_path, SYSFS_I2C_SLAVE_PATH, sizeof(input_sysfs_path));
input_sysfs_path_len = strlen(input_sysfs_path);
-#ifdef TARGET_8610
- if (access(input_sysfs_path, F_OK)) {
- input_sysfs_path_len -= strlen(SYSFS_I2C_SLAVE_PATH);
- strcpy(&input_sysfs_path[input_sysfs_path_len],
- SYSFS_INPUT_DEV_PATH);
- input_sysfs_path_len += strlen(SYSFS_INPUT_DEV_PATH);
- }
-#endif
enable(0, 1);
}
}
AccelSensor::AccelSensor(char *name)
: SensorBase(NULL, "accelerometer"),
- mEnabled(0),
- mInputReader(6),
+ mInputReader(4),
mHasPendingEvent(false),
mEnabledTime(0)
{
@@ -86,6 +79,7 @@ AccelSensor::AccelSensor(char *name)
mPendingEvent.sensor = SENSORS_ACCELERATION_HANDLE;
mPendingEvent.type = SENSOR_TYPE_ACCELEROMETER;
memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
+ mPendingEvent.acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
if (data_fd) {
strlcpy(input_sysfs_path, SYSFS_CLASS, sizeof(input_sysfs_path));
@@ -98,9 +92,8 @@ AccelSensor::AccelSensor(char *name)
}
AccelSensor::AccelSensor(SensorContext *context)
- : SensorBase(NULL, NULL),
- mEnabled(0),
- mInputReader(6),
+ : SensorBase(NULL, NULL, context),
+ mInputReader(4),
mHasPendingEvent(false),
mEnabledTime(0)
{
@@ -108,6 +101,7 @@ AccelSensor::AccelSensor(SensorContext *context)
mPendingEvent.sensor = context->sensor->handle;
mPendingEvent.type = SENSOR_TYPE_ACCELEROMETER;
memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
+ mPendingEvent.acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
strlcpy(input_sysfs_path, context->enable_path, sizeof(input_sysfs_path));
input_sysfs_path_len = strlen(input_sysfs_path);
@@ -130,6 +124,7 @@ int AccelSensor::enable(int32_t, int en) {
if (strcmp(propBuf, "1") == 0) {
ALOGE("sensors.accel.loopback is set");
mEnabled = flags;
+ mEnabledTime = 0;
return 0;
}
@@ -145,6 +140,7 @@ int AccelSensor::enable(int32_t, int en) {
if (flags) {
buf[0] = '1';
mEnabledTime = getTimestamp() + IGNORE_EVENT_TIME;
+ sysclk_sync_offset = getClkOffset();
} else {
buf[0] = '0';
}
@@ -160,7 +156,7 @@ int AccelSensor::enable(int32_t, int en) {
}
bool AccelSensor::hasPendingEvents() const {
- return mHasPendingEvent;
+ return mHasPendingEvent || mHasPendingMetadata;
}
int AccelSensor::setDelay(int32_t, int64_t delay_ns)
@@ -178,7 +174,7 @@ int AccelSensor::setDelay(int32_t, int64_t delay_ns)
fd = open(input_sysfs_path, O_RDWR);
if (fd >= 0) {
char buf[80];
- sprintf(buf, "%d", delay_ms);
+ snprintf(buf, sizeof(buf), "%d", delay_ms);
write(fd, buf, strlen(buf)+1);
close(fd);
return 0;
@@ -198,6 +194,13 @@ int AccelSensor::readEvents(sensors_event_t* data, int count)
return mEnabled ? 1 : 0;
}
+ if (mHasPendingMetadata) {
+ mHasPendingMetadata--;
+ meta_data.timestamp = getTimestamp();
+ *data = meta_data;
+ return mEnabled ? 1 : 0;
+ }
+
ssize_t n = mInputReader.fill(data_fd);
if (n < 0)
return n;
@@ -220,33 +223,32 @@ again:
mPendingEvent.data[2] = value * CONVERT_ACCEL_Z;
}
} else if (type == EV_SYN) {
- switch ( event->code ){
+ switch (event->code){
case SYN_TIME_SEC:
{
mUseAbsTimeStamp = true;
report_time = event->value*1000000000LL;
}
- break;
+ break;
case SYN_TIME_NSEC:
{
mUseAbsTimeStamp = true;
mPendingEvent.timestamp = report_time+event->value;
}
- break;
+ break;
case SYN_REPORT:
{
- if (mEnabled && mUseAbsTimeStamp) {
- if(mPendingEvent.timestamp >= mEnabledTime) {
- *data++ = mPendingEvent;
- numEventReceived++;
- }
+ if(mUseAbsTimeStamp != true) {
+ mPendingEvent.timestamp = timevalToNano(event->time);
+ }
+ mPendingEvent.timestamp -= sysclk_sync_offset;
+ if (mEnabled) {
+ *data++ = mPendingEvent;
+ numEventReceived++;
count--;
- mUseAbsTimeStamp = false;
- } else {
- ALOGE_IF(!mUseAbsTimeStamp, "AccelSensor:timestamp not received");
}
}
- break;
+ break;
}
} else {
ALOGE("AccelSensor: unknown event (type=%d, code=%d)",
@@ -268,16 +270,17 @@ again:
return numEventReceived;
}
-int AccelSensor::calibrate(int32_t handle, struct cal_cmd_t *para,
+int AccelSensor::calibrate(int32_t, struct cal_cmd_t *para,
struct cal_result_t *cal_result)
{
int fd;
- char temp[3][LENGTH];
- char buf[3 * LENGTH];
+ char temp[ARRAY][LENGTH];
+ char buf[ARRAY * LENGTH];
char *token, *strsaveptr, *endptr;
int i, err;
off_t offset;
int para1 = 0;
+
if (para == NULL || cal_result == NULL) {
ALOGE("Null pointer calibrate parameters\n");
return -1;
@@ -293,52 +296,43 @@ int AccelSensor::calibrate(int32_t handle, struct cal_cmd_t *para,
ALOGE("open %s failed\n", input_sysfs_path);
return -1;
}
- if (fd >= 0) {
- offset = lseek(fd, 0, SEEK_SET);
- char *p = buf;
- memset(buf, 0, sizeof(buf));
- err = read(fd, buf, sizeof(buf)-1);
- if(err < 0) {
- ALOGE("read error\n");
+ offset = lseek(fd, 0, SEEK_SET);
+ char *p = buf;
+ memset(buf, 0, sizeof(buf));
+ err = read(fd, buf, sizeof(buf)-1);
+ if(err < 0) {
+ ALOGE("read error\n");
+ close(fd);
+ return err;
+ }
+ for(i = 0; i < ARRAY; i++, p = NULL) {
+ token = strtok_r(p, ",", &strsaveptr);
+ if(token == NULL)
+ break;
+ if(strlen(token) > LENGTH - 1) {
+ ALOGE("token is too long\n");
close(fd);
- return err;
- }
- for(i = 0; i < sizeof(temp) / LENGTH; i++, p = NULL) {
- token = strtok_r(p, ",", &strsaveptr);
- if(token == NULL)
- break;
- if(strlen(token) > LENGTH - 1) {
- ALOGE("token is too long\n");
- close(fd);
- return -1;
- }
- strlcpy(temp[i], token, sizeof(temp[i]));
+ return -1;
}
- close(fd);
- for(int i = 0; i < sizeof(temp) / LENGTH; i++) {
- cal_result->offset[i] = strtol(temp[i], &endptr, 10);
- if (cal_result->offset[i] == LONG_MAX || cal_result->offset[i] == LONG_MIN) {
- ALOGE("cal_result->offset[%d] error value\n", i);
- return -1;
- }
- if (endptr == temp[i]) {
- ALOGE("No digits were found\n");
- return -1;
- }
+ strlcpy(temp[i], token, sizeof(temp[i]));
+ }
+ close(fd);
+ for(int i = 0; i < ARRAY; i++) {
+ cal_result->offset[i] = strtol(temp[i], &endptr, 0);
+ if (endptr == temp[i]) {
+ ALOGE("No digits were found\n");
+ return -1;
}
- return 0;
- } else {
- ALOGE("open %s error\n", input_sysfs_path);
- return -1;
}
return 0;
}
-int AccelSensor::initCalibrate(int32_t handle, struct cal_result_t *cal_result)
+int AccelSensor::initCalibrate(int32_t, struct cal_result_t *cal_result)
{
int fd, i, err;
char buf[LENGTH];
int arry[] = {CMD_W_OFFSET_X, CMD_W_OFFSET_Y, CMD_W_OFFSET_Z};
+
if (cal_result == NULL) {
ALOGE("Null pointer initcalibrate parameter\n");
return -1;
@@ -348,7 +342,8 @@ int AccelSensor::initCalibrate(int32_t handle, struct cal_result_t *cal_result)
fd = open(input_sysfs_path, O_RDWR);
if (fd >= 0) {
int para1 = 0;
- for(i = 0; i < sizeof(arry) / sizeof(int); ++i) {
+
+ for(i = 0; i < (int)ARRAY_SIZE(arry); ++i) {
para1 = SET_CMD_H(cal_result->offset[i], arry[i]);
snprintf(buf, sizeof(buf), "%d", para1);
err = write(fd, buf, strlen(buf)+1);
diff --git a/sensors/AkmSensor.h b/sensors/AkmSensor.h
deleted file mode 100644
index 35bff27..0000000
--- a/sensors/AkmSensor.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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_AKM_SENSOR_H
-#define ANDROID_AKM_SENSOR_H
-
-#include <stdint.h>
-#include <errno.h>
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#include "SensorBase.h"
-#include "InputEventReader.h"
-
-/*****************************************************************************/
-
-struct input_event;
-
-class AkmSensor : public SensorBase {
-public:
- AkmSensor();
- AkmSensor(char *name);
- virtual ~AkmSensor();
-
- enum {
- Accelerometer = 0,
- MagneticField = 1,
- Orientation = 2,
- numSensors
- };
-
- virtual int setDelay(int32_t handle, int64_t ns);
- virtual int enable(int32_t handle, int enabled);
- virtual int readEvents(sensors_event_t* data, int count);
- void processEvent(int code, int value);
-
-private:
- int update_delay();
- uint32_t mEnabled;
- uint32_t mPendingMask;
- InputEventCircularReader mInputReader;
- sensors_event_t mPendingEvents[numSensors];
- uint64_t mDelays[numSensors];
-};
-
-/*****************************************************************************/
-
-#endif // ANDROID_AKM_SENSOR_H
diff --git a/sensors/Android.mk b/sensors/Android.mk
index 5e96f94..4bd303d 100644
--- a/sensors/Android.mk
+++ b/sensors/Android.mk
@@ -1,78 +1,59 @@
-ifneq ($(filter msm8960 msm8610 msm8916 msm8909,$(TARGET_BOARD_PLATFORM)),)
-# Disable temporarily for compilling error
-ifneq ($(BUILD_TINY_ANDROID),true)
LOCAL_PATH := $(call my-dir)
-# HAL module implemenation stored in
include $(CLEAR_VARS)
-ifneq ($(filter msm8610,$(TARGET_BOARD_PLATFORM)),)
- LOCAL_MODULE := sensors.$(TARGET_BOARD_PLATFORM)
- LOCAL_CFLAGS := -DTARGET_8610
-else
- ifneq ($(filter msm8916 msm8909,$(TARGET_BOARD_PLATFORM)),)
- LOCAL_MODULE := sensors.$(TARGET_BOARD_PLATFORM)
- else
- LOCAL_MODULE := sensors.msm8930
- endif
-endif
-
-ifdef TARGET_2ND_ARCH
-LOCAL_MODULE_RELATIVE_PATH := hw
-else
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-endif
+# Export calibration library needed dependency headers
+LOCAL_COPY_HEADERS_TO := sensors/inc
+LOCAL_COPY_HEADERS := \
+ CalibrationModule.h \
+ sensors_extension.h \
+ sensors.h
-LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := \
+ sensors.cpp \
+ SensorBase.cpp \
+ LightSensor.cpp \
+ ProximitySensor.cpp \
+ CompassSensor.cpp \
+ Accelerometer.cpp \
+ Gyroscope.cpp \
+ InputEventReader.cpp \
+ CalibrationManager.cpp \
+ NativeSensorManager.cpp \
+ VirtualSensor.cpp \
+ sensors_XML.cpp
LOCAL_CFLAGS += -DLOG_TAG=\"Sensors\"
-ifeq ($(call is-board-platform,msm8960),true)
- LOCAL_CFLAGS += -DTARGET_8930
-endif
-LOCAL_C_INCLUDES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+LOCAL_C_INCLUDES := \
+ external/libxml2/include \
+ external/icu/icu4c/source/common
-LOCAL_SRC_FILES := \
- sensors.cpp \
- SensorBase.cpp \
- LightSensor.cpp \
- ProximitySensor.cpp \
- CompassSensor.cpp \
- Accelerometer.cpp \
- Gyroscope.cpp \
- InputEventReader.cpp \
- CalibrationManager.cpp \
- NativeSensorManager.cpp \
- VirtualSensor.cpp \
- sensors_XML.cpp
-
-LOCAL_C_INCLUDES += external/libxml2/include \
- external/icu/icu4c/source/common
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_SHARED_LIBRARIES := liblog libcutils libdl libxml2 libutils
+LOCAL_MODULE := sensors.msm8916
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE_TAGS := optional
+
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libcalmodule_common
LOCAL_SRC_FILES := \
- algo/common/common_wrapper.c \
- algo/common/compass/AKFS_AOC.c \
- algo/common/compass/AKFS_Device.c \
- algo/common/compass/AKFS_Direction.c \
- algo/common/compass/AKFS_VNorm.c
+ algo/common/common_wrapper.c \
+ algo/common/compass/AKFS_AOC.c \
+ algo/common/compass/AKFS_Device.c \
+ algo/common/compass/AKFS_Direction.c \
+ algo/common/compass/AKFS_VNorm.c
LOCAL_SHARED_LIBRARIES := liblog libcutils
LOCAL_MODULE_TAGS := optional
-ifdef TARGET_2ND_ARCH
-LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
-LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
-else
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)
-endif
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib
include $(BUILD_SHARED_LIBRARY)
@@ -85,6 +66,3 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)
LOCAL_SRC_FILES := calmodule.cfg
include $(BUILD_PREBUILT)
-
-endif #BUILD_TINY_ANDROID
-endif #TARGET_BOARD_PLATFORM
diff --git a/sensors/CalibrationManager.cpp b/sensors/CalibrationManager.cpp
index cb43097..e888918 100644
--- a/sensors/CalibrationManager.cpp
+++ b/sensors/CalibrationManager.cpp
@@ -38,16 +38,32 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <CalibrationModule.h>
#include "sensors.h"
#include "CalibrationManager.h"
+#include "NativeSensorManager.h"
ANDROID_SINGLETON_STATIC_INSTANCE(CalibrationManager);
+static int store_calibrate_params(struct sensor_t *sensor, struct sensors_event_t *bias)
+{
+ sensors_XML& sensor_XML(sensors_XML :: getInstance());
+ struct cal_result_t cal_result;
+ int err = 0;
+
+ cal_result.offset[0] = bias->data[0] ;
+ cal_result.offset[1] = bias->data[1] ;
+ cal_result.offset[2] = bias->data[2] ;
+ err = sensor_XML.write_sensors_params(sensor, &cal_result, CAL_DYNAMIC);
+ if (err < 0) {
+ ALOGE("write calibrate %s sensor error\n", sensor->name);
+ return err;
+ }
+
+ return 0;
+}
+
int CalibrationManager::check_algo(const sensor_cal_algo_t *list)
{
if (list->tag != SENSOR_CAL_ALGO_TAG)
return -1;
- if ((list->type < SENSOR_TYPE_ACCELEROMETER) ||
- (list->type > SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR))
- return -1;
if (list->compatible == NULL)
return -1;
if (list->module == NULL)
@@ -70,7 +86,9 @@ void CalibrationManager::loadCalLibs()
int i = 0;
int count;
int tmp;
+ struct sensor_algo_args args;
+ args.store_calibrate_params = store_calibrate_params;
algo_count = 0;
algo_list = NULL;
@@ -132,7 +150,7 @@ void CalibrationManager::loadCalLibs()
modules[i]->dso = dso;
- if (modules[i]->methods->init(modules[i])) {
+ if (modules[i]->methods->init(modules[i], &args)) {
ALOGE("init %s failed\n", modules[i]->id);
modules[i] = NULL;
continue;
@@ -222,12 +240,12 @@ const sensor_cal_algo_t* CalibrationManager::getCalAlgo(const sensor_t *s/* = NU
}
if (i != algo_count) {
- ALOGI("found exactly compatible algo for type %d", s->type);
+ ALOGI("found exactly compatible algo for %s", s->name);
return list[i];
}
if (tmp != NULL)
- ALOGI("found compatible algo for type %d", s->type);
+ ALOGI("found compatible algo for %s", s->name);
return tmp;
}
diff --git a/sensors/CalibrationModule.h b/sensors/CalibrationModule.h
index 1226c24..b9eff5a 100644
--- a/sensors/CalibrationModule.h
+++ b/sensors/CalibrationModule.h
@@ -45,7 +45,7 @@ __BEGIN_DECLS
#define TEMPERATURE_NAME "temperature"
#define PROXIMITY_NAME "proximity"
#define GRAVITY_NAME "gravity"
-#define LINEAR_ACCELERATION_NAME "liner_acceleration"
+#define LINEAR_ACCELERATION_NAME "linear_acceleration"
#define ROTATION_VECTOR_NAME "rotation_vector"
#define RELATIVE_HUMIDITY_NAME "relative_humidity"
#define AMBIENT_TEMPERATURE_NAME "ambient_temperature"
@@ -71,6 +71,7 @@ enum {
CMD_ENABLE = 0, /* Enable status changed */
CMD_DELAY, /* Polling rate changed */
CMD_BATCH, /* Batching parameter changed */
+ CMD_INIT,
};
struct sensor_cal_algo_t;
@@ -79,6 +80,8 @@ struct sensor_cal_module_t;
struct sensor_algo_args {
int enable;
int delay_ms;
+ struct sensor_t sensor;
+ int (*store_calibrate_params)(struct sensor_t *sensor, struct sensors_event_t *bias);
};
struct compass_algo_args {
@@ -86,6 +89,11 @@ struct compass_algo_args {
uint32_t reserved[16];
};
+struct gyro_algo_args {
+ struct sensor_algo_args common;
+ float bias[3];
+};
+
struct sensor_algo_methods_t {
int (*convert)(sensors_event_t *raw, sensors_event_t *result, struct sensor_algo_args *args);
/* Note that the config callback is called from a different thread as convert */
@@ -93,7 +101,7 @@ struct sensor_algo_methods_t {
};
struct sensor_cal_methods_t {
- int (*init)(const struct sensor_cal_module_t* module);
+ int (*init)(const struct sensor_cal_module_t* module, struct sensor_algo_args *args);
void (*deinit)();
/* Return 0 on success */
int (*get_algo_list)(const struct sensor_cal_algo_t **algo);
diff --git a/sensors/CompassSensor.cpp b/sensors/CompassSensor.cpp
index 1f9ba3a..c380fe4 100644
--- a/sensors/CompassSensor.cpp
+++ b/sensors/CompassSensor.cpp
@@ -34,7 +34,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <dirent.h>
#include <sys/select.h>
#include <cutils/log.h>
-
+#include <cutils/properties.h>
#include "CompassSensor.h"
#include "sensors.h"
@@ -56,8 +56,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/*****************************************************************************/
CompassSensor::CompassSensor(struct SensorContext *context)
: SensorBase(NULL, NULL, context),
- mEnabled(0),
- mInputReader(6),
+ mInputReader(4),
mHasPendingEvent(false),
mEnabledTime(0),
res(CONVERT_MAG)
@@ -89,6 +88,15 @@ int CompassSensor::enable(int32_t, int en) {
int flags = en ? 1 : 0;
compass_algo_args arg;
arg.common.enable = flags;
+ char propBuf[PROPERTY_VALUE_MAX];
+
+ property_get("sensors.compass.loopback", propBuf, "0");
+ if (strcmp(propBuf, "1") == 0) {
+ ALOGE("sensors.compass.loopback is set");
+ mEnabled = flags;
+ mEnabledTime = 0;
+ return 0;
+ }
if (flags != mEnabled) {
int fd;
@@ -124,7 +132,7 @@ int CompassSensor::enable(int32_t, int en) {
}
bool CompassSensor::hasPendingEvents() const {
- return mHasPendingEvent;
+ return mHasPendingEvent || mHasPendingMetadata;
}
int CompassSensor::setDelay(int32_t, int64_t delay_ns)
@@ -133,6 +141,12 @@ int CompassSensor::setDelay(int32_t, int64_t delay_ns)
int delay_ms = delay_ns / 1000000;
compass_algo_args arg;
arg.common.delay_ms = delay_ms;
+ char propBuf[PROPERTY_VALUE_MAX];
+ property_get("sensors.compass.loopback", propBuf, "0");
+ if (strcmp(propBuf, "1") == 0) {
+ ALOGE("sensors.compass.loopback is set");
+ return 0;
+ }
if ((algo != NULL) && (algo->methods->config != NULL)) {
if (algo->methods->config(CMD_DELAY, (sensor_algo_args*)&arg)) {
@@ -145,7 +159,7 @@ int CompassSensor::setDelay(int32_t, int64_t delay_ns)
fd = open(input_sysfs_path, O_RDWR);
if (fd >= 0) {
char buf[80];
- sprintf(buf, "%d", delay_ms);
+ snprintf(buf, sizeof(buf), "%d", delay_ms);
write(fd, buf, strlen(buf)+1);
close(fd);
return 0;
@@ -165,6 +179,13 @@ int CompassSensor::readEvents(sensors_event_t* data, int count)
return mEnabled ? 1 : 0;
}
+ if (mHasPendingMetadata) {
+ mHasPendingMetadata--;
+ meta_data.timestamp = getTimestamp();
+ *data = meta_data;
+ return mEnabled ? 1 : 0;
+ }
+
ssize_t n = mInputReader.fill(data_fd);
if (n < 0)
return n;
@@ -188,51 +209,56 @@ again:
mPendingEvent.magnetic.z = value * res;
}
} else if (type == EV_SYN) {
- if (event->code == SYN_TIME_SEC) {
- mUseAbsTimeStamp = true;
- report_time = event->value*1000000000LL;
- } else if (event->code == SYN_TIME_NSEC) {
- mUseAbsTimeStamp = true;
- mPendingEvent.timestamp = report_time+event->value;
- } else if (mEnabled) {
- if (!mUseAbsTimeStamp) {
- ALOGE("CompassSensor: timestamp not received");
- } else if (mPendingEvent.timestamp >= mEnabledTime) {
- raw = mPendingEvent;
-
- if (algo != NULL) {
- if (algo->methods->convert(&raw, &result, NULL)) {
- ALOGW("Calibration in progress...");
+ switch (event->code) {
+ case SYN_TIME_SEC:
+ mUseAbsTimeStamp = true;
+ report_time = event->value*1000000000LL;
+ break;
+ case SYN_TIME_NSEC:
+ mUseAbsTimeStamp = true;
+ mPendingEvent.timestamp = report_time+event->value;
+ break;
+ case SYN_REPORT:
+ if (mUseAbsTimeStamp != true) {
+ mPendingEvent.timestamp = timevalToNano(event->time);
+ }
+ if (mEnabled) {
+ raw = mPendingEvent;
+
+ if (algo != NULL) {
+ if (algo->methods->convert(&raw, &result, NULL)) {
+ ALOGW("Calibration in progress...");
+ result = raw;
+ result.magnetic.status = SENSOR_STATUS_UNRELIABLE;
+ }
+ } else {
result = raw;
- result.magnetic.status = SENSOR_STATUS_UNRELIABLE;
}
- } else {
- result = raw;
- }
- *data = result;
- data->version = sizeof(sensors_event_t);
- data->sensor = mPendingEvent.sensor;
- data->type = SENSOR_TYPE_MAGNETIC_FIELD;
- data->timestamp = mPendingEvent.timestamp;
-
- /* The raw data is stored inside sensors_event_t.data after
- * sensors_event_t.magnetic. Notice that the raw data is
- * required to composite the virtual sensor uncalibrated
- * magnetic field sensor.
- *
- * data[0~2]: calibrated magnetic field data.
- * data[3]: magnetic field data accuracy.
- * data[4~6]: uncalibrated magnetic field data.
- */
- data->data[4] = mPendingEvent.data[0];
- data->data[5] = mPendingEvent.data[1];
- data->data[6] = mPendingEvent.data[2];
-
- data++;
- numEventReceived++;
- }
- count--;
+ *data = result;
+ data->version = sizeof(sensors_event_t);
+ data->sensor = mPendingEvent.sensor;
+ data->type = SENSOR_TYPE_MAGNETIC_FIELD;
+ data->timestamp = mPendingEvent.timestamp;
+
+ /* The raw data is stored inside sensors_event_t.data after
+ * sensors_event_t.magnetic. Notice that the raw data is
+ * required to composite the virtual sensor uncalibrated
+ * magnetic field sensor.
+ *
+ * data[0~2]: calibrated magnetic field data.
+ * data[3]: magnetic field data accuracy.
+ * data[4~6]: uncalibrated magnetic field data.
+ */
+ data->data[4] = mPendingEvent.data[0];
+ data->data[5] = mPendingEvent.data[1];
+ data->data[6] = mPendingEvent.data[2];
+
+ data++;
+ numEventReceived++;
+ count--;
+ }
+ break;
}
} else {
ALOGE("CompassSensor: unknown event (type=%d, code=%d)",
diff --git a/sensors/CompassSensor.h b/sensors/CompassSensor.h
index d33fdb1..5dba355 100644
--- a/sensors/CompassSensor.h
+++ b/sensors/CompassSensor.h
@@ -43,12 +43,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct input_event;
class CompassSensor : public SensorBase {
- int mEnabled;
InputEventCircularReader mInputReader;
sensors_event_t mPendingEvent;
bool mHasPendingEvent;
- char input_sysfs_path[PATH_MAX];
- int input_sysfs_path_len;
int64_t mEnabledTime;
float res;
diff --git a/sensors/GyroSensor.h b/sensors/GyroSensor.h
index 0fa2618..d4b58a1 100644
--- a/sensors/GyroSensor.h
+++ b/sensors/GyroSensor.h
@@ -31,15 +31,14 @@
struct input_event;
class GyroSensor : public SensorBase {
- int mEnabled;
InputEventCircularReader mInputReader;
sensors_event_t mPendingEvent;
+ sensor_t mSensor;
bool mHasPendingEvent;
- char input_sysfs_path[PATH_MAX];
- int input_sysfs_path_len;
int64_t mEnabledTime;
int setInitialState();
+ int read_dynamic_calibrate_params(struct sensor_t *sensor);
public:
GyroSensor();
diff --git a/sensors/Gyroscope.cpp b/sensors/Gyroscope.cpp
index 9841dc6..ff299e4 100644
--- a/sensors/Gyroscope.cpp
+++ b/sensors/Gyroscope.cpp
@@ -47,8 +47,7 @@
GyroSensor::GyroSensor()
: SensorBase(NULL, GYRO_INPUT_DEV_NAME),
- mEnabled(0),
- mInputReader(6),
+ mInputReader(4),
mHasPendingEvent(false),
mEnabledTime(0)
{
@@ -56,24 +55,20 @@ GyroSensor::GyroSensor()
mPendingEvent.sensor = SENSORS_GYROSCOPE_HANDLE;
mPendingEvent.type = SENSOR_TYPE_GYROSCOPE;
memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
+ mPendingEvent.gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
if (data_fd) {
strlcpy(input_sysfs_path, "/sys/class/input/", sizeof(input_sysfs_path));
strlcat(input_sysfs_path, input_name, sizeof(input_sysfs_path));
-#ifdef TARGET_8610
- strlcat(input_sysfs_path, "/device/", sizeof(input_sysfs_path));
-#else
strlcat(input_sysfs_path, "/device/device/", sizeof(input_sysfs_path));
-#endif
input_sysfs_path_len = strlen(input_sysfs_path);
enable(0, 1);
}
}
GyroSensor::GyroSensor(struct SensorContext *context)
- : SensorBase(NULL, NULL),
- mEnabled(0),
- mInputReader(6),
+ : SensorBase(NULL, NULL, context),
+ mInputReader(4),
mHasPendingEvent(false),
mEnabledTime(0)
{
@@ -81,18 +76,21 @@ GyroSensor::GyroSensor(struct SensorContext *context)
mPendingEvent.sensor = context->sensor->handle;
mPendingEvent.type = SENSOR_TYPE_GYROSCOPE;
memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
+ mPendingEvent.gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
+
data_fd = context->data_fd;
strlcpy(input_sysfs_path, context->enable_path, sizeof(input_sysfs_path));
input_sysfs_path_len = strlen(input_sysfs_path);
mUseAbsTimeStamp = false;
+ mSensor = *(context->sensor);
+ read_dynamic_calibrate_params(&mSensor);
enable(0, 1);
}
GyroSensor::GyroSensor(char *name)
: SensorBase(NULL, GYRO_INPUT_DEV_NAME),
- mEnabled(0),
- mInputReader(6),
+ mInputReader(4),
mHasPendingEvent(false),
mEnabledTime(0)
{
@@ -100,6 +98,7 @@ GyroSensor::GyroSensor(char *name)
mPendingEvent.sensor = SENSORS_GYROSCOPE_HANDLE;
mPendingEvent.type = SENSOR_TYPE_GYROSCOPE;
memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
+ mPendingEvent.gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
if (data_fd) {
strlcpy(input_sysfs_path, SYSFS_CLASS, sizeof(input_sysfs_path));
@@ -142,6 +141,7 @@ int GyroSensor::enable(int32_t, int en) {
property_get("sensors.gyro.loopback", propBuf, "0");
if (strcmp(propBuf, "1") == 0) {
mEnabled = flags;
+ mEnabledTime = 0;
ALOGE("sensors.gyro.loopback is set");
return 0;
}
@@ -157,13 +157,13 @@ int GyroSensor::enable(int32_t, int en) {
if (flags) {
buf[0] = '1';
mEnabledTime = getTimestamp() + IGNORE_EVENT_TIME;
+ sysclk_sync_offset = getClkOffset();
} else {
buf[0] = '0';
}
err = write(fd, buf, sizeof(buf));
close(fd);
mEnabled = flags;
- setInitialState();
return 0;
}
return -1;
@@ -172,7 +172,7 @@ int GyroSensor::enable(int32_t, int en) {
}
bool GyroSensor::hasPendingEvents() const {
- return mHasPendingEvent;
+ return mHasPendingEvent || mHasPendingMetadata;
}
int GyroSensor::setDelay(int32_t, int64_t delay_ns)
@@ -190,7 +190,7 @@ int GyroSensor::setDelay(int32_t, int64_t delay_ns)
fd = open(input_sysfs_path, O_RDWR);
if (fd >= 0) {
char buf[80];
- sprintf(buf, "%d", delay_ms);
+ snprintf(buf, sizeof(buf), "%d", delay_ms);
write(fd, buf, strlen(buf)+1);
close(fd);
return 0;
@@ -210,12 +210,20 @@ int GyroSensor::readEvents(sensors_event_t* data, int count)
return mEnabled ? 1 : 0;
}
+ if (mHasPendingMetadata) {
+ mHasPendingMetadata--;
+ meta_data.timestamp = getTimestamp();
+ *data = meta_data;
+ return mEnabled ? 1 : 0;
+ }
+
ssize_t n = mInputReader.fill(data_fd);
if (n < 0)
return n;
int numEventReceived = 0;
input_event const* event;
+ sensors_event_t raw, result;
#if FETCH_FULL_EVENT_BEFORE_RETURN
again:
@@ -246,18 +254,43 @@ again:
}
break;
case SYN_REPORT:
- {
- if (mEnabled && mUseAbsTimeStamp) {
- if(mPendingEvent.timestamp >= mEnabledTime) {
- *data++ = mPendingEvent;
- numEventReceived++;
- }
- count--;
- mUseAbsTimeStamp = false;
- } else {
- ALOGE_IF(!mUseAbsTimeStamp, "GyroSensor:timestamp not received");
+ if(mUseAbsTimeStamp != true) {
+ mPendingEvent.timestamp = timevalToNano(event->time);
+ }
+ if (!mEnabled) {
+ break;
+ }
+
+ mPendingEvent.timestamp -= sysclk_sync_offset;
+ raw = mPendingEvent;
+ if (algo != NULL) {
+ if (algo->methods->convert(&raw, &result, NULL)) {
+ ALOGE("Calibrated failed\n");
+ result = raw;
}
+ } else {
+ result = raw;
}
+ *data = result;
+ data->version = sizeof(sensors_event_t);
+ data->sensor = mPendingEvent.sensor;
+ data->type = SENSOR_TYPE_GYROSCOPE;
+ data->timestamp = mPendingEvent.timestamp;
+ /* The raw data is stored inside sensors_event_t.data after
+ * sensors_event_t.gyroscope. Notice that the raw data is
+ * required to composite the virtual sensor uncalibrated
+ * gyroscope field sensor.
+ *
+ * data[0~2]: calibrated gyroscope field data.
+ * data[3]: gyroscope field data accuracy.
+ * data[4~6]: uncalibrated gyroscope field data.
+ */
+ data->data[4] = mPendingEvent.data[0];
+ data->data[5] = mPendingEvent.data[1];
+ data->data[6] = mPendingEvent.data[2];
+ data++;
+ numEventReceived++;
+ count--;
break;
}
} else {
@@ -280,3 +313,35 @@ again:
return numEventReceived;
}
+int GyroSensor::read_dynamic_calibrate_params(struct sensor_t *sensor)
+{
+ sensors_XML& sensor_XML(sensors_XML :: getInstance());
+ struct cal_result_t cal_result;
+ int err = 0;
+
+ err = sensor_XML.read_sensors_params(sensor, &cal_result, 1);
+ if (err < 0) {
+ ALOGE("read dynamic calibrate %s sensor error\n", sensor->name);
+ cal_result.offset[0] = 0;
+ cal_result.offset[1] = 0;
+ cal_result.offset[2] = 0;
+ }
+
+ gyro_algo_args arg;
+
+ arg.bias[0] = cal_result.offset[0];
+ arg.bias[1] = cal_result.offset[1];
+ arg.bias[2] = cal_result.offset[2];
+ arg.common.sensor = *sensor;
+
+ if (algo != NULL) {
+ if (algo->methods->config(CMD_INIT, (sensor_algo_args*)&arg)) {
+ ALOGE("Init gyro calibration parameters failed\n");
+ return -1;
+ }
+ } else {
+ ALOGE("Init gyro algo error\n");
+ }
+
+ return 0;
+}
diff --git a/sensors/LightSensor.cpp b/sensors/LightSensor.cpp
index f3f74db..8f5e51e 100644
--- a/sensors/LightSensor.cpp
+++ b/sensors/LightSensor.cpp
@@ -76,7 +76,6 @@ static const int input_report_type[SUPPORTED_LSENSOR_COUNT] = {
LightSensor::LightSensor()
: SensorBase(NULL, NULL),
- mEnabled(0),
mInputReader(4),
mHasPendingEvent(false),
sensor_index(-1)
@@ -111,7 +110,6 @@ LightSensor::LightSensor()
LightSensor::LightSensor(char *name)
: SensorBase(NULL, data_device_name[GENERIC_LS]),
- mEnabled(0),
mInputReader(4),
mHasPendingEvent(false),
sensor_index(GENERIC_LS)
@@ -132,8 +130,7 @@ LightSensor::LightSensor(char *name)
}
LightSensor::LightSensor(struct SensorContext *context)
- : SensorBase(NULL, NULL),
- mEnabled(0),
+ : SensorBase(NULL, NULL, context),
mInputReader(4),
mHasPendingEvent(false),
sensor_index(GENERIC_LS)
@@ -147,7 +144,6 @@ LightSensor::LightSensor(struct SensorContext *context)
strlcpy(input_sysfs_path, context->enable_path, sizeof(input_sysfs_path));
input_sysfs_path_len = strlen(input_sysfs_path);
mUseAbsTimeStamp = false;
- enable(0, 1);
}
LightSensor::~LightSensor() {
@@ -217,12 +213,14 @@ int LightSensor::enable(int32_t, int en)
ALOGE("open %s failed.(%s)\n", input_sysfs_path, strerror(errno));
return -1;
}
+ } else if (flags) { /* already enabled */
+ mHasPendingEvent = true;
}
return 0;
}
bool LightSensor::hasPendingEvents() const {
- return mHasPendingEvent;
+ return mHasPendingEvent || mHasPendingMetadata;
}
int LightSensor::readEvents(sensors_event_t* data, int count)
@@ -237,6 +235,13 @@ int LightSensor::readEvents(sensors_event_t* data, int count)
return mEnabled ? 1 : 0;
}
+ if (mHasPendingMetadata) {
+ mHasPendingMetadata--;
+ meta_data.timestamp = getTimestamp();
+ *data = meta_data;
+ return mEnabled ? 1 : 0;
+ }
+
ssize_t n = mInputReader.fill(data_fd);
if (n < 0)
return n;
@@ -251,33 +256,26 @@ int LightSensor::readEvents(sensors_event_t* data, int count)
mPendingEvent.light = convertEvent(event->value);
}
} else if (type == EV_SYN) {
- switch ( event->code ){
+ switch ( event->code ) {
case SYN_TIME_SEC:
- {
- mUseAbsTimeStamp = true;
- report_time = event->value*1000000000LL;
- }
- break;
+ mUseAbsTimeStamp = true;
+ report_time = event->value*1000000000LL;
+ break;
case SYN_TIME_NSEC:
- {
- mUseAbsTimeStamp = true;
- mPendingEvent.timestamp = report_time+event->value;
- }
- break;
+ mUseAbsTimeStamp = true;
+ mPendingEvent.timestamp = report_time+event->value;
+ break;
case SYN_REPORT:
- {
- if(mUseAbsTimeStamp != true) {
- mPendingEvent.timestamp = timevalToNano(event->time);
- }
- if (mEnabled) {
- *data++ = mPendingEvent;
- count--;
- numEventReceived++;
- }
+ if(mUseAbsTimeStamp != true) {
+ mPendingEvent.timestamp = timevalToNano(event->time);
+ }
+ if (mEnabled) {
+ *data++ = mPendingEvent;
+ count--;
+ numEventReceived++;
}
- break;
+ break;
}
-
} else {
ALOGE("LightSensor: unknown event (type=%d, code=%d)",
type, event->code);
diff --git a/sensors/LightSensor.h b/sensors/LightSensor.h
index b1f53ee..f0dd893 100644
--- a/sensors/LightSensor.h
+++ b/sensors/LightSensor.h
@@ -31,12 +31,9 @@
struct input_event;
class LightSensor : public SensorBase {
- int mEnabled;
InputEventCircularReader mInputReader;
sensors_event_t mPendingEvent;
bool mHasPendingEvent;
- char input_sysfs_path[PATH_MAX];
- int input_sysfs_path_len;
int sensor_index;
int setInitialState();
diff --git a/sensors/NativeSensorManager.cpp b/sensors/NativeSensorManager.cpp
index 358b9dc..e81acc2 100644
--- a/sensors/NativeSensorManager.cpp
+++ b/sensors/NativeSensorManager.cpp
@@ -1,5 +1,5 @@
/*--------------------------------------------------------------------------
-Copyright (c) 2014, The Linux Foundation. All rights reserved.
+Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -27,6 +27,7 @@ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------*/
#include "NativeSensorManager.h"
+#include <unistd.h>
ANDROID_SINGLETON_STATIC_INSTANCE(NativeSensorManager);
@@ -34,14 +35,18 @@ enum {
ORIENTATION = 0,
PSEUDO_GYROSCOPE,
ROTATION_VECTOR,
+ GAME_ROTATION_VECTOR,
LINEAR_ACCELERATION,
GRAVITY,
+ POCKET,
VIRTUAL_SENSOR_COUNT,
};
+char NativeSensorManager::virtualSensorName[VIRTUAL_SENSOR_COUNT][SYSFS_MAXLEN];
+
const struct sensor_t NativeSensorManager::virtualSensorList [VIRTUAL_SENSOR_COUNT] = {
[ORIENTATION] = {
- .name = "oem-orientation",
+ .name = virtualSensorName[ORIENTATION],
.vendor = "oem",
.version = 1,
.handle = '_dmy',
@@ -56,13 +61,13 @@ const struct sensor_t NativeSensorManager::virtualSensorList [VIRTUAL_SENSOR_COU
.stringType = NULL,
.requiredPermission = NULL,
.maxDelay = 0,
- .flags = 0,
+ .flags = SENSOR_FLAG_CONTINUOUS_MODE,
#endif
.reserved = {},
},
[PSEUDO_GYROSCOPE] = {
- .name = "oem-pseudo-gyro",
+ .name = virtualSensorName[PSEUDO_GYROSCOPE],
.vendor = "oem",
.version = 1,
.handle = '_dmy',
@@ -77,13 +82,13 @@ const struct sensor_t NativeSensorManager::virtualSensorList [VIRTUAL_SENSOR_COU
.stringType = NULL,
.requiredPermission = NULL,
.maxDelay = 0,
- .flags = 0,
+ .flags = SENSOR_FLAG_CONTINUOUS_MODE,
#endif
.reserved = {},
},
[ROTATION_VECTOR] = {
- .name = "oem-rotation-vector",
+ .name = virtualSensorName[ROTATION_VECTOR],
.vendor = "oem",
.version = 1,
.handle = '_dmy',
@@ -98,13 +103,34 @@ const struct sensor_t NativeSensorManager::virtualSensorList [VIRTUAL_SENSOR_COU
.stringType = NULL,
.requiredPermission = NULL,
.maxDelay = 0,
- .flags = 0,
+ .flags = SENSOR_FLAG_CONTINUOUS_MODE,
+#endif
+ .reserved = {},
+ },
+
+ [GAME_ROTATION_VECTOR] = {
+ .name = "qti-game-rotation-vector",
+ .vendor = "QTI",
+ .version = 1,
+ .handle = '_dmy',
+ .type = SENSOR_TYPE_GAME_ROTATION_VECTOR,
+ .maxRange = 1,
+ .resolution = 1.0f / (1<<24),
+ .power = 1,
+ .minDelay = 10000,
+ .fifoReservedEventCount = 0,
+ .fifoMaxEventCount = 0,
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+ .stringType = NULL,
+ .requiredPermission = NULL,
+ .maxDelay = 0,
+ .flags = SENSOR_FLAG_CONTINUOUS_MODE,
#endif
.reserved = {},
},
[LINEAR_ACCELERATION] = {
- .name = "oem-linear-acceleration",
+ .name = virtualSensorName[LINEAR_ACCELERATION],
.vendor = "oem",
.version = 1,
.handle = '_dmy',
@@ -119,13 +145,13 @@ const struct sensor_t NativeSensorManager::virtualSensorList [VIRTUAL_SENSOR_COU
.stringType = NULL,
.requiredPermission = NULL,
.maxDelay = 0,
- .flags = 0,
+ .flags = SENSOR_FLAG_CONTINUOUS_MODE,
#endif
.reserved = {},
},
[GRAVITY] = {
- .name = "oem-gravity",
+ .name = virtualSensorName[GRAVITY],
.vendor = "oem",
.version = 1,
.handle = '_dmy',
@@ -140,13 +166,74 @@ const struct sensor_t NativeSensorManager::virtualSensorList [VIRTUAL_SENSOR_COU
.stringType = NULL,
.requiredPermission = NULL,
.maxDelay = 0,
- .flags = 0,
+ .flags = SENSOR_FLAG_CONTINUOUS_MODE,
+#endif
+ .reserved = {},
+ },
+
+ [POCKET] = {
+ .name = virtualSensorName[POCKET],
+ .vendor = "oem",
+ .version = 1,
+ .handle = '_dmy',
+ .type = SENSOR_TYPE_POCKET,
+ .maxRange = 1.0f,
+ .resolution = 1.0f,
+ .power = 1,
+ .minDelay = 5000,
+ .fifoReservedEventCount = 0,
+ .fifoMaxEventCount = 0,
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+ .stringType = "com.oem.pocketdetector",
+ .requiredPermission = NULL,
+ .maxDelay = 0,
+ .flags = SENSOR_FLAG_ON_CHANGE_MODE,
#endif
.reserved = {},
},
};
-int NativeSensorManager::initVirtualSensor(struct SensorContext *ctx, int handle, int64_t dep,
+int NativeSensorManager::addDependency(struct SensorContext *ctx, int handle)
+{
+ struct SensorContext *dep;
+ struct listnode *node;
+ struct SensorRefMap *ref, *item;
+
+ if (!ctx->is_virtual) {
+ ALOGE("Only available for virtual sensors.\n");
+ return -1;
+ }
+
+ dep = getInfoByHandle(handle);
+
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+ if (ctx->sensor->maxDelay == 0)
+ ctx->sensor->maxDelay = dep->sensor->maxDelay;
+ else
+ ctx->sensor->maxDelay = dep->sensor->maxDelay < ctx->sensor->maxDelay ?
+ dep->sensor->maxDelay : ctx->sensor->maxDelay;
+#endif
+
+ if (dep != NULL) {
+ list_for_each(node, &ctx->dep_list) {
+ ref = node_to_item(node, struct SensorRefMap, list);
+ if (ref->ctx == dep) {
+ ALOGW("The dependency already present");
+ return 0;
+ }
+ }
+
+ item = new SensorRefMap;
+ item->ctx = dep;
+ list_add_tail(&ctx->dep_list, &item->list);
+
+ return 0;
+ }
+
+ return -1;
+}
+
+int NativeSensorManager::initVirtualSensor(struct SensorContext *ctx, int handle,
struct sensor_t info)
{
CalibrationManager& cm(CalibrationManager::getInstance());
@@ -162,20 +249,10 @@ int NativeSensorManager::initVirtualSensor(struct SensorContext *ctx, int handle
ctx->sensor->handle = handle;
ctx->driver = new VirtualSensor(ctx);
ctx->data_fd = -1;
- ctx->data_path = NULL;
- ctx->enable_path = NULL;
ctx->is_virtual = true;
- for (i = 0; i < sizeof(dep) * 8; i++) {
- if (dep & (1ULL << i)) {
- ref = getInfoByType(i);
- if (ref != NULL) {
- item = new SensorRefMap;
- item->ctx = ref;
- list_add_tail(&ctx->dep_list, &item->list);
- }
- }
- }
+ memset(ctx->enable_path, 0, sizeof(ctx->enable_path));
+ memset(ctx->data_path, 0, sizeof(ctx->data_path));
type_map.add(ctx->sensor->type, ctx);
handle_map.add(ctx->sensor->handle, ctx);
@@ -185,18 +262,29 @@ int NativeSensorManager::initVirtualSensor(struct SensorContext *ctx, int handle
const struct SysfsMap NativeSensorManager::node_map[] = {
- {offsetof(struct sensor_t, name), SYSFS_NAME, TYPE_STRING},
- {offsetof(struct sensor_t, vendor), SYSFS_VENDOR, TYPE_STRING},
- {offsetof(struct sensor_t, version), SYSFS_VERSION, TYPE_INTEGER},
- {offsetof(struct sensor_t, type), SYSFS_TYPE, TYPE_INTEGER},
- {offsetof(struct sensor_t, maxRange), SYSFS_MAXRANGE, TYPE_FLOAT},
- {offsetof(struct sensor_t, resolution), SYSFS_RESOLUTION, TYPE_FLOAT},
- {offsetof(struct sensor_t, power), SYSFS_POWER, TYPE_FLOAT},
- {offsetof(struct sensor_t, minDelay), SYSFS_MINDELAY, TYPE_INTEGER},
+ {offsetof(struct sensor_t, name), SYSFS_NAME, TYPE_STRING, 1},
+ {offsetof(struct sensor_t, vendor), SYSFS_VENDOR, TYPE_STRING, 1},
+ {offsetof(struct sensor_t, version), SYSFS_VERSION, TYPE_INTEGER, 1},
+ {offsetof(struct sensor_t, type), SYSFS_TYPE, TYPE_INTEGER, 1},
+ {offsetof(struct sensor_t, maxRange), SYSFS_MAXRANGE, TYPE_FLOAT, 1},
+ {offsetof(struct sensor_t, resolution), SYSFS_RESOLUTION, TYPE_FLOAT, 1},
+ {offsetof(struct sensor_t, power), SYSFS_POWER, TYPE_FLOAT, 1},
+ {offsetof(struct sensor_t, minDelay), SYSFS_MINDELAY, TYPE_INTEGER, 1},
+ {offsetof(struct sensor_t, fifoReservedEventCount), SYSFS_FIFORESVCNT, TYPE_INTEGER, 0},
+ {offsetof(struct sensor_t, fifoMaxEventCount), SYSFS_FIFOMAXCNT, TYPE_INTEGER, 0},
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+#if defined(__LP64__)
+ {offsetof(struct sensor_t, maxDelay), SYSFS_MAXDELAY, TYPE_INTEGER64, 0},
+ {offsetof(struct sensor_t, flags), SYSFS_FLAGS, TYPE_INTEGER64, 0},
+#else
+ {offsetof(struct sensor_t, maxDelay), SYSFS_MAXDELAY, TYPE_INTEGER, 0},
+ {offsetof(struct sensor_t, flags), SYSFS_FLAGS, TYPE_INTEGER, 0},
+#endif
+#endif
};
NativeSensorManager::NativeSensorManager():
- mSensorCount(0), type_map(NULL), handle_map(NULL), fd_map(NULL)
+ mSensorCount(0), mScanned(false), mEventCount(0), type_map(NULL), handle_map(NULL), fd_map(NULL)
{
int i;
@@ -236,19 +324,23 @@ NativeSensorManager::~NativeSensorManager()
delete context[i].driver;
}
- list_for_each_safe(node, n, &context[i].listener) {
- item = node_to_item(node, struct SensorRefMap, list);
- if (item != NULL) {
- list_remove(&item->list);
- delete item;
+ if (!list_empty(&(context[i].listener))) {
+ list_for_each_safe(node, n, &context[i].listener) {
+ item = node_to_item(node, struct SensorRefMap, list);
+ if (item != NULL) {
+ list_remove(&item->list);
+ delete item;
+ }
}
}
- list_for_each_safe(node, n, &context[i].dep_list) {
- item = node_to_item(node, struct SensorRefMap, list);
- if (item != NULL) {
- list_remove(&item->list);
- delete item;
+ if (!list_empty(&(context[i].dep_list))) {
+ list_for_each_safe(node, n, &context[i].dep_list) {
+ item = node_to_item(node, struct SensorRefMap, list);
+ if (item != NULL) {
+ list_remove(&item->list);
+ delete item;
+ }
}
}
}
@@ -274,6 +366,14 @@ void NativeSensorManager::dump()
context[i].delay_ns,
context[i].enable);
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+ ALOGI("minDelay=%d maxDelay=%d flags=%d\n",
+ context[i].sensor->minDelay,
+ context[i].sensor->maxDelay,
+ context[i].sensor->flags);
+#endif
+
+
ALOGI("Listener:");
list_for_each(node, &context[i].listener) {
ref = node_to_item(node, struct SensorRefMap, list);
@@ -290,57 +390,34 @@ void NativeSensorManager::dump()
ALOGI("\n");
}
+void NativeSensorManager::compositeVirtualSensorName(const char *sensor_name, char *chip_name, int type)
+{
+ char *save_ptr;
+ const char *token;
+ char temp[SYSFS_MAXLEN];
+
+ strlcpy(temp, sensor_name, SYSFS_MAXLEN);
+ token = strtok_r(temp, "-_ ", &save_ptr);
+ if (token == NULL)
+ token = "";
+ strlcpy(chip_name, token, SYSFS_MAXLEN);
+ strlcat(chip_name, "-", SYSFS_MAXLEN);
+ strlcat(chip_name, type_to_name(type), SYSFS_MAXLEN);
+}
+
int NativeSensorManager::getDataInfo() {
- struct dirent **namelist;
- char *file;
- char path[PATH_MAX];
- char name[80];
- int nNodes;
int i, j;
- int fd = -1;
struct SensorContext *list;
int has_acc = 0;
int has_compass = 0;
int has_gyro = 0;
- int event_count = 0;
+ int has_light = 0;
+ int has_proximity = 0;
struct sensor_t sensor_mag;
-
- strlcpy(path, EVENT_PATH, sizeof(path));
- file = path + strlen(EVENT_PATH);
- nNodes = scandir(path, &namelist, 0, alphasort);
- if (nNodes < 0) {
- ALOGE("scan %s failed.(%s)\n", EVENT_PATH, strerror(errno));
- return -1;
- }
-
- for (event_count = 0, j = 0; (j < nNodes) && (j < MAX_SENSORS); j++) {
- if (namelist[j]->d_type != DT_CHR) {
- continue;
- }
-
- strlcpy(file, namelist[j]->d_name, sizeof(path) - strlen(EVENT_PATH));
-
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- ALOGE("open %s failed(%s)", path, strerror(errno));
- continue;
- }
-
- if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
- name[0] = '\0';
- }
-
- strlcpy(event_list[event_count].data_name, name, sizeof(event_list[0].data_name));
- strlcpy(event_list[event_count].data_path, path, sizeof(event_list[0].data_path));
- close(fd);
- event_count++;
- }
-
- for (j = 0; j <nNodes; j++ ) {
- free(namelist[j]);
- }
-
- free(namelist);
+ struct sensor_t sensor_acc;
+ struct sensor_t sensor_light;
+ struct sensor_t sensor_proximity;
+ struct sensor_t sensor_gyro;
mSensorCount = getSensorListInner();
for (i = 0; i < mSensorCount; i++) {
@@ -350,22 +427,11 @@ int NativeSensorManager::getDataInfo() {
item = new struct SensorRefMap;
item->ctx = list;
+ /* hardware sensor depend on itself */
list_add_tail(&list->dep_list, &item->list);
- /* Initialize data_path and data_fd */
- for (j = 0; (j < event_count) && (j < MAX_SENSORS); j++) {
- if (strcmp(list->sensor->name, event_list[j].data_name) == 0) {
- list->data_path = strdup(event_list[j].data_path);
- break;
- }
-
- if (strcmp(event_list[j].data_name, type_to_name(list->sensor->type)) == 0) {
- list->data_path = strdup(event_list[j].data_path);
- }
- }
-
- if (list->data_path != NULL)
- list->data_fd = open(list->data_path,O_RDONLY | O_CLOEXEC | O_NONBLOCK);
+ if (strlen(list->data_path) != 0)
+ list->data_fd = open(list->data_path, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
else
list->data_fd = -1;
@@ -382,6 +448,7 @@ int NativeSensorManager::getDataInfo() {
case SENSOR_TYPE_ACCELEROMETER:
has_acc = 1;
list->driver = new AccelSensor(list);
+ sensor_acc = *(list->sensor);
break;
case SENSOR_TYPE_MAGNETIC_FIELD:
has_compass = 1;
@@ -389,14 +456,27 @@ int NativeSensorManager::getDataInfo() {
sensor_mag = *(list->sensor);
break;
case SENSOR_TYPE_PROXIMITY:
+ has_proximity = 1;
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+ /* reporting mode fix up */
+ list->sensor->flags |= SENSOR_FLAG_ON_CHANGE_MODE;
+#endif
list->driver = new ProximitySensor(list);
+ sensor_proximity = *(list->sensor);
break;
case SENSOR_TYPE_LIGHT:
+ has_light = 1;
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+ /* reporting mode fix up */
+ list->sensor->flags |= SENSOR_FLAG_ON_CHANGE_MODE;
+#endif
list->driver = new LightSensor(list);
+ sensor_light = *(list->sensor);
break;
case SENSOR_TYPE_GYROSCOPE:
has_gyro = 1;
list->driver = new GyroSensor(list);
+ sensor_gyro = *(list->sensor);
break;
default:
list->driver = NULL;
@@ -406,66 +486,116 @@ int NativeSensorManager::getDataInfo() {
initCalibrate(list);
}
-
/* Some vendor or the reference design implements some virtual sensors
* or pseudo sensors. These sensors are required by some of the applications.
* Here we check the CalibratoinManager to decide whether to enable them.
*/
CalibrationManager &cm(CalibrationManager::getInstance());
struct SensorRefMap *ref;
+ char *chip;
- if (has_compass) {
- /* The uncalibrated magnetic field sensor shares the same vendor/name as the
- * calibrated one. */
- sensor_mag.type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
+ if (has_light && has_proximity) {
+ compositeVirtualSensorName(sensor_proximity.name, virtualSensorName[POCKET], SENSOR_TYPE_POCKET);
+ ALOGD("pocket virtual sensor name changed to %s\n", virtualSensorName[POCKET]);
if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount),
- 1ULL << SENSOR_TYPE_MAGNETIC_FIELD, sensor_mag)) {
+ virtualSensorList[POCKET])) {
+ addDependency(&context[mSensorCount], sensor_proximity.handle);
+ addDependency(&context[mSensorCount], sensor_light.handle);
mSensorCount++;
}
}
if (has_acc && has_compass) {
- int dep = (1ULL << SENSOR_TYPE_ACCELEROMETER) | (1ULL << SENSOR_TYPE_MAGNETIC_FIELD);
-
+ compositeVirtualSensorName(sensor_mag.name, virtualSensorName[ORIENTATION], SENSOR_TYPE_ORIENTATION);
+ ALOGD("orientation virtual sensor name changed to %s\n", virtualSensorName[ORIENTATION]);
/* HAL implemented orientation. Android will replace it for
* platform with Gyro with SensorFusion.
* The calibration manager will first match "oem-orientation" and
* then match "orientation" to select the algorithms. */
- if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount), dep,
+ if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount),
virtualSensorList[ORIENTATION])) {
+ addDependency(&context[mSensorCount], sensor_acc.handle);
+ addDependency(&context[mSensorCount], sensor_mag.handle);
mSensorCount++;
}
if (!has_gyro) {
+ compositeVirtualSensorName(sensor_mag.name, virtualSensorName[ORIENTATION], SENSOR_TYPE_ORIENTATION);
+ ALOGD("orientation virtual sensor name changed to %s\n", virtualSensorName[ORIENTATION]);
/* Pseudo gyroscope is a pseudo sensor which implements by accelerometer and
* magnetometer. Some sensor vendors provide such implementations. The pseudo
* gyroscope sensor is low cost but the performance is worse than the actual
* gyroscope. So disable it for the system with actual gyroscope. */
- if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount), dep,
+#ifdef ENABLE_DEPRECATED_VITRUAL_SENSOR
+ if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount),
virtualSensorList[PSEUDO_GYROSCOPE])) {
+ addDependency(&context[mSensorCount], sensor_acc.handle);
+ addDependency(&context[mSensorCount], sensor_mag.handle);
mSensorCount++;
}
-
+#endif
+ compositeVirtualSensorName(sensor_mag.name, virtualSensorName[LINEAR_ACCELERATION], SENSOR_TYPE_LINEAR_ACCELERATION);
+ ALOGD("liear acceleration virtual sensor name changed to %s\n", virtualSensorName[LINEAR_ACCELERATION]);
/* For linear acceleration */
- if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount), dep,
+ if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount),
virtualSensorList[LINEAR_ACCELERATION])) {
+ addDependency(&context[mSensorCount], sensor_acc.handle);
+ addDependency(&context[mSensorCount], sensor_mag.handle);
mSensorCount++;
}
+ compositeVirtualSensorName(sensor_mag.name, virtualSensorName[ROTATION_VECTOR], SENSOR_TYPE_ROTATION_VECTOR);
+ ALOGD("rotation vector virtual sensor name changed to %s\n", virtualSensorName[ROTATION_VECTOR]);
/* For rotation vector */
- if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount), dep,
+ if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount),
virtualSensorList[ROTATION_VECTOR])) {
+ addDependency(&context[mSensorCount], sensor_acc.handle);
+ addDependency(&context[mSensorCount], sensor_mag.handle);
mSensorCount++;
}
+ compositeVirtualSensorName(sensor_mag.name, virtualSensorName[GRAVITY], SENSOR_TYPE_GRAVITY);
+ ALOGD("gravity virtual sensor name changed to %s\n", virtualSensorName[GRAVITY]);
/* For gravity */
- if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount), dep,
+ if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount),
virtualSensorList[GRAVITY])) {
+ addDependency(&context[mSensorCount], sensor_acc.handle);
+ addDependency(&context[mSensorCount], sensor_mag.handle);
mSensorCount++;
}
}
}
+ if (has_compass) {
+ /* The uncalibrated magnetic field sensor shares the same vendor/name as the
+ * calibrated one. */
+ sensor_mag.type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
+ if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount),
+ sensor_mag)) {
+ addDependency(&context[mSensorCount], sensor_mag.handle);
+ mSensorCount++;
+ }
+ }
+
+ if (has_gyro) {
+ sensor_gyro.type = SENSOR_TYPE_GYROSCOPE_UNCALIBRATED;
+ if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount),
+ sensor_gyro)) {
+ addDependency(&context[mSensorCount], sensor_gyro.handle);
+ mSensorCount++;
+ }
+ }
+
+ if (has_acc && has_gyro) {
+ /* For game rotation vector */
+ if (!initVirtualSensor(&context[mSensorCount], SENSORS_HANDLE(mSensorCount),
+ virtualSensorList[GAME_ROTATION_VECTOR])) {
+ addDependency(&context[mSensorCount], sensor_acc.handle);
+ addDependency(&context[mSensorCount], sensor_gyro.handle);
+ mSensorCount++;
+ }
+ }
+
return 0;
}
@@ -537,14 +667,17 @@ int NativeSensorManager::getNode(char *buf, char *path, const struct SysfsMap *m
fd = open(path, O_RDONLY);
if (fd < 0) {
ALOGE("open %s failed.(%s)\n", path, strerror(errno));
- return -1;
+ /* Ignore unrequired nodes for backward compatiblity */
+ return map->required ? -1 : 0;
}
len = read(fd, tmp, sizeof(tmp) - 1);
if ((len <= 0) || (strlen(tmp) == 0)) {
ALOGE("read %s failed.(%s)\n", path, strerror(errno));
close(fd);
- return -1;
+
+ /* Ignore unrequired nodes for backward compatiblity */
+ return map->required ? -1 : 0;
}
tmp[len - 1] = '\0';
@@ -561,12 +694,138 @@ int NativeSensorManager::getNode(char *buf, char *path, const struct SysfsMap *m
} else if (map->type == TYPE_FLOAT) {
float *p = (float*)(buf + map->offset);
*p = atof(tmp);
+ } else if (map->type == TYPE_INTEGER64) {
+ int64_t *p = (int64_t *)(buf + map->offset);
+ *p = atoll(tmp);
}
close(fd);
return 0;
}
+int NativeSensorManager::getEventPathOld(const struct SensorContext *list, char *event_path)
+{
+ struct dirent **namelist;
+ char *file;
+ char path[PATH_MAX];
+ char name[80];
+ int nNodes;
+ int fd = -1;
+ int j;
+
+ /* scan "/dev/input" to get information */
+ if (!mScanned) {
+ strlcpy(path, EVENT_PATH, sizeof(path));
+ file = path + strlen(EVENT_PATH);
+ nNodes = scandir(path, &namelist, 0, alphasort);
+ if (nNodes < 0) {
+ ALOGE("scan %s failed.(%s)\n", EVENT_PATH, strerror(errno));
+ return -1;
+ }
+
+ for (mEventCount = 0, j = 0; (j < nNodes) && (j < MAX_SENSORS); j++) {
+ if (namelist[j]->d_type != DT_CHR) {
+ continue;
+ }
+
+ strlcpy(file, namelist[j]->d_name, sizeof(path) - strlen(EVENT_PATH));
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ ALOGE("open %s failed(%s)", path, strerror(errno));
+ continue;
+ }
+
+ if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
+ name[0] = '\0';
+ }
+
+ strlcpy(event_list[mEventCount].data_name, name, sizeof(event_list[0].data_name));
+ strlcpy(event_list[mEventCount].data_path, path, sizeof(event_list[0].data_path));
+ close(fd);
+ mEventCount++;
+ }
+
+ for (j = 0; j <nNodes; j++ ) {
+ free(namelist[j]);
+ }
+
+ free(namelist);
+ mScanned = true;
+ }
+
+ /* Initialize data_path and data_fd */
+ for (j = 0; (j < mEventCount) && (j < MAX_SENSORS); j++) {
+ if (strcmp(list->sensor->name, event_list[j].data_name) == 0) {
+ strlcpy(event_path, event_list[j].data_path, PATH_MAX);
+ break;
+ }
+
+ if (strcmp(event_list[j].data_name, type_to_name(list->sensor->type)) == 0) {
+ strlcpy(event_path, event_list[j].data_path, PATH_MAX);
+ }
+ }
+
+ return 0;
+}
+
+int NativeSensorManager::getEventPath(const char *sysfs_path, char *event_path)
+{
+ DIR *dir;
+ struct dirent *de;
+ char symlink[PATH_MAX];
+ int len;
+ char *needle;
+
+ if ((sysfs_path == NULL) || (event_path == NULL)) {
+ ALOGE("invalid NULL argument.");
+ return -EINVAL;
+ }
+
+ dir = opendir(sysfs_path);
+ if (dir == NULL) {
+ ALOGE("open %s failed.(%s)\n", strerror(errno));
+ return -1;
+ }
+
+ len = readlink(sysfs_path, symlink, PATH_MAX);
+ if (len < 0) {
+ ALOGE("readlink failed for %s(%s)\n", sysfs_path, strerror(errno));
+ return -1;
+ }
+
+ needle = strrchr(symlink, '/');
+ if (needle == NULL) {
+ ALOGE("unexpected symlink %s\n", symlink);
+ return -1;
+ }
+
+ if (strncmp(needle + 1, "input", strlen("input")) != 0) {
+ ALOGE("\n");
+ ALOGE("==========================Notice=================================");
+ ALOGE("sensors_classdev %s need to register as the child of input device\n", sysfs_path);
+ ALOGE("in order to speed up Android sensor service initialization time");
+ ALOGE("Please update your sensor driver.");
+ ALOGE("================================================================");
+ ALOGE("\n");
+
+ return -ENODEV;
+ }
+
+ strlcpy(event_path, EVENT_PATH, PATH_MAX);
+
+ while ((de = readdir(dir))) {
+ if (strncmp(de->d_name, "event", strlen("event")) == 0) {
+ strlcat(event_path, de->d_name, sizeof(de->d_name));
+ break;
+ }
+ }
+
+ closedir(dir);
+
+ return 0;
+}
+
int NativeSensorManager::getSensorListInner()
{
int number = 0;
@@ -585,7 +844,7 @@ int NativeSensorManager::getSensorListInner()
return 0;
}
strlcpy(devname, dirname, PATH_MAX);
- filename = devname + strlen(devname);
+ filename = devname + strlen(dirname);
while ((de = readdir(dir))) {
if(de->d_name[0] == '.' &&
@@ -602,8 +861,10 @@ int NativeSensorManager::getSensorListInner()
for (i = 0; i < ARRAY_SIZE(node_map); i++) {
strlcpy(nodename, node_map[i].node, PATH_MAX - strlen(SYSFS_CLASS) - strlen(de->d_name));
err = getNode((char*)(list->sensor), devname, &node_map[i]);
- if (err)
+ if (err) {
+ ALOGE("Get node for %s failed.\n", devname);
break;
+ }
}
if (i < ARRAY_SIZE(node_map))
@@ -613,11 +874,23 @@ int NativeSensorManager::getSensorListInner()
continue;
/* Setup other information */
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+ if (list->sensor->maxDelay == 0)
+ list->sensor->maxDelay = 10000000;
+ else
+ list->sensor->maxDelay = list->sensor->maxDelay * 1000; /* milliseconds to microseconds */
+#endif
list->sensor->handle = SENSORS_HANDLE(number);
- list->data_path = NULL;
strlcpy(nodename, "", SYSFS_MAXLEN);
- list->enable_path = strdup(devname);
+ strlcpy(list->enable_path, devname, PATH_MAX);
+
+ /* initialize data path */
+ strlcpy(nodename, "device", SYSFS_MAXLEN);
+
+ if (getEventPath(devname, list->data_path) == -ENODEV) {
+ getEventPathOld(list, list->data_path);
+ }
number++;
}
@@ -635,21 +908,38 @@ int NativeSensorManager::activate(int handle, int enable)
struct SensorContext *ctx;
struct SensorRefMap *item;
+ ALOGD("activate called handle:%d enable:%d", handle, enable);
+
list = getInfoByHandle(handle);
if (list == NULL) {
ALOGE("Invalid handle(%d)", handle);
return -EINVAL;
}
+ list->enable = enable;
+
+ /* one shot sensors don't act as base sensors */
+ if (list->sensor->flags & SENSOR_FLAG_ONE_SHOT_MODE)
+ return list->driver->enable(handle, enable);
+
/* Search for the background sensor for the sensor specified by handle. */
list_for_each(node, &list->dep_list) {
item = node_to_item(node, struct SensorRefMap, list);
if (enable) {
+ registerListener(item->ctx, list);
+
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+ /* HAL 1.3 already set listener's delay and latency
+ * Sync it right now to make it take effect.
+ */
+ syncLatency(item->ctx->sensor->handle);
+#endif
+
/* Enable the background sensor and register a listener on it. */
- err = item->ctx->driver->enable(item->ctx->sensor->handle, 1);
- if (!err) {
- registerListener(item->ctx, list);
- }
+ ALOGD("%s calling driver enable", item->ctx->sensor->name);
+ item->ctx->driver->enable(item->ctx->sensor->handle, 1);
+ syncDelay(item->ctx->sensor->handle);
+
} else {
/* The background sensor has other listeners, we need
* to unregister the current sensor from it and sync the
@@ -657,20 +947,29 @@ int NativeSensorManager::activate(int handle, int enable)
*/
if (!list_empty(&item->ctx->listener)) {
unregisterListener(item->ctx, list);
- /* We're activiating the hardware sensor itself */
- if ((item->ctx == list) && (item->ctx->enable))
- item->ctx->enable = 0;
+ /* restore delay settings */
syncDelay(item->ctx->sensor->handle);
+
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+ /* restore latency settings */
+ syncLatency(item->ctx->sensor->handle);
+#endif
}
/* Disable the background sensor if it doesn't have any listeners. */
if (list_empty(&item->ctx->listener)) {
+ ALOGD("%s calling driver disable", item->ctx->sensor->name);
item->ctx->driver->enable(item->ctx->sensor->handle, 0);
}
+
}
}
- list->enable = enable;
+ /* Settings change notification */
+ if (list->is_virtual) {
+ ALOGD("%s calling driver %s", list->sensor->name, enable ? "enable" : "disable");
+ list->driver->enable(handle, enable);
+ }
return err;
}
@@ -689,46 +988,79 @@ int NativeSensorManager::syncDelay(int handle)
return -EINVAL;
}
- if (list_empty(&list->listener)) {
- min_ns = list->delay_ns;
- } else {
- node = list_head(&list->listener);
- item = node_to_item(node, struct SensorRefMap, list);
- min_ns = item->ctx->delay_ns;
+ if (list_empty(&list->listener))
+ return 0;
- list_for_each(node, &list->listener) {
- item = node_to_item(node, struct SensorRefMap, list);
- ctx = item->ctx;
- /* To handle some special case that the polling delay is 0. This
- * may happen if the background sensor is not enabled but the virtual
- * sensor is enabled case.
- */
- if (ctx->delay_ns == 0) {
- ALOGW("Listener delay is 0. Fix it to minDelay");
- ctx->delay_ns = ctx->sensor->minDelay;
- }
+ node = list_head(&list->listener);
+ item = node_to_item(node, struct SensorRefMap, list);
+ min_ns = item->ctx->delay_ns;
- if (min_ns > ctx->delay_ns)
- min_ns = ctx->delay_ns;
+ list_for_each(node, &list->listener) {
+ item = node_to_item(node, struct SensorRefMap, list);
+ ctx = item->ctx;
+ /* To handle some special case that the polling delay is 0. This
+ * may happen if the background sensor is not enabled but the virtual
+ * sensor is enabled case.
+ */
+ if (ctx->delay_ns == 0) {
+ ALOGD("%s delay is 0. continue...", ctx->sensor->name);
+ continue;
}
- }
- if ((list->delay_ns != 0) && (list->delay_ns < min_ns) &&
- (list->enable))
- min_ns = list->delay_ns;
+ if (min_ns > ctx->delay_ns)
+ min_ns = ctx->delay_ns;
+ }
+ ALOGD("%s calling driver setDelay %d ms\n", list->sensor->name, min_ns / 1000000);
return list->driver->setDelay(list->sensor->handle, min_ns);
}
+int NativeSensorManager::syncLatency(int handle)
+{
+ const SensorRefMap *item;
+ SensorContext *ctx;
+ const SensorContext *list;
+ struct listnode *node;
+ int64_t min_ns;
+
+ list = getInfoByHandle(handle);
+ if (list == NULL) {
+ ALOGE("Invalid handle(%d)", handle);
+ return -EINVAL;
+ }
+
+ if (list_empty(&list->listener))
+ return 0;
+
+ node = list_head(&list->listener);
+ item = node_to_item(node, struct SensorRefMap, list);
+ min_ns = item->ctx->latency_ns;
+
+ list_for_each(node, &list->listener) {
+ item = node_to_item(node, struct SensorRefMap, list);
+ ctx = item->ctx;
+
+ if (min_ns > ctx->latency_ns)
+ min_ns = ctx->latency_ns;
+ }
+
+ if (list->sensor->fifoMaxEventCount) {
+ ALOGD("%s calling driver setLatency %d ms\n", list->sensor->name, min_ns / 1000000);
+ list->driver->setLatency(list->sensor->handle, min_ns);
+ }
+
+ return 0;
+}
+
int NativeSensorManager::setDelay(int handle, int64_t ns)
{
SensorContext *list;
int i;
- int number = getSensorCount();
int64_t delay = ns;
struct SensorRefMap *item;
struct listnode *node;
+ ALOGD("setDelay called handle:%d sample_ns:%lld", handle, ns);
list = getInfoByHandle(handle);
if (list == NULL) {
@@ -736,16 +1068,22 @@ int NativeSensorManager::setDelay(int handle, int64_t ns)
return -EINVAL;
}
- list->delay_ns = delay;
+ if (ns == 0) {
+ ALOGE("%s delay set to 0", list->sensor->name);
+ return -EINVAL;
+ }
+
+ /* ignore setDelay call for one-shot sensors */
+ if (list->sensor->flags & SENSOR_FLAG_ONE_SHOT_MODE)
+ return 0;
- // min_delay sysfs entry is in microseconds
if (ns < list->sensor->minDelay * 1000) {
+ ALOGW("%s delay is less than minDelay. Cast it to minDelay", list->sensor->name);
list->delay_ns = list->sensor->minDelay * 1000;
+ } else {
+ list->delay_ns = delay;
}
- if (list->delay_ns == 0)
- list->delay_ns = 1000000; // clamped to 1ms
-
list_for_each(node, &list->dep_list) {
item = node_to_item(node, struct SensorRefMap, list);
syncDelay(item->ctx->sensor->handle);
@@ -775,7 +1113,7 @@ int NativeSensorManager::readEvents(int handle, sensors_event_t* data, int count
for (j = 0; j < nb; j++) {
list_for_each(node, &list->listener) {
item = node_to_item(node, struct SensorRefMap, list);
- if (item->ctx->enable) {
+ if (item->ctx->enable && (item->ctx != list)) {
item->ctx->driver->injectEvents(&data[j], 1);
}
}
@@ -788,6 +1126,84 @@ int NativeSensorManager::readEvents(int handle, sensors_event_t* data, int count
return 0;
}
+int NativeSensorManager::batch(int handle, int64_t sample_ns, int64_t latency_ns)
+{
+ SensorContext *list;
+ struct listnode *node;
+ struct SensorRefMap *item;
+
+ ALOGD("batch called handle:%d sample_ns:%lld latency_ns:%lld", handle, sample_ns, latency_ns);
+
+ if ((latency_ns != 0) && (latency_ns < sample_ns)) {
+ ALOGE("latency_ns is smaller than sample_ns");
+ return -EINVAL;
+ }
+
+ list = getInfoByHandle(handle);
+ if (list == NULL) {
+ ALOGE("Invalid handle(%d)", handle);
+ return -EINVAL;
+ }
+
+ /* ignore batch call for one-shot sensors */
+ if (list->sensor->flags & SENSOR_FLAG_ONE_SHOT_MODE)
+ return 0;
+
+ /* *sample_ns* is the same as *ns* passed to setDelay */
+ list->delay_ns = sample_ns;
+ list->latency_ns = latency_ns;
+
+ /* should take effect now for ones with listeners */
+ list_for_each(node, &list->dep_list) {
+ item = node_to_item(node, struct SensorRefMap, list);
+ syncDelay(item->ctx->sensor->handle);
+ syncLatency(item->ctx->sensor->handle);
+ }
+
+ return 0;
+}
+
+int NativeSensorManager::flush(int handle)
+{
+ const SensorContext *list;
+ int ret = 0;
+ struct SensorRefMap *item;
+ struct listnode *node;
+
+ ALOGD("flush called\n", handle);
+ list = getInfoByHandle(handle);
+ if (list == NULL) {
+ ALOGE("Invalid handle(%d)", handle);
+ return -EINVAL;
+ }
+
+ /* one shot sensors should return -EINVAL */
+ if (list->sensor->flags & SENSOR_FLAG_ONE_SHOT_MODE)
+ return -EINVAL;
+
+ /* calling flush for virtual sensor */
+ if (list->is_virtual) {
+ ret = list->driver->flush(handle);
+ if (ret) {
+ ALOGE("Calling flush failed(%d)", ret);
+ return ret;
+ }
+
+ } else {
+ list_for_each(node, &list->dep_list) {
+ item = node_to_item(node, struct SensorRefMap, list);
+ ret = item->ctx->driver->flush(item->ctx->sensor->handle);
+ if (ret) {
+ ALOGE("Calling flush failed(%d)", ret);
+ return ret;
+ }
+ }
+
+ }
+
+ return 0;
+}
+
int NativeSensorManager::hasPendingEvents(int handle)
{
const SensorContext *list;
@@ -823,7 +1239,7 @@ int NativeSensorManager::calibrate(int handle, struct cal_cmd_t *para)
if (!para->save) {
return err;
}
- err = sensor_XML.write_sensors_params(list->sensor, &cal_result);
+ err = sensor_XML.write_sensors_params(list->sensor, &cal_result, CAL_STATIC);
if (err < 0) {
ALOGE("write calibrate %s sensor error\n", list->sensor->name);
return err;
@@ -842,9 +1258,9 @@ int NativeSensorManager::initCalibrate(const SensorContext *list)
return -EINVAL;
}
memset(&cal_result, 0, sizeof(cal_result));
- err = sensor_XML.read_sensors_params(list->sensor, &cal_result);
+ err = sensor_XML.read_sensors_params(list->sensor, &cal_result, CAL_STATIC);
if (err < 0) {
- ALOGE("read calibrate params error\n");
+ ALOGE("read %s calibrate params error\n", list->sensor->name);
return err;
}
diff --git a/sensors/NativeSensorManager.h b/sensors/NativeSensorManager.h
index 8272162..7ea8639 100644
--- a/sensors/NativeSensorManager.h
+++ b/sensors/NativeSensorManager.h
@@ -68,13 +68,14 @@ enum {
TYPE_STRING = 0,
TYPE_INTEGER,
TYPE_FLOAT,
+ TYPE_INTEGER64,
};
struct SensorContext {
char name[SYSFS_MAXLEN]; // name of the sensor
char vendor[SYSFS_MAXLEN]; // vendor of the sensor
- char *enable_path; // the control path to enable this sensor
- char *data_path; // the data path to get sensor events
+ char enable_path[PATH_MAX]; // the control path of this sensor
+ char data_path[PATH_MAX]; // the data path to get sensor events
struct sensor_t *sensor; // point to the sensor_t structure in the sensor list
SensorBase *driver; // point to the sensor driver instance
@@ -83,20 +84,22 @@ struct SensorContext {
int enable; // indicate if the sensor is enabled
bool is_virtual; // indicate if this is a virtual sensor
int64_t delay_ns; // the poll delay setting of this sensor
+ int64_t latency_ns; // the max report latency of this sensor
struct listnode dep_list; // the background sensor type needed for this sensor
struct listnode listener; // the head of listeners of this sensor
};
struct SensorEventMap {
- char data_name[80];
- char data_path[PATH_MAX];
+ char data_name[80];
+ char data_path[PATH_MAX];
};
struct SysfsMap {
int offset;
const char *node;
int type;
+ int required;
};
/* To contain the listener list and denpend list */
@@ -114,21 +117,28 @@ class NativeSensorManager : public Singleton<NativeSensorManager> {
struct SensorEventMap event_list[MAX_SENSORS];
static const struct SysfsMap node_map[];
static const struct sensor_t virtualSensorList[];
+ static char virtualSensorName[][SYSFS_MAXLEN];
int mSensorCount;
+ bool mScanned;
+ int mEventCount;
DefaultKeyedVector<int32_t, struct SensorContext*> type_map;
DefaultKeyedVector<int32_t, struct SensorContext*> handle_map;
DefaultKeyedVector<int, struct SensorContext*> fd_map;
+ void compositeVirtualSensorName(const char *sensor_name, char *chip_name, int type);
int getNode(char *buf, char *path, const struct SysfsMap *map);
int getSensorListInner();
int getDataInfo();
int registerListener(struct SensorContext *hw, struct SensorContext *virt);
int unregisterListener(struct SensorContext *hw, struct SensorContext *virt);
int syncDelay(int handle);
- int initVirtualSensor(struct SensorContext *ctx, int handle, int64_t dep, struct sensor_t info);
int initCalibrate(const SensorContext *list);
+ int initVirtualSensor(struct SensorContext *ctx, int handle, struct sensor_t info);
+ int addDependency(struct SensorContext *ctx, int handle);
+ int getEventPath(const char *sysfs_path, char *event_path);
+ int getEventPathOld(const struct SensorContext *list, char *event_path);
public:
int getSensorList(const sensor_t **list);
inline SensorContext* getInfoByFd(int fd) { return fd_map.valueFor(fd); };
@@ -139,8 +149,11 @@ public:
int hasPendingEvents(int handle);
int activate(int handle, int enable);
int setDelay(int handle, int64_t ns);
+ int syncLatency(int handle);
int readEvents(int handle, sensors_event_t *data, int count);
int calibrate(int handle, struct cal_cmd_t *para);
+ int batch(int handle, int64_t sample_ns, int64_t latency_ns);
+ int flush(int handle);
};
#endif
diff --git a/sensors/ProximitySensor.cpp b/sensors/ProximitySensor.cpp
index 30c9b6d..6a77751 100644
--- a/sensors/ProximitySensor.cpp
+++ b/sensors/ProximitySensor.cpp
@@ -31,7 +31,10 @@
#define EVENT_TYPE_PROXIMITY ABS_DISTANCE
-#define PROXIMITY_THRESHOLD 5.0f
+#define PROXIMITY_THRESHOLD 5.0f
+
+#define ARRAY 3
+
/*****************************************************************************/
enum input_device_name {
@@ -63,13 +66,13 @@ static const char *input_sysfs_enable_list[SUPPORTED_PSENSOR_COUNT] = {
ProximitySensor::ProximitySensor()
: SensorBase(NULL, NULL),
- mEnabled(0),
mInputReader(4),
mHasPendingEvent(false),
sensor_index(-1),
mThreshold_h(0),
mThreshold_l(0),
- mBias(0)
+ mBias(0),
+ res(PROXIMITY_THRESHOLD)
{
int i;
mPendingEvent.version = sizeof(sensors_event_t);
@@ -100,48 +103,48 @@ ProximitySensor::ProximitySensor()
}
ProximitySensor::ProximitySensor(struct SensorContext *context)
- : SensorBase(NULL, NULL),
- mEnabled(0),
- mInputReader(4),
- mHasPendingEvent(false),
- sensor_index(GENERIC_PSENSOR),
- mThreshold_h(0),
- mThreshold_l(0),
- mBias(0)
+: SensorBase(NULL, NULL, context),
+ mInputReader(4),
+ mHasPendingEvent(false),
+ sensor_index(GENERIC_PSENSOR),
+ mThreshold_h(0),
+ mThreshold_l(0),
+ mBias(0),
+ res(context->sensor->resolution)
{
- mPendingEvent.version = sizeof(sensors_event_t);
- mPendingEvent.sensor = context->sensor->handle;
- mPendingEvent.type = SENSOR_TYPE_PROXIMITY;
- memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
-
- data_fd = context->data_fd;
- strlcpy(input_sysfs_path, context->enable_path, sizeof(input_sysfs_path));
- input_sysfs_path_len = strlen(input_sysfs_path);
+ mPendingEvent.version = sizeof(sensors_event_t);
+ mPendingEvent.sensor = context->sensor->handle;
+ mPendingEvent.type = SENSOR_TYPE_PROXIMITY;
+ memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
+
+ data_fd = context->data_fd;
+ strlcpy(input_sysfs_path, context->enable_path, sizeof(input_sysfs_path));
+ input_sysfs_path_len = strlen(input_sysfs_path);
}
ProximitySensor::ProximitySensor(char *name)
- : SensorBase(NULL, data_device_name[GENERIC_PSENSOR]),
- mEnabled(0),
- mInputReader(4),
- mHasPendingEvent(false),
- sensor_index(GENERIC_PSENSOR),
- mThreshold_h(0),
- mThreshold_l(0),
- mBias(0)
+: SensorBase(NULL, data_device_name[GENERIC_PSENSOR]),
+ mInputReader(4),
+ mHasPendingEvent(false),
+ sensor_index(GENERIC_PSENSOR),
+ mThreshold_h(0),
+ mThreshold_l(0),
+ mBias(0),
+ res(PROXIMITY_THRESHOLD)
{
- mPendingEvent.version = sizeof(sensors_event_t);
- mPendingEvent.sensor = SENSORS_PROXIMITY_HANDLE;
- mPendingEvent.type = SENSOR_TYPE_PROXIMITY;
- memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
-
- if (data_fd) {
- strlcpy(input_sysfs_path, SYSFS_CLASS, sizeof(input_sysfs_path));
- strlcat(input_sysfs_path, name, sizeof(input_sysfs_path));
- strlcat(input_sysfs_path, "/", sizeof(input_sysfs_path));
- input_sysfs_path_len = strlen(input_sysfs_path);
- ALOGI("The proximity sensor path is %s",input_sysfs_path);
- enable(0, 1);
- }
+ mPendingEvent.version = sizeof(sensors_event_t);
+ mPendingEvent.sensor = SENSORS_PROXIMITY_HANDLE;
+ mPendingEvent.type = SENSOR_TYPE_PROXIMITY;
+ memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
+
+ if (data_fd) {
+ strlcpy(input_sysfs_path, SYSFS_CLASS, sizeof(input_sysfs_path));
+ strlcat(input_sysfs_path, name, sizeof(input_sysfs_path));
+ strlcat(input_sysfs_path, "/", sizeof(input_sysfs_path));
+ input_sysfs_path_len = strlen(input_sysfs_path);
+ ALOGI("The proximity sensor path is %s",input_sysfs_path);
+ enable(0, 1);
+ }
}
ProximitySensor::~ProximitySensor() {
if (mEnabled) {
@@ -168,6 +171,14 @@ int ProximitySensor::enable(int32_t, int en) {
ALOGE("invalid sensor index:%d\n", sensor_index);
return -1;
}
+
+ mEnabled = flags;
+ /**
+ * this is an on-change sensor. it might not get a reading for a while
+ * and Android requires a reading as soon as it is turned on.
+ * re-send the last reading.
+ */
+ mHasPendingEvent = flags;
fd = open(input_sysfs_path, O_RDWR);
if (fd >= 0) {
char buf[2];
@@ -179,18 +190,30 @@ int ProximitySensor::enable(int32_t, int en) {
}
write(fd, buf, sizeof(buf));
close(fd);
- mEnabled = flags;
- return 0;
} else {
ALOGE("open %s failed.(%s)\n", input_sysfs_path, strerror(errno));
return -1;
}
+
+ if (mEnabled) {
+ struct input_absinfo absinfo;
+ int rc = ioctl(data_fd, EVIOCGABS(EVENT_TYPE_PROXIMITY), &absinfo);
+ if (rc < 0) {
+ ALOGE("ProximitySensor: EVIOCGABS error: %d", errno);
+ return -errno;
+ }
+
+ mPendingEvent.distance = indexToValue(absinfo.value);
+ return 0;
+ }
+ } else if (flags) {
+ mHasPendingEvent = true;
}
return 0;
}
bool ProximitySensor::hasPendingEvents() const {
- return mHasPendingEvent;
+ return mHasPendingEvent || mHasPendingMetadata;
}
int ProximitySensor::readEvents(sensors_event_t* data, int count)
@@ -205,6 +228,13 @@ int ProximitySensor::readEvents(sensors_event_t* data, int count)
return mEnabled ? 1 : 0;
}
+ if (mHasPendingMetadata) {
+ mHasPendingMetadata--;
+ meta_data.timestamp = getTimestamp();
+ *data = meta_data;
+ return mEnabled ? 1 : 0;
+ }
+
ssize_t n = mInputReader.fill(data_fd);
if (n < 0)
return n;
@@ -222,12 +252,26 @@ int ProximitySensor::readEvents(sensors_event_t* data, int count)
}
}
} else if (type == EV_SYN) {
- mPendingEvent.timestamp = timevalToNano(event->time);
- if (mEnabled) {
- *data++ = mPendingEvent;
- count--;
- numEventReceived++;
- }
+ switch ( event->code ) {
+ case SYN_TIME_SEC:
+ mUseAbsTimeStamp = true;
+ report_time = event->value * 1000000000LL;
+ break;
+ case SYN_TIME_NSEC:
+ mUseAbsTimeStamp = true;
+ mPendingEvent.timestamp = report_time + event->value;
+ break;
+ case SYN_REPORT:
+ if(mUseAbsTimeStamp != true) {
+ mPendingEvent.timestamp = timevalToNano(event->time);
+ }
+ if (mEnabled) {
+ *data++ = mPendingEvent;
+ count--;
+ numEventReceived++;
+ }
+ break;
+ }
} else {
ALOGE("ProximitySensor: unknown event (type=%d, code=%d)",
type, event->code);
@@ -240,107 +284,92 @@ int ProximitySensor::readEvents(sensors_event_t* data, int count)
float ProximitySensor::indexToValue(size_t index) const
{
- return index * PROXIMITY_THRESHOLD;
+ return index * res;
}
-int ProximitySensor::calibrate(int32_t handle, struct cal_cmd_t *para,
+int ProximitySensor::calibrate(int32_t, struct cal_cmd_t *para,
struct cal_result_t *cal_result)
{
- int fd;
- char temp[3][LENGTH];
- char buf[3 * LENGTH];
- char *token, *strsaveptr, *endptr;
- int i, err;
- off_t offset;
- int para1 = 0;
- if (para == NULL || cal_result == NULL) {
- ALOGE("Null pointer calibrate parameters\n");
- return -1;
+ int fd;
+ char temp[ARRAY][LENGTH];
+ char buf[ARRAY * LENGTH];
+ char *token, *strsaveptr, *endptr;
+ int i, err;
+ off_t offset;
+ int para1 = 0;
+
+ if (para == NULL || cal_result == NULL) {
+ ALOGE("Null pointer calibrate parameters\n");
+ return -1;
+ }
+ para1 = CMD_CAL(para->axis, para->apply_now);
+ strlcpy(&input_sysfs_path[input_sysfs_path_len],
+ SYSFS_CALIBRATE, SYSFS_MAXLEN);
+ fd = open(input_sysfs_path, O_RDWR);
+ if (fd >= 0) {
+ snprintf(buf, sizeof(buf), "%d", para1);
+ err = write(fd, buf, strlen(buf)+1);
+ if (err < 0) {
+ ALOGE("write error\n");
+ close(fd);
+ return err;
}
- para1 = CMD_CAL(para->axis, para->apply_now);
- strlcpy(&input_sysfs_path[input_sysfs_path_len],
- SYSFS_CALIBRATE, SYSFS_MAXLEN);
- fd = open(input_sysfs_path, O_RDWR);
- if (fd >= 0) {
- snprintf(buf, sizeof(buf), "%d", para1);
- err = write(fd, buf, strlen(buf)+1);
- if(err < 0) {
- ALOGE("write error\n");
- close(fd);
- return err;
- }
- } else {
- return -1;
+ } else {
+ ALOGE("open %s failed\n", input_sysfs_path);
+ return -1;
+ }
+ offset = lseek(fd, 0, SEEK_SET);
+ char *p = buf;
+ memset(buf, 0, sizeof(buf));
+ err = read(fd, buf, sizeof(buf)-1);
+ if(err < 0) {
+ ALOGE("proximity read error\n");
+ close(fd);
+ return err;
+ }
+ for(i = 0; i < ARRAY; i++, p = NULL) {
+ token = strtok_r(p, ",", &strsaveptr);
+ if(token == NULL)
+ break;
+ if(strlen(token) > LENGTH - 1) {
+ ALOGE("token is too long\n");
+ close(fd);
+ return -1;
}
- if (fd >= 0) {
- offset = lseek(fd, 0, SEEK_SET);
- char *p = buf;
- memset(buf, 0, sizeof(buf));
- err = read(fd, buf, sizeof(buf)-1);
- if(err < 0) {
- ALOGE("proximity read error\n");
- close(fd);
- return err;
- }
- for(i = 0; sizeof(temp) / LENGTH; i++, p = NULL) {
- token = strtok_r(p, ",", &strsaveptr);
- if(token == NULL)
- break;
- if(strlen(token) > LENGTH - 1) {
- ALOGE("token is too long\n");
- close(fd);
- return -1;
- }
- strlcpy(temp[i], token, sizeof(temp[i]));
- }
- close(fd);
- if (para->axis == 0) {
- mThreshold_h = strtol(temp[0], &endptr, 10);
- if (mThreshold_h == LONG_MAX || mThreshold_h == LONG_MIN) {
- ALOGE("mThreshold_h error value\n");
- return -1;
- }
- if (endptr == temp[0]) {
- ALOGE("No digits were found\n");
- return -1;
- }
- } else if (para->axis == 1) {
- mThreshold_l = strtol(temp[1], &endptr, 10);
- if (mThreshold_l == LONG_MAX || mThreshold_l == LONG_MIN) {
- ALOGE("mThreshold_l error value\n");
- return -1;
- }
- if (endptr == temp[1]) {
- ALOGE("No digits were found\n");
- return -1;
- }
- } else if (para->axis == 2) {
- mBias = strtol(temp[2], &endptr, 10);
- if (mBias == LONG_MAX || mBias == LONG_MIN) {
- ALOGE("mBias error value\n");
- return -1;
- }
- if (endptr == temp[2]) {
- ALOGE("No digits were found\n");
- return -1;
- }
- }
- cal_result->threshold_h = mThreshold_h;
- cal_result->threshold_l = mThreshold_l;
- cal_result->bias = mBias;
- return 0;
- } else {
- ALOGE("open %s error\n", input_sysfs_path);
- return -1;
+ strlcpy(temp[i], token, sizeof(temp[i]));
+ }
+ close(fd);
+ if (para->axis == AXIS_THRESHOLD_H) {
+ mThreshold_h = strtol(temp[0], &endptr, 0);
+ if (endptr == temp[0]) {
+ ALOGE("No digits were found\n");
+ return -1;
}
- return 0;
+ } else if (para->axis == AXIS_THRESHOLD_L) {
+ mThreshold_l = strtol(temp[1], &endptr, 0);
+ if (endptr == temp[1]) {
+ ALOGE("No digits were found\n");
+ return -1;
+ }
+ } else if (para->axis == AXIS_BIAS) {
+ mBias = strtol(temp[2], &endptr, 0);
+ if (endptr == temp[2]) {
+ ALOGE("No digits were found\n");
+ return -1;
+ }
+ }
+ cal_result->threshold_h = mThreshold_h;
+ cal_result->threshold_l = mThreshold_l;
+ cal_result->bias = mBias;
+ return 0;
}
-int ProximitySensor::initCalibrate(int32_t handle, struct cal_result_t *cal_result)
+int ProximitySensor::initCalibrate(int32_t, struct cal_result_t *cal_result)
{
int fd , i, err;
- char buf[33];
+ char buf[LENGTH];
int arry[] = {CMD_W_THRESHOLD_H, CMD_W_THRESHOLD_L, CMD_W_BIAS};
+
if (cal_result == NULL) {
ALOGE("Null pointer initcalibrate parameter\n");
return -1;
@@ -350,7 +379,7 @@ int ProximitySensor::initCalibrate(int32_t handle, struct cal_result_t *cal_resu
fd = open(input_sysfs_path, O_RDWR);
if (fd >= 0) {
int temp, para1 = 0;
- for(i = 0; i < sizeof(arry) / sizeof(int); ++i) {
+ for(i = 0; i < (int)ARRAY_SIZE(arry); ++i) {
para1 = SET_CMD_H(cal_result->offset[i], arry[i]);
snprintf(buf, sizeof(buf), "%d",
para1);
diff --git a/sensors/ProximitySensor.h b/sensors/ProximitySensor.h
index 89b107f..0710e57 100644
--- a/sensors/ProximitySensor.h
+++ b/sensors/ProximitySensor.h
@@ -31,24 +31,22 @@
struct input_event;
class ProximitySensor : public SensorBase {
- int mEnabled;
InputEventCircularReader mInputReader;
sensors_event_t mPendingEvent;
bool mHasPendingEvent;
- char input_sysfs_path[PATH_MAX];
- int input_sysfs_path_len;
int sensor_index;
int mThreshold_h;
int mThreshold_l;
int mBias;
+ float res;
int setInitialState();
float indexToValue(size_t index) const;
public:
- ProximitySensor();
- ProximitySensor(char *name);
- ProximitySensor(struct SensorContext *context);
+ ProximitySensor();
+ ProximitySensor(char *name);
+ ProximitySensor(struct SensorContext *context);
virtual ~ProximitySensor();
virtual int readEvents(sensors_event_t* data, int count);
virtual bool hasPendingEvents() const;
diff --git a/sensors/SensorBase.cpp b/sensors/SensorBase.cpp
index 72e360d..63cb52f 100644
--- a/sensors/SensorBase.cpp
+++ b/sensors/SensorBase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved.
* Not a Contribution.
* Copyright (C) 2008 The Android Open Source Project
*
@@ -37,13 +37,22 @@ SensorBase::SensorBase(
const char* dev_name,
const char* data_name,
const struct SensorContext* context /* = NULL */)
- : dev_name(dev_name), data_name(data_name),
- algo(NULL), dev_fd(-1), data_fd(-1)
+ : dev_name(dev_name), data_name(data_name), algo(NULL),
+ dev_fd(-1), data_fd(-1), mEnabled(0), mHasPendingMetadata(0)
{
if (context != NULL) {
CalibrationManager& cm(CalibrationManager::getInstance());
- algo = cm.getCalAlgo(context->sensor);
- }
+ algo = cm.getCalAlgo(context->sensor);
+
+ /* Set up the sensors_meta_data_event_t event*/
+ meta_data.version = META_DATA_VERSION;
+ meta_data.sensor = context->sensor->handle;
+ meta_data.type = SENSOR_TYPE_META_DATA;
+ meta_data.reserved0 = 0;
+ meta_data.timestamp = 0LL;
+ meta_data.meta_data.what = META_DATA_FLUSH_COMPLETE;
+ meta_data.meta_data.sensor = context->sensor->handle;
+ }
if (data_name) {
data_fd = openInput(data_name);
@@ -97,6 +106,10 @@ int64_t SensorBase::getTimestamp() {
return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec;
}
+int64_t SensorBase::getClkOffset() {
+ return (getTimestamp() - android::elapsedRealtimeNano());
+}
+
int SensorBase::openInput(const char* inputName) {
int fd = -1;
const char *dirname = "/dev/input";
@@ -107,15 +120,15 @@ int SensorBase::openInput(const char* inputName) {
dir = opendir(dirname);
if(dir == NULL)
return -1;
- strcpy(devname, dirname);
- filename = devname + strlen(devname);
+ strlcpy(devname, dirname, PATH_MAX);
+ filename = devname + strlen(dirname);
*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);
+ strlcpy(filename, de->d_name, PATH_MAX - strlen(SYSFS_CLASS));
fd = open(devname, O_RDONLY);
if (fd>=0) {
char name[80];
@@ -123,7 +136,7 @@ int SensorBase::openInput(const char* inputName) {
name[0] = '\0';
}
if (!strcmp(name, inputName)) {
- strcpy(input_name, filename);
+ strlcpy(input_name, filename, PATH_MAX);
break;
} else {
close(fd);
@@ -138,16 +151,93 @@ int SensorBase::openInput(const char* inputName) {
int SensorBase::injectEvents(sensors_event_t*, int)
{
- return 0;
+ ALOGW("injectEvents is not implemented");
+ return 0;
+}
+
+int SensorBase::calibrate(int32_t, struct cal_cmd_t*,
+ struct cal_result_t*)
+{
+ return -1;
+}
+
+int SensorBase::initCalibrate(int32_t, struct cal_result_t*)
+{
+ return -1;
}
-int SensorBase::calibrate(int32_t handle, struct cal_cmd_t *para,
- struct cal_result_t *outpara)
+int SensorBase::setLatency(int32_t, int64_t latency_ns)
{
- return -1;
+ int fd;
+ int latency_ms;
+ ssize_t len;
+ char buf[80];
+
+ if ((latency_ns / 1000000ULL) >= ((1ULL << 31) - 1))
+ return -EINVAL;
+
+ latency_ms = latency_ns / 1000000;
+ strlcpy(&input_sysfs_path[input_sysfs_path_len],
+ SYSFS_MAXLATENCY, SYSFS_MAXLEN);
+ fd = open(input_sysfs_path, O_RDWR);
+ if (fd < 0) {
+ ALOGE("open %s failed.(%s)", input_sysfs_path, strerror(errno));
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "%d", latency_ms);
+ len = write(fd, buf, strlen(buf) + 1);
+ if (len < (ssize_t)strlen(buf) + 1) {
+ ALOGE("write %s:%s failed.(%s)", input_sysfs_path, buf, strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+ return 0;
}
-int SensorBase::initCalibrate(int32_t handle, struct cal_result_t *prar)
+int SensorBase::flush(int32_t handle)
{
- return -1;
+ int fd;
+ const char *buf = "1";
+ int len;
+
+ NativeSensorManager& sm(NativeSensorManager::getInstance());
+ struct SensorContext* ctx = sm.getInfoByHandle(handle);
+
+ /* The SensorService will call
+ * batch->flush(not call for the first connection)->activiate
+ * Note the number of FLUSH_COMPLETE events should be the
+ * same as the number of *flush* called.
+ */
+
+ /* Should return -EINVAL if the sensor is not enabled */
+ if ((!mEnabled) || (ctx == NULL) || (ctx->sensor->flags & SENSOR_FLAG_ONE_SHOT_MODE)) {
+ ALOGE("handle:%d mEnabled:%d ctx:%p\n", handle, mEnabled, ctx);
+ return -EINVAL;
+ }
+
+ /* sensors have FIFO: call into driver */
+ if (ctx->sensor->fifoMaxEventCount) {
+ strlcpy(&input_sysfs_path[input_sysfs_path_len],
+ SYSFS_FLUSH, SYSFS_MAXLEN);
+ fd = open(input_sysfs_path, O_RDWR);
+ if (fd < 0) {
+ ALOGE("open %s failed.(%s)", input_sysfs_path, strerror(errno));
+ return -1;
+ }
+
+ len = write(fd, buf, strlen(buf)+1);
+ if (len < (ssize_t)strlen(buf) + 1) {
+ ALOGE("write %s failed.(%s)", input_sysfs_path, strerror(errno));
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ }
+
+ mHasPendingMetadata++;
+ return 0;
}
+
diff --git a/sensors/SensorBase.h b/sensors/SensorBase.h
index 90ea1f7..e805ec7 100644
--- a/sensors/SensorBase.h
+++ b/sensors/SensorBase.h
@@ -27,6 +27,7 @@
#include <hardware/sensors.h>
#include <CalibrationManager.h>
#include <sensors_extension.h>
+#include <utils/SystemClock.h>
/*****************************************************************************/
@@ -43,9 +44,16 @@ protected:
int data_fd;
int64_t report_time;
bool mUseAbsTimeStamp;
+ sensors_meta_data_event_t meta_data;
+ char input_sysfs_path[PATH_MAX];
+ int input_sysfs_path_len;
+ int mEnabled;
+ int mHasPendingMetadata;
+ int64_t sysclk_sync_offset;
int openInput(const char* inputName);
static int64_t getTimestamp();
+ static int64_t getClkOffset();
static int64_t timevalToNano(timeval const& t) {
@@ -68,8 +76,10 @@ public:
virtual int setDelay(int32_t handle, int64_t ns);
virtual int enable(int32_t handle, int enabled) = 0;
virtual int calibrate(int32_t handle, struct cal_cmd_t *para,
- struct cal_result_t *outpara);
- virtual int initCalibrate(int32_t handle, struct cal_result_t *prar);
+ struct cal_result_t *cal_result);
+ virtual int initCalibrate(int32_t handle, struct cal_result_t *cal_result);
+ virtual int setLatency(int32_t handle, int64_t ns);
+ virtual int flush(int32_t handle);
};
/*****************************************************************************/
diff --git a/sensors/VirtualSensor.cpp b/sensors/VirtualSensor.cpp
index 0bfe0a0..fba61dc 100644
--- a/sensors/VirtualSensor.cpp
+++ b/sensors/VirtualSensor.cpp
@@ -1,5 +1,5 @@
/*--------------------------------------------------------------------------
-Copyright (c) 2014, The Linux Foundation. All rights reserved.
+Copyright (c) 2014, 2016, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -44,9 +44,8 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
VirtualSensor::VirtualSensor(const struct SensorContext *ctx)
: SensorBase(NULL, NULL, ctx),
- mEnabled(0),
- mHasPendingEvent(false),
- mEnabledTime(0),
+ reportLastEvent(false),
+ mFirstEventReceived(false),
context(ctx),
mRead(mBuffer),
mWrite(mBuffer),
@@ -54,7 +53,6 @@ VirtualSensor::VirtualSensor(const struct SensorContext *ctx)
mFreeSpace(MAX_EVENTS)
{
- enable(0, 1);
}
VirtualSensor::~VirtualSensor() {
@@ -64,21 +62,50 @@ VirtualSensor::~VirtualSensor() {
}
int VirtualSensor::enable(int32_t, int en) {
- mEnabled = en? 1 : 0;
+ int flag = en ? 1 : 0;
+ sensor_algo_args arg;
+
+ if (mEnabled != flag) {
+ mEnabled = flag;
+ mFirstEventReceived = false;
+ arg.enable = mEnabled;
+ if ((algo != NULL) && (algo->methods->config != NULL)) {
+ if (algo->methods->config(CMD_ENABLE, (sensor_algo_args*)&arg)) {
+ ALOGW("Calling enable config failed");
+ }
+ }
+ } else if (flag) {
+ reportLastEvent = mFirstEventReceived ? true : false;
+ }
+
return 0;
}
bool VirtualSensor::hasPendingEvents() const {
- return mBufferEnd - mBuffer - mFreeSpace;
+ return (mBufferEnd - mBuffer - mFreeSpace) || reportLastEvent || mHasPendingMetadata;
}
int VirtualSensor::readEvents(sensors_event_t* data, int count)
{
int number = 0;
- if (count < 1)
+ if ((count < 1) || (!mEnabled))
return -EINVAL;
+ if (reportLastEvent) {
+ *data++ = mLastEvent;
+ count--;
+ reportLastEvent = false;
+ number++;
+ }
+
+ if (mHasPendingMetadata && count) {
+ *data++ = meta_data;
+ count--;
+ mHasPendingMetadata--;
+ number++;
+ }
+
while (count && (mBufferEnd - mBuffer - mFreeSpace)) {
*data++ = *mRead++;
if (mRead >= mBufferEnd)
@@ -86,8 +113,13 @@ int VirtualSensor::readEvents(sensors_event_t* data, int count)
number++;
mFreeSpace++;
count--;
+ if (!mFirstEventReceived)
+ mFirstEventReceived = true;
}
+ if (number > 0)
+ mLastEvent = data[number - 1];
+
return number;
}
@@ -101,15 +133,17 @@ int VirtualSensor::injectEvents(sensors_event_t* data, int count)
for (i = 0; i < count; i++) {
event = data[i];
-
- if (mFreeSpace) {
- sensors_event_t out;
+ sensors_event_t out;
+ if (mFreeSpace && (event.type != SENSOR_TYPE_META_DATA)) {
if (algo->methods->convert(&event, &out, NULL))
continue;
out.version = sizeof(sensors_event_t);
out.sensor = context->sensor->handle;
out.type = context->sensor->type;
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+ out.flags = context->sensor->flags;
+#endif
out.timestamp = event.timestamp;
*mWrite++ = out;
diff --git a/sensors/VirtualSensor.h b/sensors/VirtualSensor.h
index 17c5161..35a3917 100644
--- a/sensors/VirtualSensor.h
+++ b/sensors/VirtualSensor.h
@@ -45,11 +45,9 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct input_event;
class VirtualSensor : public SensorBase {
- int mEnabled;
- sensors_vec_t dm;
- sensors_vec_t da;
- bool mHasPendingEvent;
- int64_t mEnabledTime;
+ sensors_event_t mLastEvent;
+ bool reportLastEvent;
+ bool mFirstEventReceived;
const SensorContext *context;
sensors_event_t mBuffer[MAX_EVENTS];
sensors_event_t* mRead;
diff --git a/sensors/algo/akm/AKFS_AOC.c b/sensors/algo/akm/AKFS_AOC.c
deleted file mode 100644
index 41c115f..0000000
--- a/sensors/algo/akm/AKFS_AOC.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
- *
- * 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 "AKFS_AOC.h"
-#include "AKFS_Math.h"
-
-/*
- * CalcR
- */
-static AKFLOAT CalcR(
- const AKFVEC *x,
- const AKFVEC *y
-){
- int16 i;
- AKFLOAT r;
-
- r = 0.0;
- for (i = 0; i < 3; i++) {
- r += (x->v[i]-y->v[i]) * (x->v[i]-y->v[i]);
- }
- r = sqrt(r);
-
- return r;
-}
-
-/*
- * From4Points2Sphere()
- */
-static int16 From4Points2Sphere(
- const AKFVEC points[], /*!< (i/o) : input vectors */
- AKFVEC *center, /*!< (o) : center of sphere */
- AKFLOAT *r /*!< (i) : add/subtract value */
-){
- AKFLOAT dif[3][3];
- AKFLOAT r2[3];
-
- AKFLOAT A;
- AKFLOAT B;
- AKFLOAT C;
- AKFLOAT D;
- AKFLOAT E;
- AKFLOAT F;
- AKFLOAT G;
-
- AKFLOAT OU;
- AKFLOAT OD;
-
- int16 i, j;
-
- for (i = 0; i < 3; i++) {
- r2[i] = 0.0;
- for (j = 0; j < 3; j++) {
- dif[i][j] = points[i].v[j] - points[3].v[j];
- r2[i] += (points[i].v[j]*points[i].v[j]
- - points[3].v[j]*points[3].v[j]);
- }
- r2[i] *= 0.5;
- }
-
- A = dif[0][0]*dif[2][2] - dif[0][2]*dif[2][0];
- B = dif[0][1]*dif[2][0] - dif[0][0]*dif[2][1];
- C = dif[0][0]*dif[2][1] - dif[0][1]*dif[2][0];
- D = dif[0][0]*r2[2] - dif[2][0]*r2[0];
- E = dif[0][0]*dif[1][1] - dif[0][1]*dif[1][0];
- F = dif[1][0]*dif[0][2] - dif[0][0]*dif[1][2];
- G = dif[0][0]*r2[1] - dif[1][0]*r2[0];
-
- OU = D*E + B*G;
- OD = C*F + A*E;
-
- if (fabs(OD) < AKFS_EPSILON) {
- return -1;
- }
-
- center->v[2] = OU / OD;
-
- OU = F*center->v[2] + G;
- OD = E;
-
- if (fabs(OD) < AKFS_EPSILON) {
- return -1;
- }
-
- center->v[1] = OU / OD;
-
- OU = r2[0] - dif[0][1]*center->v[1] - dif[0][2]*center->v[2];
- OD = dif[0][0];
-
- if (fabs(OD) < AKFS_EPSILON) {
- return -1;
- }
-
- center->v[0] = OU / OD;
-
- *r = CalcR(&points[0], center);
-
- return 0;
-
-}
-
-/*
- * MeanVar
- */
-static void MeanVar(
- const AKFVEC v[], /*!< (i) : input vectors */
- const int16 n, /*!< (i) : number of vectors */
- AKFVEC *mean, /*!< (o) : (max+min)/2 */
- AKFVEC *var /*!< (o) : variation in vectors */
-){
- int16 i;
- int16 j;
- AKFVEC max;
- AKFVEC min;
-
- for (j = 0; j < 3; j++) {
- min.v[j] = v[0].v[j];
- max.v[j] = v[0].v[j];
- for (i = 1; i < n; i++) {
- if (v[i].v[j] < min.v[j]) {
- min.v[j] = v[i].v[j];
- }
- if (v[i].v[j] > max.v[j]) {
- max.v[j] = v[i].v[j];
- }
- }
- mean->v[j] = (max.v[j] + min.v[j]) / 2.0; /*mean */
- var->v[j] = max.v[j] - min.v[j]; /*var */
- }
-}
-
-/*
- * Get4points
- */
-static void Get4points(
- const AKFVEC v[], /*!< (i) : input vectors */
- const int16 n, /*!< (i) : number of vectors */
- AKFVEC out[] /*!< (o) : */
-){
- int16 i, j;
- AKFLOAT temp;
- AKFLOAT d;
-
- AKFVEC dv[AKFS_HBUF_SIZE];
- AKFVEC cross = {{0, 0, 0}};
- AKFVEC tempv = {{0, 0, 0}};
-
- /* out 0 */
- out[0] = v[0];
-
- /* out 1 */
- d = 0.0;
- for (i = 1; i < n; i++) {
- temp = CalcR(&v[i], &out[0]);
- if (d < temp) {
- d = temp;
- out[1] = v[i];
- }
- }
-
- /* out 2 */
- d = 0.0;
- for (j = 0; j < 3; j++) {
- dv[0].v[j] = out[1].v[j] - out[0].v[j];
- }
- for (i = 1; i < n; i++) {
- for (j = 0; j < 3; j++) {
- dv[i].v[j] = v[i].v[j] - out[0].v[j];
- }
- tempv.v[0] = dv[0].v[1]*dv[i].v[2] - dv[0].v[2]*dv[i].v[1];
- tempv.v[1] = dv[0].v[2]*dv[i].v[0] - dv[0].v[0]*dv[i].v[2];
- tempv.v[2] = dv[0].v[0]*dv[i].v[1] - dv[0].v[1]*dv[i].v[0];
- temp = tempv.u.x * tempv.u.x
- + tempv.u.y * tempv.u.y
- + tempv.u.z * tempv.u.z;
- if (d < temp) {
- d = temp;
- out[2] = v[i];
- cross = tempv;
- }
- }
-
- /* out 3 */
- d = 0.0;
- for (i = 1; i < n; i++) {
- temp = dv[i].u.x * cross.u.x
- + dv[i].u.y * cross.u.y
- + dv[i].u.z * cross.u.z;
- temp = fabs(temp);
- if (d < temp) {
- d = temp;
- out[3] = v[i];
- }
- }
-}
-
-/*
- * CheckInitFvec
- */
-static int16 CheckInitFvec(
- const AKFVEC *v /*!< [in] vector */
-){
- int16 i;
-
- for (i = 0; i < 3; i++) {
- if (AKFS_FMAX <= v->v[i]) {
- return 1; /* initvalue */
- }
- }
-
- return 0; /* not initvalue */
-}
-
-/*
- * AKFS_AOC
- */
-int16 AKFS_AOC( /*!< (o) : calibration success(AKFS_SUCCESS), failure(AKFS_ERROR) */
- AKFS_AOC_VAR *haocv, /*!< (i/o) : a set of variables */
- const AKFVEC *hdata, /*!< (i) : vectors of data */
- AKFVEC *ho /*!< (i/o) : offset */
-){
- int16 i, j;
- int16 num;
- AKFLOAT tempf;
- AKFVEC tempho;
-
- AKFVEC fourpoints[4];
-
- AKFVEC var;
- AKFVEC mean;
-
- /* buffer new data */
- for (i = 1; i < AKFS_HBUF_SIZE; i++) {
- haocv->hbuf[AKFS_HBUF_SIZE-i] = haocv->hbuf[AKFS_HBUF_SIZE-i-1];
- }
- haocv->hbuf[0] = *hdata;
-
- /* Check Init */
- num = 0;
- for (i = AKFS_HBUF_SIZE; 3 < i; i--) {
- if (CheckInitFvec(&haocv->hbuf[i-1]) == 0) {
- num = i;
- break;
- }
- }
- if (num < 4) {
- return AKFS_ERROR;
- }
-
- /* get 4 points */
- Get4points(haocv->hbuf, num, fourpoints);
-
- /* estimate offset */
- if (0 != From4Points2Sphere(fourpoints, &tempho, &haocv->hraoc)) {
- return AKFS_ERROR;
- }
-
- /* check distance */
- for (i = 0; i < 4; i++) {
- for (j = (i+1); j < 4; j++) {
- tempf = CalcR(&fourpoints[i], &fourpoints[j]);
- if ((tempf < haocv->hraoc) || (tempf < AKFS_HR_TH)) {
- return AKFS_ERROR;
- }
- }
- }
-
- /* update offset buffer */
- for (i = 1; i < AKFS_HOBUF_SIZE; i++) {
- haocv->hobuf[AKFS_HOBUF_SIZE-i] = haocv->hobuf[AKFS_HOBUF_SIZE-i-1];
- }
- haocv->hobuf[0] = tempho;
-
- /* clear hbuf */
- for (i = (AKFS_HBUF_SIZE>>1); i < AKFS_HBUF_SIZE; i++) {
- for (j = 0; j < 3; j++) {
- haocv->hbuf[i].v[j] = AKFS_FMAX;
- }
- }
-
- /* Check Init */
- if (CheckInitFvec(&haocv->hobuf[AKFS_HOBUF_SIZE-1]) == 1) {
- return AKFS_ERROR;
- }
-
- /* Check ovar */
- tempf = haocv->hraoc * AKFS_HO_TH;
- MeanVar(haocv->hobuf, AKFS_HOBUF_SIZE, &mean, &var);
- if ((var.u.x >= tempf) || (var.u.y >= tempf) || (var.u.z >= tempf)) {
- return AKFS_ERROR;
- }
-
- *ho = mean;
-
- return AKFS_SUCCESS;
-}
-
-/*
- * AKFS_InitAOC
- */
-void AKFS_InitAOC(
- AKFS_AOC_VAR *haocv
-){
- int16 i, j;
-
- /* Initialize buffer */
- for (i = 0; i < AKFS_HBUF_SIZE; i++) {
- for (j = 0; j < 3; j++) {
- haocv->hbuf[i].v[j] = AKFS_FMAX;
- }
- }
- for (i = 0; i < AKFS_HOBUF_SIZE; i++) {
- for (j = 0; j < 3; j++) {
- haocv->hobuf[i].v[j] = AKFS_FMAX;
- }
- }
-
- haocv->hraoc = 0.0;
-}
-
diff --git a/sensors/algo/akm/AKFS_AOC.h b/sensors/algo/akm/AKFS_AOC.h
deleted file mode 100644
index 7fff6c4..0000000
--- a/sensors/algo/akm/AKFS_AOC.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
- *
- * 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 AKFS_INC_AOC_H
-#define AKFS_INC_AOC_H
-
-#include "AKFS_Device.h"
-
-/***** Constant definition ****************************************************/
-#define AKFS_HBUF_SIZE 20
-#define AKFS_HOBUF_SIZE 4
-#define AKFS_HR_TH 10
-#define AKFS_HO_TH 0.15
-
-/***** Macro definition *******************************************************/
-
-/***** Type declaration *******************************************************/
-typedef struct _AKFS_AOC_VAR{
- AKFVEC hbuf[AKFS_HBUF_SIZE];
- AKFVEC hobuf[AKFS_HOBUF_SIZE];
- AKFLOAT hraoc;
-} AKFS_AOC_VAR;
-
-/***** Prototype of function **************************************************/
-AKLIB_C_API_START
-int16 AKFS_AOC(
- AKFS_AOC_VAR *haocv,
- const AKFVEC *hdata,
- AKFVEC *ho
-);
-
-void AKFS_InitAOC(
- AKFS_AOC_VAR *haocv
-);
-
-AKLIB_C_API_END
-
-#endif
-
diff --git a/sensors/algo/akm/AKFS_Configure.h b/sensors/algo/akm/AKFS_Configure.h
deleted file mode 100644
index 1f80f48..0000000
--- a/sensors/algo/akm/AKFS_Configure.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
- *
- * 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 AKFS_INC_CONFIG_H
-#define AKFS_INC_CONFIG_H
-
-/***** Language configuration *************************************************/
-#if defined(__cplusplus)
-#define AKLIB_C_API_START extern "C" {
-#define AKLIB_C_API_END }
-#else
-#define AKLIB_C_API_START
-#define AKLIB_C_API_END
-#endif
-
-/*! If following line is commented in, double type is used for floating point
- calculation */
-/*
-#define AKFS_PRECISION_DOUBLE
-*/
-
-#endif
-
diff --git a/sensors/algo/akm/AKFS_Decomp.c b/sensors/algo/akm/AKFS_Decomp.c
deleted file mode 100644
index da1d3ba..0000000
--- a/sensors/algo/akm/AKFS_Decomp.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
- *
- * 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 "AKFS_Decomp.h"
-#include "AKFS_Device.h"
-
-/******************************************************************************/
-/*! Convert from sensor local data unit to micro tesla, then buffer the data.
- @return #AKFS_SUCCESS on success. Otherwise the return value is #AKFS_ERROR.
- @param[in] mag
- @param[in] status
- @param[in] asa
- @param[in] nhdata
- @param[out] hdata
- */
-int16 AKFS_Decomp(
- const int16 mag[3],
- const int16 status,
- const uint8vec *asa,
- const int16 nhdata,
- AKFVEC hdata[]
-)
-{
- /* put st1 and st2 value */
- if (AKM_ST_ERROR(status)) {
- return AKFS_ERROR;
- }
-
- /* magnetic */
- AKFS_BufShift(nhdata, 1, hdata);
- hdata[0].u.x = AKM_HDATA_CONVERTER(mag[0], asa->u.x) * AKM_SENSITIVITY;
- hdata[0].u.y = AKM_HDATA_CONVERTER(mag[1], asa->u.y) * AKM_SENSITIVITY;
- hdata[0].u.z = AKM_HDATA_CONVERTER(mag[2], asa->u.z) * AKM_SENSITIVITY;
-
- return AKFS_SUCCESS;
-}
-
diff --git a/sensors/algo/akm/AKFS_Decomp.h b/sensors/algo/akm/AKFS_Decomp.h
deleted file mode 100644
index ef43fba..0000000
--- a/sensors/algo/akm/AKFS_Decomp.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
- *
- * 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 AKFS_INC_DECOMP_H
-#define AKFS_INC_DECOMP_H
-
-#include "AKFS_Device.h"
-
-/***** Constant definition ****************************************************/
-#if defined(AKM_DEVICE_AK8963)
-#define AKM_SENSITIVITY 0.15f
-#define AKM_ST_ERROR(st) (((st)&0x19) != 0x11)
-#define AKM_HDATA_CONVERTER(data, asa) \
- (AKFLOAT)(((data)*(((asa)/256.0f) + 0.5f)))
-
-#elif defined(AKM_DEVICE_AK8975)
-#define AKM_SENSITIVITY 0.3f
-#define AKM_ST_ERROR(st) (((st)&0x09) != 0x01)
-#define AKM_HDATA_CONVERTER(data, asa) \
- (AKFLOAT)(((data)*(((asa)/256.0f) + 0.5f)))
-
-#elif defined(AKM_DEVICE_AK09911)
-#define AKM_SENSITIVITY 0.6f
-#define AKM_ST_ERROR(st) (((st)&0x09) != 0x01)
-#define AKM_HDATA_CONVERTER(data, asa) \
- (AKFLOAT)(((data)*(((asa)/128.0f) + 1.0f)))
-
-#endif
-
-
-/***** Type declaration *******************************************************/
-
-/***** Prototype of function **************************************************/
-AKLIB_C_API_START
-int16 AKFS_Decomp(
- const int16 mag[3],
- const int16 status,
- const uint8vec *asa,
- const int16 nhdata,
- AKFVEC hdata[]
-);
-AKLIB_C_API_END
-
-#endif
diff --git a/sensors/algo/akm/AKFS_Device.c b/sensors/algo/akm/AKFS_Device.c
deleted file mode 100644
index 75c36c3..0000000
--- a/sensors/algo/akm/AKFS_Device.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
- *
- * 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 "AKFS_Device.h"
-
-/******************************************************************************/
-/*! Initialize #AKFVEC array.
- @return #AKFS_SUCCESS on success. Otherwise the return value is #AKFS_ERROR.
- @param[in] ndata
- @param[out] vdata
- */
-int16 AKFS_InitBuffer(
- const int16 ndata, /*!< Size of vector buffer */
- AKFVEC vdata[] /*!< Vector buffer */
-)
-{
- int i;
-
- /* size check */
- if (ndata <= 0) {
- return AKFS_ERROR;
- }
-
- for (i = 0; i < ndata; i++) {
- vdata[i].u.x = AKFS_INIT_VALUE_F;
- vdata[i].u.y = AKFS_INIT_VALUE_F;
- vdata[i].u.z = AKFS_INIT_VALUE_F;
- }
-
- return AKFS_SUCCESS;
-}
-
-/******************************************************************************/
-/*! Shift #AKFVEC array.
- @return #AKFS_SUCCESS on success. Otherwise the return value is #AKFS_ERROR.
- @param[in] len
- @param[in] shift
- @param[in/out] v
- */
-int16 AKFS_BufShift(
- const int16 len, /*!< size of buffer */
- const int16 shift, /*!< shift size */
- AKFVEC v[] /*!< buffer */
-)
-{
- int16 i;
-
- if ((shift < 1) || (len < shift)) {
- return AKFS_ERROR;
- }
- for (i = len-1; i >= shift; i--) {
- v[i] = v[i-shift];
- }
- return AKFS_SUCCESS;
-}
-
-/******************************************************************************/
-/*! Rotate vector according to the specified layout pattern number.
- @return #AKFS_SUCCESS on success. Otherwise the return value is #AKFS_ERROR.
- @param[in] pat
- @param[in/out] vec
- */
-int16 AKFS_Rotate(
- const AKFS_PATNO pat,
- AKFVEC *vec
-)
-{
- AKFLOAT tmp;
- switch (pat) {
- /* Obverse */
- case PAT1:
- /* This is Android default */
- break;
- case PAT2:
- tmp = vec->u.x;
- vec->u.x = vec->u.y;
- vec->u.y = -tmp;
- break;
- case PAT3:
- vec->u.x = -(vec->u.x);
- vec->u.y = -(vec->u.y);
- break;
- case PAT4:
- tmp = vec->u.x;
- vec->u.x = -(vec->u.y);
- vec->u.y = tmp;
- break;
- /* Reverse */
- case PAT5:
- vec->u.x = -(vec->u.x);
- vec->u.z = -(vec->u.z);
- break;
- case PAT6:
- tmp = vec->u.x;
- vec->u.x = vec->u.y;
- vec->u.y = tmp;
- vec->u.z = -(vec->u.z);
- break;
- case PAT7:
- vec->u.y = -(vec->u.y);
- vec->u.z = -(vec->u.z);
- break;
- case PAT8:
- tmp = vec->u.x;
- vec->u.x = -(vec->u.y);
- vec->u.y = -tmp;
- vec->u.z = -(vec->u.z);
- break;
- default:
- return AKFS_ERROR;
- }
-
- return AKFS_SUCCESS;
-}
-
-/******************************************************************************/
-/*! Rotate vector according to the specified layout matrix.
- @return #AKFS_SUCCESS on success. Otherwise the return value is #AKFS_ERROR.
- @param[in] pat
- @param[in/out] vec
- */
-int16 AKFS_RotateMat(
- const int16 layout[3][3],
- AKFVEC *vec
-)
-{
- AKFVEC tmp;
-
- tmp.u.x = layout[0][0]*vec->u.x + layout[0][1]*vec->u.y + layout[0][2]*vec->u.z;
- tmp.u.y = layout[1][0]*vec->u.x + layout[1][1]*vec->u.y + layout[1][2]*vec->u.z;
- tmp.u.z = layout[2][0]*vec->u.x + layout[2][1]*vec->u.y + layout[2][2]*vec->u.z;
-
- *vec = tmp;
-
- return AKFS_SUCCESS;
-}
diff --git a/sensors/algo/akm/AKFS_Device.h b/sensors/algo/akm/AKFS_Device.h
deleted file mode 100644
index e1893e8..0000000
--- a/sensors/algo/akm/AKFS_Device.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
- *
- * 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 AKFS_INC_DEVICE_H
-#define AKFS_INC_DEVICE_H
-
-#include <float.h>
-#include "AKFS_Configure.h"
-
-/***** Constant definition ****************************************************/
-#define AKFS_ERROR 0
-#define AKFS_SUCCESS 1
-
-#define AKFS_HDATA_SIZE 32
-#define AKFS_ADATA_SIZE 32
-
-/***** Type declaration *******************************************************/
-typedef signed char int8;
-typedef signed short int16;
-typedef unsigned char uint8;
-typedef unsigned short uint16;
-
-
-#ifdef AKFS_PRECISION_DOUBLE
-typedef double AKFLOAT;
-#define AKFS_EPSILON DBL_EPSILON
-#define AKFS_FMAX DBL_MAX
-#define AKFS_FMIN DBL_MIN
-
-#else
-typedef float AKFLOAT;
-#define AKFS_EPSILON FLT_EPSILON
-#define AKFS_FMAX FLT_MAX
-#define AKFS_FMIN FLT_MIN
-
-#endif
-
-/* Treat maximum value as initial value */
-#define AKFS_INIT_VALUE_F AKFS_FMAX
-
-/***** Vector ****************************************************************/
-typedef union _uint8vec {
- struct {
- uint8 x;
- uint8 y;
- uint8 z;
- } u;
- uint8 v[3];
-} uint8vec;
-
-typedef union _AKFVEC {
- struct {
- AKFLOAT x;
- AKFLOAT y;
- AKFLOAT z;
- } u;
- AKFLOAT v[3];
-} AKFVEC;
-
-/***** Layout pattern ********************************************************/
-typedef enum _AKFS_PATNO {
- PAT_INVALID = 0,
- PAT1, /* obverse: 1st pin is right down */
- PAT2, /* obverse: 1st pin is left down */
- PAT3, /* obverse: 1st pin is left top */
- PAT4, /* obverse: 1st pin is right top */
- PAT5, /* reverse: 1st pin is left down (from top view) */
- PAT6, /* reverse: 1st pin is left top (from top view) */
- PAT7, /* reverse: 1st pin is right top (from top view) */
- PAT8 /* reverse: 1st pin is right down (from top view) */
-} AKFS_PATNO;
-
-/***** Prototype of function **************************************************/
-AKLIB_C_API_START
-int16 AKFS_InitBuffer(
- const int16 ndata, /*!< Size of raw vector buffer */
- AKFVEC vdata[] /*!< Raw vector buffer */
-);
-
-int16 AKFS_BufShift(
- const int16 len,
- const int16 shift,
- AKFVEC v[]
-);
-
-int16 AKFS_Rotate(
- const AKFS_PATNO pat,
- AKFVEC *vec
-);
-
-int16 AKFS_RotateMat(
- const int16 layout[3][3],
- AKFVEC *vec
-);
-AKLIB_C_API_END
-
-#endif
-
diff --git a/sensors/algo/akm/AKFS_Direction.c b/sensors/algo/akm/AKFS_Direction.c
deleted file mode 100644
index 2107e7e..0000000
--- a/sensors/algo/akm/AKFS_Direction.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
- *
- * 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 "AKFS_Device.h"
-#include "AKFS_Direction.h"
-#include "AKFS_VNorm.h"
-#include "AKFS_Math.h"
-
-/******************************************************************************/
-/* About definition of coordinate system and calculated value.
- Coordinate system is right-handed.
- X-Axis: from left to right.
- Y-Axis: from bottom to top.
- Z-Axis: from reverse to obverse.
-
- azimuth: Rotation around Z axis, with positive values
- when y-axis moves toward the x-axis.
- pitch: Rotation around X axis, with positive values
- when z-axis moves toward the y-axis.
- roll: Rotation around Y axis, with positive values
- when x-axis moves toward the z-axis.
-*/
-
-
-/******************************************************************************/
-/*! This function is used internally, so output is RADIAN!
- @return #AKFS_SUCCESS on success. Otherwise the return value is #AKFS_ERROR.
- @param[in] avec
- @param[out] pitch
- @param[out] roll
- */
-static int16 AKFS_Angle(
- const AKFVEC *avec,
- AKFLOAT *pitch, /* radian */
- AKFLOAT *roll /* radian */
-)
-{
- AKFLOAT av; /* Size of vector */
-
- av = AKFS_SQRT((avec->u.x)*(avec->u.x) + (avec->u.y)*(avec->u.y) + (avec->u.z)*(avec->u.z));
-
- if (av < AKFS_EPSILON) {
- return AKFS_ERROR;
- }
-
- *pitch = AKFS_ASIN(-(avec->u.y) / av);
- *roll = AKFS_ASIN((avec->u.x) / av);
-
- return AKFS_SUCCESS;
-}
-
-/******************************************************************************/
-/*! This function is used internally, so output is RADIAN!
- @return None
- @param[in] hvec
- @param[in] pitch
- @param[in] roll
- @param[out] azimuth
- */
-static void AKFS_Azimuth(
- const AKFVEC *hvec,
- const AKFLOAT pitch, /* radian */
- const AKFLOAT roll, /* radian */
- AKFLOAT *azimuth /* radian */
-)
-{
- AKFLOAT sinP; /* sin value of pitch angle */
- AKFLOAT cosP; /* cos value of pitch angle */
- AKFLOAT sinR; /* sin value of roll angle */
- AKFLOAT cosR; /* cos value of roll angle */
- AKFLOAT Xh; /* X axis element of vector which is projected to horizontal plane */
- AKFLOAT Yh; /* Y axis element of vector which is projected to horizontal plane */
-
- sinP = AKFS_SIN(pitch);
- cosP = AKFS_COS(pitch);
- sinR = AKFS_SIN(roll);
- cosR = AKFS_COS(roll);
-
- Yh = -(hvec->u.x)*cosR + (hvec->u.z)*sinR;
- Xh = (hvec->u.x)*sinP*sinR + (hvec->u.y)*cosP + (hvec->u.z)*sinP*cosR;
-
- /* atan2(y, x) -> divisor and dividend is opposite from mathematical equation. */
- *azimuth = AKFS_ATAN2(Yh, Xh);
-}
-
-/******************************************************************************/
-/*! Output is DEGREE!
- @return #AKFS_SUCCESS on success. Otherwise the return value is #AKFS_ERROR.
- @param[in] nhvec
- @param[in] hvec
- @param[in] hnave
- @param[in] navec
- @param[in] avec
- @param[in] anave
- @param[out] azimuth
- @param[out] pitch
- @param[out] roll
- */
-int16 AKFS_Direction(
- const int16 nhvec,
- const AKFVEC hvec[],
- const int16 hnave,
- const int16 navec,
- const AKFVEC avec[],
- const int16 anave,
- AKFLOAT *azimuth,
- AKFLOAT *pitch,
- AKFLOAT *roll
-)
-{
- AKFVEC have, aave;
- AKFLOAT azimuthRad;
- AKFLOAT pitchRad;
- AKFLOAT rollRad;
-
- /* arguments check */
- if ((nhvec <= 0) || (navec <= 0) || (hnave <= 0) || (anave <= 0)) {
- return AKFS_ERROR;
- }
- if ((nhvec < hnave) || (navec < anave)) {
- return AKFS_ERROR;
- }
-
- /* average */
- if (AKFS_VbAve(nhvec, hvec, hnave, &have) != AKFS_SUCCESS) {
- return AKFS_ERROR;
- }
- if (AKFS_VbAve(navec, avec, anave, &aave) != AKFS_SUCCESS) {
- return AKFS_ERROR;
- }
-
- /* calculate pitch and roll */
- if (AKFS_Angle(&aave, &pitchRad, &rollRad) != AKFS_SUCCESS) {
- return AKFS_ERROR;
- }
-
- /* calculate azimuth */
- AKFS_Azimuth(&have, pitchRad, rollRad, &azimuthRad);
-
- *azimuth = RAD2DEG(azimuthRad);
- *pitch = RAD2DEG(pitchRad);
- *roll = RAD2DEG(rollRad);
-
- /* Adjust range of azimuth */
- if (*azimuth < 0) {
- *azimuth += 360.0f;
- }
-
- return AKFS_SUCCESS;
-}
-
-
diff --git a/sensors/algo/akm/AKFS_Direction.h b/sensors/algo/akm/AKFS_Direction.h
deleted file mode 100644
index fe1dc13..0000000
--- a/sensors/algo/akm/AKFS_Direction.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
- *
- * 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 AKFS_INC_DIRECTION_H
-#define AKFS_INC_DIRECTION_H
-
-#include "AKFS_Device.h"
-
-/***** Prototype of function **************************************************/
-AKLIB_C_API_START
-int16 AKFS_Direction(
- const int16 nhvec,
- const AKFVEC hvec[],
- const int16 hnave,
- const int16 navec,
- const AKFVEC avec[],
- const int16 anave,
- AKFLOAT *azimuth,
- AKFLOAT *pitch,
- AKFLOAT *roll
-);
-AKLIB_C_API_END
-
-#endif
-
diff --git a/sensors/algo/akm/AKFS_Math.h b/sensors/algo/akm/AKFS_Math.h
deleted file mode 100644
index dfe48b3..0000000
--- a/sensors/algo/akm/AKFS_Math.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
- *
- * 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 AKFS_INC_MATH_H
-#define AKFS_INC_MATH_H
-
-#include <math.h>
-#include "AKFS_Configure.h"
-
-/***** Constant definition ****************************************************/
-#define AKFS_PI 3.141592654f
-#define RAD2DEG(rad) ((rad)*180.0f/AKFS_PI)
-
-/***** Macro definition *******************************************************/
-
-#ifdef AKFS_PRECISION_DOUBLE
-#define AKFS_SIN(x) sin(x)
-#define AKFS_COS(x) cos(x)
-#define AKFS_ASIN(x) asin(x)
-#define AKFS_ACOS(x) acos(x)
-#define AKFS_ATAN2(y, x) atan2((y), (x))
-#define AKFS_SQRT(x) sqrt(x)
-#else
-#define AKFS_SIN(x) sinf(x)
-#define AKFS_COS(x) cosf(x)
-#define AKFS_ASIN(x) asinf(x)
-#define AKFS_ACOS(x) acosf(x)
-#define AKFS_ATAN2(y, x) atan2f((y), (x))
-#define AKFS_SQRT(x) sqrtf(x)
-#endif
-
-#endif
-
diff --git a/sensors/algo/akm/AKFS_VNorm.c b/sensors/algo/akm/AKFS_VNorm.c
deleted file mode 100644
index 5372a36..0000000
--- a/sensors/algo/akm/AKFS_VNorm.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
- *
- * 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 "AKFS_Device.h"
-#include "AKFS_VNorm.h"
-
-/******************************************************************************/
-/*! Normalize vector.
- @return #AKFS_SUCCESS on success. Otherwise the return value is #AKFS_ERROR.
- @param[in] ndata Size of raw vector buffer
- @param[in] vdata Raw vector buffer
- @param[in] nbuf Size of data to be buffered
- @param[in] o Offset
- @param[in] s Sensitivity
- @param[in] tgt Target sensitivity
- @param[in] nvec Size of normalized vector buffer
- @param[out] vvec Normalized vector buffer
- */
-int16 AKFS_VbNorm(
- const int16 ndata,
- const AKFVEC vdata[],
- const int16 nbuf,
- const AKFVEC *o,
- const AKFVEC *s,
- const AKFLOAT tgt,
- const int16 nvec,
- AKFVEC vvec[]
-)
-{
- int i;
-
- /* size check */
- if ((ndata <= 0) || (nvec <= 0) || (nbuf <= 0)) {
- return AKFS_ERROR;
- }
- /* dependency check */
- if ((nbuf < 1) || (ndata < nbuf) || (nvec < nbuf)) {
- return AKFS_ERROR;
- }
- /* sensitivity check */
- if ((s->u.x <= AKFS_EPSILON) ||
- (s->u.y <= AKFS_EPSILON) ||
- (s->u.z <= AKFS_EPSILON) ||
- (tgt <= 0)) {
- return AKFS_ERROR;
- }
-
- /* calculate and store data to buffer */
- if (AKFS_BufShift(nvec, nbuf, vvec) != AKFS_SUCCESS) {
- return AKFS_ERROR;
- }
- for (i = 0; i < nbuf; i++) {
- vvec[i].u.x = ((vdata[i].u.x - o->u.x) / (s->u.x) * (AKFLOAT)tgt);
- vvec[i].u.y = ((vdata[i].u.y - o->u.y) / (s->u.y) * (AKFLOAT)tgt);
- vvec[i].u.z = ((vdata[i].u.z - o->u.z) / (s->u.z) * (AKFLOAT)tgt);
- }
-
- return AKFS_SUCCESS;
-}
-
-/******************************************************************************/
-/*! Calculate an averaged vector form a given buffer.
- @return #AKFS_SUCCESS on success. Otherwise the return value is #AKFS_ERROR.
- @param[in] nvec Size of normalized vector buffer
- @param[in] vvec Normalized vector buffer
- @param[in] nave Number of average
- @param[out] vave Averaged vector
- */
-int16 AKFS_VbAve(
- const int16 nvec,
- const AKFVEC vvec[],
- const int16 nave,
- AKFVEC *vave
-)
-{
- int i;
-
- /* arguments check */
- if ((nave <= 0) || (nvec <= 0) || (nvec < nave)) {
- return AKFS_ERROR;
- }
-
- /* calculate average */
- vave->u.x = 0;
- vave->u.y = 0;
- vave->u.z = 0;
- for (i = 0; i < nave; i++) {
- if ((vvec[i].u.x == AKFS_INIT_VALUE_F) ||
- (vvec[i].u.y == AKFS_INIT_VALUE_F) ||
- (vvec[i].u.z == AKFS_INIT_VALUE_F)) {
- break;
- }
- vave->u.x += vvec[i].u.x;
- vave->u.y += vvec[i].u.y;
- vave->u.z += vvec[i].u.z;
- }
- if (i == 0) {
- vave->u.x = 0;
- vave->u.y = 0;
- vave->u.z = 0;
- } else {
- vave->u.x /= i;
- vave->u.y /= i;
- vave->u.z /= i;
- }
- return AKFS_SUCCESS;
-}
-
-
diff --git a/sensors/algo/akm/AKFS_VNorm.h b/sensors/algo/akm/AKFS_VNorm.h
deleted file mode 100644
index 92dd949..0000000
--- a/sensors/algo/akm/AKFS_VNorm.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
- *
- * 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 AKFS_INC_VNORM_H
-#define AKFS_INC_VNORM_H
-
-#include "AKFS_Device.h"
-
-/***** Prototype of function **************************************************/
-AKLIB_C_API_START
-int16 AKFS_VbNorm(
- const int16 ndata,
- const AKFVEC vdata[],
- const int16 nbuf,
- const AKFVEC *o,
- const AKFVEC *s,
- const AKFLOAT tgt,
- const int16 nvec,
- AKFVEC vvec[]
-);
-
-int16 AKFS_VbAve(
- const int16 nvec,
- const AKFVEC vvec[],
- const int16 nave,
- AKFVEC *vave
-);
-
-AKLIB_C_API_END
-
-#endif
-
diff --git a/sensors/algo/akm/NOTICE b/sensors/algo/akm/NOTICE
deleted file mode 100644
index d645695..0000000
--- a/sensors/algo/akm/NOTICE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
diff --git a/sensors/algo/akm/README.md b/sensors/algo/akm/README.md
deleted file mode 100644
index a3e3803..0000000
--- a/sensors/algo/akm/README.md
+++ /dev/null
@@ -1,34 +0,0 @@
-AK8975/AK8963/AK09911 Sensor Daemon for Android.
-=========
-Compass Control Program for Android Open Source Project
-
-## NOTICE
- 1. Asahi Kasei Microdevices Corporation ("AKM") is pleased to make available to you the source codes of the Electronic Compass Control Program ("Software") for download from this website at no charge. By downloading the Software, you expressly assume all risk and liability associated with downloading and using the Software.
-
- 2. AKM PROVIDES THE SOFTWARE AND THIS DOWNLOADING SERVICE "AS IS" WITHOUT WARRANTY OF ANY KIND AND ALL SUCH WARRANTIES, EXPRESS OR IMPLIED, ARE HEREBY DISCLAIMED, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE ACCURACY, AVAILABILITY, OR NON-INFRINGEMENT. YOU ACKNOWLEDGE THAT AKM IS NOT OBLIGATED TO PROVIDE AND DOES NOT PROVIDE ANY SUPPORT OR ASSISTANCE WITH RESPECT TO THE SOFTWARE.
-
- 3. This downloading service shall not affect nor extend any warranty or disclaimer which AKM makes in each of AKM's products in which the Software works with.
-
- 4. This NOTICE shall be governed by and interpreted under the laws of Japan. All disputes arising out of or under this NOTICE shall be subject to under the exclusive and agreed jurisdiction of the Tokyo District Court as the court of first instance.
-
-## About
-This software is developed by Asahi Kasei Microdevices Corporation ("AKM") to provide compatible daemon program, it is known as akmd2 in many production Android phones.
-
-This software consists from two parts, one is Sensor Control Program (i.e. akmd2) and Sensor HAL (sensors.*.so). Sensor Control Program gets magnetic sensor data form the AKM's compass IC, then estimate offset and calculate azimuth, pitch and roll angle. This behavior is quite similar to the original one. We aimed to develop a compatible daemon software.
-
-This software may help people who wants to study how to control AKM's magnetic sensor on Android.
-
-## License
-The license for all code in this source code is specified in the NOTICE file. Please, refer to this file for further details.
-
-## Build
-To build this project, uncomment your desired device from the top of Android.mk file.
-
- vi $(YOUR_ENV)/AK8975_FS/Android.mk
-
-For example, if you wish to have a software for AK8975, please uncomment the following line.
-
- export AKMD_DEVICE_TYPE=8975
-
-Type 'mm -B', then you will get two binary files, **akmdfs** and **sensors.default.so**.
-
diff --git a/sensors/algo/akm/akm_wrapper.c b/sensors/algo/akm/akm_wrapper.c
deleted file mode 100644
index e790b33..0000000
--- a/sensors/algo/akm/akm_wrapper.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*--------------------------------------------------------------------------
-Copyright (c) 2014, The Linux Foundation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of The Linux Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
-
-#include <stdio.h>
-#include <CalibrationModule.h>
-
-#define LOG_TAG "sensor_cal.akm"
-#include <utils/Log.h>
-
-#include "AKFS_Device.h"
-#include "AKFS_Decomp.h"
-#include "AKFS_AOC.h"
-#include "AKFS_Math.h"
-#include "AKFS_VNorm.h"
-
-#define SENSOR_CAL_ALGO_VERSION 1
-#define AKM_MAG_SENSE (1.0)
-#define CSPEC_HNAVE_V 8
-#define AKFS_GEOMAG_MAX 70
-
-struct sensor_cal_module_t SENSOR_CAL_MODULE_INFO;
-static struct sensor_cal_algo_t algo_list[];
-
-/*! A parameter structure. */
-/* ix*_ : x-bit integer */
-/* f**_ : floating value */
-/* p**_ : pointer */
-/* e**_ : enum */
-/* *s*_ : struct */
-/* *v*_ : vector (special type of struct) */
-/* **a_ : array */
-typedef struct _AKMPRMS{
-
- /* Variables for Decomp. */
- AKFVEC fva_hdata[AKFS_HDATA_SIZE];
- uint8vec i8v_asa;
-
- /* Variables forAOC. */
- AKFS_AOC_VAR s_aocv;
-
- /* Variables for Magnetometer buffer. */
- AKFVEC fva_hvbuf[AKFS_HDATA_SIZE];
- AKFVEC fv_ho;
- AKFVEC fv_hs;
- AKFS_PATNO e_hpat;
-
- /* Variables for Accelerometer buffer. */
- AKFVEC fva_avbuf[AKFS_ADATA_SIZE];
- AKFVEC fv_ao;
- AKFVEC fv_as;
-
- /* Variables for Direction. */
- AKFLOAT f_azimuth;
- AKFLOAT f_pitch;
- AKFLOAT f_roll;
-
- /* Variables for vector output */
- AKFVEC fv_hvec;
- AKFVEC fv_avec;
- int16 i16_hstatus;
-
-} AKMPRMS;
-
-static AKMPRMS g_prms;
-
-static int convert_magnetic(sensors_vec_t *raw, sensors_vec_t *result,
- struct sensor_algo_args *args)
-{
- int16 akret;
- int16 aocret;
- AKFLOAT radius;
- AKMPRMS *prms = &g_prms;
- int i;
-
- /* Shift out old data from the buffer for better calibration */
- for (i = AKFS_HDATA_SIZE - 1; i >= 1; i--) {
- prms->fva_hdata[i] = prms->fva_hdata[i - 1];
- }
-
- prms->fva_hdata[0].u.x = raw->x;
- prms->fva_hdata[0].u.y = raw->y;
- prms->fva_hdata[0].u.z = raw->z;
-
- /* Offset calculation is done in this function */
- /* hdata[in] : Android coordinate, sensitivity adjusted. */
- /* ho [out]: Android coordinate, sensitivity adjusted. */
- aocret = AKFS_AOC(
- &prms->s_aocv,
- prms->fva_hdata,
- &prms->fv_ho
- );
-
- /* Subtract offset */
- /* hdata[in] : Android coordinate, sensitivity adjusted. */
- /* ho [in] : Android coordinate, sensitivity adjusted. */
- /* hvbuf[out]: Android coordinate, sensitivity adjusted, */
- /* offset subtracted. */
- akret = AKFS_VbNorm(
- AKFS_HDATA_SIZE,
- prms->fva_hdata,
- 1,
- &prms->fv_ho,
- &prms->fv_hs,
- AKM_MAG_SENSE,
- AKFS_HDATA_SIZE,
- prms->fva_hvbuf
- );
- if (akret == AKFS_ERROR) {
- ALOGE("error here!");
- return -1;
- }
-
- /* Averaging */
- /* hvbuf[in] : Android coordinate, sensitivity adjusted, */
- /* offset subtracted. */
- /* hvec [out]: Android coordinate, sensitivity adjusted, */
- /* offset subtracted, averaged. */
- akret = AKFS_VbAve(
- AKFS_HDATA_SIZE,
- prms->fva_hvbuf,
- CSPEC_HNAVE_V,
- &prms->fv_hvec
- );
- if (akret == AKFS_ERROR) {
- ALOGE("error here!");
- return -1;
- }
-
- /* Check the size of magnetic vector */
- radius = AKFS_SQRT(
- (prms->fv_hvec.u.x * prms->fv_hvec.u.x) +
- (prms->fv_hvec.u.y * prms->fv_hvec.u.y) +
- (prms->fv_hvec.u.z * prms->fv_hvec.u.z));
-
- if (radius > AKFS_GEOMAG_MAX) {
- prms->i16_hstatus = 0;
- } else {
- if (aocret == AKFS_SUCCESS) {
- prms->i16_hstatus = 3;
- }
- }
-
- result->x = prms->fv_hvec.u.x;
- result->y = prms->fv_hvec.u.y;
- result->z = prms->fv_hvec.u.z;
- result->status = prms->i16_hstatus;
-
- return 0;
-}
-
-static int config_magnetic(int cmd, struct sensor_algo_args *args)
-{
- struct compass_algo_args *param = (struct compass_algo_args*)args;
-
- switch (cmd) {
- case CMD_ENABLE:
- ALOGD("Enable status changed to %d\n", param->common.enable);
- break;
- case CMD_DELAY:
- ALOGD("Polling rate changed to %d\n", param->common.delay_ms);
- break;
- case CMD_BATCH:
- break;
- }
-
- return 0;
-}
-
-static int cal_init(const struct sensor_cal_module_t *module)
-{
- AKMPRMS *prms = &g_prms;
-
- /* Clear all data. */
- memset(prms, 0, sizeof(AKMPRMS));
-
- /* Sensitivity */
- prms->fv_hs.u.x = AKM_MAG_SENSE;
- prms->fv_hs.u.y = AKM_MAG_SENSE;
- prms->fv_hs.u.z = AKM_MAG_SENSE;
-
- /* Initialize buffer */
- AKFS_InitBuffer(AKFS_HDATA_SIZE, prms->fva_hdata);
- AKFS_InitBuffer(AKFS_HDATA_SIZE, prms->fva_hvbuf);
- AKFS_InitBuffer(AKFS_ADATA_SIZE, prms->fva_avbuf);
-
- /* Initialize for AOC */
- AKFS_InitAOC(&prms->s_aocv);
- /* Initialize magnetic status */
- prms->i16_hstatus = 0;
-
- return 0;
-}
-
-static void cal_deinit()
-{
- ALOGI("%s called\n", __func__);
-}
-
-static int cal_get_algo_list(const struct sensor_cal_algo_t **algo)
-{
- *algo = algo_list;
- return 0;
-}
-
-static struct sensor_algo_methods_t algo_methods = {
- .convert = convert_magnetic,
- .config = config_magnetic,
-};
-
-static const char* sensor_match_table[] = {
- "akm09911-mag",
- "akm8963-mag",
- "compass",
- NULL
-};
-
-static struct sensor_cal_algo_t algo_list[] = {
- {
- .tag = SENSOR_CAL_ALGO_TAG,
- .version = SENSOR_CAL_ALGO_VERSION,
- .type = SENSOR_TYPE_MAGNETIC_FIELD,
- .compatible = sensor_match_table,
- .module = &SENSOR_CAL_MODULE_INFO,
- .methods = &algo_methods,
- },
-};
-
-static struct sensor_cal_methods_t cal_methods = {
- .init = cal_init,
- .deinit = cal_deinit,
- .get_algo_list = cal_get_algo_list,
-};
-
-struct sensor_cal_module_t SENSOR_CAL_MODULE_INFO = {
- .tag = SENSOR_CAL_MODULE_TAG,
- .id = "cal_module_akm",
- .version = SENSOR_CAL_MODULE_VERSION,
- .vendor = "akm",
- .dso = NULL,
- .number = 1,
- .methods = &cal_methods,
- .reserved = {0},
-};
diff --git a/sensors/algo/common/common_wrapper.c b/sensors/algo/common/common_wrapper.c
index 9419947..39b1327 100644
--- a/sensors/algo/common/common_wrapper.c
+++ b/sensors/algo/common/common_wrapper.c
@@ -105,6 +105,9 @@ typedef struct _AKMPRMS{
} AKMPRMS;
static AKMPRMS g_prms;
+static float last_pocket = -1.0f;
+static float last_light = -1.0f;
+static float last_proximity = -1.0f;
static int convert_magnetic(sensors_event_t *raw, sensors_event_t *result,
struct sensor_algo_args *args __attribute__((unused)))
@@ -288,7 +291,7 @@ static int convert_rotation_vector(sensors_event_t *raw, sensors_event_t *result
return 0;
}
-static int config_magnetic(int cmd, struct sensor_algo_args *args __attribute__((unused)))
+static int config_magnetic(int cmd, struct sensor_algo_args *args)
{
struct compass_algo_args *param = (struct compass_algo_args*)args;
@@ -325,6 +328,65 @@ static int convert_uncalibrated_magnetic(sensors_event_t *raw, sensors_event_t *
return -1;
}
+static int convert_pocket(sensors_event_t *raw, sensors_event_t *result,
+ struct sensor_algo_args *args __attribute__((unused)))
+{
+ float inside;
+
+ *result = *raw;
+ if (raw->type == SENSOR_TYPE_PROXIMITY) {
+ last_proximity = raw->data[0];
+ } else if (raw->type == SENSOR_TYPE_LIGHT) {
+ last_light = raw->data[0];
+ } else {
+ ALOGE("type error:%d\n", raw->type);
+ return -1;
+ }
+
+ ALOGD("last_light:%f last_proximity:%f\n", last_light, last_proximity);
+
+ if (last_proximity < 0.0f) {
+ if (last_light < 0.0f) {
+ ALOGE("sensor data error\n");
+ return -1;
+ } else if (last_light > 1000.0f) {
+ inside = 0;
+ } else {
+ inside = 1;
+ }
+ } else if (last_proximity < 5.0f) {
+ inside = 1;
+ } else {
+ inside = 0;
+ }
+
+ if (last_pocket != inside) {
+ last_pocket = inside;
+ result->data[0] = inside;
+ return 0;
+ }
+
+ return -1;
+}
+
+static int config_pocket(int cmd, struct sensor_algo_args *args)
+{
+ struct compass_algo_args *param = (struct compass_algo_args*)args;
+
+ switch (cmd) {
+ case CMD_ENABLE:
+ ALOGD("Enable status changed to %d\n", param->common.enable);
+ if (param->common.enable) {
+ last_pocket = -1.0f;
+ last_light = -1.0f;
+ last_proximity = -1.0f;
+ }
+ break;
+ }
+
+ return 0;
+}
+
static int cal_init(const struct sensor_cal_module_t *module __attribute__((unused)))
{
AKMPRMS *prms = &g_prms;
@@ -401,6 +463,19 @@ static const char* mag_uncalib_match_table[] = {
NULL
};
+static struct sensor_algo_methods_t pocket_methods = {
+ .convert = convert_pocket,
+ .config = config_pocket,
+};
+
+static const char* pocket_match_table[] = {
+ "liteon-pocket",
+ "ltr553-pocket",
+ "ap3426-pocket",
+ "oem-pocket",
+ NULL
+};
+
static struct sensor_cal_algo_t algo_list[] = {
{
.tag = SENSOR_CAL_ALGO_TAG,
@@ -438,6 +513,15 @@ static struct sensor_cal_algo_t algo_list[] = {
.methods = &mag_uncalib_methods,
},
+ {
+ .tag = SENSOR_CAL_ALGO_TAG,
+ .version = SENSOR_CAL_ALGO_VERSION,
+ .type = SENSOR_TYPE_POCKET,
+ .compatible = pocket_match_table,
+ .module = &SENSOR_CAL_MODULE_INFO,
+ .methods = &pocket_methods,
+ },
+
};
static struct sensor_cal_methods_t cal_methods = {
diff --git a/sensors/calmodule.cfg b/sensors/calmodule.cfg
index 6fb4f3b..1153aea 100644
--- a/sensors/calmodule.cfg
+++ b/sensors/calmodule.cfg
@@ -1,2 +1,5 @@
-libcalmodule_akm.so
libcalmodule_common.so
+libcalmodule_gyroscope.so
+libcalmodule_qti_algo.so
+libcalmodule_akm.so
+libcalmodule_yamaha.so
diff --git a/sensors/sensors.cpp b/sensors/sensors.cpp
index bf78200..333df83 100644
--- a/sensors/sensors.cpp
+++ b/sensors/sensors.cpp
@@ -35,7 +35,6 @@
#include "AccelSensor.h"
#include "LightSensor.h"
#include "ProximitySensor.h"
-#include "AkmSensor.h"
#include "CompassSensor.h"
#include "GyroSensor.h"
@@ -91,15 +90,17 @@ struct sensors_module_t HAL_MODULE_INFO_SYM = {
};
struct sensors_poll_context_t {
+ // extension for sensors_poll_device_1, must be first
struct sensors_poll_device_1_ext_t device;// must be first
-
- sensors_poll_context_t();
- ~sensors_poll_context_t();
+ 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 handleCommandPipe();
int calibrate(int handle, cal_cmd_t *para);
+ int batch(int handle, int sample_ns, int latency_ns);
+ int flush(int handle);
private:
struct pollfd mPollFds[MAX_SENSORS+1];
@@ -109,6 +110,7 @@ private:
/** command write fd */
int mCmdFdWrite;
SensorBase* mSensors[MAX_SENSORS];
+ mutable Mutex mLock;
};
/*****************************************************************************/
@@ -159,7 +161,6 @@ sensors_poll_context_t::~sensors_poll_context_t() {
}
int sensors_poll_context_t::activate(int handle, int enabled) {
-
struct sensor_command cmd;
memset(&cmd, 0x00, sizeof(cmd));
@@ -185,7 +186,6 @@ int sensors_poll_context_t::activate(int handle, int enabled) {
}
int sensors_poll_context_t::setDelay(int handle, int64_t ns) {
-
struct sensor_command cmd;
memset(&cmd, 0x00, sizeof(cmd));
@@ -222,6 +222,7 @@ int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count)
// see if we have some leftover from the last poll()
for (int i = 0 ; count && i < number ; i++) {
if ((mPollFds[i].revents & POLLIN) || (sm.hasPendingEvents(slist[i].handle))) {
+ Mutex::Autolock _l(mLock);
int nb = sm.readEvents(slist[i].handle, data, count);
if (nb < 0) {
ALOGE("readEvents failed.(%d)", errno);
@@ -322,12 +323,28 @@ int sensors_poll_context_t::calibrate(int handle, struct cal_cmd_t *para)
int err = -1;
NativeSensorManager& sm(NativeSensorManager::getInstance());
+ Mutex::Autolock _l(mLock);
err = sm.calibrate(handle, para);
return err;
}
+int sensors_poll_context_t::batch(int handle, int sample_ns, int latency_ns)
+{
+ NativeSensorManager& sm(NativeSensorManager::getInstance());
+ Mutex::Autolock _l(mLock);
+
+ return sm.batch(handle, sample_ns, latency_ns);
+}
+
+int sensors_poll_context_t::flush(int handle)
+{
+ NativeSensorManager& sm(NativeSensorManager::getInstance());
+ Mutex::Autolock _l(mLock);
+
+ return sm.flush(handle);
+}
/*****************************************************************************/
static int poll__close(struct hw_device_t *dev)
@@ -363,6 +380,22 @@ static int poll_calibrate(struct sensors_poll_device_1_ext_t *dev,
sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
return ctx->calibrate(handle, para);
}
+
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+static int poll__batch(struct sensors_poll_device_1 *dev,
+ int handle, int /*flags*/, int64_t sample_ns,
+ int64_t latency_ns) {
+ sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
+ return ctx->batch(handle, sample_ns, latency_ns);
+}
+
+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);
+}
+#endif
+
/*****************************************************************************/
/** Open a new instance of a sensor device using name */
@@ -371,17 +404,27 @@ static int open_sensors(const struct hw_module_t* module, const char*,
{
int status = -EINVAL;
sensors_poll_context_t *dev = new sensors_poll_context_t();
+ NativeSensorManager& sm(NativeSensorManager::getInstance());
memset(&dev->device, 0, sizeof(sensors_poll_device_1_ext_t));
dev->device.common.tag = HARDWARE_DEVICE_TAG;
- dev->device.common.version = 0;
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+ ALOGI("Sensors device API version 1.3 supported\n");
+ dev->device.common.version = SENSORS_DEVICE_API_VERSION_1_3;
+#else
+ dev->device.common.version = SENSORS_DEVICE_API_VERSION_0_1;
+#endif
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.poll = poll__poll;
dev->device.calibrate = poll_calibrate;
+#if defined(SENSORS_DEVICE_API_VERSION_1_3)
+ dev->device.batch = poll__batch;
+ dev->device.flush = poll__flush;
+#endif
*device = &dev->device.common;
status = 0;
diff --git a/sensors/sensors.h b/sensors/sensors.h
index 71eaa82..b65d476 100644
--- a/sensors/sensors.h
+++ b/sensors/sensors.h
@@ -41,8 +41,10 @@ __BEGIN_DECLS
#define SENSORS_GYROSCOPE_HANDLE 5
#define SENSORS_PRESSURE_HANDLE 6
+#define SENSOR_TYPE_POCKET (SENSOR_TYPE_DEVICE_PRIVATE_BASE + 1)
+
#define MAX_SENSORS (20)
-#define SYSFS_MAXLEN (20)
+#define SYSFS_MAXLEN (50)
#define SYSFS_CLASS "/sys/class/sensors/"
#define SYSFS_NAME "name"
#define SYSFS_VENDOR "vendor"
@@ -57,6 +59,12 @@ __BEGIN_DECLS
#define SYSFS_POLL_DELAY "poll_delay"
#define SYSFS_CALIBRATE "calibrate"
#define SYSFS_CAL_PARAMS "cal_params"
+#define SYSFS_FIFORESVCNT "fifo_reserved_event_count"
+#define SYSFS_FIFOMAXCNT "fifo_max_event_count"
+#define SYSFS_MAXLATENCY "max_latency"
+#define SYSFS_MAXDELAY "max_delay"
+#define SYSFS_FLUSH "flush"
+#define SYSFS_FLAGS "flags"
#define COMPASS_VENDOR_AKM "AKM"
#define COMPASS_VENDOR_ALPS "Alps"
@@ -76,7 +84,7 @@ __BEGIN_DECLS
#define TEMPERATURE_NAME "temperature"
#define PROXIMITY_NAME "proximity"
#define GRAVITY_NAME "gravity"
-#define LINEAR_ACCELERATION_NAME "liner_acceleration"
+#define LINEAR_ACCELERATION_NAME "linear_acceleration"
#define ROTATION_VECTOR_NAME "rotation_vector"
#define RELATIVE_HUMIDITY_NAME "relative_humidity"
#define AMBIENT_TEMPERATURE_NAME "ambient_temperature"
@@ -87,6 +95,7 @@ __BEGIN_DECLS
#define STEP_COUNTER_NAME "step_counter"
#define STEP_DETECTOR_NAME "step_detector"
#define GEOMAGNETIC_ROTATION_VECTOR_NAME "geomagnetic_field"
+#define POCKET_NAME "pocket"
/* The hardware sensor type supported by HAL */
#define SUPPORTED_SENSORS_TYPE ( \
@@ -94,8 +103,7 @@ __BEGIN_DECLS
(1ULL << SENSOR_TYPE_MAGNETIC_FIELD) | \
(1ULL << SENSOR_TYPE_PROXIMITY) | \
(1ULL << SENSOR_TYPE_LIGHT) | \
- (1ULL << SENSOR_TYPE_GYROSCOPE ) | \
- (1ULL << SENSOR_TYPE_PRESSURE))
+ (1ULL << SENSOR_TYPE_GYROSCOPE))
/*****************************************************************************/
@@ -143,6 +151,8 @@ static inline const char* type_to_name(int type)
return STEP_COUNTER_NAME;
case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
return GEOMAGNETIC_ROTATION_VECTOR_NAME;
+ case SENSOR_TYPE_POCKET:
+ return POCKET_NAME;
default:
return "";
}
diff --git a/sensors/sensors_XML.cpp b/sensors/sensors_XML.cpp
index 24eae58..9786a48 100644
--- a/sensors/sensors_XML.cpp
+++ b/sensors/sensors_XML.cpp
@@ -1,5 +1,5 @@
/*--------------------------------------------------------------------------
-Copyright (c) 2014, The Linux Foundation. All rights reserved.
+Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -31,72 +31,167 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "sensors_XML.h"
#include <cutils/log.h>
#include "unistd.h"
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <private/android_filesystem_config.h>
#define SENSOR_XML_ROOT_ELEMENT "sensors"
ANDROID_SINGLETON_STATIC_INSTANCE(sensors_XML);
const static char *filepath[] = {
- "/persist/sensors_calibration_params.xml",
- "/data/sensors_calibration_param.xml"
+ "/persist/sensors/sensors_calibration_params.xml",
+ "/data/sensors_calibration_params.xml"
};
-char *sensor_param[] = {"offset_x", "offset_y", "offset_z", "threshold_h", "threshold_l", "bias"};
+const char *sensor_param[] = {"offset_x", "offset_y", "offset_z", "threshold_h", "threshold_l", "bias"};
+const char *cal_state[] = {"static","dynamic"};
sensors_XML :: sensors_XML()
: mdoc(NULL)
{
}
-int sensors_XML :: write_sensors_params(struct sensor_t *sensor, struct cal_result_t *cal_result)
+static int config_file_copy()
+{
+ int bufsize;
+ int fd[2];
+ off_t offset;
+ char *ptr;
+ char *wptr;
+ int bytes_read, bytes_write;
+ int err = 0;
+
+ if ((fd[0] = open(filepath[0], O_RDONLY)) == -1) {
+ ALOGE("open calibrate sensor config error %d", errno);
+ return -errno;
+ }
+ if ((fd[1] = open(filepath[1], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) == -1) {
+ ALOGE("create calibrate sensor config error");
+ close(fd[0]);
+ return -errno;
+ }
+
+ offset = lseek(fd[0], 0, SEEK_END);
+ if (offset < 0) {
+ ALOGE("lseek %s error %d", filepath[0], errno);
+ err = -errno;
+ goto close_fd;
+ }
+
+ bufsize = offset;
+ ptr = (char*)malloc(bufsize);
+ if (ptr == NULL) {
+ ALOGE("malloc memory for %s error", filepath[1]);
+ err = -errno;
+ goto close_fd;
+ }
+
+ offset = lseek(fd[0], 0, SEEK_SET);
+ if (offset < 0) {
+ ALOGE("lseek %s error %d", filepath[0], errno);
+ err = -errno;
+ goto free_ptr;
+ }
+ bytes_read = read(fd[0], ptr, bufsize);
+ if (bytes_read == -1 && errno != EINTR) {
+ ALOGE("read calibrate sensor config error");
+ err = -errno;
+ goto free_ptr;
+ }
+
+ wptr = ptr;
+ while ((bytes_write = write(fd[1], wptr, bytes_read))) {
+ if (bytes_write == -1 && errno != EINTR) {
+ ALOGE("write calibrate sensor config error");
+ err = -errno;
+ goto free_ptr;
+ } else if (bytes_write == bytes_read) {
+ break;
+ }else if (bytes_write > 0) {
+ wptr += bytes_write;
+ bytes_read -= bytes_write;
+ }
+ }
+free_ptr:
+ free(ptr);
+close_fd:
+ close(fd[0]);
+ close(fd[1]);
+ return err;
+}
+
+int sensors_XML :: write_sensors_params(struct sensor_t *sensor, struct cal_result_t *cal_result, int state)
{
xmlNodePtr rootNode, curNode, newNode;
xmlAttrPtr value;
bool newcreate = false;
char string[33];
+ int fnum = 0;
int i = 0, j, MAX = 0;
+ int err = 0;
+
+ if (state < CAL_STATIC || state > CAL_DYNAMIC) {
+ ALOGE("state error\n");
+ return -1;
+ }
if (cal_result == NULL) {
ALOGE("Null pointer parameter\n");
return -1;
}
- if (!access(filepath[0], F_OK)) {
- mdoc = xmlReadFile(filepath[0], "UTF-8" , XML_PARSE_NOBLANKS);
- if (mdoc == NULL) {
- ALOGE("read calibration file error\n");
- return -EINVAL;
+
+ if (state == 1)
+ fnum = 1;
+
+ if (!access(filepath[fnum], F_OK)) {
+ if (!access(filepath[fnum], W_OK)) {
+ mdoc = xmlReadFile(filepath[fnum], "UTF-8" , XML_PARSE_NOBLANKS);
+ if (mdoc == NULL) {
+ ALOGE("read calibration file error\n");
+ return -EINVAL;
+ }
+ } else {
+ ALOGE("No permission write file %s\n", filepath[fnum]);
+ return -1;
}
} else {
mdoc = xmlNewDoc(BAD_CAST "1.0");
if (mdoc == NULL) {
ALOGE("create sensor calibration file error\n");
- return -EINVAL;
+ return -1;
}
newcreate = true;
}
+
if(newcreate) {
rootNode = xmlNewNode(NULL, BAD_CAST SENSOR_XML_ROOT_ELEMENT);
xmlDocSetRootElement(mdoc, rootNode);
curNode = xmlNewNode(NULL, BAD_CAST "sensor");
xmlAddChild(rootNode, curNode);
xmlNewProp(curNode, BAD_CAST "name", BAD_CAST sensor->name);
+ xmlNewProp(curNode, BAD_CAST "state", BAD_CAST cal_state[state]);
} else {
rootNode = xmlDocGetRootElement(mdoc);
if (rootNode == NULL) {
ALOGE("empty document\n");
xmlFreeDoc(mdoc);
+ return -1;
}
if (xmlStrcmp(rootNode->name, BAD_CAST SENSOR_XML_ROOT_ELEMENT)) {
ALOGE("root node != sensors\n");
xmlFreeDoc(mdoc);
+ return -1;
}
curNode = rootNode->xmlChildrenNode;
while(curNode != NULL) {
- if (!xmlStrcmp(xmlGetProp(curNode, BAD_CAST "name"), BAD_CAST sensor->name))
+ if (!xmlStrcmp(xmlGetProp(curNode, BAD_CAST "name"), BAD_CAST sensor->name) &&
+ !xmlStrcmp(xmlGetProp(curNode, BAD_CAST "state"), BAD_CAST cal_state[state]))
break;
curNode = curNode->next;
}
}
switch(sensor->type) {
case SENSOR_TYPE_ACCELEROMETER:
+ case SENSOR_TYPE_GYROSCOPE:
i = 0;
MAX = 3;
break;
@@ -108,61 +203,115 @@ int sensors_XML :: write_sensors_params(struct sensor_t *sensor, struct cal_resu
case SENSOR_TYPE_MAGNETIC_FIELD:
case SENSOR_TYPE_PRESSURE:
case SENSOR_TYPE_TEMPERATURE:
- case SENSOR_TYPE_GYROSCOPE:
default:
break;
}
if (newcreate) {
- for(j = 0; i < MAX; i++, j++) {
+ for(j = 0; i < MAX && j < 3; i++, j++) {
snprintf(string, sizeof(string), "%d", cal_result->offset[j]);
- xmlNewProp(curNode, BAD_CAST sensor_param[i], BAD_CAST string);
+ value = xmlNewProp(curNode, BAD_CAST sensor_param[i], BAD_CAST string);
+ if (value == NULL) {
+ ALOGE("write value in new create error\n");
+ xmlFreeDoc(mdoc);
+ return -1;
+ }
}
} else {
- if(curNode == NULL) {
+ if (curNode == NULL) {
curNode = xmlNewNode(NULL, BAD_CAST "sensor");
xmlAddChild(rootNode, curNode);
value = xmlNewProp(curNode, BAD_CAST "name", BAD_CAST sensor->name);
if (value == NULL) {
- ALOGE("\nname is NULL\n");
+ ALOGE("name is NULL\n");
+ xmlFreeDoc(mdoc);
+ return -1;
+ }
+ value = xmlNewProp(curNode, BAD_CAST "state", BAD_CAST cal_state[state]);
+ if (value == NULL) {
+ ALOGE("state is NULL\n");
+ xmlFreeDoc(mdoc);
+ return -1;
}
- for(j = 0; i < MAX; i++, j++) {
+ for(j = 0; i < MAX && j < 3; i++, j++) {
snprintf(string, sizeof(string), "%d", cal_result->offset[j]);
- xmlNewProp(curNode, BAD_CAST sensor_param[i], BAD_CAST string);
+ value = xmlNewProp(curNode, BAD_CAST sensor_param[i], BAD_CAST string);
+ if (value == NULL) {
+ ALOGE("write value error\n");
+ xmlFreeDoc(mdoc);
+ return -1;
+ }
}
} else {
- for(j = 0; i < MAX; i++, j++) {
+ for(j = 0; i < MAX && j < 3; i++, j++) {
snprintf(string, sizeof(string), "%d", cal_result->offset[j]);
- xmlSetProp(curNode, BAD_CAST sensor_param[i], BAD_CAST string);
+ value = xmlSetProp(curNode, BAD_CAST sensor_param[i], BAD_CAST string);
+ if (value == NULL) {
+ ALOGE("set value error\n");
+ xmlFreeDoc(mdoc);
+ return -1;
+ }
}
}
}
- xmlSaveFormatFileEnc(filepath[0], mdoc, "UTF-8", 1);
+ if (xmlSaveFormatFileEnc(filepath[fnum], mdoc, "UTF-8", 1) == -1) {
+ ALOGE("save %s failed %s\n", filepath[fnum], strerror(errno));
+ xmlFreeDoc(mdoc);
+ return -1;
+ }
+ if (fnum == 0) {
+ if (getuid() != AID_ROOT) {
+ goto exit;
+ }
+ err = chown(filepath[fnum], AID_ROOT, AID_SYSTEM);
+ if (err != 0) {
+ ALOGE("chown %s failed %s", filepath[fnum], strerror(errno));
+ xmlFreeDoc(mdoc);
+ return -1;
+ }
+ err = chmod(filepath[fnum], 0660);
+ if (err != 0) {
+ ALOGE("chmod %s failed %s", filepath[fnum], strerror(errno));
+ xmlFreeDoc(mdoc);
+ return -1;
+ }
+ }
+
+exit:
xmlFreeDoc(mdoc);
return 0;
}
-int sensors_XML :: read_sensors_params(struct sensor_t *sensor, struct cal_result_t *cal_result)
+int sensors_XML :: read_sensors_params(struct sensor_t *sensor, struct cal_result_t *cal_result, int state)
{
xmlNodePtr rootNode, curNode;
int i = 0, j, MAX = 0;
+
+ if (state < CAL_STATIC || state > CAL_DYNAMIC) {
+ ALOGE("state error\n");
+ return -1;
+ }
if (cal_result == NULL) {
ALOGE("Null pointer parameter\n");
return -1;
}
- if(!access(filepath[1], R_OK)) {
+ if (!access(filepath[1], R_OK)) {
mdoc = xmlReadFile(filepath[1], "UTF-8" , XML_PARSE_RECOVER);
} else if (!access(filepath[0], F_OK)){
- char buf[200];
- snprintf(buf, sizeof(buf), "cp %s %s", filepath[0], filepath[1]);
- system(buf);
+ int err;
+
+ err = config_file_copy();
+ if (err < 0) {
+ ALOGE("copy %s error", filepath[0]);
+ return err;
+ }
if (!access(filepath[1], R_OK)) {
mdoc = xmlReadFile(filepath[1], "UTF-8" , XML_PARSE_RECOVER);
} else {
- ALOGE("file can't read\n");
+ ALOGE("file %s can't read\n", filepath[1]);
return -1;
}
} else {
- ALOGE("file can't read\n");
+ ALOGE("file %s can't read\n", filepath[0]);
return -1;
}
rootNode = xmlDocGetRootElement(mdoc);
@@ -179,12 +328,14 @@ int sensors_XML :: read_sensors_params(struct sensor_t *sensor, struct cal_resul
}
curNode = rootNode->xmlChildrenNode;
while(curNode != NULL) {
- if (!xmlStrcmp(xmlGetProp(curNode, BAD_CAST "name"), BAD_CAST sensor->name))
+ if (!xmlStrcmp(xmlGetProp(curNode, BAD_CAST "name"), BAD_CAST sensor->name) &&
+ !xmlStrcmp(xmlGetProp(curNode, BAD_CAST "state"), BAD_CAST cal_state[state]))
break;
curNode = curNode->next;
}
switch(sensor->type) {
case SENSOR_TYPE_ACCELEROMETER:
+ case SENSOR_TYPE_GYROSCOPE:
i = 0;
MAX = 3;
break;
@@ -196,21 +347,24 @@ int sensors_XML :: read_sensors_params(struct sensor_t *sensor, struct cal_resul
case SENSOR_TYPE_MAGNETIC_FIELD:
case SENSOR_TYPE_PRESSURE:
case SENSOR_TYPE_TEMPERATURE:
- case SENSOR_TYPE_GYROSCOPE:
default:
break;
}
if (curNode != NULL) {
xmlChar* value;
- for(j = 0; i < MAX; ++i, ++j) {
+ for(j = 0; i < MAX && j < 3; i++, j++) {
value = xmlGetProp(curNode, BAD_CAST sensor_param[i]);
- cal_result->offset[j] = atoi((char*)value);
+ if(value != NULL) {
+ cal_result->offset[j] = atoi((char*)value);
+ }
}
} else {
- for(j = 0; j < 3; ++j) {
+ for(j = 0; j < 3; j++) {
cal_result->offset[j] = 0;
}
- ALOGE("The sensor calibrate parameters is not found\n");
+ ALOGE("The sensor %s calibrate parameters is not found\n", sensor->name);
+ xmlFreeDoc(mdoc);
+ return -1;
}
xmlFreeDoc(mdoc);
return 0;
@@ -219,7 +373,7 @@ int sensors_XML :: read_sensors_params(struct sensor_t *sensor, struct cal_resul
int sensors_XML :: sensors_calibrate_reset()
{
int i;
- for(i=0; i < 2; ++i) {
+ for(i=0; i < 2; i++) {
if (access(filepath[i], F_OK)) {
ALOGE("file is not exits\n");
return -1;
@@ -235,12 +389,12 @@ int sensors_XML :: sensors_calibrate_reset()
int sensors_XML :: sensors_rm_file()
{
- if (access(filepath[1], F_OK)) {
- return 0;
- }
- if (remove(filepath[1])) {
- ALOGE("reset calibrate error\n");
- return -1;
- }
+ if (access(filepath[1], F_OK)) {
return 0;
+ }
+ if (remove(filepath[1])) {
+ ALOGE("reset calibrate error\n");
+ return -1;
+ }
+ return 0;
}
diff --git a/sensors/sensors_XML.h b/sensors/sensors_XML.h
index d9ab5e8..f4f5ea1 100644
--- a/sensors/sensors_XML.h
+++ b/sensors/sensors_XML.h
@@ -37,12 +37,18 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace android;
+enum {
+ CAL_STATIC,
+ CAL_DYNAMIC,
+ CAL_COUNT,
+};
+
class sensors_XML : public Singleton<sensors_XML> {
friend class Singleton<sensors_XML>;
xmlDocPtr mdoc;
public:
- int read_sensors_params(struct sensor_t *sensor, struct cal_result_t *cal_result);
- int write_sensors_params(struct sensor_t *sensor, struct cal_result_t *cal_result);
+ int read_sensors_params(struct sensor_t *sensor, struct cal_result_t *cal_result, int state);
+ int write_sensors_params(struct sensor_t *sensor, struct cal_result_t *cal_result, int state);
sensors_XML();
int sensors_calibrate_reset();
int sensors_rm_file();