Home | History | Annotate | Download | only in toolbox
      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 
     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 
     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
     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