]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
usb: chipidea: usbmisc_imx: add imx6sx initialization routine
authorPeter Chen <peter.chen@freescale.com>
Wed, 11 Feb 2015 04:44:53 +0000 (12:44 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Mar 2015 15:19:10 +0000 (16:19 +0100)
Except the same process with earlier imx6, it has below two features:

- Choose which vbus voltage as vbus wakeup source
We choose B_SESSION_VALID as vbus wakeup source since when the system
goes to suspend, the vbus comparator can't compare the vbus voltage
for VBUS_VALID.

- Disable dp/dm (linestate) change as wakeup source at device mode
when the vbus is not there, we don't expect dp/dm change waking up
usb controller at this situation.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/chipidea/usbmisc_imx.c

index 90b7d7f3c81b08d6a0e0eec96a0ec44ff8fa4cb5..8af070f15d3eabf821d6c13e70836f01fc4fd2b7 100644 (file)
 #define MX6_BM_WAKEUP_ENABLE           BIT(10)
 #define MX6_BM_ID_WAKEUP               BIT(16)
 #define MX6_BM_VBUS_WAKEUP             BIT(17)
+#define MX6SX_BM_DPDM_WAKEUP_EN                BIT(29)
 #define MX6_BM_WAKEUP_INTR             BIT(31)
+#define MX6_USB_OTG1_PHY_CTRL          0x18
+/* For imx6dql, it is host-only controller, for later imx6, it is otg's */
+#define MX6_USB_OTG2_PHY_CTRL          0x1c
+#define MX6SX_USB_VBUS_WAKEUP_SOURCE(v)        (v << 8)
+#define MX6SX_USB_VBUS_WAKEUP_SOURCE_VBUS      MX6SX_USB_VBUS_WAKEUP_SOURCE(0)
+#define MX6SX_USB_VBUS_WAKEUP_SOURCE_AVALID    MX6SX_USB_VBUS_WAKEUP_SOURCE(1)
+#define MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID    MX6SX_USB_VBUS_WAKEUP_SOURCE(2)
+#define MX6SX_USB_VBUS_WAKEUP_SOURCE_SESS_END  MX6SX_USB_VBUS_WAKEUP_SOURCE(3)
 
 #define VF610_OVER_CUR_DIS             BIT(7)
 
@@ -259,6 +268,35 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
        return 0;
 }
 
+static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data)
+{
+       void __iomem *reg = NULL;
+       unsigned long flags;
+       struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+       u32 val;
+       int ret = 0;
+
+       usbmisc_imx6q_init(data);
+
+       if (data->index == 0 || data->index == 1) {
+               reg = usbmisc->base + MX6_USB_OTG1_PHY_CTRL + data->index * 4;
+               spin_lock_irqsave(&usbmisc->lock, flags);
+               /* Set vbus wakeup source as bvalid */
+               val = readl(reg);
+               writel(val | MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID, reg);
+               /*
+                * Disable dp/dm wakeup in device mode when vbus is
+                * not there.
+                */
+               val = readl(usbmisc->base + data->index * 4);
+               writel(val & ~MX6SX_BM_DPDM_WAKEUP_EN,
+                       usbmisc->base + data->index * 4);
+               spin_unlock_irqrestore(&usbmisc->lock, flags);
+       }
+
+       return ret;
+}
+
 static int usbmisc_vf610_init(struct imx_usbmisc_data *data)
 {
        struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
@@ -301,6 +339,11 @@ static const struct usbmisc_ops vf610_usbmisc_ops = {
        .init = usbmisc_vf610_init,
 };
 
+static const struct usbmisc_ops imx6sx_usbmisc_ops = {
+       .set_wakeup = usbmisc_imx6q_set_wakeup,
+       .init = usbmisc_imx6sx_init,
+};
+
 int imx_usbmisc_init(struct imx_usbmisc_data *data)
 {
        struct imx_usbmisc *usbmisc;
@@ -372,6 +415,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = {
                .compatible = "fsl,vf610-usbmisc",
                .data = &vf610_usbmisc_ops,
        },
+       {
+               .compatible = "fsl,imx6sx-usbmisc",
+               .data = &imx6sx_usbmisc_ops,
+       },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);