usb: chipidea: imx: support configuring for active low oc signal
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Tue, 4 Dec 2018 08:31:29 +0000 (09:31 +0100)
committerPeter Chen <peter.chen@nxp.com>
Tue, 11 Dec 2018 01:13:09 +0000 (09:13 +0800)
The status quo on i.MX6 is that if "over-current-active-high" is
specified in the device tree this is configured as expected. If
the property is missing polarity isn't changed and so the
polarity is kept as setup by the bootloader. Reset default is
active high, so active low can only be used with help by the
bootloader. On i.MX7 it is similar, but there disabling of
over current detection has a similar inconsistency.

This patch introduces a new property that allows to explicitly
configure for active low over current detection and consistently
sets this up. In the absence of an explicit configuration the
bit is kept as is. On i.MX7 over current detection is used unless
disabled in the device tree.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
drivers/usb/chipidea/ci_hdrc_imx.c
drivers/usb/chipidea/ci_hdrc_imx.h
drivers/usb/chipidea/usbmisc_imx.c

index 3381b9618b5b3644b2b2afa8a5c3e0244a7ce1a6..adae82385dd6bffe4cee15648dd865e9cbc5bf72 100644 (file)
@@ -90,8 +90,9 @@ i.mx specific properties
 - fsl,usbmisc: phandler of non-core register device, with one
   argument that indicate usb controller index
 - disable-over-current: disable over current detect
-- over-current-active-high: over current signal polarity is high active,
-  typically over current signal polarity is low active.
+- over-current-active-low: over current signal polarity is active low.
+- over-current-active-high: over current signal polarity is active high.
+  It's recommended to specify the over current polarity.
 - external-vbus-divider: enables off-chip resistor divider for Vbus
 
 Example:
index 56781c329db0867ad10b061b6d28c9f6eef69b46..1951b37aa39dcaec61a7c5d57659998845676bcb 100644 (file)
@@ -136,11 +136,19 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
 
        data->dev = &misc_pdev->dev;
 
-       if (of_find_property(np, "disable-over-current", NULL))
+       /*
+        * Check the various over current related properties. If over current
+        * detection is disabled we're not interested in the polarity.
+        */
+       if (of_find_property(np, "disable-over-current", NULL)) {
                data->disable_oc = 1;
-
-       if (of_find_property(np, "over-current-active-high", NULL))
-               data->oc_polarity = 1;
+       } else if (of_find_property(np, "over-current-active-high", NULL)) {
+               data->oc_pol_active_low = 0;
+               data->oc_pol_configured = 1;
+       } else if (of_find_property(np, "over-current-active-low", NULL)) {
+               data->oc_pol_active_low = 1;
+               data->oc_pol_configured = 1;
+       }
 
        if (of_find_property(np, "external-vbus-divider", NULL))
                data->evdo = 1;
index fcecab478934125f2959443326fecf6181632b7a..7cc53e2ce564e4722029fd97ae798edde4586d2d 100644 (file)
@@ -11,7 +11,13 @@ struct imx_usbmisc_data {
        int index;
 
        unsigned int disable_oc:1; /* over current detect disabled */
-       unsigned int oc_polarity:1; /* over current polarity if oc enabled */
+
+       /* true if over-current polarity is active low */
+       unsigned int oc_pol_active_low:1;
+
+       /* true if dt specifies polarity */
+       unsigned int oc_pol_configured:1;
+
        unsigned int evdo:1; /* set external vbus divider option */
        unsigned int ulpi:1; /* connected to an ULPI phy */
        unsigned int hsic:1; /* HSIC controlller */
index 43a15a6e86f5775b79b560fd8f901072b34aed1f..4c3839d345cd3abd06716d68895e72b8dfc65ee8 100644 (file)
@@ -356,11 +356,17 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
        reg = readl(usbmisc->base + data->index * 4);
        if (data->disable_oc) {
                reg |= MX6_BM_OVER_CUR_DIS;
-       } else if (data->oc_polarity == 1) {
-               /* High active */
-               reg &= ~(MX6_BM_OVER_CUR_DIS | MX6_BM_OVER_CUR_POLARITY);
        } else {
-               reg &= ~(MX6_BM_OVER_CUR_DIS);
+               reg &= ~MX6_BM_OVER_CUR_DIS;
+
+               /*
+                * If the polarity is not configured keep it as setup by the
+                * bootloader.
+                */
+               if (data->oc_pol_configured && data->oc_pol_active_low)
+                       reg |= MX6_BM_OVER_CUR_POLARITY;
+               else if (data->oc_pol_configured)
+                       reg &= ~MX6_BM_OVER_CUR_POLARITY;
        }
        writel(reg, usbmisc->base + data->index * 4);
 
@@ -552,9 +558,17 @@ static int usbmisc_imx7d_init(struct imx_usbmisc_data *data)
        reg = readl(usbmisc->base);
        if (data->disable_oc) {
                reg |= MX6_BM_OVER_CUR_DIS;
-       } else if (data->oc_polarity == 1) {
-               /* High active */
-               reg &= ~(MX6_BM_OVER_CUR_DIS | MX6_BM_OVER_CUR_POLARITY);
+       } else {
+               reg &= ~MX6_BM_OVER_CUR_DIS;
+
+               /*
+                * If the polarity is not configured keep it as setup by the
+                * bootloader.
+                */
+               if (data->oc_pol_configured && data->oc_pol_active_low)
+                       reg |= MX6_BM_OVER_CUR_POLARITY;
+               else if (data->oc_pol_configured)
+                       reg &= ~MX6_BM_OVER_CUR_POLARITY;
        }
        writel(reg, usbmisc->base);