diff options
| -rw-r--r-- | README | 8 | ||||
| -rw-r--r-- | arch/arm/include/asm/arch-exynos/cpu.h | 1 | ||||
| -rw-r--r-- | board/samsung/universal_c210/universal.c | 48 | ||||
| -rw-r--r-- | common/cmd_usb.c | 3 | ||||
| -rw-r--r-- | common/usb.c | 27 | ||||
| -rw-r--r-- | drivers/serial/usbtty.c | 10 | ||||
| -rw-r--r-- | drivers/usb/gadget/epautoconf.c | 8 | ||||
| -rw-r--r-- | drivers/usb/gadget/s3c_udc_otg.c | 10 | ||||
| -rw-r--r-- | drivers/usb/ulpi/ulpi-viewport.c | 4 | ||||
| -rw-r--r-- | drivers/usb/ulpi/ulpi.c | 30 | ||||
| -rw-r--r-- | include/configs/s5pc210_universal.h | 4 | ||||
| -rw-r--r-- | include/max8998_pmic.h | 1 | ||||
| -rw-r--r-- | include/usb/ulpi.h | 8 | ||||
| -rw-r--r-- | include/usbdescriptors.h | 2 | 
14 files changed, 122 insertions, 42 deletions
| @@ -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 diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h index 4464d2715..6d97b9954 100644 --- a/arch/arm/include/asm/arch-exynos/cpu.h +++ b/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> diff --git a/board/samsung/universal_c210/universal.c b/board/samsung/universal_c210/universal.c index f9b8a7642..8393e4fdd 100644 --- a/board/samsung/universal_c210/universal.c +++ b/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 diff --git a/common/cmd_usb.c b/common/cmd_usb.c index d4ec2a291..320667f5f 100644 --- a/common/cmd_usb.c +++ b/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"); diff --git a/common/usb.c b/common/usb.c index 4418c70f4..63a11c8f5 100644 --- a/common/usb.c +++ b/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: diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c index e2e87fef6..a263b2c1f 100644 --- a/drivers/serial/usbtty.c +++ b/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; diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 189648942..5b8776e0b 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/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;  } diff --git a/drivers/usb/gadget/s3c_udc_otg.c b/drivers/usb/gadget/s3c_udc_otg.c index 5a3ac78ff..901fac982 100644 --- a/drivers/usb/gadget/s3c_udc_otg.c +++ b/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); diff --git a/drivers/usb/ulpi/ulpi-viewport.c b/drivers/usb/ulpi/ulpi-viewport.c index fa2e004a6..490fb0e25 100644 --- a/drivers/usb/ulpi/ulpi-viewport.c +++ b/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); diff --git a/drivers/usb/ulpi/ulpi.c b/drivers/usb/ulpi/ulpi.c index 805e29d76..620222799 100644 --- a/drivers/usb/ulpi/ulpi.c +++ b/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); diff --git a/include/configs/s5pc210_universal.h b/include/configs/s5pc210_universal.h index b36ad3a19..be000cbaf 100644 --- a/include/configs/s5pc210_universal.h +++ b/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 */ diff --git a/include/max8998_pmic.h b/include/max8998_pmic.h index bf28820c5..10c892a51 100644 --- a/include/max8998_pmic.h +++ b/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) diff --git a/include/usb/ulpi.h b/include/usb/ulpi.h index d87129087..802f077be 100644 --- a/include/usb/ulpi.h +++ b/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. diff --git a/include/usbdescriptors.h b/include/usbdescriptors.h index 392fcf537..2dec3b93d 100644 --- a/include/usbdescriptors.h +++ b/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; |