blob: 164126d07ce451571a221bbe385f929c9b4fb636 [file] [log] [blame]
/*
* Power debug tool (powerdebug)
*
* Copyright (C) 2016, Linaro Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include <getopt.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ncurses.h>
#include "display.h"
#include "mainloop.h"
#include "powerdebug.h"
void usage(void)
{
printf("Usage: powerdebug [OPTIONS]\n");
printf("\n");
printf("powerdebug -d [ -r ] [ -s ] [ -c [ -p <clock-name> ] ] "
"[ -v ]\n");
printf("powerdebug [ -r | -s | -c ]\n");
printf(" -r, --regulator Show regulator information\n");
printf(" -s, --sensor Show sensor information\n");
printf(" -c, --clock Show clock information\n");
printf(" -p, --findparents Show all parents for a particular"
" clock\n");
printf(" -t, --time Set ticktime in seconds (eg. 10.0)\n");
printf(" -d, --dump Dump information once (no refresh)\n");
printf(" -v, --verbose Verbose mode (use with -r and/or"
" -s)\n");
printf(" -V, --version Show Version\n");
printf(" -h, --help Help\n");
}
void version()
{
printf("powerdebug version %s\n", VERSION);
}
/*
* Options:
* -r, --regulator : regulators
* -s, --sensor : sensors
* -c, --clock : clocks
* -g, --gpio : gpios
* -p, --findparents : clockname whose parents have to be found
* -t, --time : ticktime
* -d, --dump : dump
* -v, --verbose : verbose
* -V, --version : version
* -h, --help : help
* no option / default : show usage!
*/
static struct option long_options[] = {
{ "regulator", 0, 0, 'r' },
{ "sensor", 0, 0, 's' },
{ "clock", 0, 0, 'c' },
{ "gpio", 0, 0, 'g' },
{ "findparents", 1, 0, 'p' },
{ "time", 1, 0, 't' },
{ "dump", 0, 0, 'd' },
{ "verbose", 0, 0, 'v' },
{ "version", 0, 0, 'V' },
{ "help", 0, 0, 'h' },
{ 0, 0, 0, 0 }
};
int getoptions(int argc, char *argv[], struct powerdebug_options *options)
{
int c;
memset(options, 0, sizeof(*options));
options->ticktime = 1;
while (1) {
int optindex = 0;
c = getopt_long(argc, argv, "rscgp:t:dvVh",
long_options, &optindex);
if (c == -1)
break;
switch (c) {
case 'r':
options->flags |= REGULATOR_OPTION;
break;
case 's':
options->flags |= SENSOR_OPTION;
break;
case 'c':
options->flags |= CLOCK_OPTION;
break;
case 'g':
options->flags |= GPIO_OPTION;
break;
case 'd':
options->flags |= DUMP_OPTION;
break;
case 'v':
options->flags |= VERBOSE_OPTION;
break;
case 'p':
options->clkname = strdup(optarg);
if (!options->clkname) {
fprintf(stderr, "failed to allocate memory");
return -1;
}
options->flags |= (DUMP_OPTION | CLOCK_OPTION);
break;
case 't':
options->ticktime = atoi(optarg);
break;
case 'V':
version();
break;
case '?':
fprintf(stderr, "%s: Unknown option %c'.\n",
argv[0], optopt);
default:
return -1;
}
}
/* No system specified to be dump, let's default to all */
if (!(options->flags & DEFAULT_OPTION))
options->flags |= DEFAULT_OPTION;
return 0;
}
static int powerdebug_dump(struct powerdebug_options *options)
{
if (options->flags & REGULATOR_OPTION)
regulator_dump();
if (options->flags & CLOCK_OPTION)
clock_dump(options->clkname);
if (options->flags & SENSOR_OPTION)
sensor_dump();
if (options->flags & GPIO_OPTION)
gpio_dump();
return 0;
}
static int powerdebug_display(struct powerdebug_options *options)
{
if (display_init(options)) {
printf("failed to initialize display\n");
return -1;
}
if (mainloop(options->ticktime * 1000))
return -1;
return 0;
}
static struct powerdebug_options *powerdebug_init(void)
{
struct powerdebug_options *options;
options = malloc(sizeof(*options));
if (!options)
return NULL;
return options;
}
int main(int argc, char **argv)
{
struct powerdebug_options *options;
int ret;
#ifdef __ANDROID__
if (setenv("TERM", "xterm", 1) < 0) {
fprintf(stderr, "setenv failure");
return 1;
}
if (setenv("TERMINFO", "/system/etc/terminfo", 1) < 0) {
fprintf(stderr, "setenv failure");
return 1;
}
#endif
options = powerdebug_init();
if (!options) {
fprintf(stderr, "not enough memory to allocate options\n");
return 1;
}
if (getoptions(argc, argv, options)) {
usage();
return 1;
}
if (mainloop_init()) {
fprintf(stderr, "failed to initialize the mainloop\n");
return 1;
}
if (regulator_init(options)) {
printf("failed to initialize regulator\n");
options->flags &= ~REGULATOR_OPTION;
}
if (clock_init(options)) {
printf("failed to initialize clock details (check debugfs)\n");
options->flags &= ~CLOCK_OPTION;
}
if (sensor_init(options)) {
printf("failed to initialize sensors\n");
options->flags &= SENSOR_OPTION;
}
if (gpio_init(options)) {
printf("failed to initialize gpios\n");
options->flags &= GPIO_OPTION;
}
ret = options->flags & DUMP_OPTION ? powerdebug_dump(options) :
powerdebug_display(options);
return ret < 0;
}