usb: r8a66597-hcd: add function for external controller
authorYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Thu, 7 Jul 2011 00:57:10 +0000 (09:57 +0900)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 8 Jul 2011 21:57:11 +0000 (14:57 -0700)
R8A66597 has the pin of WR0 and WR1. So, if one write-pin of CPU
connects to the pins, we have to change the setting of FIFOSEL
register in the controller. If we don't change the setting,
the controller cannot send the data of odd length.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/r8a66597.h
include/linux/usb/r8a66597.h

index db6f8b9c19b6d5a1a9768f0bb50bae3bdf8ae5ee..cc8ba3c220b5238e9097bbcd14026c74df7b1e26 100644 (file)
@@ -1438,7 +1438,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum)
        if (pipenum > 0)
                r8a66597_write(r8a66597, ~(1 << pipenum), BEMPSTS);
        if (urb->transfer_buffer) {
-               r8a66597_write_fifo(r8a66597, td->pipe->fifoaddr, buf, size);
+               r8a66597_write_fifo(r8a66597, td->pipe, buf, size);
                if (!usb_pipebulk(urb->pipe) || td->maxpacket != size)
                        r8a66597_write(r8a66597, BVAL, td->pipe->fifoctr);
        }
index 25563e9a90bc71d00ddcd80787edd937aea1e4d8..f28782d20eef0eab2a0f7c124146e3c154ba8e2f 100644 (file)
@@ -201,11 +201,26 @@ static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
        iowrite16(val, r8a66597->reg + offset);
 }
 
+static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
+                                u16 val, u16 pat, unsigned long offset)
+{
+       u16 tmp;
+       tmp = r8a66597_read(r8a66597, offset);
+       tmp = tmp & (~pat);
+       tmp = tmp | val;
+       r8a66597_write(r8a66597, tmp, offset);
+}
+
+#define r8a66597_bclr(r8a66597, val, offset)   \
+                       r8a66597_mdfy(r8a66597, 0, val, offset)
+#define r8a66597_bset(r8a66597, val, offset)   \
+                       r8a66597_mdfy(r8a66597, val, 0, offset)
+
 static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
-                                      unsigned long offset, u16 *buf,
+                                      struct r8a66597_pipe *pipe, u16 *buf,
                                       int len)
 {
-       void __iomem *fifoaddr = r8a66597->reg + offset;
+       void __iomem *fifoaddr = r8a66597->reg + pipe->fifoaddr;
        unsigned long count;
        unsigned char *pb;
        int i;
@@ -230,26 +245,15 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
                iowrite16_rep(fifoaddr, buf, len);
                if (unlikely(odd)) {
                        buf = &buf[len];
+                       if (r8a66597->pdata->wr0_shorted_to_wr1)
+                               r8a66597_bclr(r8a66597, MBW_16, pipe->fifosel);
                        iowrite8((unsigned char)*buf, fifoaddr);
+                       if (r8a66597->pdata->wr0_shorted_to_wr1)
+                               r8a66597_bset(r8a66597, MBW_16, pipe->fifosel);
                }
        }
 }
 
-static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
-                                u16 val, u16 pat, unsigned long offset)
-{
-       u16 tmp;
-       tmp = r8a66597_read(r8a66597, offset);
-       tmp = tmp & (~pat);
-       tmp = tmp | val;
-       r8a66597_write(r8a66597, tmp, offset);
-}
-
-#define r8a66597_bclr(r8a66597, val, offset)   \
-                       r8a66597_mdfy(r8a66597, 0, val, offset)
-#define r8a66597_bset(r8a66597, val, offset)   \
-                       r8a66597_mdfy(r8a66597, val, 0, offset)
-
 static inline unsigned long get_syscfg_reg(int port)
 {
        return port == 0 ? SYSCFG0 : SYSCFG1;
index 26d2167340573e8e2b8fa9cf7b7e96344fb39422..30e171683a85ed5e984e45f82551bf42db83457f 100644 (file)
@@ -42,6 +42,9 @@ struct r8a66597_platdata {
 
        /* set one = big endian, set zero = little endian */
        unsigned        endian:1;
+
+       /* (external controller only) set one = WR0_N shorted to WR1_N */
+       unsigned        wr0_shorted_to_wr1:1;
 };
 
 /* Register definitions */