static void lpbb_setsda(device_t dev, int val) { device_t ppbus = device_get_parent(dev); ppb_lock(ppbus); if (val == 0) ppb_wdtr(ppbus, (u_char)SDA_out); else ppb_wdtr(ppbus, (u_char)~SDA_out); ppb_unlock(ppbus); }
/* Reset bus by setting SDA first and then SCL. */ static void lpbb_reset_bus(device_t dev) { device_t ppbus = device_get_parent(dev); ppb_assert_locked(ppbus); ppb_wdtr(ppbus, (u_char)~SDA_out); ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus) | SCL_out)); }
/* * byte_peripheral_outbyte() * * Write 1 byte in BYTE mode */ static int byte_peripheral_outbyte(device_t bus, char *buffer, int last) { int error = 0; /* Event 7 */ if ((error = do_1284_wait(bus, nBUSY, nBUSY))) { ppb_1284_set_error(bus, PPB_TIMEOUT, 7); goto error; } /* check termination */ if (!(ppb_rstr(bus) & SELECT)) { ppb_peripheral_terminate(bus, PPB_WAIT); goto error; } /* Event 15 - put byte on data lines */ #ifdef DEBUG_1284 printf("B"); #endif ppb_wdtr(bus, *buffer); /* Event 9 */ ppb_wctr(bus, (AUTOFEED | STROBE) & ~(nINIT | SELECTIN)); /* Event 10 - wait data read */ if ((error = do_peripheral_wait(bus, nBUSY, 0))) { ppb_1284_set_error(bus, PPB_TIMEOUT, 16); goto error; } /* Event 11 */ if (!last) { ppb_wctr(bus, (AUTOFEED) & ~(nINIT | STROBE | SELECTIN)); } else { ppb_wctr(bus, (nINIT) & ~(STROBE | SELECTIN | AUTOFEED)); } #if 0 /* Event 16 - wait strobe */ if ((error = do_peripheral_wait(bus, nACK | nBUSY, 0))) { ppb_1284_set_error(bus, PPB_TIMEOUT, 16); goto error; } #endif /* check termination */ if (!(ppb_rstr(bus) & SELECT)) { ppb_peripheral_terminate(bus, PPB_WAIT); goto error; } error: return (error); }
static void pcfclock_write_cmd(dev_t dev, unsigned char command) { u_int unit = minor(dev); device_t ppidev = UNITODEVICE(unit); device_t ppbus = device_get_parent(ppidev); unsigned char ctr = 14; char i; for (i = 0; i <= 7; i++) { ppb_wdtr(ppbus, i); AUTOFEED_CLOCK(i & 1 ? AFC_HI : AFC_LO); DELAY(3000); } ppb_wdtr(ppbus, command); AUTOFEED_CLOCK(AFC_LO); DELAY(3000); AUTOFEED_CLOCK(AFC_HI); }
/* * ppb_1284_negociate() * * IEEE1284 negociation phase * * Normal nibble mode or request device id mode (see ppb_1284.h) * * After negociation, nFAULT is low if data is available */ int ppb_1284_negociate(device_t bus, int mode, int options) { int error; int request_mode; #ifdef DEBUG_1284 printf("n"); #endif if (ppb_1284_get_state(bus) >= PPB_PERIPHERAL_NEGOCIATION) ppb_peripheral_terminate(bus, PPB_WAIT); if (ppb_1284_get_state(bus) != PPB_FORWARD_IDLE) ppb_1284_terminate(bus); #ifdef DEBUG_1284 printf("%d", mode); #endif /* ensure the host is in compatible mode */ ppb_set_mode(bus, PPB_COMPATIBLE); /* reset error to catch the actual negociation error */ ppb_1284_reset_error(bus, PPB_FORWARD_IDLE); /* calculate ext. value */ request_mode = ppb_request_mode(mode, options); /* default state */ ppb_wctr(bus, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED)); DELAY(1); /* enter negociation phase */ ppb_1284_set_state(bus, PPB_NEGOCIATION); /* Event 0 - put the exten. value on the data lines */ ppb_wdtr(bus, request_mode); #ifdef PERIPH_1284 /* request remote host attention */ ppb_wctr(bus, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN)); DELAY(1); ppb_wctr(bus, (nINIT) & ~(STROBE | AUTOFEED | SELECTIN)); #else DELAY(1); #endif /* !PERIPH_1284 */ /* Event 1 - enter IEEE1284 mode */ ppb_wctr(bus, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN)); #ifdef PERIPH_1284 /* ignore the PError line, wait a bit more, remote host's * interrupts don't respond fast enough */ if (ppb_poll_bus(bus, 40, nACK | SELECT | nFAULT, SELECT | nFAULT, PPB_NOINTR | PPB_POLL)) { ppb_1284_set_error(bus, PPB_NOT_IEEE1284, 2); error = ENODEV; goto error; } #else /* Event 2 - trying IEEE1284 dialog */ if (do_1284_wait(bus, nACK | PERROR | SELECT | nFAULT, PERROR | SELECT | nFAULT)) { ppb_1284_set_error(bus, PPB_NOT_IEEE1284, 2); error = ENODEV; goto error; } #endif /* !PERIPH_1284 */ /* Event 3 - latch the ext. value to the peripheral */ ppb_wctr(bus, (nINIT | STROBE | AUTOFEED) & ~SELECTIN); DELAY(1); /* Event 4 - IEEE1284 device recognized */ ppb_wctr(bus, nINIT & ~(SELECTIN | AUTOFEED | STROBE)); /* Event 6 - waiting for status lines */ if (do_1284_wait(bus, nACK, nACK)) { ppb_1284_set_error(bus, PPB_TIMEOUT, 6); error = EBUSY; goto error; } /* Event 7 - quering result consider nACK not to misunderstand * a remote computer terminate sequence */ if (options & PPB_EXTENSIBILITY_LINK) { /* XXX not fully supported yet */ ppb_1284_terminate(bus); return (0); } if (request_mode == NIBBLE_1284_NORMAL) { if (do_1284_wait(bus, nACK | SELECT, nACK)) { ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 7); error = ENODEV; goto error; } } else { if (do_1284_wait(bus, nACK | SELECT, SELECT | nACK)) { ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 7); error = ENODEV; goto error; } } switch (mode) { case PPB_NIBBLE: case PPB_PS2: /* enter reverse idle phase */ ppb_1284_set_state(bus, PPB_REVERSE_IDLE); break; case PPB_ECP: /* negociation ok, now setup the communication */ ppb_1284_set_state(bus, PPB_SETUP); ppb_wctr(bus, (nINIT | AUTOFEED) & ~(SELECTIN | STROBE)); #ifdef PERIPH_1284 /* ignore PError line */ if (do_1284_wait(bus, nACK | SELECT | nBUSY, nACK | SELECT | nBUSY)) { ppb_1284_set_error(bus, PPB_TIMEOUT, 30); error = ENODEV; goto error; } #else if (do_1284_wait(bus, nACK | SELECT | PERROR | nBUSY, nACK | SELECT | PERROR | nBUSY)) { ppb_1284_set_error(bus, PPB_TIMEOUT, 30); error = ENODEV; goto error; } #endif /* !PERIPH_1284 */ /* ok, the host enters the ForwardIdle state */ ppb_1284_set_state(bus, PPB_ECP_FORWARD_IDLE); break; case PPB_EPP: ppb_1284_set_state(bus, PPB_EPP_IDLE); break; default: panic("%s: unknown mode (%d)!", __func__, mode); } ppb_set_mode(bus, mode); return (0); error: ppb_1284_terminate(bus); return (error); }