1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "Sensors" 18 19 #include <fcntl.h> 20 #include <errno.h> 21 #include <math.h> 22 #include <poll.h> 23 #include <unistd.h> 24 #include <dirent.h> 25 #include <sys/select.h> 26 27 #include <cutils/log.h> 28 29 #include "SensorBase.h" 30 #include "iio/events.h" 31 32 #define IIO_MAX_NAME_LENGTH 30 33 34 const char *iio_dir = "/sys/bus/iio/devices/"; 35 36 /*****************************************************************************/ 37 38 SensorBase::SensorBase( 39 const char* dev_name, 40 const char* data_name) 41 : mDevName(dev_name), mDataName(data_name), 42 mDevFd(-1), mDataFd(-1) 43 { 44 ALOGV("%s(): dev_name=%s", __func__, dev_name); 45 if (mDataName) { 46 mDataFd = openInput(mDataName); 47 } 48 } 49 50 SensorBase::~SensorBase() { 51 if (mDataFd >= 0) { 52 close(mDataFd); 53 } 54 if (mDevFd >= 0) { 55 close(mDevFd); 56 } 57 } 58 59 int SensorBase::openDevice() { 60 if ((mDevFd < 0) && mDevName) { 61 mDevFd = open(mDevName, O_RDONLY); 62 ALOGE_IF(mDevFd < 0, "Couldn't open %s (%s)", mDevName, strerror(errno)); 63 } 64 return 0; 65 } 66 67 int SensorBase::closeDevice() { 68 if (mDevFd >= 0) { 69 close(mDevFd); 70 mDevFd = -1; 71 } 72 return 0; 73 } 74 75 int SensorBase::getFd() const { 76 if (!mDataName) { 77 return mDevFd; 78 } 79 return mDataFd; 80 } 81 82 int SensorBase::setDelay(int32_t handle, int64_t ns) { 83 return 0; 84 } 85 86 bool SensorBase::hasPendingEvents() const { 87 return false; 88 } 89 90 int64_t SensorBase::getTimestamp() { 91 struct timespec t; 92 t.tv_sec = t.tv_nsec = 0; 93 clock_gettime(CLOCK_MONOTONIC, &t); 94 return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec; 95 } 96 97 /* 98 * find_type_by_name() - function to match top level types by name 99 * @name: top level type instance name 100 * @type: the type of top level instance being sort 101 * 102 * Typical types this is used for are device and trigger. 103 * 104 * NOTE: This function is copied from drivers/staging/iio/Documentation/iio_utils.h 105 * and modified. 106 */ 107 int SensorBase::findTypeByName(const char *name, const char *type) 108 { 109 const struct dirent *ent; 110 int iio_id; 111 int ret = -ENODEV; 112 113 FILE *nameFile; 114 DIR *dp; 115 char thisname[IIO_MAX_NAME_LENGTH]; 116 char filename[PATH_MAX]; 117 118 dp = opendir(iio_dir); 119 if (dp == NULL) { 120 ALOGE("No industrialio devices available"); 121 return ret; 122 } 123 124 while (ent = readdir(dp), ent != NULL) { 125 if (strcmp(ent->d_name, ".") != 0 && 126 strcmp(ent->d_name, "..") != 0 && 127 strlen(ent->d_name) > strlen(type) && 128 strncmp(ent->d_name, type, strlen(type)) == 0) { 129 if (sscanf(ent->d_name + strlen(type), "%d", &iio_id) != 1) 130 continue; 131 132 sprintf(filename, "%s%s%d/name", iio_dir, type, iio_id); 133 nameFile = fopen(filename, "r"); 134 if (!nameFile) 135 continue; 136 137 if (fscanf(nameFile, "%s", thisname) == 1) { 138 if (strcmp(name, thisname) == 0) { 139 fclose(nameFile); 140 ret = iio_id; 141 break; 142 } 143 } 144 fclose(nameFile); 145 } 146 } 147 closedir(dp); 148 return ret; 149 } 150 151 int SensorBase::openInput(const char* inputName) { 152 int event_fd = -1; 153 char devname[PATH_MAX]; 154 int dev_num; 155 156 dev_num = findTypeByName(inputName, "iio:device"); 157 if (dev_num >= 0) { 158 int fd; 159 sprintf(devname, "/dev/iio:device%d", dev_num); 160 fd = open(devname, O_RDONLY); 161 if (fd >= 0) { 162 if (ioctl(fd, IIO_GET_EVENT_FD_IOCTL, &event_fd) >= 0) 163 strcpy(mInputName, devname + 5); 164 else 165 ALOGE("couldn't get a event fd from %s", devname); 166 close(fd); /* close /dev/iio:device* */ 167 } else { 168 ALOGE("couldn't open %s (%s)", devname, strerror(errno)); 169 } 170 } else { 171 ALOGE("couldn't find the device %s", inputName); 172 } 173 174 return event_fd; 175 } 176