Send commitlog mailing list submissions to
        commitlog@lists.openmoko.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://lists.openmoko.org/mailman/listinfo/commitlog
or, via email, send a message with subject or body 'help' to
        [EMAIL PROTECTED]

You can reach the person managing the list at
        [EMAIL PROTECTED]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of commitlog digest..."
Today's Topics:

   1. r4502 - in developers/werner: . greg greg/tests
      ([EMAIL PROTECTED])
--- Begin Message ---
Author: werner
Date: 2008-06-26 07:01:10 +0200 (Thu, 26 Jun 2008)
New Revision: 4502

Added:
   developers/werner/greg/
   developers/werner/greg/Makefile
   developers/werner/greg/README
   developers/werner/greg/cpp.c
   developers/werner/greg/cpp.h
   developers/werner/greg/dr.pl
   developers/werner/greg/greg.c
   developers/werner/greg/greg.h
   developers/werner/greg/lang.l
   developers/werner/greg/lang.y
   developers/werner/greg/pcf50633.greg
   developers/werner/greg/reg.h
   developers/werner/greg/tests/
   developers/werner/greg/tests/Common
   developers/werner/greg/tests/Makefile
   developers/werner/greg/tests/field
   developers/werner/greg/tests/reg
   developers/werner/greg/tests/value
   developers/werner/greg/tests/width
Log:
greg is a processor for register definitions. It can be used to pretty-print
register dumps. Work in progress.



Added: developers/werner/greg/Makefile
===================================================================
--- developers/werner/greg/Makefile                             (rev 0)
+++ developers/werner/greg/Makefile     2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,52 @@
+CFLAGS_WARN=-Wall -Wshadow -Wstrict-prototypes -Wmissing-prototypes \
+           -Wmissing-declarations
+CFLAGS=-g -DCPP='"cpp"' $(CFLAGS_WARN)
+SLOPPY=-Wno-unused -Wno-implicit-function-declaration -Wno-missing-prototypes \
+       -Wno-missing-declarations
+LDLIBS=-lfl
+
+OBJS=greg.o lex.yy.o y.tab.o cpp.o
+
+.PHONY:                all dep depend clean spotless test tests
+
+# ----- Build -----------------------------------------------------------------
+
+all:           greg
+
+greg:          $(OBJS)
+
+lex.yy.c:      lang.l y.tab.h
+               $(LEX) lang.l
+
+lex.yy.o:      lex.yy.c y.tab.h
+               $(CC) -c $(CFLAGS) $(SLOPPY) lex.yy.c
+
+y.tab.c y.tab.h: lang.y
+               $(YACC) $(YYFLAGS) -d lang.y
+
+y.tab.o:       y.tab.c
+               $(CC) -c $(CFLAGS) $(SLOPPY) y.tab.c
+
+# ----- Dependencies ----------------------------------------------------------
+
+dep depend .depend: lex.yy.c y.tab.h y.tab.c
+               $(CPP) $(CFLAGS) -MM -MG *.c >.depend || \
+                 { rm -f .depend; exit 1; }
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
+# ----- Cleanup ---------------------------------------------------------------
+
+clean:
+               rm -f lex.yy.c y.tab.h y.tab.c
+               rm -f $(OBJS) .depend
+
+spotless:      clean
+               rm -f greg
+
+# ----- Tests -----------------------------------------------------------------
+
+test tests:    greg
+               $(MAKE) -C tests

Added: developers/werner/greg/README
===================================================================
--- developers/werner/greg/README                               (rev 0)
+++ developers/werner/greg/README       2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,109 @@
+"greg" reads a general register description and can then produce output based
+on this description, or answer queries.
+
+Example: it can pretty-print a register dump.
+
+./greg pcf50633.greg reg_id reg_value ...
+
+Where reg_id is the identifier of the register, e.g., "13" for GPIOCTL,
+and reg_value is the value of that register. Note that reg_id is a
+case-sensitive string, while reg_value is a number in the usual C
+syntax.
+
+
+Known issues
+------------
+
+- output format should be easier to read
+- value names in pcf50633.greg are often unsuitable for identifier generation
+  (should align them properly with what we use in u-boot and kernel)
+- "pretty-print" is hard to read
+- unique() should use rb-trees
+- greg.c should use unique(), to accelerate lookups
+
+
+dr.pl
+-----
+
+dr.pl is a wrapper for "greg". It processes dumps like the one produced by
+the following function (in u-boot):
+
+
+static void dump_pmu(void)
+{
+       int i, j;
+
+       for (i = 0; i != 0x70; i += 16) {
+               printf("%02x:", i);
+               for (j = 0; j != 16; j++)
+                       printf(" %02x", pcf50633_reg_read(i+j));
+               printf("\n");
+       }
+}
+
+
+Example register dump (with titles):
+
+
+in LED loop, with battery.
+
+00: 13 84 00 00 00 00 00 00 f0 40 00 00 00 d3 aa 4a
+10: 15 44 ff 01 00 00 00 00 02 08 6b 01 00 0a 1b 02
+20: 00 22 2f 01 00 22 00 00 2f 00 05 20 11 18 00 18
+30: 00 00 00 00 00 15 00 15 00 18 00 00 00 ff 3f 00
+40: 00 07 00 00 28 19 ff ff 00 01 10 33 20 50 19 00
+50: 00 08 00 00 00 0b 00 f0 00 13 14 17 04 19 05 08
+60: 7f 7f 3f 07 3f 1f ff 00 00 00 00 00 00 00 00 00
+
+in LED loop, no battery. (LED on)
+
+00: 13 84 00 00 00 00 00 00 f0 40 00 00 00 d3 aa 4a
+10: 15 44 bf 01 00 00 00 00 03 08 6b 01 00 0a 1b 02
+20: 00 22 2f 01 00 22 00 00 2f 00 05 20 11 18 00 18
+30: 00 00 00 00 00 15 00 15 00 18 00 00 00 ff 3f 00
+40: 00 07 00 00 28 19 ff ff 00 01 10 33 20 d0 19 00
+50: 00 08 00 00 00 0b 00 f0 00 41 14 17 04 19 05 08
+60: 7f 7f 3f 07 3f 1f ff 00 00 00 00 00 00 00 00 00
+
+
+If these two dumps are sent to the standard input of dr.pl, it will
+output the difference between them:
+
+
+----- in LED loop, no battery. (LED on) ---------------------------------------
+--- _a  2008-06-26 01:52:33.000000000 -0300
++++ _b  2008-06-26 01:52:33.000000000 -0300
+@@ -1,11 +1,11 @@
+-18 BVMCTL = 0x02 -- BVM control
++18 BVMCTL = 0x03 -- BVM control
+     bvmlow -- BAT voltage is lower than Vth(batok)
+-       0 (0x0)
++       1 (0x1)
+     bvmlvl -- Vth(batok)
+        001 (0x1): 2_80V
+     bvmdisdb -- 62ms debounce filter
+        0 (0x0): enabled
+-4d MBCS3 = 0x50 -- MBC charger status 3
++4d MBCS3 = 0xd0 -- MBC charger status 3
+     usblim_play -- USB current limiting in USB-to-SYS path
+        0 (0x0)
+     usblim_chg -- USB current limiting in USB-to-BAT path
+@@ -21,7 +21,7 @@
+     vbatstat -- battery voltage > Vbatcond
+        1 (0x1)
+     vres -- battery voltage > Vth(RES)
+-       0 (0x0)
+-59 RTCSC = 0x13 -- RTC second value
++       1 (0x1)
++59 RTCSC = 0x41 -- RTC second value
+     sec -- current seconds, BCD
+-       001.0011 (0x13)
++       100.0001 (0x41)
+
+
+If more than two dumps are input to dr.pl, it will produce the
+difference between the first and the second, then the second and
+the third, and so on.
+
+If only one dump is input to dr.pl, it will pretty-print all
+registers.

Added: developers/werner/greg/cpp.c
===================================================================
--- developers/werner/greg/cpp.c                                (rev 0)
+++ developers/werner/greg/cpp.c        2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,214 @@
+/*
+ * cpp.c - CPP subprocess
+ *
+ * Written 2002-2004, 2006, 2008 by Werner Almesberger
+ * Copyright 2002,2003 California Institute of Technology
+ * Copyright 2004, 2006 Werner Almesberger
+ * Copyright 2008 by OpenMoko, Inc.
+ *
+ * Distributed under GPLv2, or any later version.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "cpp.h"
+
+
+const char *cpp_command = CPP;
+
+static pid_t cpp_pid;
+static int cpp_argc = 0;
+static const char **cpp_argv = NULL;
+static int real_stdin = -1;
+
+
+void add_cpp_arg(const char *arg)
+{
+    if (!cpp_argc)
+       cpp_argc = 1;
+    cpp_argv = realloc(cpp_argv,sizeof(const char *)*(cpp_argc+1));
+    if (!cpp_argv) {
+       perror("realloc");
+       exit(1);
+    }
+    if (cpp_argc == 1)
+       cpp_argv[0] = cpp_command;
+    if (arg) {
+       arg = strdup(arg);
+       if (!arg) {
+           perror("strdup");
+           exit(1);
+       }
+    }
+    cpp_argv[cpp_argc++] = arg;
+}
+
+
+void add_cpp_Wp(const char *arg)
+{
+    char *tmp = strdup(arg);
+    char *curr,*end;
+
+    if (!tmp) {
+       perror("strdup");
+       exit(1);
+    }
+    curr = tmp;
+    do {
+       end = strchr(curr,',');
+       if (end)
+           *end++ = 0;
+       add_cpp_arg(curr);
+       curr = end;
+    }
+    while (end);
+    free(tmp);
+}
+
+
+static void kill_cpp(void)
+{
+    if (cpp_pid)
+       (void) kill(cpp_pid,SIGTERM);
+}
+
+
+static void run_cpp(const char *name,int fd,int close_fd)
+{
+    char **arg;
+    int fds[2];
+
+    if (pipe(fds) < 0) {
+        perror("pipe");
+        exit(1);
+    }
+    if (name)
+       add_cpp_arg(name);
+    add_cpp_arg(NULL);
+    cpp_pid = fork();
+    if (cpp_pid < 0) {
+        perror("fork");
+        exit(1);
+    }
+    if (!cpp_pid) {
+       if (close(fds[0]) < 0) {
+           perror("close");
+           exit(1);
+       }
+       if (close_fd != -1 && close(close_fd) < 0) {
+           perror("close");
+           exit(1);
+       }
+       if (fd != -1 && dup2(fd,0) < 0) {
+           perror("dup2");
+           exit(1);
+       }
+       if (dup2(fds[1],1) < 0) {
+           perror("dup2");
+           exit(1);
+       }
+       if (execvp(cpp_command,(char **) cpp_argv) < 0) {
+         /* prototype is weird */
+           perror(cpp_command);
+           exit(1);
+       }
+       /* not reached */
+    }
+    if (close(fds[1]) < 0) {
+       perror("close");
+       exit(1);
+    }
+    real_stdin = dup(0);
+    if (real_stdin < 0) {
+       perror("dup");
+       exit(1);
+    }
+    if (fd != -1 && close(fd) < 0) {
+       perror("close");
+       exit(1);
+    }
+    if (dup2(fds[0],0) < 0) {
+       perror("dup2");
+       exit(1);
+    }
+    for (arg = (char **) cpp_argv+1; *arg; arg++)
+       free(*arg);
+    free(cpp_argv);
+    cpp_argv = NULL;
+    cpp_argc = 0;
+}
+
+
+void run_cpp_on_file(const char *name)
+{
+    run_cpp(name,name ? -1 : 0,-1);
+    atexit(kill_cpp);
+}
+
+
+void run_cpp_on_string(const char *str)
+{
+    int fds[2];
+    pid_t pid;
+    int left,wrote;
+
+    if (pipe(fds) < 0) {
+        perror("pipe");
+        exit(1);
+    }
+    run_cpp(NULL,fds[0],fds[1]);
+    pid = fork();
+    if (pid < 0) {
+       perror("fork");
+       exit(1);
+    }
+    if (!pid) {
+       for (left = strlen(str); left; left -= wrote) {
+           wrote = write(fds[1],str,left);
+           if (wrote < 0)
+               break; /* die silently */
+           str += wrote;
+       }
+       exit(0);
+    }
+    if (close(fds[1]) < 0) {
+       perror("close");
+       exit(1);
+    }
+    atexit(kill_cpp);
+}
+
+
+void reap_cpp(void)
+{
+    int status;
+
+    cpp_pid = 0;
+    if (waitpid(cpp_pid,&status,0) < 0) {
+       perror("waitpid");
+       exit(1);
+    }
+    if (!status) {
+       if (dup2(real_stdin,0) < 0) {
+           perror("dup2");
+           exit(1);
+       }
+       return;
+    }
+    if (WIFEXITED(status))
+       exit(WEXITSTATUS(status));
+    if (WIFSIGNALED(status))
+       fprintf(stderr,"cpp terminated with signal %d\n",WTERMSIG(status));
+    else
+       fprintf(stderr,"cpp terminated with incomprehensible status %d\n",
+         status);
+    exit(1);
+}

Added: developers/werner/greg/cpp.h
===================================================================
--- developers/werner/greg/cpp.h                                (rev 0)
+++ developers/werner/greg/cpp.h        2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,24 @@
+/*
+ * cpp.h - CPP subprocess
+ *
+ * Written 2002,2003,2008 by Werner Almesberger
+ * Copyright 2002,2003 Caltech Netlab FAST project
+ * Copyright 2008 by OpenMoko, Inc.
+ *
+ * Distributed under GPLv2, or any later version.
+ *
+ */
+
+#ifndef CPP_H
+#define CPP_H
+
+
+extern const char *cpp_command;
+
+void add_cpp_arg(const char *arg);
+void add_cpp_Wp(const char *arg);
+void run_cpp_on_file(const char *name); /* NULL for stdin */
+void run_cpp_on_string(const char *str);
+void reap_cpp(void);
+
+#endif /* CPP_H */

Added: developers/werner/greg/dr.pl
===================================================================
--- developers/werner/greg/dr.pl                                (rev 0)
+++ developers/werner/greg/dr.pl        2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,50 @@
+#!/usr/bin/perl
+
+$run = 0;
+
+
+sub flush
+{
+    local ($single) = @_;
+    if (++$run > 2) {
+       undef @a;
+       undef @b;
+       for ($i = 0; $i != 0x70; $i++) {
+           next if $i == 0x2c || $i == 0x51 || $i == 0x58 || $i == 0x6f;
+           if ($l[$i] != $v[$i]) {
+               push(@a, sprintf("%02x", $i), "0x".$l[$i]);
+               push(@b, sprintf("%02x", $i), "0x".$v[$i]);
+           }
+       }
+       print "----- ".$title." ".("-" x (72-length $title))."\n";
+       if ($single) {
+           system("./greg pcf50633.greg ".join(" ", @a));
+       } else {
+           system("./greg pcf50633.greg >_a ".join(" ", @a));
+           system("./greg pcf50633.greg >_b ".join(" ", @b));
+           system("diff -u _a _b");
+       }
+    }
+    @l = @v;
+    undef @v;
+}
+
+
+while (<>) {
+    chop;
+    next if /^\s*$/;
+    &flush(0) if /^00:/;
+    if (!/^..:/) {
+       $title = $_;
+       next;
+    }
+    @r = split " ";
+    $b = hex shift @r;
+    for ($i = 0; $i != 16; $i++) {
+       die unless defined $r[$i];
+       $v[$b+$i] = $r[$i];
+    }
+}
+&flush(0);
+
+&flush(1) if $run == 2;


Property changes on: developers/werner/greg/dr.pl
___________________________________________________________________
Name: svn:executable
   + *

Added: developers/werner/greg/greg.c
===================================================================
--- developers/werner/greg/greg.c                               (rev 0)
+++ developers/werner/greg/greg.c       2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,123 @@
+/*
+ * greg.c - Generalized register processor
+ *
+ * Copyright (C) 2008 by OpenMoko, Inc.
+ * Written by Werner Almesberger <[EMAIL PROTECTED]>
+ * All Rights Reserved
+ *
+ * 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.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "reg.h"
+#include "cpp.h"
+#include "greg.h"
+
+
+static int show_reserved = 0;
+
+
+static const char *num_to_binary(unsigned long long num, int bits)
+{
+       static char buf[32+8+1];
+       char *p = buf;
+       int i;
+
+       for (i = bits-1; i >= 0; i--) {
+               *p++ = (num >> i) & 1 ? '1' : '0';
+               if (i && !(i & 3))
+                       *p++ = '.';
+       }
+       *p = 0;
+       return buf;
+}
+
+
+static void print_value(const struct value *v, unsigned long long n)
+{
+       switch (v->type) {
+       case vt_none:
+               break;
+       case vt_list:
+               printf(": %s",
+                   v->u.list[n].name ? v->u.list[n].name : "RESERVED");
+               if (v->u.list[n].comment)
+                       printf(" -- %s", v->u.list[n].comment);
+               break;
+       case vt_formula:
+               printf(": %d+%d*%llu = %llu", v->u.formula.b, v->u.formula.a, n,
+                    v->u.formula.b+(unsigned long long) v->u.formula.a*n);
+               if (v->u.formula.unit)
+                       printf(" %s", v->u.formula.unit);
+               break;
+       default:
+               abort();
+       }
+}
+
+
+static void print_field(const struct field *field, unsigned long long value)
+{
+       printf("    %s", field->name ? field->name : "(reserved)");
+       if (field->comment)
+               printf(" -- %s", field->comment);
+       putchar('\n');
+       printf("\t%s (0x%0*llx)", num_to_binary(value, field->bits),
+           (field->bits+3) >> 2, value);
+       print_value(&field->value, value);
+       putchar('\n');
+}
+
+
+static void print(const char *id, unsigned long long value)
+{
+       const struct reg *reg;
+       const struct field *field;
+
+       for (reg = regs; reg; reg = reg->next)
+               if (!strcmp(reg->id, id))
+                       break;
+       if (!reg) {
+               fprintf(stderr, "register \"%s\" not found\n", id);
+               exit(1);
+       }
+       printf("%s %s = 0x%0*llx",
+           reg->id, reg->name, (reg->bits+3) >> 2, value);
+       if (reg->comment)
+               printf(" -- %s", reg->comment);
+       putchar('\n');
+       for (field = reg->fields; field; field = field->next) {
+               if (field->name || show_reserved)
+                       print_field(field, value & ((1ULL << field->bits)-1));
+               value >>= field->bits;
+       }
+}
+
+
+static void usage(const char *name)
+{
+       fprintf(stderr, "usage: %s regdef-file [reg value ...]\n", name);
+       exit(1);
+}
+
+
+int main(int argc,char **argv)
+{
+       int i;
+
+       if (argc < 2 || (argc & 1))
+               usage(*argv);
+       run_cpp_on_file(argv[1]);
+       (void) yyparse();
+       for (i = 2; i != argc; i += 2)
+               print(argv[i], strtoull(argv[i+1], NULL, 0));
+       return 0;
+       
+}

Added: developers/werner/greg/greg.h
===================================================================
--- developers/werner/greg/greg.h                               (rev 0)
+++ developers/werner/greg/greg.h       2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,23 @@
+/*
+ * greg.h - Generalized register processor
+ *
+ * Copyright (C) 2008 by OpenMoko, Inc.
+ * Written by Werner Almesberger <[EMAIL PROTECTED]>
+ * All Rights Reserved
+ *
+ * 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.
+ */
+
+#ifndef GREG_H
+#define GREG_H
+
+int yyparse(void);
+
+void __attribute__((noreturn)) yyerrorf(const char *fmt,...)
+  __attribute__((format(printf,1,2)));
+void __attribute__((noreturn)) yyerror(const char *s);
+
+#endif /* !GREG_H */

Added: developers/werner/greg/lang.l
===================================================================
--- developers/werner/greg/lang.l                               (rev 0)
+++ developers/werner/greg/lang.l       2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,115 @@
+%{
+/*
+ * lang.l - Input language of the generalized register processor
+ *
+ * Copyright (C) 2008 by OpenMoko, Inc.
+ * Written by Werner Almesberger <[EMAIL PROTECTED]>
+ * All Rights Reserved
+ *
+ * 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.
+ */
+
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "y.tab.h"
+
+#include "greg.h"
+
+
+static int lineno = 1;
+static int col0 = 1; /* token starts in the first column */
+
+
+static char *unique(const char *s)
+{
+       static struct node {
+               char *s;
+               struct node *left, *right;
+       } *root = NULL;
+       struct node **n = &root;
+       int cmp;
+
+       while (*n) {
+               cmp = strcmp((*n)->s, s);
+               if (!cmp)
+                       return (*n)->s;
+               n = cmp < 0 ? &(*n)->left : &(*n)->right;
+       }
+       *n = malloc(sizeof(struct node));
+       if (!*n) {
+               perror("malloc");
+               exit(1);
+       }
+       (*n)->s = strdup(s);
+       if (!(*n)->s) {
+               perror("strdup");
+               exit(1);
+       }
+       (*n)->left = (*n)->right = NULL;
+       return (*n)->s;
+}
+
+%}
+
+%%
+
+"%"[0-9]+              { yylval.num = strtoul(yytext+1, NULL, 10);
+                         col0 = 0;
+                         return TOK_BITS; }
+
+_                      return '_';
+
+[A-Za-z0-9_]+          { int token = col0 ? TOK_REG : TOK_ID;
+                         col0 = 0;
+                         yylval.s = unique(yytext);
+                         return token; }
+
+\"[^\"\n\t]*\"         { yylval.s = strdup(yytext+1);
+                         if (!yylval.s) {
+                               perror("strdup");
+                               exit(1);
+                         }
+                         *strrchr(yylval.s,'"') = 0;
+                         return STRING; }
+
+[\t ]*                 col0 = 0;
+
+((;|"//")[^\n]*)?\n    { col0 = 1;
+                         lineno++; }
+
+^#\ [0-9]+\ \"[^"]*\"(\ [0-9]+)*\n {
+                         lineno = strtol(yytext+2, NULL, 0);
+                         col0 = 1; }
+
+
+.                      { col0 = 0;
+                         return *yytext; }
+
+
+%%
+
+
+void __attribute__((noreturn)) yyerrorf(const char *fmt,...)
+{
+       va_list ap;
+
+       //if (!isatty(fileno(yyin)))
+       fprintf(stderr,"%d: ", lineno);
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       fprintf(stderr, " near \"%s\"\n", yytext);
+       exit(1);
+}
+
+
+void __attribute__((noreturn)) yyerror(const char *s)
+{
+       yyerrorf("%s", s);
+}

Added: developers/werner/greg/lang.y
===================================================================
--- developers/werner/greg/lang.y                               (rev 0)
+++ developers/werner/greg/lang.y       2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,261 @@
+%{
+/*
+ * lang.y - Input language of the generalized register processor
+ *
+ * Copyright (C) 2008 by OpenMoko, Inc.
+ * Written by Werner Almesberger <[EMAIL PROTECTED]>
+ * All Rights Reserved
+ *
+ * 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.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "reg.h"
+#include "greg.h"
+
+
+struct reg *regs = NULL;
+
+static int bits = 8;   /* bits per register */
+static int bit;                /* current bit */
+
+static struct reg *reg; /* current register */
+static struct field *field; /* current field */
+static struct value_list *list; /* current value list slot */
+
+
+#define alloc_type(t)  ((t *) alloc(sizeof(t)))
+
+
+static void *alloc(size_t size)
+{
+       void *tmp = malloc(size);
+
+       if (tmp)
+               return tmp;
+       perror("malloc");
+       exit(1);
+}
+
+
+static int number(char *s)
+{
+       char *end;
+       int tmp;
+
+       tmp = strtol(s, &end, 0);
+       if (*end || tmp < 0)
+               yyerrorf("bad number \"%s\"", s);
+       return tmp;
+}
+
+
+static void add_field(const char *name, int size, const char *comment)
+{
+       struct field *tmp = alloc_type(struct field);
+       const struct field *f;
+
+       if (name)
+               for (f = reg->fields; f; f= f->next)
+                       if (f->name == name)
+                               yyerrorf("duplicate field name \"%s\"", name);
+       if (bit)
+               field->next = tmp;
+       else
+               reg->fields = tmp;
+       field = tmp;
+       field->name = name;
+       field->comment = comment;
+       field->bits = size;
+       field->next = NULL;
+       bit += size;
+       if (bit > bits)
+               yyerrorf("too many bits (%d > %d)", bit, bits);
+}
+
+
+static void add_value(const char *name, const char *comment)
+{
+       const struct value_list *l;
+
+       if (name)
+               for (l = field->value.u.list; l != list; l++)
+                       if (l->name == name)
+                               yyerrorf("duplicate value name \"%s\"", name);
+       list->name = name;
+       list->comment = comment;
+       list++;
+}
+
+
+%}
+
+%union {
+       unsigned num;
+       char *s;
+};
+
+
+%token <num>   TOK_BITS
+%token <s>     TOK_REG TOK_ID STRING
+
+%type  <s>     opt_string opt_id
+
+%%
+
+all:
+       | all item
+       ;
+
+item:
+       TOK_BITS
+               {
+                       bits = $1;
+               }
+       | register
+       ;
+
+register:
+       TOK_REG TOK_ID opt_string
+               {
+                       struct reg **next;
+
+                       for (next = &regs; *next; next = &(*next)->next) {
+                               if ((*next)->id == $1)
+                                       yyerrorf(
+                                           "duplicate register ID \"%s\"", $1);
+                               if ((*next)->name == $2)
+                                       yyerrorf(
+                                           "duplicate register name \"%s\"",
+                                            $2);
+                       }
+                       *next = reg = alloc_type(struct reg);
+                       reg->id = $1;
+                       reg->name = $2;
+                       reg->comment = $3;
+                       reg->bits = bits;
+                       reg->fields = NULL;
+                       reg->next = NULL;
+                       bit = 0;
+               }
+           fields
+               {
+                       if (bit && bit < bits)
+                               yyerrorf("not enough bits (%d < %d)",
+                                   bit, bits);
+                       reg++;
+               }
+       ;
+
+fields:
+       | fields field
+       ;
+
+field:
+       '_'
+               {
+                       add_field(NULL, 1, NULL);
+               }
+       | '_' '[' TOK_ID ']'
+               {
+                       add_field(NULL, number($3), NULL);
+               }
+       | TOK_ID opt_string
+               {
+                       add_field($1, 1, $2);
+               }
+           opt_values
+       | TOK_ID '[' TOK_ID ']' opt_string
+               {
+                       add_field($1, number($3), $5);
+               }
+           opt_values
+       ;
+
+opt_values:
+               {
+                       field->value.type = vt_none;
+               }
+       | '{'
+               {
+                       field->value.type = vt_list;
+                       field->value.u.list = list =
+                           alloc(sizeof(*list)*(1 << field->bits));
+               }
+           values '}'
+               {
+                       int want = 1 << field->bits;
+
+                       if (list != field->value.u.list+want)
+                               yyerrorf("not enough values (%d < %d)",
+                                   (int) (list-field->value.u.list), want);
+               }
+       | '<' TOK_ID '+' TOK_ID '*' opt_id '>'
+               {
+                       field->value.type = vt_formula;
+                       field->value.u.formula.b = number($2);
+                       field->value.u.formula.a = number($4);
+                       field->value.u.formula.unit = $6;
+               }
+       ;
+
+opt_id:
+               {
+                       $$ = NULL;
+               }
+       | TOK_ID
+               {
+                       $$ = $1;
+               }
+       ;
+
+values:
+       | values
+               {
+                       int want = 1 << field->bits;
+
+                       if (list == field->value.u.list+want)
+                               yyerrorf("too many values (expected %d)", want);
+               }
+          value
+       ;
+
+value:
+       '_'
+               {
+                       add_value(NULL, NULL);
+               }
+       | TOK_ID opt_string
+               {
+                       add_value($1, $2);
+               }
+       ;
+
+opt_string:
+               {
+                       $$ = NULL;
+               }
+       | opt_string STRING
+               {
+                       if (!$1)
+                               $$ = $2;
+                       else {
+                               size_t len1 = strlen($1);
+                               size_t len2 = strlen($2);
+
+                               $$ = alloc(len1+len2+1);
+                               memcpy($$, $1, len1);
+                               memcpy($$+len1, $2, len2+1);
+                               free($1);
+                               free($2);
+                       }
+               }
+       ;

Added: developers/werner/greg/pcf50633.greg
===================================================================
--- developers/werner/greg/pcf50633.greg                                (rev 0)
+++ developers/werner/greg/pcf50633.greg        2008-06-26 05:01:10 UTC (rev 
4502)
@@ -0,0 +1,735 @@
+/*
+ * NXP PCF50633 register definitions
+ */
+
+
+#define S(s) #s
+
+
+/* ----- Identification ---------------------------------------------------- */
+
+
+00 VERSION     "Version ID"
+01 VARIANT     "Version ID"
+
+
+/* ----- On/Off Control (OOC) ---------------------------------------------- */
+
+
+0c OOCSHDWN    "OOC shutdown"
+       go_stby         { no_action transition_to_Standby }
+       _
+       totrst          { no_action reset_timeout }
+       coldboot        { no_coldboot coldboot }
+       _[4]
+
+0d OOCWAKE     "OOC wake-up"
+       onkey_wake
+       exton1_wake
+       exton2_wake
+       exton3_wake
+       rtc_wake
+       _
+       usb_wake
+       adp_wake
+
+#define DEBOUNCE { none 5ms 14ms 62ms }
+
+0e OOCTIM1     "OOC debounce 1"
+       exton1_deb[2]   DEBOUNCE
+       exton2_deb[2]   DEBOUNCE
+       exton3_deb[2]   DEBOUNCE
+       shdwn_deb[2]    DEBOUNCE
+
+0f OOCTIM2     "OOC debounce 2 (STANDBY)"
+       onkey_deb[3]    "debounce time for nONKEY"
+                       { none 5ms 14ms 62ms 200ms 500ms 1000ms 2000ms }
+       actphdel[2]     "delay between activation phases"
+                       { 5ms 10ms 15ms 20ms }
+       hcrstdel[2]     "delay between selected activation phase and host "
+                       "controller reset"
+                       { 3ms 6ms 13ms 26ms }
+       almon           "ambient light monitor"
+
+#define EXTON_MODE { wake_on_falling_edge wake_on_rising_edge \
+                    wake_on_falling_8s_timeout_on_rising \
+                    wake_on_rising_8s_timeout_on_falling }
+
+10 OOCMODE     "OOC mode"
+       exton1_mode[2]  "EXTON1 mode selection" EXTON_MODE
+       exton2_mode[2]  "EXTON2 mode selection" EXTON_MODE
+       exton3_mode[2]  "EXTON3 mode selection" EXTON_MODE
+       onkey_mode[2]   "ONKEY mode selection"
+                       { wake_on_falling_edge
+                         wake_on_falling_8s_timeout_if_low_1s
+                         wake_on_falling_8s_timeout_on_rising
+                         _ }
+
+11 OOCCTL      "OOC control"
+       actphrst[2]     "selects activity phase to which host controller "
+                       "reset is related"
+                       { phase_1 phase_2 phase_3 phase_4 }
+       actclk32on      "CLK32K output in Active state"
+       heatbeat        { KEEPACT_required_DC_high
+                         KEEPACT_requires_toggling }
+       usbbatchk       { disabled "Vbat status has no effect on state machine"
+                         enabled "Vbat > Vth(batok) to go to Standby state" }
+       _
+       stbclk32on      "CLK32K output in Standby state"
+       _
+
+12 OOCSTAT     "OOC status"
+       onkey           "ONKEY above threshold"
+       exton1          "EXTON1 above threshold"
+       exton2          "EXTON2 above threshold"
+       exton3          "EXTON3 above threshold"
+       bubpres         "Vbubat above Vth(bubpres)"
+       sysok           "Vsys above Vth(sysok)"
+       batok           "Vbat above Vth(batok)"
+       tmpok           "die_below_Tth_die"
+
+
+/* ----- Interrupt Controller (INT) ---------------------------------------- */
+
+
+02 INT1                "Interrupt 1"
+       adpins          "ADAPTSNS has risen above Vth(adaptpres)"
+       adprem          "ADAPTSNS has dropped below Vth(adaptpres)"
+       usbins          "USBx has risen above Vth(usbpres)"
+       usbrem          "USBx has dropped below Vth(usbpres)"
+       _[2]
+       rtcalarm        "RTC alarm time expired"
+       second          "RTC periodic one second interrupt"
+
+03 INT2                "Interrupt 2"
+       onkeyr          "rising edge on nONKEY"
+       onkeyf          "falling edge on nONKEY"
+       exton1r         "rising edge on EXTON1"
+       exton1f         "falling edge on EXTON1"
+       exton2r         "rising edge on EXTON2"
+       exton2f         "falling edge on EXTON2"
+       exton3r         "rising edge on EXTON3"
+       exton3f         "falling edge on EXTON3"
+
+04 INT3                "Interrupt 3"
+       batfull         "battery is fully charged"
+       chghalt         "charger has entered HALT mode"
+       thlimon         "charger has activated thermal-loop current limiting "
+                       "in the USB-to-SYS path"
+       thlimoff        "charger has deactivated thermal-loop current "
+                       "limiting in the USB-to-SYS path"
+       usblimon        "charger has activated USB current limiting "
+                       "in the USB-to-SYS path"
+       usblimoff       "charger has deactivated USB current limiting "
+                       "in the USB-to-SYS path"
+       adcrdy          "ADC conversion completed"
+       onkey1s         "nONKEY low for at least 1 second"
+
+05 INT4                "Interrupt 4"
+       lowsys          "SYS voltage fallen below Vth(sysok)"
+       lowbat          "BAT voltage fallen below Vth(batok)"
+       hightmp         "Tth(die) exceeded"
+       autopwrfail     "AUTO output voltage below 90% of target"
+       dwn1pwrfail     "DOWN1 output voltage below 90% of target"
+       dwn2pwrfail     "DOWN2 output voltage below 90% of target"
+       ledpwrfail      "LED output current below 90% of target"
+       ledovp          "overvoltage detected at output of LED converter"
+
+06 INT5                "Interrupt 5"
+       ldo1pwrfail     "LDO1 output voltage below 90% of target"
+       ldo2pwrfail     "LDO2 output voltage below 90% of target"
+       ldo3pwrfail     "LDO3 output voltage below 90% of target"
+       ldo4pwrfail     "LDO4 output voltage below 90% of target"
+       ldo5pwrfail     "LDO5 output voltage below 90% of target"
+       ldo6pwrfail     "LDO6 output voltage below 90% of target"
+       hcldopwrfail    "HCLDO output voltage below 90% of target"
+       hcldoovl        "overload (Io > 350mA) detected in HCLDO regulator"
+
+07 INT1MASK    "Interrupt mask 1"
+       adpinsm
+       adpremm
+       usbinsm
+       usbremm
+       _[2]
+       rtcalarmm
+       secondm
+
+08 INT2MASK    "Interrupt mask 2"
+       onkeyrm
+       onkeyfm
+       exton1rm
+       exton1fm
+       exton2rm
+       exton2fm
+       exton3rm
+       exton3fm
+
+09 INT3MASK    "Interrupt mask 3"
+       batfullm
+       chghaltm
+       thlimonm
+       thlimoffm
+       usblimonm
+       usblimoffm
+       adcrdym
+       onkey1sm
+
+0a INT4MASK    "Interrupt mask 4"
+       lowsysm
+       lowbatm
+       hightmpm
+       autopwrfailm
+       dwn1pwrfailm
+       dwn2pwrfailm
+       ledpwrfailm
+       ledovpm
+
+0b INT5MASK    "Interrupt mask 5"
+       ldo1pwrfailm
+       ldo2pwrfailm
+       ldo3pwrfailm
+       ldo4pwrfailm
+       ldo5pwrfailm
+       ldo6pwrfailm
+       hcldopwrfailm
+       hcldoovlm
+
+
+/* ----- General Purpose Input/Output (GPIO/GPO) --------------------------- */
+
+
+13 GPIOCTL     "GPIO I/O mode control"
+       gpio1dir        "GPIO1 I/O mode"
+                       { output input }
+       gpio2dir        "GPIO2 I/O mode"
+                       { output input }
+       gpio3dir        "GPIO3 I/O mode"
+                       { output input }
+       _[5]
+
+#define GPIOxCFG(x)                                                    \
+    GPIO##x##CFG "GPIO" S(x) " signal selection"                       \
+       gpio##x##sel[3] "GPIO" S(x) " output signal selection"          \
+                       { fixed_0 _ sysok battery_charging mobile_mode  \
+                         usbpres actph##x fixed_1 }                    \
+       gpio##x##pol    "GPIO" S(x) " output signal polarity"           \
+                       { no_inversion inversion }                      \
+       _[4]
+
+14 GPIOxCFG(1)
+15 GPIOxCFG(2)
+16 GPIOxCFG(3)
+
+17 GPOCFG      "GPO signal selection"
+       gposel[3]       "GPO output signal selection"
+                       { fixed_0 led_nfet sysok clk32k mobile_mode
+                         usbpres actph4 fixed_1 }
+       gpopol          "GPO output signal polarity"
+                       { no_inversion inversion }
+       _[4]
+
+
+/* ----- System Voltage Monitor (SVM) -------------------------------------- */
+
+
+19 SVMCTL      "SVM control"
+       svmlow          "SYS voltage is lower than Vth(sysok)"
+       svmlvl[3]       "Vth(sysok)"
+                       { _ 2_80V 2_90V 3_00V 3_10V 3_20V 3_30V 3_40V }
+       svmdisdb        "62ms debounce filter"
+                       { enabled disabled }
+       _[3]
+
+
+/* ----- Battery Voltage Monitor (BVM) ------------------------------------- */
+
+
+18 BVMCTL      "BVM control"
+       bvmlow          "BAT voltage is lower than Vth(batok)"
+       bvmlvl[3]       "Vth(batok)"
+                       { _ 2_80V 2_90V 3_00V 3_10V 3_20V 3_30V 3_40V }
+       bvmdisdb        "62ms debounce filter"
+                       { enabled disabled }
+       _[3]
+
+
+/* ----- Power Supply Module (PSM) ----------------------------------------- */
+
+
+3b STBYCTL1    "LDO Standby control"
+       ldo1_ena_stb    "LDO1 in ON in Standby"
+       _
+       ldo2_ena_stb    "LDO2 in ON in Standby"
+       _
+       ldo3_ena_stb    "LDO3 in ON in Standby"
+       _
+       ldo4_ena_stb    "LDO4 in ON in Standby"
+       _
+
+3c STBYCTL2    "LDO Standby control"
+       ldo5_ena_stb    "LDO5 in ON in Standby"
+       _
+       ldo6_ena_stb    "LDO6 in ON in Standby"
+       _
+       hcldo_ena_stb   "HCLDO in ON in Standby"
+       _
+       memldo_ena_stb  "MEMLDO in ON in Standby"
+       _
+
+#define DEBPF(REG, reg)                                                        
\
+       reg##_debpf[2]  S(REG) " power failure debounce time"           \
+                       { none 1ms 10ms 100ms }
+
+#define STAT(REG, reg)                                                 \
+       reg##_pwrok     S(REG) " > 90% of target"
+
+3d DEBPF1      "Power fail debounce 1"
+       DEBPF(AUTO, auto)
+       DEBPF(DOWN1, down1)
+       DEBPF(DOWN2, down2)
+       DEBPF(LED, led)
+
+3e DEBPF2      "Power fail debounce 2"
+       DEBPF(LDO1, ldo1)
+       DEBPF(LDO2, ldo2)
+       DEBPF(LDO3, ldo3)
+       DEBPF(LDO4, ldo4)
+
+3f DEBPF3      "Power fail debounce 3"
+       DEBPF(LDO5, ldo5)
+       DEBPF(LDO6, ldo6)
+       DEBPF(HCLDO, hcldo)
+       _[2]
+
+41 DCDCSTAT    "DC-to-DC converter status"
+       STAT(AUTO, auto)
+       STAT(DOWN1, down1)
+       STAT(DOWN2, down2)
+       STAT(LED, led)
+       _[4]
+
+42 LDOSTAT     "LDO status"
+       STAT(LDO1, ldo1)
+       STAT(LDO2, ldo2)
+       STAT(LDO3, ldo3)
+       STAT(LDO4, ldo4)
+       STAT(LDO5, ldo5)
+       STAT(LDO6, ldo6)
+       STAT(HCLDO, hcldo)
+       hcldo_ovl       "HCLDO is in overload mode"
+
+
+/* ----- AUTO, DOWN1 and DOWN2 converters ---------------------------------- */
+
+
+#define DC_OUT(reg)                                                    \
+       reg##_out[8]    "Vo(prog) [1800mV,3800mV]"                      \
+                       <625+25* mV>
+       
+#define ENA(reg)                                                       \
+       reg##_on        { off on }                                      \
+       reg##_p1c       { off on_gpio1 "ON when GPIO1 = 1" }            \
+       reg##_p2c       { off on_gpio2 "ON when GPIO2 = 1" }            \
+       reg##_p3c       { off on_gpio3 "ON when GPIO3 = 1" }            \
+       reg##_ena_act[2] "selects activation phase"                     \
+                       { actph1 actph2 actph3 actph4 }                 \
+       _[2]
+
+#define MXC(reg)                                                       \
+       reg##_maxc[6]   "Ii(max)"                                       \
+                       <0+40* mA>                                      \
+       reg##_maxcmod   "current limit mode"                            \
+                       { start_up always }                             \
+       _
+
+#define DOWNxCTL(x)                                                    \
+       down##x##pwmonly { pfm_pwm "automatic PFM-PWM selection"        \
+                         pwm "converter operates in PWM mode" }        \
+       down##x##_dvmstep[4]                                            \
+                       "DVM step time, 32768 Hz"                       \
+                       <0+30* us>                                      \
+       _[3]
+
+#define LDO_OUT(reg)                                                   \
+       reg##_out[5]    "Vo(prog)"                                      \
+                       <900+100* mV>                                   \
+       reg##_swmod     { linear_reg switch }                           \
+       _[2]
+
+
+1a AUTOOUT     "AUTO output voltage select (STANDBY)"
+       DC_OUT(auto)
+
+1b AUTOENA     "AUTO output enable (STANDBY)"
+       ENA(auto)
+
+1c AUTOCTL     "AUTO control register (STANDBY)"
+       autopwmonly     { pfm_pwm "automatic PFM-PWM selection"
+                         pwm "converter operates in PWM mode" }
+       auto_mod        { auto_up_down down_only }
+       _[6]
+
+1d AUTOMXC     "AUTO maximum current (STANDBY)"
+       MXC(auto)
+
+1e DOWN1OUT    "DOWN1 output voltage select (STANDBY)"
+       DC_OUT(down1)
+
+1f DOWN1ENA    "DOWN1 output enable (STANDBY)"
+       ENA(down1)
+
+20 DOWN1CTL    "DOWN1 control (STANDBY)"
+       DOWNxCTL(1)
+
+21 DOWN1MXC    "DOWN1 maximum current (STANDBY)"
+       MXC(down1)
+
+22 DOWN2OUT    "DOWN2 output voltage select (STANDBY)"
+       DC_OUT(down2)
+
+23 DOWN2ENA    "DOWN2 output enable (STANDBY)"
+       ENA(down2)
+
+24 DOWN2CTL    "DOWN2 control (STANDBY)"
+       DOWNxCTL(2)
+
+25 DOWN2MXC    "DOWN2 maximum current (STANDBY)"
+       MXC(down2)
+
+26 MEMLDOOUT   "MEMLDO output voltage select (STANDBY)"
+       LDO_OUT(memldo)
+
+27 MEMLDOENA   "MEMLDO output enable (STANDBY)"
+       ENA(memldo)
+
+84 DCDCPFM     "DCDC force PFM control (NOPOWER)"
+       autopfm         "force AUTO temporarily to PFM mode"
+       down1pfm        "force DOWN1 temporarily to PFM mode"
+       down2pfm        "force DOWN2 temporarily to PFM mode"
+       _[5]
+
+
+/* ----- LED boost converter & Ambient Light Monitor (ALM) ----------------- */
+
+
+28 LEDOUT      "LED output voltage select (STANDBY)"
+       led_out[6]       "Iled = Vledfb/Rsense"
+               // x000  x001  x010  x011  x100  x101  x110  x111
+               {     _   2mV     _  10mV     _     _     _     _       // 000x
+                  27mV     _  37mV     _     _     _  56mV     _       // 001x
+                     _     _  81mV     _     _     _ 113mV     _       // 010x
+                     _     _ 149mV     _     _     _ 196mV     _       // 011x
+                     _     _ 250mV     _     _     _ 318mV     _       // 100x
+                     _     _ 401mV     _     _     _ 501mV     _       // 101x
+                     _     _ 626mV     _     _     _ 778mV     _       // 110x
+                     _     _ 961mV     _     _     _     _ 1250mV }    // 111x
+       _[2]
+// TODO: complete the table
+// TODO: find a way to programatically generate tables
+// maybe do it like tcsim does, { code }
+
+29 LEDENA      "LED output enable (STANDBY)"
+       ENA(led)
+
+2a LEDCTL      "LED control (STANDBY)"
+       led_ovpon       "overvoltage protection"
+       led_ovprs       "reset overvoltage protection"
+       led_ocp         "OCP limit"
+                       { 1000mA 500mA }
+       _[5]
+
+2b LEDDIM      "LED ramp control (STANDBY)"
+       led_dimstep[8]  "tdimstep=16*led_dimstep/32768s"
+                       <0+488* us>
+
+4f ALMGAIN     "Ambient lighting gain factor (STANDBY)"
+       alm_gain[5]     "ambient light processing gain factor"
+       _[3]
+
+50 ALMDATA     "Ambient light intensity data (STANDBY)"
+       alm_data[8]
+
+
+/* ----- Linear regulators ------------------------------------------------- */
+
+
+#define LDOxOUT(LDO, ldo)                                              \
+    LDO##OUT   S(LDO) " output voltage select (STANDBY)"               \
+       LDO_OUT(reg)
+
+#define LDOxENA(LDO, ldo)                                              \
+    LDO##ENA   S(LDO) " output enable (STANDBY)"                       \
+       ENA(ldo)
+
+
+2d LDOxOUT(LDO1, ldo1)
+2e LDOxENA(LDO1, ldo1)
+
+2f LDOxOUT(LDO2, ldo2)
+30 LDOxENA(LDO2, ldo2)
+
+31 LDOxOUT(LDO3, ldo3)
+32 LDOxENA(LDO3, ldo3)
+
+33 LDOxOUT(LDO4, ldo4)
+34 LDOxENA(LDO4, ldo4)
+
+35 LDOxOUT(LDO5, ldo5)
+36 LDOxENA(LDO5, ldo5)
+
+37 LDOxOUT(LDO6, ldo6)
+38 LDOxENA(LDO6, ldo6)
+
+39 LDOxOUT(HCLDO, hcldo)
+3a LDOxENA(HCLDO, hcldo)
+
+40 HCLDOOVL    "HCLDO overload protection"
+       hcldo_debovl[2] "overload detecton debounce time"
+                       { none 1ms 10ms 100ms }
+       _[6]
+
+
+/* ----- Main Battery Charger (MBC) ---------------------------------------- */
+
+
+43 MBCC1       "MBC charger control 1"
+       chgena          "charger enabled"
+       autostop        "stop charging when current falls below cutoffcur"
+       autores         "resume charging then Vbat < Vth(RES), 96% of vmax"
+       resume          "resume if in Battery Full"
+       restart         "restart if in Halt"
+       prewdtime       "maximum charging time during Precharge phase"
+                       { 30min 60min }
+       wdtime[2]       "maximum charging time after Precharge phase"
+                       { 1h 2h 4h 6h }
+
+44 MBCC2       "MBC charger control 2"
+       vbatcond[2]     { 2_7V 2_85V 3_0V 3_15V }
+       vmax[4]         "Vbat(float)prog"
+                       <4000+20* mV>
+       _
+       vresdebtime     "debounce time for Vth(RES)"
+                       { 32s 64s }
+
+45 MBCC3       "MBC charger control 3"
+       prechgcur[8]    "pre-charge current level, N/255*Ich(ref)"
+
+46 MBCC4       "MBC charger control 4"
+       fstchgcur1[8]   "fast charge current level in adapter Fast Charge "
+                       "phase, N/255*Ich(ref)"
+
+47 MBCC5       "MBC charger control 5"
+       fstchgcur2[8]   "fast charge current level in USB Fast Charge "
+                       "phase, N/255*Ich(ref)"
+
+48 MBCC6       "MBC charger control 6"
+       cutoffcur[5]    "cutoff current level (full in CV), 1/32*Ichg"
+       _[3]
+
+49 MBCC7       "MBC charger control 7"
+       usbdevstat[2]   "USB device status setting (STANDBY)"
+                       { 100mA 500mA 1000mA suspend }
+       batttempena     "battery temperature is measured and impacts the "
+                       "MBC state machine"
+       _[3]
+       batsysimax[2]   "maximum BAT-SYS current when ideal diode is conducting"
+                       { 1_6A 1_8A 2_0A 2_2A }
+
+4a MBCC8       "MBC charger control 8"
+       ntclvt[4]       "NTC voltage level for battery high temperature "
+                       "threshold"
+                       <600+50* mV>
+       usbenasus       "USB-SYS switch enabled in USB suspend, "
+                       "ideal diode disabled"
+       _[3]
+
+4b MBCS1       "MBC charger status 1"
+       usbpres         "Vusb > Vth(usbpres)"
+       usbok           "Vusb > Vbat+dVusbok"
+       adaptpres       "Vadaptsns > Vth(adaptpres)"
+       adaptok         "Vsys > Vbat+dVadaptok"
+       tbatstat[2]     "battery temperature status indication"
+                       { within_window above_window below_window undefined }
+       prewdtexp       "watchdog timer expired during pre-charging"
+       wdtexp          "watchdog timer expired after pre-charging"
+
+4c MBCS2       "MBC charger status 2"
+       mbcmod[4]       "main MBC operating modes and charge phases"
+                       { play_only usb_precharge usb_precharge_wait
+                         usb_fast_charge usb_fast_charge_wait usb_suspend
+                         adapter_precharge adapter_precharge_wait
+                         adapter_fast_charge adapter_fast_charge_wait
+                         battery_full halt _ _ _ _ }
+       chgstat[2]      "charger connection status"
+                       { no_charger adapter usb  adapter_and_usb }
+       resstat         "charging has resumed automatically"
+       _
+
+4d MBCS3       "MBC charger status 3"
+       usblim_play     "USB current limiting in USB-to-SYS path"
+       usblim_chg      "USB current limiting in USB-to-BAT path"
+       tlim_play       "temperature limiting in USB-to-SYS path"
+       tlim_chg        "temperature limiting in USB-to-BAT or SYS-BAT path"
+       ilim            "battery charge current > cutoffcur level"
+       vlim            "battery voltage equals vmax level"
+       vbatstat        "battery voltage > Vbatcond"
+       vres            "battery voltage > Vth(RES)"
+
+
+/* ----- Backup Battery Charger (BBC) -------------------------------------- */
+
+
+4e BBCCTL      "Backup battery charger control"
+       bbce    "enable backup battery charger (STANDBY)"
+       bbcr    "bypass output resistor"
+       bbcc[2] "backup battery charge current, Ich(BUBAT)"
+               { 50uA 100uA 200uA 400uA }
+       bbcv    "limiting voltage for backup battery charger Vlim(BUBAT)"
+               { 2_5V 3_0V }
+       _[3]
+
+
+/* ----- 10-bit Analog-to-Digital Converter (ADC) -------------------------- */
+
+
+54 ADCC1       "A/D converter control 1"
+       adcstart        "ADC conversion start command"
+       adcres          "ADC resolution"        
+                       { 10bit 8bit }
+       adc_av[2]       "measurement averaging"
+                       { none 4_samples 8_samples 16_samples }
+       adcinmux[4]     "ADC input selection"
+                       { batsns_r "BATSNS via resistive divider"
+                         batsns_sub "BATSNS via subtractor"
+                         adcin2_r "ADCIN2 via resistive divider"
+                         adcin2_sub "ADCIN2 via subtractor"
+                         _
+                         _
+                         battemp "BATTEMP"
+                         adcin1 "ADCIN1"
+                         _ _ _ _ _ _ _ _ }
+
+53 ADCC2       "A/C converter control 2"
+       adcratioen[2]   "ratiometric measurement"
+                       { none "no ratiometric mode measurement"
+                         battemp "BATTEMP only"
+                         adcin1 "ADCIN1 only"
+                         battemp_adcin "BATTEMP and ADCIN1" }
+       adcratioset     "ratiometric settling time"
+                       { 10us 100us }
+       _[5]
+
+52 ADCC3       "A/C converter control 3"
+       accswen         "enable biasing for ratiometric measurement on ADCIN1"
+       _
+       ntcswen         "enable biasing for ratiometric measurement on BATTEMP"
+       _
+       adcdivsel       "resistive divider type"
+                       { by_3 by_2 }
+       _[3]
+
+55 ADCS1       "A/D converter status 1"
+       adcdat1h[8]     "8 most significant bits of the (first) ADC result"
+
+56 ADCS2       "A/D converter status 2"
+       adcdat2h[8]     "8 most significant bits of the second ADC result"
+
+57 ADCS3       "A/D converter status 3"
+       adcdat1l[2]     "2 least significant bits of the (first) ADC result"
+       adcdat2l[2]     "2 least significant bits of the second ADC result"
+       adcrefmux[3]    "ADC reference selection"
+                       { ntcsw accws 2_0V visa
+                         _ _ _ 2_0V_again }
+       adcrdy          "ADC conversion is completed"
+
+
+/* ----- Real-time clock (RTC) --------------------------------------------- */
+
+
+#define WEEKDAYS { sun mon tue wed thu fri sat _ }
+
+#define MONTHS                                 \
+       { _   jan feb mar apr may jun jul       \
+         aug sep _   _   _   _   _   _         \
+         oct nov dec _   _   _   _   _         \
+         _   _   _   _   _   _   _   _ }
+
+
+59 RTCSC       "RTC second value"
+       sec[7]          "current seconds, BCD"
+       _
+
+5a RTCMN       "RTC minute value"
+       min[7]          "current minutes, BCD"
+       _
+
+5b RTCHR       "RTC hour value"
+       hour[6]         "current hours, BCD"
+       _[2]
+
+5c RTCWD       "RTC day-of-week value"
+       wkday[3]        "current day-of-week"
+                       WEEKDAYS
+       _[5]
+
+5d RTCDT       "RTC day value"
+       day[5]          "current day value, BCD, 01-based"
+       _[3]
+
+5e RTCMT       "RTC month value"
+       month[5]        "current month value"
+                       MONTHS
+       _[3]
+
+5f RTCYR       "RTC year value"
+       year[8]         "current year, BCD"
+
+60 RTCSCA      "RTC second alarm value"
+       seca[7]         "alarm seconds, BCD"
+       _
+
+61 RTCMNA      "RTC minute alarm value"
+       mina[7]         "alarm minutes, BCD"
+       _
+
+62 RTCHRA      "RTC hour alarm value"
+       houra[6]        "alarm hours, BCD"
+       _[2]
+
+63 RTCWDA      "RTC weekday alarm value"
+       wkdaya[3]       "alarm day-of-week"
+                       WEEKDAYS
+       _[5]
+
+64 RTCDTA      "RTC day alarm value"
+       daya[5]         "alarm day value, BCD, 01-based"
+       _[3]
+
+65 RTCMTA      "RTC month alarm value"
+       montha[5]       "alarm month value"
+                       MONTHS
+       _[3]
+
+66 RTCYRA      "RTC year alarm value"
+       yeara[8]        "alarm year, BCD"
+
+
+/* ----- General Purpose Memory (GPM) -------------------------------------- */
+
+
+#define MEMBYTE(n)                                                     \
+       MEMBYTE##n "General purpose memory byte " S(n)                  \
+               membyte##n[8]
+
+
+67 MEMBYTE(0)
+68 MEMBYTE(1)
+69 MEMBYTE(2)
+6a MEMBYTE(3)
+6b MEMBYTE(4)
+6c MEMBYTE(5)
+6d MEMBYTE(6)
+6e MEMBYTE(7)
+
+
+/* ------------------------------------------------------------------------- */

Added: developers/werner/greg/reg.h
===================================================================
--- developers/werner/greg/reg.h                                (rev 0)
+++ developers/werner/greg/reg.h        2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,55 @@
+/*
+ * lang.y - Input language of the generalized register pretty-printer
+ *
+ * Copyright (C) 2008 by OpenMoko, Inc.
+ * Written by Werner Almesberger <[EMAIL PROTECTED]>
+ * All Rights Reserved
+ *
+ * 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.
+ */
+
+
+#ifndef REG_H
+#define REG_H
+
+
+struct reg {
+       const char *id;         /* technical register ID */
+       const char *name;       /* human-readable register name */
+       const char *comment;    /* description or NULL */
+       int bits;               /* register width in bits */
+       struct field *fields;   /* list of fields, always non-NULL */
+       struct reg *next;       /* next register */
+};
+
+struct value {
+       enum { vt_none, vt_list, vt_formula } type;
+       union {
+               struct value_list {
+                       const char *name;
+                       const char *comment;
+               } *list;
+               struct {
+                       int a;                  /* aX+b */
+                       int b;
+                       const char *unit;       /* unit name, may be NULL */
+               } formula;
+       } u;
+};
+
+struct field {
+       const char *name;       /* human-readable field name */
+       const char *comment;    /* description or NULL */
+       int bits;               /* field size in bits */
+       struct value value;
+       struct field *next;     /* next field */
+};
+
+
+extern struct reg *regs;
+
+
+#endif /* !REG_H */

Added: developers/werner/greg/tests/Common
===================================================================
--- developers/werner/greg/tests/Common                         (rev 0)
+++ developers/werner/greg/tests/Common 2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+
+fail()
+{
+    echo FAILED "($SCRIPT)" 1>&2
+    cat _out 1>&2
+    exit 1
+}
+
+
+process()
+{
+    echo -n "$1: " 1>&2
+    shift
+    ../greg - "$@" >_out 2>&1
+}
+
+
+greg()
+{
+    process "$@" || fail
+}
+
+
+greg_fail()
+{
+    process "$@" && fail
+}
+
+
+expect()
+{
+    if ! diff -u - _out >_tmp; then
+       echo FAILED "($SCRIPT)" 1>&2
+       cat _tmp
+       exit
+    fi
+    rm -f _out _tmp
+    echo PASSED 1>&2
+    passed=`expr ${passed:-0} + 1`
+}

Added: developers/werner/greg/tests/Makefile
===================================================================
--- developers/werner/greg/tests/Makefile                               (rev 0)
+++ developers/werner/greg/tests/Makefile       2008-06-26 05:01:10 UTC (rev 
4502)
@@ -0,0 +1,11 @@
+.PHONY:        tests clean
+
+# Explicitly enumerate the lower case letters to escape localization weirdness.
+
+tests:
+       for n in [abcdefghijklmnopqrstuvwxyz]*; do \
+         SCRIPT=$$n PATH=.:$$PATH . ./$$n; done; \
+         echo "Passed all $$passed tests" 2>&1
+
+clean:
+       rm -f _*

Added: developers/werner/greg/tests/field
===================================================================
--- developers/werner/greg/tests/field                          (rev 0)
+++ developers/werner/greg/tests/field  2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,93 @@
+#!/bin/sh
+. ./Common
+
+# -----------------------------------------------------------------------------
+
+greg "named field without comment" foo 0x12 <<EOF
+foo bar
+       blah[8]
+EOF
+
+expect <<EOF
+foo bar = 0x12
+    blah
+       0001.0010 (0x12)
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg "named field with comment" bar 52 <<EOF
+bar blah
+       foo[8] "field blah"
+EOF
+
+expect <<EOF
+bar blah = 0x34
+    foo -- field blah
+       0011.0100 (0x34)
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg "anonymous field without comment" bar 0x55 <<EOF
+bar foo
+       _[5]
+       bar[3]
+EOF
+
+expect <<EOF
+bar foo = 0x55
+    bar
+       010 (0x2)
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg "anonymous field with comment" foo 0xaa <<EOF
+foo blah
+       bar[5]
+       _[3]
+EOF
+
+expect <<EOF
+foo blah = 0xaa
+    bar
+       0.1010 (0x0a)
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg_fail "fields don't fill register" <<EOF
+foo bar
+       blah[4]
+       _[3]
+EOF
+
+expect <<EOF
+4: not enough bits (7 < 8) near ""
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg_fail "fields exceed register" <<EOF
+foo bar
+       _[3]
+       blah[7]
+EOF
+
+expect <<EOF
+4: too many bits (10 > 8) near ""
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg_fail "duplicate field name" <<EOF
+bar blah
+       foo
+       _[6]
+       foo
+EOF
+
+expect <<EOF
+5: duplicate field name "foo" near ""
+EOF


Property changes on: developers/werner/greg/tests/field
___________________________________________________________________
Name: svn:executable
   + *

Added: developers/werner/greg/tests/reg
===================================================================
--- developers/werner/greg/tests/reg                            (rev 0)
+++ developers/werner/greg/tests/reg    2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,54 @@
+#!/bin/sh
+. ./Common
+
+# -----------------------------------------------------------------------------
+
+greg "8 bit register, no comment" foo 0x12 <<EOF
+foo bar
+EOF
+
+expect <<EOF
+foo bar = 0x12
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg "8 bit register, with comment" bar 52 <<EOF
+bar blah "hello"
+EOF
+
+expect <<EOF
+bar blah = 0x34 -- hello
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg_fail "duplicate register ID" <<EOF
+foo bar
+foo blah
+EOF
+
+expect <<EOF
+3: duplicate register ID "foo" near ""
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg_fail "duplicate register name" <<EOF
+foo blah
+bar blah
+EOF
+
+expect <<EOF
+3: duplicate register name "blah" near ""
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg "duplicate register comment" <<EOF
+foo bar "blah"
+bar foo "blah"
+EOF
+
+expect <<EOF
+EOF


Property changes on: developers/werner/greg/tests/reg
___________________________________________________________________
Name: svn:executable
   + *

Added: developers/werner/greg/tests/value
===================================================================
--- developers/werner/greg/tests/value                          (rev 0)
+++ developers/werner/greg/tests/value  2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,88 @@
+#!/bin/sh
+. ./Common
+
+# -----------------------------------------------------------------------------
+
+greg "named value without comment" foo 2 <<EOF
+foo bar
+       blah[2] { zero one two three }
+       _[6]
+EOF
+
+expect <<EOF
+foo bar = 0x02
+    blah
+       10 (0x2): two
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg "named value with comment" foo 0x40 <<EOF
+foo bar
+       _[6]
+       blah[2] { zero "null" one "eins" two "zwei" three "drei" }
+EOF
+
+expect <<EOF
+foo bar = 0x40
+    blah
+       01 (0x1): one -- eins
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg "anonymus value without comment" foo 3 <<EOF
+foo bar
+       blah[2] { zero one two _ }
+       _[6]
+EOF
+
+expect <<EOF
+foo bar = 0x03
+    blah
+       11 (0x3): RESERVED
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg_fail "anonymus value with comment (error)" foo 0 <<EOF
+foo bar
+       _[5]
+       blah[3] { _ "zero" one two _ _ _ _ _ }
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg_fail "not enough values" <<EOF
+foo bar
+       blah[3] { a b c d e f }
+       _[5]
+EOF
+
+expect <<EOF
+2: not enough values (6 < 8) near "}"
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg_fail "too many values" <<EOF
+foo bar
+       _[6]
+       blah[2] { 1 2 3 4 5 }
+EOF
+
+expect <<EOF
+3: too many values (expected 4) near "5"
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg_fail "duplicate value name" <<EOF
+bar blah
+       _[6]
+       foo[2] { a b a c }
+EOF
+
+expect <<EOF
+3: duplicate value name "a" near "c"
+EOF


Property changes on: developers/werner/greg/tests/value
___________________________________________________________________
Name: svn:executable
   + *

Added: developers/werner/greg/tests/width
===================================================================
--- developers/werner/greg/tests/width                          (rev 0)
+++ developers/werner/greg/tests/width  2008-06-26 05:01:10 UTC (rev 4502)
@@ -0,0 +1,68 @@
+#!/bin/sh
+. ./Common
+
+# -----------------------------------------------------------------------------
+
+greg "4 bit register" foo 0x8 <<EOF
+%4
+foo bar
+EOF
+
+expect <<EOF
+foo bar = 0x8
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg "5 bit register" foo 8 <<EOF
+%5
+foo bar
+EOF
+
+expect <<EOF
+foo bar = 0x08
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg "8 bit register" foo 9 <<EOF
+%8
+foo bar
+EOF
+
+expect <<EOF
+foo bar = 0x09
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg "16 bit register" foo 0x8765 <<EOF
+%16
+foo foo
+EOF
+
+expect <<EOF
+foo foo = 0x8765
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg "32 bit register" bar 0x87654321 <<EOF
+%32
+bar bar
+EOF
+
+expect <<EOF
+bar bar = 0x87654321
+EOF
+
+# -----------------------------------------------------------------------------
+
+greg "64 bit register" foo 0x123456789abcdef0 <<EOF
+%64
+foo bar
+EOF
+
+expect <<EOF
+foo bar = 0x123456789abcdef0
+EOF


Property changes on: developers/werner/greg/tests/width
___________________________________________________________________
Name: svn:executable
   + *




--- End Message ---
_______________________________________________
commitlog mailing list
commitlog@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/commitlog

Reply via email to