/* * vaio.c - brightness (and maybe volume) control for Sony Vaio PCG-C1VE * and other related PCs. * Copyright (C) Nick Brown (nick.brown@coe.int), 2001. * GNU Public License applies (of course). * * Derived from GVaioControls by Drew Bertola * (http://gvaiocontrols.serialhacker.net/) * This version is command-line only, but can be run with setuid privileges. * * Revision history: * 2001-04-02 First release * * To build (wot, no Makefile ?): * gcc -o yourexename vaio.c */ #define BRIGHTNESS_REQ 0x96 #define BRIGHTNESS_DATA_REG 0x62 #define BRIGHTNESS_CST_REG 0x66 #include #include typedef unsigned short u16; static int verbose = 0; static int relative = 0; static int dump = 0; static int brightness = 0; static void brightness_set (u16 value) { /* * Next statement was in GVaioControls but condition doesn't always seem * to be met, so program can loop forever. */ #if 0 while (inw(BRIGHTNESS_CST_REG) & 3) { usleep(1); } #endif outw(0x81, BRIGHTNESS_CST_REG); while (inw(BRIGHTNESS_CST_REG) & 2) { usleep(1); } outw(BRIGHTNESS_REQ, BRIGHTNESS_DATA_REG); while (inw(BRIGHTNESS_CST_REG) & 2) { usleep(1); } outw(value, BRIGHTNESS_DATA_REG); while (inw(BRIGHTNESS_CST_REG) & 2) { usleep(1); } } static u16 brightness_get (void) { /* * Next statement was in GVaioControls but condition doesn't always seem * to be met, so program can loop forever. */ #if 0 while (inw(BRIGHTNESS_CST_REG) & 3) { usleep(1); } #endif outb(0x80, BRIGHTNESS_CST_REG); while (inw(BRIGHTNESS_CST_REG) & 2) { usleep(1); } outb(BRIGHTNESS_REQ, BRIGHTNESS_DATA_REG); while (inw(BRIGHTNESS_CST_REG) & 2) { usleep(1); } return (inw(BRIGHTNESS_DATA_REG) & 255); } /* * Complain about command line syntax, and exit. */ static void usage (void) { fprintf(stderr, "Usage: VAIO -b [-r] [-R] [-v] [-d] [brightness-value]\n"); fprintf(stderr, "-b: specify brightness (mandatory; later versions may use other flags)\n"); fprintf(stderr, "-d: write current value to stdout, brightness-value ignored\n"); fprintf(stderr, "-r: brightness-value is relative positive (default is absolute)\n"); fprintf(stderr, "-R: brightness-value is relative negative (default is absolute)\n"); fprintf(stderr, "-v: verbose\n"); fprintf(stderr, "brightness-value: brightness value, in range 0-255\n"); exit(0); } /* * Here we go... */ int main (int argc, char *argv []) { int i; int n_parm = 0; u16 current = 0; int value; for (i = 1; i < argc; i++) { char *argp; if ((argp = argv[i])[0] == '-') { while (*++argp) { switch (*argp) { case 'b': { brightness = 1; break; } case 'd': { dump = 1; break; } case 'r': { relative = 1; break; } case 'R': { relative = -1; break; } case 'v': { verbose = 1; break; } default: { usage(); break; } } } } else { switch (n_parm++) { case 0: { if ((sscanf(argv[i], "%d", &value)) != 1) { usage(); } break; } default: { break; } } } } if (n_parm > 1) { usage(); } if ((n_parm == 0) && (! dump)) { usage(); } if (! brightness) { usage(); } if (verbose) { fprintf(stderr, "Setting I/O permissions\n"); } ioperm(BRIGHTNESS_DATA_REG, 0x08, 1); if (dump || relative) { if (verbose) { fprintf(stderr, "Getting current brightness value..."); } current = brightness_get(); if (verbose) { fprintf(stderr, " current value %d\n", current); } } if (dump) { printf("%d\n", current); } else { int new; if (relative) { new = ((value * relative) + current); } else { new = value; } if (new > 255) { new = 255; } else if (new < 0) { new = 0; } if (verbose) { fprintf(stderr, "Setting new brightness value %d...", (u16)new); } brightness_set(new); if (verbose) { fprintf(stderr, " done\n"); } } return 1; }