USB: otg/ulpi: extend the generic ulpi driver.
authorIgor Grinberg <grinberg@compulab.co.il>
Thu, 15 Jul 2010 13:00:16 +0000 (16:00 +0300)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 10 Aug 2010 21:35:40 +0000 (14:35 -0700)
1) Introduce ulpi specific flags for control of the ulpi phy
2) Extend the generic ulpi driver with support for Function and
Interface control of upli phy
3) Update the platforms using the generic ulpi driver with new ulpi
flags
4) Remove the otg control flags not in use

Signed-off-by: Igor Grinberg <grinberg@compulab.co.il>
Signed-off-by: Mike Rapoport <mike@compulab.co.il>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
arch/arm/mach-mx3/mach-armadillo5x0.c
arch/arm/mach-mx3/mach-mx31lilly.c
arch/arm/mach-mx3/mach-mx31lite.c
arch/arm/mach-mx3/mach-mx31moboard.c
arch/arm/mach-mx3/mach-pcm037.c
arch/arm/mach-mx3/mach-pcm043.c
arch/arm/mach-mx3/mx31moboard-smartbot.c
drivers/usb/otg/ulpi.c
include/linux/usb/otg.h
include/linux/usb/ulpi.h

index 96aadcadb4ff094b1b5eeaaebc502b68cd87a370..68879c996a55d0db79b84f94952ed8efc6c0cf7a 100644 (file)
@@ -551,9 +551,9 @@ static void __init armadillo5x0_init(void)
        /* USB */
 #if defined(CONFIG_USB_ULPI)
        usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-                       USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+                       ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
        usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-                       USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+                       ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
 
        mxc_register_device(&mxc_otg_host, &usbotg_pdata);
        mxc_register_device(&mxc_usbh2, &usbh2_pdata);
index 8f66f65e80e2079a3dae7e70ddb2a530960d8f98..7c37daabb757351e559a81da063b4f78562cb6db 100644 (file)
@@ -245,9 +245,9 @@ static struct mxc_usbh_platform_data usbh2_pdata = {
 static void lilly1131_usb_init(void)
 {
        usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-                               USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+                               ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
        usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-                               USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+                               ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
 
        mxc_register_device(&mxc_usbh1, &usbh1_pdata);
        mxc_register_device(&mxc_usbh2, &usbh2_pdata);
index da236c497d2ae38f2d6f01ca765df1957e1be8a1..f66a9576d8c242ed691583f9762d6acaa15b433c 100644 (file)
@@ -256,7 +256,7 @@ static void __init mxc_board_init(void)
 #if defined(CONFIG_USB_ULPI)
        /* USB */
        usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-                               USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+                               ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
 
        mxc_register_device(&mxc_usbh2, &usbh2_pdata);
 #endif
index 67776bc61c336cc09dfd2c31f7408a20875e79e9..7a075e8bf2d4767d2eb7b8b724b5e960edde0de1 100644 (file)
@@ -412,7 +412,7 @@ static struct mxc_usbh_platform_data usbh2_pdata = {
 static int __init moboard_usbh2_init(void)
 {
        usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-                       USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+                       ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
 
        return mxc_register_device(&mxc_usbh2, &usbh2_pdata);
 }
index 8a292dd1a7146311394a90540af4811a60df804f..214de11b20b919ece5a33c0041d8f8a62571f5e9 100644 (file)
@@ -654,13 +654,13 @@ static void __init mxc_board_init(void)
 #if defined(CONFIG_USB_ULPI)
        if (otg_mode_host) {
                otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-                               USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+                               ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
 
                mxc_register_device(&mxc_otg_host, &otg_pdata);
        }
 
        usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-                               USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+                               ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
 
        mxc_register_device(&mxc_usbh2, &usbh2_pdata);
 #endif
index 47f5311b301a18170fa30c86de22cd0d2b64495b..28886f0e62f97de762c015e5d9db2fdf4f84f400 100644 (file)
@@ -378,7 +378,7 @@ static void __init mxc_board_init(void)
 #if defined(CONFIG_USB_ULPI)
        if (otg_mode_host) {
                otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-                               USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+                               ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
 
                mxc_register_device(&mxc_otg_host, &otg_pdata);
        }
index 40c3e7564cb61c43d77cbd1b01793262e6552eca..417757e78c65bef82725bfc135d1e03b5bf29392 100644 (file)
@@ -134,7 +134,7 @@ static struct mxc_usbh_platform_data otg_host_pdata = {
 static int __init smartbot_otg_host_init(void)
 {
        otg_host_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-                       USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+                       ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
 
        return mxc_register_device(&mxc_otg_host, &otg_host_pdata);
 }
index ef7dbe40f1114fa991f40ed9f1a7c27b2d9b29b6..ccc81950822b25e9550b3947863630516f4b2d54 100644 (file)
@@ -37,25 +37,106 @@ static unsigned int ulpi_ids[] = {
        ULPI_ID(0x0424, 0x0006),        /* SMSC USB3319 */
 };
 
-static int ulpi_set_flags(struct otg_transceiver *otg)
+static int ulpi_set_otg_flags(struct otg_transceiver *otg)
 {
-       unsigned int flags = 0;
+       unsigned int flags = ULPI_OTG_CTRL_DP_PULLDOWN |
+                            ULPI_OTG_CTRL_DM_PULLDOWN;
 
-       if (otg->flags & USB_OTG_PULLUP_ID)
+       if (otg->flags & ULPI_OTG_ID_PULLUP)
                flags |= ULPI_OTG_CTRL_ID_PULLUP;
 
-       if (otg->flags & USB_OTG_PULLDOWN_DM)
-               flags |= ULPI_OTG_CTRL_DM_PULLDOWN;
+       /*
+        * ULPI Specification rev.1.1 default
+        * for Dp/DmPulldown is enabled.
+        */
+       if (otg->flags & ULPI_OTG_DP_PULLDOWN_DIS)
+               flags &= ~ULPI_OTG_CTRL_DP_PULLDOWN;
 
-       if (otg->flags & USB_OTG_PULLDOWN_DP)
-               flags |= ULPI_OTG_CTRL_DP_PULLDOWN;
+       if (otg->flags & ULPI_OTG_DM_PULLDOWN_DIS)
+               flags &= ~ULPI_OTG_CTRL_DM_PULLDOWN;
 
-       if (otg->flags & USB_OTG_EXT_VBUS_INDICATOR)
+       if (otg->flags & ULPI_OTG_EXTVBUSIND)
                flags |= ULPI_OTG_CTRL_EXTVBUSIND;
 
        return otg_io_write(otg, flags, ULPI_OTG_CTRL);
 }
 
+static int ulpi_set_fc_flags(struct otg_transceiver *otg)
+{
+       unsigned int flags = 0;
+
+       /*
+        * ULPI Specification rev.1.1 default
+        * for XcvrSelect is Full Speed.
+        */
+       if (otg->flags & ULPI_FC_HS)
+               flags |= ULPI_FUNC_CTRL_HIGH_SPEED;
+       else if (otg->flags & ULPI_FC_LS)
+               flags |= ULPI_FUNC_CTRL_LOW_SPEED;
+       else if (otg->flags & ULPI_FC_FS4LS)
+               flags |= ULPI_FUNC_CTRL_FS4LS;
+       else
+               flags |= ULPI_FUNC_CTRL_FULL_SPEED;
+
+       if (otg->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)
+               flags |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING;
+       else if (otg->flags & ULPI_FC_OP_DIS_NRZI)
+               flags |= ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI;
+       else if (otg->flags & ULPI_FC_OP_NSYNC_NEOP)
+               flags |= ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP;
+       else
+               flags |= ULPI_FUNC_CTRL_OPMODE_NORMAL;
+
+       /*
+        * ULPI Specification rev.1.1 default
+        * for SuspendM is Powered.
+        */
+       flags |= ULPI_FUNC_CTRL_SUSPENDM;
+
+       return otg_io_write(otg, flags, ULPI_FUNC_CTRL);
+}
+
+static int ulpi_set_ic_flags(struct otg_transceiver *otg)
+{
+       unsigned int flags = 0;
+
+       if (otg->flags & ULPI_IC_AUTORESUME)
+               flags |= ULPI_IFC_CTRL_AUTORESUME;
+
+       if (otg->flags & ULPI_IC_EXTVBUS_INDINV)
+               flags |= ULPI_IFC_CTRL_EXTERNAL_VBUS;
+
+       if (otg->flags & ULPI_IC_IND_PASSTHRU)
+               flags |= ULPI_IFC_CTRL_PASSTHRU;
+
+       if (otg->flags & ULPI_IC_PROTECT_DIS)
+               flags |= ULPI_IFC_CTRL_PROTECT_IFC_DISABLE;
+
+       return otg_io_write(otg, flags, ULPI_IFC_CTRL);
+}
+
+static int ulpi_set_flags(struct otg_transceiver *otg)
+{
+       int ret;
+
+       ret = ulpi_set_otg_flags(otg);
+       if (ret)
+               return ret;
+
+       ret = ulpi_set_ic_flags(otg);
+       if (ret)
+               return ret;
+
+       return ulpi_set_fc_flags(otg);
+}
+
 static int ulpi_init(struct otg_transceiver *otg)
 {
        int i, vid, pid, ret;
@@ -80,6 +161,31 @@ static int ulpi_init(struct otg_transceiver *otg)
        return -ENODEV;
 }
 
+static int ulpi_set_host(struct otg_transceiver *otg, struct usb_bus *host)
+{
+       unsigned int flags = otg_io_read(otg, ULPI_IFC_CTRL);
+
+       if (!host) {
+               otg->host = NULL;
+               return 0;
+       }
+
+       otg->host = 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)
+               flags |= ULPI_IFC_CTRL_6_PIN_SERIAL_MODE;
+       else if (otg->flags & ULPI_IC_3PIN_SERIAL)
+               flags |= ULPI_IFC_CTRL_3_PIN_SERIAL_MODE;
+       else if (otg->flags & ULPI_IC_CARKIT)
+               flags |= ULPI_IFC_CTRL_CARKITMODE;
+
+       return otg_io_write(otg, flags, ULPI_IFC_CTRL);
+}
+
 static int ulpi_set_vbus(struct otg_transceiver *otg, bool on)
 {
        unsigned int flags = otg_io_read(otg, ULPI_OTG_CTRL);
@@ -87,10 +193,10 @@ static int ulpi_set_vbus(struct otg_transceiver *otg, bool on)
        flags &= ~(ULPI_OTG_CTRL_DRVVBUS | ULPI_OTG_CTRL_DRVVBUS_EXT);
 
        if (on) {
-               if (otg->flags & USB_OTG_DRV_VBUS)
+               if (otg->flags & ULPI_OTG_DRVVBUS)
                        flags |= ULPI_OTG_CTRL_DRVVBUS;
 
-               if (otg->flags & USB_OTG_DRV_VBUS_EXT)
+               if (otg->flags & ULPI_OTG_DRVVBUS_EXT)
                        flags |= ULPI_OTG_CTRL_DRVVBUS_EXT;
        }
 
@@ -111,6 +217,7 @@ otg_ulpi_create(struct otg_io_access_ops *ops,
        otg->flags      = flags;
        otg->io_ops     = ops;
        otg->init       = ulpi_init;
+       otg->set_host   = ulpi_set_host;
        otg->set_vbus   = ulpi_set_vbus;
 
        return otg;
index 54b2c5e48b9d78b8f8e3e7faf4486f0a2edf539e..545cba73ccaffe5047feddbfcc33589cfe940ba6 100644 (file)
@@ -43,13 +43,6 @@ enum usb_xceiv_events {
        USB_EVENT_ENUMERATED,   /* gadget driver enumerated */
 };
 
-#define USB_OTG_PULLUP_ID              (1 << 0)
-#define USB_OTG_PULLDOWN_DP            (1 << 1)
-#define USB_OTG_PULLDOWN_DM            (1 << 2)
-#define USB_OTG_EXT_VBUS_INDICATOR     (1 << 3)
-#define USB_OTG_DRV_VBUS               (1 << 4)
-#define USB_OTG_DRV_VBUS_EXT           (1 << 5)
-
 struct otg_transceiver;
 
 /* for transceivers connected thru an ULPI interface, the user must
index 900d97b7096a2ef64856022bb61d7121149eb09a..82b1507f47351d8afe754b32a7d1e1bcac60abb7 100644 (file)
 #include <linux/usb/otg.h>
 /*-------------------------------------------------------------------------*/
 
+/*
+ * ULPI Flags
+ */
+#define ULPI_OTG_ID_PULLUP             (1 << 0)
+#define ULPI_OTG_DP_PULLDOWN_DIS       (1 << 1)
+#define ULPI_OTG_DM_PULLDOWN_DIS       (1 << 2)
+#define ULPI_OTG_DISCHRGVBUS           (1 << 3)
+#define ULPI_OTG_CHRGVBUS              (1 << 4)
+#define ULPI_OTG_DRVVBUS               (1 << 5)
+#define ULPI_OTG_DRVVBUS_EXT           (1 << 6)
+#define ULPI_OTG_EXTVBUSIND            (1 << 7)
+
+#define ULPI_IC_6PIN_SERIAL            (1 << 8)
+#define ULPI_IC_3PIN_SERIAL            (1 << 9)
+#define ULPI_IC_CARKIT                 (1 << 10)
+#define ULPI_IC_CLKSUSPM               (1 << 11)
+#define ULPI_IC_AUTORESUME             (1 << 12)
+#define ULPI_IC_EXTVBUS_INDINV         (1 << 13)
+#define ULPI_IC_IND_PASSTHRU           (1 << 14)
+#define ULPI_IC_PROTECT_DIS            (1 << 15)
+
+#define ULPI_FC_HS                     (1 << 16)
+#define ULPI_FC_FS                     (1 << 17)
+#define ULPI_FC_LS                     (1 << 18)
+#define ULPI_FC_FS4LS                  (1 << 19)
+#define ULPI_FC_TERMSEL                        (1 << 20)
+#define ULPI_FC_OP_NORM                        (1 << 21)
+#define ULPI_FC_OP_NODRV               (1 << 22)
+#define ULPI_FC_OP_DIS_NRZI            (1 << 23)
+#define ULPI_FC_OP_NSYNC_NEOP          (1 << 24)
+#define ULPI_FC_RST                    (1 << 25)
+#define ULPI_FC_SUSPM                  (1 << 26)
+
+/*-------------------------------------------------------------------------*/
+
 /*
  * Macros for Set and Clear
  * See ULPI 1.1 specification to find the registers with Set and Clear offsets
 
 /*-------------------------------------------------------------------------*/
 
+/*
+ * Register Bits
+ */
+
 /* Function Control */
 #define ULPI_FUNC_CTRL_XCVRSEL                 (1 << 0)
 #define  ULPI_FUNC_CTRL_XCVRSEL_MASK           (3 << 0)