add libsensors from source
This commit is contained in:
		
							
								
								
									
										310
									
								
								libsensors/AkmSensor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										310
									
								
								libsensors/AkmSensor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,310 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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)
 | 
			
		||||
{
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    return akm_set_delay(sensor_type, ns);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								libsensors/AkmSensor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								libsensors/AkmSensor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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();
 | 
			
		||||
    void *mLibAKM;
 | 
			
		||||
    uint32_t mEnabled;
 | 
			
		||||
    uint32_t mPendingMask;
 | 
			
		||||
    InputEventCircularReader mInputReader;
 | 
			
		||||
    sensors_event_t mPendingEvents[numSensors];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#endif  // ANDROID_AKM_SENSOR_H
 | 
			
		||||
							
								
								
									
										45
									
								
								libsensors/Android.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								libsensors/Android.mk
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
# 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.GT-I9100
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										185
									
								
								libsensors/GyroSensor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								libsensors/GyroSensor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,185 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										55
									
								
								libsensors/GyroSensor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								libsensors/GyroSensor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2008 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ANDROID_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
 | 
			
		||||
							
								
								
									
										88
									
								
								libsensors/InputEventReader.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								libsensors/InputEventReader.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								libsensors/InputEventReader.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								libsensors/InputEventReader.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2008 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ANDROID_INPUT_EVENT_READER_H
 | 
			
		||||
#define ANDROID_INPUT_EVENT_READER_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
struct input_event;
 | 
			
		||||
 | 
			
		||||
class InputEventCircularReader
 | 
			
		||||
{
 | 
			
		||||
    struct input_event* const mBuffer;
 | 
			
		||||
    struct input_event* const mBufferEnd;
 | 
			
		||||
    struct input_event* mHead;
 | 
			
		||||
    struct input_event* mCurr;
 | 
			
		||||
    ssize_t mFreeSpace;
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										170
									
								
								libsensors/LightSensor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								libsensors/LightSensor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,170 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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"
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
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 = indexToValue(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) {
 | 
			
		||||
                    // FIXME: not sure why we're getting -1 sometimes
 | 
			
		||||
                    mPendingEvent.light = indexToValue(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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float LightSensor::indexToValue(size_t index) const
 | 
			
		||||
{
 | 
			
		||||
    static const float luxValues[10] = {
 | 
			
		||||
            10.0, 160.0, 225.0, 320.0, 640.0,
 | 
			
		||||
            1280.0, 2600.0, 5800.0, 8000.0, 10240.0
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const size_t maxIndex = sizeof(luxValues)/sizeof(*luxValues) - 1;
 | 
			
		||||
    if (index > maxIndex)
 | 
			
		||||
        index = maxIndex;
 | 
			
		||||
    return luxValues[index];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								libsensors/LightSensor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								libsensors/LightSensor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2008 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ANDROID_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
 | 
			
		||||
							
								
								
									
										0
									
								
								libsensors/MODULE_LICENSE_APACHE2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								libsensors/MODULE_LICENSE_APACHE2
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										143
									
								
								libsensors/ProximitySensor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								libsensors/ProximitySensor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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(CM_DEVICE_NAME, "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
 | 
			
		||||
{
 | 
			
		||||
    return index * PROXIMITY_THRESHOLD_CM;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								libsensors/ProximitySensor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								libsensors/ProximitySensor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2008 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
							
								
								
									
										128
									
								
								libsensors/SensorBase.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								libsensors/SensorBase.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,128 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								libsensors/SensorBase.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								libsensors/SensorBase.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2008 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ANDROID_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
 | 
			
		||||
							
								
								
									
										51
									
								
								libsensors/ak8973b.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								libsensors/ak8973b.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
							
								
								
									
										326
									
								
								libsensors/sensors.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										326
									
								
								libsensors/sensors.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,326 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										144
									
								
								libsensors/sensors.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								libsensors/sensors.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,144 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 9 cm on
 | 
			
		||||
 * this hardware */
 | 
			
		||||
#define PROXIMITY_THRESHOLD_CM  9.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_RY
 | 
			
		||||
#define EVENT_TYPE_GYRO_Y           REL_RX
 | 
			
		||||
#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/64.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                  (2000.0f*(float)M_PI/180.0f)
 | 
			
		||||
#define CONVERT_GYRO                ((70.0f / 1000.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
 | 
			
		||||
		Reference in New Issue
	
	Block a user