1ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda/*
2ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda * Copyright (C) 2008 The Android Open Source Project
3ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda *
4ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda * Licensed under the Apache License, Version 2.0 (the "License");
5ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda * you may not use this file except in compliance with the License.
6ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda * You may obtain a copy of the License at
7ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda *
8ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda *      http://www.apache.org/licenses/LICENSE-2.0
9ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda *
10ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda * Unless required by applicable law or agreed to in writing, software
11ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda * distributed under the License is distributed on an "AS IS" BASIS,
12ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda * See the License for the specific language governing permissions and
14ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda * limitations under the License.
15ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda */
16ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
17ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda#include <fcntl.h>
18ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda#include <errno.h>
19ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda#include <math.h>
20ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda#include <poll.h>
21ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda#include <unistd.h>
22ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda#include <dirent.h>
23ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda#include <sys/select.h>
24ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda#include <dlfcn.h>
25ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
26ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda#include <cutils/log.h>
27ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
28ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda#include "AkmSensor.h"
29ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
30ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda#define AKMD_DEFAULT_INTERVAL	200000000
31ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
32ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda/*****************************************************************************/
33ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
34ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi MasudaAkmSensor::AkmSensor()
35ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda: SensorBase(NULL, "compass"),
36ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda      mPendingMask(0),
37ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda      mInputReader(32)
38ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda{
39ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	for (int i=0; i<numSensors; i++) {
40ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		mEnabled[i] = 0;
41ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		mDelay[i] = -1;
42ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	}
43ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    memset(mPendingEvents, 0, sizeof(mPendingEvents));
44ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
45ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    mPendingEvents[Accelerometer].version = sizeof(sensors_event_t);
46ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    mPendingEvents[Accelerometer].sensor = ID_A;
47ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER;
48ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    mPendingEvents[Accelerometer].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
49ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
50ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    mPendingEvents[MagneticField].version = sizeof(sensors_event_t);
51ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    mPendingEvents[MagneticField].sensor = ID_M;
52ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD;
53ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    mPendingEvents[MagneticField].magnetic.status = SENSOR_STATUS_ACCURACY_HIGH;
54ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
55ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    mPendingEvents[Orientation  ].version = sizeof(sensors_event_t);
56ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    mPendingEvents[Orientation  ].sensor = ID_O;
57ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    mPendingEvents[Orientation  ].type = SENSOR_TYPE_ORIENTATION;
58ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    mPendingEvents[Orientation  ].orientation.status = SENSOR_STATUS_ACCURACY_HIGH;
59ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
60ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    if (data_fd) {
61ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		strcpy(input_sysfs_path, "/sys/class/compass/akm8975/");
62ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		input_sysfs_path_len = strlen(input_sysfs_path);
63ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	} else {
64ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		input_sysfs_path[0] = '\0';
65ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		input_sysfs_path_len = 0;
66ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	}
67ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda}
68ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
69ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi MasudaAkmSensor::~AkmSensor()
70ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda{
71ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	for (int i=0; i<numSensors; i++) {
72ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		setEnable(i, 0);
73ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	}
74ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda}
75ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
76ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masudaint AkmSensor::setEnable(int32_t handle, int enabled)
77ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda{
78ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	int id = handle2id(handle);
79ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	int err = 0;
80ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	char buffer[2];
81ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
82ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	switch (id) {
83ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	case Accelerometer:
84ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		strcpy(&input_sysfs_path[input_sysfs_path_len], "enable_acc");
85ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		break;
86ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	case MagneticField:
87ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		strcpy(&input_sysfs_path[input_sysfs_path_len], "enable_mag");
88ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		break;
89ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	case Orientation:
90ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		strcpy(&input_sysfs_path[input_sysfs_path_len], "enable_ori");
91ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		break;
92ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	default:
93ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		ALOGE("AkmSensor: unknown handle (%d)", handle);
94ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		return -EINVAL;
95ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	}
96ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
97ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	buffer[0] = '\0';
98ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	buffer[1] = '\0';
99ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
100ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	if (mEnabled[id] <= 0) {
101ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		if(enabled) buffer[0] = '1';
102ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	} else if (mEnabled[id] == 1) {
103ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		if(!enabled) buffer[0] = '0';
104ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	}
105ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
106ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    if (buffer[0] != '\0') {
107ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		err = write_sys_attribute(input_sysfs_path, buffer, 1);
108ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		if (err != 0) {
109ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			return err;
110ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		}
111ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		ALOGD("AkmSensor: set %s to %s",
112ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			&input_sysfs_path[input_sysfs_path_len], buffer);
113ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
114ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		/* for AKMD specification */
115ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		if (buffer[0] == '1') {
116ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			setDelay(handle, AKMD_DEFAULT_INTERVAL);
117ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		} else {
118ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			setDelay(handle, -1);
119ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		}
120ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    }
121ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
122ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	if (enabled) {
123ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		(mEnabled[id])++;
124ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		if (mEnabled[id] > 32767) mEnabled[id] = 32767;
125ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	} else {
126ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		(mEnabled[id])--;
127ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		if (mEnabled[id] < 0) mEnabled[id] = 0;
128ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	}
129ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	ALOGD("AkmSensor: mEnabled[%d] = %d", id, mEnabled[id]);
130ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
131ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    return err;
132ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda}
133ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
134ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masudaint AkmSensor::setDelay(int32_t handle, int64_t ns)
135ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda{
136ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	int id = handle2id(handle);
137ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	int err = 0;
138ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	char buffer[32];
139ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	int bytes;
140ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
141ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    if (ns < -1 || 2147483647 < ns) {
142ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		ALOGE("AkmSensor: invalid delay (%lld)", ns);
143ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        return -EINVAL;
144ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	}
145ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
146ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    switch (id) {
147ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case Accelerometer:
148ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			strcpy(&input_sysfs_path[input_sysfs_path_len], "delay_acc");
149ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			break;
150ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case MagneticField:
151ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			strcpy(&input_sysfs_path[input_sysfs_path_len], "delay_mag");
152ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			break;
153ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case Orientation:
154ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			strcpy(&input_sysfs_path[input_sysfs_path_len], "delay_ori");
155ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			break;
156ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		default:
157ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			ALOGE("AkmSensor: unknown handle (%d)", handle);
158ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			return -EINVAL;
159ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    }
160ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
161ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	if (ns != mDelay[id]) {
162ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda   		bytes = sprintf(buffer, "%lld", ns);
163ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		err = write_sys_attribute(input_sysfs_path, buffer, bytes);
164ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		if (err == 0) {
165ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			mDelay[id] = ns;
166ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			ALOGD("AkmSensor: set %s to %f ms.",
167ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda				&input_sysfs_path[input_sysfs_path_len], ns/1000000.0f);
168ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		}
169ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	}
170ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
171ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    return err;
172ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda}
173ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
174ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masudaint64_t AkmSensor::getDelay(int32_t handle)
175ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda{
176ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	int id = handle2id(handle);
177ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	if (id > 0) {
178ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		return mDelay[id];
179ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	} else {
180ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		return 0;
181ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	}
182ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda}
183ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
184ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masudaint AkmSensor::getEnable(int32_t handle)
185ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda{
186ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	int id = handle2id(handle);
187ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	if (id >= 0) {
188ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		return mEnabled[id];
189ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	} else {
190ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		return 0;
191ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	}
192ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda}
193ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
194ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masudaint AkmSensor::readEvents(sensors_event_t* data, int count)
195ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda{
196ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    if (count < 1)
197ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        return -EINVAL;
198ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
199ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    ssize_t n = mInputReader.fill(data_fd);
200ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    if (n < 0)
201ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        return n;
202ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
203ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    int numEventReceived = 0;
204ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    input_event const* event;
205ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
206ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    while (count && mInputReader.readEvent(&event)) {
207ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        int type = event->type;
208ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        if (type == EV_ABS) {
209ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            processEvent(event->code, event->value);
210ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mInputReader.next();
211ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        } else if (type == EV_SYN) {
212ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            int64_t time = timevalToNano(event->time);
213ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            for (int j=0 ; count && mPendingMask && j<numSensors ; j++) {
214ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda                if (mPendingMask & (1<<j)) {
215ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda                    mPendingMask &= ~(1<<j);
216ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda                    mPendingEvents[j].timestamp = time;
217ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda					//ALOGD("data=%8.5f,%8.5f,%8.5f",
218ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda						//mPendingEvents[j].data[0],
219ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda						//mPendingEvents[j].data[1],
220ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda						//mPendingEvents[j].data[2]);
221ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda                    if (mEnabled[j]) {
222ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda                        *data++ = mPendingEvents[j];
223ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda                        count--;
224ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda                        numEventReceived++;
225ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda                    }
226ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda                }
227ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            }
228ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            if (!mPendingMask) {
229ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda                mInputReader.next();
230ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            }
231ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        } else {
232ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            ALOGE("AkmSensor: unknown event (type=%d, code=%d)",
233ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda                    type, event->code);
234ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mInputReader.next();
235ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        }
236ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    }
237ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    return numEventReceived;
238ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda}
239ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
240ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masudaint AkmSensor::setAccel(sensors_event_t* data)
241ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda{
242ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	int err;
243ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	int16_t acc[3];
244ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
245ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	acc[0] = (int16_t)(data->acceleration.x / GRAVITY_EARTH * AKSC_LSG);
246ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	acc[1] = (int16_t)(data->acceleration.y / GRAVITY_EARTH * AKSC_LSG);
247ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	acc[2] = (int16_t)(data->acceleration.z / GRAVITY_EARTH * AKSC_LSG);
248ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
249ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	strcpy(&input_sysfs_path[input_sysfs_path_len], "accel");
250ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	err = write_sys_attribute(input_sysfs_path, (char*)acc, 6);
251ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	if (err < 0) {
252ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		ALOGD("AkmSensor: %s write failed.",
253ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			&input_sysfs_path[input_sysfs_path_len]);
254ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	}
255ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda	return err;
256ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda}
257ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
258ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masudaint AkmSensor::handle2id(int32_t handle)
259ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda{
260ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    switch (handle) {
261ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case ID_A:
262ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			return Accelerometer;
263ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case ID_M:
264ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			return MagneticField;
265ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case ID_O:
266ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			return Orientation;
267ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda		default:
268ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			ALOGE("AkmSensor: unknown handle (%d)", handle);
269ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda			return -EINVAL;
270ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    }
271ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda}
272ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
273ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masudavoid AkmSensor::processEvent(int code, int value)
274ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda{
275ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    switch (code) {
276ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case EVENT_TYPE_ACCEL_X:
277ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingMask |= 1<<Accelerometer;
278ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingEvents[Accelerometer].acceleration.x = value * CONVERT_A;
279ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            break;
280ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case EVENT_TYPE_ACCEL_Y:
281ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingMask |= 1<<Accelerometer;
282ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingEvents[Accelerometer].acceleration.y = value * CONVERT_A;
283ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            break;
284ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case EVENT_TYPE_ACCEL_Z:
285ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingMask |= 1<<Accelerometer;
286ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingEvents[Accelerometer].acceleration.z = value * CONVERT_A;
287ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            break;
288ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
289ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case EVENT_TYPE_MAGV_X:
290ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingMask |= 1<<MagneticField;
291ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingEvents[MagneticField].magnetic.x = value * CONVERT_M;
292ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            break;
293ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case EVENT_TYPE_MAGV_Y:
294ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingMask |= 1<<MagneticField;
295ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingEvents[MagneticField].magnetic.y = value * CONVERT_M;
296ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            break;
297ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case EVENT_TYPE_MAGV_Z:
298ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingMask |= 1<<MagneticField;
299ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingEvents[MagneticField].magnetic.z = value * CONVERT_M;
300ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            break;
301ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case EVENT_TYPE_MAGV_STATUS:
302ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingMask |= 1<<MagneticField;
303ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingEvents[MagneticField].magnetic.status = value;
304ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            break;
305ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda
306ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case EVENT_TYPE_YAW:
307ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingMask |= 1<<Orientation;
308ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingEvents[Orientation].orientation.azimuth = value * CONVERT_O;
309ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            break;
310ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case EVENT_TYPE_PITCH:
311ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingMask |= 1<<Orientation;
312ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingEvents[Orientation].orientation.pitch = value * CONVERT_O;
313ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            break;
314ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case EVENT_TYPE_ROLL:
315ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingMask |= 1<<Orientation;
316ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingEvents[Orientation].orientation.roll = value * CONVERT_O;
317ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            break;
318ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda        case EVENT_TYPE_ORIENT_STATUS:
319ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingMask |= 1<<Orientation;
320ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            mPendingEvents[Orientation].orientation.status = value;
321ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda            break;
322ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda    }
323ab17e987e7f5371df91fe4e137fcf9041489ffdfTsuyoshi Masuda}
324