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