• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #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 
14 struct syren_io_args {
15 	unsigned long	page;
16 	unsigned long	addr;
17 	unsigned long	value;
18 };
19 
20 typedef struct {
21 	u_char			page;
22 	u_char			addr;
23 	const char		*name;
24 } syren_reg;
25 
26 static 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 
find_reg(const char * name)43 static 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 
usage(void)55 static int usage(void)
56 {
57 	fprintf(stderr, "usage: syren [r/w] [REGNAME | page:addr] (value)\n");
58 	return 1;
59 }
60 
61 int
syren_main(int argc,char ** argv)62 syren_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 
155