#include #include #include #include #include #define SB_PORT_RESET 0x06 #define SB_PORT_READ 0x0a #define SB_PORT_STATUS 0x0c #define SB_PORT_COMMAND 0x0c #define SB_PORT_DATA_AVAIL 0x0e #define SB_DSP_GALAXY 9 #define GALAXY_DSP_MPU 2 #define GALAXY_DSP_MPUA 4 #define GALAXY_PORT_CONFIG 0x400 #define GALAXY_CONFIG_MPU_ENABLE (1 << 21) #define GALAXY_CONFIG_MPUA_330 (1 << 20) #define BUSY_LOOPS 100000 int sbdsp_reset(long int port) { int i; outb(1, port + SB_PORT_RESET); usleep(10); outb(0, port + SB_PORT_RESET); usleep(30); for (i = BUSY_LOOPS; i; i--) if (inb(port + SB_PORT_DATA_AVAIL) & 0x80) { if (inb(port + SB_PORT_READ) == 0xaa) return 0; break; } return 1; } int sbdsp_command(long int port, unsigned char val) { int i; for (i = BUSY_LOOPS; i; i--) if ((inb(port + SB_PORT_STATUS) & 0x80) == 0) { outb(val, port + SB_PORT_COMMAND); return 0; } return 1; } int galaxy_set(long int port, unsigned char cmd, int set) { if (sbdsp_command(port, SB_DSP_GALAXY) != 0) return 1; if (sbdsp_command(port, cmd) != 0) return 1; return sbdsp_command(port, set ? 255 : 0); } int main(int argc, char *argv[]) { long int port = 0x220; uint32_t conf = 0x887C0101; unsigned char val; char *s; int c = getopt(argc, argv, "p:"); if (c != -1) { if (c != 'p') goto usage; port = strtol(optarg, &s, 0); if (*s || (port != 0x220 && port != 0x240)) goto usage; } if (optind < argc) { conf = strtol(argv[optind++], &s, 16); if (*s) goto usage; } if (optind < argc) { usage: printf("usage: %s [-p ] [value]\n", argv[0]); return EXIT_FAILURE; } if (iopl(3) != 0) goto iopl; if (sbdsp_reset(port) != 0) { printf("could not find board\n"); return EXIT_FAILURE; } if (galaxy_set(port, GALAXY_DSP_MPU, conf & GALAXY_CONFIG_MPU_ENABLE) != 0) goto set; if (galaxy_set(port, GALAXY_DSP_MPUA, conf & GALAXY_CONFIG_MPUA_330) != 0) { set: printf("could not set board\n"); return EXIT_FAILURE; } val = inb(port + GALAXY_PORT_CONFIG + 4); outb(val | 0x80, port + GALAXY_PORT_CONFIG + 4); usleep(100); outb(conf, port + GALAXY_PORT_CONFIG + 3); conf >>= 8; outb(conf, port + GALAXY_PORT_CONFIG + 2); conf >>= 8; outb(conf, port + GALAXY_PORT_CONFIG + 1); conf >>= 8; outb(conf, port + GALAXY_PORT_CONFIG); outb(val & 0x7f, port + GALAXY_PORT_CONFIG + 4); if (iopl(0) != 0) { iopl: perror ("iopl"); return EXIT_FAILURE; } return EXIT_SUCCESS; }