blob: b904a008aa5f5a8e95a846ad091d3e723f0852d5 [file] [log] [blame]
JP Abgrall5dcc6c92012-05-31 20:39:43 -07001/*
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
34const char *iio_dir = "/sys/bus/iio/devices/";
35
36/*****************************************************************************/
37
38SensorBase::SensorBase(
39 const char* dev_name,
40 const char* data_name)
41 : mDevName(dev_name), mDataName(data_name),
42 mDevFd(-1), mDataFd(-1)
43{
JP Abgralldb7bdef2012-06-21 15:04:34 -070044 ALOGV("%s(): dev_name=%s", __func__, dev_name);
JP Abgrall5dcc6c92012-05-31 20:39:43 -070045 if (mDataName) {
46 mDataFd = openInput(mDataName);
47 }
48}
49
50SensorBase::~SensorBase() {
51 if (mDataFd >= 0) {
52 close(mDataFd);
53 }
54 if (mDevFd >= 0) {
55 close(mDevFd);
56 }
57}
58
59int 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
67int SensorBase::closeDevice() {
68 if (mDevFd >= 0) {
69 close(mDevFd);
70 mDevFd = -1;
71 }
72 return 0;
73}
74
75int SensorBase::getFd() const {
76 if (!mDataName) {
77 return mDevFd;
78 }
79 return mDataFd;
80}
81
82int SensorBase::setDelay(int32_t handle, int64_t ns) {
83 return 0;
84}
85
86bool SensorBase::hasPendingEvents() const {
87 return false;
88}
89
90int64_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 */
107int 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
151int 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}