Hello Amit/Sanjay,

Did you get a chance to look at the patch?

--
Thanks,
-Meraj

On Mon, Jun 30, 2014 at 2:06 PM, Mohammad Merajul Islam Molla
<meraj.eni...@gmail.com> wrote:
> Add support for pinctrl in powerdebug. Both dump and display
> modes supported. Tested only on Samsung Arndale board.
>
> Sample output in display mode on Arndale Board -
>
> Pin   Name       MUX Owner       GPIO Owner      HOG   Function
> Group
> 0     gpa0-0     MUX UNCLAIMED   GPIO UNCLAIMED
> 1     gpa0-1     MUX UNCLAIMED   GPIO UNCLAIMED
> 2     gpa0-2     MUX UNCLAIMED   GPIO UNCLAIMED
> 3     gpa0-3     MUX UNCLAIMED   GPIO UNCLAIMED
> 4     gpa0-4     MUX UNCLAIMED   GPIO UNCLAIMED
> 5     gpa0-5     MUX UNCLAIMED   GPIO UNCLAIMED
> 6     gpa0-6     12c80000.i2c    GPIO UNCLAIMED        i2c2-bus-mux
> i2c2-bus-grp
> 7     gpa0-7     12c80000.i2c    GPIO UNCLAIMED        i2c2-bus-mux
> i2c2-bus-grp
> 8     gpa1-0     MUX UNCLAIMED   GPIO UNCLAIMED
> 9     gpa1-1     MUX UNCLAIMED   GPIO UNCLAIMED
> 10    gpa1-2     12c90000.i2c    GPIO UNCLAIMED        i2c3-bus-mux
> i2c3-bus-grp
> 11    gpa1-3     12c90000.i2c    GPIO UNCLAIMED        i2c3-bus-mux
> i2c3-bus-grp
>
>
>
> ---
>  Android.mk   |   2 +-
>  Makefile     |   2 +-
>  README       |   4 +-
>  display.c    |   3 +-
>  display.h    |   2 +-
>  pinctrl.c    | 329 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  pinctrl.h    |  19 ++++
>  powerdebug.c |  35 +++++--
>  8 files changed, 381 insertions(+), 15 deletions(-)
>  create mode 100644 pinctrl.c
>  create mode 100644 pinctrl.h
>
> diff --git a/Android.mk b/Android.mk
> index 36c73cd..19d00ca 100644
> --- a/Android.mk
> +++ b/Android.mk
> @@ -29,6 +29,6 @@ LOCAL_C_INCLUDES += external/stlport/stlport/ \
>
>  LOCAL_SRC_FILES += \
>         powerdebug.c sensor.c clocks.c regulator.c \
> -       display.c tree.c utils.c mainloop.c gpio.c
> +       display.c tree.c utils.c mainloop.c gpio.c pinctrl.c
>
>  include $(BUILD_EXECUTABLE)
> diff --git a/Makefile b/Makefile
> index 2da9d67..f002438 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -5,7 +5,7 @@ CFLAGS?=-O1 -g -Wall -Wshadow
>  CC?=gcc
>
>  OBJS = powerdebug.o sensor.o clocks.o regulator.o gpio.o \
> -       display.o tree.o utils.o mainloop.o
> +       display.o tree.o utils.o mainloop.o pinctrl.o
>
>  default: powerdebug
>
> diff --git a/README b/README
> index 1479db1..b24dd98 100644
> --- a/README
> +++ b/README
> @@ -1,8 +1,8 @@
>  powerdebug
>  ----------
>
> -This is a new tool which displays regulator, sensor and clock tree
> -information.
> +This is a new tool which displays regulator, sensor, clock tree, gpio and
> +pinctrl information.
>
>  Current version only displays regulator information and clock tree from
>  debugfs. Support will be added for sensors later.
> diff --git a/display.c b/display.c
> index 0000ee9..fb899c0 100644
> --- a/display.c
> +++ b/display.c
> @@ -63,7 +63,8 @@ struct windata windata[] = {
>         [CLOCK]     = { .name = "Clocks"     },
>         [REGULATOR] = { .name = "Regulators" },
>         [SENSOR]    = { .name = "Sensors"    },
> -       [GPIO]      = { .name = "Gpio"    },
> +       [GPIO]      = { .name = "Gpio"       },
> +       [PINCTRL]   = { .name = "Pins"       },
>  };
>
>  static void display_fini(void)
> diff --git a/display.h b/display.h
> index e3a1529..4496f30 100644
> --- a/display.h
> +++ b/display.h
> @@ -13,7 +13,7 @@
>   *       - initial API and implementation
>   
> *******************************************************************************/
>
> -enum { CLOCK, REGULATOR, SENSOR, GPIO };
> +enum { CLOCK, REGULATOR, SENSOR, GPIO, PINCTRL };
>
>  struct display_ops {
>         int (*display)(bool refresh);
> diff --git a/pinctrl.c b/pinctrl.c
> new file mode 100644
> index 0000000..eef06e2
> --- /dev/null
> +++ b/pinctrl.c
> @@ -0,0 +1,329 @@
> +
> +/*******************************************************************************
> + * Copyright (C) 2014, 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:
> + *     Mohammad Merajul Islam Molla <meraj.mo...@samsung.com>
> + *                                     (Samsung R&D Institute Bangladesh)
> + *             - initial API and implementation
> + 
> *******************************************************************************/
> +
> +#ifndef _GNU_SOURCE
> +#define _GNU_SOURCE
> +#include <stdio.h>
> +#undef _GNU_SOURCE
> +#endif
> +#include <string.h>
> +#include <stdbool.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <dirent.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
> +
> +#include "pinctrl.h"
> +#include "display.h"
> +
> +#define SIZE 64
> +#define MAX_PINS 256
> +
> +#define PIN_fmt         "%*[^ ] %d"
> +#define NAME_fmt       "%*[^(]( %s"
> +#define MUX_fmt                "%*[^:]: %s"
> +#define GPIO_fmt       "%*[^:]: %*[^ ] %s"
> +#define GPIO_fmt1      "%*[^:]: %*[^ ] %*[^ ] %s"
> +
> +#define SYS_PINCTRL "/sys/kernel/debug/pinctrl"
> +
> +static bool pinctrl_error = false;
> +
> +static struct pintcrl_info {
> +       int pin;
> +       char name[SIZE];
> +       char mux_owner[SIZE];
> +       char gpio_owner[SIZE];
> +       char hog[SIZE];
> +       char function[SIZE];
> +       char group[SIZE];
> +} pins_info[MAX_PINS];
> +
> +static int fill_pinctrl_info();
> +
> +static int pinctrl_print_header(void)
> +{
> +       char *buf;
> +       int ret;
> +
> +       if (asprintf(&buf, "%-5s %-10s %-15s %-15s %-5s %-20s %-20s",
> +                    "Pin", "Name", "MUX Owner", "GPIO Owner", "HOG",
> "Function",
> +                    "Group") < 0)
> +               return -1;
> +
> +       ret = display_column_name(buf);
> +
> +       free(buf);
> +
> +       return ret;
> +}
> +
> +static char *pin_line(int pin)
> +{
> +       char *pinline = 0;
> +
> +       if (asprintf(&pinline,"%-5d %-10s %-15s %-15s %-5s %-20s %-20s",
> +               pins_info[pin].pin, pins_info[pin].name,
> +               pins_info[pin].mux_owner, pins_info[pin].gpio_owner,
> +               pins_info[pin].hog, pins_info[pin].function,
> +               pins_info[pin].group) < 0)
> +               return NULL;
> +
> +       return pinline;
> +}
> +
> +static int pinctrl_print_info()
> +{
> +       int i;
> +       int line = 0;
> +       char *buffer;
> +
> +       display_reset_cursor(PINCTRL);
> +
> +       pinctrl_print_header();
> +
> +       for (i = 0; i < MAX_PINS; i++) {
> +               if (pins_info[i].pin == -1)
> +                       continue;
> +
> +               buffer = pin_line(i);
> +               if (!buffer)
> +                       return -1;
> +
> +               display_print_line(PINCTRL, line, buffer, 0, NULL);
> +               line++;
> +
> +               free(buffer);
> +       }
> +
> +       display_refresh_pad(PINCTRL);
> +
> +       return 0;
> +}
> +
> +static int dump_pinctrl_info()
> +{
> +       int i;
> +
> +       for (i = 0; i < MAX_PINS; i++) {
> +               if (pins_info[i].pin == -1)
> +                       continue;
> +               printf("\tPin %d: (Name: %s, MUX_owner: %s,
> GPIO_owner: %s, HOG: %s, Function: %s, Group: %s)\n",
> +                       pins_info[i].pin, pins_info[i].name,
> +                       pins_info[i].mux_owner, pins_info[i].gpio_owner,
> +                       pins_info[i].hog,
> +                       pins_info[i].function, pins_info[i].group);
> +       }
> +
> +       return 0;
> +}
> +
> +
> +int pinctrl_dump()
> +{
> +       int ret;
> +
> +       if (pinctrl_error)
> +               return -1;
> +
> +       printf("\nPin Information:\n");
> +       printf("****************\n");
> +       ret = dump_pinctrl_info();
> +       printf("\n\n");
> +
> +       return ret;
> +
> +}
> +
> +static int pinctrl_display(bool refresh)
> +{
> +       if (pinctrl_error) {
> +               display_message(PINCTRL,
> +                       "error: path " SYS_PINCTRL " not found or not root");
> +               return -2;
> +       }
> +
> +       if (refresh && fill_pinctrl_info())
> +               return -1;
> +
> +       return pinctrl_print_info();
> +}
> +
> +static struct display_ops pinctrl_ops = {
> +       .display = pinctrl_display,
> +};
> +
> +static int read_pin_info(const char *path)
> +{
> +       FILE *fpinmux;
> +       int pin;
> +       int ret = 0;
> +       char *p;
> +       char buf[4096];
> +
> +       fpinmux = fopen(path, "r");
> +       if (!fpinmux) {
> +               printf("error: failed to read %s\n", path);
> +               return -1;
> +       }
> +
> +       /* first two lines are headers, ignore */
> +       fgets(buf, 4096, fpinmux);
> +       fgets(buf, 4096, fpinmux);
> +
> +       while (fgets(buf, 4096, fpinmux)) {
> +               int mux_owner = 0;
> +
> +               /* get pin number */
> +               sscanf(buf, PIN_fmt, &pin);
> +
> +               if (pin >= MAX_PINS) {
> +                       printf("WARNING: # of pins > max pins (256),
> need to increase limit\n");
> +                       continue;
> +               }
> +
> +               pins_info[pin].pin = pin;
> +               sscanf(buf, NAME_fmt, pins_info[pin].name);
> +               pins_info[pin].name[strlen(pins_info[pin].name) - 2] = '\0';
> +
> +               if (strstr(buf, "MUX UNCLAIMED"))
> +                       strcpy(pins_info[pin].mux_owner, "MUX UNCLAIMED");
> +               else {
> +                       sscanf(buf, MUX_fmt, pins_info[pin].mux_owner);
> +                       mux_owner = 1;
> +               }
> +
> +               if (strstr(buf, "GPIO UNCLAIMED"))
> +                       strcpy(pins_info[pin].gpio_owner, "GPIO UNCLAIMED");
> +               else {
> +                       if (mux_owner)
> +                               sscanf(buf, GPIO_fmt,
> pins_info[pin].gpio_owner);
> +                       else
> +                               sscanf(buf, GPIO_fmt1,
> pins_info[pin].gpio_owner);
> +               }
> +
> +               if (strstr(buf, "HOG"))
> +                       strcpy(pins_info[pin].hog, "HOG");
> +               else
> +                       strcpy(pins_info[pin].hog, "");
> +
> +               if ((p = strstr(buf, "function"))) {
> +                       p += 9;
> +                       sscanf(p, "%s", pins_info[pin].function);
> +               }
> +               else
> +                       strcpy(pins_info[pin].function, "");
> +
> +               if ((p = strstr(buf, "group"))) {
> +                       p += 5;
> +                       sscanf(p, "%s", pins_info[pin].group);
> +               }
> +               else
> +                       strcpy(pins_info[pin].group, "");
> +       }
> +
> +       fclose(fpinmux);
> +       return ret;
> +}
> +
> +static void init_pins_info()
> +{
> +       int i;
> +
> +       memset(pins_info, 0, sizeof(pins_info));
> +
> +       for (i = 0; i < MAX_PINS; i++)
> +               pins_info[i].pin = -1;
> +}
> +
> +static int fill_pinctrl_info()
> +{
> +       DIR *dir;
> +       char *newpath, *pinmux_path;
> +       struct dirent dirent, *direntp;
> +       struct stat s;
> +       int ret = 0;
> +
> +       dir = opendir(SYS_PINCTRL);
> +       if (!dir) {
> +               printf("error: unable to open directory " SYS_PINCTRL);
> +               ret = -1;
> +               goto out;
> +       }
> +
> +       init_pins_info();
> +
> +       while (!readdir_r(dir, &dirent, &direntp)) {
> +               ret = 0;
> +
> +               if (!direntp)
> +                       break;
> +
> +               if (direntp->d_name[0] == '.')
> +                       continue;
> +
> +               ret = asprintf(&newpath, "%s/%s", SYS_PINCTRL, 
> direntp->d_name);
> +               if (ret < 0)
> +                       goto out;
> +
> +               ret = stat(newpath, &s);
> +               if (ret)
> +                       goto out_free_newpath;
> +
> +               if (S_ISDIR(s.st_mode)) {
> +                       ret = asprintf(&pinmux_path, "%s/%s", newpath,
> +                                       "pinmux-pins");
> +                       if (ret < 0)
> +                               goto out_free_newpath;
> +
> +                       if (read_pin_info(pinmux_path)) {
> +                               ret = -1;
> +                               goto out_free_pinmux;
> +                       }
> +               }
> +       }
> +
> +out_free_pinmux:
> +       free(pinmux_path);
> +
> +out_free_newpath:
> +       free(newpath);
> +
> +out:
> +       closedir(dir);
> +       return ret;
> +}
> +
> +int pinctrl_init(void)
> +{
> +       int ret = 0;
> +
> +       ret = display_register(PINCTRL, &pinctrl_ops);
> +       if (ret)
> +               printf("error: pinctrl display register failed");
> +
> +       if (access(SYS_PINCTRL, F_OK)) {
> +               pinctrl_error = true;
> +               return -1;
> +       }
> +
> +       if (fill_pinctrl_info())
> +               return -1;
> +
> +       return ret;
> +}
> diff --git a/pinctrl.h b/pinctrl.h
> new file mode 100644
> index 0000000..2fa4f3a
> --- /dev/null
> +++ b/pinctrl.h
> @@ -0,0 +1,19 @@
> +/*******************************************************************************
> + * Copyright (C) 2014, 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:
> + *     Mohammad merajul Islam Molla <meraj.mo...@samsung.com>
> + *                                     (Samsung R&D Institute Bangladesh)
> + *
> + *       - initial API and implementation
> + 
> *******************************************************************************/
> +
> +extern int pinctrl_init(void);
> +extern int pinctrl_dump(void);
> diff --git a/powerdebug.c b/powerdebug.c
> index 6cf3a1b..b4f4833 100644
> --- a/powerdebug.c
> +++ b/powerdebug.c
> @@ -26,6 +26,7 @@
>  #include "clocks.h"
>  #include "sensor.h"
>  #include "gpio.h"
> +#include "pinctrl.h"
>  #include "mainloop.h"
>  #include "powerdebug.h"
>
> @@ -35,13 +36,14 @@ void usage(void)
>  {
>         printf("Usage: powerdebug [OPTIONS]\n");
>         printf("\n");
> -       printf("powerdebug -d [ -r ] [ -s ] [ -c [ -p <clock-name> ] ] "
> +       printf("powerdebug -d [ -r ] [ -s ] [ -p ][ -c [ -P <clock-name> ] ] "
>                 "[ -v ]\n");
> -       printf("powerdebug [ -r | -s | -c ]\n");
> +       printf("powerdebug [ -r | -s | -c | -p] \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"
> +       printf("  -p, --pin             Show pin 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");
> @@ -62,7 +64,8 @@ void version()
>   * -s, --sensor                : sensors
>   * -c, --clock         : clocks
>   * -g, --gpio           : gpios
> - * -p, --findparents    : clockname whose parents have to be found
> + * -p, --pin           : pins
> + * -P, --findparents    : clockname whose parents have to be found
>   * -t, --time          : ticktime
>   * -d, --dump          : dump
>   * -v, --verbose       : verbose
> @@ -76,7 +79,8 @@ static struct option long_options[] = {
>         { "sensor", 0, 0, 's' },
>         { "clock",  0, 0, 'c' },
>         { "gpio",  0, 0, 'g' },
> -       { "findparents", 1, 0, 'p' },
> +       { "pin", 0 , 0, 'p' },
> +       { "findparents", 1, 0, 'P' },
>         { "time", 1, 0, 't' },
>         { "dump", 0, 0, 'd' },
>         { "verbose", 0, 0, 'v' },
> @@ -91,6 +95,7 @@ struct powerdebug_options {
>         bool sensors;
>         bool clocks;
>         bool gpios;
> +       bool pins;
>         bool dump;
>         unsigned int ticktime;
>         int selectedwindow;
> @@ -108,7 +113,7 @@ int getoptions(int argc, char *argv[], struct
> powerdebug_options *options)
>         while (1) {
>                 int optindex = 0;
>
> -               c = getopt_long(argc, argv, "rscgp:t:dvVh",
> +               c = getopt_long(argc, argv, "rscgpP:t:dvVh",
>                                 long_options, &optindex);
>                 if (c == -1)
>                         break;
> @@ -131,6 +136,10 @@ int getoptions(int argc, char *argv[], struct
> powerdebug_options *options)
>                         options->selectedwindow = GPIO;
>                         break;
>                 case 'p':
> +                       options->pins = true;
> +                       options->selectedwindow = PINCTRL;
> +                       break;
> +               case 'P':
>                         options->clkname = strdup(optarg);
>                         if (!options->clkname) {
>                                 fprintf(stderr, "failed to allocate memory");
> @@ -161,9 +170,9 @@ 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->gpios)
> -               options->regulators = options->clocks =
> -                       options->sensors = options->gpios = true;
> +           !options->sensors && !options->gpios && !options->pins)
> +               options->regulators = options->clocks = options->sensors =
> +                       options->gpios = options->pins = true;
>
>         if (options->selectedwindow == -1)
>                 options->selectedwindow = CLOCK;
> @@ -185,6 +194,9 @@ static int powerdebug_dump(struct
> powerdebug_options *options)
>         if (options->gpios)
>                 gpio_dump();
>
> +       if (options->pins)
> +               pinctrl_dump();
> +
>         return 0;
>  }
>
> @@ -266,6 +278,11 @@ int main(int argc, char **argv)
>                 options->gpios = false;
>         }
>
> +       if (pinctrl_init()) {
> +               printf("failed to initialize pinctrl\n");
> +               options->pins = false;
> +       }
> +
>         ret = options->dump ? powerdebug_dump(options) :
>                 powerdebug_display(options);
>
>
>
> --
> Thanks,
> -Meraj

_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to