comparison superio/superio.c @ 0:c34b37680055 default tip

Inital commit of random SuperIO code.
author Daniel O'Connor <darius@dons.net.au>
date Thu, 20 Oct 2011 16:48:24 +1030
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:c34b37680055
1 #include <stdio.h>
2 #include <errno.h>
3 #include <string.h>
4 #include <fcntl.h>
5 #include <stdlib.h>
6 #include <sys/types.h>
7 #include <machine/cpufunc.h>
8 #include <unistd.h>
9
10 void
11 usage(char *name) {
12 fprintf(stderr,
13 "Bad usage\n"
14 "\t%s [-b base] [-d dev] [-t type] adr [data]\n"
15 "\n"
16 "Read/write registers in Winbond SuperIO parts\n"
17 "base is the base address for the chip (default: 0x2e)\n"
18 "dev is the sub-device to talk to (default: -1/global)\n"
19 "type is the chip type (i = ITE, w = WinBond)\n"
20 "adr is the register to read/write\n"
21 "data is the data to write to adr\n", name);
22 exit(1);
23 }
24
25 int
26 main(int argc, char **argv) {
27 int fd, base, dev, type, adr, data, ch;
28 char *progname;
29
30 type = 'w';
31 base = 0x2e;
32 dev = -1;
33
34 progname = argv[0];
35
36 while ((ch = getopt(argc, argv, "b:d:t:")) != -1) {
37 switch (ch) {
38 case 'b':
39 base = strtol(optarg, NULL, 0) & 0xffff;
40 break;
41
42 case 'd':
43 dev = strtol(optarg, NULL, 0) & 0xff;
44 break;
45
46 case 't':
47 if (optarg[0] != 'w' && optarg[0] != 'i') {
48 fprintf(stderr, "type must be w or i\n\n");
49 usage(progname);
50 }
51
52 type = optarg[0];
53 break;
54
55 default:
56 usage(progname);
57 break;
58 }
59 }
60 argc -= optind;
61 argv += optind;
62
63 if (argc != 1 && argc != 2)
64 usage(progname);
65
66 if ((fd = open("/dev/io", O_RDWR)) == -1) {
67 fprintf(stderr, "Can't open /dev/io: %s\n", strerror(errno));
68 exit(1);
69 }
70
71 adr = strtol(argv[0], NULL, 0) & 0xff;
72
73 /* Enter extended function mode */
74 if (type == 'w') {
75 outb(base, 0x87);
76 outb(base, 0x87);
77 } else {
78 /* Taken from the Linux driver drivers/hwmon/it87.c */
79 outb(base, 0x87);
80 outb(base, 0x01);
81 outb(base, 0x55);
82 outb(base, 0x55);
83 }
84
85 /* Sub device to select (skip if global) */
86 if (dev != -1) {
87 outb(base, 0x07); /* Logical device select register */
88 outb(base + 1, dev & 0xff);
89 }
90
91 /* Register to access */
92 outb(base, adr);
93
94 if (argc == 2) {
95 data = strtol(argv[1], NULL, 0) & 0xff;
96 printf("Bank 0x%02x: 0x%02x <- 0x%02x\n", dev, adr, data);
97 outb(base + 1, data);
98 } else
99 printf("Bank 0x%02x: 0x%02x -> 0x%02x\n", dev, adr, inb(base + 1));
100
101 /* Exit extended function mode */
102 if (type == 'w') {
103 outb(base, 0xaa);
104 outb(base, 0xaa);
105 } else {
106 outb(base, 0x02);
107 outb(base, 0x02);
108 }
109
110 exit(0);
111 }
112