M pc/devlml.c => pc/devlml.c +57 -45
@@ 11,33 11,34 @@
// Lml 22 driver
enum{
+ Qdir,
Q819,
Q856,
Qreg,
- Qvideo,
+ Qjvideo,
Qjframe,
};
-static Dirtab viddir[]={
-// name, qid, size, mode
- "vid819", {Q819}, 0, 0644,
- "vid856", {Q856}, 0, 0644,
- "vidreg", {Qreg}, 0, 0644,
- "video", {Qvideo}, 0, 0666,
+static Dirtab lmldir[]={
+// name, qid, size, mode
+ "lml819", {Q819}, 0, 0644,
+ "lml856", {Q856}, 0, 0644,
+ "lmlreg", {Qreg}, 0, 0644,
+ "jvideo", {Qjvideo}, 0, 0666,
"jframe", {Qjframe}, 0, 0666,
};
CodeData * codeData;
-int currentBuffer;
-int currentBufferLength;
+int currentBuffer;
+int currentBufferLength;
void * currentBufferPtr;
-int frameNo;
+int frameNo;
Rendez sleeper;
-int singleFrame;
-int bufferPrepared;
-int hdrPos;
-int nopens;
+int singleFrame;
+int bufferPrepared;
+int hdrPos;
+int nopens;
uchar q856[3];
static FrameHeader frameHeader = {
@@ 455,14 456,13 @@ vwrite(Chan *, void *va, long count, vlong pos) {
static void lmlintr(Ureg *, void *);
static void
-vidreset(void)
+lmlreset(void)
{
ulong regpa;
int i;
pcidev = pcimatch(nil, PCI_VENDOR_ZORAN, PCI_DEVICE_ZORAN_36067);
if (pcidev == nil) {
- print("No zr36067 found.\n");
return;
}
codeData = (CodeData*)xspanalloc(sizeof(CodeData), BY2PG, 0);
@@ 472,7 472,7 @@ vidreset(void)
}
print("Installing Motion JPEG driver %s\n", MJPG_VERSION);
- print("Buffer size %ux\n", sizeof(CodeData));
+ print("Buffer at 0x%.8lux, size 0x%.8ux\n", codeData, sizeof(CodeData));
// Get access to DMA memory buffer
memset(codeData, 0xAA, sizeof(CodeData));
@@ 491,7 491,7 @@ vidreset(void)
pciPhysBaseAddr = (void *)(pcidev->mem[0].bar & ~0x0F);
- print("zr36067 found at %lux\n", pciPhysBaseAddr);
+ print("zr36067 found at 0x%.8lux", pciPhysBaseAddr);
regpa = upamalloc(pcidev->mem[0].bar & ~0x0F, pcidev->mem[0].size, 0);
if (regpa == 0) {
@@ 499,6 499,7 @@ vidreset(void)
return;
}
pciBaseAddr = (ulong)KADDR(regpa);
+ print(", mapped at 0x%.8lux\n", pciBaseAddr);
// make sure the device will respond to mem accesses
// (pcicmd_master | pcicmd_memory) -- probably superfluous
@@ 510,30 511,29 @@ vidreset(void)
// Interrupt handler
intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf);
- print("LML33 Installed\n");
return;
}
static Chan*
-vidattach(char *spec)
+lmlattach(char *spec)
{
return devattach('V', spec);
}
static int
-vidwalk(Chan *c, char *name)
+lmlwalk(Chan *c, char *name)
{
- return devwalk(c, name, viddir, nelem(viddir), devgen);
+ return devwalk(c, name, lmldir, nelem(lmldir), devgen);
}
static void
-vidstat(Chan *c, char *dp)
+lmlstat(Chan *c, char *dp)
{
- devstat(c, dp, viddir, nelem(viddir), devgen);
+ devstat(c, dp, lmldir, nelem(lmldir), devgen);
}
static Chan*
-vidopen(Chan *c, int omode)
+lmlopen(Chan *c, int omode)
{
c->aux = 0;
switch(c->qid.path){
@@ 541,7 541,7 @@ vidopen(Chan *c, int omode)
case Q856:
case Qreg:
break;
- case Qvideo:
+ case Qjvideo:
case Qjframe:
if (nopens)
error(Einuse);
@@ 556,28 556,34 @@ vidopen(Chan *c, int omode)
// allow one open total for these two
break;
}
- return devopen(c, omode, viddir, nelem(viddir), devgen);
+ return devopen(c, omode, lmldir, nelem(lmldir), devgen);
}
static void
-vidclose(Chan *c)
+lmlclose(Chan *c)
{
switch(c->qid.path){
case Q819:
case Q856:
case Qreg:
- case Qvideo:
+ case Qjvideo:
case Qjframe:
authclose(c);
}
}
static long
-vidread(Chan *c, void *va, long n, vlong off) {
+lmlread(Chan *c, void *va, long n, vlong voff) {
int i, d;
uchar *buf = va;
+ long off = voff;
+ long v;
+
+ switch(c->qid.path & ~CHDIR){
+
+ case Qdir:
+ return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen);
- switch(c->qid.path){
case Q819:
if (off < 0 || off + n > 0x20)
return 0;
@@ 621,24 627,30 @@ vidread(Chan *c, void *va, long n, vlong off) {
break;
case 4:
if (off & (n-1)) return 0;
- *(long *)buf = readl(pciBaseAddr + off);
+ v = readl(pciBaseAddr + off);
+ *(long *)buf = v;
+print("reading %lux at %lux (%lux)\n", v, pciBaseAddr + off, off);
break;
default:
return 0;
}
return n;
- case Qvideo:
+ case Qjvideo:
case Qjframe:
return vread(c, buf, n, off);
}
}
static long
-vidwrite(Chan *c, void *va, long n, vlong off) {
+lmlwrite(Chan *c, void *va, long n, vlong off) {
int i;
uchar *buf = va;
- switch(c->qid.path){
+ switch(c->qid.path & ~CHDIR){
+
+ case Qdir:
+ error(Eperm);
+
case Q819:
if (off < 0 || off + n > 0x20)
return 0;
@@ 680,28 692,28 @@ vidwrite(Chan *c, void *va, long n, vlong off) {
return 0;
}
return n;
- case Qvideo:
+ case Qjvideo:
case Qjframe:
return vwrite(c, buf, n, off);
}
}
-Dev viddevtab = {
+Dev lmldevtab = {
'V',
"video",
- vidreset,
+ lmlreset,
devinit,
- vidattach,
+ lmlattach,
devclone,
- vidwalk,
- vidstat,
- vidopen,
+ lmlwalk,
+ lmlstat,
+ lmlopen,
devcreate,
- vidclose,
- vidread,
+ lmlclose,
+ lmlread,
devbread,
- vidwrite,
+ lmlwrite,
devbwrite,
devremove,
devwstat,
M pc/devlml.h => pc/devlml.h +4 -4
@@ 12,7 12,7 @@
// driver.
// The number of uS delay in I2C state transitions (probably >= 10)
-#define I2C_DELAY 15
+#define I2C_DELAY 50
// The amount of spinning to do before the I2C bus is timed out
#define I2C_TIMEOUT 10000000
@@ 89,9 89,9 @@ typedef struct {
#define FRAGM_FINAL_B 1
#define STAT_BIT 1
-#define writel(v, a) *(ulong *)(a) = v
-#define writew(v, a) *(ushort *)(a) = v
-#define writeb(v, a) *(uchar *)(a) = v
+#define writel(v, a) (*(ulong *)(a) = (v))
+#define writew(v, a) (*(ushort *)(a) = (v))
+#define writeb(v, a) (*(uchar *)(a) = (v))
#define readl(a) (*(ulong *)(a))
#define readw(a) (*(ushort *)(a))
#define readb(a) (*(uchar *)(a))
M pc/ns16552.h => pc/ns16552.h +25 -5
@@ 14,7 14,7 @@ enum
#define uartwrreg(u,r,v) outb((u)->port + r, (u)->sticky[r] | (v))
#define uartrdreg(u,r) inb((u)->port + r)
-void ns16552setup(ulong, ulong, char*);
+void ns16552setup(ulong, ulong, char*, int);
void ns16552special(int, int, Queue**, Queue**, int (*)(Queue*, int));
void uartclock(void);
/*
@@ 93,9 93,9 @@ ns16552install(void)
already = 1;
/* first two ports are always there and always the normal frequency */
- ns16552setup(0x3F8, UartFREQ, "eia0");
+ ns16552setup(0x3F8, UartFREQ, "eia0", Ns550);
intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN);
- ns16552setup(0x2F8, UartFREQ, "eia1");
+ ns16552setup(0x2F8, UartFREQ, "eia1", Ns550);
intrenable(IrqUART1, ns16552intrx, (void*)1, BUSUNKNOWN);
addclock0link(uartclock);
@@ 133,9 133,29 @@ ns16552install(void)
port = sc->port;
for(j=0; j < sc->size; j++){
sprint(name, "eia%d%2.2d", nscard, j);
- ns16552setup(port, sc->freq, name);
+ ns16552setup(port, sc->freq, name, Ns550);
port += 8;
}
+ } else if(cistrcmp(sc->type, "turbo650") == 0){
+ /*
+ * port gives base port address for the uart
+ * irq is interrupt
+ * freq is the baud rate generator frequency
+ */
+ if(sc->freq == 0)
+ sc->freq = UartFREQ*4;
+ sprint(name, "eia%d00", nscard);
+ ns16552setup(sc->port, sc->freq, name, Ns650);
+
+ /*
+ * multiply clock speed by 4
+ */
+ if(sc->mem == 0)
+ outb(0x2c8, 0);
+ else
+ outb(sc->mem, 0);
+
+ intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN);
} else if(cistrcmp(sc->type, "com") == 0 && sc->port != 0x3F8 && sc->port != 0x2F8){
/*
* port gives base port address for the uart
@@ 145,7 165,7 @@ ns16552install(void)
if(sc->freq == 0)
sc->freq = UartFREQ;
sprint(name, "eia%d00", nscard);
- ns16552setup(sc->port, sc->freq, name);
+ ns16552setup(sc->port, sc->freq, name, Ns550);
intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN);
}
nscard++;
M port/devns16552.c => port/devns16552.c +53 -16
@@ 22,11 22,17 @@ enum
Ixmt= (1<<1), /* for xmit buffer empty */
Irstat=(1<<2), /* for change in rcv'er status */
Imstat=(1<<3), /* for change in modem status */
+ Isleep=(1<<4), /* put in sleep mode; 16C650 */
+ Ixoff= (1<<5), /* for xoff received; 16C650 */
+ Irts= (1<<6), /* for !rts asserted in auto mode; 16C650 */
+ Icts= (1<<7), /* for !cts asserted in auto mode; 16C650 */
Istat= 2, /* interrupt flag (read) */
Fenabd=(3<<6), /* on if fifo's enabled */
+ Irctsd=(1<<4), /* auto rts or cts changed state */
Fifoctl=2, /* fifo control (write) */
Fena= (1<<0), /* enable xmit/rcv fifos */
- Ftrig= (1<<6), /* trigger after 4 input characters */
+ Ftrig4= (1<<6), /* trigger after 4 input characters */
+ Ftrig24= (2<<6), /* trigger after 24 input characters */
Fclear=(3<<1), /* clear xmit & rcv fifos */
Format= 3, /* byte format */
Bits8= (3<<0), /* 8 bits/byte */
@@ 36,12 42,16 @@ enum
Pforce=(1<<5), /* force parity */
Break= (1<<6), /* generate a break */
Dra= (1<<7), /* address the divisor */
+ Ers= 0xbf, /* enable enhaced register set on 16C650 */
Mctl= 4, /* modem control */
Dtr= (1<<0), /* data terminal ready */
Rts= (1<<1), /* request to send */
Ri= (1<<2), /* ring */
Inton= (1<<3), /* turn on interrupts */
Loop= (1<<4), /* loop back */
+ Intsel=(1<<5), /* NO! open source interrupts; 16C650 */
+ Irda= (1<<6), /* infrared interface; 16C650 */
+ Cdiv= (1<<7), /* divide clock by four; 16C650 */
Lstat= 5, /* line status */
Inready=(1<<0), /* receive buffer full */
Oerror=(1<<1), /* receiver overrun */
@@ 60,12 70,20 @@ enum
Scratch=7, /* scratchpad */
Dlsb= 0, /* divisor lsb */
Dmsb= 1, /* divisor msb */
+ Efr= 2, /* enhanced features for 16C650 */
+ Eena= (1<<4), /* enable enhanced bits in normal registers */
+ Arts= (1<<6), /* auto rts */
+ Acts= (1<<7), /* auto cts */
CTLS= 023,
CTLQ= 021,
Stagesize= 1024,
Nuart= 32, /* max per machine */
+
+ Ns450= 0,
+ Ns550,
+ Ns650,
};
typedef struct Uart Uart;
@@ 79,7 97,7 @@ struct Uart
char name[NAMELEN];
uchar sticky[8]; /* sticky write register values */
- ulong port;
+ ulong port; /* io ports */
ulong freq; /* clock frequency */
uchar mask; /* bits/char */
int dev;
@@ 96,7 114,7 @@ struct Uart
Lock flock; /* fifo */
uchar fifoon; /* fifo's enabled */
- uchar nofifo; /* earlier chip version with nofifo */
+ uchar type; /* chip version */
Lock rlock; /* receive */
uchar istage[Stagesize];
@@ 207,7 225,6 @@ ns16552bits(Uart *p, int bits)
uartwrreg(p, Format, 0);
}
-
/*
* toggle DTR
*/
@@ 255,7 272,7 @@ ns16552fifoon(Uart *p)
{
ulong i, x;
- if(p->nofifo)
+ if(p->type < Ns550)
return;
x = splhi();
@@ 273,11 290,14 @@ ns16552fifoon(Uart *p)
/* turn on fifo */
p->fifoon = 1;
- uartwrreg(p, Fifoctl, Fena|Ftrig);
+ if(p->type == Ns650)
+ uartwrreg(p, Fifoctl, Fena|Ftrig24);
+ else
+ uartwrreg(p, Fifoctl, Fena|Ftrig4);
if((p->istat & Fenabd) == 0){
/* didn't work, must be an earlier chip type */
- p->nofifo = 1;
+ p->type = Ns450;
}
splx(x);
@@ 289,16 309,32 @@ ns16552fifoon(Uart *p)
static void
ns16552mflow(Uart *p, int n)
{
+
+
ilock(&p->tlock);
if(n){
- p->sticky[Iena] |= Imstat;
- uartwrreg(p, Iena, 0);
- p->modem = 1;
- p->cts = uartrdreg(p, Mstat) & Cts;
+print("mflow type %d\n", p->type);
+ if(p->type == Ns650){
+ outb(p->port + Format, 0xbf);
+ outb(p->port + Efr, Eena|Arts|Acts);
+ uartwrreg(p, Format, 0);
+ p->cts = 1;
+ } else {
+ p->sticky[Iena] |= Imstat;
+ uartwrreg(p, Iena, 0);
+ p->modem = 1;
+ p->cts = uartrdreg(p, Mstat) & Cts;
+ }
} else {
- p->sticky[Iena] &= ~Imstat;
- uartwrreg(p, Iena, 0);
- p->modem = 0;
+ if(p->type == Ns650){
+ outb(p->port + Format, 0xbf);
+ outb(p->port + Efr, Eena|Arts|Acts);
+ uartwrreg(p, Format, 0);
+ } else {
+ p->sticky[Iena] &= ~Imstat;
+ uartwrreg(p, Iena, 0);
+ p->modem = 0;
+ }
p->cts = 1;
}
iunlock(&p->tlock);
@@ 521,7 557,7 @@ ns16552setup0(Uart *p)
* called by main() to create a new duart
*/
void
-ns16552setup(ulong port, ulong freq, char *name)
+ns16552setup(ulong port, ulong freq, char *name, int type)
{
Uart *p;
@@ 535,6 571,7 @@ ns16552setup(ulong port, ulong freq, char *name)
nuart++;
p->port = port;
p->freq = freq;
+ p->type = type;
ns16552setup0(p);
}
@@ 990,7 1027,7 @@ ns16552write(Chan *c, void *buf, long n, vlong)
* It must be something I don't understand. -- presotto
*/
lock(&p->flock);
- if((p->istat & Fenabd) == 0 && p->fifoon && p->nofifo == 0)
+ if((p->istat & Fenabd) == 0 && p->fifoon && p->type < Ns550)
ns16552fifoon(p);
unlock(&p->flock);