diff wbread/wbread.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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wbread/wbread.c	Thu Oct 20 16:48:24 2011 +1030
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <machine/cpufunc.h>
+#include <unistd.h>
+
+#define VPERLSB 0.008
+#define MAXDIG (VPERLSB * 256)
+
+#define WB_ADR	0x5
+#define WB_DATA	0x6
+
+void
+usage(char *name) {
+    fprintf(stderr,
+	    "Bad usage\n"
+	    "\t%s [-b base]\n"
+	    "\n"
+	    "Read/write registers in Winbond SuperIO parts\n"
+	    "base is the base address for the chip (default: 0x290)\n"
+	    "adr is the register to read/write\n"
+	    "data is the data to write to adr\n", name);
+    exit(1);
+}
+
+int
+readwb(int base, int adr) {
+    /* Register to access */
+    outb(base + WB_ADR, adr);
+
+    return(inb(base + WB_DATA));
+}
+
+void
+writewb(int base, int adr, int val) {
+    /* Register to access */
+    outb(base + WB_ADR, adr);
+
+    outb(base + WB_DATA, val);
+}
+
+float
+raw2volt(int val, float r1, float r2) {
+    float digval, result;
+    
+    digval = val * VPERLSB;
+    result = digval * ((r1 + r2) / r2);
+    return(result);
+}
+
+float
+raw2negvolt(int val, float r1, float r2) {
+    return((val * 0.008 - 2.048)/(r2 / (r1 + r2))) + 2.048;
+}
+
+float
+raw2rpm(int val, int divisor) {
+    return(1360000 / (float)(val) / divisor);
+}
+
+int
+raw2divisor(int val) {
+    return(1 << val);
+}
+
+int
+main(int argc, char **argv) {
+    int	fd, base, ch, tmp;
+    char *progname;
+    
+    base = 0x290;
+    
+    progname = argv[0];
+    
+    while ((ch = getopt(argc, argv, "b:")) != -1) {
+	switch (ch) {
+	    case 'b':
+		base = strtol(optarg, NULL, 0) & 0xffff;
+		break;
+		    
+	    default:
+		usage(progname);
+		break;
+	}
+    }
+    argc -= optind;
+    argv += optind;
+	
+    if ((fd = open("/dev/io", O_RDWR)) == -1) {
+	fprintf(stderr, "Can't open /dev/io: %s\n", strerror(errno));
+	exit(1);
+    }
+
+    printf("3V3 = %.2f V\n", raw2volt(readwb(base, 0x23), 34000, 34000));
+    printf("-12V = %.2f V\n", raw2negvolt(readwb(base, 0x26), 232000, 10000));
+    tmp = (readwb(base, 0x47) & 0xc0) >> 6;
+    tmp |= (readwb(base, 0x5d) & 0x40) >> 4;
+    tmp = raw2divisor(tmp);
+    printf("CPU fan = %.0f rpm (divisor %d)\n", raw2rpm(readwb(base, 0x29), tmp), tmp);
+    exit(0);
+}
+