Re: [U-Boot] [PATCH 05/11] usb-gadget: add FOTG210 USB gadget support

2013-03-31 Thread Kuo-Jung Su
2013/3/30 Marek Vasut :
> Dear Kuo-Jung Su,
>
>> From: Kuo-Jung Su 
>>
>> This patch would try to use Faraday FOTG210 to implement
>> a USB RNDIS Ethernet.
>>
>> Signed-off-by: Kuo-Jung Su 
>
> [...]
>
>> +static inline int
>> +ep_reset(struct fotg210_chip *chip, uint8_t ep_addr)
>> +{
>> + int ep = ep_addr & USB_ENDPOINT_NUMBER_MASK;
>> +
>> + if (ep_addr & USB_DIR_IN) {
>> + /* input */
>> + USB_REG32(chip, REG_IEP1 + (ep - 1) * 4) |= BIT(12);
>> + USB_REG32(chip, REG_IEP1 + (ep - 1) * 4) &= ~BIT(12);
>> + USB_REG32(chip, REG_IEP1 + (ep - 1) * 4) &= ~BIT(11);
>> + } else {
>> + /* output */
>> + USB_REG32(chip, REG_OEP1 + (ep - 1) * 4) |= BIT(12);
>> + USB_REG32(chip, REG_OEP1 + (ep - 1) * 4) &= BIT(12);
>> + USB_REG32(chip, REG_OEP1 + (ep - 1) * 4) &= BIT(11);
>> + }
>
> Use readl(), writel(), clrsetbits_le32() etc.
>
> For example see drivers/i2c/mxs_i2c.c
>

Got it, thanks

> [...]
>
>> +/*
>> + * Global Registers
>> + */
>> +#define REG_ISR 0x0C0/* Interrupt Status */
>> +#define REG_IMR 0x0C4/* Interrupt Control */
>
> Use structure based access, ie.
>
> arch/arm/include/asm/arch-mxs/regs-i2c.h
>
> struct regs {
> uint32_t reg1;
> uint32_t reg2;
> ...
> };
>
> writel(val, ®s->reg1);

Got it, thanks

--
Best wishes,
Kuo-Jung Su
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH 05/11] usb-gadget: add FOTG210 USB gadget support

2013-03-29 Thread Marek Vasut
Dear Kuo-Jung Su,

> From: Kuo-Jung Su 
> 
> This patch would try to use Faraday FOTG210 to implement
> a USB RNDIS Ethernet.
> 
> Signed-off-by: Kuo-Jung Su 

[...]

> +static inline int
> +ep_reset(struct fotg210_chip *chip, uint8_t ep_addr)
> +{
> + int ep = ep_addr & USB_ENDPOINT_NUMBER_MASK;
> +
> + if (ep_addr & USB_DIR_IN) {
> + /* input */
> + USB_REG32(chip, REG_IEP1 + (ep - 1) * 4) |= BIT(12);
> + USB_REG32(chip, REG_IEP1 + (ep - 1) * 4) &= ~BIT(12);
> + USB_REG32(chip, REG_IEP1 + (ep - 1) * 4) &= ~BIT(11);
> + } else {
> + /* output */
> + USB_REG32(chip, REG_OEP1 + (ep - 1) * 4) |= BIT(12);
> + USB_REG32(chip, REG_OEP1 + (ep - 1) * 4) &= BIT(12);
> + USB_REG32(chip, REG_OEP1 + (ep - 1) * 4) &= BIT(11);
> + }

Use readl(), writel(), clrsetbits_le32() etc.

For example see drivers/i2c/mxs_i2c.c

[...]

> +/*
> + * Global Registers
> + */
> +#define REG_ISR 0x0C0/* Interrupt Status */
> +#define REG_IMR 0x0C4/* Interrupt Control */

Use structure based access, ie.

arch/arm/include/asm/arch-mxs/regs-i2c.h

struct regs {
uint32_t reg1;
uint32_t reg2;
...
};

writel(val, ®s->reg1);
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


[U-Boot] [PATCH 05/11] usb-gadget: add FOTG210 USB gadget support

2013-03-29 Thread Kuo-Jung Su
From: Kuo-Jung Su 

This patch would try to use Faraday FOTG210 to implement
a USB RNDIS Ethernet.

Signed-off-by: Kuo-Jung Su 
---
 drivers/usb/gadget/Makefile   |1 +
 drivers/usb/gadget/fotg210.c  |  926 +
 drivers/usb/gadget/fotg210.h  |   99 
 drivers/usb/gadget/gadget_chips.h |8 +
 4 files changed, 1034 insertions(+)
 create mode 100644 drivers/usb/gadget/fotg210.c
 create mode 100644 drivers/usb/gadget/fotg210.h

diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index e545b6b..432cf17 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -35,6 +35,7 @@ endif
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
 endif
diff --git a/drivers/usb/gadget/fotg210.c b/drivers/usb/gadget/fotg210.c
new file mode 100644
index 000..640ae55
--- /dev/null
+++ b/drivers/usb/gadget/fotg210.c
@@ -0,0 +1,926 @@
+/*
+ * Faraday USB 2.0 OTG Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su 
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fotg210.h"
+
+#define CFG_HALF_SPEED 0
+#define CFG_LOW_TIMING 0
+#define CFG_NUM_ENDPOINTS  4
+#define CFG_EP0_MAX_PACKET_SIZE64
+#define CFG_EPX_MAX_PACKET_SIZE512
+
+struct fotg210_chip;
+
+struct fotg210_ep {
+   struct usb_ep ep;
+
+   uint32_t maxpacket:16;
+   uint32_t id:4;
+   uint32_t stopped:1;
+   uint32_t rsvd:11;
+
+   struct list_head  queue;
+   const struct usb_endpoint_descriptor *desc;
+   struct fotg210_chip  *chip;
+};
+
+struct fotg210_request {
+   struct usb_request req;
+   struct list_head   queue;
+   struct fotg210_ep *ep;
+};
+
+struct fotg210_chip {
+   struct usb_gadget gadget;
+   struct usb_gadget_driver *driver;
+   uint32_t  iobase;
+   uint8_t   irq;
+   uint16_t  addr;
+   int   pullup;
+   enum usb_device_state state;
+   struct fotg210_ep ep[1 + CFG_NUM_ENDPOINTS];
+};
+
+static struct usb_endpoint_descriptor ep0_desc = {
+   .bLength = sizeof(struct usb_endpoint_descriptor),
+   .bDescriptorType  = USB_DT_ENDPOINT,
+   .bEndpointAddress = USB_DIR_IN,
+   .bmAttributes =USB_ENDPOINT_XFER_CONTROL,
+};
+
+#define USB_REG32(chip, off)*(volatile uint32_t *)((chip)->iobase + (off))
+
+static inline int
+fifo_to_ep(struct fotg210_chip *chip, int id, int in)
+{
+   return (id < 0) ? 0 : ((id % 4) + 1);
+}
+
+static inline int
+ep_to_fifo(struct fotg210_chip *chip, int id)
+{
+   return (id <= 0) ? -1 : ((id - 1) % 4);
+}
+
+static inline int
+ep_reset(struct fotg210_chip *chip, uint8_t ep_addr)
+{
+   int ep = ep_addr & USB_ENDPOINT_NUMBER_MASK;
+
+   if (ep_addr & USB_DIR_IN) {
+   /* input */
+   USB_REG32(chip, REG_IEP1 + (ep - 1) * 4) |= BIT(12);
+   USB_REG32(chip, REG_IEP1 + (ep - 1) * 4) &= ~BIT(12);
+   USB_REG32(chip, REG_IEP1 + (ep - 1) * 4) &= ~BIT(11);
+   } else {
+   /* output */
+   USB_REG32(chip, REG_OEP1 + (ep - 1) * 4) |= BIT(12);
+   USB_REG32(chip, REG_OEP1 + (ep - 1) * 4) &= BIT(12);
+   USB_REG32(chip, REG_OEP1 + (ep - 1) * 4) &= BIT(11);
+   }
+
+   return 0;
+}
+
+static int
+fotg210_reset(struct fotg210_chip *chip)
+{
+   chip->state = USB_STATE_POWERED;
+
+   /* device address reset */
+   chip->addr  = 0;
+   USB_REG32(chip, REG_DCAR)   = 0;
+
+   /* enable the chip and perform a soft reset later */
+   USB_REG32(chip, REG_DCCR)   = BIT(5);
+
+   /* set idle counter */
+   USB_REG32(chip, REG_DCIDLE) = 7;
+
+   /* disable interrupts */
+   USB_REG32(chip, REG_HCIER)  = 0;
+   USB_REG32(chip, REG_DCIMR)  = 0x3;
+   USB_REG32(chip, REG_DCIMR0) = 0x3F;
+   USB_REG32(chip, REG_DCIMR1) = 0xF00FF;
+   USB_REG32(chip, REG_DCIMR2) = 0x7FF;
+
+   /* clear interrupts */
+   USB_REG32(chip, REG_HCISR)  = 0x3F;
+   USB_REG32(chip, REG_OTGISR) = 0x1FFF;
+   USB_REG32(chip, REG_DCISR)  = 0;
+   USB_REG32(chip, REG_DCISR0) = 0;
+   USB_REG32(chip, REG_DCISR1) = 0;
+   USB_REG32(chip, REG_DCISR2) = 0;
+
+   /* soft reset */
+   USB_REG32(chip, REG_DCCR) |= BIT(4);
+   while (USB_REG32(chip, REG_DCCR) & BIT(4))
+   ;
+
+   /* CX FIFO reset */
+   USB_REG32(chip, REG_DCC