159 lines
2.8 KiB
C
159 lines
2.8 KiB
C
#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 ®isters[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) {
|
|
if(strlen(argv[2]) >= sizeof(name)){
|
|
fprintf(stderr, "REGNAME too long\n");
|
|
return 0;
|
|
}
|
|
strlcpy(name, argv[2], sizeof(name));
|
|
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 {
|
|
strlcpy(name, r->name, sizeof(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;
|
|
}
|
|
|