## diffname pc/devlml.c 1999/0422
## diff -e /dev/null /n/emeliedump/1999/0422/sys/src/brazil/pc/devlml.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "io.h"
#include "devlml.h"
// Lml 22 driver
enum{
Q819,
Q856,
Qi22,
Q060,
Q067,
Qstat,
Qvideo,
Qjframe,
};
static Dirtab viddir[]={
// name, qid, size, mode
"vid819", {Q819}, 0, 0644,
"vid856", {Q856}, 0, 0644,
"vidi22", {Qi22}, 0, 0644,
"vid060", {Q060}, 0, 0644,
"vid067", {Q067}, 0, 0644,
"vidstat", {Qstat}, 0, 0444,
"video", {Qvideo}, 0, 0666,
"jframe", {Qjframe}, 0, 0666,
};
CodeData * codeData;
MjpgDrv * mjpgDrv;
static void lmlintr(Ureg *ur, void *arg);
static void
vidreset(void)
{
ulong regpa;
int i;
codeData = (CodeData*)xspanalloc(sizeof(CodeData), BY2PG, 0);
if (codeData == nil) {
print("devlml: xspanalloc(%ux, %ux, 0)\n", sizeof(CodeData), BY2PG);
return;
}
print("Installing Motion JPEG driver %s\n", MJPG_VERSION);
print("Buffer size %ux\n", sizeof(CodeData));
// Get access to DMA memory buffer
memset(codeData, 0xAA, sizeof(CodeData));
strncpy(codeData->idString, MJPG_VERSION, strlen(MJPG_VERSION));
for(i = 0; i < NBUF; i++) {
codeData->statCom[i] = PADDR(&(codeData->fragmDescr[i]));
codeData->statComInitial[i] = codeData->statCom[i];
codeData->fragmDescr[i].fragmAddress =
(H33_Fragment *)PADDR(&(codeData->frag[i]));
// Length is in double words, in position 1..20
codeData->fragmDescr[i].fragmLength = (FRAGSIZE >> 1) | FRAGM_FINAL_B;
}
// Get dynamic kernel memory allocaton for the driver
if((mjpgDrv = xallocz(sizeof(MjpgDrv), 0)) == nil) {
print("LML33: can't allocate dynamic memory for MjpgDrv\n");
return;
}
if((lml33Board = xallocz(sizeof(LML33Board), 0)) == nil) {
print("LML33: can't allocate dynamic memory for lml33Board\n");
return;
}
print("initializing LML33 board...");
lml33Board->pcidev = pcimatch(nil, PCI_VENDOR_ZORAN, PCI_DEVICE_ZORAN_36067);
if (lml33Board->pcidev == nil) {
print("zr36067 not found. Install aborted.\n");
return;
}
lml33Board->pciPhysBaseAddr =
(void *)(lml33Board->pcidev->mem[0].bar & ~0x0F);
print("zr36067 found at %lux\n", lml33Board->pciPhysBaseAddr);
regpa = upamalloc(lml33Board->pcidev->mem[0].bar & ~0x0F, lml33Board->pcidev->mem[0].size, 0);
if (regpa == 0) {
print("lml: failed to map registers\n");
return;
}
lml33Board->pciBaseAddr = KADDR(regpa);
// make sure the device will respond to mem accesses
// (pcicmd_master | pcicmd_memory) -- probably superfluous
// pcicfgw32(lml33Board->pcidev, PciPCR, 0x04 | 0x02);
// set bus latency -- probably superfluous
// pcicfgw8(lml33Board->pcidev, PciLTR, 64);
// Interrupt handler
intrenable(lml33Board->pcidev->intl, lmlintr, lml33Board, lml33Board->pcidev->tbdf);
print("LML33 Installed\n");
return;
}
static Chan*
vidattach(char *spec)
{
return devattach('V', spec);
}
static int
vidwalk(Chan *c, char *name)
{
return devwalk(c, name, viddir, nelem(viddir), devgen);
}
static void
vidstat(Chan *c, char *dp)
{
devstat(c, dp, viddir, nelem(viddir), devgen);
}
static Chan*
vidopen(Chan *c, int omode)
{
c->aux = 0;
switch(c->qid.path){
case Q819:
case Q856:
case Qi22:
case Q060:
case Q067:
// allow one open per file
break;
case Qstat:
// allow many opens
break;
case Qvideo:
case Qjframe:
// allow one open total for these two
break;
}
return devopen(c, omode, viddir, nelem(viddir), devgen);
}
static void
vidclose(Chan *c)
{
switch(c->qid.path){
case Q819:
case Q856:
case Qi22:
case Q060:
case Q067:
case Qstat:
case Qvideo:
case Qjframe:
authclose(c);
}
}
static long
vidread(Chan *c, void *buf, long n, vlong off)
{
switch(c->qid.path){
case Q819:
case Q856:
case Qi22:
case Q060:
case Q067:
return chipread(c, buf, n, off);
case Qstat:
return statread(c, buf, n, off);
case Qvideo:
case Qjframe:
return videoread(c, buf, n, off);
}
}
static long
vidwrite(Chan *c, void *va, long n, vlong off)
{
}
Dev viddevtab = {
'V',
"video",
vidreset,
devinit,
vidattach,
devclone,
vidwalk,
vidstat,
vidopen,
devcreate,
vidclose,
vidread,
devbread,
vidwrite,
devbwrite,
devremove,
devwstat,
};
static void
lmlintr(Ureg *ur, void *arg)
{
LML33Board *lml33Board = (Lml33Board *)arg;
}
.
## diffname pc/devlml.c 1999/0423
## diff -e /n/emeliedump/1999/0422/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0423/sys/src/brazil/pc/devlml.c
218c
.
216d
214c
lmlintr(Ureg *ur, void *)
.
189a
switch(c->qid.path){
case Q819:
if (off < 0 || off + n > 20)
return 0;
return chipwrite(BT819Addr, buf, n, off);
case Q856:
if (off < 0xda || off + n > 0xe0)
return 0;
return chipwrite(BT856Addr, buf, n, off);
case Q060:
return post060write(buf, n, off);
case Q067:
if (off < 0 || off + n > 20 || (off & 0x3) || n != 4) return 0;
writel(*(long *)buf, pciBaseAddr + off);
return 4;
case Qvideo:
case Qjframe:
return videowrite(c, buf, n, off);
}
.
178,180c
if (off < 0 || off + n > 20 || (off & 0x3) || n != 4) return 0;
*(long *)buf = readl(pciBaseAddr + off);
return 4;
.
176a
return post060read(buf, n, off);
.
175c
if (off < 0xda || off + n > 0xe0)
return 0;
return chipread(BT856Addr, buf, n, off);
.
173a
if (off < 0 || off + n > 20)
return 0;
return chipread(BT819Addr, buf, n, off);
.
170,171c
vidread(Chan *c, void *buf, long n, vlong off) {
.
162d
159d
142,144d
137d
106c
intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf);
.
103c
// pcicfgw8(pcidev, PciLTR, 64);
.
100c
// pcicfgw32(pcidev, PciPCR, 0x04 | 0x02);
.
96c
pciBaseAddr = (ulong)KADDR(regpa);
.
91c
regpa = upamalloc(pcidev->mem[0].bar & ~0x0F, pcidev->mem[0].size, 0);
.
89c
print("zr36067 found at %lux\n", pciPhysBaseAddr);
.
81,87c
pciPhysBaseAddr = (void *)(pcidev->mem[0].bar & ~0x0F);
.
74,77d
64c
(Fragment *)PADDR(&(codeData->frag[i]));
.
46a
pcidev = pcimatch(nil, PCI_VENDOR_ZORAN, PCI_DEVICE_ZORAN_36067);
if (pcidev == nil) {
print("No zr36067 found.\n");
return;
}
.
41a
lml33_i2c_waitscl(void) {
int i;
ulong a;
for(i=0;;i++) {
a = readl(pciBaseAddr + ZR36057_I2C_BUS);
if (a & ZR36057_I2C_SCL) break;
if (i>I2C_TIMEOUT) error(Eio);
}
}
static void
lml33_i2c_start(void) {
writel(ZR36057_I2C_SCL|ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_waitscl();
lml33_i2c_pause();
writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_pause();
writel(0, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_pause();
}
static void
lml33_i2c_stop(void) {
// the clock should already be low, make sure data is
writel(0, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_pause();
// set clock high and wait for device to catch up
writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_waitscl();
lml33_i2c_pause();
// set the data high to indicate the stop bit
writel(ZR36057_I2C_SCL|ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_pause();
}
static void lml33_i2c_wrbit(int bit) {
if (bit){
writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); // set data
lml33_i2c_pause();
writel(ZR36057_I2C_SDA|ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_waitscl();
lml33_i2c_pause();
writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_pause();
} else {
writel(0, pciBaseAddr + ZR36057_I2C_BUS); // clr data
lml33_i2c_pause();
writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_waitscl();
lml33_i2c_pause();
writel(0, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_pause();
}
}
static int
lml33_i2c_rdbit(void) {
int bit;
// the clk line should be low
// ensure we are not asserting the data line
writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_pause();
// set the clock high and wait for device to catch up
writel(ZR36057_I2C_SDA|ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_waitscl();
lml33_i2c_pause();
// the data line should be a valid bit
bit = readl(pciBaseAddr+ZR36057_I2C_BUS);
if (bit & ZR36057_I2C_SDA){
bit = 1;
} else {
bit = 0;
}
// set the clock low to indicate end of cycle
writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS);
lml33_i2c_pause();
return bit;
}
static int
lml33_i2c_rdbyte(uchar *v) {
int i, ack;
uchar res;
res = 0;
for (i=0;i<8;i++){
res = res << 1;
res += lml33_i2c_rdbit();
}
ack = lml33_i2c_rdbit();
*v = res;
return ack;
}
static int
lml33_i2c_wrbyte(uchar v) {
int i, ack;
for (i=0;i<8;i++){
lml33_i2c_wrbit(v & 0x80);
v = v << 1;
}
ack = lml33_i2c_rdbit();
return ack;
}
static void
lml33_i2c_write_bytes(uchar addr, uchar sub, uchar *bytes, long num) {
int ack;
long i;
lml33_i2c_start();
ack = lml33_i2c_wrbyte(addr);
if (ack == 1) error(Eio);
ack = lml33_i2c_wrbyte(sub);
if (ack == 1) error(Eio);
for(i=0;i<num;i+=1){
ack = lml33_i2c_wrbyte(bytes[i]);
if (ack == 1) error(Eio);
}
lml33_i2c_stop();
}
static uchar
lml33_i2c_rd8(int addr, int sub)
{
int ack;
uchar msb;
lml33_i2c_start();
ack = lml33_i2c_wrbyte(addr);
if (ack == 1){
lml33_i2c_stop();
error(Eio);
}
ack = lml33_i2c_wrbyte(sub);
if (ack == 1){
lml33_i2c_stop();
error(Eio);
}
lml33_i2c_start();
ack = lml33_i2c_wrbyte(addr+1);
if (ack == 1){
lml33_i2c_stop();
error(Eio);
}
ack = lml33_i2c_rdbyte(&msb);
if (ack == 0){
lml33_i2c_stop();
error(Eio);
}
lml33_i2c_stop();
return msb;
}
/*
* The following mapping applies for the guests in the LML33
*
* Guest Device
* 0 zr36060
* uses subaddress GADR[0..1]
* 1 zr36060 START#
* 2 -
* 3 zr36060 RESET#
* 4 -
* 5 -
* 6 -
* 7 -
*/
// lml33_post_idle waits for the guest bus to become free
static int
lml33_post_idle(void) {
ulong a;
int timeout;
for(timeout = 0;;timeout += 1){
a = readl(pciBaseAddr + ZR36057_POST_OFFICE);
if ((a & ZR36057_POST_PEND) == 0)
return a;
if (timeout == GUEST_TIMEOUT)
return -1;
}
}
// lml33_post_write writes a byte to a guest using postoffice mechanism
static void
lml33_post_write(int guest, int reg, int v) {
int w;
// wait for postoffice not busy
lml33_post_idle();
// Trim the values, just in case
guest &= 0x07;
reg &= 0x07;
v &= 0xFF;
// write postoffice operation
w = ZR36057_POST_DIR + (guest<<20) + (reg<<16) + v;
writel(w, pciBaseAddr + ZR36057_POST_OFFICE);
// wait for postoffice not busy
w = lml33_post_idle();
// decide if write went ok
if (w == -1) error(Eio);
}
// lml33_post_read reads a byte from a guest using postoffice mechanism
static uchar
lml33_post_read(int guest, int reg) {
int w;
// wait for postoffice not busy
lml33_post_idle();
// Trim the values, just in case
guest &= 0x07;
reg &= 0x07;
// write postoffice operation
w = (guest<<20) + (reg<<16);
writel(w, pciBaseAddr + ZR36057_POST_OFFICE);
// wait for postoffice not busy, get result
w = lml33_post_idle();
// decide if read went ok
if (w == -1) error(Eio);
return (uchar)(w & 0xFF);
}
static void
lml33_zr060_write(int reg, int v) {
int guest_id;
guest_id = GID060;
lml33_post_write(guest_id, 1, reg>>8 & 0x03);
lml33_post_write(guest_id, 2, reg & 0xff);
lml33_post_write(guest_id, 3, v);
}
static uchar
lml33_zr060_read(int reg) {
int guest_id;
guest_id = GID060;
lml33_post_write(guest_id, 1, reg>>8 & 0x03);
lml33_post_write(guest_id, 2, reg & 0xff);
return lml33_post_read(guest_id, 3);
}
long
chipread(long addr, char *buf, long n, long off) {
long i;
for (i = 0; i < n; i++) {
*buf++ = lml33_i2c_rd8(addr, off++);
}
return i;
}
long
post060read(char *buf, long n, long off) {
long i;
for (i = 0; i < n; i++) {
*buf++ = lml33_zr060_read(off++);
}
return i;
}
static void lmlintr(Ureg *, void *);
static void
.
40a
microdelay(I2C_DELAY);
}
.
39c
static void
lml33_i2c_pause(void) {
.
31d
28d
19d
16d
## diffname pc/devlml.c 1999/0424
## diff -e /n/emeliedump/1999/0423/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0424/sys/src/brazil/pc/devlml.c
539a
if(flags & ZR36057_INTR_JPEGREP)
wakeup(&sleeper);
return;
.
538a
// Reset all interrupts from 067
writel(0xff000000, pciBaseAddr + ZR36057_INTR_STAT);
.
536,537c
lmlintr(Ureg *, void *) {
ulong flags = readl(pciBaseAddr+ZR36057_INTR_STAT);
// print("MjpgDrv_intrHandler stat=0x%08x\n", flags);
.
510c
return vwrite(c, buf, n, off);
.
505,507c
if (off < 0 || off + n > 0x200 || (off & 0x3))
return 0;
for (i = n; i >= 4; i -= 4) {
writel(*(long *)buf, pciBaseAddr + off);
buf += 4;
off += 4;
}
return n-i;
.
503c
if (off < 0 || off + n > 0x60)
return 0;
for (i = 0; i < n; i++)
if (lml33_zr060_write(off++, *buf++) < 0)
break;
return n - i;
.
501c
for (i = n; i > 0; i--)
if (lml33_i2c_wr8(BT856Addr, off++, *buf++) == 0)
break;
return n - i;
.
497c
for (i = n; i > 0; i--)
if (lml33_i2c_wr8(BT819Addr, off++, *buf++) == 0)
break;
return n - i;
.
495c
if (off < 0 || off + n > 0x20)
.
490,491c
vidwrite(Chan *c, void *va, long n, vlong off) {
int i;
uchar *buf = va;
.
485c
return vread(c, buf, n, off);
.
480,482c
if (off < 0 || off + n > 0x200 || (off & 0x3))
return 0;
for (i = n; i >= 4; i -= 4) {
*(long *)buf = readl(pciBaseAddr + off);
buf += 4;
off += 4;
}
return n-i;
.
478c
if (off < 0 || off + n > 0x60)
return 0;
for (i = 0; i < n; i++) {
if ((d = lml33_zr060_read(off++)) < 0) break;
*buf++ = d;
}
return n - i;
.
476c
for (i = 0; i < n; i++) {
if ((d = lml33_i2c_rd8(BT856Addr, off++)) < 0) break;
*buf++ = d;
}
return n - i;
.
472c
for (i = 0; i < n; i++) {
if ((d = lml33_i2c_rd8(BT819Addr, off++)) < 0) break;
*buf++ = d;
}
return n - i;
.
470c
if (off < 0 || off + n > 0x20)
.
466c
vidread(Chan *c, void *va, long n, vlong off) {
int i, d;
uchar *buf = va;
.
444a
if (nopens)
error(Einuse);
nopens = 1;
singleFrame = (c->qid.path == Qjframe) ? 1 : 0;;
currentBuffer = 0;
currentBufferLength = 0;
currentBufferPtr = 0;
frameNo = 0;
bufferPrepared = 0;
hdrPos = -1;
.
441d
381,386d
345a
static long
vwrite(Chan *, void *va, long count, vlong pos) {
// how much bytes left to transfer for the header
int hdrLeft;
char *buf = va;
//print("devlml::vwrite() count=0x%x pos=0x%x\n", count, pos);
// We just started writing, not into the header copy
if(pos==0 && hdrPos == -1) {
currentBuffer=-1;
currentBufferLength=0;
frameNo=-1;
bufferPrepared = 0;
}
// We need next buffer to fill (either because we're done with the
// current buffer) of because we're just beginning (but not into the header)
if (hdrPos == -1 && pos >= currentBufferLength) {
while((currentBuffer = getProcessedBuffer(codeData)) == -1)
sleep(&sleeper, return0, 0);
// print("current buffer %d\n",currentBuffer);
getBuffer(codeData, currentBuffer, ¤tBufferPtr, &frameNo);
// We need to receive the header now
hdrPos = 0;
}
// We're into the header processing
if (hdrPos != -1) {
// Calculate how many bytes we need to receive to fill the header
hdrLeft = sizeof(FrameHeader) - hdrPos;
// If we complete or go over the header with this count
if (count >= hdrLeft) {
// Adjust count of bytes that remain to be copied into video buffer
count = count - hdrLeft;
memmove((char*)&frameHeader + hdrPos, buf, hdrLeft);
// Make sure we have a standard LML33 header
if (frameHeader.mrkSOI == MRK_SOI
&& frameHeader.mrkAPP3==MRK_APP3
&& strcmp(frameHeader.nm,APP_NAME) == 0) {
//print("Starting new buffer len=0x%x frame=%d\n", frameHeader.frameSize, frameHeader.frameSeqNo);
// Obtain values we need for playback process from the header
currentBufferLength = frameHeader.frameSize;
} else if (singleFrame) {
currentBufferLength = FRAGSIZE;
} else {
// We MUST have header for motion video decompression
print("No frame size (APP3 marker) in MJPEG file\n");
error(Eio);
}
// Finish header processing
hdrPos = -1;
// Copy the header into the playback buffer
memmove(currentBufferPtr, (char*)&frameHeader, sizeof(FrameHeader));
// And set position just behind header for playback buffer write
pos = sizeof(FrameHeader);
} else {
memmove((char*)&frameHeader + hdrPos, buf, count);
hdrPos += count;
return count;
}
} else
hdrLeft = 0;
if(count + pos > currentBufferLength) {
count = currentBufferLength - pos;
}
memmove((char *)currentBufferPtr + pos, buf + hdrLeft, count);
pos += count;
// print("return 0x%x 0x%x\n",pos,count);
// Now is the right moment to initiate playback of the frame (if it's full)
if(pos >= currentBufferLength) {
// We have written the frame, time to display it
//print("Passing written buffer to 067\n");
prepareBuffer(codeData, currentBuffer);
bufferPrepared = 1;
}
//print("return 0x%lx 0x%x 0x%x 0x%x\n",pos,count,hdrLeft+count,currentBufferLength);
return hdrLeft + count;
}
.
343c
prevFrame = frameNo;
// We get to the end of the current buffer, also covers just
// open file, since 0 >= -1
if(hdrPos == -1 && pos >= currentBufferLength) {
prepareBuffer(codeData, currentBuffer);
// if not the first buffer read and single frame mode - return EOF
if (currentBuffer != -1 && singleFrame)
return 0;
while((currentBuffer = getProcessedBuffer(codeData)) == -1)
sleep(&sleeper, return0, 0);
currentBufferLength = getBuffer(codeData, currentBuffer,
¤tBufferPtr, &frameNo);
pos = 0; // ??????????????
// print("getBufffer %d -> %d 0x%x %d\n",currentBuffer, currentBufferLength, currentBufferPtr, frameNo);
if(frameNo != (prevFrame + 1) % 256)
print("Frames out of sequence: %d %d\n", prevFrame, frameNo);
// Fill in APP marker fields here
thetime = todget();
frameHeader.sec = (ulong)(thetime / 1000000000LL);
frameHeader.usec = (ulong)(thetime % 1000000000LL) / 1000;
frameHeader.frameSize = currentBufferLength - 2 + sizeof(FrameHeader);
frameHeader.frameSeqNo++;
frameHeader.frameNo = frameNo;
hdrPos=0;
}
if (hdrPos != -1) {
hdrLeft = sizeof(FrameHeader) - hdrPos;
// Write the frame size here
if (count >= hdrLeft) {
memmove(buf, (char*)&frameHeader + hdrPos, hdrLeft);
retcount += hdrLeft;
cpcount = count - hdrLeft;
pos = sizeof(frameHeader.mrkSOI);
hdrPos = -1;
} else {
memmove(buf, (char*)&frameHeader + hdrPos, count);
hdrPos += count;
return count;
}
}
if(cpcount + pos > currentBufferLength)
cpcount = currentBufferLength - pos;
memmove(buf + retcount, (char *)currentBufferPtr + pos, cpcount);
retcount += cpcount;
//pr_debug("return %d %d\n",cpcount,retcount);
return retcount;
.
340,341c
static long
vread(Chan *, void *va, long count, vlong pos) {
int prevFrame;
// how much bytes left to transfer for the header
int hdrLeft;
// Count of bytes that we need to copy into buf from code-buffer
// (different from count only while in header reading mode)
int cpcount = count;
// Count of bytes that we copied into buf altogether and will return
int retcount=0;
vlong thetime;
uchar *buf = va;
//print("devlml::vread() count=%ld pos=%lld\n", count, pos);
// If we just begin reading a file, pos would never be 0 otherwise
if (pos == 0 && hdrPos == -1) {
currentBuffer = -1;
currentBufferLength = 0;
frameNo = -1;
.
336,338c
static int
getBuffer(CodeData *this, int bufferNo, void** bufferPtr, int* frameNo) {
int codeLength;
if(this->statCom[bufferNo] & STAT_BIT) {
*bufferPtr = (void*)this->fragmDescr[bufferNo].fragmAddress;
*frameNo = this->statCom[bufferNo] >> 24;
codeLength=((this->statCom[bufferNo] & 0x00FFFFFF) >> 1);
return codeLength;
} else
return -1;
}
.
333c
return -1;
.
330,331c
static int
getProcessedBuffer(CodeData* this){
static lastBuffer=NBUF-1;
int lastBuffer0 = lastBuffer;
while (1) {
lastBuffer = (lastBuffer+1) % NBUF;
if(this->statCom[lastBuffer]&STAT_BIT)
return lastBuffer;
if(lastBuffer==lastBuffer0)
break;
.
326,328c
static int
prepareBuffer(CodeData * this, int bufferNo) {
if(bufferNo >= 0 && bufferNo < NBUF && (this->statCom[bufferNo] & STAT_BIT)) {
this->statCom[bufferNo] = this->statComInitial[bufferNo];
return this->fragmDescr[bufferNo].fragmLength;
} else
return -1;
}
.
314c
static int
.
311c
return lml33_post_write(guest_id, 3, v);
.
303c
static int
.
300c
return w & 0xFF;
.
298c
if (w == -1) return -1;
.
279c
static int
.
272,275c
return lml33_post_idle() == -1;
.
255c
static int
.
223a
static int
lml33_i2c_wr8(uchar addr, uchar sub, uchar msb) {
lml33_i2c_start();
if (lml33_i2c_wrbyte(addr) == 1
|| lml33_i2c_wrbyte(sub) == 1
|| lml33_i2c_wrbyte(msb) == 1)
return 0;
lml33_i2c_stop();
return 1;
}
.
213,218d
210c
return -1;
.
207,208c
if (lml33_i2c_wrbyte(addr+1) == 1
|| lml33_i2c_rdbyte(&msb) == 0){
.
199,204d
196c
return -1;
.
193,194c
if (lml33_i2c_wrbyte(addr) == 1
|| lml33_i2c_wrbyte(sub) == 1) {
.
188d
185c
static int
.
34a
int currentBuffer;
int currentBufferLength;
void * currentBufferPtr;
int frameNo;
Rendez sleeper;
int singleFrame;
int bufferPrepared;
int hdrPos;
int nopens;
static FrameHeader frameHeader = {
MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
{ 'L', 'M', 'L', '\0'},
-1, 0, 0, 0, 0
};
.
33d
## diffname pc/devlml.c 1999/0428
## diff -e /n/emeliedump/1999/0424/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0428/sys/src/brazil/pc/devlml.c
741c
return n;
.
738,739c
break;
default:
return 0;
.
736c
switch (n) {
case 1:
writeb(*buf, pciBaseAddr + off);
break;
case 2:
writew(*(short *)buf, pciBaseAddr + off);
break;
case 4:
.
726,733c
case Qreg:
.
699c
return n;
.
696,697c
break;
default:
return 0;
.
694c
switch(n) {
case 1:
*buf = readb(pciBaseAddr + off);
break;
case 2:
*(short *)buf = readw(pciBaseAddr + off);
break;
case 4:
.
683,691c
case Qreg:
.
653,654c
case Qreg:
.
626,627c
case Qreg:
.
258,340d
241,256d
26,27c
"vidreg", {Qreg}, 0, 0644,
.
16,17c
Qreg,
.
## diffname pc/devlml.c 1999/0429
## diff -e /n/emeliedump/1999/0428/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0429/sys/src/brazil/pc/devlml.c
619,622c
if (i2c_wr8(BT856Addr, off, *buf) == 0)
return 0;
switch ((int)off) {
case 0xDA:
q856[0] = *buf;
break;
case 0xDC:
q856[1] = *buf;
break;
case 0xDE:
q856[2] = *buf;
break;
}
return 1;
.
617c
if (n != 1 || off < 0xda || off + n > 0xe0)
.
613c
if (i2c_wr8(BT819Addr, off++, *buf++) == 0)
.
579c
return 1;
.
575,577c
switch ((int)off) {
case 0:
if ((d = i2c_bt856rd8()) < 0)
return 0;
*buf = d;
break;
case 0xDA:
*buf = q856[0];
break;
case 0xDC:
*buf = q856[1];
break;
case 0xDE:
*buf = q856[2];
break;
default:
return 0;
.
573c
if (n != 1)
.
568c
if ((d = i2c_rd8(BT819Addr, off++)) < 0) break;
.
234c
i2c_stop();
.
229,231c
if (i2c_wrbyte(addr) == 1
|| i2c_wrbyte(sub) == 1
|| i2c_wrbyte(msb) == 1)
.
227c
i2c_start();
.
225c
i2c_wr8(uchar addr, uchar sub, uchar msb) {
.
219c
i2c_stop();
.
213,215c
if (i2c_wrbyte(addr+1) == 1
|| i2c_rdbyte(&msb) == 0){
i2c_stop();
.
211c
i2c_start();
.
205,207c
if (i2c_wrbyte(addr) == 1
|| i2c_wrbyte(sub) == 1) {
i2c_stop();
.
203c
i2c_start();
.
199c
i2c_bt856rd8(void) {
uchar ret;
i2c_start ();
if (i2c_wrbyte(BT856Addr + 1) == 1
|| i2c_rdbyte(&ret) == 0) {
i2c_stop ();
return -1;
}
i2c_stop ();
return ret;
}
static int
i2c_rd8(int addr, int sub)
.
195c
i2c_stop();
.
191c
ack = i2c_wrbyte(bytes[i]);
.
187c
ack = i2c_wrbyte(sub);
.
184c
ack = i2c_wrbyte(addr);
.
182c
i2c_start();
.
178c
i2c_write_bytes(uchar addr, uchar sub, uchar *bytes, long num) {
.
172c
ack = i2c_rdbit();
.
168c
i2c_wrbit(v & 0x80);
.
164c
i2c_wrbyte(uchar v) {
.
156c
ack = i2c_rdbit();
.
153c
res += i2c_rdbit();
.
146c
i2c_rdbyte(uchar *v) {
.
140c
i2c_pause();
.
127,128c
i2c_waitscl();
i2c_pause();
.
123c
i2c_pause();
.
117c
i2c_rdbit(void) {
.
112c
i2c_pause();
.
109,110c
i2c_waitscl();
i2c_pause();
.
107c
i2c_pause();
.
104c
i2c_pause();
.
101,102c
i2c_waitscl();
i2c_pause();
.
99c
i2c_pause();
.
96c
static void i2c_wrbit(int bit) {
.
93c
i2c_pause();
.
88,89c
i2c_waitscl();
i2c_pause();
.
84c
i2c_pause();
.
81c
i2c_stop(void) {
.
77c
i2c_pause();
.
74c
i2c_pause();
.
70,71c
i2c_waitscl();
i2c_pause();
.
67c
i2c_start(void) {
.
55c
i2c_waitscl(void) {
.
49c
i2c_pause(void) {
.
40a
uchar q856[3];
.
## diffname pc/devlml.c 1999/0430
## diff -e /n/emeliedump/1999/0429/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0430/sys/src/brazil/pc/devlml.c
621a
if (off & (n-1)) return 0;
.
618a
if (off & (n-1)) return 0;
.
612c
if (off < 0 || off + n > 0x400)
.
408,409c
&& frameHeader.mrkAPP3 == MRK_APP3
&& strcmp(frameHeader.nm, APP_NAME) == 0) {
.
## diffname pc/devlml.c 1999/0513
## diff -e /n/emeliedump/1999/0430/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0513/sys/src/brazil/pc/devlml.c
704c
lmlwrite,
.
701,702c
lmlclose,
lmlread,
.
697,699c
lmlwalk,
lmlstat,
lmlopen,
.
695c
lmlattach,
.
693c
lmlreset,
.
689c
Dev lmldevtab = {
.
683c
case Qjvideo:
.
641c
switch(c->qid.path & ~CHDIR){
case Qdir:
error(Eperm);
.
637c
lmlwrite(Chan *c, void *va, long n, vlong off) {
.
630c
case Qjvideo:
.
624c
v = readl(pciBaseAddr + off);
*(long *)buf = v;
print("reading %lux at %lux (%lux)\n", v, pciBaseAddr + off, off);
.
580c
switch(c->qid.path & ~CHDIR){
case Qdir:
return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen);
.
578a
long off = voff;
long v;
.
576c
lmlread(Chan *c, void *va, long n, vlong voff) {
.
569c
case Qjvideo:
.
563c
lmlclose(Chan *c)
.
559c
return devopen(c, omode, lmldir, nelem(lmldir), devgen);
.
544c
case Qjvideo:
.
536c
lmlopen(Chan *c, int omode)
.
532c
devstat(c, dp, lmldir, nelem(lmldir), devgen);
.
530c
lmlstat(Chan *c, char *dp)
.
526c
return devwalk(c, name, lmldir, nelem(lmldir), devgen);
.
524c
lmlwalk(Chan *c, char *name)
.
518c
lmlattach(char *spec)
.
513d
501a
print(", mapped at 0x%.8lux\n", pciBaseAddr);
.
494c
print("zr36067 found at 0x%.8lux", pciPhysBaseAddr);
.
475c
print("Buffer at 0x%.8lux, size 0x%.8ux\n", codeData, sizeof(CodeData));
.
465d
458c
lmlreset(void)
.
37,40c
int singleFrame;
int bufferPrepared;
int hdrPos;
int nopens;
.
35c
int frameNo;
.
32,33c
int currentBuffer;
int currentBufferLength;
.
21,26c
static Dirtab lmldir[]={
// name, qid, size, mode
"lml819", {Q819}, 0, 0644,
"lml856", {Q856}, 0, 0644,
"lmlreg", {Qreg}, 0, 0644,
"jvideo", {Qjvideo}, 0, 0666,
.
17c
Qjvideo,
.
13a
Qdir,
.
## diffname pc/devlml.c 1999/0514
## diff -e /n/emeliedump/1999/0513/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0514/sys/src/brazil/pc/devlml.c
688a
print("writing %lux to %lux (%lux)\n", *(long *)buf, pciBaseAddr + off, off);
.
647a
long off = voff;
.
645c
lmlwrite(Chan *c, void *va, long n, vlong voff) {
.
## diffname pc/devlml.c 1999/0515
## diff -e /n/emeliedump/1999/0514/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0515/sys/src/brazil/pc/devlml.c
733,734c
if(flags & ZR36057_INTR_JPEGREP) {
if(debug&(DBGREAD|DBGWRIT))
print("MjpgDrv_intrHandler wakeup\n");
wakeup(&sleeper);
}
.
728c
if(debug&(DBGREAD|DBGWRIT))
print("MjpgDrv_intrHandler stat=0x%.8lux\n", flags);
.
690c
if (off & 0x3)
return 0;
.
686a
if (off & 0x1)
return 0;
.
680c
if (off < 0 || off + n > 0x400)
.
661c
return i;
.
630,632c
*(long *)buf = readl(pciBaseAddr + off);
.
616a
case Qmap:
if (off < 0)
return 0;
for (i = 0; i < n; i++) {
if (off + i > sizeof lmlmap)
break;
buf[i] = ((uchar *)&lmlmap)[off + i];
}
return i;
.
594c
return i;
.
580d
570a
nopens = 0;
.
568a
case Qmap:
authclose(c);
break;
.
542a
case Qmap:
.
513a
lmlmap.pci = pciBaseAddr;
lmlmap.dma = PADDR(codeData);
lmlmap.codedata = (ulong)codeData;
.
365c
//pr_debug&DBGREGS("return %d %d\n",cpcount,retcount);
.
324a
if(debug&DBGREAD)
pprint("devlml::wokeup\n");
.
322a
if(debug&DBGREAD)
pprint("devlml::sleep\n");
.
318a
if(debug&DBGREAD)
pprint("devlml::prepareBuffer\n");
.
309a
if(debug&DBGREAD)
pprint("devlml::first read\n");
.
306c
if(debug&DBGREAD)
pprint("devlml::vread() count=%ld pos=%lld\n", count, pos);
.
232a
if (debug&DBGREGS) pprint("i2c_rd8, failure 2\n");
.
224a
if (debug&DBGREGS) pprint("i2c_rd8, failure 1\n");
.
49a
ulong
writel(ulong v, ulong a) {
if (debug&DBGREGS)
pprint("writing %.8lux to %.8lux (%.4lux)\n",
v, a, (ulong)a-pciBaseAddr);
return *(ulong *)a = v;
}
ushort
writew(ushort v, ulong a) {
if (debug&DBGREGS)
pprint("writing %.4ux to %.8lux (%.4lux)\n",
v, a, (ulong)a-pciBaseAddr);
return *(ushort *)a = v;
}
uchar
writeb(uchar v, ulong a) {
if (debug&DBGREGS)
pprint("writing %.2ux to %.8lux (%.4lux)\n",
v, a, (ulong)a-pciBaseAddr);
return *(uchar *)a = v;
}
ulong
readl(ulong a) {
ulong v;
v = *(ulong*)a;
if (debug&DBGREGS)
pprint("reading %.8lux from %.8lux (%.4lux)\n",
v, a, (ulong)a-pciBaseAddr);
return v;
}
ushort
readw(ulong a) {
ushort v;
v = *(ushort*)a;
if (debug&DBGREGS)
pprint("reading %.4ux from %.8lux (%.4lux)\n",
v, a, (ulong)a-pciBaseAddr);
return v;
}
uchar
readb(ulong a) {
uchar v;
v = *(uchar*)a;
if (debug&DBGREGS)
pprint("reading %.2ux from %.8lux (%.4lux)\n",
v, a, (ulong)a-pciBaseAddr);
return v;
}
.
43a
struct {
ulong pci;
ulong dma;
ulong codedata;
} lmlmap;
.
26a
"lmlmap", {Qmap}, 0, 0444,
.
17a
Qmap,
.
10a
#define DBGREGS 0x1
#define DBGREAD 0x2
#define DBGWRIT 0x4
int debug = DBGREAD|DBGWRIT;
.
## diffname pc/devlml.c 1999/0517
## diff -e /n/emeliedump/1999/0515/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0517/sys/src/brazil/pc/devlml.c
752c
if (off < 0 || off + n >= 0x20)
.
710c
if (off + i >= sizeof lmlmap)
.
642a
intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf);
.
641a
for (i = 0; i < 4; i++) {
codeData->statCom[i] = codeData->statComInitial[i];
// Also memset the buffer with some fill value
memset(&(codeData->frag[i]),0x55,sizeof codeData->frag[i]);
}
.
622a
int i;
.
568c
codeData->fragdesc[i].leng = (FRAGSIZE >> 1) | FRAGM_FINAL_B;
.
565,566c
codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i]));
.
563c
codeData->statCom[i] = PADDR(&(codeData->fragdesc[i]));
.
357c
*bufferPtr = (void*)this->fragdesc[bufferNo].addr;
.
333c
return this->fragdesc[bufferNo].leng;
.
115,116c
pprint("%.8lux (%.8lux) --> %.2ux\n",
a, (ulong)a-pciBaseAddr, v);
.
104,105c
pprint("%.8lux (%.8lux) --> %.4ux\n",
a, (ulong)a-pciBaseAddr, v);
.
93,94c
pprint("%.8lux (%.8lux) --> %.8lux\n",
a, (ulong)a-pciBaseAddr, v);
.
82,83c
pprint("%.8lux (%.8lux) <-- %.2ux\n",
a, (ulong)a-pciBaseAddr, v);
.
74,75c
pprint("%.8lux (%.8lux) <-- %.4ux\n",
a, (ulong)a-pciBaseAddr, v);
.
66,67c
pprint("%.8lux (%.8lux) <-- %.8lux\n",
a, (ulong)a-pciBaseAddr, v);
.
51,56d
32,33c
"lmlreg", {Qreg}, 0x400, 0644,
"lmlmap", {Qmap}, sizeof lmlmap, 0444,
.
17a
struct {
ulong pci;
ulong dma;
ulong codedata;
} lmlmap;
.
14c
int debug = DBGREAD|DBGWRIT|DBGREGS;
.
## diffname pc/devlml.c 1999/0518
## diff -e /n/emeliedump/1999/0517/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0518/sys/src/brazil/pc/devlml.c
798a
break;
default:
return 0;
}
return n;
case Qbuf:
if (off < 0 || off + n >= sizeof *codeData)
return 0;
switch (n) {
case 1:
writeb(*buf, (ulong)codeData + off);
break;
case 2:
if (off & 0x1)
return 0;
writew(*(short *)buf, (ulong)codeData + off);
break;
case 4:
if (off & 0x3)
return 0;
writel(*(long *)buf, (ulong)codeData + off);
.
784c
if (off < 0 || off + n >= 0x400)
.
741a
case Qbuf:
if (off < 0 || off + n >= sizeof *codeData)
return 0;
switch(n) {
case 1:
*buf = readb((ulong)codeData + off);
break;
case 2:
if (off & (n-1)) return 0;
*(short *)buf = readw((ulong)codeData + off);
break;
case 4:
if (off & (n-1)) return 0;
*(long *)buf = readl((ulong)codeData + off);
break;
default:
return 0;
}
return n;
.
724c
if (off < 0 || off + n >= 0x400)
.
663a
case Qbuf:
.
657,658c
lmlclose(Chan *c) {
.
650d
644,648d
629a
case Qbuf:
.
620,622c
lmlopen(Chan *c, int omode) {
.
595c
lmlmap.statcom = PADDR(codeData->statCom);
.
567c
codeData->fragdesc[i].leng = ((sizeof codeData->frag[i]) >> 1) | FRAGM_FINAL_B;
.
564d
560,561d
529c
prepareBuffer(currentBuffer);
.
473c
getBuffer(currentBuffer, ¤tBufferPtr, &frameNo);
.
469c
while((currentBuffer = getProcessedBuffer()) == -1)
.
406c
currentBufferLength = getBuffer(currentBuffer,
.
402c
while((currentBuffer = getProcessedBuffer()) == -1)
.
396c
prepareBuffer(currentBuffer);
.
354,360c
getBuffer(int i, void** bufferPtr, int* frameNo) {
if(codeData->statCom[i] & STAT_BIT) {
*bufferPtr = (void*)(&codeData->frag[i]);
*frameNo = codeData->statCom[i] >> 24;
return (codeData->statCom[i] & 0x00FFFFFF) >> 1;
.
347c
if (lastBuffer == l)
.
345c
if (codeData->statCom[lastBuffer] & STAT_BIT)
.
339,341c
getProcessedBuffer(void){
static lastBuffer = NBUF-1;
int l = lastBuffer;
.
330,335c
prepareBuffer(int i) {
if (i >= 0 && i < NBUF && (codeData->statCom[i] & STAT_BIT)) {
codeData->statCom[i] = PADDR(&(codeData->fragdesc[i]));
return codeData->fragdesc[i].leng;
} else
return -1;
.
39a
"lmlbuf", {Qbuf}, 0, 0644,
.
29a
Qbuf,
.
20c
ulong statcom;
.
## diffname pc/devlml.c 1999/0519
## diff -e /n/emeliedump/1999/0518/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0519/sys/src/brazil/pc/devlml.c
14c
int debug = DBGREAD|DBGWRIT;
.
## diffname pc/devlml.c 1999/0520
## diff -e /n/emeliedump/1999/0519/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0520/sys/src/brazil/pc/devlml.c
873,874c
if(flags & INTR_JPEGREP) {
if ((debug&DBGINTR) || ((debug&DBGINTS) && (count++ % 128) == 0))
.
871c
writel(0xff000000, pciBaseAddr + INTR_STAT);
.
867c
if(debug&(DBGINTR))
.
865c
static count;
ulong flags = readl(pciBaseAddr+INTR_STAT);
.
773,774c
for (i = 0; i < n; i++)
if (i2c_wr8(BT819Addr, off + i, *buf++) == 0)
.
769a
case Q060:
if (off < 0 || off + n > 0x400)
return 0;
for (i = 0; i < n; i++) {
if (zr060_write(off + i, *buf++) < 0) break;
}
return i;
.
675a
case Q060:
if (off < 0 || off + n > 0x400)
return 0;
for (i = 0; i < n; i++) {
if ((d = zr060_read(off + i)) < 0) break;
*buf++ = d;
}
return i;
.
650a
case Q060:
.
639a
state = New;
.
621a
case Q060:
.
561c
for (i = 0; i < NBUF; i++) {
.
520,535d
514,518d
503,512c
if (debug&DBGWRIT)
pprint("current buffer %d\n", curbuf);
bufptr = codeData->frag[curbuf].fb;
bufpos = 0;
state = Header;
// Fall through
case Header:
if (count < sizeof(FrameHeader) - bufpos) {
memmove(bufptr, p, count);
bufptr += count;
bufpos += count;
return nbytes;
}
// Fill remainder of header
i = sizeof(FrameHeader) - bufpos;
memmove(bufptr, p, i);
bufptr += i;
bufpos += i;
p += i;
count -= i;
// verify header
if (codeData->frag[curbuf].fh.mrkSOI != MRK_SOI
|| codeData->frag[curbuf].fh.mrkAPP3 != MRK_APP3
|| strcmp(codeData->frag[curbuf].fh.nm, APP_NAME)) {
// Header is bad
pprint("devlml: header error: 0x%.4ux, 0x%.4ux, `%.4s'\n",
codeData->frag[curbuf].fh.mrkSOI,
codeData->frag[curbuf].fh.mrkAPP3,
codeData->frag[curbuf].fh.nm);
state = Error;
return p - (char *)va;
}
fragsize = codeData->frag[curbuf].fh.frameSize;
if (fragsize <= sizeof(FrameHeader)
|| fragsize > sizeof(Fragment)) {
pprint("devlml: frame size error: 0x%.8ux\n",
fragsize);
state = Error;
return p - (char *)va;
}
state = Body;
// Fall through
case Body:
if (count < fragsize - bufpos) {
memmove(bufptr, p, count);
bufptr += count;
bufpos += count;
return nbytes;
}
i = fragsize - bufpos;
memmove(bufptr, p, i);
bufptr += i;
bufpos += i;
p += i;
count -= i;
// We have written the frame, time to display it
i = prepareBuffer(curbuf);
if (debug&DBGWRIT)
pprint("Sending buffer %d: %d\n", curbuf, i);
state = New;
break;
case Error:
return 0;
.
457,501c
p = (char *)va;
while (count > 0) {
switch (state) {
case New:
while((curbuf = getProcessedBuffer()) == -1) {
if (debug&DBGWRIT)
pprint("devlml::sleep\n");
sleep(&sleeper, return0, 0);
.
452,455c
vwrite(Chan *, void *va, long nbytes, vlong) {
static int bufpos;
static char *bufptr;
static int curbuf;
static int fragsize;
char *p;
long count = nbytes;
int i;
.
449a
*/
.
414c
pprint("Frames out of sequence: %d %d\n", prevFrame, frameNo);
.
412c
// pprint("getBufffer %d -> %d 0x%x %d\n",currentBuffer, currentBufferLength, currentBufferPtr, frameNo);
.
407,408c
currentBufferLength = getBuffer(currentBuffer, &frameNo);
currentBufferPtr = (void*)(&codeData->frag[currentBuffer]);
.
366a
vread(Chan *, void *va, long nbytes, vlong) {
static int bufpos;
static char *bufptr;
static int curbuf;
static int fragsize;
static int frameno;
static int frameprev;
char *p;
long count = nbytes;
int i;
vlong thetime;
p = (char *)va;
while (count > 0) {
switch (state) {
case New:
while((curbuf = getProcessedBuffer()) == -1)
sleep(&sleeper, return0, 0);
fragsize = getBuffer(curbuf, &frameno);
if (debug & DBGREAD)
pprint("devlml: got read buf %d, fr %d, size %d\n",
curbuf, frameNo, fragsize);
if(frameno != (frameprev + 1) % 256)
pprint("Frames out of sequence: %d %d\n",
frameno, frameprev);
frameprev = frameno;
// Fill in APP marker fields here
thetime = todget();
frameHeader.sec = (ulong)(thetime / 1000000000LL);
frameHeader.usec = (ulong)(thetime % 1000000000LL) / 1000;
frameHeader.frameSize = fragsize - 2 + sizeof(FrameHeader);
frameHeader.frameSeqNo++;
frameHeader.frameNo = frameno;
bufpos = 0;
state = Body;
bufptr = (char *)(&frameHeader);
// Fall through
case Header:
i = sizeof(FrameHeader) - bufpos;
if (count <= i) {
memmove(p, bufptr, count);
bufptr += count;
bufpos += count;
return nbytes;
}
memmove(p, bufptr, i);
count -= i;
p += i;
bufpos = 2;
bufptr = codeData->frag[curbuf].fb;
state = Body;
// Fall through
case Body:
i = fragsize - bufpos;
if (count <= i) {
memmove(p, bufptr, count);
bufptr += count;
bufpos += count;
return nbytes;
}
memmove(p, bufptr, i);
count -= i;
p += i;
// Allow reuse of current buffer
prepareBuffer(curbuf);
state = New;
break;
case Error:
return 0;
}
}
}
/*
static long
.
359d
356c
getBuffer(int i, int* frameNo) {
.
331a
post_idle(void) {
ulong a;
int timeout;
for (timeout = 0; timeout < GUEST_TIMEOUT; timeout++){
a = readl(pciBaseAddr + POST_OFFICE);
if ((a & POST_PEND) == 0)
return a;
}
pprint("post_idle timeout\n");
return -1;
}
// post_write writes a byte to a guest using postoffice mechanism
int
post_write(unsigned int guest, unsigned int reg, unsigned int v) {
int w;
// wait for postoffice not busy
post_idle();
// Trim the values, just in case
guest &= 0x07;
reg &= 0x07;
v &= 0xFF;
// write postoffice operation
w = POST_DIR | (guest<<20) | (reg<<16) | v;
writel(w, pciBaseAddr + POST_OFFICE);
// wait for postoffice not busy
return post_idle() == -1;
}
// post_read reads a byte from a guest using postoffice mechanism
int
post_read(int guest, int reg) {
int w;
// wait for postoffice not busy
post_idle();
// Trim the values, just in case
guest &= 0x07;
reg &= 0x07;
// write postoffice operation
w = (guest<<20) + (reg<<16);
writel(w, pciBaseAddr + POST_OFFICE);
// wait for postoffice not busy, get result
w = post_idle();
// decide if read went ok
if (w == -1) return -1;
return w & 0xFF;
}
static int
zr060_write(int reg, int v) {
if (post_write(GID060, 1, (reg>>8) & 0x03)
|| post_write(GID060, 2, reg & 0xff)
|| post_write(GID060, 3, v))
return -1;
}
static int
zr060_read(int reg) {
if (post_write(GID060, 1, (reg>>8) & 0x03)
|| post_write(GID060, 2, reg & 0xff))
return -1;
return post_read(GID060, 3);
}
static int
.
330a
/*
* The following mapping applies for the guests in the LML33
*
* Guest Device
* 0 zr36060
* uses subaddress GADR[0..1]
* 1 zr36060 START#
* 2 -
* 3 zr36060 RESET#
* 4 -
* 5 -
* 6 -
* 7 -
*/
// post_idle waits for the guest bus to become free
.
264c
for (i = 0; i < num; i++) {
.
241c
for (i = 0; i < 8; i++) {
.
225c
for (i = 0; i < 8; i++) {
.
213c
writel(I2C_SDA, pciBaseAddr + I2C_BUS);
.
205,206c
bit = readl(pciBaseAddr+I2C_BUS);
if (bit & I2C_SDA){
.
200c
writel(I2C_SDA|I2C_SCL, pciBaseAddr + I2C_BUS);
.
196c
writel(I2C_SDA, pciBaseAddr + I2C_BUS);
.
185c
writel(0, pciBaseAddr + I2C_BUS);
.
182c
writel(I2C_SCL, pciBaseAddr + I2C_BUS);
.
180c
writel(0, pciBaseAddr + I2C_BUS); // clr data
.
177c
writel(I2C_SDA, pciBaseAddr + I2C_BUS);
.
174c
writel(I2C_SDA|I2C_SCL, pciBaseAddr + I2C_BUS);
.
172c
writel(I2C_SDA, pciBaseAddr + I2C_BUS); // set data
.
166c
writel(I2C_SCL|I2C_SDA, pciBaseAddr + I2C_BUS);
.
161c
writel(I2C_SCL, pciBaseAddr + I2C_BUS);
.
157c
writel(0, pciBaseAddr + I2C_BUS);
.
150c
writel(0, pciBaseAddr + I2C_BUS);
.
147c
writel(I2C_SCL, pciBaseAddr + I2C_BUS);
.
143c
writel(I2C_SCL|I2C_SDA, pciBaseAddr + I2C_BUS);
.
133,137c
for (i = 0; i < I2C_TIMEOUT; i++)
if (readl(pciBaseAddr + I2C_BUS) & I2C_SCL)
return;
error(Eio);
.
131d
57a
State state = New;
.
47a
typedef enum {
New,
Header,
Body,
Error,
} State;
.
36a
"lml060", {Q060}, 0x400, 0644,
.
25a
Q060,
.
15a
#define DBGREGS 0x01
#define DBGREAD 0x02
#define DBGWRIT 0x04
#define DBG819 0x08
#define DBGINTR 0x10
#define DBGINTS 0x20
int debug = DBGREAD;
.
11,14c
static void * pciPhysBaseAddr;
static ulong pciBaseAddr;
static Pcidev * pcidev;
.
## diffname pc/devlml.c 1999/0521
## diff -e /n/emeliedump/1999/0520/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0521/sys/src/brazil/pc/devlml.c
826a
for (i = 0; i < NBUF; i++)
codeData->statCom[i] = PADDR(&(codeData->fragdesc[i]));
.
820,825d
815a
case Qjvideo:
.
814d
803a
int i;
.
714a
if (singleFrame) {
state = Error;
return nbytes - count;
}
.
705d
699c
i = fragsize - bufpos;
if (count < i) {
.
694c
return nbytes - count;
.
686c
return nbytes - count;
.
552,637d
550d
542a
if (singleFrame) {
state = Error;
return nbytes - count;
}
.
530c
if (count < i) {
.
525c
bufptr = codeData->frag[curbuf].fb + 2;
.
510c
state = Header;
.
501a
if (fragsize <= 0 || fragsize > sizeof(Fragment)) {
pprint("Wrong sized fragment, %d (ignored)\n",
fragsize);
prepareBuffer(curbuf);
break;
}
.
498,500c
if (frameno != (frameprev + 1) % 256)
pprint("Frame out of sequence: %d %d\n",
frameprev, frameno);
.
492c
while ((curbuf = getProcessedBuffer()) == -1)
.
71,72d
65,67d
22c
int debug = 0;
.
## diffname pc/devlml.c 1999/0522
## diff -e /n/emeliedump/1999/0521/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0522/sys/src/brazil/pc/devlml.c
701a
// LMLSEG
memset(&segbuf, 0, sizeof(segbuf));
segbuf.attr = SG_PHYSICAL;
segbuf.name = smalloc(NAMELEN);
snprint(segbuf.name, NAMELEN, "lmlmjpg");
segbuf.pa = PADDR(codeData);
segbuf.size = sizeof(CodeData);
addphysseg(&segbuf);
memset(&segreg, 0, sizeof(segreg));
segreg.attr = SG_PHYSICAL;
segreg.name = smalloc(NAMELEN);
snprint(segreg.name, NAMELEN, "lmlregs");
segreg.pa = (ulong)regpa;
segreg.size = pcidev->mem[0].size;
addphysseg(&segreg);
//
.
649a
// LMLSEG
Physseg segbuf;
Physseg segreg;
//
.
## diffname pc/devlml.c 1999/0525
## diff -e /n/emeliedump/1999/0522/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0525/sys/src/brazil/pc/devlml.c
979a
#endif
.
906a
#ifdef MEMMAP
.
898a
#endif
.
897a
#ifdef MEMMAP
.
889a
#endif
.
804a
#ifdef MEMMAP
.
796a
#endif
.
795a
#ifdef MEMMAP
.
786a
#endif
.
778a
#ifdef MEMMAP
.
758a
#endif
.
751a
#ifdef MEMMAP
.
722c
if (addphysseg(&segreg) == -1) {
print("lml: physsegment: lmlmjpg\n");
return;
}
.
713,714c
segbuf.size = cdsize;
if (addphysseg(&segbuf) == -1) {
print("lml: physsegment: lmlmjpg\n");
return;
}
.
705a
#endif
.
702a
#ifdef MEMMAP
.
671a
codeData->physaddr = PADDR(&(codeData->statCom[0]));
.
668c
print("Buffer at 0x%.8lux, size 0x%.8lux\n", codeData, cdsize);
.
663c
print("devlml: xspanalloc(%lux, %ux, 0)\n", cdsize, BY2PG);
.
661c
cdsize = (sizeof(CodeData) + BY2PG - 1) & ~(BY2PG - 1);
codeData = (CodeData*)xspanalloc(cdsize, BY2PG, 0);
.
654a
ulong cdsize;
.
434a
#endif
.
102,112d
85a
ulong
readl(ulong a) {
ulong v;
v = *(ulong*)a;
if (debug&DBGREGS)
pprint("%.8lux (%.8lux) --> %.8lux\n",
a, (ulong)a-pciBaseAddr, v);
return v;
}
.
77a
#ifndef MEMMAP
#define writel(v, a) *(ulong *)(a) = (v)
#define readl(a) *(ulong*)(a)
#else
.
51a
#endif
.
45a
#ifdef MEMMAP
.
39a
#endif
.
33a
#ifdef MEMMAP
.
30a
#endif
.
25a
#ifdef MEMMAP
.
## diffname pc/devlml.c 1999/0526
## diff -e /n/emeliedump/1999/0525/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0526/sys/src/brazil/pc/devlml.c
938,1013d
936a
case Qjcount:
.
935d
928,930d
922a
case Qjcount:
return vcount(c, buf, n, off);
.
832,919d
822,824d
814a
case Qjcount:
.
803,812d
784a
case Qjcount:
.
774,782d
745,746d
717,723d
707,713d
685c
codeData->physaddr = PADDR(codeData->statCom);
.
664d
661d
643c
pprint("Sending buffer %d\n", curbuf);
.
641c
codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf]));
.
580,584c
curbuf = getbuffer();
.
553c
codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf]));
.
511c
codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf]));
.
504c
if (!singleFrame && frameno != (frameprev + 1) % 256)
.
498,500c
curbuf = getbuffer();
frameNo = codeData->statCom[curbuf] >> 24;
fragsize = (codeData->statCom[curbuf] & 0x00ffffff)>>1;
.
352,480d
245,348c
// reads always return one byte: the next available buffer number
if (nbytes <= 0) return 0;
*p = getbuffer();
.
240,243c
static long
vcount(Chan *, void *va, long nbytes, vlong) {
char *p = (char *)va;
.
232,237c
return 0;
.
216,230c
for (;;) {
last = (last+1) % NBUF;
if (codeData->statCom[last] & STAT_BIT)
return last;
if (last == l)
sleep(&sleeper, return0, 0);
.
212,214c
getbuffer(void){
static last = NBUF-1;
int l = last;
.
97,210d
88,95d
85d
59a
"jcount", {Qjcount}, 0, 0444,
.
50,57d
45a
Qjcount,
.
36,43d
26,33d
15,20c
#define DBGREAD 0x01
#define DBGWRIT 0x02
#define DBGINTR 0x04
#define DBGINTS 0x08
.
## diffname pc/devlml.c 1999/0527
## diff -e /n/emeliedump/1999/0526/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0527/sys/src/brazil/pc/devlml.c
330c
print("lml: physsegment: lmlregs\n");
return;
}
memset(&seggrab, 0, sizeof(seggrab));
seggrab.attr = SG_PHYSICAL;
seggrab.name = smalloc(NAMELEN);
snprint(seggrab.name, NAMELEN, "lmlgrab");
seggrab.pa = (ulong)PADDR(grabpa);
seggrab.size = grablen;
if (addphysseg(&seggrab) == -1) {
print("lml: physsegment: lmlgrab\n");
.
283c
print("MJPG buffer at 0x%.8lux, size 0x%.8lux\n", codeData, cdsize);
print("Grab buffer at 0x%.8lux, size 0x%.8lux\n", grabpa, grablen);
.
281a
grablen = (720 * 480 * 2 * 2 + BY2PG - 1) & ~(BY2PG - 1);
grabpa = (ulong *)xspanalloc(grablen, BY2PG, 0);
if (grabpa == nil) {
print("devlml: xspanalloc(%lux, %ux, 0)\n", grablen, BY2PG);
return;
}
*grabpa = PADDR(grabpa);
.
268a
ulong *grabpa;
ulong grablen;
.
266a
Physseg seggrab;
.
## diffname pc/devlml.c 1999/0529
## diff -e /n/emeliedump/1999/0527/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0529/sys/src/brazil/pc/devlml.c
356c
return;
.
350c
seggrab.pa = PADDR(grabbuf);
.
299c
codeData->pamjpg = PADDR(codeData->statCom);
codeData->pagrab = PADDR(grabbuf);
.
295c
print("Grab buffer at 0x%.8lux, size 0x%.8lux\n", grabbuf, grablen);
.
292a
memset(grabbuf, 0x33, grablen);
.
291d
285,287c
grablen = GRABDATASIZE;
grabbuf = xspanalloc(grablen, BY2PG, 0);
if (grabbuf == nil) {
.
278c
cdsize = CODEDATASIZE;
.
270c
void *grabbuf;
.
## diffname pc/devlml.c 1999/0531
## diff -e /n/emeliedump/1999/0529/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0531/sys/src/brazil/pc/devlml.c
123c
thetime = todget(nil);
.
## diffname pc/devlml.c 1999/0601
## diff -e /n/emeliedump/1999/0531/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0601/sys/src/brazil/pc/devlml.c
436,443c
error(Eperm);
return 0;
.
432,434c
lmlwrite(Chan *, void *, long, vlong) {
.
423,425d
406,407d
391,396d
387a
// allow one open
.
385,386d
381d
357a
// Interrupt handler
intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf);
.
323,325d
309,310d
299d
292,293d
89,259d
54,60d
51,52d
40,46d
33,34d
26,27d
## diffname pc/devlml.c 1999/0610
## diff -e /n/emeliedump/1999/0601/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0610/sys/src/brazil/pc/devlml.c
263,265c
vlong thetime;
fstart = jpgframeno & 0x00000003;
for (;;) {
jpgframeno++;
fno = jpgframeno & 0x00000003;
if (codeData->statCom[fno] & STAT_BIT)
break;
if (fno == fstart) {
if (debug & DBGINTR)
print("Spurious lml jpg intr?\n");
return;
}
}
thetime = todget(nil);
jpgheader[fno].sec = (ulong)(thetime / 1000000000LL);
jpgheader[fno].usec = (ulong)(thetime % 1000000000LL) / 1000;
jpgheader[fno].frameSize =
(codeData->statCom[fno] & 0x00ffffff) >> 1;
jpgheader[fno].frameSeqNo = codeData->statCom[fno] >> 24;
jpgheader[fno].frameNo = jpgframeno;
wakeup(&sleepjpg);
.
253c
ulong fstart, fno;
.
218,219c
case Qjpg:
return jpgread(c, buf, n, off);
/* case Qraw:
return rawread(c, buf, n, off);
*/
.
206a
authclose(c);
.
203,205c
case Qjpg:
jpgopens = 0;
break;
/* case Qraw:
rawopens = 0;
break;
*/
.
194a
/* case Qraw:
// allow one open
if (rawopens)
error(Einuse);
rawopens = 1;
rawframeno = 0;
break;
*/
.
193c
jpgopens = 1;
jpgframeno = 0;
prepbuf();
.
191c
if (jpgopens)
.
189c
case Qjpg:
.
114a
prepbuf();
.
108,113d
81d
71a
prepbuf(void) {
int i;
for (i = 0; i < NBUF; i++) {
codeData->statCom[i] = PADDR(&(codeData->fragdesc[i]));
codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i]));
// Length is in double words, in position 1..20
codeData->fragdesc[i].leng = ((sizeof codeData->frag[i]) >> 1) | FRAGM_FINAL_B;
}
}
static void
.
68a
/*
static long
rawread(Chan *, void *va, long nbytes, vlong) {
// reads should be at least sizeof(FrameHeader) long
// Frameno is the number of the buffer containing the data
if (nbytes < sizeof(FrameHeader)) return 0;
sleep(&sleepraw, return0, 0);
memmove(va, &rawheader, sizeof rawheader);
return sizeof rawheader;
}
*/
.
63,66c
// reads should be of size 1 or sizeof(FrameHeader)
// Frameno is the number of the buffer containing the data
bufno = getbuffer();
if (nbytes == sizeof(FrameHeader)) {
memmove(va, &jpgheader[bufno], sizeof jpgheader[bufno]);
return sizeof jpgheader[bufno];
}
if (nbytes == 1) {
*(char *)va = bufno;
return 1;
}
return 0;
.
60,61c
jpgread(Chan *, void *va, long nbytes, vlong) {
int bufno;
.
54c
sleep(&sleepjpg, return0, 0);
.
39c
int jpgopens;
//int rawopens;
.
37c
Rendez sleepjpg;
//Rendez sleepraw;
.
35a
static ulong jpgframeno;
//static ulong rawframeno;
//static FrameHeader rawheader;
static FrameHeader jpgheader[NBUF] = {
{
MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
{ 'L', 'M', 'L', '\0'},
-1, 0, 0, 0, 0
}, {
MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
{ 'L', 'M', 'L', '\0'},
-1, 0, 0, 0, 0
}, {
MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
{ 'L', 'M', 'L', '\0'},
-1, 0, 0, 0, 0
}, {
MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
{ 'L', 'M', 'L', '\0'},
-1, 0, 0, 0, 0
}
};
.
34c
static CodeData * codeData;
.
30,31c
// name, qid, size, mode
"lmljpg", {Qjpg}, 0, 0444,
// "lmlraw", {Qraw}, 0, 0444,
.
26c
Qjpg,
// Qraw,
.
## diffname pc/devlml.c 1999/0819
## diff -e /n/emeliedump/1999/0610/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0819/sys/src/brazil/pc/devlml.c
218c
intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf, "lml");
.
## diffname pc/devlml.c 1999/0909
## diff -e /n/emeliedump/1999/0819/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0909/sys/src/brazil/pc/devlml.c
354c
jpgheader[fno].nsec = (ulong)(thetime % 1000000000LL);
.
## diffname pc/devlml.c 1999/0915
## diff -e /n/emeliedump/1999/0909/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/0915/sys/src/brazil/pc/devlml.c
9a
#include "index.h"
#include "avctl.h"
#include "misc.h"
Medium *m;
AVctl *ctl = &ctlinit;
.
## diffname pc/devlml.c 1999/1005
## diff -e /n/emeliedump/1999/0915/sys/src/brazil/pc/devlml.c /n/emeliedump/1999/1005/sys/src/brazil/pc/devlml.c
10,17d
## diffname pc/devlml.c 2000/0716
## diff -e /n/emeliedump/1999/1005/sys/src/brazil/pc/devlml.c /n/emeliedump/2000/0716/sys/src/9/pc/devlml.c
338a
if(debug&(DBGINTR))
print("MjpgDrv_intrHandler stat=0x%.8lux\n", flags);
.
331,333d
20c
int debug = -1;
.
## diffname pc/devlml.c 2001/0221
## diff -e /n/emeliedump/2000/0716/sys/src/9/pc/devlml.c /n/emeliedump/2001/0221/sys/src/9/pc/devlml.c
20c
int debug = 0;
.
## diffname pc/devlml.c 2001/0527
## diff -e /n/emeliedump/2001/0221/sys/src/9/pc/devlml.c /n/emeliedump/2001/0527/sys/src/9/pc/devlml.c
20c
int debug = -1;
.
## diffname pc/devlml.c 2001/0630
## diff -e /n/emeliedump/2001/0527/sys/src/9/pc/devlml.c /n/emeliedump/2001/0630/sys/src/9/pc/devlml.c
312d
286,287c
switch((ulong)c->qid.path){
.
278d
269c
switch((ulong)c->qid.path){
.
245c
switch((ulong)c->qid.path){
.
238c
return devstat(c, db, n, lmldir, nelem(lmldir), devgen);
.
235,236c
static int
lmlstat(Chan *c, uchar *db, int n)
.
232c
return devwalk(c, nc, name, nname, lmldir, nelem(lmldir), devgen);
.
229,230c
static Walkqid*
lmlwalk(Chan *c, Chan *nc, char **name, int nname)
.
208,209c
kstrdup(&seggrab.name, "lmlgrab");
.
197,198c
kstrdup(&segreg.name, "lmlregs");
.
186,187c
kstrdup(&segbuf.name, "lmlmjpg");
.
31,33c
".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
"lmljpg", {Qjpg}, 0, 0444,
// "lmlraw", {Qraw}, 0, 0444,
.
## diffname pc/devlml.c 2001/1012
## diff -e /n/emeliedump/2001/0630/sys/src/9/pc/devlml.c /n/emeliedump/2001/1012/sys/src/9/pc/devlml.c
143a
if(isaconfig("lml", 0, &isa) == 0) {
if (debug) print("lml not in plan9.ini\n");
return;
}
.
15,16c
#define DBGREAD 0x01
#define DBGWRIT 0x02
.
## diffname pc/devlml.c 2001/1019
## diff -e /n/emeliedump/2001/1012/sys/src/9/pc/devlml.c /n/emeliedump/2001/1019/sys/src/9/pc/devlml.c
162c
print("devlml: xalloc(%lux, %ux, 0)\n", grablen, BY2PG);
.
160c
grabbuf = (void*)(((ulong*)xalloc(grablen+ BY2PG) +BY2PG-1)&~(BY2PG-1));
.
155c
print("devlml: xalloc(%lux, %ux, 0)\n", cdsize, BY2PG);
.
153c
codeData = (CodeData*)(((ulong*)xalloc(cdsize+ BY2PG) +BY2PG-1)&~(BY2PG-1));
.
## diffname pc/devlml.c 2001/1026
## diff -e /n/emeliedump/2001/1019/sys/src/9/pc/devlml.c /n/emeliedump/2001/1026/sys/src/9/pc/devlml.c
166c
print("Installing Motion JPEG driver %s, irq %d\n", MJPG_VERSION, pcidev->intl);
.
160c
grabbuf = (void*)(((ulong)xalloc(grablen+ BY2PG) +BY2PG-1)&~(BY2PG-1));
.
153c
codeData = (CodeData*)(((ulong)xalloc(cdsize+ BY2PG) +BY2PG-1)&~(BY2PG-1));
.
142a
ISAConf isa;
.
## diffname pc/devlml.c 2001/1027
## diff -e /n/emeliedump/2001/1026/sys/src/9/pc/devlml.c /n/emeliedump/2001/1027/sys/src/9/pc/devlml.c
161c
grabbuf = (void*)(((ulong)xalloc(grablen+ BY2PG) + BY2PG-1) & ~(BY2PG-1));
.
154c
codeData = (CodeData*)(((ulong)xalloc(cdsize+ BY2PG) + BY2PG-1) & ~(BY2PG-1));
.
64c
Rendez sleepjpg;
.
## diffname pc/devlml.c 2001/1101
## diff -e /n/emeliedump/2001/1027/sys/src/9/pc/devlml.c /n/emeliedump/2001/1101/sys/src/9/pc/devlml.c
351,353c
jpgheader[fno].ftime = todget(nil);
.
334d
59c
-1, 0, 0, 0
.
55c
-1, 0, 0, 0
.
51c
-1, 0, 0, 0
.
47c
-1, 0, 0, 0
.
20c
int debug = 0;
.
## diffname pc/devlml.c 2001/1102
## diff -e /n/emeliedump/2001/1101/sys/src/9/pc/devlml.c /n/emeliedump/2001/1102/sys/src/9/pc/devlml.c
217a
iprint("%.8uX: %.8uX\n", pciBaseAddr + INTR_STAT,
*((unsigned long *)(pciBaseAddr + INTR_STAT)));
.
152a
.
143a
uchar ipin, intl;
.
## diffname pc/devlml.c 2001/1106
## diff -e /n/emeliedump/2001/1102/sys/src/9/pc/devlml.c /n/emeliedump/2001/1106/sys/src/9/pc/devlml.c
358,359c
jpgheader->frameSeqNo = codeData->statCom[fno] >> 24;
jpgheader->frameNo = jpgframeno;
.
355,356c
jpgheader = (FrameHeader *)codeData->frag[fno].hdr;
jpgheader->ftime = todget(nil);
jpgheader->frameSize =
.
333a
FrameHeader *jpgheader;
.
221,223d
144d
129c
codeData->fragdesc[i].leng = (FRAGSIZE >> 1) | FRAGM_FINAL_B;
memmove(codeData->frag[i].hdr, &jpgheader, sizeof(FrameHeader)-2);
.
127c
codeData->fragdesc[i].addr = PADDR(codeData->frag[i].fb);
.
96,97c
memmove(va, jpgheader, sizeof(FrameHeader));
return sizeof(FrameHeader);
.
94a
jpgheader = (FrameHeader*)codeData->frag[bufno].hdr;
.
90a
FrameHeader *jpgheader;
.
43,60c
static FrameHeader jpgheader = {
MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
{ 'L', 'M', 'L', '\0'},
-1, 0, 0, 0
.
## diffname pc/devlml.c 2001/1107
## diff -e /n/emeliedump/2001/1106/sys/src/9/pc/devlml.c /n/emeliedump/2001/1107/sys/src/9/pc/devlml.c
341,346c
if (jpgopens && jpgmode == OREAD){
jpgheader = (FrameHeader *)(codeData->frag[fno].hdr+2);
jpgheader->frameNo = jpgframeno;
jpgheader->ftime = todget(nil);
jpgheader->frameSize =
(codeData->statCom[fno] & 0x00ffffff) >> 1;
jpgheader->frameSeqNo = codeData->statCom[fno] >> 24;
}
.
281,284c
return jpgread(c, buf, n, off, 1);
case Qraw:
return jpgread(c, buf, n, off, 0);
.
265,268d
262a
case Qraw:
.
246,253d
243a
jpgmode = omode;
.
238a
case Qraw:
.
118c
memmove(codeData->frag[i].hdr+2, &jpgheader, sizeof(FrameHeader)-2);
.
94,106d
81,82c
while ((bufno = getbuffer(nil)) == 0 && dosleep)
sleep(&sleepjpg, getbuffer, 0);
if (--bufno < 0)
return 0;
jpgheader = (FrameHeader*)(codeData->frag[bufno].hdr+2);
.
75c
jpgread(Chan *, void *va, long nbytes, vlong, int dosleep) {
.
69c
return 0;
.
67c
return last + 1;
.
60c
getbuffer(void *){
.
53a
int jpgmode;
.
33c
"lmlraw", {Qraw}, 0, 0444,
.
27c
Qraw,
.
## diffname pc/devlml.c 2001/1108
## diff -e /n/emeliedump/2001/1107/sys/src/9/pc/devlml.c /n/emeliedump/2001/1108/sys/src/9/pc/devlml.c
323,331c
statcom = lml->codedata->statCom[fno];
jpgheader = (FrameHeader *)(lml->codedata->frag[fno].hdr+2);
jpgheader->frameNo = lml->jpgframeno;
jpgheader->ftime = todget(nil);
jpgheader->frameSize = (statcom & 0x00ffffff) >> 1;
jpgheader->frameSeqNo = statcom >> 24;
wakeup(&lml->sleepjpg);
.
313,315c
lml->jpgframeno++;
fno = lml->jpgframeno & 0x00000003;
if (lml->codedata->statCom[fno] & STAT_BIT)
.
311c
fstart = lml->jpgframeno & 0x00000003;
.
304c
writel(0xff000000, lml->pciBaseAddr + INTR_STAT);
.
302c
ulong fstart, fno, flags, statcom;
LML *lml;
lml = x;
flags = readl(lml->pciBaseAddr+INTR_STAT);
.
298,300c
lmlintr(Ureg *, void *x) {
.
263,266c
case Qctl1:
i++;
case Qctl0:
if (i >= nlml)
error(Eio);
lml = lmls+i;
len = snprint(lmlinfo, sizeof lmlinfo, "lml%djpg lml%draw\nlml%d.regs 0x%lux 0x%ux\nlml%d.mjpg 0x%lux 0x%ux\n",
i, i,
i, lml->pcidev->mem[0].bar & ~0x0F, lml->pcidev->mem[0].size,
i, PADDR(lml->codedata), Codedatasize);
if (voff > len)
return 0;
if (n > len - voff)
n = len - voff;
memmove(va, lmlinfo+voff, n);
return n;
case Qjpg1:
i++;
case Qjpg0:
if (i >= nlml)
error(Eio);
return jpgread(lmls+i, buf, n, off, 1);
case Qraw1:
i++;
case Qraw0:
if (i >= nlml)
error(Eio);
return jpgread(lmls+i, buf, n, off, 0);
.
259a
i = 0;
.
258a
LML *lml;
static char lmlinfo[1024];
int len;
.
256a
int i;
.
248,250c
case Qjpg1:
case Qraw1:
i++;
case Qjpg0:
case Qraw0:
lmls[i].jpgopens = 0;
.
246a
i = 0;
.
245a
int i;
.
235,238c
lml->jpgopens = 1;
lml->jpgframeno = 0;
prepbuf(lml);
.
233c
if (i >= nlml)
error(Eio);
lml = lmls+i;
if (lml->jpgopens)
.
230,231c
case Qctl1:
i++;
case Qctl0:
if (i >= nlml)
error(Eio);
break;
case Qjpg1:
case Qraw1:
i++;
case Qjpg0:
case Qraw0:
.
228a
i = 0;
.
227a
if (omode != OREAD)
error(Eperm);
.
226a
int i;
LML *lml;
.
168,203d
163,166c
// Interrupt handler
intrenable(pcidev->intl, lmlintr, lml, pcidev->tbdf, "lml");
.
161c
memset(&segbuf, 0, sizeof(segbuf));
segbuf.attr = SG_PHYSICAL;
sprint(name, "lml%d.regs", nlml);
kstrdup(&segbuf.name, name);
segbuf.pa = (ulong)regpa;
segbuf.size = pcidev->mem[0].size;
if (addphysseg(&segbuf) == -1) {
print("lml: physsegment: %s\n", name);
return;
}
.
159c
memset(&segbuf, 0, sizeof(segbuf));
segbuf.attr = SG_PHYSICAL;
sprint(name, "lml%d.mjpg", nlml);
kstrdup(&segbuf.name, name);
segbuf.pa = PADDR(lml->codedata);
segbuf.size = Codedatasize;
if (addphysseg(&segbuf) == -1) {
print("lml: physsegment: %s\n", name);
return;
}
.
157c
regpa = upamalloc(pcidev->mem[0].bar & ~0x0F, pcidev->mem[0].size, 0);
if (regpa == 0) {
print("lml: failed to map registers\n");
return;
}
lml->pciBaseAddr = (ulong)KADDR(regpa);
print(", mapped at 0x%.8lux\n", lml->pciBaseAddr);
.
153,155c
print("zr36067 found at 0x%.8lux", pcidev->mem[0].bar & ~0x0F);
.
149,151c
prepbuf(lml);
.
142,147c
// Get access to DMA memory buffer
lml->codedata->pamjpg = PADDR(lml->codedata->statCom);
.
135,140c
print("Installing Motion JPEG driver %s, irq %d\n", MJPG_VERSION, pcidev->intl);
print("MJPG buffer at 0x%.8lux, size 0x%.8ux\n", lml->codedata, Codedatasize);
.
126,133c
pcidev = nil;
for (nlml = 0; nlml < NLML && (pcidev = pcimatch(pcidev, VENDOR_ZORAN, ZORAN_36067)); nlml++){
if(isaconfig("lml", nlml, &isa) == 0) {
if (debug) print("lml %d not in plan9.ini\n", nlml);
break;
}
lml = &lmls[nlml];
lml->pcidev = pcidev;
lml->codedata = (CodeData*)(((ulong)xalloc(Codedatasize+ BY2PG) + BY2PG-1) & ~(BY2PG-1));
if (lml->codedata == nil) {
print("devlml: xalloc(%ux, %ux, 0)\n", Codedatasize, BY2PG);
return;
}
.
124a
char name[32];
Pcidev *pcidev;
LML *lml;
.
121,123d
118,119d
109,110c
lml->codedata->fragdesc[i].leng = (FRAGSIZE >> 1) | FRAGM_FINAL_B;
memmove(lml->codedata->frag[i].hdr+2, &jpgheader, sizeof(FrameHeader)-2);
.
106,107c
lml->codedata->statCom[i] = PADDR(&(lml->codedata->fragdesc[i]));
lml->codedata->fragdesc[i].addr = PADDR(lml->codedata->frag[i].fb);
.
102c
prepbuf(LML *lml) {
.
87c
jpgheader = (FrameHeader*)(lml->codedata->frag[bufno].hdr+2);
.
82,83c
while ((bufno = getbuffer(lml)) == 0 && dosleep)
sleep(&lml->sleepjpg, getbuffer, lml);
.
79c
.
76c
jpgread(LML *lml, void *va, long nbytes, vlong, int dosleep) {
.
67c
if (lml->codedata->statCom[last] & STAT_BIT)
.
64a
lml = x;
.
63a
LML *lml;
.
61c
getbuffer(void *x){
.
49,56d
41c
int nlml;
.
38,39c
struct LML {
// Hardware
Pcidev * pcidev;
ulong pciBaseAddr;
// Allocated memory
CodeData * codedata;
// Software state
ulong jpgframeno;
int frameNo;
Rendez sleepjpg;
int jpgopens;
} lmls[NLML];
.
36c
typedef struct LML LML;
.
31,33c
".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
"lml0ctl", {Qctl0}, 0, 0666,
"lml0jpg", {Qjpg0}, 0, 0444,
"lml0raw", {Qraw0}, 0, 0444,
"lml1ctl", {Qctl1}, 0, 0666,
"lml1jpg", {Qjpg1}, 0, 0444,
"lml1raw", {Qraw1}, 0, 0444,
.
29a
#define QID(q) ((ulong)(q).path)
#define QIDLML(q) ((((ulong)(q).path)-1)>>1)
.
26,27c
Qctl0,
Qjpg0,
Qraw0,
Qctl1,
Qjpg1,
Qraw1,
.
11,14d
## diffname pc/devlml.c 2002/0109
## diff -e /n/emeliedump/2001/1108/sys/src/9/pc/devlml.c /n/emeliedump/2002/0109/sys/src/9/pc/devlml.c
321c
devinit,
devshutdown,
.
|