#include #include /* * 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; }