New powerdebug tool
This is a new tool to show some of the information which powertop doesn't - like, information for sensor, regulator etc.
diff --git a/powerdebug.c b/powerdebug.c
new file mode 100644
index 0000000..dcf1a59
--- /dev/null
+++ b/powerdebug.c
@@ -0,0 +1,255 @@
+#include <getopt.h>
+
+#include "powerdebug.h"
+
+
+int numregulators;
+
+int init_regulator_ds(void)
+{
+ DIR *regdir;
+ struct dirent *item;
+
+ regdir = opendir("/sys/class/regulator");
+ if (!regdir)
+ return(1);
+ while((item = readdir(regdir))) {
+ if (strncmp(item->d_name, "regulator", 9))
+ continue;
+
+ numregulators++;
+ }
+ closedir(regdir);
+
+ regulators_info = (struct regulator_info *)malloc(numregulators*
+ sizeof(struct regulator_info));
+ if (!regulators_info) {
+ fprintf(stderr, "init_regulator_ds: Not enough memory to read information for %d regulators!\n",
+ numregulators);
+ return(1);
+ }
+
+ return(0);
+}
+
+int read_and_print_sensor_info(int verbose)
+{
+ DIR *dir, *subdir;
+ int len;
+ char filename[PATH_MAX], devpath[PATH_MAX];
+ char device[PATH_MAX];
+ struct dirent *item, *subitem;
+
+/*
+ 1. readdir /sys/class/hwmon
+ 2. foreach subdir in above, do following
+ a) check if its virtual or physical (check for device)
+ b) for each *type* (in, temp, pwm, fan, curr, power, energy)
+ i> search for "_" (strrchr... check for last)
+ ii> check the *item* depending on type
+ i.e for "in" type items=min, max, input, label
+ for "fan" type items=min,max,input,div,target,label
+ for "pwm" type items=enable, mode, freq
+ for "temp" type items=type, max, min,input,crit,offset,label,lowest,highest,
+ for "curr" type items=max,min,input
+ for "power" type items=average,average_interval,average_min/max, average_highest/lowest, input, input_highest/lowest, accuracy,alarm, cap, cap_min/max
+ for "energy" type items=input
+ for "intrusion" type items=alarm,beep
+*/
+
+ sprintf(filename, "%s", "/sys/class/hwmon");
+
+ dir = opendir(filename);
+ if (!dir)
+ return errno;
+
+ while ((item = readdir(dir))) {
+ if (item->d_name[0] == '.') /* skip the hidden files */
+ continue;
+
+ sprintf(filename, "/sys/class/hwmon/%s", item->d_name);
+ sprintf(devpath, "%s/device", filename);
+
+ len = readlink(devpath, device, PATH_MAX - 1);
+
+ if (len < 0)
+ strcpy(devpath, filename);
+ else
+ device[len] = '\0';
+
+ subdir = opendir(devpath);
+
+ printf("\nSensor Information for %s :\n", item->d_name);
+ fflush(stdin);
+ while ((subitem = readdir(subdir))) {
+ if (subitem->d_name[0] == '.') /* skip hidden files */
+ continue;
+
+ if(!strncmp(subitem->d_name, "in", 2))
+ get_sensor_info(devpath, subitem->d_name, "in",
+ verbose);
+ else if (!strncmp(subitem->d_name, "temp", 4))
+ get_sensor_info(devpath, subitem->d_name,
+ "temp", verbose);
+ else if (!strncmp(subitem->d_name, "fan", 4))
+ get_sensor_info(devpath, subitem->d_name,
+ "fan", verbose);
+ else if (!strncmp(subitem->d_name, "pwm", 4))
+ get_sensor_info(devpath, subitem->d_name,
+ "pwm", verbose);
+
+ }
+
+ closedir(subdir);
+ }
+ closedir(dir);
+
+ return 0;
+}
+
+
+int read_regulator_info(int verbose)
+{
+ FILE *file = NULL;
+ DIR *regdir, *dir;
+ int len, count = 0, ret = 0;
+ char line[1024], filename[1024], *fptr;
+ struct dirent *item, *ritem;
+
+ regdir = opendir("/sys/class/regulator");
+ if (!regdir)
+ return(1);
+ while((item = readdir(regdir))) {
+ if (strlen(item->d_name) < 3)
+ continue;
+
+ if (strncmp(item->d_name, "regulator", 9))
+ continue;
+
+ len = sprintf(filename, "/sys/class/regulator/%s",item->d_name);
+
+ dir = opendir(filename);
+ if (!dir) {
+ ret = 1;
+ goto exit2;
+ }
+
+ count++;
+ if (count > numregulators) {
+ ret = 1;
+ goto exit1;
+ }
+
+ while((ritem = readdir(dir))) {
+ strcpy(regulators_info[count-1].name, item->d_name);
+ if (strlen(ritem->d_name) < 3)
+ continue;
+
+ sprintf(filename + len, "/%s", ritem->d_name);
+ // printf("Inside %s directory. Opening file %s!\n", item->d_name, ritem->d_name);
+
+ file = fopen(filename, "r");
+ if (!file)
+ continue;
+
+ memset(line, 0, 1024);
+ fptr = fgets(line, 1024, file);
+ fclose(file);
+ if (!fptr) {
+ ret = 1;
+ goto exit1;
+ }
+ // printf("Read file %s, data=%s, count = %d\n", filename, fptr, count);
+
+ if (!strcmp(ritem->d_name, "name"))
+ strcpy(regulators_info[count-1].name, fptr);
+ if (!strcmp(ritem->d_name, "state"))
+ strcpy(regulators_info[count-1].state, fptr);
+ if (!strcmp(ritem->d_name, "status"))
+ strcpy(regulators_info[count-1].status, fptr);
+
+ /* Read following _only_ if verbose option specified */
+ if(!verbose)
+ continue;
+
+ if (!strcmp(ritem->d_name, "type"))
+ strcpy(regulators_info[count-1].type, fptr);
+ if (!strcmp(ritem->d_name, "opmode"))
+ strcpy(regulators_info[count-1].opmode, fptr);
+
+ if (!strcmp(ritem->d_name, "microvolts"))
+ regulators_info[count-1].microvolts = atoi(fptr);
+ if (!strcmp(ritem->d_name, "microamps"))
+ regulators_info[count-1].microamps = atoi(fptr);
+ if (!strcmp(ritem->d_name, "num_users"))
+ regulators_info[count-1].num_users = atoi(fptr);
+
+ }
+exit1:
+ closedir(dir);
+ if (ret)
+ break;
+ }
+exit2:
+ closedir(regdir);
+
+ return ret;
+}
+
+
+int main(int argc, char **argv)
+{
+ int c;
+ int regulators = 0, sensors = 0, verbose = 0;
+
+ /* Options:
+ * -r : regulator
+ * -s : sensors
+ * -v : verbose
+ * no option / default : all
+ */
+
+ while ((c = getopt (argc, argv, "rsvh")) != -1)
+ switch (c)
+ {
+ case 'r':
+ regulators = 1;
+ break;
+ case 's':
+ sensors = 1;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'h':
+ usage (argv);
+ case '?':
+ fprintf (stderr, "Unknown option %c'.\n", optopt);
+ return 1;
+ default:
+ usage(argv);
+ }
+
+ /* By default print both regulator and sensor information */
+ if (!regulators && !sensors) {
+ /* What should be the default behavior ?
+ regulators = 1;
+ sensors = 1;
+ */
+ usage(argv);
+ }
+
+ init_regulator_ds();
+
+ if (regulators) {
+ read_regulator_info(verbose);
+ print_regulator_info(verbose);
+ }
+
+ if (sensors) {
+ read_and_print_sensor_info(verbose);
+ }
+
+ return 0;
+
+}