blob: d4ce1f64f7541baddb77945f9f975637d2a2c89a [file] [log] [blame]
Daniel Lezcano7c15fad2016-02-18 15:57:43 +00001/*
2 * Power debug tool (powerdebug)
Amit Arora39f29542010-09-14 12:03:22 +05303 *
Daniel Lezcano7c15fad2016-02-18 15:57:43 +00004 * Copyright (C) 2016, Linaro Limited.
Amit Arora39f29542010-09-14 12:03:22 +05305 *
Daniel Lezcano7c15fad2016-02-18 15:57:43 +00006 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
Amit Arora39f29542010-09-14 12:03:22 +053010 *
Daniel Lezcano7c15fad2016-02-18 15:57:43 +000011 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 */
Amit Arora39f29542010-09-14 12:03:22 +053021
Amit Arorae9e16b02010-08-03 10:15:20 +053022#include <getopt.h>
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010023#include <stdbool.h>
Daniel Lezcano15627482011-06-15 15:45:12 +020024#include <string.h>
25#include <stdlib.h>
26#include <stdio.h>
27#include <errno.h>
28#include <ncurses.h>
Sanjay Singh Rawat83b37c32013-04-17 14:57:07 +053029#include <signal.h>
Daniel Lezcanocac52d92011-03-26 22:05:49 +010030#include "regulator.h"
Daniel Lezcano192c1d22011-03-26 22:06:14 +010031#include "display.h"
Daniel Lezcanof0e06652011-03-26 22:06:19 +010032#include "clocks.h"
Daniel Lezcano597892a2011-06-15 15:45:12 +020033#include "sensor.h"
Daniel Lezcano716b23e2011-08-25 15:46:13 +020034#include "gpio.h"
Daniel Lezcanodb145802011-06-21 00:57:08 +020035#include "mainloop.h"
Amit Arorae9e16b02010-08-03 10:15:20 +053036#include "powerdebug.h"
37
Sanjay Singh Rawat83b37c32013-04-17 14:57:07 +053038extern void sigwinch_handler(int);
39
Daniel Lezcano9db095c2016-02-18 13:05:01 +000040#define REGULATOR_OPTION 0x01
41#define SENSOR_OPTION 0x02
42#define CLOCK_OPTION 0x04
43#define GPIO_OPTION 0x08
44
45#define VERBOSE_OPTION 0x10
46#define DUMP_OPTION 0x20
47
48#define DEFAULT_OPTION (REGULATOR_OPTION | SENSOR_OPTION | \
49 CLOCK_OPTION | GPIO_OPTION)
50
Amit Arora422c52f2010-12-02 16:22:29 +053051void usage(void)
Amit Arorae9e16b02010-08-03 10:15:20 +053052{
Amit Arora422c52f2010-12-02 16:22:29 +053053 printf("Usage: powerdebug [OPTIONS]\n");
54 printf("\n");
55 printf("powerdebug -d [ -r ] [ -s ] [ -c [ -p <clock-name> ] ] "
56 "[ -v ]\n");
57 printf("powerdebug [ -r | -s | -c ]\n");
Amit Arora17552782010-12-02 12:23:14 +053058 printf(" -r, --regulator Show regulator information\n");
59 printf(" -s, --sensor Show sensor information\n");
60 printf(" -c, --clock Show clock information\n");
Amit Arora422c52f2010-12-02 16:22:29 +053061 printf(" -p, --findparents Show all parents for a particular"
Amit Kucheriaa0adae42011-01-12 10:54:23 -060062 " clock\n");
Amit Arora17552782010-12-02 12:23:14 +053063 printf(" -t, --time Set ticktime in seconds (eg. 10.0)\n");
64 printf(" -d, --dump Dump information once (no refresh)\n");
Amit Arora422c52f2010-12-02 16:22:29 +053065 printf(" -v, --verbose Verbose mode (use with -r and/or"
Amit Kucheriaa0adae42011-01-12 10:54:23 -060066 " -s)\n");
Amit Arora17552782010-12-02 12:23:14 +053067 printf(" -V, --version Show Version\n");
68 printf(" -h, --help Help\n");
Amit Arorae9e16b02010-08-03 10:15:20 +053069}
70
Amit Arora17552782010-12-02 12:23:14 +053071void version()
Amit Arorae9e16b02010-08-03 10:15:20 +053072{
Amit Arora17552782010-12-02 12:23:14 +053073 printf("powerdebug version %s\n", VERSION);
Amit Arorae9e16b02010-08-03 10:15:20 +053074}
75
Daniel Lezcano316bcae2011-03-23 14:37:30 +010076/*
77 * Options:
Daniel Lezcano716b23e2011-08-25 15:46:13 +020078 * -r, --regulator : regulators
Daniel Lezcano316bcae2011-03-23 14:37:30 +010079 * -s, --sensor : sensors
80 * -c, --clock : clocks
Daniel Lezcano716b23e2011-08-25 15:46:13 +020081 * -g, --gpio : gpios
Daniel Lezcano316bcae2011-03-23 14:37:30 +010082 * -p, --findparents : clockname whose parents have to be found
83 * -t, --time : ticktime
84 * -d, --dump : dump
85 * -v, --verbose : verbose
86 * -V, --version : version
87 * -h, --help : help
88 * no option / default : show usage!
89 */
90
91static struct option long_options[] = {
92 { "regulator", 0, 0, 'r' },
93 { "sensor", 0, 0, 's' },
94 { "clock", 0, 0, 'c' },
Daniel Lezcano716b23e2011-08-25 15:46:13 +020095 { "gpio", 0, 0, 'g' },
Daniel Lezcano316bcae2011-03-23 14:37:30 +010096 { "findparents", 1, 0, 'p' },
97 { "time", 1, 0, 't' },
98 { "dump", 0, 0, 'd' },
99 { "verbose", 0, 0, 'v' },
100 { "version", 0, 0, 'V' },
101 { "help", 0, 0, 'h' },
102 { 0, 0, 0, 0 }
103};
104
105struct powerdebug_options {
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000106 int flags;
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100107 unsigned int ticktime;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100108 int selectedwindow;
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100109 char *clkname;
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100110};
111
112int getoptions(int argc, char *argv[], struct powerdebug_options *options)
Amit Arorae9e16b02010-08-03 10:15:20 +0530113{
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100114 int c;
Amit Arorae9e16b02010-08-03 10:15:20 +0530115
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100116 memset(options, 0, sizeof(*options));
117 options->ticktime = 10;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100118 options->selectedwindow = -1;
Amit Arorae9e16b02010-08-03 10:15:20 +0530119
Amit Arorafefe8bf2010-08-05 13:31:20 +0530120 while (1) {
121 int optindex = 0;
Amit Arorafefe8bf2010-08-05 13:31:20 +0530122
Daniel Lezcano716b23e2011-08-25 15:46:13 +0200123 c = getopt_long(argc, argv, "rscgp:t:dvVh",
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100124 long_options, &optindex);
Amit Arorafefe8bf2010-08-05 13:31:20 +0530125 if (c == -1)
126 break;
127
128 switch (c) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530129 case 'r':
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000130 options->flags |= REGULATOR_OPTION;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100131 options->selectedwindow = REGULATOR;
Amit Arora6e774cd2010-10-28 11:31:24 +0530132 break;
133 case 's':
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000134 options->flags |= SENSOR_OPTION;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100135 options->selectedwindow = SENSOR;
Amit Arora6e774cd2010-10-28 11:31:24 +0530136 break;
137 case 'c':
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000138 options->flags |= CLOCK_OPTION;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100139 options->selectedwindow = CLOCK;
Amit Arora6e774cd2010-10-28 11:31:24 +0530140 break;
Daniel Lezcano716b23e2011-08-25 15:46:13 +0200141 case 'g':
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000142 options->flags |= GPIO_OPTION;
Daniel Lezcano716b23e2011-08-25 15:46:13 +0200143 options->selectedwindow = GPIO;
144 break;
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000145 case 'd':
146 options->flags |= DUMP_OPTION;
147 break;
148 case 'v':
149 options->flags |= VERBOSE_OPTION;
150 break;
Amit Aroraf4fb8102010-11-30 13:55:50 +0530151 case 'p':
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100152 options->clkname = strdup(optarg);
153 if (!options->clkname) {
Daniel Lezcano9420fde2011-03-23 14:37:31 +0100154 fprintf(stderr, "failed to allocate memory");
155 return -1;
156 }
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000157 options->flags |= (DUMP_OPTION | CLOCK_OPTION);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530158 break;
Amit Arora6e774cd2010-10-28 11:31:24 +0530159 case 't':
Daniel Lezcano7f112da2011-03-23 14:37:32 +0100160 options->ticktime = atoi(optarg);
Amit Arora6e774cd2010-10-28 11:31:24 +0530161 break;
Amit Arora6e774cd2010-10-28 11:31:24 +0530162 case 'V':
163 version();
164 break;
Amit Arora6e774cd2010-10-28 11:31:24 +0530165 case '?':
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100166 fprintf(stderr, "%s: Unknown option %c'.\n",
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600167 argv[0], optopt);
Amit Arora6e774cd2010-10-28 11:31:24 +0530168 default:
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100169 return -1;
Amit Arorafefe8bf2010-08-05 13:31:20 +0530170 }
Amit Arorae9e16b02010-08-03 10:15:20 +0530171 }
Amit Aroraa06a7302010-12-02 15:59:37 +0530172
Daniel Lezcano934fc092011-03-26 22:06:18 +0100173 /* No system specified to be dump, let's default to all */
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000174 if (!(options->flags & DEFAULT_OPTION))
175 options->flags |= DEFAULT_OPTION;
Amit Arorafefe8bf2010-08-05 13:31:20 +0530176
Daniel Lezcanoc9c14622011-03-26 22:06:10 +0100177 if (options->selectedwindow == -1)
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100178 options->selectedwindow = CLOCK;
Amit Arorae9e16b02010-08-03 10:15:20 +0530179
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100180 return 0;
181}
182
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200183static int powerdebug_dump(struct powerdebug_options *options)
Daniel Lezcano21c04d42011-03-26 22:06:04 +0100184{
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000185 if (options->flags & REGULATOR_OPTION)
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200186 regulator_dump();
Daniel Lezcanob5746712011-03-26 22:06:05 +0100187
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000188 if (options->flags & CLOCK_OPTION)
Daniel Lezcano597892a2011-06-15 15:45:12 +0200189 clock_dump(options->clkname);
Daniel Lezcanob5746712011-03-26 22:06:05 +0100190
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000191 if (options->flags & SENSOR_OPTION)
Daniel Lezcano3d0aef42011-06-15 15:45:12 +0200192 sensor_dump();
Daniel Lezcanob5746712011-03-26 22:06:05 +0100193
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000194 if (options->flags & GPIO_OPTION)
Daniel Lezcano716b23e2011-08-25 15:46:13 +0200195 gpio_dump();
196
Daniel Lezcano21c04d42011-03-26 22:06:04 +0100197 return 0;
198}
199
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200200static int powerdebug_display(struct powerdebug_options *options)
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100201{
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200202 if (display_init(options->selectedwindow)) {
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100203 printf("failed to initialize display\n");
204 return -1;
205 }
206
Daniel Lezcanodb145802011-06-21 00:57:08 +0200207 if (mainloop(options->ticktime * 1000))
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100208 return -1;
209
210 return 0;
211}
212
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100213static struct powerdebug_options *powerdebug_init(void)
214{
215 struct powerdebug_options *options;
216
Daniel Lezcano188ff0f2016-02-18 15:40:12 +0000217 signal(SIGWINCH, sigwinch_handler);
218
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100219 options = malloc(sizeof(*options));
220 if (!options)
221 return NULL;
222
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100223 return options;
224}
225
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100226int main(int argc, char **argv)
227{
228 struct powerdebug_options *options;
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200229 int ret;
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100230
Sanjay Singh Rawat9fe0c052013-02-22 17:57:18 +0530231#ifdef __ANDROID__
232 if (setenv("TERM", "xterm", 1) < 0) {
233 fprintf(stderr, "setenv failure");
234 return 1;
235 }
236 if (setenv("TERMINFO", "/system/etc/terminfo", 1) < 0) {
237 fprintf(stderr, "setenv failure");
238 return 1;
239 }
240#endif
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100241 options = powerdebug_init();
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100242 if (!options) {
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100243 fprintf(stderr, "not enough memory to allocate options\n");
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100244 return 1;
245 }
246
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100247 if (getoptions(argc, argv, options)) {
248 usage();
249 return 1;
250 }
251
Daniel Lezcanodb145802011-06-21 00:57:08 +0200252 if (mainloop_init()) {
253 fprintf(stderr, "failed to initialize the mainloop\n");
254 return 1;
255 }
256
Daniel Lezcano188ff0f2016-02-18 15:40:12 +0000257 if ((options->flags & REGULATOR_OPTION) && regulator_init()) {
Sanjay Singh Rawat5fef0052013-04-17 15:02:01 +0530258 printf("failed to initialize regulator\n");
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000259 options->flags &= ~REGULATOR_OPTION;
Daniel Lezcano4aab2fe2011-03-26 22:05:53 +0100260 }
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100261
Daniel Lezcano188ff0f2016-02-18 15:40:12 +0000262 if ((options->flags & CLOCK_OPTION) && clock_init()) {
Daniel Lezcanof0e06652011-03-26 22:06:19 +0100263 printf("failed to initialize clock details (check debugfs)\n");
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000264 options->flags &= ~CLOCK_OPTION;
Daniel Lezcanof0e06652011-03-26 22:06:19 +0100265 }
266
Daniel Lezcano188ff0f2016-02-18 15:40:12 +0000267 if ((options->flags & SENSOR_OPTION) && sensor_init()) {
Daniel Lezcano3d0aef42011-06-15 15:45:12 +0200268 printf("failed to initialize sensors\n");
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000269 options->flags &= SENSOR_OPTION;
Daniel Lezcano3d0aef42011-06-15 15:45:12 +0200270 }
271
Daniel Lezcano188ff0f2016-02-18 15:40:12 +0000272 if ((options->flags & GPIO_OPTION) && gpio_init()) {
Daniel Lezcano716b23e2011-08-25 15:46:13 +0200273 printf("failed to initialize gpios\n");
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000274 options->flags &= GPIO_OPTION;
Daniel Lezcano716b23e2011-08-25 15:46:13 +0200275 }
276
Daniel Lezcano9db095c2016-02-18 13:05:01 +0000277 ret = options->flags & DUMP_OPTION ? powerdebug_dump(options) :
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200278 powerdebug_display(options);
Daniel Lezcano21c04d42011-03-26 22:06:04 +0100279
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100280 return ret < 0;
Amit Arorae9e16b02010-08-03 10:15:20 +0530281}