ref: 20614fd8f8ef258b5930d849d4263487daad9014
dir: /jacksense.c/
#include <u.h> #include <libc.h> #include <bio.h> static void usage(void) { fprint(2, "usage: %s [-h hp_safe_volume] [-s sp_safe_volume]\n", argv0); exits("usage"); } void main(int argc, char **argv) { int hp, sp, lp, cmd, ctl, vol, lastvol, newvol; int debug, hpsafevol, spsafevol; u32int x, y[4], has, had, c; char *s, *a[16], tmp[32]; Biobuf *b; debug = 0; hpsafevol = 65; spsafevol = 70; ARGBEGIN{ case 'd': debug++; break; case 'h': hpsafevol = atoi(EARGF(usage())); break; case 's': spsafevol = atoi(EARGF(usage())); break; default: usage(); }ARGEND if((cmd = open("/dev/hdacmd", ORDWR)) < 0) sysfatal("%r"); if((ctl = open("/dev/audioctl", OWRITE)) < 0) sysfatal("%r"); if((vol = open("/dev/volume", ORDWR)) < 0) sysfatal("%r"); if((b = Bopen("/dev/audiostat", OREAD)) == nil) sysfatal("%r"); sp = -1; hp = -1; lp = -1; while((sp < 0 || hp < 0) && (s = Brdline(b, '\n')) != nil){ s[Blinelen(b)-1] = 0; if(tokenize(s, a, nelem(a)) < 8) continue; if(strcmp(a[0], "pin") != 0 || strcmp(a[2], "out") != 0) continue; if(strcmp(a[3], "jack") == 0 && strcmp(a[6], "hpout") == 0){ hp = atoi(a[1]); if(debug) fprint(2, "hpout pin %d\n", hp); } if(strcmp(a[3], "fix") == 0){ if(strcmp(a[6], "speaker") == 0){ sp = atoi(a[1]); if(debug) fprint(2, "speaker pin %d\n", sp); }else if(strcmp(a[4], "int") == 0){ /* fallback for built-in speakers/etc */ lp = atoi(a[1]); if(debug) fprint(2, "speaker fallback pin %d\n", sp); } } } Bterm(b); if(sp < 0) sp = lp; if(sp < 0 || hp < 0){ fprint(2, "couldn't detect pins\n"); exits("pins"); } x = 0x0f0900 | (hp<<4)<<16 | (hp>>4)<<24; had = -1; lastvol = (spsafevol < hpsafevol ? spsafevol : hpsafevol)*2/3; for(;;){ c = 0; again: if(write(cmd, &x, 4) != 4 || read(cmd, y, sizeof(y)) < 4) sysfatal("command failed: %r"); has = y[0] & (1<<31); if(has != had){ if(c++ < 2){ sleep(75); goto again; } newvol = lastvol; if(pread(vol, tmp, sizeof(tmp)-1, 0) > 0 && strncmp(tmp, "master ", 7) == 0) lastvol = atoi(tmp+7); if(had == ~0) newvol = lastvol; /* SAVE MY EARS, OK? THANKS */ if(has && newvol > hpsafevol) newvol = hpsafevol; else if(!has && newvol > spsafevol) newvol = spsafevol; if(fprint(ctl, "pin %d", has ? hp : sp) < 0) fprint(2, "vol: %r\n"); if(fprint(vol, "master 0 0") < 0) fprint(2, "vol: %r\n"); sleep(100); if(fprint(vol, "master %d %d", newvol, newvol) < 0) fprint(2, "vol: %r\n"); } had = has; sleep(300); } }