summaryrefslogtreecommitdiff
path: root/drivers/usb/chipidea/usbmisc_imx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/chipidea/usbmisc_imx.c')
-rw-r--r--drivers/usb/chipidea/usbmisc_imx.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index f0f8edc078d6..a8dabfff463e 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -97,6 +97,8 @@
#define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID MX7D_USB_VBUS_WAKEUP_SOURCE(1)
#define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID MX7D_USB_VBUS_WAKEUP_SOURCE(2)
#define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END MX7D_USB_VBUS_WAKEUP_SOURCE(3)
+#define MX7D_USB_TERMSEL_OVERRIDE BIT(4)
+#define MX7D_USB_TERMSEL_OVERRIDE_EN BIT(5)
#define OTG_DRVVBUS0 BIT(16)
#define OTG_ADP_PRBENB0 BIT(13)
@@ -144,6 +146,9 @@ struct usbmisc_ops {
bool (*adp_sense_connection)(struct imx_usbmisc_data *data);
/* Check if it's a device attach or dettach event */
bool (*adp_attach_event)(struct imx_usbmisc_data *data);
+ /* override UTMI termination select */
+ int (*term_select_override)(struct imx_usbmisc_data *data,
+ bool enable, int val);
};
struct imx_usbmisc {
@@ -736,6 +741,37 @@ static int usbmisc_imx7d_power_lost_check(struct imx_usbmisc_data *data)
return 0;
}
+static int usbmisc_term_select_override(struct imx_usbmisc_data *data,
+ bool enable, int val)
+{
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+
+ reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ if (enable) {
+ if (val)
+ writel(reg | MX7D_USB_TERMSEL_OVERRIDE,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ else
+ writel(reg & ~MX7D_USB_TERMSEL_OVERRIDE,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+
+ reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ writel(reg | MX7D_USB_TERMSEL_OVERRIDE_EN,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ } else {
+ writel(reg & ~MX7D_USB_TERMSEL_OVERRIDE_EN,
+ usbmisc->base + MX7D_USBNC_USB_CTRL2);
+ }
+
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+ return 0;
+}
+
static const struct usbmisc_ops imx25_usbmisc_ops = {
.init = usbmisc_imx25_init,
.post = usbmisc_imx25_post,
@@ -779,6 +815,7 @@ static const struct usbmisc_ops imx7d_usbmisc_ops = {
.is_sense_int = usbmisc_otg_adp_is_sense_int,
.adp_sense_connection = usbmisc_otg_adp_sense_connection,
.adp_attach_event = usbmisc_otg_adp_is_attach_event,
+ .term_select_override = usbmisc_term_select_override,
};
int imx_usbmisc_init(struct imx_usbmisc_data *data)
@@ -963,6 +1000,21 @@ bool imx_usbmisc_adp_attach_event(struct imx_usbmisc_data *data)
}
EXPORT_SYMBOL_GPL(imx_usbmisc_adp_attach_event);
+int imx_usbmisc_term_select_override(struct imx_usbmisc_data *data,
+ bool enable, int val)
+{
+ struct imx_usbmisc *usbmisc;
+
+ if (!data)
+ return 0;
+
+ usbmisc = dev_get_drvdata(data->dev);
+ if (!usbmisc->ops->term_select_override)
+ return 0;
+ return usbmisc->ops->term_select_override(data, enable, val);
+}
+EXPORT_SYMBOL_GPL(imx_usbmisc_term_select_override);
+
static const struct of_device_id usbmisc_imx_dt_ids[] = {
{
.compatible = "fsl,imx25-usbmisc",