/* Bits in B data register: all active low */ #define CTLR_IRQ 0x08 /* Controller rcv status (input) */ #define ST_MASK 0x30 /* mask for selecting ADB state bits */
/* Bits in ACR */ #define SR_CTRL 0x1c /* Shift register control bits */ #define SR_EXT 0x0c /* Shift on external clock */ #define SR_OUT 0x10 /* Shift out if 1 */
/* Bits in IFR and IER */ #define IER_SET 0x80 /* set bits in IER */ #define IER_CLR 0/* clear bits in IER */ #define SR_INT 0x04 /* Shift register full/empty */
/* ADB transaction states according to GMHW */ #define ST_CMD 0x00 /* ADB state: command byte */ #define ST_EVEN 0x10 /* ADB state: even data byte */ #define ST_ODD 0x20 /* ADB state: odd data byte */ #define ST_IDLE 0x30 /* ADB state: idle, nothing to send */
staticstruct adb_request *current_req; /* first request struct in the queue */ staticstruct adb_request *last_req; /* last request struct in the queue */ staticunsignedchar reply_buf[16]; /* storage for autopolled replies */ staticunsignedchar *reply_ptr; /* next byte in reply_buf or req->reply */ staticbool reading_reply; /* store reply in reply_buf else req->reply */ staticint data_index; /* index of the next byte to send from req->data */ staticint reply_len; /* number of bytes received in reply_buf or req->reply */ staticint status; /* VIA's ADB status bits captured upon interrupt */ staticbool bus_timeout; /* no data was sent by the device */ staticbool srq_asserted; /* have to poll for the device that asserted it */ static u8 last_cmd; /* the most recent command byte transmitted */ static u8 last_talk_cmd; /* the most recent Talk command byte transmitted */ static u8 last_poll_cmd; /* the most recent Talk R0 command byte transmitted */ staticunsignedint autopoll_devs; /* bits set are device addresses to poll */
/* Check for MacII style ADB */ staticint macii_probe(void)
{ if (macintosh_config->adb_type != MAC_ADB_II) return -ENODEV;
via = via1;
pr_info("adb: Mac II ADB Driver v1.0 for Unified ADB\n"); return0;
}
/* Initialize the driver */ staticint macii_init(void)
{ int err;
/* Send an ADB poll (Talk Register 0 command prepended to the request queue) */ staticvoid macii_queue_poll(void)
{ staticstruct adb_request req; unsignedchar poll_command; unsignedint poll_addr;
/* This only polls devices in the autopoll list, which assumes that *unprobeddevicesneverassertSRQ.Thatcouldhappenifadevicewas *pluggedinaftertheadbbusscan.Unpluggingitagainwillresolve *theproblem.ThisbehaviourissimilartoMacOS.
*/ if (!autopoll_devs) return;
/* The device most recently polled may not be the best device to poll *rightnow.Someotherdevice(s)mayhavesignalledSRQ(theactive *devicewon'tdothat).Ortheautopolllistmayhavebeenchanged. *Trypollingthenexthigheraddress.
*/
poll_addr = (last_poll_cmd & ADDR_MASK) >> 4; if ((srq_asserted && last_cmd == last_poll_cmd) ||
!(autopoll_devs & (1 << poll_addr))) { unsignedint higher_devs;
/* Now send it. Be careful though, that first byte of the request *isactuallyADB_PACKET;therealdatabeginsatindex1! *Andreq->nbytesisthenumberofbytesofrealdataplusone.
*/
/* Output mode */
via[ACR] |= SR_OUT; /* Load data */
via[SR] = req->data[1]; /* set ADB state to 'command' */
via[B] = (via[B] & ~ST_MASK) | ST_CMD;
if (!arg) { /* Clear the SR IRQ flag when polling. */ if (via[IFR] & SR_INT)
via[IFR] = SR_INT; else {
local_irq_restore(flags); return IRQ_NONE;
}
}
status = via[B] & (ST_MASK | CTLR_IRQ);
switch (macii_state) { case idle:
WARN_ON((status & ST_MASK) != ST_IDLE);
reply_ptr = reply_buf;
reading_reply = false;
bus_timeout = false;
srq_asserted = false;
x = via[SR];
if (!(status & CTLR_IRQ)) { /* /CTLR_IRQ asserted in idle state means we must *readanautopollreplyfromthetransceiverbuffer.
*/
macii_state = reading;
*reply_ptr = x;
reply_len = 1;
} else { /* bus timeout */
reply_len = 0; break;
}
/* set ADB state = even for first data byte */
via[B] = (via[B] & ~ST_MASK) | ST_EVEN; break;
case sending:
req = current_req;
if (status == (ST_CMD | CTLR_IRQ)) { /* /CTLR_IRQ de-asserted after the command byte means *thehostcancontinuewiththetransaction.
*/
/* Store command byte */
last_cmd = req->data[1]; if ((last_cmd & OP_MASK) == TALK) {
last_talk_cmd = last_cmd; if ((last_cmd & CMD_MASK) == ADB_READREG(0, 0))
last_poll_cmd = last_cmd;
}
}
if (status == ST_CMD) { /* /CTLR_IRQ asserted after the command byte means we *mustreadanautopollreply.Thefirstbytewas *lostbecausetheshiftregisterwasanoutput.
*/
macii_state = reading;
if ((via[B] & ST_MASK) == ST_CMD) { /* just sent the command byte, set to EVEN */
via[B] = (via[B] & ~ST_MASK) | ST_EVEN;
} else { /* invert state bits, toggle ODD/EVEN */
via[B] ^= ST_MASK;
} break;
case reading:
x = via[SR];
WARN_ON((status & ST_MASK) == ST_CMD ||
(status & ST_MASK) == ST_IDLE);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.