From 40a802559879af09848114f3b41817513934a23e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 15 Nov 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-11-15 --- bitsy/devuda1341.c | 58 +++++++++++++++++++--------- bitsy/sa1110dma.c | 96 ++++++++++++++++++++++++---------------------- bitsy/sa1110dma.h | 7 ++-- pc/devi82365.c | 4 +- port/latin1.h | 4 +- 5 files changed, 98 insertions(+), 71 deletions(-) diff --git a/bitsy/devuda1341.c b/bitsy/devuda1341.c index 546f41d3e4d1243a96bf603b276612c4257e3f79..25f49c08ff5feb65dc9d2f042d8e99a6492786cb 100644 --- a/bitsy/devuda1341.c +++ b/bitsy/devuda1341.c @@ -132,6 +132,7 @@ struct Buf struct IOstate { QLock; + Lock ilock; Rendez vous; Chan *chan; /* chan of open */ int dma; /* dma chan, alloc on open, free on close */ @@ -435,15 +436,17 @@ audioenable(void) L3_init(); /* Setup the uarts */ - ppcregs->assignment &= ~(1<<18); /* Could be the other way round! */ + ppcregs->assignment &= (1<<18); /* Could be the other way round! */ gpioregs->altfunc &= ~(GPIO_SSP_TXD_o | GPIO_SSP_RXD_i | GPIO_SSP_SCLK_o | GPIO_SSP_SFRM_o); gpioregs->altfunc |= (GPIO_SSP_CLK_i); gpioregs->direction &= ~(GPIO_SSP_CLK_i); - sspregs->control0 = 0x10<<0 | 0x1<<4 | 1<<7 | 0x8<<8; + sspregs->control0 = 0xf<<0 | 0x1<<4 | 0x3<<8; sspregs->control1 = 0<<3 + 0<<4 + 1<<5; + sspregs->control0 |= 1<<7; /* enable */ + /* Enable the audio power */ audiopower(1); amplifierpower(1); @@ -458,12 +461,14 @@ audioenable(void) delay(100); print("Ser4SSSR=0x%lux\n", sspregs->status); + gpioregs->clear = EGPIO_codec_reset; + gpioregs->set = EGPIO_codec_reset; + /* Reset the chip */ data[0] = 2<<4 /* system clock */ | 1<<1 /* lsb16 */ | 1<<6 /* reset */; L3_write(UDA1341_L3Addr<<2 | UDA1341_STATUS, data, 1 ); - gpioregs->clear = EGPIO_codec_reset; - gpioregs->set = EGPIO_codec_reset; + delay(10); data[0] = 2<<4 /* system clock */ | 1<<1 /* lsb16 */; L3_write( (UDA1341_L3Addr<<2)|UDA1341_STATUS, data, 1 ); @@ -496,22 +501,38 @@ audioenable(void) data[1] = 0xe0 | 0<<2 | 3; /* agc time constant and output level */ L3_write(UDA1341_L3Addr<<2 | UDA1341_DATA0, data, 2 ); + /* Reset the chip */ + data[0] = 2<<4 /* system clock */ | 1<<1 /* lsb16 */ | 1<<6 /* reset */; + L3_write(UDA1341_L3Addr<<2 | UDA1341_STATUS, data, 1 ); + + delay(10); + + data[0] = 2<<4 /* system clock */ | 1<<1 /* lsb16 */; + L3_write( (UDA1341_L3Addr<<2)|UDA1341_STATUS, data, 1 ); + /* Reset done */ + if (debug) print("#A: audio enabled\n"); } static void sendaudio(IOstate *b) { - /* call this with lock held */ - if (debug) print("#A: sendaudio\n"); + /* interrupt routine calls this too */ + if (debug > 1) print("#A: sendaudio\n"); + ilock(&b->ilock); while (b->next != b->filling) { assert(b->next->nbytes); - if (dmastart(b->dma, b->next->virt, b->next->nbytes) == 0) - break; incref(&b->active); + if (dmastart(b->dma, b->next->virt, b->next->nbytes) == 0) { + decref(&b->active); + break; + } + if (debug > 1) print("#A: dmastart @%p\n", b->next); + b->next->nbytes = 0; b->next++; if (b->next == &b->buf[Nbuf]) b->next = &b->buf[0]; } + iunlock(&b->ilock); } static void @@ -519,16 +540,13 @@ audiointr(void *x, ulong) { IOstate *s = x; if (s == &audio.o) { - decref(&s->active); /* Only interrupt routine touches s->current */ - s->current->nbytes = 0; + if (debug > 1) iprint("#A: audio interrupt @%p\n", s->current); s->current++; if (s->current == &s->buf[Nbuf]) s->current = &s->buf[0]; - if (canlock((Lock*)s)) { - sendaudio(s); - unlock((Lock*)s); - } + decref(&s->active); + sendaudio(s); } wakeup(&s->vous); } @@ -598,8 +616,8 @@ audioopen(Chan *c, int omode) audio.o.chan = c; audio.o.dma = dmaalloc(0, 0, 8, 2, SSPXmitDMA, Port4SSP, audiointr, (void*)&audio.o); } - qunlock(&audio); // mxvolume(); + qunlock(&audio); if (debug) print("#A: open done\n"); break; } @@ -626,6 +644,7 @@ audioclose(Chan *c) break; case Qaudio: + if (debug > 1) print("#A: close\n"); if(c->flag & COPEN) { qlock(&audio); qlock(&audio.o); @@ -638,7 +657,7 @@ audioclose(Chan *c) /* closing the write end */ audio.amode &= ~Awrite; - while (audio.o.filling->nbytes) { + if (audio.o.filling->nbytes) { audio.o.filling++; if (audio.o.filling == &audio.o.buf[Nbuf]) audio.o.filling = &audio.o.buf[0]; @@ -827,7 +846,7 @@ audiowrite(Chan *c, void *vp, long n, vlong) break; case Qaudio: - if (debug) print("#A: write %ld\n", n); + if (debug > 1) print("#A: write %ld\n", n); if((audio.amode & Awrite) == 0) error(Emode); a = &audio.o; @@ -838,8 +857,10 @@ audiowrite(Chan *c, void *vp, long n, vlong) } while(n > 0) { /* wait if dma in progress */ - while (a->active.ref && a->filling == a->current) + while (a->active.ref && a->filling == a->current) { + if (debug > 1) print("#A: sleep\n"); sleep(&a->vous, audioqnotfull, a); + } m = Bufsize - a->filling->nbytes; if(m > n) @@ -850,6 +871,7 @@ audiowrite(Chan *c, void *vp, long n, vlong) n -= m; p += m; if(a->filling->nbytes >= Bufsize) { + if (debug > 1) print("#A: filled @%p\n", a->filling); a->filling++; if (a->filling == &a->buf[Nbuf]) a->filling = a->buf; diff --git a/bitsy/sa1110dma.c b/bitsy/sa1110dma.c index 33691eb544007cd3f97fb429a30314e86f6bf9c0..5350dc7284b924be4d2e1982b2270965d7fc108e 100644 --- a/bitsy/sa1110dma.c +++ b/bitsy/sa1110dma.c @@ -41,7 +41,8 @@ enum { }; typedef struct DMAchan { - int inuse; + int allocated; + Ref active; Rendez r; void (*intr)(void*, ulong); void *param; @@ -71,6 +72,8 @@ dmainit(void) { /* map the lcd regs into the kernel's virtual space */ dmaregs = (struct dmaregs*)mapspecial(DMAREGS, NDMA*sizeof(struct dmaregs));; + if (debug) print("dma: dmaalloc registers 0x%ux mapped at 0x%p\n", + DMAREGS, dmaregs); for (i = 0; i < NDMA; i++) { intrenable(IRQdma0+i, dmaintr, &dmaregs[i], "DMA"); } @@ -79,23 +82,26 @@ dmainit(void) { int dmaalloc(int rd, int bigendian, int burstsize, int datumsize, int device, ulong port, void (*intr)(void*, ulong), void *param) { int i; + ulong ddar; - if (debug) print("dma: dmaalloc\n"); lock(&dma); for (i = 0; i < NDMA; i++) { - if (dma.chan[i].inuse) + if (dma.chan[i].allocated) continue; - dma.chan[i].inuse++; + dma.chan[i].allocated++; unlock(&dma); - dmaregs[i].ddar = + ddar = (rd?1:0)< 1) print("dma: dmastart 0x%lux\n", status); + + if (dma.chan[chan].active.ref >= 2) { + if (debug > 1) print("\n"); return 0; + } + + if ((status & (1<dcsr_rd) & (1<dcsr_rd; + if (debug > 1) + iprint("dma: interrupt channel %d, status 0x%lux\n", i, dcsr); + if (dcsr & 1<dcsr_clr |= donebit; if (dma.chan[i].intr) - (*dma.chan[i].intr)(dma.chan[i].param, dcsr); + (*dma.chan[i].intr)(dma.chan[i].param, 3-dma.chan[i].active.ref); + /* must call interrupt routine before calling decref */ + decref(&dma.chan[i].active); + wakeup(&dma.chan[i].r); } else - print("spurious DMA interrupt, channel %d, status 0x%lux\n", i, dcsr); + iprint("spurious DMA interrupt, channel %d, status 0x%lux\n", i, dcsr); } diff --git a/bitsy/sa1110dma.h b/bitsy/sa1110dma.h index b9aaa6fd609a37221a3bc9868e5274e8bf9e600d..1778d97237adcdba83f9a40230477d3a0c30fccf 100644 --- a/bitsy/sa1110dma.h +++ b/bitsy/sa1110dma.h @@ -10,7 +10,8 @@ enum { void dmainit(void); int dmaalloc(int, int, int, int, int, ulong, void (*)(void*, ulong), void*); void dmafree(int); + ulong dmastart(int, void *, int); -ulong dmadone(int, ulong); -void dmawait(int, ulong); -int dmaidle(int chan); + +void dmawait(int); +int dmaidle(int); diff --git a/pc/devi82365.c b/pc/devi82365.c index 4ca157561087fc99c4f86d668a101ed9dd81b801..96d9e626f6268c900777a477cb558e6fd7bd0aef 100644 --- a/pc/devi82365.c +++ b/pc/devi82365.c @@ -661,14 +661,14 @@ i82365reset(void) /* look for controllers if the ports aren't already taken */ if(ioalloc(0x3E0, 2, 0, "i82365.0") >= 0){ - i82365probe(0x3E0, 0x3E1, 0); + i82365probe(0x3E0, 0x3E1, 0) || i82365probe(0x3E0, 0x3E1, 1); if(ncontroller == 0) iofree(0x3E0); } if(ioalloc(0x3E2, 2, 0, "i82365.1") >= 0){ i = ncontroller; - i82365probe(0x3E2, 0x3E3, 0); + i82365probe(0x3E2, 0x3E3, 0) || i82365probe(0x3E2, 0x3E3, 1); if(ncontroller == i) iofree(0x3E2); diff --git a/port/latin1.h b/port/latin1.h index 2ecfaecfcf5de03b6609a11affcc55b89e3a6c4c..d122e00723d822c9ecf65e506fe9886f32fe6ba6 100644 --- a/port/latin1.h +++ b/port/latin1.h @@ -57,7 +57,7 @@ "P", "P", L"ℙ", "Q", "Q", L"ℚ", "R", "R", L"ℝ", - "S", "S", L"§", + "S", "123S", L"¹²³§", "T", "-u", L"Ŧ⊨", "V", "=", L"⇐", "Y", "R", L"Ʀ", @@ -85,7 +85,7 @@ "o", "AOUaeiu", L"Å⊚Ůåœƣů", "p", "Odgrt", L"℗∂¶∏∝", "r", "\"\'O", L"”’®", - "s", "()+-0123456789=abnoprstu", L"⁽⁾⁺⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁼ª⊂ⁿº⊃√ß∍∑", + "s", "()+-0123456789=abnoprstu", L"⁽⁾⁺⁻⁰ⁱ⁲⁳⁴⁵⁶⁷⁸⁹⁼ª⊂ⁿº⊃√ß∍∑", "t", "-efmsu", L"ŧ∃∴™ς⊢", "u", "-AEGIOUaegiou", L"ʉĂĔĞĬŎŬ↑ĕğĭŏŭ", "v\"", "Uu", L"Ǚǚ",