Browse Source

Merge branch 'master' of git://git.denx.de/u-boot-usb

* 'master' of git://git.denx.de/u-boot-usb:
  USB: Use (get|put)_unaligned for accessing wMaxPacketSize
  usb:gadget:s5p Enable the USB Gadget framework at Exynos4210 (C210 Universal)
  README: add documentation for CONFIG_USB_ULPI*
  USB: ULPI: increase error case verbosity
  USB: ULPI: clean a mixup of return types
  USB: ULPI: switch argument type from u8 to unsigned
Wolfgang Denk 13 years ago
parent
commit
8b0affecb9

+ 8 - 0
README

@@ -1185,6 +1185,14 @@ The following options need to be configured:
 			for your device
 			- CONFIG_USBD_PRODUCTID 0xFFFF
 
+- ULPI Layer Support:
+		The ULPI (UTMI Low Pin (count) Interface) PHYs are supported via
+		the generic ULPI layer. The generic layer accesses the ULPI PHY
+		via the platform viewport, so you need both the genric layer and
+		the viewport enabled. Currently only Chipidea/ARC based
+		viewport is supported.
+		To enable the ULPI layer support, define CONFIG_USB_ULPI and
+		CONFIG_USB_ULPI_VIEWPORT in your board configuration file.
 
 - MMC Support:
 		The MMC controller on the Intel PXA is supported. To

+ 1 - 0
arch/arm/include/asm/arch-exynos/cpu.h

@@ -46,6 +46,7 @@
 #define EXYNOS4_ADC_BASE		0x13910000
 #define EXYNOS4_PWMTIMER_BASE		0x139D0000
 #define EXYNOS4_MODEM_BASE		0x13A00000
+#define EXYNOS4_USBPHY_CONTROL          0x10020704
 
 #ifndef __ASSEMBLY__
 #include <asm/io.h>

+ 48 - 0
board/samsung/universal_c210/universal.c

@@ -28,6 +28,9 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
 #include <pmic.h>
+#include <usb/s3c_udc.h>
+#include <asm/arch/cpu.h>
+#include <max8998_pmic.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -253,3 +256,48 @@ int board_mmc_init(bd_t *bis)
 
 }
 #endif
+
+#ifdef CONFIG_USB_GADGET
+static int s5pc210_phy_control(int on)
+{
+	int ret;
+	struct pmic *p = get_pmic();
+
+	if (pmic_probe(p))
+		return -1;
+
+	if (on) {
+		ret |= pmic_set_output(p,
+				       MAX8998_REG_BUCK_ACTIVE_DISCHARGE3,
+				       MAX8998_SAFEOUT1, LDO_ON);
+		ret |= pmic_set_output(p, MAX8998_REG_ONOFF1,
+				      MAX8998_LDO3, LDO_ON);
+		ret |= pmic_set_output(p, MAX8998_REG_ONOFF2,
+				      MAX8998_LDO8, LDO_ON);
+
+	} else {
+		ret |= pmic_set_output(p, MAX8998_REG_ONOFF2,
+				      MAX8998_LDO8, LDO_OFF);
+		ret |= pmic_set_output(p, MAX8998_REG_ONOFF1,
+				      MAX8998_LDO3, LDO_OFF);
+		ret |= pmic_set_output(p,
+				       MAX8998_REG_BUCK_ACTIVE_DISCHARGE3,
+				       MAX8998_SAFEOUT1, LDO_OFF);
+	}
+
+	if (ret) {
+		puts("MAX8998 LDO setting error!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+struct s3c_plat_otg_data s5pc210_otg_data = {
+	.phy_control = s5pc210_phy_control,
+	.regs_phy = EXYNOS4_USBPHY_BASE,
+	.regs_otg = EXYNOS4_USBOTG_BASE,
+	.usb_phy_ctrl = EXYNOS4_USBPHY_CONTROL,
+	.usb_flags = PHY0_SLEEP,
+};
+#endif

+ 2 - 1
common/cmd_usb.c

@@ -28,6 +28,7 @@
 #include <common.h>
 #include <command.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 #include <part.h>
 #include <usb.h>
 
@@ -240,7 +241,7 @@ void usb_display_ep_desc(struct usb_endpoint_descriptor *epdesc)
 		printf("Interrupt");
 		break;
 	}
-	printf(" MaxPacket %d", epdesc->wMaxPacketSize);
+	printf(" MaxPacket %d", get_unaligned(&epdesc->wMaxPacketSize));
 	if ((epdesc->bmAttributes & 0x03) == 0x3)
 		printf(" Interval %dms", epdesc->bInterval);
 	printf("\n");

+ 19 - 8
common/usb.c

@@ -49,6 +49,7 @@
 #include <asm/processor.h>
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 
 #include <usb.h>
 #ifdef CONFIG_4xx
@@ -279,30 +280,32 @@ usb_set_maxpacket_ep(struct usb_device *dev, int if_idx, int ep_idx)
 {
 	int b;
 	struct usb_endpoint_descriptor *ep;
+	u16 ep_wMaxPacketSize;
 
 	ep = &dev->config.if_desc[if_idx].ep_desc[ep_idx];
 
 	b = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	ep_wMaxPacketSize = get_unaligned(&ep->wMaxPacketSize);
 
 	if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
 						USB_ENDPOINT_XFER_CONTROL) {
 		/* Control => bidirectional */
-		dev->epmaxpacketout[b] = ep->wMaxPacketSize;
-		dev->epmaxpacketin[b] = ep->wMaxPacketSize;
+		dev->epmaxpacketout[b] = ep_wMaxPacketSize;
+		dev->epmaxpacketin[b] = ep_wMaxPacketSize;
 		USB_PRINTF("##Control EP epmaxpacketout/in[%d] = %d\n",
 			   b, dev->epmaxpacketin[b]);
 	} else {
 		if ((ep->bEndpointAddress & 0x80) == 0) {
 			/* OUT Endpoint */
-			if (ep->wMaxPacketSize > dev->epmaxpacketout[b]) {
-				dev->epmaxpacketout[b] = ep->wMaxPacketSize;
+			if (ep_wMaxPacketSize > dev->epmaxpacketout[b]) {
+				dev->epmaxpacketout[b] = ep_wMaxPacketSize;
 				USB_PRINTF("##EP epmaxpacketout[%d] = %d\n",
 					   b, dev->epmaxpacketout[b]);
 			}
 		} else {
 			/* IN Endpoint */
-			if (ep->wMaxPacketSize > dev->epmaxpacketin[b]) {
-				dev->epmaxpacketin[b] = ep->wMaxPacketSize;
+			if (ep_wMaxPacketSize > dev->epmaxpacketin[b]) {
+				dev->epmaxpacketin[b] = ep_wMaxPacketSize;
 				USB_PRINTF("##EP epmaxpacketin[%d] = %d\n",
 					   b, dev->epmaxpacketin[b]);
 			}
@@ -333,6 +336,7 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
 	struct usb_descriptor_header *head;
 	int index, ifno, epno, curr_if_num;
 	int i;
+	u16 ep_wMaxPacketSize;
 
 	ifno = -1;
 	epno = -1;
@@ -378,8 +382,15 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
 			dev->config.if_desc[ifno].no_of_ep++;
 			memcpy(&dev->config.if_desc[ifno].ep_desc[epno],
 				&buffer[index], buffer[index]);
-			le16_to_cpus(&(dev->config.if_desc[ifno].ep_desc[epno].\
-							       wMaxPacketSize));
+			ep_wMaxPacketSize = get_unaligned(&dev->config.\
+							if_desc[ifno].\
+							ep_desc[epno].\
+							wMaxPacketSize);
+			put_unaligned(le16_to_cpu(ep_wMaxPacketSize),
+					&dev->config.\
+					if_desc[ifno].\
+					ep_desc[epno].\
+					wMaxPacketSize);
 			USB_PRINTF("if %d, ep %d\n", ifno, epno);
 			break;
 		default:

+ 6 - 4
drivers/serial/usbtty.c

@@ -25,6 +25,7 @@
 #include <config.h>
 #include <circbuf.h>
 #include <stdio_dev.h>
+#include <asm/unaligned.h>
 #include "usbtty.h"
 #include "usb_cdc_acm.h"
 #include "usbdescriptors.h"
@@ -626,6 +627,9 @@ static void usbtty_init_strings (void)
 	usb_strings = usbtty_string_table;
 }
 
+#define init_wMaxPacketSize(x)	le16_to_cpu(get_unaligned(\
+			&ep_descriptor_ptrs[(x) - 1]->wMaxPacketSize));
+
 static void usbtty_init_instances (void)
 {
 	int i;
@@ -688,14 +692,12 @@ static void usbtty_init_instances (void)
 		endpoint_instance[i].rcv_attributes =
 			ep_descriptor_ptrs[i - 1]->bmAttributes;
 
-		endpoint_instance[i].rcv_packetSize =
-			le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
+		endpoint_instance[i].rcv_packetSize = init_wMaxPacketSize(i);
 
 		endpoint_instance[i].tx_attributes =
 			ep_descriptor_ptrs[i - 1]->bmAttributes;
 
-		endpoint_instance[i].tx_packetSize =
-			le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
+		endpoint_instance[i].tx_packetSize = init_wMaxPacketSize(i);
 
 		endpoint_instance[i].tx_attributes =
 			ep_descriptor_ptrs[i - 1]->bmAttributes;

+ 5 - 3
drivers/usb/gadget/epautoconf.c

@@ -25,6 +25,7 @@
 #include <linux/usb/ch9.h>
 #include <asm/errno.h>
 #include <linux/usb/gadget.h>
+#include <asm/unaligned.h>
 #include "gadget_chips.h"
 
 #define isdigit(c)      ('0' <= (c) && (c) <= '9')
@@ -127,7 +128,7 @@ static int ep_matches(
 	 * where it's an output parameter representing the full speed limit.
 	 * the usb spec fixes high speed bulk maxpacket at 512 bytes.
 	 */
-	max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize);
+	max = 0x7ff & le16_to_cpu(get_unaligned(&desc->wMaxPacketSize));
 	switch (type) {
 	case USB_ENDPOINT_XFER_INT:
 		/* INT:  limit 64 bytes full speed, 1024 high speed */
@@ -143,7 +144,8 @@ static int ep_matches(
 			return 0;
 
 		/* BOTH:  "high bandwidth" works only at high speed */
-		if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) {
+		if ((get_unaligned(&desc->wMaxPacketSize) &
+					__constant_cpu_to_le16(3<<11))) {
 			if (!gadget->is_dualspeed)
 				return 0;
 			/* configure your hardware with enough buffering!! */
@@ -176,7 +178,7 @@ static int ep_matches(
 		/* min() doesn't work on bitfields with gcc-3.5 */
 		if (size > 64)
 			size = 64;
-		desc->wMaxPacketSize = cpu_to_le16(size);
+		put_unaligned(cpu_to_le16(size), &desc->wMaxPacketSize);
 	}
 	return 1;
 }

+ 6 - 4
drivers/usb/gadget/s3c_udc_otg.c

@@ -40,6 +40,7 @@
 #include <linux/usb/gadget.h>
 
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 #include <asm/io.h>
 
 #include <asm/mach-types.h>
@@ -586,7 +587,8 @@ static int s3c_ep_enable(struct usb_ep *_ep,
 	if (!_ep || !desc || ep->desc || _ep->name == ep0name
 	    || desc->bDescriptorType != USB_DT_ENDPOINT
 	    || ep->bEndpointAddress != desc->bEndpointAddress
-	    || ep_maxpacket(ep) < le16_to_cpu(desc->wMaxPacketSize)) {
+	    || ep_maxpacket(ep) <
+	    le16_to_cpu(get_unaligned(&desc->wMaxPacketSize))) {
 
 		DEBUG("%s: bad ep or descriptor\n", __func__);
 		return -EINVAL;
@@ -603,8 +605,8 @@ static int s3c_ep_enable(struct usb_ep *_ep,
 
 	/* hardware _could_ do smaller, but driver doesn't */
 	if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
-	     && le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(ep))
-	    || !desc->wMaxPacketSize) {
+	     && le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)) !=
+	     ep_maxpacket(ep)) || !get_unaligned(&desc->wMaxPacketSize)) {
 
 		DEBUG("%s: bad %s maxpacket\n", __func__, _ep->name);
 		return -ERANGE;
@@ -620,7 +622,7 @@ static int s3c_ep_enable(struct usb_ep *_ep,
 	ep->stopped = 0;
 	ep->desc = desc;
 	ep->pio_irqs = 0;
-	ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
+	ep->ep.maxpacket = le16_to_cpu(get_unaligned(&desc->wMaxPacketSize));
 
 	/* Reset halt state */
 	s3c_udc_set_nak(ep);

+ 2 - 2
drivers/usb/ulpi/ulpi-viewport.c

@@ -98,7 +98,7 @@ static int ulpi_request(u32 ulpi_viewport, u32 value)
 	return err;
 }
 
-u32 ulpi_write(u32 ulpi_viewport, u8 *reg, u32 value)
+int ulpi_write(u32 ulpi_viewport, u8 *reg, u32 value)
 {
 	u32 val = ULPI_RWRUN | ULPI_RWCTRL | ((u32)reg << 16) | (value & 0xff);
 
@@ -107,7 +107,7 @@ u32 ulpi_write(u32 ulpi_viewport, u8 *reg, u32 value)
 
 u32 ulpi_read(u32 ulpi_viewport, u8 *reg)
 {
-	u32 err;
+	int err;
 	u32 val = ULPI_RWRUN | ((u32)reg << 16);
 
 	err = ulpi_request(ulpi_viewport, val);

+ 15 - 15
drivers/usb/ulpi/ulpi.c

@@ -39,8 +39,8 @@ static struct ulpi_regs *ulpi = (struct ulpi_regs *)0;
 
 static int ulpi_integrity_check(u32 ulpi_viewport)
 {
-	u32 err, val, tval = ULPI_TEST_VALUE;
-	int i;
+	u32 val, tval = ULPI_TEST_VALUE;
+	int err, i;
 
 	/* Use the 'special' test value to check all bits */
 	for (i = 0; i < 2; i++, tval <<= 1) {
@@ -79,9 +79,9 @@ int ulpi_init(u32 ulpi_viewport)
 	return ulpi_integrity_check(ulpi_viewport);
 }
 
-int ulpi_select_transceiver(u32 ulpi_viewport, u8 speed)
+int ulpi_select_transceiver(u32 ulpi_viewport, unsigned speed)
 {
-	u8 tspeed = ULPI_FC_FULL_SPEED;
+	u32 tspeed = ULPI_FC_FULL_SPEED;
 	u32 val;
 
 	switch (speed) {
@@ -92,8 +92,8 @@ int ulpi_select_transceiver(u32 ulpi_viewport, u8 speed)
 		tspeed = speed;
 		break;
 	default:
-		printf("ULPI: %s: wrong transceiver speed specified, "
-			"falling back to full speed\n", __func__);
+		printf("ULPI: %s: wrong transceiver speed specified: %u, "
+			"falling back to full speed\n", __func__, speed);
 	}
 
 	val = ulpi_read(ulpi_viewport, &ulpi->function_ctrl);
@@ -127,9 +127,9 @@ int ulpi_set_pd(u32 ulpi_viewport, int enable)
 	return ulpi_write(ulpi_viewport, reg, val);
 }
 
-int ulpi_opmode_sel(u32 ulpi_viewport, u8 opmode)
+int ulpi_opmode_sel(u32 ulpi_viewport, unsigned opmode)
 {
-	u8 topmode = ULPI_FC_OPMODE_NORMAL;
+	u32 topmode = ULPI_FC_OPMODE_NORMAL;
 	u32 val;
 
 	switch (opmode) {
@@ -140,8 +140,8 @@ int ulpi_opmode_sel(u32 ulpi_viewport, u8 opmode)
 		topmode = opmode;
 		break;
 	default:
-		printf("ULPI: %s: wrong OpMode specified, "
-			"falling back to OpMode Normal\n", __func__);
+		printf("ULPI: %s: wrong OpMode specified: %u, "
+			"falling back to OpMode Normal\n", __func__, opmode);
 	}
 
 	val = ulpi_read(ulpi_viewport, &ulpi->function_ctrl);
@@ -154,15 +154,15 @@ int ulpi_opmode_sel(u32 ulpi_viewport, u8 opmode)
 	return ulpi_write(ulpi_viewport, &ulpi->function_ctrl, val);
 }
 
-int ulpi_serial_mode_enable(u32 ulpi_viewport, u8 smode)
+int ulpi_serial_mode_enable(u32 ulpi_viewport, unsigned smode)
 {
 	switch (smode) {
 	case ULPI_IFACE_6_PIN_SERIAL_MODE:
 	case ULPI_IFACE_3_PIN_SERIAL_MODE:
 		break;
 	default:
-		printf("ULPI: %s: unrecognized Serial Mode specified\n",
-			__func__);
+		printf("ULPI: %s: unrecognized Serial Mode specified: %u\n",
+			__func__, smode);
 		return ULPI_ERROR;
 	}
 
@@ -171,7 +171,7 @@ int ulpi_serial_mode_enable(u32 ulpi_viewport, u8 smode)
 
 int ulpi_suspend(u32 ulpi_viewport)
 {
-	u32 err;
+	int err;
 
 	err = ulpi_write(ulpi_viewport, &ulpi->function_ctrl_clear,
 			ULPI_FC_SUSPENDM);
@@ -214,7 +214,7 @@ int ulpi_reset_wait(u32) __attribute__((weak, alias("__ulpi_reset_wait")));
 
 int ulpi_reset(u32 ulpi_viewport)
 {
-	u32 err;
+	int err;
 
 	err = ulpi_write(ulpi_viewport,
 			&ulpi->function_ctrl_set, ULPI_FC_RESET);

+ 4 - 0
include/configs/s5pc210_universal.h

@@ -262,4 +262,8 @@
 #define CONFIG_PMIC_I2C
 #define CONFIG_PMIC_MAX8998
 
+#define CONFIG_USB_GADGET
+#define CONFIG_USB_GADGET_S3C_UDC_OTG
+#define CONFIG_USB_GADGET_DUALSPEED
+
 #endif	/* __CONFIG_H */

+ 1 - 0
include/max8998_pmic.h

@@ -76,6 +76,7 @@ enum {
 
 #define MAX8998_LDO3		(1 << 2)
 #define MAX8998_LDO8		(1 << 5)
+#define MAX8998_SAFEOUT1	(1 << 4)
 
 #define MAX8998_I2C_ADDR        (0xCC >> 1)
 

+ 4 - 4
include/usb/ulpi.h

@@ -41,7 +41,7 @@ int ulpi_init(u32 ulpi_viewport);
  *                ULPI_FC_LOW_SPEED,  ULPI_FC_FS4LS
  * returns 0 on success, ULPI_ERROR on failure.
  */
-int ulpi_select_transceiver(u32 ulpi_viewport, u8 speed);
+int ulpi_select_transceiver(u32 ulpi_viewport, unsigned speed);
 
 /*
  * Enable/disable VBUS.
@@ -66,7 +66,7 @@ int ulpi_set_pd(u32 ulpi_viewport, int enable);
  *
  * returns 0 on success, ULPI_ERROR on failure.
  */
-int ulpi_opmode_sel(u32 ulpi_viewport, u8 opmode);
+int ulpi_opmode_sel(u32 ulpi_viewport, unsigned opmode);
 
 /*
  * Switch to Serial Mode.
@@ -78,7 +78,7 @@ int ulpi_opmode_sel(u32 ulpi_viewport, u8 opmode);
  * Switches immediately to Serial Mode.
  * To return from Serial Mode, STP line needs to be asserted.
  */
-int ulpi_serial_mode_enable(u32 ulpi_viewport, u8 smode);
+int ulpi_serial_mode_enable(u32 ulpi_viewport, unsigned smode);
 
 /*
  * Put PHY into low power mode.
@@ -108,7 +108,7 @@ int ulpi_reset(u32 ulpi_viewport);
  *
  * returns 0 on success, ULPI_ERROR on failure.
  */
-u32 ulpi_write(u32 ulpi_viewport, u8 *reg, u32 value);
+int ulpi_write(u32 ulpi_viewport, u8 *reg, u32 value);
 
 /*
  * Read the ULPI PHY register content via the viewport.

+ 1 - 1
include/usbdescriptors.h

@@ -199,7 +199,7 @@ struct usb_endpoint_descriptor {
 	u8 bmAttributes;
 	u16 wMaxPacketSize;
 	u8 bInterval;
-} __attribute__ ((packed)) __attribute__ ((aligned(2)));
+} __attribute__ ((packed));
 
 struct usb_interface_descriptor {
 	u8 bLength;