| /* |
| * Copyright (C) 2012 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 <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 "SensorBase.h" |
| #include "iio/events.h" |
| |
| #define IIO_MAX_NAME_LENGTH 30 |
| |
| const char *iio_dir = "/sys/bus/iio/devices/"; |
| |
| /*****************************************************************************/ |
| |
| SensorBase::SensorBase( |
| const char* dev_name, |
| const char* data_name) |
| : mDevName(dev_name), mDataName(data_name), |
| mDevFd(-1), mDataFd(-1) |
| { |
| ALOGV("%s(): dev_name=%s", __func__, dev_name); |
| if (mDataName) { |
| mDataFd = openInput(mDataName); |
| } |
| } |
| |
| SensorBase::~SensorBase() { |
| if (mDataFd >= 0) { |
| close(mDataFd); |
| } |
| if (mDevFd >= 0) { |
| close(mDevFd); |
| } |
| } |
| |
| int SensorBase::openDevice() { |
| if ((mDevFd < 0) && mDevName) { |
| mDevFd = open(mDevName, O_RDONLY); |
| ALOGE_IF(mDevFd < 0, "Couldn't open %s (%s)", mDevName, strerror(errno)); |
| } |
| return 0; |
| } |
| |
| int SensorBase::closeDevice() { |
| if (mDevFd >= 0) { |
| close(mDevFd); |
| mDevFd = -1; |
| } |
| return 0; |
| } |
| |
| int SensorBase::getFd() const { |
| if (!mDataName) { |
| return mDevFd; |
| } |
| return mDataFd; |
| } |
| |
| 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; |
| } |
| |
| /* |
| * find_type_by_name() - function to match top level types by name |
| * @name: top level type instance name |
| * @type: the type of top level instance being sort |
| * |
| * Typical types this is used for are device and trigger. |
| * |
| * NOTE: This function is copied from drivers/staging/iio/Documentation/iio_utils.h |
| * and modified. |
| */ |
| int SensorBase::findTypeByName(const char *name, const char *type) |
| { |
| const struct dirent *ent; |
| int iio_id; |
| int ret = -ENODEV; |
| |
| FILE *nameFile; |
| DIR *dp; |
| char thisname[IIO_MAX_NAME_LENGTH]; |
| char filename[PATH_MAX]; |
| |
| dp = opendir(iio_dir); |
| if (dp == NULL) { |
| ALOGE("No industrialio devices available"); |
| return ret; |
| } |
| |
| while (ent = readdir(dp), ent != NULL) { |
| if (strcmp(ent->d_name, ".") != 0 && |
| strcmp(ent->d_name, "..") != 0 && |
| strlen(ent->d_name) > strlen(type) && |
| strncmp(ent->d_name, type, strlen(type)) == 0) { |
| if (sscanf(ent->d_name + strlen(type), "%d", &iio_id) != 1) |
| continue; |
| |
| sprintf(filename, "%s%s%d/name", iio_dir, type, iio_id); |
| nameFile = fopen(filename, "r"); |
| if (!nameFile) |
| continue; |
| |
| if (fscanf(nameFile, "%s", thisname) == 1) { |
| if (strcmp(name, thisname) == 0) { |
| fclose(nameFile); |
| ret = iio_id; |
| break; |
| } |
| } |
| fclose(nameFile); |
| } |
| } |
| closedir(dp); |
| return ret; |
| } |
| |
| int SensorBase::openInput(const char* inputName) { |
| int event_fd = -1; |
| char devname[PATH_MAX]; |
| int dev_num; |
| |
| dev_num = findTypeByName(inputName, "iio:device"); |
| if (dev_num >= 0) { |
| int fd; |
| sprintf(devname, "/dev/iio:device%d", dev_num); |
| fd = open(devname, O_RDONLY); |
| if (fd >= 0) { |
| if (ioctl(fd, IIO_GET_EVENT_FD_IOCTL, &event_fd) >= 0) |
| strcpy(mInputName, devname + 5); |
| else |
| ALOGE("couldn't get a event fd from %s", devname); |
| close(fd); /* close /dev/iio:device* */ |
| } else { |
| ALOGE("couldn't open %s (%s)", devname, strerror(errno)); |
| } |
| } else { |
| ALOGE("couldn't find the device %s", inputName); |
| } |
| |
| return event_fd; |
| } |