Hi everybody,
I've managed to get the first byte read by ECP hardware in
parport_pc_ecp_read_block_pio instead of software emulation.
This is how I proceeded (get your IEEE1284 standard and open it on page
37, figure 14, ECP Mode forward to reverse, reverse, and reverse to
forward :-)
Prior to asserting nReverseRequest low, IEEE1284 states that HostACK
must be low (Event 38). That was done by software, to start the
Forward-to-Reverse phase.
It seems that my parallel port chip (ITE8661F) wants to assert HostACK
low itself. This is done automaticaly when writing 011 in the ECP
Control register, when direction is 1 (reverse).
So, I asserted HostACK high prior to Event 38, called
parport_pc_data_to_reverse (maybe I should call
parport_pc_data_to_reverse first, dunno), and then changed the mode to
ECP (change_mode (ECR_ECP)). The parallel port hardware then took care
itself of Event 38 and asserted HostACK low. Then you go on with Event
39 (nReverseRequest low), and the data transfer is started automatically
when data is available on the peripheral side.
I attached the patch to this e-mail. I'm waiting for your comments.
Cheers,
Laurent Pinchart
diff -u --recursive --new-file linux-2.4.5/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
--- linux-2.4.5/drivers/parport/parport_pc.c Wed May 23 04:54:04 2001
+++ linux/drivers/parport/parport_pc.c Sat Jun 9 15:54:22 2001
@@ -13,6 +13,7 @@
* Many ECP bugs fixed. Fred Barnes & Jamie Lokier, 1999
* More PCI support now conditional on CONFIG_PCI, 03/2001, Paul G.
* Various hacks, Fred Barnes, 04/2001
+ * ECP FIFO read hack, Laurent Pinchart <laurent.pinchart@capflow.com>
*/
/* This driver should work with any hardware that is broadly compatible
@@ -996,13 +1000,23 @@
if (port->ieee1284.phase != IEEE1284_PH_REV_IDLE) {
/* change to reverse-idle phase (must be in forward-idle) */
- /* Event 38: Set nAutoFd low (also make sure nStrobe is high) */
+ /* pre-Event 38: The hardware wants to do Event 38 by itself, so
+ set nAutoFd high (also make sure nStrobe is high) */
parport_frob_control (port,
PARPORT_CONTROL_AUTOFD
| PARPORT_CONTROL_STROBE,
- PARPORT_CONTROL_AUTOFD);
+ 0);
+
parport_pc_data_reverse (port); /* Must be in PS2 mode */
udelay (5);
+
+ /* Set up ECP FIFO mode */
+ r = change_mode (port, ECR_ECP); /* ECP FIFO */
+ if (r)
+ printk (KERN_DEBUG "%s: Warning change_mode ECR_ECP failed\n", port->name);
+
+ /* Event 38 happens right here (hardware controlled */
+
/* Event 39: Set nInit low to initiate bus reversal */
parport_frob_control (port,
PARPORT_CONTROL_INIT,
@@ -1016,51 +1030,13 @@
}
}
- /* Set up ECP FIFO mode.*/
/* parport_pc_frob_control (port,
PARPORT_CONTROL_STROBE |
PARPORT_CONTROL_AUTOFD,
PARPORT_CONTROL_AUTOFD); */
- r = change_mode (port, ECR_ECP); /* ECP FIFO */
- if (r) printk (KERN_DEBUG "%s: Warning change_mode ECR_ECP failed\n", port->name);
port->ieee1284.phase = IEEE1284_PH_REV_DATA;
- /* the first byte must be collected manually */
-dump_parport_state ("pre 43", port);
- /* Event 43: Wait for nAck to go low */
- r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0);
- if (r) {
- /* timed out while reading -- no data */
- printk (KERN_DEBUG "PIO read timed out (initial byte)\n");
- goto out_no_data;
- }
- /* read byte */
- *bufp++ = inb (DATA (port));
- left--;
-dump_parport_state ("43-44", port);
- /* Event 44: nAutoFd (HostAck) goes high to acknowledge */
- parport_pc_frob_control (port,
- PARPORT_CONTROL_AUTOFD,
- 0);
-dump_parport_state ("pre 45", port);
- /* Event 45: Wait for nAck to go high */
-/* r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK); */
-dump_parport_state ("post 45", port);
-r = 0;
- if (r) {
- /* timed out while waiting for peripheral to respond to ack */
- printk (KERN_DEBUG "ECP PIO read timed out (waiting for nAck)\n");
-
- /* keep hold of the byte we've got already */
- goto out_no_data;
- }
- /* Event 46: nAutoFd (HostAck) goes low to accept more data */
- parport_pc_frob_control (port,
- PARPORT_CONTROL_AUTOFD,
- PARPORT_CONTROL_AUTOFD);
-
-
dump_parport_state ("rev idle", port);
/* Do the transfer. */
while (left > fifofull) {
@@ -1146,8 +1124,6 @@
port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
dump_parport_state ("rev idle2", port);
-out_no_data:
-
/* Go to forward idle mode to shut the peripheral up (event 47). */
parport_frob_control (port, PARPORT_CONTROL_INIT, PARPORT_CONTROL_INIT);
-- To unsubscribe, send mail to: linux-parport-request@torque.net --
-- with the single word "unsubscribe" in the body of the message. --
This archive was generated by hypermail 2b29 : Tue Jun 12 2001 - 03:37:27 EDT