* [RFC PATCH 1/3] USB: Add Generic USB PHY Layer code
2011-12-06 10:43 [RFC PATCH 0/3] Use Generic USB PHY Layer at i.MX Platform Peter Chen
@ 2011-12-06 10:43 ` Peter Chen
2011-12-06 10:43 ` [RFC PATCH 2/3] USB: ehci-mxc: Use new phy structure code for mxc host use Peter Chen
2011-12-06 10:43 ` [RFC PATCH 3/3] ARM: mx51: Create two usb phy platform drivers Peter Chen
2 siblings, 0 replies; 4+ messages in thread
From: Peter Chen @ 2011-12-06 10:43 UTC (permalink / raw)
To: linux-arm-kernel
This code is based on Heikki Krogerus's RFC that
Separate USB transceivers from the OTG utility
(http://www.spinics.net/lists/linux-usb/msg50149.html)
The main changes are:
- Change usb_get_transceiver's parameter from phy's name to related
controller device's name
- Fix some errors, and let it work OK at freescale i.MX51 bbg board.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
drivers/usb/otg/Kconfig | 2 +
drivers/usb/otg/Makefile | 1 +
drivers/usb/otg/phy.c | 368 ++++++++++++++++++++++++++++++++++++++++++++++
include/linux/usb/phy.h | 250 +++++++++++++++++++++++++++++++
4 files changed, 621 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index c66481a..a313dbd 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -130,4 +130,6 @@ config FSL_USB2_OTG
help
Enable this to support Freescale USB OTG transceiver.
+config USB_PHY
+ bool
endif # USB || OTG
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile
index 566655c..6545d6d 100644
--- a/drivers/usb/otg/Makefile
+++ b/drivers/usb/otg/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_TWL6030_USB) += twl6030-usb.o
obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o
obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o
obj-$(CONFIG_USB_ULPI) += ulpi.o
+obj-$(CONFIG_USB_PHY) += phy.o
obj-$(CONFIG_USB_ULPI_VIEWPORT) += ulpi_viewport.o
obj-$(CONFIG_USB_MSM_OTG) += msm_otg.o
obj-$(CONFIG_AB8500_USB) += ab8500-usb.o
diff --git a/drivers/usb/otg/phy.c b/drivers/usb/otg/phy.c
new file mode 100644
index 0000000..8a5f50c
--- /dev/null
+++ b/drivers/usb/otg/phy.c
@@ -0,0 +1,368 @@
+/*
+ * phy.c -- USB Pysical Layer utility code
+ *
+ * Copyright (C) 2011 Intel Corporation
+ *
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/list.h>
+
+#include <linux/usb/phy.h>
+
+static LIST_HEAD(xceiv_list);
+static DEFINE_MUTEX(xceiv_lock);
+
+/* For transceiver drivers */
+
+/*
+ * usb_register_transceiver - add a USB transceiver
+ * @xceiv: the transceiver to be added
+ *
+ * Add new transceiver to the list. USB transceiver drivers call this
+ * after filling struct usb_transceiver.
+ */
+void usb_register_transceiver(struct usb_transceiver *x)
+{
+ mutex_lock(&xceiv_lock);
+
+ list_add_tail(&x->list, &xceiv_list);
+
+ mutex_unlock(&xceiv_lock);
+}
+EXPORT_SYMBOL(usb_register_transceiver);
+
+/*
+ * usb_del_transceiver - remove a USB transceiver from the list
+ * @xceiv: the transceiver to be removed from the list
+ *
+ * Removes a transceiver from the list. USB transceiver drivers will
+ * call this when they are unloading. It is the responsibility of the
+ * driver the ensure there are no users left before calling this.
+ */
+void usb_unregister_transceiver(struct usb_transceiver *xceiv)
+{
+ mutex_lock(&xceiv_lock);
+
+ list_del(&xceiv->list);
+
+ mutex_unlock(&xceiv_lock);
+}
+EXPORT_SYMBOL(usb_unregister_transceiver);
+
+/* For everyone */
+
+/*
+ * usb_get_transceiver - find a USB transceiver
+ * @name: the device name which uses this transceiver
+ *
+ * Returns a transceiver driver matching the name, or NULL, and gets
+ * refcount to it. The caller is responsible for calling
+ * usb_put_transceiver() to release that count.
+ */
+struct usb_transceiver *usb_get_transceiver(const char *name)
+{
+ struct usb_transceiver *xceiv;
+
+ mutex_lock(&xceiv_lock);
+
+ list_for_each_entry(xceiv, &xceiv_list, list) {
+ if (strcmp(xceiv->recv_name, name) == 0) {
+ get_device(xceiv->dev);
+ mutex_unlock(&xceiv_lock);
+ return xceiv;
+ }
+ }
+
+ mutex_unlock(&xceiv_lock);
+
+ return NULL;
+}
+EXPORT_SYMBOL(usb_get_transceiver);
+
+/*
+ * usb_put_transceiver - release a USB transceiver
+ * @xceiv: the transceiver returned by usb_get_transceiver()
+ *
+ * Releases a refcount the caller received from usb_get_transceiver().
+ */
+void usb_put_transceiver(struct usb_transceiver *xceiv)
+{
+ mutex_lock(&xceiv_lock);
+
+ if (xceiv)
+ put_device(xceiv->dev);
+
+ mutex_unlock(&xceiv_lock);
+}
+EXPORT_SYMBOL(usb_put_transceiver);
+
+/* USB charging */
+
+static int usb_charger_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct usb_charger *charger =
+ container_of(psy, struct usb_charger, psy);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = charger->present;
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = charger->online;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ val->intval = charger->max_current;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static enum power_supply_property power_props[] = {
+ POWER_SUPPLY_PROP_PRESENT, /* Charger detected */
+ POWER_SUPPLY_PROP_ONLINE, /* VBUS online */
+ POWER_SUPPLY_PROP_CURRENT_MAX, /* Maximum current in mA */
+};
+
+static void usb_charger_work(struct work_struct *data)
+{
+ int ret;
+ struct usb_charger *charger =
+ container_of(data, struct usb_charger, work);
+ struct usb_transceiver *xceiv =
+ container_of(charger, struct usb_transceiver, charger);
+
+ /**
+ * FIXME: THIS IS ONLY THE CONCEPT
+ */
+
+ if (!charger->online)
+ return;
+
+ mutex_lock(&charger->lock);
+
+ /*
+ * Let the charger know VBUS is online. This will usually
+ * starts data contact detection.
+ */
+ if (charger->connect && charger->connect(charger))
+ goto out;
+
+ /* Start the primary charger detection. */
+ if (charger->detect) {
+ ret = charger->detect(charger);
+ if (ret <= 0)
+ goto out;
+ else
+ charger->present = ret;
+ }
+
+ charger->psy.type = POWER_SUPPLY_TYPE_USB_DCP;
+
+ /* Set charger type (DCP, CDP, SDP...). */
+ if (charger->present && charger->get_type) {
+ ret = charger->get_type(charger);
+ if (ret >= 0)
+ charger->psy.type = ret;
+ }
+out:
+ switch (charger->psy.type) {
+ case POWER_SUPPLY_TYPE_USB_DCP:
+ charger->max_current = 5000; /* FIXME */
+ break;
+ case POWER_SUPPLY_TYPE_USB_CDP:
+ charger->max_current = 500;
+ /* FALLTHROUGH */
+ case POWER_SUPPLY_TYPE_USB:
+ default:
+ if (xceiv->link_connect)
+ xceiv->link_connect(xceiv->link_data);
+ break;
+ }
+
+ power_supply_changed(&charger->psy);
+
+ mutex_unlock(&charger->lock);
+}
+
+/*
+ * usb_create_charger - create a USB charger
+ * @charger: the charger to be initialized
+ * @name: name for the power supply
+ * @supplied_to: the power supplies that use this charger (batteries)
+ * @num_supplicants: number of power supplies using this charger
+ *
+ * Registers a power supply for the charger. The charger driver will
+ * call this after filling struct usb_charger. All the users are
+ * expected to be in the supplied_to parameter.
+ *
+ * There is no expectation for charger detection capability. USB as
+ * B-peripheral will always supply power. If charger detection is
+ * supported, the driver will fill the appropriate callbacks in the
+ * struct usb_charger.
+ *
+ * A transceiver will always contain the charger, was it used or not.
+ * The charger detection may be done in the transceiver hw or it may
+ * be done in a completely separate hw block. In any case, a charger
+ * is always linked with a transceiver as a transceiver will always
+ * represent the USB PHY where the power is actually coming.
+ */
+int usb_create_charger(struct usb_charger *charger,
+ const char *name,
+ char **supplied_to,
+ size_t num_supplicants)
+{
+ int ret;
+ struct power_supply *psy = &charger->psy;
+ struct usb_transceiver *xceiv =
+ container_of(charger, struct usb_transceiver, charger);
+
+ if (!charger->dev)
+ return -EINVAL;
+
+ if (name)
+ psy->name = name;
+ else
+ psy->name = "usb";
+ psy->type = POWER_SUPPLY_TYPE_USB;
+ psy->properties = power_props;
+ psy->num_properties = ARRAY_SIZE(power_props);
+ psy->get_property = usb_charger_get_property;
+
+ psy->supplied_to = supplied_to;
+ psy->num_supplicants = num_supplicants;
+
+ ret = power_supply_register(charger->dev, psy);
+ if (ret)
+ goto fail;
+
+ mutex_init(&charger->lock);
+ INIT_WORK(&charger->work, usb_charger_work);
+
+ xceiv->has_charger = 1;
+fail:
+ return ret;
+}
+EXPORT_SYMBOL(usb_create_charger);
+
+/*
+ * usb_remove_charger - remove a USB charger
+ * @charger: the charger to be removed
+ *
+ * Unregister the chargers power supply.
+ */
+void usb_remove_charger(struct usb_charger *charger)
+{
+ struct usb_transceiver *xceiv =
+ container_of(charger, struct usb_transceiver, charger);
+
+ if (!xceiv->has_charger)
+ return;
+
+ power_supply_unregister(&charger->psy);
+ xceiv->has_charger = 0;
+}
+EXPORT_SYMBOL(usb_remove_charger);
+
+/*
+ * usb_set_power - Set the maximum power allowed to draw
+ * @xceiv: the transceiver containing the charger
+ * @mA: maximum current in milliamps
+ *
+ * Called from the controller after enumeration to inform the maximum
+ * power from the configuration, after bus suspend and resume.
+ */
+int usb_set_power(struct usb_transceiver *xceiv, unsigned mA)
+{
+ struct usb_charger *charger = &xceiv->charger;
+
+ /**
+ * FIXME: THIS IS ONLY THE CONCEPT
+ */
+
+ if (!xceiv->has_charger || !charger->online)
+ return 0;
+
+ if (charger->max_current == mA)
+ return 0;
+
+ /* If the charger is present, this is a CDP charger */
+ /* FIXME: Check the charger type. */
+ /* FIXME: When the bus is suspended, the current needs to be handled */
+ if (charger->present)
+ charger->max_current = 5000; /* FIXME */
+ else
+ charger->max_current = mA;
+
+ if (charger->set_power)
+ charger->set_power(charger, mA);
+
+ power_supply_changed(&charger->psy);
+
+ return 0;
+}
+EXPORT_SYMBOL(usb_set_power);
+
+/*
+ * usb_vbus_connect - inform about VBUS connection
+ * @xceiv: the transceiver containing the charger
+ *
+ * Inform the charger VBUS is connected. The USB device controller is
+ * expected to keep the dataline pullups disabled until link_connect()
+ * is called.
+ */
+int usb_vbus_connect(struct usb_transceiver *xceiv)
+{
+ struct usb_charger *charger = &xceiv->charger;
+
+ if (!xceiv->has_charger) {
+ if (xceiv->link_connect)
+ xceiv->link_connect(xceiv->link_data);
+ return 0;
+ }
+
+ charger->online = 1;
+ schedule_work(&charger->work);
+
+ return 0;
+}
+EXPORT_SYMBOL(usb_vbus_connect);
+
+/*
+ * usb_vbus_disconnect - inform about VBUS disconnection
+ * @xceiv: the transceiver containing the charger
+ *
+ * Inform the charger that VBUS is disconnected. The charging will be
+ * stopped and the charger properties cleared.
+ */
+int usb_vbus_disconnect(struct usb_transceiver *xceiv)
+{
+ struct usb_charger *charger = &xceiv->charger;
+
+ if (!xceiv->has_charger)
+ return 0;
+
+ charger->online = 0;
+ charger->present = 0;
+ charger->max_current = 0;
+ charger->psy.type = POWER_SUPPLY_TYPE_USB;
+
+ if (charger->disconnect)
+ charger->disconnect(charger);
+
+ power_supply_changed(&charger->psy);
+
+ return 0;
+}
+EXPORT_SYMBOL(usb_vbus_disconnect);
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
new file mode 100644
index 0000000..f0f4ecf
--- /dev/null
+++ b/include/linux/usb/phy.h
@@ -0,0 +1,250 @@
+
+#ifndef __LINUX_USB_PHY_H
+#define __LINUX_USB_PHY_H
+
+#include <linux/power_supply.h>
+
+struct usb_transceiver;
+
+struct usb_xceiv_io_ops {
+ int (*read)(struct usb_transceiver *xceiv, u32 reg);
+ int (*write)(struct usb_transceiver *xceiv, u32 val, u32 reg);
+};
+
+enum usb_xceiv_interface {
+ USB_XCEIV_UNDEF,
+ USB_XCEIV_UTMI,
+ USB_XCEIV_UTMIPLUS,
+ USB_XCEIV_ULPI,
+ USB_XCEIV_SIE,
+};
+
+enum battery_charging_spec {
+ BATTERY_CHARGING_SPEC_NONE = 0,
+ BATTERY_CHARGING_SPEC_UNKNOWN,
+ BATTERY_CHARGING_SPEC_1_0,
+ BATTERY_CHARGING_SPEC_1_1,
+ BATTERY_CHARGING_SPEC_1_2,
+};
+
+struct usb_charger {
+ struct device *dev;
+ struct power_supply psy;
+ struct work_struct work;
+ struct mutex lock;
+
+ /* Compliant with Battery Charging Specification version (if any) */
+ enum battery_charging_spec bc;
+
+ /* properties */
+ unsigned present:1;
+ unsigned online:1;
+ unsigned max_current;
+
+ int (*connect)(struct usb_charger *charger);
+ int (*disconnect)(struct usb_charger *charger);
+ int (*set_power)(struct usb_charger *charger, unsigned mA);
+
+ int (*detect)(struct usb_charger *charger);
+ int (*get_type)(struct usb_charger *charger);
+ /*void (*detect_aca)(struct usb_charger *charger);*/
+};
+
+struct usb_transceiver {
+ struct device *dev;
+ /* the device name of related usb controller */
+ char *recv_name;
+
+ struct list_head list;
+ struct usb_charger charger;
+ unsigned has_charger:1;
+
+ unsigned long link_data;
+ unsigned int flags;
+
+ /*
+ * For hw platforms where the transceiver needs to take care
+ * of some of the OTG protocols.
+ */
+ struct otg *otg;
+
+ enum usb_xceiv_interface interface;
+
+ struct usb_xceiv_io_ops *io_ops;
+ void __iomem *io_priv;
+
+ /* Initialize/shutdown the USB transceiver */
+ int (*init)(struct usb_transceiver *xceiv);
+ int (*shutdown)(struct usb_transceiver *xceiv);
+
+ /* set transceiver into suspend mode */
+ int (*set_suspend)(struct usb_transceiver *xceiv,
+ int suspend);
+ /* effective for A-peripheral, ignored for B devices */
+ int (*set_vbus)(struct usb_transceiver *xceiv,
+ bool enabled);
+
+ /* Called by the PHY utility code when it's safe to connect */
+ void (*link_connect)(unsigned long data);
+
+ /* UTMI+ OTG control functions */
+ int (*id_pullup)(struct usb_transceiver *xceiv, int on);
+ int (*dp_pulldown)(struct usb_transceiver *xceiv, int on);
+ int (*dm_pulldown)(struct usb_transceiver *xceiv, int on);
+ int (*dischrg_vbus)(struct usb_transceiver *xceiv, int on);
+ int (*chrg_vbus)(struct usb_transceiver *xceiv, int on);
+ int (*drv_vbus)(struct usb_transceiver *xceiv, int on);
+};
+
+/* helpers for direct access thru low-level io interface */
+static inline int xceiv_io_read(struct usb_transceiver *xceiv, u32 reg)
+{
+ if (xceiv->io_ops && xceiv->io_ops->read)
+ return xceiv->io_ops->read(xceiv, reg);
+
+ return -EINVAL;
+}
+
+static inline int xceiv_io_write(struct usb_transceiver *xceiv, u32 val, u32 reg)
+{
+ if (xceiv->io_ops && xceiv->io_ops->write)
+ return xceiv->io_ops->write(xceiv, val, reg);
+
+ return -EINVAL;
+}
+/* Prototypes */
+extern void usb_register_transceiver(struct usb_transceiver *x);
+extern void usb_unregister_transceiver(struct usb_transceiver *xceiv);
+extern struct usb_transceiver *usb_get_transceiver(const char *name);
+extern void usb_put_transceiver(struct usb_transceiver *xceiv);
+
+extern int usb_set_power(struct usb_transceiver *xceiv, unsigned mA);
+extern int usb_vbus_connect(struct usb_transceiver *xceiv);
+extern int usb_vbus_disconnect(struct usb_transceiver *xceiv);
+
+/* Helpers for USB transceiver initialization and powering */
+
+/*
+ * ULPI transceivers will need ULPI access from the controller. When the
+ * controller is initialized, the controller driver will fill the
+ * usb_xceiv_io_ops and call this.
+ */
+static inline int
+usb_transceiver_init(struct usb_transceiver *xceiv)
+{
+ if (xceiv->init)
+ return xceiv->init(xceiv);
+ return 0;
+}
+
+/*
+ * This is a wrapper that the controller driver can use to deliver all
+ * the required variables to the transceiver.
+ */
+static inline int
+usb_start_transceiver(struct usb_transceiver *xceiv,
+ struct usb_xceiv_io_ops *io_ops,
+ void __iomem *io_priv,
+ void (*link_connect)(unsigned long),
+ unsigned long link_data)
+{
+ xceiv->io_ops = io_ops;
+ xceiv->io_priv = io_priv;
+ xceiv->link_connect = link_connect;
+ xceiv->link_data = link_data;
+
+ if (xceiv->init)
+ return xceiv->init(xceiv);
+
+ return 0;
+}
+
+/*
+ * REVISIT With ULPI transceivers, the controller should still be able to allow
+ * ULPI reads and writes before calling this.
+ */
+static inline int
+usb_transceiver_shutdown(struct usb_transceiver *xceiv)
+{
+ if (xceiv->shutdown)
+ return xceiv->shutdown(xceiv);
+ return 0;
+}
+
+static inline int
+usb_transceiver_set_suspend(struct usb_transceiver *xceiv, int suspend)
+{
+ if (xceiv->set_suspend)
+ return xceiv->set_suspend(xceiv, suspend);
+ return 0;
+}
+
+/* Helpers for OTG capable transceivers */
+
+/*
+ * xceiv_to_otg - return struct otg member
+ * @xceiv: USB transceiver
+ *
+ * Simple helper that can be used with other drivers that need to
+ * access the otg structure. One case would be separate host
+ * controller drivers. If the device controller driver holds the
+ * struct otg, the struct usb_transceiver can be used to deliver it to
+ * the host controller drivers.
+ */
+static inline struct otg
+*xceiv_to_otg(struct usb_transceiver *xceiv)
+{
+ if (xceiv && xceiv->otg)
+ return xceiv->otg;
+ return NULL;
+}
+
+static inline int
+usb_phy_id_pullup(struct usb_transceiver *xceiv, int on)
+{
+ if (xceiv->id_pullup)
+ return xceiv->id_pullup(xceiv, on);
+ return -ENOTSUPP;
+}
+
+static inline int
+usb_phy_dp_pulldown(struct usb_transceiver *xceiv, int on)
+{
+ if (xceiv->dp_pulldown)
+ return xceiv->dp_pulldown(xceiv, on);
+ return -ENOTSUPP;
+}
+
+static inline int
+usb_phy_dm_pulldown(struct usb_transceiver *xceiv, int on)
+{
+ if (xceiv->dm_pulldown)
+ return xceiv->dm_pulldown(xceiv, on);
+ return -ENOTSUPP;
+}
+
+static inline int
+usb_phy_dischrg_vbus(struct usb_transceiver *xceiv, int on)
+{
+ if (xceiv->dischrg_vbus)
+ return xceiv->dischrg_vbus(xceiv, on);
+ return -ENOTSUPP;
+}
+
+static inline int
+usb_phy_chrg_vbus(struct usb_transceiver *xceiv, int on)
+{
+ if (xceiv->chrg_vbus)
+ return xceiv->chrg_vbus(xceiv, on);
+ return -ENOTSUPP;
+}
+
+static inline int
+usb_phy_drv_vbus(struct usb_transceiver *xceiv, int on)
+{
+ if (xceiv->drv_vbus)
+ return xceiv->drv_vbus(xceiv, on);
+ return -ENOTSUPP;
+}
+
+#endif /* __LINUX_USB_PHY_H */
--
1.6.3.3
^ permalink raw reply related [flat|nested] 4+ messages in thread* [RFC PATCH 3/3] ARM: mx51: Create two usb phy platform drivers
2011-12-06 10:43 [RFC PATCH 0/3] Use Generic USB PHY Layer at i.MX Platform Peter Chen
2011-12-06 10:43 ` [RFC PATCH 1/3] USB: Add Generic USB PHY Layer code Peter Chen
2011-12-06 10:43 ` [RFC PATCH 2/3] USB: ehci-mxc: Use new phy structure code for mxc host use Peter Chen
@ 2011-12-06 10:43 ` Peter Chen
2 siblings, 0 replies; 4+ messages in thread
From: Peter Chen @ 2011-12-06 10:43 UTC (permalink / raw)
To: linux-arm-kernel
This patch creates two usb phy platform driver: utmi and ulpi.
And this code is to show how generic phy layer work, so I haven't
extracted all plat/mach code to mxc phy driver, and current change
can only work at i.mx51 bbg board
For further, It needs to refine this patch when going to mainline
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
arch/arm/mach-mx5/Kconfig | 4 +
arch/arm/mach-mx5/board-mx51_babbage.c | 33 ++++++-
arch/arm/plat-mxc/Makefile | 1 +
arch/arm/plat-mxc/devices/Kconfig | 6 +
arch/arm/plat-mxc/devices/Makefile | 2 +
arch/arm/plat-mxc/devices/platform-fsl-phy-ulpi.c | 18 +++
arch/arm/plat-mxc/devices/platform-fsl-phy-utmi.c | 18 +++
arch/arm/plat-mxc/include/mach/devices-common.h | 5 +
arch/arm/plat-mxc/include/mach/mxc_phy.h | 20 ++++
arch/arm/plat-mxc/include/mach/ulpi.h | 11 --
arch/arm/plat-mxc/ulpi.c | 114 ++++++++++++++++++--
arch/arm/plat-mxc/utmi.c | 121 +++++++++++++++++++++
drivers/usb/otg/ulpi.c | 99 +++++++++---------
13 files changed, 380 insertions(+), 72 deletions(-)
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index af0c212..b7c0449 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -67,6 +67,7 @@ config MACH_IMX51_DT
config MACH_MX51_BABBAGE
bool "Support MX51 BABBAGE platforms"
+ select MXC_ULPI if USB_ULPI
select SOC_IMX51
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
@@ -75,6 +76,9 @@ config MACH_MX51_BABBAGE
select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_USB_PHY_ULPI
+ select IMX_HAVE_PLATFORM_USB_PHY_UTMI
+ select USB_PHY
help
Include support for MX51 Babbage platform, also known as MX51EVK in
u-boot. This includes specific configurations for the board and its
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
index 5c83760..35453f3 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -23,6 +23,8 @@
#include <mach/common.h>
#include <mach/hardware.h>
#include <mach/iomux-mx51.h>
+#include <mach/ulpi.h>
+#include <mach/mxc_phy.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
@@ -243,6 +245,11 @@ be different for other Freescale SoCs, thus a common bitmask is not
possible and cannot get place in /plat-mxc/ehci.c.*/
static int initialize_otg_port(struct platform_device *pdev)
{
+ return mx51_initialize_usb_hw(0, MXC_EHCI_INTERNAL_PHY);
+}
+
+static int mx51_utmi_init(void)
+{
u32 v;
void __iomem *usb_base;
void __iomem *usbother_base;
@@ -261,7 +268,8 @@ static int initialize_otg_port(struct platform_device *pdev)
mdelay(10);
- return mx51_initialize_usb_hw(0, MXC_EHCI_INTERNAL_PHY);
+ /* Other UTMI phy setting, like wakeup, OC, etc */
+ return 0;
}
static int initialize_usbh1_port(struct platform_device *pdev)
@@ -291,6 +299,14 @@ static const struct mxc_usbh_platform_data dr_utmi_config __initconst = {
.portsc = MXC_EHCI_UTMI_16BIT,
};
+static int mx51_bbg_otg_set_vbus(bool on)
+{
+ /* don't needed at mx51 bbg since it is controlled by ID pin
+ * automatically
+ */
+ return 0;
+}
+
static const struct fsl_usb2_platform_data usb_pdata __initconst = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_UTMI_WIDE,
@@ -301,6 +317,18 @@ static const struct mxc_usbh_platform_data usbh1_config __initconst = {
.portsc = MXC_EHCI_MODE_ULPI,
};
+static const struct fsl_usb_phy_utmi_platform_data phy_utmi_pdata __initconst = {
+ .recv_name = "mxc-ehci.0",
+ .otg_set_vbus = mx51_bbg_otg_set_vbus,
+ .utmi_init = mx51_utmi_init,
+ .flags = 0,
+};
+
+static const struct fsl_usb_phy_ulpi_platform_data phy_ulpi_pdata __initconst = {
+ .recv_name = "mxc-ehci.1",
+ .flags = 0,
+};
+
static int otg_mode_host;
static int __init babbage_otg_mode(char *options)
@@ -395,6 +423,9 @@ static void __init mx51_babbage_init(void)
gpio_usbh1_active();
imx51_add_mxc_ehci_hs(1, &usbh1_config);
+
+ imx_add_usb_phy_utmi(&phy_utmi_pdata);
+ imx_add_usb_phy_ulpi(&phy_ulpi_pdata);
/* setback USBH1_STP to be function */
mxc_iomux_v3_setup_pad(usbh1stp);
babbage_usbhub_reset();
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index b9f0f5f..f661bf4 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
obj-$(CONFIG_MXC_PWM) += pwm.o
obj-$(CONFIG_MXC_ULPI) += ulpi.o
+obj-$(CONFIG_MXC_ULPI) += utmi.o
obj-$(CONFIG_MXC_USE_EPIT) += epit.o
obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
index cb3e3ee..9cf482e 100644
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -80,6 +80,12 @@ config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
config IMX_HAVE_PLATFORM_SPI_IMX
bool
+config IMX_HAVE_PLATFORM_USB_PHY_ULPI
+ bool
+
+config IMX_HAVE_PLATFORM_USB_PHY_UTMI
+ bool
+
config IMX_HAVE_PLATFORM_AHCI
bool
default y if ARCH_MX53
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
index c11ac84..f2f3d7c 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -27,3 +27,5 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) += platform-ahci-imx.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_USB_PHY_ULPI) += platform-fsl-phy-ulpi.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_USB_PHY_UTMI) += platform-fsl-phy-utmi.o
diff --git a/arch/arm/plat-mxc/devices/platform-fsl-phy-ulpi.c b/arch/arm/plat-mxc/devices/platform-fsl-phy-ulpi.c
new file mode 100644
index 0000000..9ea6738
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-fsl-phy-ulpi.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Peter Chen <peter.chen@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/dma-mapping.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+struct platform_device *__init imx_add_usb_phy_ulpi(
+ const struct fsl_usb_phy_ulpi_platform_data *pdata)
+{
+ return imx_add_platform_device("imx-phy-ulpi", -1, NULL,
+ 0, pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-fsl-phy-utmi.c b/arch/arm/plat-mxc/devices/platform-fsl-phy-utmi.c
new file mode 100644
index 0000000..1f73a3f
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-fsl-phy-utmi.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Peter Chen <peter.chen@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/dma-mapping.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+struct platform_device *__init imx_add_usb_phy_utmi(
+ const struct fsl_usb_phy_utmi_platform_data *pdata)
+{
+ return imx_add_platform_device("imx-phy-utmi", -1, NULL,
+ 0, pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index def9ba5..cbb0d27 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -233,7 +233,12 @@ struct imx_mxc_ehci_data {
struct platform_device *__init imx_add_mxc_ehci(
const struct imx_mxc_ehci_data *data,
const struct mxc_usbh_platform_data *pdata);
+#include <mach/mxc_phy.h>
+struct platform_device *__init imx_add_usb_phy_ulpi(
+ const struct fsl_usb_phy_ulpi_platform_data *pdata);
+struct platform_device *__init imx_add_usb_phy_utmi(
+ const struct fsl_usb_phy_utmi_platform_data *pdata);
#include <mach/mmc.h>
struct imx_mxc_mmc_data {
int id;
diff --git a/arch/arm/plat-mxc/include/mach/mxc_phy.h b/arch/arm/plat-mxc/include/mach/mxc_phy.h
new file mode 100644
index 0000000..821edaa
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_phy.h
@@ -0,0 +1,20 @@
+#ifndef __INCLUDE_ASM_ARCH_MXC_PHY_H
+#define __INCLUDE_ASM_ARCH_MXC_PHY_H
+
+#include <linux/usb/phy.h>
+struct fsl_usb_phy_ulpi_platform_data {
+#define MAX_NAME_LEN 16
+ /* the device name of related usb controller */
+ char recv_name[MAX_NAME_LEN];
+ u32 flags;
+};
+struct fsl_usb_phy_utmi_platform_data {
+#define MAX_NAME_LEN 16
+ /* the device name of related usb controller */
+ char recv_name[MAX_NAME_LEN];
+ u32 flags;
+ int (*otg_set_vbus)(bool on);
+ int (*utmi_init)(void);
+};
+#endif /* __INCLUDE_ASM_ARCH_MXC_PHY_H */
+
diff --git a/arch/arm/plat-mxc/include/mach/ulpi.h b/arch/arm/plat-mxc/include/mach/ulpi.h
index f9161c9..4c041ca 100644
--- a/arch/arm/plat-mxc/include/mach/ulpi.h
+++ b/arch/arm/plat-mxc/include/mach/ulpi.h
@@ -1,16 +1,5 @@
#ifndef __MACH_ULPI_H
#define __MACH_ULPI_H
-#ifdef CONFIG_USB_ULPI
-struct otg_transceiver *imx_otg_ulpi_create(unsigned int flags);
-#else
-static inline struct otg_transceiver *imx_otg_ulpi_create(unsigned int flags)
-{
- return NULL;
-}
-#endif
-
-extern struct otg_io_access_ops mxc_ulpi_access_ops;
-
#endif /* __MACH_ULPI_H */
diff --git a/arch/arm/plat-mxc/ulpi.c b/arch/arm/plat-mxc/ulpi.c
index 477e45b..8e08a20 100644
--- a/arch/arm/plat-mxc/ulpi.c
+++ b/arch/arm/plat-mxc/ulpi.c
@@ -16,15 +16,21 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/delay.h>
-#include <linux/usb/otg.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/usb/phy.h>
#include <linux/usb/ulpi.h>
-#include <mach/ulpi.h>
+#include <mach/mxc_phy.h>
+
+#include "../drivers/usb/otg/ulpi.c"
+
+#define DRIVER_DESC "i.MX USB Transceiver ULPI Driver"
+#define DRIVER_AUTHOR "Sascha Hauer/Daniel Mack"
/* ULPIVIEW register bits */
#define ULPIVW_WU (1 << 31) /* Wakeup */
@@ -40,6 +46,9 @@
#define ULPIVW_WDATA_MASK 0xff /* write data field */
#define ULPIVW_WDATA_SHIFT 0
+static const char driver_name[] = "imx-phy-ulpi";
+static const char driver_desc[] = DRIVER_DESC;
+
static int ulpi_poll(void __iomem *view, u32 bit)
{
int timeout = 10000;
@@ -58,10 +67,10 @@ static int ulpi_poll(void __iomem *view, u32 bit)
return -ETIMEDOUT;
}
-static int ulpi_read(struct otg_transceiver *otg, u32 reg)
+static int ulpi_read(struct usb_transceiver *xceiv, u32 reg)
{
int ret;
- void __iomem *view = otg->io_priv;
+ void __iomem *view = xceiv->io_priv;
/* make sure interface is running */
if (!(__raw_readl(view) & ULPIVW_SS)) {
@@ -84,10 +93,10 @@ static int ulpi_read(struct otg_transceiver *otg, u32 reg)
return (__raw_readl(view) >> ULPIVW_RDATA_SHIFT) & ULPIVW_RDATA_MASK;
}
-static int ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg)
+static int ulpi_write(struct usb_transceiver *xceiv, u32 val, u32 reg)
{
int ret;
- void __iomem *view = otg->io_priv;
+ void __iomem *view = xceiv->io_priv;
/* make sure the interface is running */
if (!(__raw_readl(view) & ULPIVW_SS)) {
@@ -106,13 +115,96 @@ static int ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg)
return ulpi_poll(view, ULPIVW_RUN);
}
-struct otg_io_access_ops mxc_ulpi_access_ops = {
+struct usb_xceiv_io_ops mxc_ulpi_access_ops = {
.read = ulpi_read,
.write = ulpi_write,
};
-EXPORT_SYMBOL_GPL(mxc_ulpi_access_ops);
-struct otg_transceiver *imx_otg_ulpi_create(unsigned int flags)
+static int imx_ulpi_probe(struct platform_device *pdev)
+{
+ struct usb_transceiver *xceiv;
+ struct fsl_usb_phy_ulpi_platform_data *pdata = pdev->dev.platform_data;
+ int ret = 0;
+
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+ printk("%s", __func__);
+
+ xceiv = kzalloc(sizeof(*xceiv), GFP_KERNEL);
+ if (!xceiv)
+ return -ENOMEM;
+
+ xceiv->recv_name = kmalloc(sizeof(pdata->recv_name), GFP_KERNEL);
+ if (!xceiv->recv_name) {
+ ret = -ENOMEM;
+ goto out_of_mem;
+ }
+ strncpy(xceiv->recv_name, pdata->recv_name, sizeof(pdata->recv_name));
+
+ xceiv->flags = pdata->flags;
+ xceiv->io_ops = &mxc_ulpi_access_ops;
+ xceiv->interface = USB_XCEIV_ULPI;
+ xceiv->init = ulpi_init;
+ xceiv->set_vbus = ulpi_set_vbus;
+
+ platform_set_drvdata(pdev, xceiv);
+
+ usb_register_transceiver(xceiv);
+
+out_of_mem:
+ return ret;
+}
+
+static int imx_ulpi_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+ return 0;
+}
+
+static int imx_ulpi_resume(struct platform_device *pdev)
+{
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+ return 0;
+}
+
+static int __exit imx_ulpi_remove(struct platform_device *pdev)
+{
+ struct usb_transceiver *xceiv = platform_get_drvdata(pdev);
+
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+ usb_unregister_transceiver(xceiv);
+
+ return 0;
+}
+
+static struct platform_driver ulpi_driver = {
+ .probe = imx_ulpi_probe,
+ .remove = __exit_p(imx_ulpi_remove),
+ .suspend = imx_ulpi_suspend,
+ .resume = imx_ulpi_resume,
+ .driver = {
+ .name = (char *)driver_name,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init imx_ulpi_init(void)
{
- return otg_ulpi_create(&mxc_ulpi_access_ops, flags);
+ printk(KERN_INFO "%s Initilizes\n", driver_desc);
+ return platform_driver_register(&ulpi_driver);
}
+
+module_init(imx_ulpi_init);
+
+static void __exit imx_ulpi_exit(void)
+{
+ platform_driver_unregister(&ulpi_driver);
+}
+
+module_exit(imx_ulpi_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/plat-mxc/utmi.c b/arch/arm/plat-mxc/utmi.c
new file mode 100644
index 0000000..3735e54
--- /dev/null
+++ b/arch/arm/plat-mxc/utmi.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Peter Chen <peter.chen@freescale.com>
+
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/usb/phy.h>
+
+#include <mach/mxc_phy.h>
+
+
+#define DRIVER_DESC "i.MX USB Transceiver UTMI Driver"
+#define DRIVER_AUTHOR "Peter Chen"
+
+static const char driver_name[] = "imx-phy-utmi";
+static const char driver_desc[] = DRIVER_DESC;
+
+static int imx_utmi_probe(struct platform_device *pdev)
+{
+ struct usb_transceiver *xceiv;
+ struct fsl_usb_phy_utmi_platform_data *pdata = pdev->dev.platform_data;
+ int ret = 0;
+
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+ xceiv = kzalloc(sizeof(*xceiv), GFP_KERNEL);
+ if (!xceiv)
+ return -ENOMEM;
+
+ xceiv->recv_name = kmalloc(sizeof(pdata->recv_name), GFP_KERNEL);
+ if (!xceiv->recv_name) {
+ ret = -ENOMEM;
+ goto out_of_mem;
+ }
+ strncpy(xceiv->recv_name, pdata->recv_name, sizeof(pdata->recv_name));
+
+ xceiv->flags = pdata->flags;
+ xceiv->set_vbus = pdata->otg_set_vbus;
+ xceiv->init = pdata->utmi_init;
+ xceiv->interface = USB_XCEIV_UTMIPLUS;
+
+ platform_set_drvdata(pdev, xceiv);
+
+ usb_register_transceiver(xceiv);
+
+out_of_mem:
+ return ret;
+}
+
+static int imx_utmi_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+ return 0;
+}
+
+static int imx_utmi_resume(struct platform_device *pdev)
+{
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+ return 0;
+}
+
+static int __exit imx_utmi_remove(struct platform_device *pdev)
+{
+ struct usb_transceiver *xceiv = platform_get_drvdata(pdev);
+
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+ usb_unregister_transceiver(xceiv);
+
+ return 0;
+}
+
+static struct platform_driver utmi_driver = {
+ .probe = imx_utmi_probe,
+ .remove = __exit_p(imx_utmi_remove),
+ .suspend = imx_utmi_suspend,
+ .resume = imx_utmi_resume,
+ .driver = {
+ .name = (char *)driver_name,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init imx_utmi_init(void)
+{
+ printk(KERN_INFO "%s Initilizes\n", driver_desc);
+ return platform_driver_register(&utmi_driver);
+}
+
+module_init(imx_utmi_init);
+
+static void __exit imx_utmi_exit(void)
+{
+ platform_driver_unregister(&utmi_driver);
+}
+
+module_exit(imx_utmi_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c
index 0b04667..1254ca2 100644
--- a/drivers/usb/otg/ulpi.c
+++ b/drivers/usb/otg/ulpi.c
@@ -27,10 +27,10 @@
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/usb.h>
+#include <linux/usb/phy.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
-
struct ulpi_info {
unsigned int id;
char *name;
@@ -49,31 +49,31 @@ static struct ulpi_info ulpi_ids[] = {
ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"),
};
-static int ulpi_set_otg_flags(struct otg_transceiver *otg)
+static int ulpi_set_xceiv_flags(struct usb_transceiver *xceiv)
{
unsigned int flags = ULPI_OTG_CTRL_DP_PULLDOWN |
ULPI_OTG_CTRL_DM_PULLDOWN;
- if (otg->flags & ULPI_OTG_ID_PULLUP)
+ if (xceiv->flags & ULPI_OTG_ID_PULLUP)
flags |= ULPI_OTG_CTRL_ID_PULLUP;
/*
* ULPI Specification rev.1.1 default
* for Dp/DmPulldown is enabled.
*/
- if (otg->flags & ULPI_OTG_DP_PULLDOWN_DIS)
+ if (xceiv->flags & ULPI_OTG_DP_PULLDOWN_DIS)
flags &= ~ULPI_OTG_CTRL_DP_PULLDOWN;
- if (otg->flags & ULPI_OTG_DM_PULLDOWN_DIS)
+ if (xceiv->flags & ULPI_OTG_DM_PULLDOWN_DIS)
flags &= ~ULPI_OTG_CTRL_DM_PULLDOWN;
- if (otg->flags & ULPI_OTG_EXTVBUSIND)
+ if (xceiv->flags & ULPI_OTG_EXTVBUSIND)
flags |= ULPI_OTG_CTRL_EXTVBUSIND;
- return otg_io_write(otg, flags, ULPI_OTG_CTRL);
+ return xceiv_io_write(xceiv, flags, ULPI_OTG_CTRL);
}
-static int ulpi_set_fc_flags(struct otg_transceiver *otg)
+static int ulpi_set_fc_flags(struct usb_transceiver *xceiv)
{
unsigned int flags = 0;
@@ -81,27 +81,27 @@ static int ulpi_set_fc_flags(struct otg_transceiver *otg)
* ULPI Specification rev.1.1 default
* for XcvrSelect is Full Speed.
*/
- if (otg->flags & ULPI_FC_HS)
+ if (xceiv->flags & ULPI_FC_HS)
flags |= ULPI_FUNC_CTRL_HIGH_SPEED;
- else if (otg->flags & ULPI_FC_LS)
+ else if (xceiv->flags & ULPI_FC_LS)
flags |= ULPI_FUNC_CTRL_LOW_SPEED;
- else if (otg->flags & ULPI_FC_FS4LS)
+ else if (xceiv->flags & ULPI_FC_FS4LS)
flags |= ULPI_FUNC_CTRL_FS4LS;
else
flags |= ULPI_FUNC_CTRL_FULL_SPEED;
- if (otg->flags & ULPI_FC_TERMSEL)
+ if (xceiv->flags & ULPI_FC_TERMSEL)
flags |= ULPI_FUNC_CTRL_TERMSELECT;
/*
* ULPI Specification rev.1.1 default
* for OpMode is Normal Operation.
*/
- if (otg->flags & ULPI_FC_OP_NODRV)
+ if (xceiv->flags & ULPI_FC_OP_NODRV)
flags |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING;
- else if (otg->flags & ULPI_FC_OP_DIS_NRZI)
+ else if (xceiv->flags & ULPI_FC_OP_DIS_NRZI)
flags |= ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI;
- else if (otg->flags & ULPI_FC_OP_NSYNC_NEOP)
+ else if (xceiv->flags & ULPI_FC_OP_NSYNC_NEOP)
flags |= ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP;
else
flags |= ULPI_FUNC_CTRL_OPMODE_NORMAL;
@@ -112,54 +112,54 @@ static int ulpi_set_fc_flags(struct otg_transceiver *otg)
*/
flags |= ULPI_FUNC_CTRL_SUSPENDM;
- return otg_io_write(otg, flags, ULPI_FUNC_CTRL);
+ return xceiv_io_write(xceiv, flags, ULPI_FUNC_CTRL);
}
-static int ulpi_set_ic_flags(struct otg_transceiver *otg)
+static int ulpi_set_ic_flags(struct usb_transceiver *xceiv)
{
unsigned int flags = 0;
- if (otg->flags & ULPI_IC_AUTORESUME)
+ if (xceiv->flags & ULPI_IC_AUTORESUME)
flags |= ULPI_IFC_CTRL_AUTORESUME;
- if (otg->flags & ULPI_IC_EXTVBUS_INDINV)
+ if (xceiv->flags & ULPI_IC_EXTVBUS_INDINV)
flags |= ULPI_IFC_CTRL_EXTERNAL_VBUS;
- if (otg->flags & ULPI_IC_IND_PASSTHRU)
+ if (xceiv->flags & ULPI_IC_IND_PASSTHRU)
flags |= ULPI_IFC_CTRL_PASSTHRU;
- if (otg->flags & ULPI_IC_PROTECT_DIS)
+ if (xceiv->flags & ULPI_IC_PROTECT_DIS)
flags |= ULPI_IFC_CTRL_PROTECT_IFC_DISABLE;
- return otg_io_write(otg, flags, ULPI_IFC_CTRL);
+ return xceiv_io_write(xceiv, flags, ULPI_IFC_CTRL);
}
-static int ulpi_set_flags(struct otg_transceiver *otg)
+static int ulpi_set_flags(struct usb_transceiver *xceiv)
{
int ret;
- ret = ulpi_set_otg_flags(otg);
+ ret = ulpi_set_xceiv_flags(xceiv);
if (ret)
return ret;
- ret = ulpi_set_ic_flags(otg);
+ ret = ulpi_set_ic_flags(xceiv);
if (ret)
return ret;
- return ulpi_set_fc_flags(otg);
+ return ulpi_set_fc_flags(xceiv);
}
-static int ulpi_check_integrity(struct otg_transceiver *otg)
+static int ulpi_check_integrity(struct usb_transceiver *xceiv)
{
int ret, i;
unsigned int val = 0x55;
for (i = 0; i < 2; i++) {
- ret = otg_io_write(otg, val, ULPI_SCRATCH);
+ ret = xceiv_io_write(xceiv, val, ULPI_SCRATCH);
if (ret < 0)
return ret;
- ret = otg_io_read(otg, ULPI_SCRATCH);
+ ret = xceiv_io_read(xceiv, ULPI_SCRATCH);
if (ret < 0)
return ret;
@@ -175,13 +175,13 @@ static int ulpi_check_integrity(struct otg_transceiver *otg)
return 0;
}
-static int ulpi_init(struct otg_transceiver *otg)
+static int ulpi_init(struct usb_transceiver *xceiv)
{
int i, vid, pid, ret;
u32 ulpi_id = 0;
for (i = 0; i < 4; i++) {
- ret = otg_io_read(otg, ULPI_PRODUCT_ID_HIGH - i);
+ ret = xceiv_io_read(xceiv, ULPI_PRODUCT_ID_HIGH - i);
if (ret < 0)
return ret;
ulpi_id = (ulpi_id << 8) | ret;
@@ -199,55 +199,56 @@ static int ulpi_init(struct otg_transceiver *otg)
}
}
- ret = ulpi_check_integrity(otg);
+ ret = ulpi_check_integrity(xceiv);
if (ret)
return ret;
- return ulpi_set_flags(otg);
+ return ulpi_set_flags(xceiv);
}
-
-static int ulpi_set_host(struct otg_transceiver *otg, struct usb_bus *host)
+/*
+static int ulpi_set_host(struct usb_transceiver *xceiv, struct usb_bus *host)
{
- unsigned int flags = otg_io_read(otg, ULPI_IFC_CTRL);
+ unsigned int flags = xceiv_io_read(xceiv, ULPI_IFC_CTRL);
if (!host) {
- otg->host = NULL;
+ xceiv->otg->usb_bus = NULL;
return 0;
}
- otg->host = host;
+ xceiv->otg->usb_bus = host;
flags &= ~(ULPI_IFC_CTRL_6_PIN_SERIAL_MODE |
ULPI_IFC_CTRL_3_PIN_SERIAL_MODE |
ULPI_IFC_CTRL_CARKITMODE);
- if (otg->flags & ULPI_IC_6PIN_SERIAL)
+ if (xceiv->flags & ULPI_IC_6PIN_SERIAL)
flags |= ULPI_IFC_CTRL_6_PIN_SERIAL_MODE;
- else if (otg->flags & ULPI_IC_3PIN_SERIAL)
+ else if (xceiv->flags & ULPI_IC_3PIN_SERIAL)
flags |= ULPI_IFC_CTRL_3_PIN_SERIAL_MODE;
- else if (otg->flags & ULPI_IC_CARKIT)
+ else if (xceiv->flags & ULPI_IC_CARKIT)
flags |= ULPI_IFC_CTRL_CARKITMODE;
- return otg_io_write(otg, flags, ULPI_IFC_CTRL);
+ return xceiv_io_write(xceiv, flags, ULPI_IFC_CTRL);
}
+*/
-static int ulpi_set_vbus(struct otg_transceiver *otg, bool on)
+static int ulpi_set_vbus(struct usb_transceiver *xceiv, bool on)
{
- unsigned int flags = otg_io_read(otg, ULPI_OTG_CTRL);
+ unsigned int flags = xceiv_io_read(xceiv, ULPI_OTG_CTRL);
flags &= ~(ULPI_OTG_CTRL_DRVVBUS | ULPI_OTG_CTRL_DRVVBUS_EXT);
if (on) {
- if (otg->flags & ULPI_OTG_DRVVBUS)
+ if (xceiv->flags & ULPI_OTG_DRVVBUS)
flags |= ULPI_OTG_CTRL_DRVVBUS;
- if (otg->flags & ULPI_OTG_DRVVBUS_EXT)
+ if (xceiv->flags & ULPI_OTG_DRVVBUS_EXT)
flags |= ULPI_OTG_CTRL_DRVVBUS_EXT;
}
- return otg_io_write(otg, flags, ULPI_OTG_CTRL);
+ return xceiv_io_write(xceiv, flags, ULPI_OTG_CTRL);
}
-
+/*
struct otg_transceiver *
otg_ulpi_create(struct otg_io_access_ops *ops,
unsigned int flags)
@@ -268,4 +269,4 @@ otg_ulpi_create(struct otg_io_access_ops *ops,
return otg;
}
EXPORT_SYMBOL_GPL(otg_ulpi_create);
-
+*/
--
1.6.3.3
^ permalink raw reply related [flat|nested] 4+ messages in thread