#include #include #include #include #include #include #include #define VREF 1.235 #define V245 2.45 #define VDIV(a, b) (((a) + (b)) / (a)) struct avi { const char *name; double offset; double scale; } avi[14] = { { "avi0", 0.0, 1.0 }, { "VCORE", 0.0, 1.0 }, { "VCC", 0.0, VDIV(10.0, 10.0) }, { "VPWR", 0.0, VDIV(10.0, 191.0) }, { "+12V", 0.0, VDIV(10.0, 38.3) }, { "-12V", 3.33, VDIV(3.32, 60.4) }, { "GND", 0.0, 1.0 }, { "Vsb", 0.0, 2.0 }, { "Vdd", 0.0, 2.0 }, { "Vbat", 0.0, 1.0 }, { "AVdd", 0.0, 2.0 }, { "TS1", 0.0, 1.0 }, { "TS2", 0.0, 1.0 }, { "TS3", 0.0, 1.0 } }; int main(int argc, char **argv) { FILE *f; int i, j, atms, avlm; struct avi *avp; double a; double vref = VREF; f = fopen("/dev/io", "r"); if (f == NULL) err(1, "Could not open /dev/io"); outb(0x2e, 0x20); i = inb(0x2f); if (i != 0xe9) errx(1, "Expected 0xe9 for SuperIO ID, got %x", i); outb(0x2e, 0x7); outb(0x2f, 0xe); outb(0x2e, 0x60); atms = inb(0x2f) * 256; outb(0x2e, 0x61); atms |= inb(0x2f); outb(0x2e, 0x30); i = inb(0x2f); if (!(i & 1)) errx(1, "TMS not enabled"); outb(0x2e, 0x7); outb(0x2f, 0xd); outb(0x2e, 0x60); avlm = inb(0x2f) * 256; outb(0x2e, 0x61); avlm |= inb(0x2f); outb(0x2e, 0x30); i = inb(0x2f); if (!(i & 1)) errx(1, "VLM not enabled"); if (argc == 2 && !strcmp(argv[1], "-i")) { /* Magic init sequence from page 208 */ outb(atms + 0x8, 0x00); outb(atms + 0x9, 0x0f); outb(atms + 0xa, 0x08); outb(atms + 0xb, 0x04); outb(atms + 0xc, 0x35); outb(atms + 0xd, 0x05); outb(atms + 0xe, 0x05); outb(atms + 8, 0); for(i = 0; i < 3; i++) { outb(atms + 9, i); outb(atms + 0xa, 1); } outb(avlm + 7, 0x10); outb(avlm + 8, 0); for(i = 0; i < 10; i++) { outb(avlm + 9, i); outb(avlm + 0xa, 1); } for(; i < 14; i++) { outb(avlm + 9, i); outb(avlm + 0xa, 0); } return (0); } if (argc >= 2 && !strcmp(argv[1], "-r")) { vref = strtod(argv[2], NULL); } printf("VREF = %.3f V245 = %.3f\n", vref, V245); for(i = 2; i < 3; i++) { outb(atms + 9, i); printf("Temp %d (status=0x%2x) %4d C\n", i, inb(atms + 0xa), (char)inb(atms + 0xb)); } #if 0 /* The offset for the -12V is measured on AD10 */ i = 10; avp = &avi[i]; outb(avlm + 9, i); j = inb(avlm + 0x0b); a = vref * V245 * j / 256.0; avi[5].offset = a * avp->scale; #endif for(i = 1; i < 11; i++) { avp = &avi[i]; outb(avlm + 9, i); j = inb(avlm + 0x0b); a = vref * V245 * j / 256.0; printf( "Volt %2d %-5s %3d %6.3f V scale %4.1f %7.3f V +/- %6.4f V\n", i, avp->name, j, a, avp->scale, (a - avp->offset) * avp->scale + avp->offset, vref * V245 / 256.0 * avp->scale); } return (0); }