Merge branch 'pu/usb' into for-next/imx
Conflicts: arch/arm/mach-imx/include/mach/devices-imx31.h
This commit is contained in:
commit
40bd757243
|
@ -21,34 +21,12 @@
|
|||
#include <mach/weim.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/devices-imx27.h>
|
||||
#include <usb/ulpi.h>
|
||||
#include <usb/chipidea-imx.h>
|
||||
|
||||
#define GPIO_IDE_POWER (GPIO_PORTE + 18)
|
||||
#define GPIO_IDE_PCOE (GPIO_PORTF + 7)
|
||||
#define GPIO_IDE_RESET (GPIO_PORTF + 10)
|
||||
|
||||
#ifdef CONFIG_USB
|
||||
static void pcm970_usbh2_init(void)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
temp = readl(MX27_USB_OTG_BASE_ADDR + 0x600);
|
||||
temp &= ~((3 << 21) | 1);
|
||||
temp |= (1 << 5) | (1 << 16) | (1 << 19) | (1 << 20);
|
||||
writel(temp, MX27_USB_OTG_BASE_ADDR + 0x600);
|
||||
|
||||
temp = readl(MX27_USB_OTG_BASE_ADDR + 0x584);
|
||||
temp &= ~(3 << 30);
|
||||
temp |= 2 << 30;
|
||||
writel(temp, MX27_USB_OTG_BASE_ADDR + 0x584);
|
||||
|
||||
mdelay(10);
|
||||
|
||||
if (!ulpi_setup((void *)(MX27_USB_OTG_BASE_ADDR + 0x570), 1))
|
||||
add_generic_usb_ehci_device(DEVICE_ID_DYNAMIC, MX27_USB_OTG_BASE_ADDR + 0x400, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DISK_INTF_PLATFORM_IDE
|
||||
static struct resource pcm970_ide_resources[] = {
|
||||
{
|
||||
|
@ -168,6 +146,11 @@ static void pcm970_mmc_init(void)
|
|||
imx27_add_mmc1(NULL);
|
||||
}
|
||||
|
||||
struct imxusb_platformdata pcm970_usbh2_pdata = {
|
||||
.flags = MXC_EHCI_MODE_ULPI | MXC_EHCI_INTERFACE_DIFF_UNI,
|
||||
.mode = IMX_USB_MODE_HOST,
|
||||
};
|
||||
|
||||
static int pcm970_init(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -177,7 +160,7 @@ static int pcm970_init(void)
|
|||
PA1_PF_USBH2_DIR,
|
||||
PA2_PF_USBH2_DATA7,
|
||||
PA3_PF_USBH2_NXT,
|
||||
PA4_PF_USBH2_STP,
|
||||
4 | GPIO_PORTA | GPIO_GPIO | GPIO_OUT,
|
||||
PD19_AF_USBH2_DATA4,
|
||||
PD20_AF_USBH2_DATA3,
|
||||
PD21_AF_USBH2_DATA6,
|
||||
|
@ -193,9 +176,14 @@ static int pcm970_init(void)
|
|||
/* Configure SJA1000 on cs4 */
|
||||
imx27_setup_weimcs(4, 0x0000DCF6, 0x444A0301, 0x44443302);
|
||||
|
||||
#ifdef CONFIG_USB
|
||||
pcm970_usbh2_init();
|
||||
#endif
|
||||
if (IS_ENABLED(CONFIG_USB)) {
|
||||
/* Stop ULPI */
|
||||
gpio_direction_output(4, 1);
|
||||
mdelay(1);
|
||||
imx_gpio_mode(PA4_PF_USBH2_STP);
|
||||
|
||||
imx27_add_usbh2(&pcm970_usbh2_pdata);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DISK_INTF_PLATFORM_IDE
|
||||
pcm970_ide_init();
|
||||
|
|
|
@ -2,7 +2,6 @@ CONFIG_ARCH_IMX=y
|
|||
CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND=y
|
||||
CONFIG_ARCH_IMX27=y
|
||||
CONFIG_MACH_PCM038=y
|
||||
CONFIG_IMX_CLKO=y
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
|
||||
CONFIG_ARM_UNWIND=y
|
||||
|
@ -16,8 +15,6 @@ CONFIG_HUSH_FANCY_PROMPT=y
|
|||
CONFIG_CMDLINE_EDITING=y
|
||||
CONFIG_AUTO_COMPLETE=y
|
||||
CONFIG_MENU=y
|
||||
CONFIG_PARTITION=y
|
||||
CONFIG_PARTITION_DISK=y
|
||||
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
|
||||
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/pcm038/env"
|
||||
CONFIG_CMD_EDIT=y
|
||||
|
@ -32,7 +29,6 @@ CONFIG_CMD_TIME=y
|
|||
CONFIG_CMD_ECHO_E=y
|
||||
CONFIG_CMD_MEMINFO=y
|
||||
CONFIG_CMD_IOMEM=y
|
||||
CONFIG_CMD_MTEST=y
|
||||
CONFIG_CMD_FLASH=y
|
||||
CONFIG_CMD_BOOTM_SHOW_TYPE=y
|
||||
CONFIG_CMD_BOOTM_VERBOSE=y
|
||||
|
@ -40,16 +36,16 @@ CONFIG_CMD_BOOTM_INITRD=y
|
|||
CONFIG_CMD_BOOTM_OFTREE=y
|
||||
CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
|
||||
CONFIG_CMD_UIMAGE=y
|
||||
# CONFIG_CMD_BOOTZ is not set
|
||||
# CONFIG_CMD_BOOTU is not set
|
||||
CONFIG_CMD_RESET=y
|
||||
CONFIG_CMD_GO=y
|
||||
CONFIG_CMD_OFTREE=y
|
||||
CONFIG_CMD_MTEST=y
|
||||
CONFIG_CMD_SPLASH=y
|
||||
CONFIG_CMD_TIMEOUT=y
|
||||
CONFIG_CMD_PARTITION=y
|
||||
CONFIG_CMD_MAGICVAR=y
|
||||
CONFIG_CMD_MAGICVAR_HELP=y
|
||||
CONFIG_CMD_SPLASH=y
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_UNCOMPRESS=y
|
||||
CONFIG_NET=y
|
||||
|
@ -68,8 +64,10 @@ CONFIG_NAND=y
|
|||
# CONFIG_NAND_ECC_HW_SYNDROME is not set
|
||||
CONFIG_NAND_IMX=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_IMX_CHIPIDEA=y
|
||||
CONFIG_USB_EHCI=y
|
||||
CONFIG_USB_ULPI=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_VIDEO=y
|
||||
CONFIG_DRIVER_VIDEO_IMX=y
|
||||
CONFIG_IMXFB_DRIVER_VIDEO_IMX_OVERLAY=y
|
||||
|
|
|
@ -72,3 +72,8 @@ struct device_d *imx_add_pata(void *base)
|
|||
{
|
||||
return imx_add_device("imx-pata", -1, base, 0x1000, NULL);
|
||||
}
|
||||
|
||||
struct device_d *imx_add_usb(void *base, int id, struct imxusb_platformdata *pdata)
|
||||
{
|
||||
return imx_add_device("imx-usb", id, base, 0x200, pdata);
|
||||
}
|
||||
|
|
|
@ -118,6 +118,7 @@ static int imx27_init(void)
|
|||
add_generic_device("imx1-gpio", 5, NULL, MX27_GPIO6_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
|
||||
add_generic_device("imx21-wdt", 0, NULL, MX27_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
|
||||
add_generic_device("imx27-esdctl", 0, NULL, MX27_ESDCTL_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
|
||||
add_generic_device("imx27-usb-misc", 0, NULL, MX27_USB_OTG_BASE_ADDR + 0x600, 0x100, IORESOURCE_MEM, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ static int imx31_init(void)
|
|||
add_generic_device("imx31-gpio", 2, NULL, MX31_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
|
||||
add_generic_device("imx21-wdt", 0, NULL, MX31_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
|
||||
add_generic_device("imx31-esdctl", 0, NULL, MX31_ESDCTL_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
|
||||
add_generic_device("imx31-usb-misc", 0, NULL, MX31_USB_OTG_BASE_ADDR + 0x600, 0x100, IORESOURCE_MEM, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ static int imx51_init(void)
|
|||
add_generic_device("imx31-gpio", 3, NULL, MX51_GPIO4_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
|
||||
add_generic_device("imx21-wdt", 0, NULL, MX51_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
|
||||
add_generic_device("imx51-esdctl", 0, NULL, MX51_ESDCTL_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
|
||||
add_generic_device("imx51-usb-misc", 0, NULL, MX51_OTG_BASE_ADDR + 0x800, 0x100, IORESOURCE_MEM, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -70,3 +70,18 @@ static inline struct device_d *imx27_add_mmc2(void *pdata)
|
|||
{
|
||||
return imx_add_mmc((void *)MX27_SDHC3_BASE_ADDR, 2, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *imx27_add_usbotg(void *pdata)
|
||||
{
|
||||
return imx_add_usb((void *)MX27_USB_OTG_BASE_ADDR, 0, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *imx27_add_usbh1(void *pdata)
|
||||
{
|
||||
return imx_add_usb((void *)MX27_USB_OTG_BASE_ADDR + 0x200, 1, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *imx27_add_usbh2(void *pdata)
|
||||
{
|
||||
return imx_add_usb((void *)MX27_USB_OTG_BASE_ADDR + 0x400, 2, pdata);
|
||||
}
|
||||
|
|
|
@ -61,3 +61,18 @@ static inline struct device_d *imx31_add_mmc1(void *pdata)
|
|||
{
|
||||
return imx_add_mmc((void *)MX31_SDHC2_BASE_ADDR, 1, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *imx31_add_usbotg(void *pdata)
|
||||
{
|
||||
return imx_add_usb((void *)MX31_USB_OTG_BASE_ADDR, 0, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *imx31_add_usbh1(void *pdata)
|
||||
{
|
||||
return imx_add_usb((void *)MX31_USB_OTG_BASE_ADDR + 0x200, 1, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *imx31_add_usbh2(void *pdata)
|
||||
{
|
||||
return imx_add_usb((void *)MX31_USB_OTG_BASE_ADDR + 0x400, 2, pdata);
|
||||
}
|
||||
|
|
|
@ -98,3 +98,18 @@ static inline struct device_d *imx51_add_pata(void)
|
|||
{
|
||||
return imx_add_pata((void *)MX51_ATA_BASE_ADDR);
|
||||
}
|
||||
|
||||
static inline struct device_d *imx51_add_usbotg(void *pdata)
|
||||
{
|
||||
return imx_add_usb((void *)MX51_OTG_BASE_ADDR, 0, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *imx51_add_usbh1(void *pdata)
|
||||
{
|
||||
return imx_add_usb((void *)MX51_OTG_BASE_ADDR + 0x200, 1, pdata);
|
||||
}
|
||||
|
||||
static inline struct device_d *imx51_add_usbh2(void *pdata)
|
||||
{
|
||||
return imx_add_usb((void *)MX51_OTG_BASE_ADDR + 0x400, 2, pdata);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <mach/imxfb.h>
|
||||
#include <mach/imx-ipu-fb.h>
|
||||
#include <mach/esdhc.h>
|
||||
#include <usb/chipidea-imx.h>
|
||||
|
||||
struct device_d *imx_add_fec_imx27(void *base, struct fec_platform_data *pdata);
|
||||
struct device_d *imx_add_fec_imx6(void *base, struct fec_platform_data *pdata);
|
||||
|
@ -21,3 +22,4 @@ struct device_d *imx_add_mmc(void *base, int id, void *pdata);
|
|||
struct device_d *imx_add_esdhc(void *base, int id, struct esdhc_platform_data *pdata);
|
||||
struct device_d *imx_add_kpp(void *base, struct matrix_keymap_data *pdata);
|
||||
struct device_d *imx_add_pata(void *base);
|
||||
struct device_d *imx_add_usb(void *base, int id, struct imxusb_platformdata *pdata);
|
||||
|
|
|
@ -151,7 +151,7 @@ int console_register(struct console_device *newcdev)
|
|||
dev->id = DEVICE_ID_DYNAMIC;
|
||||
strcpy(dev->name, "cs");
|
||||
if (newcdev->dev)
|
||||
dev_add_child(newcdev->dev, dev);
|
||||
dev->parent = newcdev->dev;
|
||||
platform_device_register(dev);
|
||||
|
||||
if (newcdev->setbrg) {
|
||||
|
|
|
@ -133,20 +133,20 @@ int register_device(struct device_d *new_device)
|
|||
INIT_LIST_HEAD(&new_device->parameters);
|
||||
INIT_LIST_HEAD(&new_device->active);
|
||||
|
||||
if (!new_device->bus)
|
||||
return 0;
|
||||
if (new_device->bus) {
|
||||
if (!new_device->parent)
|
||||
new_device->parent = &new_device->bus->dev;
|
||||
|
||||
if (!new_device->parent) {
|
||||
new_device->parent = &new_device->bus->dev;
|
||||
dev_add_child(new_device->parent, new_device);
|
||||
list_add_tail(&new_device->bus_list, &new_device->bus->device_list);
|
||||
|
||||
bus_for_each_driver(new_device->bus, drv) {
|
||||
if (!match(drv, new_device))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_add_tail(&new_device->bus_list, &new_device->bus->device_list);
|
||||
|
||||
bus_for_each_driver(new_device->bus, drv) {
|
||||
if (!match(drv, new_device))
|
||||
break;
|
||||
}
|
||||
if (new_device->parent)
|
||||
list_add_tail(&new_device->sibling, &new_device->parent->children);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -186,16 +186,6 @@ int unregister_device(struct device_d *old_dev)
|
|||
}
|
||||
EXPORT_SYMBOL(unregister_device);
|
||||
|
||||
int dev_add_child(struct device_d *dev, struct device_d *child)
|
||||
{
|
||||
child->parent = dev;
|
||||
|
||||
list_add_tail(&child->sibling, &dev->children);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dev_add_child);
|
||||
|
||||
struct driver_d *get_driver_by_name(const char *name)
|
||||
{
|
||||
struct driver_d *drv;
|
||||
|
|
|
@ -258,7 +258,6 @@ struct i2c_client *i2c_new_device(struct i2c_adapter *adapter,
|
|||
client->addr = chip->addr;
|
||||
|
||||
client->dev.parent = &adapter->dev;
|
||||
dev_add_child(client->dev.parent, &client->dev);
|
||||
|
||||
status = register_device(&client->dev);
|
||||
|
||||
|
@ -403,9 +402,6 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adapter)
|
|||
adapter->dev.id = adapter->nr;
|
||||
strcpy(adapter->dev.name, "i2c");
|
||||
|
||||
if (adapter->dev.parent)
|
||||
dev_add_child(adapter->dev.parent, &adapter->dev);
|
||||
|
||||
ret = register_device(&adapter->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -1557,7 +1557,7 @@ int mci_register(struct mci_host *host)
|
|||
mci_dev->id = DEVICE_ID_DYNAMIC;
|
||||
strcpy(mci_dev->name, mci_driver.name);
|
||||
mci_dev->platform_data = host;
|
||||
dev_add_child(host->hw_dev, mci_dev);
|
||||
mci_dev->parent = host->hw_dev;
|
||||
|
||||
return platform_device_register(mci_dev);
|
||||
}
|
||||
|
|
|
@ -184,10 +184,8 @@ int add_mtd_device(struct mtd_info *mtd, char *devname)
|
|||
devname = "mtd";
|
||||
strcpy(mtd->class_dev.name, devname);
|
||||
mtd->class_dev.id = DEVICE_ID_DYNAMIC;
|
||||
if (mtd->parent) {
|
||||
if (mtd->parent)
|
||||
mtd->class_dev.parent = mtd->parent;
|
||||
dev_add_child(mtd->class_dev.parent, &mtd->class_dev);
|
||||
}
|
||||
register_device(&mtd->class_dev);
|
||||
|
||||
mtd->cdev.ops = &mtd_ops;
|
||||
|
|
|
@ -47,8 +47,6 @@ int mdiobus_register(struct mii_bus *bus)
|
|||
bus->dev.id = DEVICE_ID_DYNAMIC;
|
||||
strcpy(bus->dev.name, "miibus");
|
||||
bus->dev.parent = bus->parent;
|
||||
if (bus->parent)
|
||||
dev_add_child(bus->parent, &bus->dev);
|
||||
|
||||
err = register_device(&bus->dev);
|
||||
if (err) {
|
||||
|
@ -157,8 +155,6 @@ static int mdio_bus_probe(struct device_d *_dev)
|
|||
char str[16];
|
||||
|
||||
dev->attached_dev->phydev = dev;
|
||||
dev->dev.parent = &dev->attached_dev->dev;
|
||||
dev_add_child(dev->dev.parent, _dev);
|
||||
|
||||
if (drv->probe) {
|
||||
ret = drv->probe(dev);
|
||||
|
|
|
@ -157,7 +157,6 @@ static struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int p
|
|||
dev->phy_id = phy_id;
|
||||
|
||||
dev->bus = bus;
|
||||
dev->dev.parent = bus->parent;
|
||||
dev->dev.bus = &mdio_bus_type;
|
||||
|
||||
strcpy(dev->dev.name, "phy");
|
||||
|
@ -229,6 +228,8 @@ static int phy_register_device(struct phy_device* dev)
|
|||
{
|
||||
int ret;
|
||||
|
||||
dev->dev.parent = &dev->attached_dev->dev;
|
||||
|
||||
ret = register_device(&dev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -400,11 +401,14 @@ int genphy_setup_forced(struct phy_device *phydev)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int phy_aneg_done(struct phy_device *phydev)
|
||||
int phy_wait_aneg_done(struct phy_device *phydev)
|
||||
{
|
||||
uint64_t start = get_time_ns();
|
||||
int ctl;
|
||||
|
||||
if (phydev->autoneg == AUTONEG_DISABLE)
|
||||
return 0;
|
||||
|
||||
while (!is_timeout(start, PHY_AN_TIMEOUT * SECOND)) {
|
||||
ctl = phy_read(phydev, MII_BMSR);
|
||||
if (ctl & BMSR_ANEGCOMPLETE) {
|
||||
|
@ -451,7 +455,7 @@ int genphy_restart_aneg(struct phy_device *phydev)
|
|||
if (ctl < 0)
|
||||
return ctl;
|
||||
|
||||
return phy_aneg_done(phydev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -81,7 +81,7 @@ struct spi_device *spi_new_device(struct spi_master *master,
|
|||
proxy->dev.id = DEVICE_ID_DYNAMIC;
|
||||
proxy->dev.type_data = proxy;
|
||||
proxy->dev.device_node = chip->device_node;
|
||||
dev_add_child(master->dev, &proxy->dev);
|
||||
proxy->dev.parent = master->dev;
|
||||
|
||||
/* drivers may modify this initial i/o setup */
|
||||
status = master->setup(proxy);
|
||||
|
|
|
@ -3,6 +3,8 @@ menuconfig USB
|
|||
|
||||
if USB
|
||||
|
||||
source drivers/usb/imx/Kconfig
|
||||
|
||||
source drivers/usb/host/Kconfig
|
||||
|
||||
source drivers/usb/otg/Kconfig
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
obj-$(CONFIG_USB) += core/
|
||||
obj-$(CONFIG_USB_IMX_CHIPIDEA) += imx/
|
||||
obj-$(CONFIG_USB_GADGET) += gadget/
|
||||
obj-$(CONFIG_USB_STORAGE) += storage/
|
||||
obj-y += host/
|
||||
|
|
|
@ -807,32 +807,18 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int ehci_probe(struct device_d *dev)
|
||||
int ehci_register(struct device_d *dev, struct ehci_data *data)
|
||||
{
|
||||
struct usb_host *host;
|
||||
struct ehci_priv *ehci;
|
||||
uint32_t reg;
|
||||
struct ehci_platform_data *pdata = dev->platform_data;
|
||||
|
||||
ehci = xzalloc(sizeof(struct ehci_priv));
|
||||
host = &ehci->host;
|
||||
dev->priv = ehci;
|
||||
|
||||
/* default to EHCI_HAS_TT to not change behaviour of boards
|
||||
* without platform_data
|
||||
*/
|
||||
if (pdata)
|
||||
ehci->flags = pdata->flags;
|
||||
else
|
||||
ehci->flags = EHCI_HAS_TT;
|
||||
|
||||
if (dev->num_resources < 2) {
|
||||
printf("echi: need 2 resources base and data");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ehci->hccr = dev_request_mem_region(dev, 0);
|
||||
ehci->hcor = dev_request_mem_region(dev, 1);
|
||||
ehci->flags = data->flags;
|
||||
ehci->hccr = data->hccr;
|
||||
ehci->hcor = data->hcor;
|
||||
|
||||
ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) * NUM_TD);
|
||||
ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD);
|
||||
|
@ -854,6 +840,30 @@ static int ehci_probe(struct device_d *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ehci_probe(struct device_d *dev)
|
||||
{
|
||||
struct ehci_data data;
|
||||
struct ehci_platform_data *pdata = dev->platform_data;
|
||||
|
||||
/* default to EHCI_HAS_TT to not change behaviour of boards
|
||||
* without platform_data
|
||||
*/
|
||||
if (pdata)
|
||||
data.flags = pdata->flags;
|
||||
else
|
||||
data.flags = EHCI_HAS_TT;
|
||||
|
||||
if (dev->num_resources < 2) {
|
||||
printf("echi: need 2 resources base and data");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
data.hccr = dev_request_mem_region(dev, 0);
|
||||
data.hcor = dev_request_mem_region(dev, 1);
|
||||
|
||||
return ehci_register(dev, &data);
|
||||
}
|
||||
|
||||
static void ehci_remove(struct device_d *dev)
|
||||
{
|
||||
struct ehci_priv *ehci = dev->priv;
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
config USB_IMX_CHIPIDEA
|
||||
bool "i.MX USB support (read help)"
|
||||
depends on ARCH_IMX
|
||||
help
|
||||
The Freescale i.MX SoCs have a variant of the chipidea ci13xxx for
|
||||
USB support. Traditionally in barebox this is supported through the
|
||||
EHCI driver for USB host and the ARC USB gadget driver for device.
|
||||
This option instead enables support for i.MX chipidea support which
|
||||
acts as a toplevel driver for the i.MX USB support. The chipidea
|
||||
support also configures the usbmisc registers which traditionally
|
||||
are configured in the board file.
|
||||
This driver is recommended for new designs, but it needs board
|
||||
support to work.
|
||||
It's safe to say yes here. Also select EHCI support for USB host.
|
|
@ -0,0 +1 @@
|
|||
obj-$(CONFIG_USB_IMX_CHIPIDEA) += imx-usb-misc.o chipidea-imx.o
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <io.h>
|
||||
#include <driver.h>
|
||||
#include <usb/ehci.h>
|
||||
#include <usb/chipidea-imx.h>
|
||||
#include <usb/ulpi.h>
|
||||
|
||||
#define MXC_EHCI_PORTSC_MASK (0xf << 28)
|
||||
|
||||
static int imx_chipidea_probe(struct device_d *dev)
|
||||
{
|
||||
struct imxusb_platformdata *pdata = dev->platform_data;
|
||||
int ret;
|
||||
void __iomem *base;
|
||||
struct ehci_data data;
|
||||
uint32_t portsc;
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(dev, "no pdata!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
base = dev_request_mem_region(dev, 0);
|
||||
if (!base)
|
||||
return -ENODEV;
|
||||
|
||||
portsc = readl(base + 0x184);
|
||||
portsc &= ~MXC_EHCI_PORTSC_MASK;
|
||||
portsc |= pdata->flags & MXC_EHCI_PORTSC_MASK;
|
||||
writel(portsc, base + 0x184);
|
||||
|
||||
ret = imx_usbmisc_port_init(dev->id, pdata->flags);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to init misc regs: %s\n", strerror(-ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((pdata->flags & MXC_EHCI_PORTSC_MASK) == MXC_EHCI_MODE_ULPI) {
|
||||
dev_dbg(dev, "using ULPI phy\n");
|
||||
if (IS_ENABLED(CONFIG_USB_ULPI)) {
|
||||
ret = ulpi_setup(base + 0x170, 1);
|
||||
} else {
|
||||
dev_err(dev, "no ULPI support available\n");
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
data.hccr = base + 0x100;
|
||||
data.hcor = base + 0x140;
|
||||
data.flags = EHCI_HAS_TT;
|
||||
|
||||
if (pdata->mode == IMX_USB_MODE_HOST) {
|
||||
ret = ehci_register(dev, &data);
|
||||
} else {
|
||||
/*
|
||||
* Not yet implemented. Register USB gadget driver here.
|
||||
*/
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
static struct driver_d imx_chipidea_driver = {
|
||||
.name = "imx-usb",
|
||||
.probe = imx_chipidea_probe,
|
||||
};
|
||||
|
||||
static int imx_chipidea_init(void)
|
||||
{
|
||||
return platform_driver_register(&imx_chipidea_driver);
|
||||
}
|
||||
device_initcall(imx_chipidea_init);
|
|
@ -0,0 +1,410 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
|
||||
* Copyright (C) 2010 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <io.h>
|
||||
#include <usb/chipidea-imx.h>
|
||||
|
||||
#define MX25_OTG_SIC_SHIFT 29
|
||||
#define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT)
|
||||
#define MX25_OTG_PM_BIT (1 << 24)
|
||||
#define MX25_OTG_PP_BIT (1 << 11)
|
||||
#define MX25_OTG_OCPOL_BIT (1 << 3)
|
||||
|
||||
#define MX25_H1_SIC_SHIFT 21
|
||||
#define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
|
||||
#define MX25_H1_PP_BIT (1 << 18)
|
||||
#define MX25_H1_PM_BIT (1 << 8)
|
||||
#define MX25_H1_IPPUE_UP_BIT (1 << 7)
|
||||
#define MX25_H1_IPPUE_DOWN_BIT (1 << 6)
|
||||
#define MX25_H1_TLL_BIT (1 << 5)
|
||||
#define MX25_H1_USBTE_BIT (1 << 4)
|
||||
#define MX25_H1_OCPOL_BIT (1 << 2)
|
||||
|
||||
static __maybe_unused int mx25_initialize_usb_hw(void __iomem *base, int port, unsigned int flags)
|
||||
{
|
||||
unsigned int v;
|
||||
|
||||
v = readl(base);
|
||||
|
||||
switch (port) {
|
||||
case 0: /* OTG port */
|
||||
v &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PM_BIT | MX25_OTG_PP_BIT |
|
||||
MX25_OTG_OCPOL_BIT);
|
||||
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT;
|
||||
|
||||
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
|
||||
v |= MX25_OTG_PM_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
|
||||
v |= MX25_OTG_PP_BIT;
|
||||
|
||||
if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW))
|
||||
v |= MX25_OTG_OCPOL_BIT;
|
||||
|
||||
break;
|
||||
case 1: /* H1 port */
|
||||
v &= ~(MX25_H1_SIC_MASK | MX25_H1_PM_BIT | MX25_H1_PP_BIT |
|
||||
MX25_H1_OCPOL_BIT | MX25_H1_TLL_BIT | MX25_H1_USBTE_BIT |
|
||||
MX25_H1_IPPUE_DOWN_BIT | MX25_H1_IPPUE_UP_BIT);
|
||||
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT;
|
||||
|
||||
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
|
||||
v |= MX25_H1_PM_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
|
||||
v |= MX25_H1_PP_BIT;
|
||||
|
||||
if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW))
|
||||
v |= MX25_H1_OCPOL_BIT;
|
||||
|
||||
if (!(flags & MXC_EHCI_TLL_ENABLED))
|
||||
v |= MX25_H1_TLL_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_INTERNAL_PHY)
|
||||
v |= MX25_H1_USBTE_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_IPPUE_DOWN)
|
||||
v |= MX25_H1_IPPUE_DOWN_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_IPPUE_UP)
|
||||
v |= MX25_H1_IPPUE_UP_BIT;
|
||||
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
writel(v, base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MX27_OTG_SIC_SHIFT 29
|
||||
#define MX27_OTG_SIC_MASK (0x3 << MX27_OTG_SIC_SHIFT)
|
||||
#define MX27_OTG_PM_BIT (1 << 24)
|
||||
|
||||
#define MX27_H2_SIC_SHIFT 21
|
||||
#define MX27_H2_SIC_MASK (0x3 << MX27_H2_SIC_SHIFT)
|
||||
#define MX27_H2_PM_BIT (1 << 16)
|
||||
#define MX27_H2_DT_BIT (1 << 5)
|
||||
|
||||
#define MX27_H1_SIC_SHIFT 13
|
||||
#define MX27_H1_SIC_MASK (0x3 << MX27_H1_SIC_SHIFT)
|
||||
#define MX27_H1_PM_BIT (1 << 8)
|
||||
#define MX27_H1_DT_BIT (1 << 4)
|
||||
|
||||
static __maybe_unused int mx27_mx31_initialize_usb_hw(void __iomem *base, int port, unsigned int flags)
|
||||
{
|
||||
unsigned int v;
|
||||
|
||||
v = readl(base);
|
||||
|
||||
switch (port) {
|
||||
case 0: /* OTG port */
|
||||
v &= ~(MX27_OTG_SIC_MASK | MX27_OTG_PM_BIT);
|
||||
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_OTG_SIC_SHIFT;
|
||||
|
||||
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
|
||||
v |= MX27_OTG_PM_BIT;
|
||||
break;
|
||||
case 1: /* H1 port */
|
||||
v &= ~(MX27_H1_SIC_MASK | MX27_H1_PM_BIT | MX27_H1_DT_BIT);
|
||||
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_H1_SIC_SHIFT;
|
||||
|
||||
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
|
||||
v |= MX27_H1_PM_BIT;
|
||||
|
||||
if (!(flags & MXC_EHCI_TLL_ENABLED))
|
||||
v |= MX27_H1_DT_BIT;
|
||||
|
||||
break;
|
||||
case 2: /* H2 port */
|
||||
v &= ~(MX27_H2_SIC_MASK | MX27_H2_PM_BIT | MX27_H2_DT_BIT);
|
||||
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_H2_SIC_SHIFT;
|
||||
|
||||
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
|
||||
v |= MX27_H2_PM_BIT;
|
||||
|
||||
if (!(flags & MXC_EHCI_TLL_ENABLED))
|
||||
v |= MX27_H2_DT_BIT;
|
||||
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
writel(v, base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define USBCTRL_OTGBASE_OFFSET 0x600
|
||||
|
||||
#define MX35_OTG_SIC_SHIFT 29
|
||||
#define MX35_OTG_SIC_MASK (0x3 << MX35_OTG_SIC_SHIFT)
|
||||
#define MX35_OTG_PM_BIT (1 << 24)
|
||||
#define MX35_OTG_PP_BIT (1 << 11)
|
||||
#define MX35_OTG_OCPOL_BIT (1 << 3)
|
||||
|
||||
#define MX35_H1_SIC_SHIFT 21
|
||||
#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
|
||||
#define MX35_H1_PP_BIT (1 << 18)
|
||||
#define MX35_H1_PM_BIT (1 << 8)
|
||||
#define MX35_H1_IPPUE_UP_BIT (1 << 7)
|
||||
#define MX35_H1_IPPUE_DOWN_BIT (1 << 6)
|
||||
#define MX35_H1_TLL_BIT (1 << 5)
|
||||
#define MX35_H1_USBTE_BIT (1 << 4)
|
||||
#define MX35_H1_OCPOL_BIT (1 << 2)
|
||||
|
||||
static __maybe_unused int mx35_initialize_usb_hw(void __iomem *base, int port, unsigned int flags)
|
||||
{
|
||||
unsigned int v;
|
||||
|
||||
v = readl(base);
|
||||
|
||||
switch (port) {
|
||||
case 0: /* OTG port */
|
||||
v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT | MX35_OTG_PP_BIT |
|
||||
MX35_OTG_OCPOL_BIT);
|
||||
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_OTG_SIC_SHIFT;
|
||||
|
||||
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
|
||||
v |= MX35_OTG_PM_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
|
||||
v |= MX35_OTG_PP_BIT;
|
||||
|
||||
if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW))
|
||||
v |= MX35_OTG_OCPOL_BIT;
|
||||
|
||||
break;
|
||||
case 1: /* H1 port */
|
||||
v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_PP_BIT |
|
||||
MX35_H1_OCPOL_BIT | MX35_H1_TLL_BIT | MX35_H1_USBTE_BIT |
|
||||
MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
|
||||
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_H1_SIC_SHIFT;
|
||||
|
||||
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
|
||||
v |= MX35_H1_PM_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
|
||||
v |= MX35_H1_PP_BIT;
|
||||
|
||||
if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW))
|
||||
v |= MX35_H1_OCPOL_BIT;
|
||||
|
||||
if (!(flags & MXC_EHCI_TLL_ENABLED))
|
||||
v |= MX35_H1_TLL_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_INTERNAL_PHY)
|
||||
v |= MX35_H1_USBTE_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_IPPUE_DOWN)
|
||||
v |= MX35_H1_IPPUE_DOWN_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_IPPUE_UP)
|
||||
v |= MX35_H1_IPPUE_UP_BIT;
|
||||
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
writel(v, base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* USB_CTRL */
|
||||
#define MX5_OTG_UCTRL_OWIE_BIT (1 << 27) /* OTG wakeup intr enable */
|
||||
#define MX5_OTG_UCTRL_OPM_BIT (1 << 24) /* OTG power mask */
|
||||
#define MX5_H1_UCTRL_H1UIE_BIT (1 << 12) /* Host1 ULPI interrupt enable */
|
||||
#define MX5_H1_UCTRL_H1WIE_BIT (1 << 11) /* HOST1 wakeup intr enable */
|
||||
#define MX5_H1_UCTRL_H1PM_BIT (1 << 8) /* HOST1 power mask */
|
||||
|
||||
/* USB_PHY_CTRL_FUNC */
|
||||
#define MX5_OTG_PHYCTRL_OC_POL_BIT (1 << 9) /* OTG Polarity of Overcurrent */
|
||||
#define MX5_OTG_PHYCTRL_OC_DIS_BIT (1 << 8) /* OTG Disable Overcurrent Event */
|
||||
#define MX5_H1_OC_POL_BIT (1 << 6) /* UH1 Polarity of Overcurrent */
|
||||
#define MX5_H1_OC_DIS_BIT (1 << 5) /* UH1 Disable Overcurrent Event */
|
||||
#define MX5_OTG_PHYCTRL_PWR_POL_BIT (1 << 3) /* OTG Power Pin Polarity */
|
||||
|
||||
/* USBH2CTRL */
|
||||
#define MX5_H2_UCTRL_H2UIE_BIT (1 << 8)
|
||||
#define MX5_H2_UCTRL_H2WIE_BIT (1 << 7)
|
||||
#define MX5_H2_UCTRL_H2PM_BIT (1 << 4)
|
||||
|
||||
#define MX5_USBCTRL_OFFSET 0x0
|
||||
#define MX5_UTMI_PHY_CTRL_0 0x8
|
||||
#define MX5_UTMI_PHY_CTRL_1 0xc
|
||||
#define MX5_USBH2CTRL_OFFSET 0x14
|
||||
|
||||
static __maybe_unused int mx5_initialize_usb_hw(void __iomem *base, int port,
|
||||
unsigned int flags)
|
||||
{
|
||||
unsigned int v;
|
||||
|
||||
switch (port) {
|
||||
case 0: /* OTG port */
|
||||
if (!(flags & MXC_EHCI_INTERNAL_PHY))
|
||||
return 0;
|
||||
|
||||
/* Adjust UTMI PHY frequency to 24MHz */
|
||||
v = readl(base + MX5_UTMI_PHY_CTRL_1);
|
||||
v = (v & ~0x3) | 0x01;
|
||||
writel(v, base + MX5_UTMI_PHY_CTRL_1);
|
||||
|
||||
v = readl(base + MX5_UTMI_PHY_CTRL_0);
|
||||
v &= ~MX5_OTG_PHYCTRL_OC_POL_BIT;
|
||||
v &= ~MX5_OTG_PHYCTRL_OC_DIS_BIT;
|
||||
v &= ~MX5_OTG_PHYCTRL_PWR_POL_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW)
|
||||
v |= MX5_OTG_PHYCTRL_OC_POL_BIT;
|
||||
|
||||
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
|
||||
v |= MX5_OTG_PHYCTRL_OC_DIS_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
|
||||
v |= MX5_OTG_PHYCTRL_PWR_POL_BIT;
|
||||
|
||||
writel(v, base + MX5_UTMI_PHY_CTRL_0);
|
||||
|
||||
v = readl(base + MX5_USBCTRL_OFFSET);
|
||||
v &= ~MX5_OTG_UCTRL_OWIE_BIT;
|
||||
v &= ~MX5_OTG_UCTRL_OPM_BIT;
|
||||
|
||||
if (flags & MXC_EHCI_WAKEUP_ENABLED)
|
||||
v |= MX5_OTG_UCTRL_OWIE_BIT;
|
||||
|
||||
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
|
||||
v |= MX5_OTG_UCTRL_OPM_BIT;
|
||||
|
||||
writel(v, base + MX5_USBCTRL_OFFSET);
|
||||
|
||||
break;
|
||||
case 1: /* H1 port */
|
||||
v = readl(base + MX5_USBCTRL_OFFSET);
|
||||
v &= ~MX5_H1_UCTRL_H1PM_BIT;
|
||||
|
||||
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
|
||||
v |= MX5_H1_UCTRL_H1PM_BIT;
|
||||
|
||||
writel(v, base + MX5_USBCTRL_OFFSET);
|
||||
|
||||
break;
|
||||
case 2: /* H2 port */
|
||||
v = readl(base + MX5_USBH2CTRL_OFFSET);
|
||||
v &= ~MX5_H2_UCTRL_H2PM_BIT;
|
||||
|
||||
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
|
||||
v |= MX5_H2_UCTRL_H2PM_BIT;
|
||||
|
||||
writel(v, base + MX5_USBH2CTRL_OFFSET);
|
||||
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_device_id imx_usbmisc_ids[] = {
|
||||
#ifdef CONFIG_ARCH_IMX25
|
||||
{
|
||||
.name = "imx25-usb-misc",
|
||||
.driver_data = (unsigned long)&mx25_initialize_usb_hw,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_IMX27
|
||||
{
|
||||
.name = "imx27-usb-misc",
|
||||
.driver_data = (unsigned long)&mx27_mx31_initialize_usb_hw,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_IMX31
|
||||
{
|
||||
.name = "imx31-usb-misc",
|
||||
.driver_data = (unsigned long)&mx27_mx31_initialize_usb_hw,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_IMX35
|
||||
{
|
||||
.name = "imx35-usb-misc",
|
||||
.driver_data = (unsigned long)&mx35_initialize_usb_hw,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_IMX51
|
||||
{
|
||||
.name = "imx51-usb-misc",
|
||||
.driver_data = (unsigned long)&mx5_initialize_usb_hw,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_IMX53
|
||||
{
|
||||
.name = "imx53-usb-misc",
|
||||
.driver_data = (unsigned long)&mx5_initialize_usb_hw,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
/* sentinel */
|
||||
},
|
||||
};
|
||||
|
||||
static int (*__imx_usbmisc_port_init)(void __iomem *base, int port, unsigned flags);
|
||||
static void __iomem *usbmisc_base;
|
||||
|
||||
int imx_usbmisc_port_init(int port, unsigned flags)
|
||||
{
|
||||
if (!__imx_usbmisc_port_init)
|
||||
return -ENODEV;
|
||||
|
||||
return __imx_usbmisc_port_init(usbmisc_base, port, flags);
|
||||
}
|
||||
|
||||
static int imx_usbmisc_probe(struct device_d *dev)
|
||||
{
|
||||
struct imx_serial_devtype_data *devtype;
|
||||
int ret;
|
||||
|
||||
ret = dev_get_drvdata(dev, (unsigned long *)&devtype);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
usbmisc_base = dev_request_mem_region(dev, 0);
|
||||
if (!usbmisc_base)
|
||||
return -ENOMEM;
|
||||
|
||||
__imx_usbmisc_port_init = (void *)devtype;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct driver_d imx_usbmisc_driver = {
|
||||
.name = "imx-usbmisc",
|
||||
.probe = imx_usbmisc_probe,
|
||||
.id_table = imx_usbmisc_ids,
|
||||
};
|
||||
|
||||
static int imx_usbmisc_init(void)
|
||||
{
|
||||
platform_driver_register(&imx_usbmisc_driver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
coredevice_initcall(imx_usbmisc_init);
|
|
@ -111,6 +111,23 @@ int ulpi_clear(u8 bits, int reg, void __iomem *view)
|
|||
}
|
||||
EXPORT_SYMBOL(ulpi_clear);
|
||||
|
||||
int ulpi_write(u8 bits, int reg, void __iomem *view)
|
||||
{
|
||||
int ret;
|
||||
|
||||
writel((ULPIVW_RUN | ULPIVW_WRITE |
|
||||
(reg << ULPIVW_ADDR_SHIFT) |
|
||||
((bits & ULPIVW_WDATA_MASK) << ULPIVW_WDATA_SHIFT)),
|
||||
view);
|
||||
|
||||
/* wait for completion */
|
||||
ret = ulpi_poll(view, ULPIVW_RUN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ulpi_write);
|
||||
|
||||
struct ulpi_info {
|
||||
uint32_t id;
|
||||
char *name;
|
||||
|
@ -161,18 +178,18 @@ int ulpi_set_vbus(void __iomem *view, int on)
|
|||
int ret;
|
||||
|
||||
if (on) {
|
||||
ret = ulpi_set(DRV_VBUS_EXT | /* enable external Vbus */
|
||||
DRV_VBUS | /* enable internal Vbus */
|
||||
USE_EXT_VBUS_IND | /* use external indicator */
|
||||
CHRG_VBUS, /* charge Vbus */
|
||||
ret = ulpi_set(ULPI_OTG_DRV_VBUS_EXT | /* enable external Vbus */
|
||||
ULPI_OTG_DRV_VBUS | /* enable internal Vbus */
|
||||
ULPI_OTG_USE_EXT_VBUS_IND | /* use external indicator */
|
||||
ULPI_OTG_CHRG_VBUS, /* charge Vbus */
|
||||
ULPI_OTGCTL, view);
|
||||
} else {
|
||||
ret = ulpi_clear(DRV_VBUS_EXT | /* disable external Vbus */
|
||||
DRV_VBUS, /* disable internal Vbus */
|
||||
ret = ulpi_clear(ULPI_OTG_DRV_VBUS_EXT | /* disable external Vbus */
|
||||
ULPI_OTG_DRV_VBUS, /* disable internal Vbus */
|
||||
ULPI_OTGCTL, view);
|
||||
|
||||
ret |= ulpi_set(USE_EXT_VBUS_IND | /* use external indicator */
|
||||
DISCHRG_VBUS, /* discharge Vbus */
|
||||
ret |= ulpi_set(ULPI_OTG_USE_EXT_VBUS_IND | /* use external indicator */
|
||||
ULPI_OTG_DISCHRG_VBUS, /* discharge Vbus */
|
||||
ULPI_OTGCTL, view);
|
||||
}
|
||||
|
||||
|
|
|
@ -413,7 +413,6 @@ static int w1_device_register(struct w1_bus *bus, struct w1_device *dev)
|
|||
dev->bus = bus;
|
||||
|
||||
dev->dev.parent = &bus->dev;
|
||||
dev_add_child(dev->dev.parent, &dev->dev);
|
||||
|
||||
ret = register_device(&dev->dev);
|
||||
if (ret)
|
||||
|
@ -600,10 +599,7 @@ int w1_bus_register(struct w1_bus *bus)
|
|||
|
||||
strcpy(bus->dev.name, "w1_bus");
|
||||
bus->dev.id = DEVICE_ID_DYNAMIC;
|
||||
|
||||
bus->dev.parent = bus->parent;
|
||||
if (bus->parent)
|
||||
dev_add_child(bus->parent, &bus->dev);
|
||||
|
||||
ret = register_device(&bus->dev);
|
||||
if (ret)
|
||||
|
|
10
fs/fs.c
10
fs/fs.c
|
@ -1107,11 +1107,6 @@ static int fs_probe(struct device_d *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (fsdev->cdev) {
|
||||
dev_add_child(fsdev->cdev->dev, &fsdev->dev);
|
||||
fsdev->parent_device = fsdev->cdev->dev;
|
||||
}
|
||||
|
||||
fsdev->driver = fsdrv;
|
||||
|
||||
list_add_tail(&fsdev->list, &fs_device_list);
|
||||
|
@ -1231,6 +1226,11 @@ int mount(const char *device, const char *fsname, const char *_path)
|
|||
if (!strncmp(device, "/dev/", 5))
|
||||
fsdev->cdev = cdev_by_name(device + 5);
|
||||
|
||||
if (fsdev->cdev) {
|
||||
fsdev->dev.parent = fsdev->cdev->dev;
|
||||
fsdev->parent_device = fsdev->cdev->dev;
|
||||
}
|
||||
|
||||
ret = register_device(&fsdev->dev);
|
||||
if (ret)
|
||||
goto err_register;
|
||||
|
|
|
@ -158,11 +158,6 @@ int device_probe(struct device_d *dev);
|
|||
*/
|
||||
int unregister_device(struct device_d *);
|
||||
|
||||
/* Organize devices in a tree. These functions do _not_ register or
|
||||
* unregister a device. Only registered devices are allowed here.
|
||||
*/
|
||||
int dev_add_child(struct device_d *dev, struct device_d *child);
|
||||
|
||||
/* Iterate over a devices children
|
||||
*/
|
||||
#define device_for_each_child(dev, child) \
|
||||
|
|
|
@ -267,6 +267,7 @@ int phy_device_connect(struct eth_device *dev, struct mii_bus *bus, int addr,
|
|||
u32 flags, phy_interface_t interface);
|
||||
|
||||
int phy_update_status(struct phy_device *phydev);
|
||||
int phy_wait_aneg_done(struct phy_device *phydev);
|
||||
|
||||
/* Generic PHY support and helper functions */
|
||||
int genphy_restart_aneg(struct phy_device *phydev);
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef __USB_CHIPIDEA_IMX_H
|
||||
#define __USB_CHIPIDEA_IMX_H
|
||||
|
||||
/*
|
||||
* POTSC flags
|
||||
*/
|
||||
#define MXC_EHCI_SERIAL (1 << 29)
|
||||
#define MXC_EHCI_MODE_UTMI_8BIT (0 << 30)
|
||||
#define MXC_EHCI_MODE_UTMI_16_BIT ((0 << 30) | (1 << 28))
|
||||
#define MXC_EHCI_MODE_PHILIPS (1 << 30)
|
||||
#define MXC_EHCI_MODE_ULPI (2 << 30)
|
||||
#define MXC_EHCI_MODE_SERIAL (3 << 30)
|
||||
|
||||
/*
|
||||
* USB misc flags
|
||||
*/
|
||||
#define MXC_EHCI_INTERFACE_DIFF_UNI (0 << 0)
|
||||
#define MXC_EHCI_INTERFACE_DIFF_BI (1 << 0)
|
||||
#define MXC_EHCI_INTERFACE_SINGLE_UNI (2 << 0)
|
||||
#define MXC_EHCI_INTERFACE_SINGLE_BI (3 << 0)
|
||||
#define MXC_EHCI_INTERFACE_MASK (0xf)
|
||||
|
||||
#define MXC_EHCI_POWER_PINS_ENABLED (1 << 5)
|
||||
#define MXC_EHCI_PWR_PIN_ACTIVE_HIGH (1 << 6)
|
||||
#define MXC_EHCI_OC_PIN_ACTIVE_LOW (1 << 7)
|
||||
#define MXC_EHCI_TLL_ENABLED (1 << 8)
|
||||
|
||||
#define MXC_EHCI_INTERNAL_PHY (1 << 9)
|
||||
#define MXC_EHCI_IPPUE_DOWN (1 << 10)
|
||||
#define MXC_EHCI_IPPUE_UP (1 << 11)
|
||||
#define MXC_EHCI_WAKEUP_ENABLED (1 << 12)
|
||||
#define MXC_EHCI_ITC_NO_THRESHOLD (1 << 13)
|
||||
|
||||
enum imx_usb_mode {
|
||||
IMX_USB_MODE_HOST,
|
||||
IMX_USB_MODE_DEVICE,
|
||||
};
|
||||
|
||||
struct imxusb_platformdata {
|
||||
unsigned long flags;
|
||||
enum imx_usb_mode mode;
|
||||
};
|
||||
|
||||
int imx_usbmisc_port_init(int port, unsigned flags);
|
||||
|
||||
#endif /* __USB_CHIPIDEA_IMX_H */
|
|
@ -5,8 +5,21 @@
|
|||
|
||||
struct ehci_platform_data {
|
||||
unsigned long flags;
|
||||
unsigned long hccr_offset;
|
||||
unsigned long hcor_offset;
|
||||
};
|
||||
|
||||
struct ehci_data {
|
||||
void __iomem *hccr;
|
||||
void __iomem *hcor;
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USB_EHCI
|
||||
int ehci_register(struct device_d *dev, struct ehci_data *data);
|
||||
#else
|
||||
static inline int ehci_register(struct device_d *dev, struct ehci_data *data)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_EHCI_H */
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef __MACH_ULPI_H
|
||||
#define __MACH_ULPI_H
|
||||
|
||||
int ulpi_write(u8 bits, int reg, void __iomem *view);
|
||||
int ulpi_set(u8 bits, int reg, void __iomem *view);
|
||||
int ulpi_clear(u8 bits, int reg, void __iomem *view);
|
||||
int ulpi_read(int reg, void __iomem *view);
|
||||
|
@ -11,6 +12,7 @@ int ulpi_setup(void __iomem *view, int on);
|
|||
#define ULPI_VID_HIGH 0x01 /* Vendor ID high */
|
||||
#define ULPI_PID_LOW 0x02 /* Product ID low */
|
||||
#define ULPI_PID_HIGH 0x03 /* Product ID high */
|
||||
#define ULPI_FUNCTION_CTRL 0x04
|
||||
#define ULPI_ITFCTL 0x07 /* Interface Control */
|
||||
#define ULPI_OTGCTL 0x0A /* OTG Control */
|
||||
|
||||
|
@ -18,15 +20,40 @@ int ulpi_setup(void __iomem *view, int on);
|
|||
#define ULPI_REG_SET 0x01
|
||||
#define ULPI_REG_CLEAR 0x02
|
||||
|
||||
/* Function Control */
|
||||
#define ULPI_FC_XCVRSEL_MASK (3 << 0)
|
||||
#define ULPI_FC_HIGH_SPEED (0 << 0)
|
||||
#define ULPI_FC_FULL_SPEED (1 << 0)
|
||||
#define ULPI_FC_LOW_SPEED (2 << 0)
|
||||
#define ULPI_FC_FS4LS (3 << 0)
|
||||
#define ULPI_FC_TERMSELECT (1 << 2)
|
||||
#define ULPI_FC_OPMODE_MASK (3 << 3)
|
||||
#define ULPI_FC_OPMODE_NORMAL (0 << 3)
|
||||
#define ULPI_FC_OPMODE_NONDRIVING (1 << 3)
|
||||
#define ULPI_FC_OPMODE_DISABLE_NRZI (2 << 3)
|
||||
#define ULPI_FC_OPMODE_NOSYNC_NOEOP (3 << 3)
|
||||
#define ULPI_FC_RESET (1 << 5)
|
||||
#define ULPI_FC_SUSPENDM (1 << 6)
|
||||
|
||||
/* Interface Control */
|
||||
#define ULPI_IFACE_6_PIN_SERIAL_MODE (1 << 0)
|
||||
#define ULPI_IFACE_3_PIN_SERIAL_MODE (1 << 1)
|
||||
#define ULPI_IFACE_CARKITMODE (1 << 2)
|
||||
#define ULPI_IFACE_CLOCKSUSPENDM (1 << 3)
|
||||
#define ULPI_IFACE_AUTORESUME (1 << 4)
|
||||
#define ULPI_IFACE_EXTVBUS_COMPLEMENT (1 << 5)
|
||||
#define ULPI_IFACE_PASSTHRU (1 << 6)
|
||||
#define ULPI_IFACE_PROTECT_IFC_DISABLE (1 << 7)
|
||||
|
||||
/* ULPI OTG Control Register bits */
|
||||
#define USE_EXT_VBUS_IND (1 << 7) /* Use ext. Vbus indicator */
|
||||
#define DRV_VBUS_EXT (1 << 6) /* Drive Vbus external */
|
||||
#define DRV_VBUS (1 << 5) /* Drive Vbus */
|
||||
#define CHRG_VBUS (1 << 4) /* Charge Vbus */
|
||||
#define DISCHRG_VBUS (1 << 3) /* Discharge Vbus */
|
||||
#define DM_PULL_DOWN (1 << 2) /* enable DM Pull Down */
|
||||
#define DP_PULL_DOWN (1 << 1) /* enable DP Pull Down */
|
||||
#define ID_PULL_UP (1 << 0) /* enable ID Pull Up */
|
||||
#define ULPI_OTG_USE_EXT_VBUS_IND (1 << 7) /* Use ext. Vbus indicator */
|
||||
#define ULPI_OTG_DRV_VBUS_EXT (1 << 6) /* Drive Vbus external */
|
||||
#define ULPI_OTG_DRV_VBUS (1 << 5) /* Drive Vbus */
|
||||
#define ULPI_OTG_CHRG_VBUS (1 << 4) /* Charge Vbus */
|
||||
#define ULPI_OTG_DISCHRG_VBUS (1 << 3) /* Discharge Vbus */
|
||||
#define ULPI_OTG_DM_PULL_DOWN (1 << 2) /* enable DM Pull Down */
|
||||
#define ULPI_OTG_DP_PULL_DOWN (1 << 1) /* enable DP Pull Down */
|
||||
#define ULPI_OTG_ID_PULL_UP (1 << 0) /* enable ID Pull Up */
|
||||
|
||||
#endif /* __MACH_ULPI_H */
|
||||
|
||||
|
|
|
@ -138,6 +138,9 @@ static int eth_carrier_check(int force)
|
|||
if (!eth_current->phydev)
|
||||
return 0;
|
||||
|
||||
if (force)
|
||||
phy_wait_aneg_done(eth_current->phydev);
|
||||
|
||||
if (force || is_timeout(last_link_check, 5 * SECOND) ||
|
||||
!eth_current->phydev->link) {
|
||||
ret = phy_update_status(eth_current->phydev);
|
||||
|
@ -260,7 +263,7 @@ int eth_register(struct eth_device *edev)
|
|||
edev->dev.id = DEVICE_ID_DYNAMIC;
|
||||
|
||||
if (edev->parent)
|
||||
dev_add_child(edev->parent, &edev->dev);
|
||||
edev->dev.parent = edev->parent;
|
||||
|
||||
register_device(&edev->dev);
|
||||
|
||||
|
|
Loading…
Reference in New Issue