aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk34
-rw-r--r--Makefile2
-rw-r--r--clocks.c25
-rw-r--r--debian/changelog13
-rw-r--r--display.c1
-rw-r--r--display.h4
-rw-r--r--gpio.c280
-rw-r--r--gpio.h17
-rw-r--r--powerdebug.c26
-rw-r--r--powerdebug.h2
-rw-r--r--regulator.c2
-rw-r--r--sensor.c2
-rw-r--r--tree.c11
-rw-r--r--tree.h2
14 files changed, 381 insertions, 40 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..e062c1c
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,34 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := libstlport
+
+LOCAL_STATIC_LIBRARIES := libncurses
+
+LOCAL_MODULE := powerdebug
+
+LOCAL_CPPFLAGS += \
+ -DDISABLE_I18N \
+ -DDISABLE_TRYCATCH \
+ -DNCURSES_NOMACROS \
+ -DDISABLE_WSTRING \
+ -DDEFAULT_TERM=\"xterm\" \
+ -DTERMINFO_PATH=\"/system/etc/terminfo\" \
+ -DDEFINE_ETHTOOL_CMD \
+
+LOCAL_C_INCLUDES += external/stlport/stlport/ \
+ external/stlport/stlport/stl \
+ external/stlport/stlport/using/h/ \
+ bionic \
+ external/ncurses \
+ external/ncurses/lib \
+ external/ncurses/include \
+ external/ncurses/include/ncurses
+
+LOCAL_SRC_FILES += \
+ powerdebug.c sensor.c clocks.c regulator.c \
+ display.c tree.c utils.c mainloop.c
+
+include $(BUILD_EXECUTABLE)
diff --git a/Makefile b/Makefile
index 8d41b24..2da9d67 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ MANDIR=/usr/share/man/man8
CFLAGS?=-O1 -g -Wall -Wshadow
CC?=gcc
-OBJS = powerdebug.o sensor.o clocks.o regulator.o \
+OBJS = powerdebug.o sensor.o clocks.o regulator.o gpio.o \
display.o tree.o utils.o mainloop.o
default: powerdebug
diff --git a/clocks.c b/clocks.c
index 20a245c..2611a0d 100644
--- a/clocks.c
+++ b/clocks.c
@@ -48,27 +48,8 @@ static struct tree *clock_tree = NULL;
static int locate_debugfs(char *clk_path)
{
- const char *mtab = "/proc/mounts";
- struct mntent *mntent;
- int ret = -1;
- FILE *file = NULL;
-
- file = setmntent(mtab, "r");
- if (!file)
- return -1;
-
- while ((mntent = getmntent(file))) {
-
- if (strcmp(mntent->mnt_type, "debugfs"))
- continue;
-
- strcpy(clk_path, mntent->mnt_dir);
- ret = 0;
- break;
- }
-
- fclose(file);
- return ret;
+ strcpy(clk_path, "/sys/kernel/debug");
+ return 0;
}
static struct clock_info *clock_alloc(void)
@@ -413,7 +394,7 @@ int clock_init(void)
if (access(clk_dir_path, F_OK))
return -1;
- clock_tree = tree_load(clk_dir_path, NULL);
+ clock_tree = tree_load(clk_dir_path, NULL, false);
if (!clock_tree)
return -1;
diff --git a/debian/changelog b/debian/changelog
index 33dd149..1aecbca 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,16 +1,23 @@
-powerdebug (0.5-2011.08-0) natty; urgency=low
+powerdebug (0.6.0-2011.09-0) natty; urgency=low
+
+ * added gpio support
+ * added android port
+
+ -- Daniel Lezcano <daniel.lezcano@linaro.org> Tue, 20 Sep 2011 15:54:06 +0200
+
+powerdebug (0.5.2-2011.08-0) natty; urgency=low
* fixed lp: 827825
-- Daniel Lezcano <daniel.lezcano@linaro.org> Wed, 17 Aug 2011 17:01:28 +0200
-powerdebug (0.5-2011.07-0) natty; urgency=low
+powerdebug (0.5.1-2011.07-0) natty; urgency=low
* fixed lp: 802387
-- Daniel Lezcano <daniel.lezcano@linaro.org> Mon, 25 Jul 2011 23:25:05 +0200
-powerdebug (0.5-2011.06-0) natty; urgency=low
+powerdebug (0.5.0-2011.06-0) natty; urgency=low
* added tree algorithm
* a lot of code cleanup
diff --git a/display.c b/display.c
index ebc4de6..f06387c 100644
--- a/display.c
+++ b/display.c
@@ -63,6 +63,7 @@ struct windata windata[] = {
[CLOCK] = { .name = "Clocks" },
[REGULATOR] = { .name = "Regulators" },
[SENSOR] = { .name = "Sensors" },
+ [GPIO] = { .name = "Gpio" },
};
static void display_fini(void)
diff --git a/display.h b/display.h
index 9e4e21a..6362a48 100644
--- a/display.h
+++ b/display.h
@@ -13,7 +13,7 @@
* - initial API and implementation
*******************************************************************************/
-enum { CLOCK, REGULATOR, SENSOR };
+enum { CLOCK, REGULATOR, SENSOR, GPIO };
struct display_ops {
int (*display)(bool refresh);
@@ -32,3 +32,5 @@ extern void *display_get_row_data(int window);
extern int display_init(int wdefault);
extern int display_register(int win, struct display_ops *ops);
extern int display_column_name(const char *line);
+
+#define NAME_MAX 255
diff --git a/gpio.c b/gpio.c
new file mode 100644
index 0000000..f7d2a10
--- /dev/null
+++ b/gpio.c
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Linaro Limited.
+ *
+ * This file is part of PowerDebug.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Daniel Lezcano <daniel.lezcano@linaro.org> (IBM Corporation)
+ * - initial API and implementation
+ *******************************************************************************/
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#include <stdio.h>
+#undef _GNU_SOURCE
+#endif
+#include <mntent.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include "powerdebug.h"
+#include "display.h"
+#include "tree.h"
+#include "utils.h"
+
+#define SYSFS_GPIO "/sys/class/gpio"
+
+struct gpio_info {
+ bool expanded;
+ int active_low;
+ int value;
+ int direction;
+ int edge;
+ char *prefix;
+} *gpios_info;
+
+static struct tree *gpio_tree = NULL;
+
+static struct gpio_info *gpio_alloc(void)
+{
+ struct gpio_info *gi;
+
+ gi = malloc(sizeof(*gi));
+ if (gi) {
+ memset(gi, -1, sizeof(*gi));
+ gi->prefix = NULL;
+ }
+
+ return gi;
+}
+
+static int gpio_filter_cb(const char *name)
+{
+ /* let's ignore some directories in order to avoid to be
+ * pulled inside the sysfs circular symlinks mess/hell
+ * (choose the word which fit better)
+ */
+ if (!strcmp(name, "device"))
+ return 1;
+
+ if (!strcmp(name, "subsystem"))
+ return 1;
+
+ if (!strcmp(name, "driver"))
+ return 1;
+
+ /* we want to ignore the gpio chips */
+ if (strstr(name, "chip"))
+ return 1;
+
+ /* we are not interested by the power value */
+ if (!strcmp(name, "power"))
+ return 1;
+
+ return 0;
+}
+
+static inline int read_gpio_cb(struct tree *t, void *data)
+{
+ struct gpio_info *gpio = t->private;
+
+ file_read_value(t->path, "active_low", "%d", &gpio->active_low);
+ file_read_value(t->path, "value", "%d", &gpio->value);
+ file_read_value(t->path, "edge", "%d", &gpio->edge);
+ file_read_value(t->path, "direction", "%d", &gpio->direction);
+
+ return 0;
+}
+
+static int read_gpio_info(struct tree *tree)
+{
+ return tree_for_each(tree, read_gpio_cb, NULL);
+}
+
+static int fill_gpio_cb(struct tree *t, void *data)
+{
+ struct gpio_info *gpio;
+
+ gpio = gpio_alloc();
+ if (!gpio)
+ return -1;
+ t->private = gpio;
+
+ /* we skip the root node but we set it expanded for its children */
+ if (!t->parent) {
+ gpio->expanded = true;
+ return 0;
+ }
+
+ return read_gpio_cb(t, data);
+
+}
+
+static int fill_gpio_tree(void)
+{
+ return tree_for_each(gpio_tree, fill_gpio_cb, NULL);
+}
+
+static int dump_gpio_cb(struct tree *t, void *data)
+{
+ struct gpio_info *gpio = t->private;
+ struct gpio_info *pgpio;
+
+ if (!t->parent) {
+ printf("/\n");
+ gpio->prefix = "";
+ return 0;
+ }
+
+ pgpio = t->parent->private;
+
+ if (!gpio->prefix)
+ if (asprintf(&gpio->prefix, "%s%s%s", pgpio->prefix,
+ t->depth > 1 ? " ": "", t->next ? "|" : " ") < 0)
+ return -1;
+
+ printf("%s%s-- %s (", gpio->prefix, !t->next ? "`" : "", t->name);
+
+ if (gpio->active_low != -1)
+ printf(" active_low:%d", gpio->active_low);
+
+ if (gpio->value != -1)
+ printf(", value:%d", gpio->value);
+
+ if (gpio->edge != -1)
+ printf(", edge:%d", gpio->edge);
+
+ if (gpio->direction != -1)
+ printf(", direction:%d", gpio->direction);
+
+ printf(" )\n");
+
+ return 0;
+}
+
+int dump_gpio_info(void)
+{
+ return tree_for_each(gpio_tree, dump_gpio_cb, NULL);
+}
+
+int gpio_dump(void)
+{
+ int ret;
+
+ printf("\nGpio Tree :\n");
+ printf("***********\n");
+ ret = dump_gpio_info();
+ printf("\n\n");
+
+ return ret;
+}
+
+static char *gpio_line(struct tree *t)
+{
+ struct gpio_info *gpio = t->private;
+ char *gpioline;
+
+ if (asprintf(&gpioline, "%-20s %-10d %-10d %-10d %-10d", t-> name,
+ gpio->value, gpio->active_low, gpio->edge, gpio->direction) < 0)
+ return NULL;
+
+ return gpioline;
+}
+
+static int _gpio_print_info_cb(struct tree *t, void *data)
+{
+ int *line = data;
+ char *buffer;
+
+ /* we skip the root node of the tree */
+ if (!t->parent)
+ return 0;
+
+ buffer = gpio_line(t);
+ if (!buffer)
+ return -1;
+
+ display_print_line(GPIO, *line, buffer, 0, t);
+
+ (*line)++;
+
+ free(buffer);
+
+ return 0;
+}
+
+static int gpio_print_info_cb(struct tree *t, void *data)
+{
+ /* we skip the root node of the tree */
+ if (!t->parent)
+ return 0;
+
+ return _gpio_print_info_cb(t, data);
+}
+
+static int gpio_print_header(void)
+{
+ char *buf;
+ int ret;
+
+ if (asprintf(&buf, "%-20s %-10s %-10s %-10s %-10s",
+ "Name", "Value", "Active_low", "Edge", "Direction") < 0)
+ return -1;
+
+ ret = display_column_name(buf);
+
+ free(buf);
+
+ return ret;
+}
+
+static int gpio_print_info(struct tree *tree)
+{
+ int ret, line = 0;
+
+ display_reset_cursor(GPIO);
+
+ gpio_print_header();
+
+ ret = tree_for_each(tree, gpio_print_info_cb, &line);
+
+ display_refresh_pad(GPIO);
+
+ return ret;
+}
+
+static int gpio_display(bool refresh)
+{
+ if (refresh && read_gpio_info(gpio_tree))
+ return -1;
+
+ return gpio_print_info(gpio_tree);
+}
+
+static struct display_ops gpio_ops = {
+ .display = gpio_display,
+};
+
+/*
+ * Initialize the gpio framework
+ */
+int gpio_init(void)
+{
+ gpio_tree = tree_load(SYSFS_GPIO, gpio_filter_cb, false);
+ if (!gpio_tree)
+ return -1;
+
+ if (fill_gpio_tree())
+ return -1;
+
+ return display_register(GPIO, &gpio_ops);
+}
diff --git a/gpio.h b/gpio.h
new file mode 100644
index 0000000..38f035f
--- /dev/null
+++ b/gpio.h
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Linaro Limited.
+ *
+ * This file is part of PowerDebug.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Daniel Lezcano <daniel.lezcano@linaro.org> (IBM Corporation)
+ * - initial API and implementation
+ *******************************************************************************/
+
+extern int gpio_init(void);
+extern int gpio_dump(void);
diff --git a/powerdebug.c b/powerdebug.c
index b4575c4..cc9e871 100644
--- a/powerdebug.c
+++ b/powerdebug.c
@@ -24,6 +24,7 @@
#include "display.h"
#include "clocks.h"
#include "sensor.h"
+#include "gpio.h"
#include "mainloop.h"
#include "powerdebug.h"
@@ -54,9 +55,10 @@ void version()
/*
* Options:
- * -r, --regulator : regulator
+ * -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
@@ -70,6 +72,7 @@ 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' },
@@ -84,6 +87,7 @@ struct powerdebug_options {
bool regulators;
bool sensors;
bool clocks;
+ bool gpios;
bool dump;
unsigned int ticktime;
int selectedwindow;
@@ -101,7 +105,7 @@ int getoptions(int argc, char *argv[], struct powerdebug_options *options)
while (1) {
int optindex = 0;
- c = getopt_long(argc, argv, "rscp:t:dvVh",
+ c = getopt_long(argc, argv, "rscgp:t:dvVh",
long_options, &optindex);
if (c == -1)
break;
@@ -119,6 +123,10 @@ int getoptions(int argc, char *argv[], struct powerdebug_options *options)
options->clocks = true;
options->selectedwindow = CLOCK;
break;
+ case 'g':
+ options->gpios = true;
+ options->selectedwindow = GPIO;
+ break;
case 'p':
options->clkname = strdup(optarg);
if (!options->clkname) {
@@ -149,8 +157,10 @@ int getoptions(int argc, char *argv[], struct powerdebug_options *options)
}
/* No system specified to be dump, let's default to all */
- if (!options->regulators && !options->clocks && !options->sensors)
- options->regulators = options->clocks = options->sensors = true;
+ if (!options->regulators && !options->clocks &&
+ !options->sensors && !options->gpios)
+ options->regulators = options->clocks =
+ options->sensors = options->gpios = true;
if (options->selectedwindow == -1)
options->selectedwindow = CLOCK;
@@ -169,6 +179,9 @@ static int powerdebug_dump(struct powerdebug_options *options)
if (options->sensors)
sensor_dump();
+ if (options->gpios)
+ gpio_dump();
+
return 0;
}
@@ -234,6 +247,11 @@ int main(int argc, char **argv)
options->sensors = false;
}
+ if (gpio_init()) {
+ printf("failed to initialize gpios\n");
+ options->gpios = false;
+ }
+
ret = options->dump ? powerdebug_dump(options) :
powerdebug_display(options);
diff --git a/powerdebug.h b/powerdebug.h
index 05d919b..39a7b31 100644
--- a/powerdebug.h
+++ b/powerdebug.h
@@ -13,4 +13,4 @@
* - initial API and implementation
*******************************************************************************/
-#define VERSION "0.5.1"
+#define VERSION "0.6.0"
diff --git a/regulator.c b/regulator.c
index e9b01bb..55bd3e9 100644
--- a/regulator.c
+++ b/regulator.c
@@ -236,7 +236,7 @@ static struct display_ops regulator_ops = {
int regulator_init(void)
{
- reg_tree = tree_load(SYSFS_REGULATOR, regulator_filter_cb);
+ reg_tree = tree_load(SYSFS_REGULATOR, regulator_filter_cb, false);
if (!reg_tree)
return -1;
diff --git a/sensor.c b/sensor.c
index e172f88..ff1e3dd 100644
--- a/sensor.c
+++ b/sensor.c
@@ -271,7 +271,7 @@ static struct display_ops sensor_ops = {
int sensor_init(void)
{
- sensor_tree = tree_load(SYSFS_SENSOR, sensor_filter_cb);
+ sensor_tree = tree_load(SYSFS_SENSOR, sensor_filter_cb, false);
if (!sensor_tree)
return -1;
diff --git a/tree.c b/tree.c
index aefe0fe..d331c60 100644
--- a/tree.c
+++ b/tree.c
@@ -17,6 +17,7 @@
#include <stdio.h>
#undef _GNU_SOURCE
#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
@@ -111,7 +112,7 @@ static inline void tree_add_child(struct tree *parent, struct tree *child)
* @filter : a callback to filter out the directories
* Returns 0 on success, -1 otherwise
*/
-static int tree_scan(struct tree *tree, tree_filter_t filter)
+static int tree_scan(struct tree *tree, tree_filter_t filter, bool follow)
{
DIR *dir;
char *basedir, *newpath;
@@ -152,7 +153,7 @@ static int tree_scan(struct tree *tree, tree_filter_t filter)
if (ret)
goto out_free_newpath;
- if (S_ISDIR(s.st_mode)) {
+ if (S_ISDIR(s.st_mode) || (S_ISLNK(s.st_mode) && follow)) {
ret = -1;
@@ -164,7 +165,7 @@ static int tree_scan(struct tree *tree, tree_filter_t filter)
tree->nrchild++;
- ret = tree_scan(child, filter);
+ ret = tree_scan(child, filter, follow);
}
out_free_newpath:
@@ -190,7 +191,7 @@ static int tree_scan(struct tree *tree, tree_filter_t filter)
* Returns a tree structure corresponding to the root node of the
* directory tree representation on success, NULL otherwise
*/
-struct tree *tree_load(const char *path, tree_filter_t filter)
+struct tree *tree_load(const char *path, tree_filter_t filter, bool follow)
{
struct tree *tree;
@@ -198,7 +199,7 @@ struct tree *tree_load(const char *path, tree_filter_t filter)
if (!tree)
return NULL;
- if (tree_scan(tree, filter)) {
+ if (tree_scan(tree, filter, follow)) {
tree_free(tree);
return NULL;
}
diff --git a/tree.h b/tree.h
index c7f3ca9..5c1c697 100644
--- a/tree.h
+++ b/tree.h
@@ -41,7 +41,7 @@ typedef int (*tree_cb_t)(struct tree *t, void *data);
typedef int (*tree_filter_t)(const char *name);
-extern struct tree *tree_load(const char *path, tree_filter_t filter);
+extern struct tree *tree_load(const char *path, tree_filter_t filter, bool follow);
extern struct tree *tree_find(struct tree *tree, const char *name);