#include #include #include #include #include #include uint16_t *mmcr; static void W(int a, unsigned d) { mmcr[a / 2] = d; } static unsigned R(int a) { return (mmcr[a/2]); } static void waitbusy() { unsigned u, u2; int i; u = R(0xc2a); /* Make data lines input */ u &= ~0x01e0; W(0xc2a, u); W(0xc38, 0x1000); /* Clear RS */ W(0xc36, 0x0040); /* Raise DIR */ W(0xc34, 0x0800); /* Set E */ for (i = 0; i < 2000; i++) { u = R(0xc30) & 0x0100; if (u == 0) break; if (i > 30) getuid(); } W(0xc38, 0x0800); /* Clear E */ W(0xc34, 0x0800); /* Set E */ W(0xc38, 0x0800); /* Clear E */ W(0xc3a, 0x0040); /* Lower DIR */ u = R(0xc2a); /* Make data lines output */ u |= 0x001e0; W(0xc2a, u); } static int WBD(unsigned d) { unsigned u, u2; u = R(0xc30); /* Get current value */ u &= ~0x19e0; /* Mask our bits out */ u |= 0x1000; /* Set DATA and ENABLE */ u2 = u; u |= ((d >> 4) & 0xf) << 5; /* Set data bits */ u2 |= (d & 0xf) << 5; /* Set data bits */ waitbusy(); W(0xc30, u); /* plunk! */ W(0xc34, 0x0800); /* Set ENABLE */ W(0xc38, 0x0800); /* Clear ENABLE */ W(0xc30, u2); /* plunk! */ W(0xc34, 0x0800); /* Set ENABLE */ W(0xc38, 0x0800); /* Clear ENABLE */ } static int WBC(unsigned d) { unsigned u, u2; u = R(0xc30); /* Get current value */ u &= ~0x19e0; /* Mask our bits out */ u2 = u; u |= ((d >> 4) & 0xf) << 5; /* Set data bits */ u2 |= (d & 0xf) << 5; /* Set data bits */ waitbusy(); W(0xc30, u); /* plunk! */ W(0xc34, 0x0800); /* Set ENABLE */ W(0xc30, u2); /* plunk! */ W(0xc34, 0x0800); /* Set ENABLE */ W(0xc38, 0x0800); /* Clear ENABLE */ } static void WSD(char *p) { while (*p) WBD(*p++); } static void WC(unsigned d) { unsigned u; printf("WC %x\n", d & 0xf); u = R(0xc30); u &= ~0x19e0; u |= (d & 0xf) << 5; u |= 0x0800; W(0xc30, u); u &= ~0x0800; W(0xc30, u); u |= 0x0800; W(0xc30, u); } int main(int argc, char **argv) { int fd, error; int i, j; unsigned u; char buf[20]; fd = open("/dev/elan-mmcr", O_RDWR); if (fd < 0) err(1, "/dev/elan-mmcr"); mmcr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); printf("mmcr = %p\n", mmcr); printf("R 0xc20 = %x (%x)\n", R(0xc20), R(0xc20) & 0x19e0); printf("R 0xc22 = %x (%x)\n", R(0xc22), R(0xc22) & 0x0040); printf("R 0xc2a = %x (%x)\n", R(0xc2a), R(0xc2a) & 0x19e0); u = R(0xc2a); u |= 0x019e0; W(0xc2a, u); printf("R 0xc2a = %x (%x)\n", R(0xc2a), R(0xc2a) & 0x19e0); printf("R 0xc2c = %x (%x)\n", R(0xc2c), R(0xc2c) & 0x0040); u = R(0xc2c); u |= 0x0040; W(0xc2c, u); printf("R 0xc2c = %x (%x)\n", R(0xc2c), R(0xc2c) & 0x0040); WC(3); usleep(10000); WC(3); usleep(10000); WC(3); usleep(10000); WC(2); usleep(10000); WBC(0x2c); WBC(0x28); WBC(0x0c); WBC(0x01); WBC(0x01); WBC(0x80); #if 0 WBC(0x80); while (1) { WBD(random()); } #endif #if 0 WBC(0x40); for (j = 0; j < 8; j++) WBD(0x0f); for (j = 0; j < 8; j++) WBD(0x07); for (j = 0; j < 8; j++) WBD(0x03); for (j = 0; j < 8; j++) WBD(0x01); for (j = 0; j < 8; j++) WBD(0x10); for (j = 0; j < 8; j++) WBD(0x18); for (j = 0; j < 8; j++) WBD(0x1c); for (j = 0; j < 8; j++) WBD(0x1e); while (1) { for (i = 0; i < 19; i++) { WBC(0x80 + i); WBD(0xff); usleep(30000); WBC(0x80 + i); WBD(0x00); usleep(30000); WBC(0x80 + i); WBD(0x01); WBD(0x04); usleep(30000); WBC(0x80 + i); WBD(0x02); WBD(0x05); usleep(30000); WBC(0x80 + i); WBD(0x03); WBD(0x06); usleep(30000); WBC(0x80 + i); WBD(random()); WBD(0x07); usleep(30000); } WBC(0x80 + 19); WBD(random()); } #endif #if 0 WBC(0x40); WBD(0x01); WBD(0x03); WBD(0x07); WBD(0x0f); /* top left */ WBD(0x0f); WBD(0x1f); WBD(0x1f); WBD(0x1f); WBD(0x1f); WBD(0x1f); WBD(0x1f); WBD(0x0f); /* bottom left */ WBD(0x0f); WBD(0x07); WBD(0x03); WBD(0x01); WBD(0x10); WBD(0x18); WBD(0x1c); WBD(0x1e); /* top right */ WBD(0x1e); WBD(0x1f); WBD(0x1f); WBD(0x1f); WBD(0x1f); WBD(0x1f); WBD(0x1f); WBD(0x1e); /* bottom right */ WBD(0x1e); WBD(0x1c); WBD(0x18); WBD(0x10); WBD(0x00); WBD(0x00); WBD(0x00); WBD(0x00); /* mid top */ WBD(0xff); WBD(0xff); WBD(0xff); WBD(0xff); WBD(0xff); WBD(0xff); WBD(0xff); WBD(0xff); /* mid bot */ WBD(0x00); WBD(0x00); WBD(0x00); WBD(0x00); WBC(0x80); WBD(0x00); WBD(0x05); WBD(0x02); WBD(0x20); WBD(0x00); WBD(0x05); WBD(0x02); WBD(0x20); WBD(0x20); WBD(0xff); WBD(0x20); WBD(0x20); WBD(0x00); WBD(0x05); WBD(0x02); WBD(0x20); WBD(0x05); WBD(0x05); WBD(0xff); WBD(0x20); WBC(0x80 + 64); WBD(0xff); WBD(0x20); WBD(0xff); WBD(0x20); WBD(0x01); WBD(0x04); WBD(0x03); WBD(0x20); WBD(0xff); WBD(0x20); WBD(0xff); WBD(0x20); WBD(0x20); WBD(0x04); WBD(0xff); WBD(0x20); WBD(0x20); WBD(0x00); WBD(0x03); WBD(0x20); WBC(0x80 + 20); WBD(0xff); WBD(0x20); WBD(0xff); WBD(0x20); WBD(0x00); WBD(0x05); WBD(0x02); WBD(0x20); WBD(0xff); WBD(0x20); WBD(0xff); WBD(0x20); WBD(0x20); WBD(0x05); WBD(0xff); WBD(0x20); WBD(0x20); WBD(0xff); WBD(0x20); WBD(0x20); WBC(0x80 + 84); WBD(0x01); WBD(0x04); WBD(0x03); WBD(0x20); WBD(0x01); WBD(0x04); WBD(0x03); WBD(0x20); WBD(0x20); WBD(0xff); WBD(0x20); WBD(0x20); WBD(0x01); WBD(0x04); WBD(0x03); WBD(0x20); WBD(0x20); WBD(0xff); WBD(0x20); WBD(0x20); #endif #if 0 WBC(0x80 + 40); for (j = 0; j < 80; j++) WBD(j); #endif i = 0; while(1) { #if 0 sprintf(buf, "%8dabcdefghij", i++); WBC(0x80 + 20); WSD(buf); #endif #if 0 WBC(0x40); for (j = 0; j < 64; j++) WBD(j); usleep(100000); #endif #if 0 WBC(0x80 + 20); WSD("...................|"); #endif } return (0); }