1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2012 Freescale Semiconductor, Inc.
6 #include <linux/module.h>
10 #include <linux/delay.h>
11 #include <linux/platform_device.h>
12 #include <linux/usb/otg.h>
14 #include "ci_hdrc_imx.h"
16 #define MX25_USB_PHY_CTRL_OFFSET 0x08
17 #define MX25_BM_EXTERNAL_VBUS_DIVIDER BIT(23)
19 #define MX25_EHCI_INTERFACE_SINGLE_UNI (2 << 0)
20 #define MX25_EHCI_INTERFACE_DIFF_UNI (0 << 0)
21 #define MX25_EHCI_INTERFACE_MASK (0xf)
23 #define MX25_OTG_SIC_SHIFT 29
24 #define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT)
25 #define MX25_OTG_PM_BIT BIT(24)
26 #define MX25_OTG_PP_BIT BIT(11)
27 #define MX25_OTG_OCPOL_BIT BIT(3)
29 #define MX25_H1_SIC_SHIFT 21
30 #define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
31 #define MX25_H1_PP_BIT BIT(18)
32 #define MX25_H1_PM_BIT BIT(16)
33 #define MX25_H1_IPPUE_UP_BIT BIT(7)
34 #define MX25_H1_IPPUE_DOWN_BIT BIT(6)
35 #define MX25_H1_TLL_BIT BIT(5)
36 #define MX25_H1_USBTE_BIT BIT(4)
37 #define MX25_H1_OCPOL_BIT BIT(2)
39 #define MX27_H1_PM_BIT BIT(8)
40 #define MX27_H2_PM_BIT BIT(16)
41 #define MX27_OTG_PM_BIT BIT(24)
43 #define MX53_USB_OTG_PHY_CTRL_0_OFFSET 0x08
44 #define MX53_USB_OTG_PHY_CTRL_1_OFFSET 0x0c
45 #define MX53_USB_CTRL_1_OFFSET 0x10
46 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK (0x11 << 2)
47 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI BIT(2)
48 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK (0x11 << 6)
49 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI BIT(6)
50 #define MX53_USB_UH2_CTRL_OFFSET 0x14
51 #define MX53_USB_UH3_CTRL_OFFSET 0x18
52 #define MX53_USB_CLKONOFF_CTRL_OFFSET 0x24
53 #define MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF BIT(21)
54 #define MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF BIT(22)
55 #define MX53_BM_OVER_CUR_DIS_H1 BIT(5)
56 #define MX53_BM_OVER_CUR_DIS_OTG BIT(8)
57 #define MX53_BM_OVER_CUR_DIS_UHx BIT(30)
58 #define MX53_USB_CTRL_1_UH2_ULPI_EN BIT(26)
59 #define MX53_USB_CTRL_1_UH3_ULPI_EN BIT(27)
60 #define MX53_USB_UHx_CTRL_WAKE_UP_EN BIT(7)
61 #define MX53_USB_UHx_CTRL_ULPI_INT_EN BIT(8)
62 #define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3
63 #define MX53_USB_PLL_DIV_24_MHZ 0x01
65 #define MX6_BM_NON_BURST_SETTING BIT(1)
66 #define MX6_BM_OVER_CUR_DIS BIT(7)
67 #define MX6_BM_OVER_CUR_POLARITY BIT(8)
68 #define MX6_BM_PWR_POLARITY BIT(9)
69 #define MX6_BM_WAKEUP_ENABLE BIT(10)
70 #define MX6_BM_UTMI_ON_CLOCK BIT(13)
71 #define MX6_BM_ID_WAKEUP BIT(16)
72 #define MX6_BM_VBUS_WAKEUP BIT(17)
73 #define MX6SX_BM_DPDM_WAKEUP_EN BIT(29)
74 #define MX6_BM_WAKEUP_INTR BIT(31)
76 #define MX6_USB_HSIC_CTRL_OFFSET 0x10
77 /* Send resume signal without 480Mhz PHY clock */
78 #define MX6SX_BM_HSIC_AUTO_RESUME BIT(23)
79 /* set before portsc.suspendM = 1 */
80 #define MX6_BM_HSIC_DEV_CONN BIT(21)
82 #define MX6_BM_HSIC_EN BIT(12)
83 /* Force HSIC module 480M clock on, even when in Host is in suspend mode */
84 #define MX6_BM_HSIC_CLK_ON BIT(11)
86 #define MX6_USB_OTG1_PHY_CTRL 0x18
87 /* For imx6dql, it is host-only controller, for later imx6, it is otg's */
88 #define MX6_USB_OTG2_PHY_CTRL 0x1c
89 #define MX6SX_USB_VBUS_WAKEUP_SOURCE(v) (v << 8)
90 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_VBUS MX6SX_USB_VBUS_WAKEUP_SOURCE(0)
91 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_AVALID MX6SX_USB_VBUS_WAKEUP_SOURCE(1)
92 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID MX6SX_USB_VBUS_WAKEUP_SOURCE(2)
93 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_SESS_END MX6SX_USB_VBUS_WAKEUP_SOURCE(3)
95 #define VF610_OVER_CUR_DIS BIT(7)
97 #define MX7D_USBNC_USB_CTRL2 0x4
98 #define MX7D_USB_VBUS_WAKEUP_SOURCE_MASK 0x3
99 #define MX7D_USB_VBUS_WAKEUP_SOURCE(v) (v << 0)
100 #define MX7D_USB_VBUS_WAKEUP_SOURCE_VBUS MX7D_USB_VBUS_WAKEUP_SOURCE(0)
101 #define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID MX7D_USB_VBUS_WAKEUP_SOURCE(1)
102 #define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID MX7D_USB_VBUS_WAKEUP_SOURCE(2)
103 #define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END MX7D_USB_VBUS_WAKEUP_SOURCE(3)
104 #define MX7D_USBNC_AUTO_RESUME BIT(2)
105 /* The default DM/DP value is pull-down */
106 #define MX7D_USBNC_USB_CTRL2_OPMODE(v) (v << 6)
107 #define MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING MX7D_USBNC_USB_CTRL2_OPMODE(1)
108 #define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK (BIT(7) | BIT(6))
109 #define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN BIT(8)
110 #define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_VAL BIT(12)
111 #define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_EN BIT(13)
112 #define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_VAL BIT(14)
113 #define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_EN BIT(15)
114 #define MX7D_USBNC_USB_CTRL2_DP_DM_MASK (BIT(12) | BIT(13) | \
117 #define MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL BIT(0)
118 #define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 BIT(1)
119 #define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 BIT(2)
120 #define MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB BIT(3)
121 #define MX7D_USB_OTG_PHY_CFG2_DRVVBUS0 BIT(16)
123 #define MX7D_USB_OTG_PHY_CFG2 0x34
125 #define MX7D_USB_OTG_PHY_STATUS 0x3c
126 #define MX7D_USB_OTG_PHY_STATUS_LINE_STATE0 BIT(0)
127 #define MX7D_USB_OTG_PHY_STATUS_LINE_STATE1 BIT(1)
128 #define MX7D_USB_OTG_PHY_STATUS_VBUS_VLD BIT(3)
129 #define MX7D_USB_OTG_PHY_STATUS_CHRGDET BIT(29)
131 #define MX7D_USB_OTG_PHY_CFG1 0x30
132 #define TXPREEMPAMPTUNE0_BIT 28
133 #define TXPREEMPAMPTUNE0_MASK (3 << 28)
134 #define TXRISETUNE0_BIT 24
135 #define TXRISETUNE0_MASK (3 << 24)
136 #define TXVREFTUNE0_BIT 20
137 #define TXVREFTUNE0_MASK (0xf << 20)
139 #define MX6_USB_OTG_WAKEUP_BITS (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP | \
140 MX6_BM_ID_WAKEUP | MX6SX_BM_DPDM_WAKEUP_EN)
143 /* It's called once when probe a usb device */
144 int (*init
)(struct imx_usbmisc_data
*data
);
145 /* It's called once after adding a usb device */
146 int (*post
)(struct imx_usbmisc_data
*data
);
147 /* It's called when we need to enable/disable usb wakeup */
148 int (*set_wakeup
)(struct imx_usbmisc_data
*data
, bool enabled
);
149 /* It's called before setting portsc.suspendM */
150 int (*hsic_set_connect
)(struct imx_usbmisc_data
*data
);
151 /* It's called during suspend/resume */
152 int (*hsic_set_clk
)(struct imx_usbmisc_data
*data
, bool enabled
);
153 /* usb charger detection */
154 int (*charger_detection
)(struct imx_usbmisc_data
*data
);
155 /* It's called when system resume from usb power lost */
156 int (*power_lost_check
)(struct imx_usbmisc_data
*data
);
157 void (*vbus_comparator_on
)(struct imx_usbmisc_data
*data
, bool on
);
163 const struct usbmisc_ops
*ops
;
166 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data
*data
);
168 static int usbmisc_imx25_init(struct imx_usbmisc_data
*data
)
170 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
177 spin_lock_irqsave(&usbmisc
->lock
, flags
);
178 switch (data
->index
) {
180 val
= readl(usbmisc
->base
);
181 val
&= ~(MX25_OTG_SIC_MASK
| MX25_OTG_PP_BIT
);
182 val
|= (MX25_EHCI_INTERFACE_DIFF_UNI
& MX25_EHCI_INTERFACE_MASK
) << MX25_OTG_SIC_SHIFT
;
183 val
|= (MX25_OTG_PM_BIT
| MX25_OTG_OCPOL_BIT
);
186 * If the polarity is not configured assume active high for
187 * historical reasons.
189 if (data
->oc_pol_configured
&& data
->oc_pol_active_low
)
190 val
&= ~MX25_OTG_OCPOL_BIT
;
192 writel(val
, usbmisc
->base
);
195 val
= readl(usbmisc
->base
);
196 val
&= ~(MX25_H1_SIC_MASK
| MX25_H1_PP_BIT
| MX25_H1_IPPUE_UP_BIT
);
197 val
|= (MX25_EHCI_INTERFACE_SINGLE_UNI
& MX25_EHCI_INTERFACE_MASK
) << MX25_H1_SIC_SHIFT
;
198 val
|= (MX25_H1_PM_BIT
| MX25_H1_OCPOL_BIT
| MX25_H1_TLL_BIT
|
199 MX25_H1_USBTE_BIT
| MX25_H1_IPPUE_DOWN_BIT
);
202 * If the polarity is not configured assume active high for
203 * historical reasons.
205 if (data
->oc_pol_configured
&& data
->oc_pol_active_low
)
206 val
&= ~MX25_H1_OCPOL_BIT
;
208 writel(val
, usbmisc
->base
);
212 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
217 static int usbmisc_imx25_post(struct imx_usbmisc_data
*data
)
219 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
230 spin_lock_irqsave(&usbmisc
->lock
, flags
);
231 reg
= usbmisc
->base
+ MX25_USB_PHY_CTRL_OFFSET
;
235 val
|= MX25_BM_EXTERNAL_VBUS_DIVIDER
;
237 val
&= ~MX25_BM_EXTERNAL_VBUS_DIVIDER
;
240 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
241 usleep_range(5000, 10000); /* needed to stabilize voltage */
246 static int usbmisc_imx27_init(struct imx_usbmisc_data
*data
)
248 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
252 switch (data
->index
) {
254 val
= MX27_OTG_PM_BIT
;
257 val
= MX27_H1_PM_BIT
;
260 val
= MX27_H2_PM_BIT
;
266 spin_lock_irqsave(&usbmisc
->lock
, flags
);
267 if (data
->disable_oc
)
268 val
= readl(usbmisc
->base
) | val
;
270 val
= readl(usbmisc
->base
) & ~val
;
271 writel(val
, usbmisc
->base
);
272 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
277 static int usbmisc_imx53_init(struct imx_usbmisc_data
*data
)
279 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
280 void __iomem
*reg
= NULL
;
287 /* Select a 24 MHz reference clock for the PHY */
288 val
= readl(usbmisc
->base
+ MX53_USB_OTG_PHY_CTRL_1_OFFSET
);
289 val
&= ~MX53_USB_PHYCTRL1_PLLDIV_MASK
;
290 val
|= MX53_USB_PLL_DIV_24_MHZ
;
291 writel(val
, usbmisc
->base
+ MX53_USB_OTG_PHY_CTRL_1_OFFSET
);
293 spin_lock_irqsave(&usbmisc
->lock
, flags
);
295 switch (data
->index
) {
297 if (data
->disable_oc
) {
298 reg
= usbmisc
->base
+ MX53_USB_OTG_PHY_CTRL_0_OFFSET
;
299 val
= readl(reg
) | MX53_BM_OVER_CUR_DIS_OTG
;
304 if (data
->disable_oc
) {
305 reg
= usbmisc
->base
+ MX53_USB_OTG_PHY_CTRL_0_OFFSET
;
306 val
= readl(reg
) | MX53_BM_OVER_CUR_DIS_H1
;
312 /* set USBH2 into ULPI-mode. */
313 reg
= usbmisc
->base
+ MX53_USB_CTRL_1_OFFSET
;
314 val
= readl(reg
) | MX53_USB_CTRL_1_UH2_ULPI_EN
;
315 /* select ULPI clock */
316 val
&= ~MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK
;
317 val
|= MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI
;
319 /* Set interrupt wake up enable */
320 reg
= usbmisc
->base
+ MX53_USB_UH2_CTRL_OFFSET
;
321 val
= readl(reg
) | MX53_USB_UHx_CTRL_WAKE_UP_EN
322 | MX53_USB_UHx_CTRL_ULPI_INT_EN
;
324 if (is_imx53_usbmisc(data
)) {
325 /* Disable internal 60Mhz clock */
326 reg
= usbmisc
->base
+
327 MX53_USB_CLKONOFF_CTRL_OFFSET
;
329 MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF
;
334 if (data
->disable_oc
) {
335 reg
= usbmisc
->base
+ MX53_USB_UH2_CTRL_OFFSET
;
336 val
= readl(reg
) | MX53_BM_OVER_CUR_DIS_UHx
;
342 /* set USBH3 into ULPI-mode. */
343 reg
= usbmisc
->base
+ MX53_USB_CTRL_1_OFFSET
;
344 val
= readl(reg
) | MX53_USB_CTRL_1_UH3_ULPI_EN
;
345 /* select ULPI clock */
346 val
&= ~MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK
;
347 val
|= MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI
;
349 /* Set interrupt wake up enable */
350 reg
= usbmisc
->base
+ MX53_USB_UH3_CTRL_OFFSET
;
351 val
= readl(reg
) | MX53_USB_UHx_CTRL_WAKE_UP_EN
352 | MX53_USB_UHx_CTRL_ULPI_INT_EN
;
355 if (is_imx53_usbmisc(data
)) {
356 /* Disable internal 60Mhz clock */
357 reg
= usbmisc
->base
+
358 MX53_USB_CLKONOFF_CTRL_OFFSET
;
360 MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF
;
364 if (data
->disable_oc
) {
365 reg
= usbmisc
->base
+ MX53_USB_UH3_CTRL_OFFSET
;
366 val
= readl(reg
) | MX53_BM_OVER_CUR_DIS_UHx
;
372 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
377 static u32
usbmisc_wakeup_setting(struct imx_usbmisc_data
*data
)
379 u32 wakeup_setting
= MX6_USB_OTG_WAKEUP_BITS
;
381 if (data
->ext_id
|| data
->available_role
!= USB_DR_MODE_OTG
)
382 wakeup_setting
&= ~MX6_BM_ID_WAKEUP
;
384 if (data
->ext_vbus
|| data
->available_role
== USB_DR_MODE_HOST
)
385 wakeup_setting
&= ~MX6_BM_VBUS_WAKEUP
;
387 return wakeup_setting
;
390 static int usbmisc_imx6q_set_wakeup
391 (struct imx_usbmisc_data
*data
, bool enabled
)
393 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
401 spin_lock_irqsave(&usbmisc
->lock
, flags
);
402 val
= readl(usbmisc
->base
+ data
->index
* 4);
404 val
&= ~MX6_USB_OTG_WAKEUP_BITS
;
405 val
|= usbmisc_wakeup_setting(data
);
407 if (val
& MX6_BM_WAKEUP_INTR
)
408 pr_debug("wakeup int at ci_hdrc.%d\n", data
->index
);
409 val
&= ~MX6_USB_OTG_WAKEUP_BITS
;
411 writel(val
, usbmisc
->base
+ data
->index
* 4);
412 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
417 static int usbmisc_imx6q_init(struct imx_usbmisc_data
*data
)
419 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
426 spin_lock_irqsave(&usbmisc
->lock
, flags
);
428 reg
= readl(usbmisc
->base
+ data
->index
* 4);
429 if (data
->disable_oc
) {
430 reg
|= MX6_BM_OVER_CUR_DIS
;
432 reg
&= ~MX6_BM_OVER_CUR_DIS
;
435 * If the polarity is not configured keep it as setup by the
438 if (data
->oc_pol_configured
&& data
->oc_pol_active_low
)
439 reg
|= MX6_BM_OVER_CUR_POLARITY
;
440 else if (data
->oc_pol_configured
)
441 reg
&= ~MX6_BM_OVER_CUR_POLARITY
;
443 /* If the polarity is not set keep it as setup by the bootlader */
444 if (data
->pwr_pol
== 1)
445 reg
|= MX6_BM_PWR_POLARITY
;
446 writel(reg
, usbmisc
->base
+ data
->index
* 4);
448 /* SoC non-burst setting */
449 reg
= readl(usbmisc
->base
+ data
->index
* 4);
450 writel(reg
| MX6_BM_NON_BURST_SETTING
,
451 usbmisc
->base
+ data
->index
* 4);
453 /* For HSIC controller */
455 reg
= readl(usbmisc
->base
+ data
->index
* 4);
456 writel(reg
| MX6_BM_UTMI_ON_CLOCK
,
457 usbmisc
->base
+ data
->index
* 4);
458 reg
= readl(usbmisc
->base
+ MX6_USB_HSIC_CTRL_OFFSET
459 + (data
->index
- 2) * 4);
460 reg
|= MX6_BM_HSIC_EN
| MX6_BM_HSIC_CLK_ON
;
461 writel(reg
, usbmisc
->base
+ MX6_USB_HSIC_CTRL_OFFSET
462 + (data
->index
- 2) * 4);
465 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
467 usbmisc_imx6q_set_wakeup(data
, false);
472 static int usbmisc_imx6_hsic_get_reg_offset(struct imx_usbmisc_data
*data
)
476 if (data
->index
== 2 || data
->index
== 3) {
477 offset
= (data
->index
- 2) * 4;
478 } else if (data
->index
== 0) {
480 * For SoCs like i.MX7D and later, each USB controller has
481 * its own non-core register region. For SoCs before i.MX7D,
482 * the first two USB controllers are non-HSIC controllers.
486 dev_err(data
->dev
, "index is error for usbmisc\n");
490 return ret
? ret
: offset
;
493 static int usbmisc_imx6_hsic_set_connect(struct imx_usbmisc_data
*data
)
497 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
500 spin_lock_irqsave(&usbmisc
->lock
, flags
);
501 offset
= usbmisc_imx6_hsic_get_reg_offset(data
);
503 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
507 val
= readl(usbmisc
->base
+ MX6_USB_HSIC_CTRL_OFFSET
+ offset
);
508 if (!(val
& MX6_BM_HSIC_DEV_CONN
))
509 writel(val
| MX6_BM_HSIC_DEV_CONN
,
510 usbmisc
->base
+ MX6_USB_HSIC_CTRL_OFFSET
+ offset
);
512 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
517 static int usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data
*data
, bool on
)
521 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
524 spin_lock_irqsave(&usbmisc
->lock
, flags
);
525 offset
= usbmisc_imx6_hsic_get_reg_offset(data
);
527 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
531 val
= readl(usbmisc
->base
+ MX6_USB_HSIC_CTRL_OFFSET
+ offset
);
532 val
|= MX6_BM_HSIC_EN
| MX6_BM_HSIC_CLK_ON
;
534 val
|= MX6_BM_HSIC_CLK_ON
;
536 val
&= ~MX6_BM_HSIC_CLK_ON
;
538 writel(val
, usbmisc
->base
+ MX6_USB_HSIC_CTRL_OFFSET
+ offset
);
539 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
545 static int usbmisc_imx6sx_init(struct imx_usbmisc_data
*data
)
547 void __iomem
*reg
= NULL
;
549 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
552 usbmisc_imx6q_init(data
);
554 if (data
->index
== 0 || data
->index
== 1) {
555 reg
= usbmisc
->base
+ MX6_USB_OTG1_PHY_CTRL
+ data
->index
* 4;
556 spin_lock_irqsave(&usbmisc
->lock
, flags
);
557 /* Set vbus wakeup source as bvalid */
559 writel(val
| MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID
, reg
);
561 * Disable dp/dm wakeup in device mode when vbus is
564 val
= readl(usbmisc
->base
+ data
->index
* 4);
565 writel(val
& ~MX6SX_BM_DPDM_WAKEUP_EN
,
566 usbmisc
->base
+ data
->index
* 4);
567 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
570 /* For HSIC controller */
572 val
= readl(usbmisc
->base
+ MX6_USB_HSIC_CTRL_OFFSET
);
573 val
|= MX6SX_BM_HSIC_AUTO_RESUME
;
574 writel(val
, usbmisc
->base
+ MX6_USB_HSIC_CTRL_OFFSET
);
580 static int usbmisc_vf610_init(struct imx_usbmisc_data
*data
)
582 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
586 * Vybrid only has one misc register set, but in two different
587 * areas. These is reflected in two instances of this driver.
589 if (data
->index
>= 1)
592 if (data
->disable_oc
) {
593 reg
= readl(usbmisc
->base
);
594 writel(reg
| VF610_OVER_CUR_DIS
, usbmisc
->base
);
600 static int usbmisc_imx7d_set_wakeup
601 (struct imx_usbmisc_data
*data
, bool enabled
)
603 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
607 spin_lock_irqsave(&usbmisc
->lock
, flags
);
608 val
= readl(usbmisc
->base
);
610 val
&= ~MX6_USB_OTG_WAKEUP_BITS
;
611 val
|= usbmisc_wakeup_setting(data
);
612 writel(val
, usbmisc
->base
);
614 if (val
& MX6_BM_WAKEUP_INTR
)
615 dev_dbg(data
->dev
, "wakeup int\n");
616 writel(val
& ~MX6_USB_OTG_WAKEUP_BITS
, usbmisc
->base
);
618 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
623 static int usbmisc_imx7d_init(struct imx_usbmisc_data
*data
)
625 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
629 if (data
->index
>= 1)
632 spin_lock_irqsave(&usbmisc
->lock
, flags
);
633 reg
= readl(usbmisc
->base
);
634 if (data
->disable_oc
) {
635 reg
|= MX6_BM_OVER_CUR_DIS
;
637 reg
&= ~MX6_BM_OVER_CUR_DIS
;
640 * If the polarity is not configured keep it as setup by the
643 if (data
->oc_pol_configured
&& data
->oc_pol_active_low
)
644 reg
|= MX6_BM_OVER_CUR_POLARITY
;
645 else if (data
->oc_pol_configured
)
646 reg
&= ~MX6_BM_OVER_CUR_POLARITY
;
648 /* If the polarity is not set keep it as setup by the bootlader */
649 if (data
->pwr_pol
== 1)
650 reg
|= MX6_BM_PWR_POLARITY
;
651 writel(reg
, usbmisc
->base
);
653 /* SoC non-burst setting */
654 reg
= readl(usbmisc
->base
);
655 writel(reg
| MX6_BM_NON_BURST_SETTING
, usbmisc
->base
);
658 reg
= readl(usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
659 reg
&= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK
;
660 writel(reg
| MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID
661 | MX7D_USBNC_AUTO_RESUME
,
662 usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
663 /* PHY tuning for signal quality */
664 reg
= readl(usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG1
);
665 if (data
->emp_curr_control
>= 0 &&
666 data
->emp_curr_control
<=
667 (TXPREEMPAMPTUNE0_MASK
>> TXPREEMPAMPTUNE0_BIT
)) {
668 reg
&= ~TXPREEMPAMPTUNE0_MASK
;
669 reg
|= (data
->emp_curr_control
<< TXPREEMPAMPTUNE0_BIT
);
672 if (data
->dc_vol_level_adjust
>= 0 &&
673 data
->dc_vol_level_adjust
<=
674 (TXVREFTUNE0_MASK
>> TXVREFTUNE0_BIT
)) {
675 reg
&= ~TXVREFTUNE0_MASK
;
676 reg
|= (data
->dc_vol_level_adjust
<< TXVREFTUNE0_BIT
);
679 if (data
->rise_fall_time_adjust
>= 0 &&
680 data
->rise_fall_time_adjust
<=
681 (TXRISETUNE0_MASK
>> TXRISETUNE0_BIT
)) {
682 reg
&= ~TXRISETUNE0_MASK
;
683 reg
|= (data
->rise_fall_time_adjust
<< TXRISETUNE0_BIT
);
686 writel(reg
, usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG1
);
689 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
691 usbmisc_imx7d_set_wakeup(data
, false);
696 static int imx7d_charger_secondary_detection(struct imx_usbmisc_data
*data
)
698 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
699 struct usb_phy
*usb_phy
= data
->usb_phy
;
703 /* Clear VDATSRCENB0 to disable VDP_SRC and IDM_SNK required by BC 1.2 spec */
704 spin_lock_irqsave(&usbmisc
->lock
, flags
);
705 val
= readl(usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
706 val
&= ~MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0
;
707 writel(val
, usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
708 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
713 /* VDM_SRC is connected to D- and IDP_SINK is connected to D+ */
714 spin_lock_irqsave(&usbmisc
->lock
, flags
);
715 val
= readl(usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
716 writel(val
| MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0
|
717 MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0
|
718 MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL
,
719 usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
720 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
726 * Per BC 1.2, check voltage of D+:
727 * DCP: if greater than VDAT_REF;
728 * CDP: if less than VDAT_REF.
730 val
= readl(usbmisc
->base
+ MX7D_USB_OTG_PHY_STATUS
);
731 if (val
& MX7D_USB_OTG_PHY_STATUS_CHRGDET
) {
732 dev_dbg(data
->dev
, "It is a dedicate charging port\n");
733 usb_phy
->chg_type
= DCP_TYPE
;
735 dev_dbg(data
->dev
, "It is a charging downstream port\n");
736 usb_phy
->chg_type
= CDP_TYPE
;
742 static void imx7_disable_charger_detector(struct imx_usbmisc_data
*data
)
744 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
748 spin_lock_irqsave(&usbmisc
->lock
, flags
);
749 val
= readl(usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
750 val
&= ~(MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB
|
751 MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0
|
752 MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0
|
753 MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL
);
754 writel(val
, usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
756 /* Set OPMODE to be 2'b00 and disable its override */
757 val
= readl(usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
758 val
&= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK
;
759 writel(val
, usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
761 val
= readl(usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
762 writel(val
& ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN
,
763 usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
764 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
767 static int imx7d_charger_data_contact_detect(struct imx_usbmisc_data
*data
)
769 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
772 int i
, data_pin_contact_count
= 0;
774 /* Enable Data Contact Detect (DCD) per the USB BC 1.2 */
775 spin_lock_irqsave(&usbmisc
->lock
, flags
);
776 val
= readl(usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
777 writel(val
| MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB
,
778 usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
779 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
781 for (i
= 0; i
< 100; i
= i
+ 1) {
782 val
= readl(usbmisc
->base
+ MX7D_USB_OTG_PHY_STATUS
);
783 if (!(val
& MX7D_USB_OTG_PHY_STATUS_LINE_STATE0
)) {
784 if (data_pin_contact_count
++ > 5)
785 /* Data pin makes contact */
787 usleep_range(5000, 10000);
789 data_pin_contact_count
= 0;
790 usleep_range(5000, 6000);
794 /* Disable DCD after finished data contact check */
795 spin_lock_irqsave(&usbmisc
->lock
, flags
);
796 val
= readl(usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
797 writel(val
& ~MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB
,
798 usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
799 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
803 "VBUS is coming from a dedicated power supply.\n");
810 static int imx7d_charger_primary_detection(struct imx_usbmisc_data
*data
)
812 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
813 struct usb_phy
*usb_phy
= data
->usb_phy
;
817 /* VDP_SRC is connected to D+ and IDM_SINK is connected to D- */
818 spin_lock_irqsave(&usbmisc
->lock
, flags
);
819 val
= readl(usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
820 val
&= ~MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL
;
821 writel(val
| MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0
|
822 MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0
,
823 usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
824 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
829 /* Check if D- is less than VDAT_REF to determine an SDP per BC 1.2 */
830 val
= readl(usbmisc
->base
+ MX7D_USB_OTG_PHY_STATUS
);
831 if (!(val
& MX7D_USB_OTG_PHY_STATUS_CHRGDET
)) {
832 dev_dbg(data
->dev
, "It is a standard downstream port\n");
833 usb_phy
->chg_type
= SDP_TYPE
;
840 * Whole charger detection process:
841 * 1. OPMODE override to be non-driving
842 * 2. Data contact check
843 * 3. Primary detection
844 * 4. Secondary detection
845 * 5. Disable charger detection
847 static int imx7d_charger_detection(struct imx_usbmisc_data
*data
)
849 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
850 struct usb_phy
*usb_phy
= data
->usb_phy
;
855 /* Check if vbus is valid */
856 val
= readl(usbmisc
->base
+ MX7D_USB_OTG_PHY_STATUS
);
857 if (!(val
& MX7D_USB_OTG_PHY_STATUS_VBUS_VLD
)) {
858 dev_err(data
->dev
, "vbus is error\n");
863 * Keep OPMODE to be non-driving mode during the whole
864 * charger detection process.
866 spin_lock_irqsave(&usbmisc
->lock
, flags
);
867 val
= readl(usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
868 val
&= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK
;
869 val
|= MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING
;
870 writel(val
, usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
872 val
= readl(usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
873 writel(val
| MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN
,
874 usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
875 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
877 ret
= imx7d_charger_data_contact_detect(data
);
881 ret
= imx7d_charger_primary_detection(data
);
882 if (!ret
&& usb_phy
->chg_type
!= SDP_TYPE
)
883 ret
= imx7d_charger_secondary_detection(data
);
885 imx7_disable_charger_detector(data
);
890 static void usbmisc_imx7d_vbus_comparator_on(struct imx_usbmisc_data
*data
,
894 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
900 spin_lock_irqsave(&usbmisc
->lock
, flags
);
902 * Disable VBUS valid comparator when in suspend mode,
903 * when OTG is disabled and DRVVBUS0 is asserted case
904 * the Bandgap circuitry and VBUS Valid comparator are
905 * still powered, even in Suspend or Sleep mode.
907 val
= readl(usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
909 val
|= MX7D_USB_OTG_PHY_CFG2_DRVVBUS0
;
911 val
&= ~MX7D_USB_OTG_PHY_CFG2_DRVVBUS0
;
913 writel(val
, usbmisc
->base
+ MX7D_USB_OTG_PHY_CFG2
);
914 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
917 static int usbmisc_imx7ulp_init(struct imx_usbmisc_data
*data
)
919 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
923 if (data
->index
>= 1)
926 spin_lock_irqsave(&usbmisc
->lock
, flags
);
927 reg
= readl(usbmisc
->base
);
928 if (data
->disable_oc
) {
929 reg
|= MX6_BM_OVER_CUR_DIS
;
931 reg
&= ~MX6_BM_OVER_CUR_DIS
;
934 * If the polarity is not configured keep it as setup by the
937 if (data
->oc_pol_configured
&& data
->oc_pol_active_low
)
938 reg
|= MX6_BM_OVER_CUR_POLARITY
;
939 else if (data
->oc_pol_configured
)
940 reg
&= ~MX6_BM_OVER_CUR_POLARITY
;
942 /* If the polarity is not set keep it as setup by the bootlader */
943 if (data
->pwr_pol
== 1)
944 reg
|= MX6_BM_PWR_POLARITY
;
946 writel(reg
, usbmisc
->base
);
948 /* SoC non-burst setting */
949 reg
= readl(usbmisc
->base
);
950 writel(reg
| MX6_BM_NON_BURST_SETTING
, usbmisc
->base
);
953 reg
= readl(usbmisc
->base
);
954 writel(reg
| MX6_BM_UTMI_ON_CLOCK
, usbmisc
->base
);
956 reg
= readl(usbmisc
->base
+ MX6_USB_HSIC_CTRL_OFFSET
);
957 reg
|= MX6_BM_HSIC_EN
| MX6_BM_HSIC_CLK_ON
;
958 writel(reg
, usbmisc
->base
+ MX6_USB_HSIC_CTRL_OFFSET
);
961 * For non-HSIC controller, the autoresume is enabled
962 * at MXS PHY driver (usbphy_ctrl bit18).
964 reg
= readl(usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
965 writel(reg
| MX7D_USBNC_AUTO_RESUME
,
966 usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
968 reg
= readl(usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
969 reg
&= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK
;
970 writel(reg
| MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID
,
971 usbmisc
->base
+ MX7D_USBNC_USB_CTRL2
);
974 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
976 usbmisc_imx7d_set_wakeup(data
, false);
981 static int usbmisc_imx7d_power_lost_check(struct imx_usbmisc_data
*data
)
983 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
987 spin_lock_irqsave(&usbmisc
->lock
, flags
);
988 val
= readl(usbmisc
->base
);
989 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
991 * Here use a power on reset value to judge
992 * if the controller experienced a power lost
994 if (val
== 0x30001000)
1000 static int usbmisc_imx6sx_power_lost_check(struct imx_usbmisc_data
*data
)
1002 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
1003 unsigned long flags
;
1006 spin_lock_irqsave(&usbmisc
->lock
, flags
);
1007 val
= readl(usbmisc
->base
+ data
->index
* 4);
1008 spin_unlock_irqrestore(&usbmisc
->lock
, flags
);
1010 * Here use a power on reset value to judge
1011 * if the controller experienced a power lost
1013 if (val
== 0x30001000)
1019 static const struct usbmisc_ops imx25_usbmisc_ops
= {
1020 .init
= usbmisc_imx25_init
,
1021 .post
= usbmisc_imx25_post
,
1024 static const struct usbmisc_ops imx27_usbmisc_ops
= {
1025 .init
= usbmisc_imx27_init
,
1028 static const struct usbmisc_ops imx51_usbmisc_ops
= {
1029 .init
= usbmisc_imx53_init
,
1032 static const struct usbmisc_ops imx53_usbmisc_ops
= {
1033 .init
= usbmisc_imx53_init
,
1036 static const struct usbmisc_ops imx6q_usbmisc_ops
= {
1037 .set_wakeup
= usbmisc_imx6q_set_wakeup
,
1038 .init
= usbmisc_imx6q_init
,
1039 .hsic_set_connect
= usbmisc_imx6_hsic_set_connect
,
1040 .hsic_set_clk
= usbmisc_imx6_hsic_set_clk
,
1043 static const struct usbmisc_ops vf610_usbmisc_ops
= {
1044 .init
= usbmisc_vf610_init
,
1047 static const struct usbmisc_ops imx6sx_usbmisc_ops
= {
1048 .set_wakeup
= usbmisc_imx6q_set_wakeup
,
1049 .init
= usbmisc_imx6sx_init
,
1050 .hsic_set_connect
= usbmisc_imx6_hsic_set_connect
,
1051 .hsic_set_clk
= usbmisc_imx6_hsic_set_clk
,
1052 .power_lost_check
= usbmisc_imx6sx_power_lost_check
,
1055 static const struct usbmisc_ops imx7d_usbmisc_ops
= {
1056 .init
= usbmisc_imx7d_init
,
1057 .set_wakeup
= usbmisc_imx7d_set_wakeup
,
1058 .charger_detection
= imx7d_charger_detection
,
1059 .power_lost_check
= usbmisc_imx7d_power_lost_check
,
1060 .vbus_comparator_on
= usbmisc_imx7d_vbus_comparator_on
,
1063 static const struct usbmisc_ops imx7ulp_usbmisc_ops
= {
1064 .init
= usbmisc_imx7ulp_init
,
1065 .set_wakeup
= usbmisc_imx7d_set_wakeup
,
1066 .hsic_set_connect
= usbmisc_imx6_hsic_set_connect
,
1067 .hsic_set_clk
= usbmisc_imx6_hsic_set_clk
,
1068 .power_lost_check
= usbmisc_imx7d_power_lost_check
,
1071 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data
*data
)
1073 struct imx_usbmisc
*usbmisc
= dev_get_drvdata(data
->dev
);
1075 return usbmisc
->ops
== &imx53_usbmisc_ops
;
1078 int imx_usbmisc_init(struct imx_usbmisc_data
*data
)
1080 struct imx_usbmisc
*usbmisc
;
1085 usbmisc
= dev_get_drvdata(data
->dev
);
1086 if (!usbmisc
->ops
->init
)
1088 return usbmisc
->ops
->init(data
);
1090 EXPORT_SYMBOL_GPL(imx_usbmisc_init
);
1092 int imx_usbmisc_init_post(struct imx_usbmisc_data
*data
)
1094 struct imx_usbmisc
*usbmisc
;
1100 usbmisc
= dev_get_drvdata(data
->dev
);
1101 if (usbmisc
->ops
->post
)
1102 ret
= usbmisc
->ops
->post(data
);
1104 dev_err(data
->dev
, "post init failed, ret=%d\n", ret
);
1108 if (usbmisc
->ops
->set_wakeup
)
1109 ret
= usbmisc
->ops
->set_wakeup(data
, false);
1111 dev_err(data
->dev
, "set_wakeup failed, ret=%d\n", ret
);
1117 EXPORT_SYMBOL_GPL(imx_usbmisc_init_post
);
1119 int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data
*data
)
1121 struct imx_usbmisc
*usbmisc
;
1126 usbmisc
= dev_get_drvdata(data
->dev
);
1127 if (!usbmisc
->ops
->hsic_set_connect
|| !data
->hsic
)
1129 return usbmisc
->ops
->hsic_set_connect(data
);
1131 EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_connect
);
1133 int imx_usbmisc_charger_detection(struct imx_usbmisc_data
*data
, bool connect
)
1135 struct imx_usbmisc
*usbmisc
;
1136 struct usb_phy
*usb_phy
;
1142 usbmisc
= dev_get_drvdata(data
->dev
);
1143 usb_phy
= data
->usb_phy
;
1144 if (!usbmisc
->ops
->charger_detection
)
1148 ret
= usbmisc
->ops
->charger_detection(data
);
1151 "Error occurs during detection: %d\n",
1153 usb_phy
->chg_state
= USB_CHARGER_ABSENT
;
1155 usb_phy
->chg_state
= USB_CHARGER_PRESENT
;
1158 usb_phy
->chg_state
= USB_CHARGER_ABSENT
;
1159 usb_phy
->chg_type
= UNKNOWN_TYPE
;
1163 EXPORT_SYMBOL_GPL(imx_usbmisc_charger_detection
);
1165 int imx_usbmisc_suspend(struct imx_usbmisc_data
*data
, bool wakeup
)
1167 struct imx_usbmisc
*usbmisc
;
1173 usbmisc
= dev_get_drvdata(data
->dev
);
1175 if (usbmisc
->ops
->vbus_comparator_on
)
1176 usbmisc
->ops
->vbus_comparator_on(data
, false);
1178 if (wakeup
&& usbmisc
->ops
->set_wakeup
)
1179 ret
= usbmisc
->ops
->set_wakeup(data
, true);
1181 dev_err(data
->dev
, "set_wakeup failed, ret=%d\n", ret
);
1185 if (usbmisc
->ops
->hsic_set_clk
&& data
->hsic
)
1186 ret
= usbmisc
->ops
->hsic_set_clk(data
, false);
1188 dev_err(data
->dev
, "set_wakeup failed, ret=%d\n", ret
);
1194 EXPORT_SYMBOL_GPL(imx_usbmisc_suspend
);
1196 int imx_usbmisc_resume(struct imx_usbmisc_data
*data
, bool wakeup
)
1198 struct imx_usbmisc
*usbmisc
;
1204 usbmisc
= dev_get_drvdata(data
->dev
);
1206 if (usbmisc
->ops
->power_lost_check
)
1207 ret
= usbmisc
->ops
->power_lost_check(data
);
1209 /* re-init if resume from power lost */
1210 ret
= imx_usbmisc_init(data
);
1212 dev_err(data
->dev
, "re-init failed, ret=%d\n", ret
);
1217 if (wakeup
&& usbmisc
->ops
->set_wakeup
)
1218 ret
= usbmisc
->ops
->set_wakeup(data
, false);
1220 dev_err(data
->dev
, "set_wakeup failed, ret=%d\n", ret
);
1224 if (usbmisc
->ops
->hsic_set_clk
&& data
->hsic
)
1225 ret
= usbmisc
->ops
->hsic_set_clk(data
, true);
1227 dev_err(data
->dev
, "set_wakeup failed, ret=%d\n", ret
);
1228 goto hsic_set_clk_fail
;
1231 if (usbmisc
->ops
->vbus_comparator_on
)
1232 usbmisc
->ops
->vbus_comparator_on(data
, true);
1237 if (wakeup
&& usbmisc
->ops
->set_wakeup
)
1238 usbmisc
->ops
->set_wakeup(data
, true);
1241 EXPORT_SYMBOL_GPL(imx_usbmisc_resume
);
1243 static const struct of_device_id usbmisc_imx_dt_ids
[] = {
1245 .compatible
= "fsl,imx25-usbmisc",
1246 .data
= &imx25_usbmisc_ops
,
1249 .compatible
= "fsl,imx35-usbmisc",
1250 .data
= &imx25_usbmisc_ops
,
1253 .compatible
= "fsl,imx27-usbmisc",
1254 .data
= &imx27_usbmisc_ops
,
1257 .compatible
= "fsl,imx51-usbmisc",
1258 .data
= &imx51_usbmisc_ops
,
1261 .compatible
= "fsl,imx53-usbmisc",
1262 .data
= &imx53_usbmisc_ops
,
1265 .compatible
= "fsl,imx6q-usbmisc",
1266 .data
= &imx6q_usbmisc_ops
,
1269 .compatible
= "fsl,vf610-usbmisc",
1270 .data
= &vf610_usbmisc_ops
,
1273 .compatible
= "fsl,imx6sx-usbmisc",
1274 .data
= &imx6sx_usbmisc_ops
,
1277 .compatible
= "fsl,imx6ul-usbmisc",
1278 .data
= &imx6sx_usbmisc_ops
,
1281 .compatible
= "fsl,imx7d-usbmisc",
1282 .data
= &imx7d_usbmisc_ops
,
1285 .compatible
= "fsl,imx7ulp-usbmisc",
1286 .data
= &imx7ulp_usbmisc_ops
,
1289 .compatible
= "fsl,imx8ulp-usbmisc",
1290 .data
= &imx7ulp_usbmisc_ops
,
1294 MODULE_DEVICE_TABLE(of
, usbmisc_imx_dt_ids
);
1296 static int usbmisc_imx_probe(struct platform_device
*pdev
)
1298 struct imx_usbmisc
*data
;
1300 data
= devm_kzalloc(&pdev
->dev
, sizeof(*data
), GFP_KERNEL
);
1304 spin_lock_init(&data
->lock
);
1306 data
->base
= devm_platform_ioremap_resource(pdev
, 0);
1307 if (IS_ERR(data
->base
))
1308 return PTR_ERR(data
->base
);
1310 data
->ops
= of_device_get_match_data(&pdev
->dev
);
1311 platform_set_drvdata(pdev
, data
);
1316 static struct platform_driver usbmisc_imx_driver
= {
1317 .probe
= usbmisc_imx_probe
,
1319 .name
= "usbmisc_imx",
1320 .of_match_table
= usbmisc_imx_dt_ids
,
1324 module_platform_driver(usbmisc_imx_driver
);
1326 MODULE_ALIAS("platform:usbmisc-imx");
1327 MODULE_LICENSE("GPL");
1328 MODULE_DESCRIPTION("driver for imx usb non-core registers");
1329 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");