static void drv_M5_command(const unsigned int cmd, const int delay) { if (UseBusy) drv_M5_busy(); /* put data on DB1..DB8 */ drv_generic_parport_data(cmd & 0xff); /* set I/OC1 */ /* set I/OC2 */ /* clear RW */ drv_generic_parport_control(SIGNAL_IOC1 | SIGNAL_IOC2 | SIGNAL_RW, (cmd & 0x100 ? SIGNAL_IOC1 : 0) | (cmd & 0x200 ? SIGNAL_IOC2 : 0)); /* Control data setup time */ ndelay(T_SU); /* send command */ drv_generic_parport_toggle(SIGNAL_EX, 1, T_W); if (UseBusy) { /* honour data hold time */ ndelay(T_H); } else { /* wait for command completion */ udelay(delay); } }
static void drv_L7_write_data(const unsigned char data) { /* put data on DB1..DB8 */ drv_generic_parport_data(data); /* CS1 = high, RW = low, A0 = high */ drv_generic_parport_control(SIGNAL_CS1 | SIGNAL_RW | SIGNAL_A0, SIGNAL_CS1 | SIGNAL_A0); /* Address Setup Time = 10 ns */ /* Data Setup Time = 20 ns */ ndelay(20); /* Control L Pulse Width = 22 ns */ drv_generic_parport_toggle(SIGNAL_CS1, 0, 22); /* Address & Data Hold Time = 10 ns */ ndelay(10); }
static void drv_M5_busy(void) { static unsigned int errors = 0; unsigned char data = 0xFF; unsigned char busymask = 0x88; unsigned int counter; /* set data-lines to input */ drv_generic_parport_direction(1); /* clear I/OC1 and I/OC2, set R/W */ drv_generic_parport_control(SIGNAL_IOC1 | SIGNAL_IOC2 | SIGNAL_RW, SIGNAL_RW); /* Control data setup time */ ndelay(T_SU); counter = 0; while (1) { /* rise enable */ drv_generic_parport_control(SIGNAL_EX, SIGNAL_EX); /* data output delay time */ ndelay(T_D); /* read the busy flag */ data = drv_generic_parport_read(); /* lower enable */ /* as T_D is larger than T_W, we don't need to delay again */ drv_generic_parport_control(SIGNAL_EX, 0); if ((data & busymask) == 0) { errors = 0; break; } /* make sure we don't wait forever * - but only check after 5 iterations * that way, we won't slow down normal mode * (where we don't need the timeout anyway) */ counter++; if (counter >= 5) { struct timeval now, end; if (counter == 5) { /* determine the time when the timeout has expired */ gettimeofday(&end, NULL); end.tv_usec += MAX_BUSYFLAG_WAIT; while (end.tv_usec > 1000000) { end.tv_usec -= 1000000; end.tv_sec++; } } /* get the current time */ gettimeofday(&now, NULL); if (now.tv_sec == end.tv_sec ? now.tv_usec >= end.tv_usec : now.tv_sec >= end.tv_sec) { error("%s: timeout waiting for busy flag (0x%02x)", Name, data); if (++errors >= MAX_BUSYFLAG_ERRORS) { error("%s: too many busy flag failures, turning off busy flag checking.", Name); UseBusy = 0; } break; } } } /* clear R/W */ drv_generic_parport_control(SIGNAL_RW, 0); /* honour data hold time */ ndelay(T_H); /* set data-lines to output */ drv_generic_parport_direction(0); }