blob: 06e329e99f4fa17ca187f4ce6b114cab2f96ae1c [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <fcntl.h>
6#include <malloc.h>
7
8/* ioctl crap */
9#define SYREN_RD 101
10#define SYREN_WR 102
11#define SYREN_OLD_RD 108
12#define SYREN_OLD_WR 109
13
14struct syren_io_args {
15 unsigned long page;
16 unsigned long addr;
17 unsigned long value;
18};
19
20typedef struct {
21 u_char page;
22 u_char addr;
23 const char *name;
24} syren_reg;
25
26static syren_reg registers[] = {
27 { 0, 0x04, "TOGBR1" },
28 { 0, 0x05, "TOGBR2" },
29 { 0, 0x06, "VBDCTRL" },
30 { 1, 0x07, "VBUCTRL" },
31 { 1, 0x08, "VBCTRL" },
32 { 1, 0x09, "PWDNRG" },
33 { 1, 0x0a, "VBPOP" },
34 { 1, 0x0b, "VBCTRL2" },
35 { 1, 0x0f, "VAUDCTRL" },
36 { 1, 0x10, "VAUSCTRL" },
37 { 1, 0x11, "VAUOCTRL" },
38 { 1, 0x12, "VAUDPLL" },
39 { 1, 0x17, "VRPCSIMR" },
40 { 0, 0, 0 }
41};
42
43static syren_reg *find_reg(const char *name)
44{
45 int i;
46
47 for (i = 0; registers[i].name != 0; i++) {
48 if (!strcasecmp(registers[i].name, name))
49 return &registers[i];
50 }
51
52 return NULL;
53}
54
55static int usage(void)
56{
57 fprintf(stderr, "usage: syren [r/w] [REGNAME | page:addr] (value)\n");
58 return 1;
59}
60
61int
62syren_main(int argc, char **argv)
63{
64 int cmd = -1;
65 syren_reg *r;
66 struct syren_io_args sio;
67 char name[32];
68 int fd;
69
70 if (argc < 3) {
71 return usage();
72 }
73
74 switch(argv[1][0]) {
75 case 'r':
76 cmd = SYREN_RD;
77 break;
78 case 'w':
79 cmd = SYREN_WR;
80 break;
81 case 'R':
82 cmd = SYREN_OLD_RD;
83 break;
84 case 'W':
85 cmd = SYREN_OLD_WR;
86 break;
87 default:
88 return usage();
89 }
90
91 if (cmd == SYREN_WR || cmd == SYREN_OLD_WR) {
92 if (argc < 4)
93 return usage();
94 sio.value = strtoul(argv[3], 0, 0);
95 }
96
97 fd = open("/dev/eac", O_RDONLY);
98 if (fd < 0) {
99 fprintf(stderr, "can't open /dev/eac\n");
100 return 1;
101 }
102
103 if (strcasecmp(argv[2], "all") == 0) {
104 int i;
105 if (cmd != SYREN_RD && cmd != SYREN_OLD_RD) {
106 fprintf(stderr, "can only read all registers\n");
107 return 1;
108 }
109
110 for (i = 0; registers[i].name; i++) {
111 sio.page = registers[i].page;
112 sio.addr = registers[i].addr;
113 if (ioctl(fd, cmd, &sio) < 0) {
114 fprintf(stderr, "%s: error\n", registers[i].name);
115 } else {
116 fprintf(stderr, "%s: %04x\n", registers[i].name, sio.value);
117 }
118 }
119
120 close(fd);
121 return 0;
122 }
123
124 r = find_reg(argv[2]);
125 if (r == NULL) {
126 strcpy(name, argv[2]);
127 char *addr_str = strchr(argv[2], ':');
128 if (addr_str == NULL)
129 return usage();
130 *addr_str++ = 0;
131 sio.page = strtoul(argv[2], 0, 0);
132 sio.addr = strtoul(addr_str, 0, 0);
133 } else {
134 strcpy(name, r->name);
135 sio.page = r->page;
136 sio.addr = r->addr;
137 }
138
139 if (ioctl(fd, cmd, &sio) < 0) {
140 fprintf(stderr, "ioctl(%d) failed\n", cmd);
141 return 1;
142 }
143
144 if (cmd == SYREN_RD || cmd == SYREN_OLD_RD) {
145 printf("%s: %04x\n", name, sio.value);
146 } else {
147 printf("wrote %04x to %s\n", sio.value, name);
148 }
149
150 close(fd);
151
152 return 0;
153}
154