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 ma...@denx.de:
 Dear Kuo-Jung Su,

 From: Kuo-Jung Su dant...@faraday-tech.com

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

 Signed-off-by: Kuo-Jung Su dant...@faraday-tech.com

 [...]

 +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, regs-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-30 Thread Marek Vasut
Dear Kuo-Jung Su,

 From: Kuo-Jung Su dant...@faraday-tech.com
 
 This patch would try to use Faraday FOTG210 to implement
 a USB RNDIS Ethernet.
 
 Signed-off-by: Kuo-Jung Su dant...@faraday-tech.com

[...]

 +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, regs-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 dant...@faraday-tech.com

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

Signed-off-by: Kuo-Jung Su dant...@faraday-tech.com
---
 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 dant...@faraday-tech.com
+ *
+ * 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 common.h
+#include command.h
+#include config.h
+#include net.h
+#include malloc.h
+#include asm/io.h
+#include asm/errno.h
+#include linux/types.h
+#include linux/usb/ch9.h
+#include linux/usb/gadget.h
+
+#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 */
+