#include <stdio.h>
#include <stdlib.h>
/*
* This file replaces tv_i2c.c with two purposes: a) track I2C access;
* and b) emulate it in a test environment.
*
*/
#include "local.h" /* before everything else */
#include "xf86i2c.h"
#include "tester.h"
#include "test_record.h"
/* ======================================== */
RecordDevicePtr TestFindDev (char *name, I2CSlaveAddr addr)
{
RecordDevicePtr *r;
for (r = config->devices; *r; r++) {
if (strcmp ((*r)->bus, name) == 0 && (*r)->dev == addr) return (*r);
}
return NULL;
}
int TestAccessCH1 (RecordDevice *this, int subaddr)
{
int result;
if (subaddr != -1) this->current = subaddr;
if (this->current == -1) return -1;
result = this->current & 0x3f;
if (this->current & 0x40) {
this->current = (this->current & 0xc0) | ((this->current + 1) & 0x3f);
}
return result;
}
int TestAccessCH2 (RecordDevice *this, int subaddr)
{
if (subaddr != -1) this->current = subaddr;
if (this->current == -1) return -1;
return this->current & 0x7f;
}
int TestStatusCH (RecordDevice *this)
{
return -1;
}
int TestAccessPH (RecordDevice *this, int subaddr)
{
return subaddr; // FIXME
}
int TestStatusPH (RecordDevice *this)
{
return -1; // FIXME DAC
}
int TestAccessCX1 (RecordDevice *this, int subaddr)
{
int result;
if (subaddr != -1) this->current = subaddr;
if (this->current & 1) return -1;
result = this->current;
this->current = (this->current + 2) & 0xff;
return result;
}
int TestAccessCX2 (RecordDevice *this, int subaddr)
{
int result;
if (subaddr != -1) this->current = subaddr;
result = this->current & ~1;
this->current = (this->current + 2) & 0xff;
return result;
}
int TestStatusCX (RecordDevice *this)
{
return (recordReadDirect (this->zone, 0xc4, BIT8) >> 5) & 0x6;
}
/* -------- -------- */
/* On TV0 for I810 ?? */
RecordDevice TestDeviceCH1 = {
bus:"TV0", dev:0xea, zone: ZONE_CH1, current:0,
access:TestAccessCH1, status:TestStatusCH};
/* On TV1 for I830 ?? */
RecordDevice TestDeviceCH2 = {
bus:"TV1", dev:0xea, zone: ZONE_CH2, current:0,
access:TestAccessCH2, status:TestStatusCH};
/* Must be on TV0 for TDFX */
RecordDevice TestDeviceCX1 = {
bus:"TV0", dev:0x8a, zone: ZONE_CX1, current:0,
access:TestAccessCX1, status:TestStatusCX};
RecordDevice TestDeviceCX2 = {
bus:"TV1", dev:0x8a, zone: ZONE_CX2, current:0,
access:TestAccessCX2, status:TestStatusCX};
RecordDevice TestDevicePH1 = {
bus:"TV0", dev:0x88, zone: ZONE_PH1, current:0,
access:TestAccessPH, status:TestStatusPH};
RecordDevice TestDevicePH2 = {
bus:"TV1", dev:0x88, zone: ZONE_PH2, current:0,
access:TestAccessPH, status:TestStatusPH};
/* -------- -------- */
Bool tvBusOk = TRUE;
/* -------- I2C bus access -------- */
Bool TVProbeBus (I2CBusPtr bus, I2CSlaveAddr addr)
{
Bool result;
if (testopt_snoop) {
result = xf86I2CProbeAddress (bus, addr);
} else {
result = (TestFindDev (bus->BusName, addr) != NULL);
}
return result;
}
void TVWriteBus (I2CDevPtr d, I2CByte subaddr, I2CByte data)
{
RecordDevicePtr r = TestFindDev (d->pI2CBus->BusName, d->SlaveAddr);
if (testopt_snoop) {
if (!xf86I2CWriteByte (d, subaddr, data)) tvBusOk = FALSE;
} else {
if (!r) tvBusOk = FALSE;
else if (r->access (r, subaddr) == -1) {
tvBusOk = FALSE;
return;
}
}
if (!r) return;
recordWrite (r->zone, r->access (r, subaddr), data, BIT8, "out");
}
void TVWriteSeqBus (I2CDevPtr d, I2CByte subaddr, I2CByte *buf, int len)
{
RecordDevicePtr r = TestFindDev (d->pI2CBus->BusName, d->SlaveAddr);
if (testopt_snoop) {
if (!xf86I2CWriteBytes (d, subaddr, buf, len)) tvBusOk = FALSE;
} else {
if (!r) tvBusOk = FALSE;
else if (r->access (r, subaddr) == -1) {
tvBusOk = FALSE;
return;
}
}
if (!r) return;
recordWrite (r->zone, r->access (r, subaddr), *buf++, BIT8, "out");
for (len--; len > 0; len--)
recordWrite (r->zone, r->access (r, -1), *buf++, BIT8, "out");
}
void TVReadBus (I2CDevPtr d, I2CByte subaddr, I2CByte *data)
{
RecordDevicePtr r = TestFindDev (d->pI2CBus->BusName, d->SlaveAddr);
if (testopt_snoop) {
if (!xf86I2CReadByte (d, subaddr, data)) tvBusOk = FALSE;
if (!r || !tvBusOk) return;
recordWrite (r->zone, r->access (r, subaddr), *data, BIT8, "in ");
} else {
if (!r) { tvBusOk = FALSE; return; }
if (r->access (r, subaddr) == -1) { tvBusOk = FALSE; return; }
*data = recordRead (r->zone, r->access (r, subaddr), BIT8, "in ");
}
}
void TVReadSeqBus (I2CDevPtr d, I2CByte subaddr, I2CByte *buf, int len)
{
RecordDevicePtr r = TestFindDev (d->pI2CBus->BusName, d->SlaveAddr);
if (testopt_snoop) {
if (!xf86I2CWriteRead (d, &subaddr, 1, buf, len)) tvBusOk = FALSE;
if (!r || !tvBusOk) return;
recordWrite (r->zone, r->access (r, subaddr), *buf++, BIT8, "in ");
for (len--; len > 0; len--)
recordWrite (r->zone, r->access (r, -1), *buf++, BIT8, "in ");
} else {
if (!r) { tvBusOk = FALSE; return; }
if (r->access (r, subaddr) == -1) { tvBusOk = FALSE; return; }
*buf++ = recordRead (r->zone, r->access (r, subaddr), BIT8, "in ");
for (len--; len > 0; len--)
*buf++ = recordRead (r->zone, r->access (r, -1), BIT8, "in ");
}
}
void TVStatusBus (I2CDevPtr d, I2CByte *data)
{
RecordDevicePtr r = TestFindDev (d->pI2CBus->BusName, d->SlaveAddr);
if (testopt_snoop) {
if (!xf86I2CReadStatus(d, data)) tvBusOk = FALSE;
if (!r || !tvBusOk) return;
recordWrite (r->zone, r->status (r), *data, BIT8, "st ");
} else {
if (!r) tvBusOk = FALSE;
*data = recordRead (r->zone, r->status (r), BIT8, "st ");
}
}
void TVStatusSeqBus (I2CDevPtr d, I2CByte *buf, int len)
{
RecordDevicePtr r = TestFindDev (d->pI2CBus->BusName, d->SlaveAddr);
if (testopt_snoop) {
if (!xf86I2CWriteRead (d, NULL, 0, buf, len)) tvBusOk = FALSE;
if (!r || !tvBusOk) return;
recordWrite (r->zone, r->status (r), *buf++, BIT8, "st ");
for (len--; len > 0; len--)
recordWrite (r->zone, r->status (r), *buf++, BIT8, "st ");
} else {
if (!r) { tvBusOk = FALSE; return; }
*buf++ = recordRead (r->zone, r->status (r), BIT8, "st ");
for (len--; len > 0; len--)
*buf++ = recordRead (r->zone, r->status (r), BIT8, "st ");
}
}
/* -------- -------- */
I2CBusPtr TestHookBus (I2CBusPtr I2CPtr)
{
return I2CPtr;
}
syntax highlighted by Code2HTML, v. 0.9.1