1 /* 2 * Copyright (C) 2010 Motorola, Inc. 3 * Copyright (C) 2008 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #include <fcntl.h> 19 #include <errno.h> 20 #include <math.h> 21 #include <poll.h> 22 #include <unistd.h> 23 #include <dirent.h> 24 #include <sys/select.h> 25 26 #include <linux/l3g4200d.h> 27 28 #include <cutils/log.h> 29 30 #include "GyroSensor.h" 31 32 /*****************************************************************************/ 33 34 GyroSensor::GyroSensor() 35 : SensorBase(GYROSCOPE_DEVICE_NAME, "gyroscope"), 36 mEnabled(0), 37 mInputReader(32) 38 { 39 mPendingEvent.version = sizeof(sensors_event_t); 40 mPendingEvent.sensor = ID_G; 41 mPendingEvent.type = SENSOR_TYPE_GYROSCOPE; 42 mPendingEvent.gyro.status = SENSOR_STATUS_ACCURACY_HIGH; 43 memset(mPendingEvent.data, 0x00, sizeof(mPendingEvent.data)); 44 45 open_device(); 46 47 int flags = 0; 48 if (!ioctl(dev_fd, L3G4200D_IOCTL_GET_ENABLE, &flags)) { 49 if (flags) { 50 mEnabled = 1; 51 } 52 } 53 54 if (!mEnabled) { 55 close_device(); 56 } 57 } 58 59 GyroSensor::~GyroSensor() { 60 } 61 62 int GyroSensor::enable(int32_t, int en) 63 { 64 int flags = en ? 1 : 0; 65 int err = 0; 66 if (flags != mEnabled) { 67 if (flags) { 68 open_device(); 69 } 70 err = ioctl(dev_fd, L3G4200D_IOCTL_SET_ENABLE, &flags); 71 err = err<0 ? -errno : 0; 72 ALOGE_IF(err, "L3G4200D_IOCTL_SET_ENABLE failed (%s)", strerror(-err)); 73 if (!err) { 74 mEnabled = flags; 75 } 76 if (!flags) { 77 close_device(); 78 } 79 } 80 return err; 81 } 82 83 int GyroSensor::setDelay(int32_t handle, int64_t ns) 84 { 85 if (ns < 0) 86 return -EINVAL; 87 88 int delay = ns / 1000000; 89 if (ioctl(dev_fd, L3G4200D_IOCTL_SET_DELAY, &delay)) { 90 return -errno; 91 } 92 return 0; 93 } 94 95 int GyroSensor::readEvents(sensors_event_t* data, int count) 96 { 97 if (count < 1) 98 return -EINVAL; 99 100 ssize_t n = mInputReader.fill(data_fd); 101 if (n < 0) 102 return n; 103 int numEventReceived = 0; 104 input_event const* event; 105 106 while (count && mInputReader.readEvent(&event)) { 107 int type = event->type; 108 if (type == EV_REL) { 109 processEvent(event->code, event->value); 110 } else if (type == EV_SYN) { 111 int64_t time = timevalToNano(event->time); 112 mPendingEvent.timestamp = time; 113 if (mEnabled) { 114 *data++ = mPendingEvent; 115 count--; 116 numEventReceived++; 117 } 118 } else { 119 ALOGE("GyroSensor: unknown event (type=%d, code=%d)", 120 type, event->code); 121 } 122 mInputReader.next(); 123 } 124 125 return numEventReceived; 126 } 127 128 void GyroSensor::processEvent(int code, int value) 129 { 130 switch (code) { 131 case EVENT_TYPE_GYRO_P: 132 mPendingEvent.gyro.x = value * CONVERT_G_P; 133 break; 134 case EVENT_TYPE_GYRO_R: 135 mPendingEvent.gyro.y = value * CONVERT_G_R; 136 break; 137 case EVENT_TYPE_GYRO_Y: 138 mPendingEvent.gyro.z = value * CONVERT_G_Y; 139 break; 140 } 141 } 142