blob: 54267c438bff731e1fe0acb2fdd86ebc02c8ef39 [file] [log] [blame]
Amit Arorae9e16b02010-08-03 10:15:20 +05301#include <getopt.h>
Amit Arorae9e16b02010-08-03 10:15:20 +05302#include "powerdebug.h"
3
Amit Arorae9e16b02010-08-03 10:15:20 +05304int numregulators;
Amit Arora47fd9182010-08-24 13:26:06 +05305int dump;
6int ticktime=3; /* in seconds */
Amit Arorae9e16b02010-08-03 10:15:20 +05307
8int init_regulator_ds(void)
9{
10 DIR *regdir;
11 struct dirent *item;
12
13 regdir = opendir("/sys/class/regulator");
14 if (!regdir)
15 return(1);
16 while((item = readdir(regdir))) {
17 if (strncmp(item->d_name, "regulator", 9))
18 continue;
19
20 numregulators++;
21 }
22 closedir(regdir);
23
24 regulators_info = (struct regulator_info *)malloc(numregulators*
25 sizeof(struct regulator_info));
26 if (!regulators_info) {
Amit Arora85fd4952010-08-05 14:04:50 +053027 fprintf(stderr, "init_regulator_ds: Not enough memory to ");
28 fprintf(stderr, "read information for %d regulators!\n",
Amit Arorae9e16b02010-08-03 10:15:20 +053029 numregulators);
30 return(1);
31 }
32
33 return(0);
34}
35
36int read_and_print_sensor_info(int verbose)
37{
38 DIR *dir, *subdir;
Amit Arora1c037892010-08-05 13:46:10 +053039 int len, found = 0;
Amit Arorae9e16b02010-08-03 10:15:20 +053040 char filename[PATH_MAX], devpath[PATH_MAX];
41 char device[PATH_MAX];
42 struct dirent *item, *subitem;
43
44/*
45 1. readdir /sys/class/hwmon
46 2. foreach subdir in above, do following
47 a) check if its virtual or physical (check for device)
48 b) for each *type* (in, temp, pwm, fan, curr, power, energy)
49 i> search for "_" (strrchr... check for last)
50 ii> check the *item* depending on type
51 i.e for "in" type items=min, max, input, label
52 for "fan" type items=min,max,input,div,target,label
53 for "pwm" type items=enable, mode, freq
54 for "temp" type items=type, max, min,input,crit,offset,label,lowest,highest,
55 for "curr" type items=max,min,input
56 for "power" type items=average,average_interval,average_min/max, average_highest/lowest, input, input_highest/lowest, accuracy,alarm, cap, cap_min/max
57 for "energy" type items=input
58 for "intrusion" type items=alarm,beep
59*/
60
61 sprintf(filename, "%s", "/sys/class/hwmon");
62
63 dir = opendir(filename);
64 if (!dir)
65 return errno;
66
67 while ((item = readdir(dir))) {
68 if (item->d_name[0] == '.') /* skip the hidden files */
69 continue;
70
Amit Arora1c037892010-08-05 13:46:10 +053071 found = 1;
72
Amit Arorae9e16b02010-08-03 10:15:20 +053073 sprintf(filename, "/sys/class/hwmon/%s", item->d_name);
74 sprintf(devpath, "%s/device", filename);
75
76 len = readlink(devpath, device, PATH_MAX - 1);
77
78 if (len < 0)
79 strcpy(devpath, filename);
80 else
81 device[len] = '\0';
82
83 subdir = opendir(devpath);
84
85 printf("\nSensor Information for %s :\n", item->d_name);
86 fflush(stdin);
87 while ((subitem = readdir(subdir))) {
88 if (subitem->d_name[0] == '.') /* skip hidden files */
89 continue;
90
91 if(!strncmp(subitem->d_name, "in", 2))
92 get_sensor_info(devpath, subitem->d_name, "in",
93 verbose);
94 else if (!strncmp(subitem->d_name, "temp", 4))
95 get_sensor_info(devpath, subitem->d_name,
96 "temp", verbose);
97 else if (!strncmp(subitem->d_name, "fan", 4))
98 get_sensor_info(devpath, subitem->d_name,
99 "fan", verbose);
100 else if (!strncmp(subitem->d_name, "pwm", 4))
101 get_sensor_info(devpath, subitem->d_name,
102 "pwm", verbose);
103
104 }
105
106 closedir(subdir);
107 }
108 closedir(dir);
109
Amit Arora1c037892010-08-05 13:46:10 +0530110 if(!found && verbose) {
111 printf("Could not find sensor information!");
112 printf(" Looks like /sys/class/hwmon is empty.\n");
113 }
114
Amit Arorae9e16b02010-08-03 10:15:20 +0530115 return 0;
116}
117
Amit Arora47fd9182010-08-24 13:26:06 +0530118void read_info_from_dirent(struct dirent *ritem, char *str, int idx)
119{
120 if (!strcmp(ritem->d_name, "name"))
121 strcpy(regulators_info[idx].name, str);
122 if (!strcmp(ritem->d_name, "state"))
123 strcpy(regulators_info[idx].state, str);
124 if (!strcmp(ritem->d_name, "status"))
125 strcpy(regulators_info[idx].status, str);
Amit Arorae9e16b02010-08-03 10:15:20 +0530126
Amit Arora47fd9182010-08-24 13:26:06 +0530127 if (!strcmp(ritem->d_name, "type"))
128 strcpy(regulators_info[idx].type, str);
129 if (!strcmp(ritem->d_name, "opmode"))
130 strcpy(regulators_info[idx].opmode, str);
131
132 if (!strcmp(ritem->d_name, "microvolts"))
133 regulators_info[idx].microvolts = atoi(str);
134 if (!strcmp(ritem->d_name, "min_microvolts"))
135 regulators_info[idx].min_microvolts = atoi(str);
136 if (!strcmp(ritem->d_name, "max_microvolts"))
137 regulators_info[idx].max_microvolts = atoi(str);
138
139 if (!strcmp(ritem->d_name, "microamps"))
140 regulators_info[idx].microamps = atoi(str);
141 if (!strcmp(ritem->d_name, "min_microamps"))
142 regulators_info[idx].min_microamps = atoi(str);
143 if (!strcmp(ritem->d_name, "max_microamps"))
144 regulators_info[idx].max_microamps = atoi(str);
145 if (!strcmp(ritem->d_name, "requested_microamps"))
146 regulators_info[idx].requested_microamps = atoi(str);
147
148 if (!strcmp(ritem->d_name, "num_users"))
149 regulators_info[idx].num_users = atoi(str);
150}
151
152int read_regulator_info(void)
Amit Arorae9e16b02010-08-03 10:15:20 +0530153{
154 FILE *file = NULL;
155 DIR *regdir, *dir;
156 int len, count = 0, ret = 0;
157 char line[1024], filename[1024], *fptr;
158 struct dirent *item, *ritem;
159
160 regdir = opendir("/sys/class/regulator");
161 if (!regdir)
162 return(1);
163 while((item = readdir(regdir))) {
164 if (strlen(item->d_name) < 3)
165 continue;
166
167 if (strncmp(item->d_name, "regulator", 9))
168 continue;
169
Amit Arora85fd4952010-08-05 14:04:50 +0530170 len = sprintf(filename, "/sys/class/regulator/%s",
171 item->d_name);
Amit Arorae9e16b02010-08-03 10:15:20 +0530172
173 dir = opendir(filename);
Amit Arora85fd4952010-08-05 14:04:50 +0530174 if (!dir)
Amit Arora7ef178c2010-08-03 15:57:21 +0530175 continue;
Amit Arorae9e16b02010-08-03 10:15:20 +0530176
177 count++;
178 if (count > numregulators) {
179 ret = 1;
Amit Arora85fd4952010-08-05 14:04:50 +0530180 goto exit;
Amit Arorae9e16b02010-08-03 10:15:20 +0530181 }
182
Amit Arorafccac912010-08-03 16:15:09 +0530183 strcpy(regulators_info[count-1].name, item->d_name);
Amit Arorae9e16b02010-08-03 10:15:20 +0530184 while((ritem = readdir(dir))) {
Amit Arorae9e16b02010-08-03 10:15:20 +0530185 if (strlen(ritem->d_name) < 3)
186 continue;
187
188 sprintf(filename + len, "/%s", ritem->d_name);
Amit Arorae9e16b02010-08-03 10:15:20 +0530189
190 file = fopen(filename, "r");
191 if (!file)
192 continue;
193
194 memset(line, 0, 1024);
195 fptr = fgets(line, 1024, file);
196 fclose(file);
Amit Arora85fd4952010-08-05 14:04:50 +0530197 if (!fptr)
Amit Arora7ef178c2010-08-03 15:57:21 +0530198 continue;
Amit Arorae9e16b02010-08-03 10:15:20 +0530199
Amit Arora47fd9182010-08-24 13:26:06 +0530200 read_info_from_dirent(ritem, fptr, count - 1);
Amit Arorae9e16b02010-08-03 10:15:20 +0530201 }
Amit Arora85fd4952010-08-05 14:04:50 +0530202exit:
Amit Arorae9e16b02010-08-03 10:15:20 +0530203 closedir(dir);
204 if (ret)
205 break;
206 }
Amit Arorae9e16b02010-08-03 10:15:20 +0530207 closedir(regdir);
208
209 return ret;
210}
211
212
213int main(int argc, char **argv)
214{
215 int c;
Amit Arora47fd9182010-08-24 13:26:06 +0530216 int firsttime = 1;
Amit Arorae9e16b02010-08-03 10:15:20 +0530217 int regulators = 0, sensors = 0, verbose = 0;
218
Amit Arorafefe8bf2010-08-05 13:31:20 +0530219 /*
220 * Options:
221 * -r, --regulator : regulator
222 * -s, --sensor : sensors
Amit Arora47fd9182010-08-24 13:26:06 +0530223 * -d, --dump : dump
Amit Arorafefe8bf2010-08-05 13:31:20 +0530224 * -v, --verbose : verbose
225 * -V, --version : version
226 * -h, --help : help
227 * no option / default : show usage!
Amit Arorae9e16b02010-08-03 10:15:20 +0530228 */
229
Amit Arorafefe8bf2010-08-05 13:31:20 +0530230 while (1) {
231 int optindex = 0;
232 static struct option long_options[] = {
233 {"regulator", 0, 0, 'r'},
234 {"sensor", 0, 0, 's'},
Amit Arora47fd9182010-08-24 13:26:06 +0530235 {"dump", 0, 0, 'd'},
Amit Arorafefe8bf2010-08-05 13:31:20 +0530236 {"verbose", 0, 0, 'v'},
237 {"version", 0, 0, 'V'},
238 {"help", 0, 0, 'h'},
239 {0, 0, 0, 0}
240 };
241
Amit Arora47fd9182010-08-24 13:26:06 +0530242 c = getopt_long(argc, argv, "rsdvVh", long_options, &optindex);
Amit Arorafefe8bf2010-08-05 13:31:20 +0530243 if (c == -1)
244 break;
245
246 switch (c) {
247 case 'r':
248 regulators = 1;
249 break;
250 case 's':
251 sensors = 1;
252 break;
Amit Arora47fd9182010-08-24 13:26:06 +0530253 case 'd':
254 dump = 1;
255 break;
Amit Arorafefe8bf2010-08-05 13:31:20 +0530256 case 'v':
257 verbose = 1;
258 break;
259 case 'V':
260 version();
261 break;
262 case 'h':
263 usage(argv);
264 break;
265 case '?':
266 fprintf (stderr, "%s: Unknown option %c'.\n",
267 argv[0], optopt);
268 exit(1);
269 default:
270 usage(argv);
271 break;
272 }
Amit Arorae9e16b02010-08-03 10:15:20 +0530273 }
274
Amit Arorafefe8bf2010-08-05 13:31:20 +0530275
276 /* Need atleast one option specified */
Amit Arorae9e16b02010-08-03 10:15:20 +0530277 if (!regulators && !sensors) {
Amit Arorae9e16b02010-08-03 10:15:20 +0530278 usage(argv);
279 }
280
281 init_regulator_ds();
282
Amit Arora47fd9182010-08-24 13:26:06 +0530283 while(1) {
284 int key = 0;
285 struct timeval tval;
286 fd_set readfds;
Amit Arorae9e16b02010-08-03 10:15:20 +0530287
Amit Arora47fd9182010-08-24 13:26:06 +0530288 if (!dump) {
289 if(firsttime) {
290 init_curses();
291 firsttime = 0;
292 }
293 create_windows();
294 show_header();
295 }
296
297 if (regulators) {
298 read_regulator_info();
299 if (!dump)
300 show_regulator_info(verbose);
301 else
302 print_regulator_info(verbose);
303 }
304
305
306 if (sensors) {
307 read_and_print_sensor_info(verbose);
308 }
309
310 if (dump)
311 break;
312
313 FD_ZERO(&readfds);
314 FD_SET(0, &readfds);
315 tval.tv_sec = ticktime;
316 tval.tv_usec = (ticktime - tval.tv_sec) * 1000000;
317
318 key = select(1, &readfds, NULL, NULL, &tval);
319
320 if (key) {
321 char keychar;
322
323 int keystroke = fgetc(stdin);
324 if (keystroke == EOF)
325 exit(0);
326
327 keychar = toupper(keystroke);
328 if (keychar == 'Q')
329 exit(0);
330 if (keychar == 'R')
331 ticktime = 3;
332 }
Amit Arorae9e16b02010-08-03 10:15:20 +0530333 }
334
Amit Arora85fd4952010-08-05 14:04:50 +0530335 exit(0);
Amit Arorae9e16b02010-08-03 10:15:20 +0530336}