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 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 ®isters[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 155