summaryrefslogtreecommitdiffstats
path: root/toolbox/syren.c
diff options
context:
space:
mode:
Diffstat (limited to 'toolbox/syren.c')
-rw-r--r--toolbox/syren.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/toolbox/syren.c b/toolbox/syren.c
new file mode 100644
index 0000000..06e329e
--- /dev/null
+++ b/toolbox/syren.c
@@ -0,0 +1,154 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <malloc.h>
+
+/* ioctl crap */
+#define SYREN_RD 101
+#define SYREN_WR 102
+#define SYREN_OLD_RD 108
+#define SYREN_OLD_WR 109
+
+struct syren_io_args {
+ unsigned long page;
+ unsigned long addr;
+ unsigned long value;
+};
+
+typedef struct {
+ u_char page;
+ u_char addr;
+ const char *name;
+} syren_reg;
+
+static syren_reg registers[] = {
+ { 0, 0x04, "TOGBR1" },
+ { 0, 0x05, "TOGBR2" },
+ { 0, 0x06, "VBDCTRL" },
+ { 1, 0x07, "VBUCTRL" },
+ { 1, 0x08, "VBCTRL" },
+ { 1, 0x09, "PWDNRG" },
+ { 1, 0x0a, "VBPOP" },
+ { 1, 0x0b, "VBCTRL2" },
+ { 1, 0x0f, "VAUDCTRL" },
+ { 1, 0x10, "VAUSCTRL" },
+ { 1, 0x11, "VAUOCTRL" },
+ { 1, 0x12, "VAUDPLL" },
+ { 1, 0x17, "VRPCSIMR" },
+ { 0, 0, 0 }
+};
+
+static syren_reg *find_reg(const char *name)
+{
+ int i;
+
+ for (i = 0; registers[i].name != 0; i++) {
+ if (!strcasecmp(registers[i].name, name))
+ return &registers[i];
+ }
+
+ return NULL;
+}
+
+static int usage(void)
+{
+ fprintf(stderr, "usage: syren [r/w] [REGNAME | page:addr] (value)\n");
+ return 1;
+}
+
+int
+syren_main(int argc, char **argv)
+{
+ int cmd = -1;
+ syren_reg *r;
+ struct syren_io_args sio;
+ char name[32];
+ int fd;
+
+ if (argc < 3) {
+ return usage();
+ }
+
+ switch(argv[1][0]) {
+ case 'r':
+ cmd = SYREN_RD;
+ break;
+ case 'w':
+ cmd = SYREN_WR;
+ break;
+ case 'R':
+ cmd = SYREN_OLD_RD;
+ break;
+ case 'W':
+ cmd = SYREN_OLD_WR;
+ break;
+ default:
+ return usage();
+ }
+
+ if (cmd == SYREN_WR || cmd == SYREN_OLD_WR) {
+ if (argc < 4)
+ return usage();
+ sio.value = strtoul(argv[3], 0, 0);
+ }
+
+ fd = open("/dev/eac", O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "can't open /dev/eac\n");
+ return 1;
+ }
+
+ if (strcasecmp(argv[2], "all") == 0) {
+ int i;
+ if (cmd != SYREN_RD && cmd != SYREN_OLD_RD) {
+ fprintf(stderr, "can only read all registers\n");
+ return 1;
+ }
+
+ for (i = 0; registers[i].name; i++) {
+ sio.page = registers[i].page;
+ sio.addr = registers[i].addr;
+ if (ioctl(fd, cmd, &sio) < 0) {
+ fprintf(stderr, "%s: error\n", registers[i].name);
+ } else {
+ fprintf(stderr, "%s: %04x\n", registers[i].name, sio.value);
+ }
+ }
+
+ close(fd);
+ return 0;
+ }
+
+ r = find_reg(argv[2]);
+ if (r == NULL) {
+ strcpy(name, argv[2]);
+ char *addr_str = strchr(argv[2], ':');
+ if (addr_str == NULL)
+ return usage();
+ *addr_str++ = 0;
+ sio.page = strtoul(argv[2], 0, 0);
+ sio.addr = strtoul(addr_str, 0, 0);
+ } else {
+ strcpy(name, r->name);
+ sio.page = r->page;
+ sio.addr = r->addr;
+ }
+
+ if (ioctl(fd, cmd, &sio) < 0) {
+ fprintf(stderr, "ioctl(%d) failed\n", cmd);
+ return 1;
+ }
+
+ if (cmd == SYREN_RD || cmd == SYREN_OLD_RD) {
+ printf("%s: %04x\n", name, sio.value);
+ } else {
+ printf("wrote %04x to %s\n", sio.value, name);
+ }
+
+ close(fd);
+
+ return 0;
+}
+