| plan 9 kernel history: overview | file list | diff list |
1998/0317/port/devaudio.c (diff list | history)
| 1997/0408/sys/src/9/port/devaudio.c:120,125 – 1998/0317/sys/src/9/port/devaudio.c:120,128 (short | long | prev | next) | ||
| 1995/0214 | int clri16; int clri401; | |
| 1996/1024 | int dma; | |
| 1998/0317 | void (*startdma)(void); void (*intr)(void); | |
| 1995/0214 | } blaster; | |
| 1995/0119 | static void swab(uchar*); | |
| 1997/0408/sys/src/9/port/devaudio.c:140,146 – 1998/0317/sys/src/9/port/devaudio.c:143,149 | ||
| 1995/0119 | return 0; } } | |
| 1997/0327 |
| |
| 1998/0317 | /* print("#A: sbcmd (0x%.2x) timeout\n", val); /**/ | |
| 1995/0119 | return 1; } | |
| 1997/0408/sys/src/9/port/devaudio.c:156,164 – 1998/0317/sys/src/9/port/devaudio.c:159,185 | ||
| 1995/0119 | } } | |
| 1997/0327 | /* print("#A: sbread did not respond\n"); /**/ | |
| 1995/0119 |
| |
| 1998/0317 | return -1; | |
| 1995/0119 | } | |
| 1998/0317 | static int ess1688w(int reg, int val) { if(sbcmd(reg) || sbcmd(val)) return 1; return 0; } static int ess1688r(int reg) { if(sbcmd(0xC0) || sbcmd(reg)) return -1; return sbread(); } | |
| 1995/0119 | static int mxcmd(int addr, int val) { | |
| 1997/0408/sys/src/9/port/devaudio.c:321,331 – 1998/0317/sys/src/9/port/devaudio.c:342,352 | ||
| 1995/0119 | b = audio.current; if(audio.amode == Aread) { | |
| 1998/0317 | if(b) /* shouldn't happen */ | |
| 1995/0119 | putbuf(&audio.full, b); b = getbuf(&audio.empty); } else { | |
| 1998/0317 | if(b) /* shouldn't happen */ | |
| 1995/0119 | putbuf(&audio.empty, b); b = getbuf(&audio.full); } | |
| 1997/0408/sys/src/9/port/devaudio.c:333,340 – 1998/0317/sys/src/9/port/devaudio.c:354,363 | ||
| 1995/0119 | if(b == 0) goto shutdown; | |
| 1996/1024 |
| |
| 1995/0119 |
| |
| 1998/0317 | if(dmasetup(blaster.dma, b->virt, Bufsize, audio.amode == Aread) >= 0) return; print("#A: dmasetup fail\n"); putbuf(&audio.empty, b); | |
| 1995/0119 | shutdown: | |
| 1996/1024 | dmaend(blaster.dma); | |
| 1997/0408/sys/src/9/port/devaudio.c:349,355 – 1998/0317/sys/src/9/port/devaudio.c:372,378 | ||
| 1995/0119 | * start first dma */ static void | |
| 1998/0317 | sb16startdma(void) | |
| 1995/0119 | { ulong count; | |
| 1995/0221 | int speed; | |
| 1997/0408/sys/src/9/port/devaudio.c:380,385 – 1998/0317/sys/src/9/port/devaudio.c:403,499 | ||
| 1995/0214 | iunlock(&blaster); | |
| 1995/0119 | } | |
| 1998/0317 | static int ess1688reset(void) { int i; outb(blaster.reset, 3); delay(1); /* >3 υs */ outb(blaster.reset, 0); delay(1); i = sbread(); if(i != 0xAA) { print("#A: no response 0x%.2x\n", i); return 1; } if(sbcmd(0xC6)){ /* extended mode */ print("#A: barf 3\n"); return 1; } return 0; } static void ess1688startdma(void) { ulong count; int speed, x; ilock(&blaster); dmaend(blaster.dma); if(audio.amode == Awrite) ess1688reset(); if(audio.amode == Aread) sbcmd(0xD3); /* speaker off */ /* * Set the speed. */ if(audio.amode == Aread) speed = audio.livol[Vspeed]; else speed = audio.lovol[Vspeed]; if(speed < 4000) speed = 4000; else if(speed > 48000) speed = 48000; if(speed > 22000) x = 0x80|(256-(795500+speed/2)/speed); else x = 128-(397700+speed/2)/speed; ess1688w(0xA1, x & 0xFF); speed = (speed * 9) / 20; x = 256 - 7160000 / (speed * 82); ess1688w(0xA2, x & 0xFF); if(audio.amode == Aread) ess1688w(0xB8, 0x0E); /* A/D, autoinit */ else ess1688w(0xB8, 0x04); /* D/A, autoinit */ x = ess1688r(0xA8) & ~0x03; ess1688w(0xA8, x|0x01); /* 2 channels */ ess1688w(0xB9, 2); /* demand mode, 4 bytes per request */ if(audio.amode == Awrite) ess1688w(0xB6, 0); ess1688w(0xB7, 0x71); ess1688w(0xB7, 0xBC); x = ess1688r(0xB1) & 0x0F; ess1688w(0xB1, x|0x50); x = ess1688r(0xB2) & 0x0F; ess1688w(0xB2, x|0x50); if(audio.amode == Awrite) sbcmd(0xD1); /* speaker on */ count = -Bufsize; ess1688w(0xA4, count & 0xFF); ess1688w(0xA5, (count>>8) & 0xFF); x = ess1688r(0xB8); ess1688w(0xB8, x|0x05); audio.active = 1; contindma(); iunlock(&blaster); } | |
| 1995/0119 | /* * if audio is stopped, * start it up again. | |
| 1997/0408/sys/src/9/port/devaudio.c:388,398 – 1998/0317/sys/src/9/port/devaudio.c:502,512 | ||
| 1995/0119 | pokeaudio(void) { if(!audio.active) | |
| 1998/0317 | blaster.startdma(); | |
| 1995/0119 | } | |
| 1998/0317 | static void sb16intr(void) | |
| 1995/0119 | { int stat, dummy; | |
| 1997/0408/sys/src/9/port/devaudio.c:417,427 – 1998/0317/sys/src/9/port/devaudio.c:531,570 | ||
| 1995/0119 | } } | |
| 1998/0317 | static void ess1688intr(void) { int dummy; if(audio.active){ ilock(&blaster); contindma(); dummy = inb(blaster.clri8); iunlock(&blaster); audio.intr = 1; wakeup(&audio.vous); USED(dummy); } else print("#A: unexpected ess1688 interrupt\n"); } | |
| 1995/0119 | void | |
| 1998/0317 | audiosbintr(void) { /* * Carrera interrupt interface. */ blaster.intr(); } static void | |
| 1995/0804 | pcaudiosbintr(Ureg*, void*) | |
| 1995/0214 | { | |
| 1997/0327 |
| |
| 1995/0214 |
| |
| 1998/0317 | /* * x86 interrupt interface. */ blaster.intr(); | |
| 1995/0214 | } void | |
| 1997/0408/sys/src/9/port/devaudio.c:498,503 – 1998/0317/sys/src/9/port/devaudio.c:641,708 | ||
| 1995/0119 | } } | |
| 1998/0317 | static int ess1688(ISAConf* sbconf) { int i, major, minor; /* * Try for ESS1688. */ sbcmd(0xE7); /* get version */ major = sbread(); minor = sbread(); if(major != 0x68 || minor != 0x8B){ print("#A: model 0x%.2x 0x%.2x; not ESS1688 compatible\n", major, minor); return 1; } ess1688reset(); switch(sbconf->irq){ case 2: case 9: i = 0x50|(0<<2); break; case 5: i = 0x50|(1<<2); break; case 7: i = 0x50|(2<<2); break; case 10: i = 0x50|(3<<2); break; default: print("#A: bad ESS1688 irq %d\n", sbconf->irq); return 1; } ess1688w(0xB1, i); switch(sbconf->dma){ case 0: i = 0x50|(1<<2); break; case 1: i = 0xF0|(2<<2); break; case 3: i = 0x50|(3<<2); break; default: print("#A: bad ESS1688 dma %d\n", sbconf->dma); return 1; } ess1688w(0xB2, i); ess1688reset(); blaster.startdma = ess1688startdma; blaster.intr = ess1688intr; return 0; } | |
| 1997/0327 | static void | |
| 1995/0119 | audioinit(void) { | |
| 1997/0408/sys/src/9/port/devaudio.c:509,515 – 1998/0317/sys/src/9/port/devaudio.c:714,720 | ||
| 1995/0214 | sbconf.irq = 7; if(isaconfig("audio", 0, &sbconf) == 0) return; | |
| 1998/0317 | if(cistrcmp(sbconf.type, "sb16") != 0 && cistrcmp(sbconf.type, "ess1688") != 0) | |
| 1995/0214 | return; switch(sbconf.port){ case 0x220: | |
| 1997/0408/sys/src/9/port/devaudio.c:544,549 – 1998/0317/sys/src/9/port/devaudio.c:749,757 | ||
| 1995/0214 | blaster.clri401 = sbconf.port + 0x100; | |
| 1997/0327 | blaster.dma = sbconf.dma; | |
| 1995/0214 | ||
| 1998/0317 | blaster.startdma = sb16startdma; blaster.intr = sb16intr; | |
| 1996/1024 | seteisadma(blaster.dma, audiodmaintr); | |
| 1995/0214 | setvec(Int0vec+sbconf.irq, pcaudiosbintr, 0); | |
| 1995/0119 | ||
| 1997/0408/sys/src/9/port/devaudio.c:566,574 – 1998/0317/sys/src/9/port/devaudio.c:774,787 | ||
| 1995/0119 | audio.minor = sbread(); if(audio.major != 4) { | |
| 1997/0327 |
| |
| 1995/0119 |
| |
| 1998/0317 | if(audio.major != 3 || audio.minor != 1 || ess1688(&sbconf)){ print("#A: model 0x%.2x 0x%.2x; not SB 16 compatible\n", audio.major, audio.minor); return; } audio.major = 4; | |
| 1995/0119 | } | |
| 1998/0317 | ||
| 1995/0119 | /* * initialize the mixer */ | |