OSDN Git Service

Merge remote-tracking branch 'origin/abt/topic/gmin/kitkat/sensors' into gmin/kitkat...
[android-x86/hardware-intel-libsensors.git] / utils.c
1 /*
2  * Copyright (C) 2014 Intel Corporation.
3  */
4
5 #include <stdlib.h>
6 #include <fcntl.h>
7 #include <utils/Log.h>
8 #include <hardware/sensors.h>
9 #include "common.h"
10 #include "utils.h"
11
12
13 /* Note:
14  *
15  * Some of these calls are going to fail, because not all sensors expose all
16  * possible sysfs attributes. As an optimization we may want to cache which
17  * ones are valid and immediately return in error for inexistent entries.
18  */
19
20 int sysfs_write_int(const char path[PATH_MAX], int value)
21 {
22         int ret;
23         int fd;
24         int len;
25         char buf[20];
26
27         if (!path[0]) {
28                 return -1;
29         }
30
31         fd = open(path, O_WRONLY);
32
33         if (fd == -1) {
34                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
35                 return -1;
36         }
37
38         len = sprintf(buf, "%d", value) + 1;
39
40         ret = write(fd, buf, len);
41
42         if (ret != len) {
43                 ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", buf, len, path,
44                       strerror(errno));
45         }
46
47         close(fd);
48
49         return ret;
50 }
51
52
53 int sysfs_read_int(const char path[PATH_MAX], int *value)
54 {
55         int fd;
56         int len;
57         char buf[20] = {0};
58
59         if (!path[0] || !value) {
60                 return -1;
61         }
62
63         fd = open(path, O_RDONLY);
64
65         if (fd == -1) {
66                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
67                 return -1;
68         }
69
70         len = read(fd, buf, sizeof(buf));
71
72         close(fd);
73
74         if (len <= 0) {
75                 ALOGW("Cannot read integer from %s (%s)\n", path,
76                       strerror(errno));
77                 return -1;
78         }
79
80         *value = atoi(buf);
81
82         ALOGV("Read %d from %s\n", *value, path);
83
84         return 0;
85 }
86
87
88 int sysfs_write_str(const char path[PATH_MAX], const char *str)
89 {
90         int ret;
91         int fd;
92         int len;
93
94         if (!path[0] || !str || !str[0]) {
95                 return -1;
96         }
97
98         fd = open(path, O_WRONLY);
99
100         if (fd == -1) {
101                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
102                 return -1;
103         }
104
105         len = strlen(str);
106
107         ret = write(fd, str, len);
108
109         if (ret != len) {
110                 ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", str, len, path,
111                       strerror(errno));
112         }
113         else
114                 ALOGV("Wrote %s to %s\n", str, path);
115
116         close(fd);
117
118         return ret;
119 }
120
121
122 int sysfs_read_str(const char path[PATH_MAX], char *buf, int buf_len)
123 {
124         int fd;
125         int len;
126
127         if (!path[0] || !buf || buf_len < 1)
128                 return -1;
129
130         fd = open(path, O_RDONLY);
131
132         if (fd == -1) {
133                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
134                 return -1;
135         }
136
137         len = read(fd, buf, buf_len);
138
139         close(fd);
140
141         if (len == -1) {
142                 ALOGW("Cannot read string from %s (%s)\n", path,
143                       strerror(errno));
144                 return -1;
145         }
146
147         buf[len == 0 ? 0 : len-1] = '\0';
148
149         ALOGV("Read %s from %s\n", buf, path);
150
151         return len;
152 }
153
154
155 int sysfs_read_float(const char path[PATH_MAX], float *value)
156 {
157         int fd;
158         int len;
159         char buf[20] = {0};
160
161         if (!path[0] || !value) {
162                 return -1;
163         }
164
165         fd = open(path, O_RDONLY);
166
167         if (fd == -1) {
168                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
169                 return -1;
170         }
171
172         len = read(fd, buf, sizeof(buf));
173
174         close(fd);
175
176         if (len <= 0) {
177                 ALOGW("Cannot read float from %s (%s)\n", path,
178                       strerror(errno));
179                 return -1;
180         }
181
182         *value = (float) strtod(buf, NULL);
183
184         ALOGV("Read %f from %s\n", *value, path);
185
186         return 0;
187 }
188
189
190 int decode_type_spec(   const char type_buf[MAX_TYPE_SPEC_LEN],
191                         struct datum_info_t *type_info)
192 {
193         /* Return size in bytes for this type specification, or -1 in error */
194         char sign;
195         char endianness;
196         unsigned int realbits, storagebits, shift;
197         int tokens;
198
199         /* Valid specs: "le:u10/16>>0", "le:s16/32>>0" or "le:s32/32>>0" */
200
201         tokens = sscanf(type_buf, "%ce:%c%u/%u>>%u",
202                         &endianness, &sign, &realbits, &storagebits, &shift);
203
204         if     (tokens != 5 ||
205                 (endianness != 'b' && endianness != 'l') ||
206                 (sign != 'u' && sign != 's') ||
207                 realbits > storagebits ||
208                 (storagebits != 16 && storagebits != 32 && storagebits != 64)) {
209                         ALOGE("Invalid iio channel type spec: %s\n", type_buf);
210                         return -1;
211                 }
212
213         type_info->endianness   =               endianness;
214         type_info->sign         =               sign;
215         type_info->realbits     =       (short) realbits;
216         type_info->storagebits  =       (short) storagebits;
217         type_info->shift        =       (short) shift;
218
219         return storagebits / 8;
220 }
221
222
223 int64_t get_timestamp(void)
224 {
225         struct timespec ts = {0};
226
227         clock_gettime(CLOCK_MONOTONIC, &ts);
228
229         return 1000000000LL * ts.tv_sec + ts.tv_nsec;
230 }