Change-Id: Ie479fbbf1a4d2fd879dc4fe63d97f9efac1ebfc0tirimbino
parent
cbf1cb2a7f
commit
cb3fc72d35
@ -1,331 +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. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <fcntl.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <math.h> |
|
||||||
#include <poll.h> |
|
||||||
#include <unistd.h> |
|
||||||
#include <dirent.h> |
|
||||||
#include <sys/select.h> |
|
||||||
#include <dlfcn.h> |
|
||||||
|
|
||||||
#include "ak8973b.h" |
|
||||||
|
|
||||||
#include <cutils/log.h> |
|
||||||
#include "AkmSensor.h" |
|
||||||
|
|
||||||
//#define LOG_NDEBUG 0
|
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
int (*akm_is_sensor_enabled)(uint32_t sensor_type); |
|
||||||
int (*akm_enable_sensor)(uint32_t sensor_type); |
|
||||||
int (*akm_disable_sensor)(uint32_t sensor_type); |
|
||||||
int (*akm_set_delay)(uint32_t sensor_type, uint64_t delay); |
|
||||||
|
|
||||||
int stub_is_sensor_enabled(uint32_t sensor_type) { |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int stub_enable_disable_sensor(uint32_t sensor_type) { |
|
||||||
return -ENODEV; |
|
||||||
} |
|
||||||
|
|
||||||
int stub_set_delay(uint32_t sensor_type, uint64_t delay) { |
|
||||||
return -ENODEV; |
|
||||||
} |
|
||||||
|
|
||||||
AkmSensor::AkmSensor() |
|
||||||
: SensorBase(NULL, NULL), |
|
||||||
mEnabled(0), |
|
||||||
mPendingMask(0), |
|
||||||
mInputReader(32) |
|
||||||
{ |
|
||||||
/* Open the library before opening the input device. The library
|
|
||||||
* creates a uinput device. |
|
||||||
*/ |
|
||||||
if (loadAKMLibrary() == 0) { |
|
||||||
data_name = "compass_sensor"; |
|
||||||
data_fd = openInput("compass_sensor"); |
|
||||||
} |
|
||||||
|
|
||||||
memset(mPendingEvents, 0, sizeof(mPendingEvents)); |
|
||||||
|
|
||||||
mPendingEvents[Accelerometer].version = sizeof(sensors_event_t); |
|
||||||
mPendingEvents[Accelerometer].sensor = ID_A; |
|
||||||
mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER; |
|
||||||
mPendingEvents[Accelerometer].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH; |
|
||||||
|
|
||||||
mPendingEvents[MagneticField].version = sizeof(sensors_event_t); |
|
||||||
mPendingEvents[MagneticField].sensor = ID_M; |
|
||||||
mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD; |
|
||||||
mPendingEvents[MagneticField].magnetic.status = SENSOR_STATUS_ACCURACY_HIGH; |
|
||||||
|
|
||||||
mPendingEvents[Orientation ].version = sizeof(sensors_event_t); |
|
||||||
mPendingEvents[Orientation ].sensor = ID_O; |
|
||||||
mPendingEvents[Orientation ].type = SENSOR_TYPE_ORIENTATION; |
|
||||||
mPendingEvents[Orientation ].orientation.status = SENSOR_STATUS_ACCURACY_HIGH; |
|
||||||
|
|
||||||
// read the actual value of all sensors if they're enabled already
|
|
||||||
struct input_absinfo absinfo; |
|
||||||
short flags = 0; |
|
||||||
|
|
||||||
if (akm_is_sensor_enabled(SENSOR_TYPE_ACCELEROMETER)) { |
|
||||||
mEnabled |= 1<<Accelerometer; |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ACCEL_X), &absinfo)) { |
|
||||||
mPendingEvents[Accelerometer].acceleration.x = absinfo.value * CONVERT_A_X; |
|
||||||
} |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Y), &absinfo)) { |
|
||||||
mPendingEvents[Accelerometer].acceleration.y = absinfo.value * CONVERT_A_Y; |
|
||||||
} |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Z), &absinfo)) { |
|
||||||
mPendingEvents[Accelerometer].acceleration.z = absinfo.value * CONVERT_A_Z; |
|
||||||
} |
|
||||||
} |
|
||||||
if (akm_is_sensor_enabled(SENSOR_TYPE_MAGNETIC_FIELD)) { |
|
||||||
mEnabled |= 1<<MagneticField; |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_MAGV_X), &absinfo)) { |
|
||||||
mPendingEvents[MagneticField].magnetic.x = absinfo.value * CONVERT_M_X; |
|
||||||
} |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_MAGV_Y), &absinfo)) { |
|
||||||
mPendingEvents[MagneticField].magnetic.y = absinfo.value * CONVERT_M_Y; |
|
||||||
} |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_MAGV_Z), &absinfo)) { |
|
||||||
mPendingEvents[MagneticField].magnetic.z = absinfo.value * CONVERT_M_Z; |
|
||||||
} |
|
||||||
} |
|
||||||
if (akm_is_sensor_enabled(SENSOR_TYPE_ORIENTATION)) { |
|
||||||
mEnabled |= 1<<Orientation; |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_YAW), &absinfo)) { |
|
||||||
mPendingEvents[Orientation].orientation.azimuth = absinfo.value; |
|
||||||
} |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_PITCH), &absinfo)) { |
|
||||||
mPendingEvents[Orientation].orientation.pitch = absinfo.value; |
|
||||||
} |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ROLL), &absinfo)) { |
|
||||||
mPendingEvents[Orientation].orientation.roll = -absinfo.value; |
|
||||||
} |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_ORIENT_STATUS), &absinfo)) { |
|
||||||
mPendingEvents[Orientation].orientation.status = uint8_t(absinfo.value & SENSOR_STATE_MASK); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// disable temperature sensor, since it is not supported
|
|
||||||
akm_disable_sensor(SENSOR_TYPE_TEMPERATURE); |
|
||||||
} |
|
||||||
|
|
||||||
AkmSensor::~AkmSensor() |
|
||||||
{ |
|
||||||
if (mLibAKM) { |
|
||||||
unsigned ref = ::dlclose(mLibAKM); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
int AkmSensor::enable(int32_t handle, int en) |
|
||||||
{ |
|
||||||
int what = -1; |
|
||||||
|
|
||||||
switch (handle) { |
|
||||||
case ID_A: what = Accelerometer; break; |
|
||||||
case ID_M: what = MagneticField; break; |
|
||||||
case ID_O: what = Orientation; break; |
|
||||||
} |
|
||||||
|
|
||||||
if (uint32_t(what) >= numSensors) |
|
||||||
return -EINVAL; |
|
||||||
|
|
||||||
int newState = en ? 1 : 0; |
|
||||||
int err = 0; |
|
||||||
|
|
||||||
if ((uint32_t(newState)<<what) != (mEnabled & (1<<what))) { |
|
||||||
uint32_t sensor_type; |
|
||||||
switch (what) { |
|
||||||
case Accelerometer: sensor_type = SENSOR_TYPE_ACCELEROMETER; break; |
|
||||||
case MagneticField: sensor_type = SENSOR_TYPE_MAGNETIC_FIELD; break; |
|
||||||
case Orientation: sensor_type = SENSOR_TYPE_ORIENTATION; break; |
|
||||||
} |
|
||||||
short flags = newState; |
|
||||||
if (en) |
|
||||||
err = akm_enable_sensor(sensor_type); |
|
||||||
else |
|
||||||
err = akm_disable_sensor(sensor_type); |
|
||||||
|
|
||||||
LOGE_IF(err, "Could not change sensor state (%s)", strerror(-err)); |
|
||||||
if (!err) { |
|
||||||
mEnabled &= ~(1<<what); |
|
||||||
mEnabled |= (uint32_t(flags)<<what); |
|
||||||
} |
|
||||||
} |
|
||||||
return err; |
|
||||||
} |
|
||||||
|
|
||||||
int AkmSensor::setDelay(int32_t handle, int64_t ns) |
|
||||||
{ |
|
||||||
int what = -1; |
|
||||||
uint32_t sensor_type = 0; |
|
||||||
|
|
||||||
if (ns < 0) |
|
||||||
return -EINVAL; |
|
||||||
|
|
||||||
switch (handle) { |
|
||||||
case ID_A: sensor_type = SENSOR_TYPE_ACCELEROMETER; break; |
|
||||||
case ID_M: sensor_type = SENSOR_TYPE_MAGNETIC_FIELD; break; |
|
||||||
case ID_O: sensor_type = SENSOR_TYPE_ORIENTATION; break; |
|
||||||
} |
|
||||||
|
|
||||||
if (sensor_type == 0) |
|
||||||
return -EINVAL; |
|
||||||
|
|
||||||
mDelays[what] = ns; |
|
||||||
return update_delay(); |
|
||||||
} |
|
||||||
|
|
||||||
int AkmSensor::update_delay() |
|
||||||
{ |
|
||||||
if (mEnabled) { |
|
||||||
uint64_t wanted = -1LLU; |
|
||||||
for (int i=0 ; i<numSensors ; i++) { |
|
||||||
if (mEnabled & (1<<i)) { |
|
||||||
uint64_t ns = mDelays[i]; |
|
||||||
wanted = wanted < ns ? wanted : ns; |
|
||||||
} |
|
||||||
} |
|
||||||
short delay = int64_t(wanted) / 1000000; |
|
||||||
if (ioctl(dev_fd, ECS_IOCTL_APP_SET_DELAY, &delay)) { |
|
||||||
return -errno; |
|
||||||
} |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
int AkmSensor::loadAKMLibrary() |
|
||||||
{ |
|
||||||
mLibAKM = dlopen("libakm.so", RTLD_NOW); |
|
||||||
|
|
||||||
if (!mLibAKM) { |
|
||||||
akm_is_sensor_enabled = stub_is_sensor_enabled; |
|
||||||
akm_enable_sensor = stub_enable_disable_sensor; |
|
||||||
akm_disable_sensor = stub_enable_disable_sensor; |
|
||||||
akm_set_delay = stub_set_delay; |
|
||||||
LOGE("AkmSensor: unable to load AKM Library, %s", dlerror()); |
|
||||||
return -ENOENT; |
|
||||||
} |
|
||||||
|
|
||||||
*(void **)&akm_is_sensor_enabled = dlsym(mLibAKM, "akm_is_sensor_enabled"); |
|
||||||
*(void **)&akm_enable_sensor = dlsym(mLibAKM, "akm_enable_sensor"); |
|
||||||
*(void **)&akm_disable_sensor = dlsym(mLibAKM, "akm_disable_sensor"); |
|
||||||
*(void **)&akm_set_delay = dlsym(mLibAKM, "akm_set_delay"); |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int AkmSensor::readEvents(sensors_event_t* data, int count) |
|
||||||
{ |
|
||||||
if (count < 1) |
|
||||||
return -EINVAL; |
|
||||||
|
|
||||||
ssize_t n = mInputReader.fill(data_fd); |
|
||||||
if (n < 0) |
|
||||||
return n; |
|
||||||
|
|
||||||
int numEventReceived = 0; |
|
||||||
input_event const* event; |
|
||||||
|
|
||||||
while (count && mInputReader.readEvent(&event)) { |
|
||||||
int type = event->type; |
|
||||||
if (type == EV_REL) { |
|
||||||
processEvent(event->code, event->value); |
|
||||||
mInputReader.next(); |
|
||||||
} else if (type == EV_SYN) { |
|
||||||
int64_t time = timevalToNano(event->time); |
|
||||||
for (int j=0 ; count && mPendingMask && j<numSensors ; j++) { |
|
||||||
if (mPendingMask & (1<<j)) { |
|
||||||
mPendingMask &= ~(1<<j); |
|
||||||
mPendingEvents[j].timestamp = time; |
|
||||||
if (mEnabled & (1<<j)) { |
|
||||||
*data++ = mPendingEvents[j]; |
|
||||||
count--; |
|
||||||
numEventReceived++; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
if (!mPendingMask) { |
|
||||||
mInputReader.next(); |
|
||||||
} |
|
||||||
} else { |
|
||||||
LOGE("AkmSensor: unknown event (type=%d, code=%d)", |
|
||||||
type, event->code); |
|
||||||
mInputReader.next(); |
|
||||||
} |
|
||||||
} |
|
||||||
return numEventReceived; |
|
||||||
} |
|
||||||
|
|
||||||
void AkmSensor::processEvent(int code, int value) |
|
||||||
{ |
|
||||||
switch (code) { |
|
||||||
case EVENT_TYPE_ACCEL_X: |
|
||||||
mPendingMask |= 1<<Accelerometer; |
|
||||||
mPendingEvents[Accelerometer].acceleration.x = value * CONVERT_A_X; |
|
||||||
break; |
|
||||||
case EVENT_TYPE_ACCEL_Y: |
|
||||||
mPendingMask |= 1<<Accelerometer; |
|
||||||
mPendingEvents[Accelerometer].acceleration.y = value * CONVERT_A_Y; |
|
||||||
break; |
|
||||||
case EVENT_TYPE_ACCEL_Z: |
|
||||||
mPendingMask |= 1<<Accelerometer; |
|
||||||
mPendingEvents[Accelerometer].acceleration.z = value * CONVERT_A_Z; |
|
||||||
break; |
|
||||||
|
|
||||||
case EVENT_TYPE_MAGV_X: |
|
||||||
LOGV("AkmSensor: EVENT_TYPE_MAGV_X value =%d", value); |
|
||||||
mPendingMask |= 1<<MagneticField; |
|
||||||
mPendingEvents[MagneticField].magnetic.x = value * CONVERT_M_X; |
|
||||||
break; |
|
||||||
case EVENT_TYPE_MAGV_Y: |
|
||||||
LOGV("AkmSensor: EVENT_TYPE_MAGV_Y value =%d", value); |
|
||||||
mPendingMask |= 1<<MagneticField; |
|
||||||
mPendingEvents[MagneticField].magnetic.y = value * CONVERT_M_Y; |
|
||||||
break; |
|
||||||
case EVENT_TYPE_MAGV_Z: |
|
||||||
LOGV("AkmSensor: EVENT_TYPE_MAGV_Z value =%d", value); |
|
||||||
mPendingMask |= 1<<MagneticField; |
|
||||||
mPendingEvents[MagneticField].magnetic.z = value * CONVERT_M_Z; |
|
||||||
break; |
|
||||||
|
|
||||||
case EVENT_TYPE_YAW: |
|
||||||
mPendingMask |= 1<<Orientation; |
|
||||||
mPendingEvents[Orientation].orientation.azimuth = value * CONVERT_O_A; |
|
||||||
break; |
|
||||||
case EVENT_TYPE_PITCH: |
|
||||||
mPendingMask |= 1<<Orientation; |
|
||||||
mPendingEvents[Orientation].orientation.pitch = value * CONVERT_O_P; |
|
||||||
break; |
|
||||||
case EVENT_TYPE_ROLL: |
|
||||||
mPendingMask |= 1<<Orientation; |
|
||||||
mPendingEvents[Orientation].orientation.roll = value * CONVERT_O_R; |
|
||||||
break; |
|
||||||
case EVENT_TYPE_ORIENT_STATUS: |
|
||||||
uint8_t status = uint8_t(value & SENSOR_STATE_MASK); |
|
||||||
if (status == 4) |
|
||||||
status = 0; |
|
||||||
mPendingMask |= 1<<Orientation; |
|
||||||
mPendingEvents[Orientation].orientation.status = status; |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
@ -1,64 +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 "sensors.h" |
|
||||||
#include "SensorBase.h" |
|
||||||
#include "InputEventReader.h" |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
struct input_event; |
|
||||||
|
|
||||||
class AkmSensor : public SensorBase { |
|
||||||
public: |
|
||||||
AkmSensor(); |
|
||||||
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 loadAKMLibrary(); |
|
||||||
int update_delay(); |
|
||||||
void *mLibAKM; |
|
||||||
uint32_t mEnabled; |
|
||||||
uint32_t mPendingMask; |
|
||||||
InputEventCircularReader mInputReader; |
|
||||||
sensors_event_t mPendingEvents[numSensors]; |
|
||||||
uint64_t mDelays[numSensors]; |
|
||||||
}; |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
#endif // ANDROID_AKM_SENSOR_H
|
|
@ -1,45 +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.
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
|
|
||||||
ifneq ($(TARGET_SIMULATOR),true) |
|
||||||
|
|
||||||
# HAL module implemenation, not prelinked, and stored in
|
|
||||||
# hw/<SENSORS_HARDWARE_MODULE_ID>.<ro.product.board>.so
|
|
||||||
include $(CLEAR_VARS) |
|
||||||
|
|
||||||
LOCAL_MODULE := sensors.$(TARGET_BOARD_PLATFORM)
|
|
||||||
|
|
||||||
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
|
|
||||||
|
|
||||||
LOCAL_MODULE_TAGS := optional
|
|
||||||
|
|
||||||
LOCAL_CFLAGS := -DLOG_TAG=\"Sensors\"
|
|
||||||
LOCAL_SRC_FILES := \
|
|
||||||
sensors.cpp \
|
|
||||||
SensorBase.cpp \
|
|
||||||
LightSensor.cpp \
|
|
||||||
ProximitySensor.cpp \
|
|
||||||
AkmSensor.cpp \
|
|
||||||
GyroSensor.cpp \
|
|
||||||
InputEventReader.cpp
|
|
||||||
|
|
||||||
LOCAL_SHARED_LIBRARIES := liblog libcutils libdl
|
|
||||||
LOCAL_PRELINK_MODULE := false
|
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY) |
|
||||||
|
|
||||||
endif # !TARGET_SIMULATOR
|
|
@ -1,185 +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. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <fcntl.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <math.h> |
|
||||||
#include <poll.h> |
|
||||||
#include <unistd.h> |
|
||||||
#include <dirent.h> |
|
||||||
#include <sys/select.h> |
|
||||||
#include <cutils/log.h> |
|
||||||
|
|
||||||
#include "GyroSensor.h" |
|
||||||
|
|
||||||
#define FETCH_FULL_EVENT_BEFORE_RETURN 1 |
|
||||||
#define IGNORE_EVENT_TIME 350000000 |
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
GyroSensor::GyroSensor() |
|
||||||
: SensorBase(NULL, "gyro_sensor"), |
|
||||||
mEnabled(0), |
|
||||||
mInputReader(4), |
|
||||||
mHasPendingEvent(false), |
|
||||||
mEnabledTime(0) |
|
||||||
{ |
|
||||||
mPendingEvent.version = sizeof(sensors_event_t); |
|
||||||
mPendingEvent.sensor = ID_GY; |
|
||||||
mPendingEvent.type = SENSOR_TYPE_GYROSCOPE; |
|
||||||
memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); |
|
||||||
|
|
||||||
if (data_fd) { |
|
||||||
strcpy(input_sysfs_path, "/sys/class/input/"); |
|
||||||
strcat(input_sysfs_path, input_name); |
|
||||||
strcat(input_sysfs_path, "/device/"); |
|
||||||
input_sysfs_path_len = strlen(input_sysfs_path); |
|
||||||
enable(0, 1); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
GyroSensor::~GyroSensor() { |
|
||||||
if (mEnabled) { |
|
||||||
enable(0, 0); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
int GyroSensor::setInitialState() { |
|
||||||
struct input_absinfo absinfo_x; |
|
||||||
struct input_absinfo absinfo_y; |
|
||||||
struct input_absinfo absinfo_z; |
|
||||||
float value; |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_GYRO_X), &absinfo_x) && |
|
||||||
!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_GYRO_X), &absinfo_y) && |
|
||||||
!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_GYRO_X), &absinfo_z)) { |
|
||||||
value = absinfo_x.value; |
|
||||||
mPendingEvent.data[0] = value * CONVERT_GYRO_X; |
|
||||||
value = absinfo_x.value; |
|
||||||
mPendingEvent.data[1] = value * CONVERT_GYRO_Y; |
|
||||||
value = absinfo_x.value; |
|
||||||
mPendingEvent.data[2] = value * CONVERT_GYRO_Z; |
|
||||||
mHasPendingEvent = true; |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int GyroSensor::enable(int32_t, int en) { |
|
||||||
int flags = en ? 1 : 0; |
|
||||||
if (flags != mEnabled) { |
|
||||||
int fd; |
|
||||||
strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); |
|
||||||
fd = open(input_sysfs_path, O_RDWR); |
|
||||||
if (fd >= 0) { |
|
||||||
char buf[2]; |
|
||||||
int err; |
|
||||||
buf[1] = 0; |
|
||||||
if (flags) { |
|
||||||
buf[0] = '1'; |
|
||||||
mEnabledTime = getTimestamp() + IGNORE_EVENT_TIME; |
|
||||||
} else { |
|
||||||
buf[0] = '0'; |
|
||||||
} |
|
||||||
err = write(fd, buf, sizeof(buf)); |
|
||||||
close(fd); |
|
||||||
mEnabled = flags; |
|
||||||
setInitialState(); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
return -1; |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
bool GyroSensor::hasPendingEvents() const { |
|
||||||
return mHasPendingEvent; |
|
||||||
} |
|
||||||
|
|
||||||
int GyroSensor::setDelay(int32_t handle, int64_t delay_ns) |
|
||||||
{ |
|
||||||
int fd; |
|
||||||
strcpy(&input_sysfs_path[input_sysfs_path_len], "poll_delay"); |
|
||||||
fd = open(input_sysfs_path, O_RDWR); |
|
||||||
if (fd >= 0) { |
|
||||||
char buf[80]; |
|
||||||
sprintf(buf, "%lld", delay_ns); |
|
||||||
write(fd, buf, strlen(buf)+1); |
|
||||||
close(fd); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
int GyroSensor::readEvents(sensors_event_t* data, int count) |
|
||||||
{ |
|
||||||
if (count < 1) |
|
||||||
return -EINVAL; |
|
||||||
|
|
||||||
if (mHasPendingEvent) { |
|
||||||
mHasPendingEvent = false; |
|
||||||
mPendingEvent.timestamp = getTimestamp(); |
|
||||||
*data = mPendingEvent; |
|
||||||
return mEnabled ? 1 : 0; |
|
||||||
} |
|
||||||
|
|
||||||
ssize_t n = mInputReader.fill(data_fd); |
|
||||||
if (n < 0) |
|
||||||
return n; |
|
||||||
|
|
||||||
int numEventReceived = 0; |
|
||||||
input_event const* event; |
|
||||||
|
|
||||||
#if FETCH_FULL_EVENT_BEFORE_RETURN |
|
||||||
again: |
|
||||||
#endif |
|
||||||
while (count && mInputReader.readEvent(&event)) { |
|
||||||
int type = event->type; |
|
||||||
if (type == EV_REL) { |
|
||||||
float value = event->value; |
|
||||||
if (event->code == EVENT_TYPE_GYRO_X) { |
|
||||||
mPendingEvent.data[0] = value * CONVERT_GYRO_X; |
|
||||||
} else if (event->code == EVENT_TYPE_GYRO_Y) { |
|
||||||
mPendingEvent.data[1] = value * CONVERT_GYRO_Y; |
|
||||||
} else if (event->code == EVENT_TYPE_GYRO_Z) { |
|
||||||
mPendingEvent.data[2] = value * CONVERT_GYRO_Z; |
|
||||||
} |
|
||||||
} else if (type == EV_SYN) { |
|
||||||
mPendingEvent.timestamp = timevalToNano(event->time); |
|
||||||
if (mEnabled) { |
|
||||||
if (mPendingEvent.timestamp >= mEnabledTime) { |
|
||||||
*data++ = mPendingEvent; |
|
||||||
numEventReceived++; |
|
||||||
} |
|
||||||
count--; |
|
||||||
} |
|
||||||
} else { |
|
||||||
LOGE("GyroSensor: unknown event (type=%d, code=%d)", |
|
||||||
type, event->code); |
|
||||||
} |
|
||||||
mInputReader.next(); |
|
||||||
} |
|
||||||
|
|
||||||
#if FETCH_FULL_EVENT_BEFORE_RETURN |
|
||||||
/* if we didn't read a complete event, see if we can fill and
|
|
||||||
try again instead of returning with nothing and redoing poll. */ |
|
||||||
if (numEventReceived == 0 && mEnabled == 1) { |
|
||||||
n = mInputReader.fill(data_fd); |
|
||||||
if (n) |
|
||||||
goto again; |
|
||||||
} |
|
||||||
#endif |
|
||||||
|
|
||||||
return numEventReceived; |
|
||||||
} |
|
||||||
|
|
@ -1,55 +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_GYRO_SENSOR_H |
|
||||||
#define ANDROID_GYRO_SENSOR_H |
|
||||||
|
|
||||||
#include <stdint.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <sys/cdefs.h> |
|
||||||
#include <sys/types.h> |
|
||||||
|
|
||||||
#include "sensors.h" |
|
||||||
#include "SensorBase.h" |
|
||||||
#include "InputEventReader.h" |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
struct input_event; |
|
||||||
|
|
||||||
class GyroSensor : 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(); |
|
||||||
|
|
||||||
public: |
|
||||||
GyroSensor(); |
|
||||||
virtual ~GyroSensor(); |
|
||||||
virtual int readEvents(sensors_event_t* data, int count); |
|
||||||
virtual bool hasPendingEvents() const; |
|
||||||
virtual int setDelay(int32_t handle, int64_t ns); |
|
||||||
virtual int enable(int32_t handle, int enabled); |
|
||||||
}; |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
#endif // ANDROID_GYRO_SENSOR_H
|
|
@ -1,88 +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. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <stdint.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <unistd.h> |
|
||||||
#include <poll.h> |
|
||||||
|
|
||||||
#include <sys/cdefs.h> |
|
||||||
#include <sys/types.h> |
|
||||||
|
|
||||||
#include <linux/input.h> |
|
||||||
|
|
||||||
#include <cutils/log.h> |
|
||||||
|
|
||||||
#include "InputEventReader.h" |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
struct input_event; |
|
||||||
|
|
||||||
InputEventCircularReader::InputEventCircularReader(size_t numEvents) |
|
||||||
: mBuffer(new input_event[numEvents * 2]), |
|
||||||
mBufferEnd(mBuffer + numEvents), |
|
||||||
mHead(mBuffer), |
|
||||||
mCurr(mBuffer), |
|
||||||
mFreeSpace(numEvents) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
InputEventCircularReader::~InputEventCircularReader() |
|
||||||
{ |
|
||||||
delete [] mBuffer; |
|
||||||
} |
|
||||||
|
|
||||||
ssize_t InputEventCircularReader::fill(int fd) |
|
||||||
{ |
|
||||||
size_t numEventsRead = 0; |
|
||||||
if (mFreeSpace) { |
|
||||||
const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event)); |
|
||||||
if (nread<0 || nread % sizeof(input_event)) { |
|
||||||
// we got a partial event!!
|
|
||||||
return nread<0 ? -errno : -EINVAL; |
|
||||||
} |
|
||||||
|
|
||||||
numEventsRead = nread / sizeof(input_event); |
|
||||||
if (numEventsRead) { |
|
||||||
mHead += numEventsRead; |
|
||||||
mFreeSpace -= numEventsRead; |
|
||||||
if (mHead > mBufferEnd) { |
|
||||||
size_t s = mHead - mBufferEnd; |
|
||||||
memcpy(mBuffer, mBufferEnd, s * sizeof(input_event)); |
|
||||||
mHead = mBuffer + s; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return numEventsRead; |
|
||||||
} |
|
||||||
|
|
||||||
ssize_t InputEventCircularReader::readEvent(input_event const** events) |
|
||||||
{ |
|
||||||
*events = mCurr; |
|
||||||
ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace; |
|
||||||
return available ? 1 : 0; |
|
||||||
} |
|
||||||
|
|
||||||
void InputEventCircularReader::next() |
|
||||||
{ |
|
||||||
mCurr++; |
|
||||||
mFreeSpace++; |
|
||||||
if (mCurr >= mBufferEnd) { |
|
||||||
mCurr = mBuffer; |
|
||||||
} |
|
||||||
} |
|
@ -1,47 +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_INPUT_EVENT_READER_H |
|
||||||
#define ANDROID_INPUT_EVENT_READER_H |
|
||||||
|
|
||||||
#include <stdint.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <sys/cdefs.h> |
|
||||||
#include <sys/types.h> |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
struct input_event; |
|
||||||
|
|
||||||
class InputEventCircularReader |
|
||||||
{ |
|
||||||
struct input_event* const mBuffer; |
|
||||||
struct input_event* const mBufferEnd; |
|
||||||
struct input_event* mHead; |
|
||||||
struct input_event* mCurr; |
|
||||||
ssize_t mFreeSpace; |
|
||||||
|
|
||||||
public: |
|
||||||
InputEventCircularReader(size_t numEvents); |
|
||||||
~InputEventCircularReader(); |
|
||||||
ssize_t fill(int fd); |
|
||||||
ssize_t readEvent(input_event const** events); |
|
||||||
void next(); |
|
||||||
}; |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
#endif // ANDROID_INPUT_EVENT_READER_H
|
|
@ -1,160 +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. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <fcntl.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <math.h> |
|
||||||
#include <poll.h> |
|
||||||
#include <unistd.h> |
|
||||||
#include <dirent.h> |
|
||||||
#include <sys/select.h> |
|
||||||
|
|
||||||
#include <linux/lightsensor.h> |
|
||||||
|
|
||||||
#include <cutils/log.h> |
|
||||||
|
|
||||||
#include "LightSensor.h" |
|
||||||
|
|
||||||
// #define LOG_NDEBUG 0
|
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
LightSensor::LightSensor() |
|
||||||
: SensorBase(NULL, "light_sensor"), |
|
||||||
mEnabled(0), |
|
||||||
mInputReader(4), |
|
||||||
mHasPendingEvent(false) |
|
||||||
{ |
|
||||||
mPendingEvent.version = sizeof(sensors_event_t); |
|
||||||
mPendingEvent.sensor = ID_L; |
|
||||||
mPendingEvent.type = SENSOR_TYPE_LIGHT; |
|
||||||
memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); |
|
||||||
|
|
||||||
if (data_fd) { |
|
||||||
strcpy(input_sysfs_path, "/sys/class/input/"); |
|
||||||
strcat(input_sysfs_path, input_name); |
|
||||||
strcat(input_sysfs_path, "/device/"); |
|
||||||
input_sysfs_path_len = strlen(input_sysfs_path); |
|
||||||
enable(0, 1); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
LightSensor::~LightSensor() { |
|
||||||
if (mEnabled) { |
|
||||||
enable(0, 0); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
int LightSensor::setInitialState() { |
|
||||||
struct input_absinfo absinfo; |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_LIGHT), &absinfo)) { |
|
||||||
// make sure to report an event immediately
|
|
||||||
mHasPendingEvent = true; |
|
||||||
mPendingEvent.light = absinfo.value; |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int LightSensor::setDelay(int32_t handle, int64_t ns) |
|
||||||
{ |
|
||||||
int fd; |
|
||||||
strcpy(&input_sysfs_path[input_sysfs_path_len], "poll_delay"); |
|
||||||
fd = open(input_sysfs_path, O_RDWR); |
|
||||||
if (fd >= 0) { |
|
||||||
char buf[80]; |
|
||||||
sprintf(buf, "%lld", ns); |
|
||||||
write(fd, buf, strlen(buf)+1); |
|
||||||
close(fd); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
int LightSensor::enable(int32_t handle, int en) |
|
||||||
{ |
|
||||||
int flags = en ? 1 : 0; |
|
||||||
if (flags != mEnabled) { |
|
||||||
int fd; |
|
||||||
strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); |
|
||||||
fd = open(input_sysfs_path, O_RDWR); |
|
||||||
if (fd >= 0) { |
|
||||||
char buf[2]; |
|
||||||
int err; |
|
||||||
buf[1] = 0; |
|
||||||
if (flags) { |
|
||||||
buf[0] = '1'; |
|
||||||
} else { |
|
||||||
buf[0] = '0'; |
|
||||||
} |
|
||||||
err = write(fd, buf, sizeof(buf)); |
|
||||||
close(fd); |
|
||||||
mEnabled = flags; |
|
||||||
return 0; |
|
||||||
} |
|
||||||
return -1; |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
bool LightSensor::hasPendingEvents() const { |
|
||||||
return mHasPendingEvent; |
|
||||||
} |
|
||||||
|
|
||||||
int LightSensor::readEvents(sensors_event_t* data, int count) |
|
||||||
{ |
|
||||||
if (count < 1) |
|
||||||
return -EINVAL; |
|
||||||
|
|
||||||
if (mHasPendingEvent) { |
|
||||||
mHasPendingEvent = false; |
|
||||||
mPendingEvent.timestamp = getTimestamp(); |
|
||||||
*data = mPendingEvent; |
|
||||||
return mEnabled ? 1 : 0; |
|
||||||
} |
|
||||||
|
|
||||||
ssize_t n = mInputReader.fill(data_fd); |
|
||||||
if (n < 0) |
|
||||||
return n; |
|
||||||
|
|
||||||
int numEventReceived = 0; |
|
||||||
input_event const* event; |
|
||||||
|
|
||||||
while (count && mInputReader.readEvent(&event)) { |
|
||||||
int type = event->type; |
|
||||||
if (type == EV_ABS) { |
|
||||||
if (event->code == EVENT_TYPE_LIGHT) { |
|
||||||
if (event->value != -1) { |
|
||||||
LOGV("LightSensor: event (value=%d)", event->value); |
|
||||||
// FIXME: not sure why we're getting -1 sometimes
|
|
||||||
mPendingEvent.light = event->value; |
|
||||||
} |
|
||||||
} |
|
||||||
} else if (type == EV_SYN) { |
|
||||||
mPendingEvent.timestamp = timevalToNano(event->time); |
|
||||||
if (mEnabled) { |
|
||||||
*data++ = mPendingEvent; |
|
||||||
count--; |
|
||||||
numEventReceived++; |
|
||||||
} |
|
||||||
} else { |
|
||||||
LOGE("LightSensor: unknown event (type=%d, code=%d)", |
|
||||||
type, event->code); |
|
||||||
} |
|
||||||
mInputReader.next(); |
|
||||||
} |
|
||||||
|
|
||||||
return numEventReceived; |
|
||||||
} |
|
@ -1,55 +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_LIGHT_SENSOR_H |
|
||||||
#define ANDROID_LIGHT_SENSOR_H |
|
||||||
|
|
||||||
#include <stdint.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <sys/cdefs.h> |
|
||||||
#include <sys/types.h> |
|
||||||
|
|
||||||
#include "sensors.h" |
|
||||||
#include "SensorBase.h" |
|
||||||
#include "InputEventReader.h" |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
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; |
|
||||||
|
|
||||||
float indexToValue(size_t index) const; |
|
||||||
int setInitialState(); |
|
||||||
|
|
||||||
public: |
|
||||||
LightSensor(); |
|
||||||
virtual ~LightSensor(); |
|
||||||
virtual int readEvents(sensors_event_t* data, int count); |
|
||||||
virtual bool hasPendingEvents() const; |
|
||||||
virtual int setDelay(int32_t handle, int64_t ns); |
|
||||||
virtual int enable(int32_t handle, int enabled); |
|
||||||
}; |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
#endif // ANDROID_LIGHT_SENSOR_H
|
|
@ -1,144 +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. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <fcntl.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <math.h> |
|
||||||
#include <poll.h> |
|
||||||
#include <unistd.h> |
|
||||||
#include <dirent.h> |
|
||||||
#include <sys/select.h> |
|
||||||
|
|
||||||
#include <linux/capella_cm3602.h> |
|
||||||
|
|
||||||
#include <cutils/log.h> |
|
||||||
|
|
||||||
#include "ProximitySensor.h" |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
ProximitySensor::ProximitySensor() |
|
||||||
: SensorBase(NULL, "proximity_sensor"), |
|
||||||
mEnabled(0), |
|
||||||
mInputReader(4), |
|
||||||
mHasPendingEvent(false) |
|
||||||
{ |
|
||||||
mPendingEvent.version = sizeof(sensors_event_t); |
|
||||||
mPendingEvent.sensor = ID_P; |
|
||||||
mPendingEvent.type = SENSOR_TYPE_PROXIMITY; |
|
||||||
memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); |
|
||||||
|
|
||||||
if (data_fd) { |
|
||||||
strcpy(input_sysfs_path, "/sys/class/input/"); |
|
||||||
strcat(input_sysfs_path, input_name); |
|
||||||
strcat(input_sysfs_path, "/device/"); |
|
||||||
input_sysfs_path_len = strlen(input_sysfs_path); |
|
||||||
enable(0, 1); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
ProximitySensor::~ProximitySensor() { |
|
||||||
if (mEnabled) { |
|
||||||
enable(0, 0); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
int ProximitySensor::setInitialState() { |
|
||||||
struct input_absinfo absinfo; |
|
||||||
if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_PROXIMITY), &absinfo)) { |
|
||||||
// make sure to report an event immediately
|
|
||||||
mHasPendingEvent = true; |
|
||||||
mPendingEvent.distance = indexToValue(absinfo.value); |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int ProximitySensor::enable(int32_t, int en) { |
|
||||||
int flags = en ? 1 : 0; |
|
||||||
if (flags != mEnabled) { |
|
||||||
int fd; |
|
||||||
strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); |
|
||||||
fd = open(input_sysfs_path, O_RDWR); |
|
||||||
if (fd >= 0) { |
|
||||||
char buf[2]; |
|
||||||
buf[1] = 0; |
|
||||||
if (flags) { |
|
||||||
buf[0] = '1'; |
|
||||||
} else { |
|
||||||
buf[0] = '0'; |
|
||||||
} |
|
||||||
write(fd, buf, sizeof(buf)); |
|
||||||
close(fd); |
|
||||||
mEnabled = flags; |
|
||||||
setInitialState(); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
return -1; |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
bool ProximitySensor::hasPendingEvents() const { |
|
||||||
return mHasPendingEvent; |
|
||||||
} |
|
||||||
|
|
||||||
int ProximitySensor::readEvents(sensors_event_t* data, int count) |
|
||||||
{ |
|
||||||
if (count < 1) |
|
||||||
return -EINVAL; |
|
||||||
|
|
||||||
if (mHasPendingEvent) { |
|
||||||
mHasPendingEvent = false; |
|
||||||
mPendingEvent.timestamp = getTimestamp(); |
|
||||||
*data = mPendingEvent; |
|
||||||
return mEnabled ? 1 : 0; |
|
||||||
} |
|
||||||
|
|
||||||
ssize_t n = mInputReader.fill(data_fd); |
|
||||||
if (n < 0) |
|
||||||
return n; |
|
||||||
|
|
||||||
int numEventReceived = 0; |
|
||||||
input_event const* event; |
|
||||||
|
|
||||||
while (count && mInputReader.readEvent(&event)) { |
|
||||||
int type = event->type; |
|
||||||
if (type == EV_ABS) { |
|
||||||
if (event->code == EVENT_TYPE_PROXIMITY) { |
|
||||||
mPendingEvent.distance = indexToValue(event->value); |
|
||||||
} |
|
||||||
} else if (type == EV_SYN) { |
|
||||||
mPendingEvent.timestamp = timevalToNano(event->time); |
|
||||||
if (mEnabled) { |
|
||||||
*data++ = mPendingEvent; |
|
||||||
count--; |
|
||||||
numEventReceived++; |
|
||||||
} |
|
||||||
} else { |
|
||||||
LOGE("ProximitySensor: unknown event (type=%d, code=%d)", |
|
||||||
type, event->code); |
|
||||||
} |
|
||||||
mInputReader.next(); |
|
||||||
} |
|
||||||
|
|
||||||
return numEventReceived; |
|
||||||
} |
|
||||||
|
|
||||||
float ProximitySensor::indexToValue(size_t index) const |
|
||||||
{ |
|
||||||
LOGV("ProximitySensor: Index = %zu", index); |
|
||||||
return index * PROXIMITY_THRESHOLD_CM; |
|
||||||
} |
|
@ -1,54 +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_PROXIMITY_SENSOR_H |
|
||||||
#define ANDROID_PROXIMITY_SENSOR_H |
|
||||||
|
|
||||||
#include <stdint.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <sys/cdefs.h> |
|
||||||
#include <sys/types.h> |
|
||||||
|
|
||||||
#include "sensors.h" |
|
||||||
#include "SensorBase.h" |
|
||||||
#include "InputEventReader.h" |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
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 setInitialState(); |
|
||||||
float indexToValue(size_t index) const; |
|
||||||
|
|
||||||
public: |
|
||||||
ProximitySensor(); |
|
||||||
virtual ~ProximitySensor(); |
|
||||||
virtual int readEvents(sensors_event_t* data, int count); |
|
||||||
virtual bool hasPendingEvents() const; |
|
||||||
virtual int enable(int32_t handle, int enabled); |
|
||||||
}; |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
#endif // ANDROID_PROXIMITY_SENSOR_H
|
|
@ -1,128 +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. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <fcntl.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <math.h> |
|
||||||
#include <poll.h> |
|
||||||
#include <unistd.h> |
|
||||||
#include <dirent.h> |
|
||||||
#include <sys/select.h> |
|
||||||
|
|
||||||
#include <cutils/log.h> |
|
||||||
|
|
||||||
#include <linux/input.h> |
|
||||||
|
|
||||||
#include "SensorBase.h" |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
SensorBase::SensorBase( |
|
||||||
const char* dev_name, |
|
||||||
const char* data_name) |
|
||||||
: dev_name(dev_name), data_name(data_name), |
|
||||||
dev_fd(-1), data_fd(-1) |
|
||||||
{ |
|
||||||
if (data_name) { |
|
||||||
data_fd = openInput(data_name); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
SensorBase::~SensorBase() { |
|
||||||
if (data_fd >= 0) { |
|
||||||
close(data_fd); |
|
||||||
} |
|
||||||
if (dev_fd >= 0) { |
|
||||||
close(dev_fd); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
int SensorBase::open_device() { |
|
||||||
if (dev_fd<0 && dev_name) { |
|
||||||
dev_fd = open(dev_name, O_RDONLY); |
|
||||||
LOGE_IF(dev_fd<0, "Couldn't open %s (%s)", dev_name, strerror(errno)); |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int SensorBase::close_device() { |
|
||||||
if (dev_fd >= 0) { |
|
||||||
close(dev_fd); |
|
||||||
dev_fd = -1; |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int SensorBase::getFd() const { |
|
||||||
if (!data_name) { |
|
||||||
return dev_fd; |
|
||||||
} |
|
||||||
return data_fd; |
|
||||||
} |
|
||||||
|
|
||||||
int SensorBase::setDelay(int32_t handle, int64_t ns) { |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
bool SensorBase::hasPendingEvents() const { |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
int64_t SensorBase::getTimestamp() { |
|
||||||
struct timespec t; |
|
||||||
t.tv_sec = t.tv_nsec = 0; |
|
||||||
clock_gettime(CLOCK_MONOTONIC, &t); |
|
||||||
return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec; |
|
||||||
} |
|
||||||
|
|
||||||
int SensorBase::openInput(const char* inputName) { |
|
||||||
int fd = -1; |
|
||||||
const char *dirname = "/dev/input"; |
|
||||||
char devname[PATH_MAX]; |
|
||||||
char *filename; |
|
||||||
DIR *dir; |
|
||||||
struct dirent *de; |
|
||||||
dir = opendir(dirname); |
|
||||||
if(dir == NULL) |
|
||||||
return -1; |
|
||||||
strcpy(devname, dirname); |
|
||||||
filename = devname + strlen(devname); |
|
||||||
*filename++ = '/'; |
|
||||||
while((de = readdir(dir))) { |
|
||||||
if(de->d_name[0] == '.' && |
|
||||||
(de->d_name[1] == '\0' || |
|
||||||
(de->d_name[1] == '.' && de->d_name[2] == '\0'))) |
|
||||||
continue; |
|
||||||
strcpy(filename, de->d_name); |
|
||||||
fd = open(devname, O_RDONLY); |
|
||||||
if (fd>=0) { |
|
||||||
char name[80]; |
|
||||||
if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) { |
|
||||||
name[0] = '\0'; |
|
||||||
} |
|
||||||
if (!strcmp(name, inputName)) { |
|
||||||
strcpy(input_name, filename); |
|
||||||
break; |
|
||||||
} else { |
|
||||||
close(fd); |
|
||||||
fd = -1; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
closedir(dir); |
|
||||||
LOGE_IF(fd<0, "couldn't find '%s' input device", inputName); |
|
||||||
return fd; |
|
||||||
} |
|
@ -1,65 +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_SENSOR_BASE_H |
|
||||||
#define ANDROID_SENSOR_BASE_H |
|
||||||
|
|
||||||
#include <stdint.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <sys/cdefs.h> |
|
||||||
#include <sys/types.h> |
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
struct sensors_event_t; |
|
||||||
|
|
||||||
class SensorBase { |
|
||||||
protected: |
|
||||||
const char* dev_name; |
|
||||||
const char* data_name; |
|
||||||
char input_name[PATH_MAX]; |
|
||||||
int dev_fd; |
|
||||||
int data_fd; |
|
||||||
|
|
||||||
int openInput(const char* inputName); |
|
||||||
static int64_t getTimestamp(); |
|
||||||
|
|
||||||
|
|
||||||
static int64_t timevalToNano(timeval const& t) { |
|
||||||
return t.tv_sec*1000000000LL + t.tv_usec*1000; |
|
||||||
} |
|
||||||
|
|
||||||
int open_device(); |
|
||||||
int close_device(); |
|
||||||
|
|
||||||
public: |
|
||||||
SensorBase( |
|
||||||
const char* dev_name, |
|
||||||
const char* data_name); |
|
||||||
|
|
||||||
virtual ~SensorBase(); |
|
||||||
|
|
||||||
virtual int readEvents(sensors_event_t* data, int count) = 0; |
|
||||||
virtual bool hasPendingEvents() const; |
|
||||||
virtual int getFd() const; |
|
||||||
virtual int setDelay(int32_t handle, int64_t ns); |
|
||||||
virtual int enable(int32_t handle, int enabled) = 0; |
|
||||||
}; |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
#endif // ANDROID_SENSOR_BASE_H
|
|
@ -1,51 +0,0 @@ |
|||||||
/*
|
|
||||||
* Definitions for akm8973 compass chip. |
|
||||||
*/ |
|
||||||
#ifndef AKM8973_H |
|
||||||
#define AKM8973_H |
|
||||||
|
|
||||||
#include <linux/ioctl.h> |
|
||||||
|
|
||||||
#define AKM8973_I2C_NAME "ak8973b" |
|
||||||
|
|
||||||
#define AKMIO 0xA1 |
|
||||||
|
|
||||||
/* IOCTLs for AKM library */ |
|
||||||
#define ECS_IOCTL_WRITE _IOW(AKMIO, 0x01, char*) |
|
||||||
#define ECS_IOCTL_READ _IOWR(AKMIO, 0x02, char*) |
|
||||||
#define ECS_IOCTL_RESET _IO(AKMIO, 0x03) |
|
||||||
#define ECS_IOCTL_SET_MODE _IOW(AKMIO, 0x04, short) |
|
||||||
#define ECS_IOCTL_GETDATA _IOR(AKMIO, 0x05, char[SENSOR_DATA_SIZE]) |
|
||||||
#define ECS_IOCTL_SET_YPR _IOW(AKMIO, 0x06, short[12]) |
|
||||||
#define ECS_IOCTL_GET_OPEN_STATUS _IOR(AKMIO, 0x07, int) |
|
||||||
#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(AKMIO, 0x08, int) |
|
||||||
#define ECS_IOCTL_GET_DELAY _IOR(AKMIO, 0x30, int64_t) |
|
||||||
#define ECS_IOCTL_GET_PROJECT_NAME _IOR(AKMIO, 0x0D, char[64]) |
|
||||||
#define ECS_IOCTL_GET_MATRIX _IOR(AKMIO, 0x0E, short [4][3][3]) |
|
||||||
|
|
||||||
/* IOCTLs for APPs */ |
|
||||||
#define ECS_IOCTL_APP_SET_MODE _IOW(AKMIO, 0x10, short) |
|
||||||
#define ECS_IOCTL_APP_SET_MFLAG _IOW(AKMIO, 0x11, short) |
|
||||||
#define ECS_IOCTL_APP_GET_MFLAG _IOW(AKMIO, 0x12, short) |
|
||||||
#define ECS_IOCTL_APP_SET_AFLAG _IOW(AKMIO, 0x13, short) |
|
||||||
#define ECS_IOCTL_APP_GET_AFLAG _IOR(AKMIO, 0x14, short) |
|
||||||
#define ECS_IOCTL_APP_SET_TFLAG _IOR(AKMIO, 0x15, short) |
|
||||||
#define ECS_IOCTL_APP_GET_TFLAG _IOR(AKMIO, 0x16, short) |
|
||||||
#define ECS_IOCTL_APP_RESET_PEDOMETER _IO(AKMIO, 0x17) |
|
||||||
#define ECS_IOCTL_APP_SET_DELAY _IOW(AKMIO, 0x18, int64_t) |
|
||||||
#define ECS_IOCTL_APP_GET_DELAY ECS_IOCTL_GET_DELAY |
|
||||||
|
|
||||||
/* Set raw magnetic vector flag */ |
|
||||||
#define ECS_IOCTL_APP_SET_MVFLAG _IOW(AKMIO, 0x19, short) |
|
||||||
|
|
||||||
/* Get raw magnetic vector flag */ |
|
||||||
#define ECS_IOCTL_APP_GET_MVFLAG _IOR(AKMIO, 0x1A, short) |
|
||||||
|
|
||||||
struct akm8973_platform_data { |
|
||||||
short layouts[4][3][3]; |
|
||||||
char project_name[64]; |
|
||||||
int gpio_RST; |
|
||||||
int gpio_INT; |
|
||||||
}; |
|
||||||
|
|
||||||
#endif |
|
@ -1,326 +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. |
|
||||||
*/ |
|
||||||
|
|
||||||
#define LOG_TAG "Sensors" |
|
||||||
|
|
||||||
#include <hardware/sensors.h> |
|
||||||
#include <fcntl.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <dirent.h> |
|
||||||
#include <math.h> |
|
||||||
#include <poll.h> |
|
||||||
#include <pthread.h> |
|
||||||
#include <stdlib.h> |
|
||||||
|
|
||||||
#include <linux/input.h> |
|
||||||
|
|
||||||
#include <utils/Atomic.h> |
|
||||||
#include <utils/Log.h> |
|
||||||
|
|
||||||
#include "sensors.h" |
|
||||||
|
|
||||||
#include "LightSensor.h" |
|
||||||
#include "ProximitySensor.h" |
|
||||||
#include "AkmSensor.h" |
|
||||||
#include "GyroSensor.h" |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
#define DELAY_OUT_TIME 0x7FFFFFFF |
|
||||||
|
|
||||||
#define LIGHT_SENSOR_POLLTIME 2000000000 |
|
||||||
|
|
||||||
|
|
||||||
#define SENSORS_ACCELERATION (1<<ID_A) |
|
||||||
#define SENSORS_MAGNETIC_FIELD (1<<ID_M) |
|
||||||
#define SENSORS_ORIENTATION (1<<ID_O) |
|
||||||
#define SENSORS_LIGHT (1<<ID_L) |
|
||||||
#define SENSORS_PROXIMITY (1<<ID_P) |
|
||||||
#define SENSORS_GYROSCOPE (1<<ID_GY) |
|
||||||
|
|
||||||
#define SENSORS_ACCELERATION_HANDLE 0 |
|
||||||
#define SENSORS_MAGNETIC_FIELD_HANDLE 1 |
|
||||||
#define SENSORS_ORIENTATION_HANDLE 2 |
|
||||||
#define SENSORS_LIGHT_HANDLE 3 |
|
||||||
#define SENSORS_PROXIMITY_HANDLE 4 |
|
||||||
#define SENSORS_GYROSCOPE_HANDLE 5 |
|
||||||
|
|
||||||
#define AKM_FTRACE 0 |
|
||||||
#define AKM_DEBUG 0 |
|
||||||
#define AKM_DATA 0 |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
/* The SENSORS Module */ |
|
||||||
static const struct sensor_t sSensorList[] = { |
|
||||||
{ "KR3DM 3-axis Accelerometer", |
|
||||||
"STMicroelectronics", |
|
||||||
1, SENSORS_ACCELERATION_HANDLE, |
|
||||||
SENSOR_TYPE_ACCELEROMETER, RANGE_A, CONVERT_A, 0.23f, 20000, { } }, |
|
||||||
{ "AK8975 3-axis Magnetic field sensor", |
|
||||||
"Asahi Kasei Microdevices", |
|
||||||
1, SENSORS_MAGNETIC_FIELD_HANDLE, |
|
||||||
SENSOR_TYPE_MAGNETIC_FIELD, 2000.0f, CONVERT_M, 6.8f, 16667, { } }, |
|
||||||
{ "AK8973 Orientation sensor", |
|
||||||
"Asahi Kasei Microdevices", |
|
||||||
1, SENSORS_ORIENTATION_HANDLE, |
|
||||||
SENSOR_TYPE_ORIENTATION, 360.0f, CONVERT_O, 7.8f, 16667, { } }, |
|
||||||
{ "CM3663 Light sensor", |
|
||||||
"Capella Microsystems", |
|
||||||
1, SENSORS_LIGHT_HANDLE, |
|
||||||
SENSOR_TYPE_LIGHT, 10240.0f, 1.0f, 0.75f, 0, { } }, |
|
||||||
{ "CM3663 Proximity sensor", |
|
||||||
"Capella Microsystems", |
|
||||||
1, SENSORS_PROXIMITY_HANDLE, |
|
||||||
SENSOR_TYPE_PROXIMITY, 5.0f, 5.0f, 0.75f, 0, { } }, |
|
||||||
{ "K3G Gyroscope sensor", |
|
||||||
"STMicroelectronics", |
|
||||||
1, SENSORS_GYROSCOPE_HANDLE, |
|
||||||
SENSOR_TYPE_GYROSCOPE, RANGE_GYRO, CONVERT_GYRO, 6.1f, 1190, { } }, |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
static int open_sensors(const struct hw_module_t* module, const char* id, |
|
||||||
struct hw_device_t** device); |
|
||||||
|
|
||||||
|
|
||||||
static int sensors__get_sensors_list(struct sensors_module_t* module, |
|
||||||
struct sensor_t const** list)
|
|
||||||
{ |
|
||||||
*list = sSensorList; |
|
||||||
return ARRAY_SIZE(sSensorList); |
|
||||||
} |
|
||||||
|
|
||||||
static struct hw_module_methods_t sensors_module_methods = { |
|
||||||
open: open_sensors |
|
||||||
}; |
|
||||||
|
|
||||||
struct sensors_module_t HAL_MODULE_INFO_SYM = { |
|
||||||
common: { |
|
||||||
tag: HARDWARE_MODULE_TAG, |
|
||||||
version_major: 1, |
|
||||||
version_minor: 0, |
|
||||||
id: SENSORS_HARDWARE_MODULE_ID, |
|
||||||
name: "Samsung Sensor module", |
|
||||||
author: "Samsung Electronic Company", |
|
||||||
methods: &sensors_module_methods, |
|
||||||
}, |
|
||||||
get_sensors_list: sensors__get_sensors_list, |
|
||||||
}; |
|
||||||
|
|
||||||
struct sensors_poll_context_t { |
|
||||||
struct sensors_poll_device_t device; // must be first
|
|
||||||
|
|
||||||
sensors_poll_context_t(); |
|
||||||
~sensors_poll_context_t(); |
|
||||||
int activate(int handle, int enabled); |
|
||||||
int setDelay(int handle, int64_t ns); |
|
||||||
int pollEvents(sensors_event_t* data, int count); |
|
||||||
|
|
||||||
private: |
|
||||||
enum { |
|
||||||
light = 0, |
|
||||||
proximity = 1, |
|
||||||
akm = 2, |
|
||||||
gyro = 3, |
|
||||||
numSensorDrivers, |
|
||||||
numFds, |
|
||||||
}; |
|
||||||
|
|
||||||
static const size_t wake = numFds - 1; |
|
||||||
static const char WAKE_MESSAGE = 'W'; |
|
||||||
struct pollfd mPollFds[numFds]; |
|
||||||
int mWritePipeFd; |
|
||||||
SensorBase* mSensors[numSensorDrivers]; |
|
||||||
|
|
||||||
int handleToDriver(int handle) const { |
|
||||||
switch (handle) { |
|
||||||
case ID_A: |
|
||||||
case ID_M: |
|
||||||
case ID_O: |
|
||||||
return akm; |
|
||||||
case ID_P: |
|
||||||
return proximity; |
|
||||||
case ID_L: |
|
||||||
return light; |
|
||||||
case ID_GY: |
|
||||||
return gyro; |
|
||||||
} |
|
||||||
return -EINVAL; |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
sensors_poll_context_t::sensors_poll_context_t() |
|
||||||
{ |
|
||||||
mSensors[light] = new LightSensor(); |
|
||||||
mPollFds[light].fd = mSensors[light]->getFd(); |
|
||||||
mPollFds[light].events = POLLIN; |
|
||||||
mPollFds[light].revents = 0; |
|
||||||
|
|
||||||
mSensors[proximity] = new ProximitySensor(); |
|
||||||
mPollFds[proximity].fd = mSensors[proximity]->getFd(); |
|
||||||
mPollFds[proximity].events = POLLIN; |
|
||||||
mPollFds[proximity].revents = 0; |
|
||||||
|
|
||||||
mSensors[akm] = new AkmSensor(); |
|
||||||
mPollFds[akm].fd = mSensors[akm]->getFd(); |
|
||||||
mPollFds[akm].events = POLLIN; |
|
||||||
mPollFds[akm].revents = 0; |
|
||||||
|
|
||||||
mSensors[gyro] = new GyroSensor(); |
|
||||||
mPollFds[gyro].fd = mSensors[gyro]->getFd(); |
|
||||||
mPollFds[gyro].events = POLLIN; |
|
||||||
mPollFds[gyro].revents = 0; |
|
||||||
|
|
||||||
int wakeFds[2]; |
|
||||||
int result = pipe(wakeFds); |
|
||||||
LOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno)); |
|
||||||
fcntl(wakeFds[0], F_SETFL, O_NONBLOCK); |
|
||||||
fcntl(wakeFds[1], F_SETFL, O_NONBLOCK); |
|
||||||
mWritePipeFd = wakeFds[1]; |
|
||||||
|
|
||||||
mPollFds[wake].fd = wakeFds[0]; |
|
||||||
mPollFds[wake].events = POLLIN; |
|
||||||
mPollFds[wake].revents = 0; |
|
||||||
} |
|
||||||
|
|
||||||
sensors_poll_context_t::~sensors_poll_context_t() { |
|
||||||
for (int i=0 ; i<numSensorDrivers ; i++) { |
|
||||||
delete mSensors[i]; |
|
||||||
} |
|
||||||
close(mPollFds[wake].fd); |
|
||||||
close(mWritePipeFd); |
|
||||||
} |
|
||||||
|
|
||||||
int sensors_poll_context_t::activate(int handle, int enabled) { |
|
||||||
int index = handleToDriver(handle); |
|
||||||
if (index < 0) return index; |
|
||||||
int err = mSensors[index]->enable(handle, enabled); |
|
||||||
if (enabled && !err) { |
|
||||||
const char wakeMessage(WAKE_MESSAGE); |
|
||||||
int result = write(mWritePipeFd, &wakeMessage, 1); |
|
||||||
LOGE_IF(result<0, "error sending wake message (%s)", strerror(errno)); |
|
||||||
} |
|
||||||
return err; |
|
||||||
} |
|
||||||
|
|
||||||
int sensors_poll_context_t::setDelay(int handle, int64_t ns) { |
|
||||||
|
|
||||||
int index = handleToDriver(handle); |
|
||||||
if (index < 0) return index; |
|
||||||
return mSensors[index]->setDelay(handle, ns); |
|
||||||
} |
|
||||||
|
|
||||||
int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count) |
|
||||||
{ |
|
||||||
int nbEvents = 0; |
|
||||||
int n = 0; |
|
||||||
|
|
||||||
do { |
|
||||||
// see if we have some leftover from the last poll()
|
|
||||||
for (int i=0 ; count && i<numSensorDrivers ; i++) { |
|
||||||
SensorBase* const sensor(mSensors[i]); |
|
||||||
if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())) { |
|
||||||
int nb = sensor->readEvents(data, count); |
|
||||||
if (nb < count) { |
|
||||||
// no more data for this sensor
|
|
||||||
mPollFds[i].revents = 0; |
|
||||||
} |
|
||||||
count -= nb; |
|
||||||
nbEvents += nb; |
|
||||||
data += nb; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (count) { |
|
||||||
// we still have some room, so try to see if we can get
|
|
||||||
// some events immediately or just wait if we don't have
|
|
||||||
// anything to return
|
|
||||||
n = poll(mPollFds, numFds, nbEvents ? 0 : -1); |
|
||||||
if (n<0) { |
|
||||||
LOGE("poll() failed (%s)", strerror(errno)); |
|
||||||
return -errno; |
|
||||||
} |
|
||||||
if (mPollFds[wake].revents & POLLIN) { |
|
||||||
char msg; |
|
||||||
int result = read(mPollFds[wake].fd, &msg, 1); |
|
||||||
LOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno)); |
|
||||||
LOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg)); |
|
||||||
mPollFds[wake].revents = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
// if we have events and space, go read them
|
|
||||||
} while (n && count); |
|
||||||
|
|
||||||
return nbEvents; |
|
||||||
} |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
static int poll__close(struct hw_device_t *dev) |
|
||||||
{ |
|
||||||
sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; |
|
||||||
if (ctx) { |
|
||||||
delete ctx; |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
static int poll__activate(struct sensors_poll_device_t *dev, |
|
||||||
int handle, int enabled) { |
|
||||||
sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; |
|
||||||
return ctx->activate(handle, enabled); |
|
||||||
} |
|
||||||
|
|
||||||
static int poll__setDelay(struct sensors_poll_device_t *dev, |
|
||||||
int handle, int64_t ns) { |
|
||||||
sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; |
|
||||||
return ctx->setDelay(handle, ns); |
|
||||||
} |
|
||||||
|
|
||||||
static int poll__poll(struct sensors_poll_device_t *dev, |
|
||||||
sensors_event_t* data, int count) { |
|
||||||
sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; |
|
||||||
return ctx->pollEvents(data, count); |
|
||||||
} |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
/** Open a new instance of a sensor device using name */ |
|
||||||
static int open_sensors(const struct hw_module_t* module, const char* id, |
|
||||||
struct hw_device_t** device) |
|
||||||
{ |
|
||||||
int status = -EINVAL; |
|
||||||
sensors_poll_context_t *dev = new sensors_poll_context_t(); |
|
||||||
|
|
||||||
memset(&dev->device, 0, sizeof(sensors_poll_device_t)); |
|
||||||
|
|
||||||
dev->device.common.tag = HARDWARE_DEVICE_TAG; |
|
||||||
dev->device.common.version = 0; |
|
||||||
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; |
|
||||||
|
|
||||||
*device = &dev->device.common; |
|
||||||
status = 0; |
|
||||||
|
|
||||||
return status; |
|
||||||
} |
|
||||||
|
|
@ -1,144 +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_SENSORS_H |
|
||||||
#define ANDROID_SENSORS_H |
|
||||||
|
|
||||||
#include <stdint.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <sys/cdefs.h> |
|
||||||
#include <sys/types.h> |
|
||||||
|
|
||||||
#include <linux/input.h> |
|
||||||
|
|
||||||
#include <hardware/hardware.h> |
|
||||||
#include <hardware/sensors.h> |
|
||||||
|
|
||||||
__BEGIN_DECLS |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) |
|
||||||
|
|
||||||
#define ID_A (0) |
|
||||||
#define ID_M (1) |
|
||||||
#define ID_O (2) |
|
||||||
#define ID_L (3) |
|
||||||
#define ID_P (4) |
|
||||||
#define ID_GY (5) |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
/*
|
|
||||||
* The SENSORS Module |
|
||||||
*/ |
|
||||||
|
|
||||||
/* the CM3663 is a binary proximity sensor that triggers around 6 cm on
|
|
||||||
* this hardware */ |
|
||||||
#define PROXIMITY_THRESHOLD_CM 6.0f |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
#define AKM_DEVICE_NAME "/dev/akm8975" |
|
||||||
#define CM_DEVICE_NAME "/dev/i2c11" // FIXME Proximity
|
|
||||||
#define LS_DEVICE_NAME "/dev/i2c11" // FIXME Lig
|
|
||||||
|
|
||||||
/*
|
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=0, code=0) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=8) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=3) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=4) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=5) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=0) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=1) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=2) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=6) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=7) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=9) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=0, code=0) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=8) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=3) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=4) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=5) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=0) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=1) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=2) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=6) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=7) |
|
||||||
E/Sensors ( 2656): AkmSensor: processing event (type=2, code=9) |
|
||||||
*/ |
|
||||||
|
|
||||||
// for akm8975
|
|
||||||
#define EVENT_TYPE_ACCEL_X ABS_Y //1
|
|
||||||
#define EVENT_TYPE_ACCEL_Y ABS_X //0
|
|
||||||
#define EVENT_TYPE_ACCEL_Z ABS_Z //2
|
|
||||||
//#define EVENT_TYPE_ACCEL_STATUS ABS_WHEEL //8
|
|
||||||
|
|
||||||
#define EVENT_TYPE_YAW ABS_RX //3
|
|
||||||
#define EVENT_TYPE_PITCH ABS_RY //4
|
|
||||||
#define EVENT_TYPE_ROLL ABS_RZ //5
|
|
||||||
#define EVENT_TYPE_ORIENT_STATUS ABS_WHEEL //8
|
|
||||||
|
|
||||||
#define EVENT_TYPE_MAGV_X ABS_RUDDER // 6
|
|
||||||
#define EVENT_TYPE_MAGV_Y ABS_THROTTLE // 7
|
|
||||||
#define EVENT_TYPE_MAGV_Z ABS_GAS // 9
|
|
||||||
|
|
||||||
#define EVENT_TYPE_TEMPERATURE ABS_THROTTLE |
|
||||||
#define EVENT_TYPE_STEP_COUNT ABS_GAS |
|
||||||
#define EVENT_TYPE_PROXIMITY ABS_DISTANCE |
|
||||||
#define EVENT_TYPE_LIGHT ABS_MISC |
|
||||||
|
|
||||||
#define EVENT_TYPE_GYRO_X REL_RX |
|
||||||
#define EVENT_TYPE_GYRO_Y REL_RY |
|
||||||
#define EVENT_TYPE_GYRO_Z REL_RZ |
|
||||||
|
|
||||||
// 90 LSB = 1G for KR3DM
|
|
||||||
#define LSB (90.0f) |
|
||||||
#define NUMOFACCDATA (8.0f) |
|
||||||
|
|
||||||
// conversion of acceleration data to SI units (m/s^2)
|
|
||||||
#define RANGE_A (2*GRAVITY_EARTH) |
|
||||||
#define CONVERT_A (GRAVITY_EARTH / LSB / NUMOFACCDATA) |
|
||||||
#define CONVERT_A_X (CONVERT_A) |
|
||||||
#define CONVERT_A_Y (-CONVERT_A) |
|
||||||
#define CONVERT_A_Z (-CONVERT_A) |
|
||||||
|
|
||||||
// conversion of magnetic data to uT units
|
|
||||||
#define CONVERT_M (1.0f/16.0f) |
|
||||||
#define CONVERT_M_X (CONVERT_M) |
|
||||||
#define CONVERT_M_Y (-CONVERT_M) |
|
||||||
#define CONVERT_M_Z (CONVERT_M) |
|
||||||
|
|
||||||
/* conversion of orientation data to degree units */ |
|
||||||
#define CONVERT_O (1.0f/1000.0f) |
|
||||||
#define CONVERT_O_A (CONVERT_O) |
|
||||||
#define CONVERT_O_P (CONVERT_O) |
|
||||||
#define CONVERT_O_R (CONVERT_O) |
|
||||||
|
|
||||||
// conversion of gyro data to SI units (radian/sec)
|
|
||||||
#define RANGE_GYRO (500.0f*(float)M_PI/180.0f) |
|
||||||
#define CONVERT_GYRO ((70.0f / 4000.0f) * ((float)M_PI / 180.0f)) |
|
||||||
#define CONVERT_GYRO_X (CONVERT_GYRO) |
|
||||||
#define CONVERT_GYRO_Y (CONVERT_GYRO) |
|
||||||
#define CONVERT_GYRO_Z (CONVERT_GYRO) |
|
||||||
|
|
||||||
#define SENSOR_STATE_MASK (0x7FFF) |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
__END_DECLS |
|
||||||
|
|
||||||
#endif // ANDROID_SENSORS_H
|
|
Loading…
Reference in new issue