xref: /linux/drivers/usb/chipidea/usbmisc_imx.c (revision 8004d08330e1aa7ae797778509e864f7ac3da687)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2012 Freescale Semiconductor, Inc.
4  * Copyright 2025 NXP
5  */
6 
7 #include <linux/module.h>
8 #include <linux/of.h>
9 #include <linux/err.h>
10 #include <linux/io.h>
11 #include <linux/delay.h>
12 #include <linux/platform_device.h>
13 #include <linux/usb/otg.h>
14 
15 #include "ci_hdrc_imx.h"
16 
17 #define MX25_USB_PHY_CTRL_OFFSET	0x08
18 #define MX25_BM_EXTERNAL_VBUS_DIVIDER	BIT(23)
19 
20 #define MX25_EHCI_INTERFACE_SINGLE_UNI	(2 << 0)
21 #define MX25_EHCI_INTERFACE_DIFF_UNI	(0 << 0)
22 #define MX25_EHCI_INTERFACE_MASK	(0xf)
23 
24 #define MX25_OTG_SIC_SHIFT		29
25 #define MX25_OTG_SIC_MASK		(0x3 << MX25_OTG_SIC_SHIFT)
26 #define MX25_OTG_PM_BIT			BIT(24)
27 #define MX25_OTG_PP_BIT			BIT(11)
28 #define MX25_OTG_OCPOL_BIT		BIT(3)
29 
30 #define MX25_H1_SIC_SHIFT		21
31 #define MX25_H1_SIC_MASK		(0x3 << MX25_H1_SIC_SHIFT)
32 #define MX25_H1_PP_BIT			BIT(18)
33 #define MX25_H1_PM_BIT			BIT(16)
34 #define MX25_H1_IPPUE_UP_BIT		BIT(7)
35 #define MX25_H1_IPPUE_DOWN_BIT		BIT(6)
36 #define MX25_H1_TLL_BIT			BIT(5)
37 #define MX25_H1_USBTE_BIT		BIT(4)
38 #define MX25_H1_OCPOL_BIT		BIT(2)
39 
40 #define MX27_H1_PM_BIT			BIT(8)
41 #define MX27_H2_PM_BIT			BIT(16)
42 #define MX27_OTG_PM_BIT			BIT(24)
43 
44 #define MX53_USB_OTG_PHY_CTRL_0_OFFSET	0x08
45 #define MX53_USB_OTG_PHY_CTRL_1_OFFSET	0x0c
46 #define MX53_USB_CTRL_1_OFFSET	        0x10
47 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK (0x11 << 2)
48 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI BIT(2)
49 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK (0x11 << 6)
50 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI BIT(6)
51 #define MX53_USB_UH2_CTRL_OFFSET	0x14
52 #define MX53_USB_UH3_CTRL_OFFSET	0x18
53 #define MX53_USB_CLKONOFF_CTRL_OFFSET	0x24
54 #define MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF BIT(21)
55 #define MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF BIT(22)
56 #define MX53_BM_OVER_CUR_DIS_H1		BIT(5)
57 #define MX53_BM_OVER_CUR_DIS_OTG	BIT(8)
58 #define MX53_BM_OVER_CUR_DIS_UHx	BIT(30)
59 #define MX53_USB_CTRL_1_UH2_ULPI_EN	BIT(26)
60 #define MX53_USB_CTRL_1_UH3_ULPI_EN	BIT(27)
61 #define MX53_USB_UHx_CTRL_WAKE_UP_EN	BIT(7)
62 #define MX53_USB_UHx_CTRL_ULPI_INT_EN	BIT(8)
63 #define MX53_USB_PHYCTRL1_PLLDIV_MASK	0x3
64 #define MX53_USB_PLL_DIV_24_MHZ		0x01
65 
66 #define MX6_BM_NON_BURST_SETTING	BIT(1)
67 #define MX6_BM_OVER_CUR_DIS		BIT(7)
68 #define MX6_BM_OVER_CUR_POLARITY	BIT(8)
69 #define MX6_BM_PWR_POLARITY		BIT(9)
70 #define MX6_BM_WAKEUP_ENABLE		BIT(10)
71 #define MX6_BM_UTMI_ON_CLOCK		BIT(13)
72 #define MX6_BM_ID_WAKEUP		BIT(16)
73 #define MX6_BM_VBUS_WAKEUP		BIT(17)
74 #define MX6SX_BM_DPDM_WAKEUP_EN		BIT(29)
75 #define MX6_BM_WAKEUP_INTR		BIT(31)
76 
77 #define MX6_USB_HSIC_CTRL_OFFSET	0x10
78 /* Send resume signal without 480Mhz PHY clock */
79 #define MX6SX_BM_HSIC_AUTO_RESUME	BIT(23)
80 /* set before portsc.suspendM = 1 */
81 #define MX6_BM_HSIC_DEV_CONN		BIT(21)
82 /* HSIC enable */
83 #define MX6_BM_HSIC_EN			BIT(12)
84 /* Force HSIC module 480M clock on, even when in Host is in suspend mode */
85 #define MX6_BM_HSIC_CLK_ON		BIT(11)
86 
87 #define MX6_USB_OTG1_PHY_CTRL		0x18
88 /* For imx6dql, it is host-only controller, for later imx6, it is otg's */
89 #define MX6_USB_OTG2_PHY_CTRL		0x1c
90 #define MX6SX_USB_VBUS_WAKEUP_SOURCE(v)	(v << 8)
91 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_VBUS	MX6SX_USB_VBUS_WAKEUP_SOURCE(0)
92 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_AVALID	MX6SX_USB_VBUS_WAKEUP_SOURCE(1)
93 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID	MX6SX_USB_VBUS_WAKEUP_SOURCE(2)
94 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_SESS_END	MX6SX_USB_VBUS_WAKEUP_SOURCE(3)
95 
96 #define VF610_OVER_CUR_DIS		BIT(7)
97 
98 #define MX7D_USBNC_USB_CTRL2		0x4
99 #define MX7D_USB_VBUS_WAKEUP_SOURCE_MASK	0x3
100 #define MX7D_USB_VBUS_WAKEUP_SOURCE(v)		(v << 0)
101 #define MX7D_USB_VBUS_WAKEUP_SOURCE_VBUS	MX7D_USB_VBUS_WAKEUP_SOURCE(0)
102 #define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID	MX7D_USB_VBUS_WAKEUP_SOURCE(1)
103 #define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID	MX7D_USB_VBUS_WAKEUP_SOURCE(2)
104 #define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END	MX7D_USB_VBUS_WAKEUP_SOURCE(3)
105 #define MX7D_USBNC_AUTO_RESUME				BIT(2)
106 /* The default DM/DP value is pull-down */
107 #define MX7D_USBNC_USB_CTRL2_OPMODE(v)			(v << 6)
108 #define MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING	MX7D_USBNC_USB_CTRL2_OPMODE(1)
109 #define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK	(BIT(7) | BIT(6))
110 #define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN		BIT(8)
111 #define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_VAL		BIT(12)
112 #define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_EN		BIT(13)
113 #define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_VAL		BIT(14)
114 #define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_EN		BIT(15)
115 #define MX7D_USBNC_USB_CTRL2_DP_DM_MASK			(BIT(12) | BIT(13) | \
116 							BIT(14) | BIT(15))
117 
118 #define MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL	BIT(0)
119 #define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0	BIT(1)
120 #define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0	BIT(2)
121 #define MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB	BIT(3)
122 #define MX7D_USB_OTG_PHY_CFG2_DRVVBUS0		BIT(16)
123 
124 #define MX7D_USB_OTG_PHY_CFG2		0x34
125 
126 #define MX7D_USB_OTG_PHY_STATUS		0x3c
127 #define MX7D_USB_OTG_PHY_STATUS_LINE_STATE0	BIT(0)
128 #define MX7D_USB_OTG_PHY_STATUS_LINE_STATE1	BIT(1)
129 #define MX7D_USB_OTG_PHY_STATUS_VBUS_VLD	BIT(3)
130 #define MX7D_USB_OTG_PHY_STATUS_CHRGDET		BIT(29)
131 
132 #define MX7D_USB_OTG_PHY_CFG1		0x30
133 #define TXPREEMPAMPTUNE0_BIT		28
134 #define TXPREEMPAMPTUNE0_MASK		(3 << 28)
135 #define TXRISETUNE0_BIT			24
136 #define TXRISETUNE0_MASK		(3 << 24)
137 #define TXVREFTUNE0_BIT			20
138 #define TXVREFTUNE0_MASK		(0xf << 20)
139 
140 #define MX6_USB_OTG_WAKEUP_BITS (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP | \
141 				 MX6_BM_ID_WAKEUP | MX6SX_BM_DPDM_WAKEUP_EN)
142 
143 /*
144  * HSIO Block Control Register
145  */
146 
147 #define BLKCTL_USB_WAKEUP_CTRL		0x0
148 #define BLKCTL_OTG_WAKE_ENABLE		BIT(31)
149 #define BLKCTL_OTG_VBUS_SESSVALID	BIT(4)
150 #define BLKCTL_OTG_ID_WAKEUP_EN		BIT(2)
151 #define BLKCTL_OTG_VBUS_WAKEUP_EN	BIT(1)
152 #define BLKCTL_OTG_DPDM_WAKEUP_EN	BIT(0)
153 
154 #define BLKCTL_WAKEUP_SOURCE		(BLKCTL_OTG_WAKE_ENABLE	   | \
155 					 BLKCTL_OTG_ID_WAKEUP_EN   | \
156 					 BLKCTL_OTG_VBUS_WAKEUP_EN | \
157 					 BLKCTL_OTG_DPDM_WAKEUP_EN)
158 
159 #define S32G_WAKEUP_IE		BIT(0)
160 #define S32G_CORE_IE		BIT(1)
161 #define S32G_PWRFLTEN		BIT(7)
162 #define S32G_WAKEUPCTRL		BIT(10)
163 #define S32G_WAKEUPEN		BIT(11)
164 
165 /* Workaround errata ERR050474 (handle packages that aren't 4 byte aligned) */
166 #define S32G_UCMALLBE		BIT(15)
167 
168 #define S32G_WAKEUP_BITS (S32G_WAKEUP_IE | S32G_CORE_IE | S32G_WAKEUPEN | \
169 			  S32G_WAKEUPCTRL)
170 
171 struct usbmisc_ops {
172 	/* It's called once when probe a usb device */
173 	int (*init)(struct imx_usbmisc_data *data);
174 	/* It's called once after adding a usb device */
175 	int (*post)(struct imx_usbmisc_data *data);
176 	/* It's called when we need to enable/disable usb wakeup */
177 	int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled);
178 	/* It's called before setting portsc.suspendM */
179 	int (*hsic_set_connect)(struct imx_usbmisc_data *data);
180 	/* It's called during suspend/resume */
181 	int (*hsic_set_clk)(struct imx_usbmisc_data *data, bool enabled);
182 	/* usb charger detection */
183 	int (*charger_detection)(struct imx_usbmisc_data *data);
184 	/* It's called when system resume from usb power lost */
185 	int (*power_lost_check)(struct imx_usbmisc_data *data);
186 	/* It's called when device controller changed pullup status */
187 	void (*pullup)(struct imx_usbmisc_data *data, bool on);
188 	/* It's called during suspend/resume to save power */
189 	void (*vbus_comparator_on)(struct imx_usbmisc_data *data, bool on);
190 };
191 
192 struct imx_usbmisc {
193 	void __iomem *base;
194 	void __iomem *blkctl;
195 	spinlock_t lock;
196 	const struct usbmisc_ops *ops;
197 };
198 
199 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data);
200 
usbmisc_imx25_init(struct imx_usbmisc_data * data)201 static int usbmisc_imx25_init(struct imx_usbmisc_data *data)
202 {
203 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
204 	unsigned long flags;
205 	u32 val = 0;
206 
207 	if (data->index > 1)
208 		return -EINVAL;
209 
210 	spin_lock_irqsave(&usbmisc->lock, flags);
211 	switch (data->index) {
212 	case 0:
213 		val = readl(usbmisc->base);
214 		val &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PP_BIT);
215 		val |= (MX25_EHCI_INTERFACE_DIFF_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT;
216 		val |= (MX25_OTG_PM_BIT | MX25_OTG_OCPOL_BIT);
217 
218 		/*
219 		 * If the polarity is not configured assume active high for
220 		 * historical reasons.
221 		 */
222 		if (data->oc_pol_configured && data->oc_pol_active_low)
223 			val &= ~MX25_OTG_OCPOL_BIT;
224 
225 		writel(val, usbmisc->base);
226 		break;
227 	case 1:
228 		val = readl(usbmisc->base);
229 		val &= ~(MX25_H1_SIC_MASK | MX25_H1_PP_BIT |  MX25_H1_IPPUE_UP_BIT);
230 		val |= (MX25_EHCI_INTERFACE_SINGLE_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT;
231 		val |= (MX25_H1_PM_BIT | MX25_H1_OCPOL_BIT | MX25_H1_TLL_BIT |
232 			MX25_H1_USBTE_BIT | MX25_H1_IPPUE_DOWN_BIT);
233 
234 		/*
235 		 * If the polarity is not configured assume active high for
236 		 * historical reasons.
237 		 */
238 		if (data->oc_pol_configured && data->oc_pol_active_low)
239 			val &= ~MX25_H1_OCPOL_BIT;
240 
241 		writel(val, usbmisc->base);
242 
243 		break;
244 	}
245 	spin_unlock_irqrestore(&usbmisc->lock, flags);
246 
247 	return 0;
248 }
249 
usbmisc_imx25_post(struct imx_usbmisc_data * data)250 static int usbmisc_imx25_post(struct imx_usbmisc_data *data)
251 {
252 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
253 	void __iomem *reg;
254 	unsigned long flags;
255 	u32 val;
256 
257 	if (data->index > 2)
258 		return -EINVAL;
259 
260 	if (data->index)
261 		return 0;
262 
263 	spin_lock_irqsave(&usbmisc->lock, flags);
264 	reg = usbmisc->base + MX25_USB_PHY_CTRL_OFFSET;
265 	val = readl(reg);
266 
267 	if (data->evdo)
268 		val |= MX25_BM_EXTERNAL_VBUS_DIVIDER;
269 	else
270 		val &= ~MX25_BM_EXTERNAL_VBUS_DIVIDER;
271 
272 	writel(val, reg);
273 	spin_unlock_irqrestore(&usbmisc->lock, flags);
274 	usleep_range(5000, 10000); /* needed to stabilize voltage */
275 
276 	return 0;
277 }
278 
usbmisc_imx27_init(struct imx_usbmisc_data * data)279 static int usbmisc_imx27_init(struct imx_usbmisc_data *data)
280 {
281 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
282 	unsigned long flags;
283 	u32 val;
284 
285 	switch (data->index) {
286 	case 0:
287 		val = MX27_OTG_PM_BIT;
288 		break;
289 	case 1:
290 		val = MX27_H1_PM_BIT;
291 		break;
292 	case 2:
293 		val = MX27_H2_PM_BIT;
294 		break;
295 	default:
296 		return -EINVAL;
297 	}
298 
299 	spin_lock_irqsave(&usbmisc->lock, flags);
300 	if (data->disable_oc)
301 		val = readl(usbmisc->base) | val;
302 	else
303 		val = readl(usbmisc->base) & ~val;
304 	writel(val, usbmisc->base);
305 	spin_unlock_irqrestore(&usbmisc->lock, flags);
306 
307 	return 0;
308 }
309 
usbmisc_imx53_init(struct imx_usbmisc_data * data)310 static int usbmisc_imx53_init(struct imx_usbmisc_data *data)
311 {
312 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
313 	void __iomem *reg = NULL;
314 	unsigned long flags;
315 	u32 val = 0;
316 
317 	if (data->index > 3)
318 		return -EINVAL;
319 
320 	/* Select a 24 MHz reference clock for the PHY  */
321 	val = readl(usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET);
322 	val &= ~MX53_USB_PHYCTRL1_PLLDIV_MASK;
323 	val |= MX53_USB_PLL_DIV_24_MHZ;
324 	writel(val, usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET);
325 
326 	spin_lock_irqsave(&usbmisc->lock, flags);
327 
328 	switch (data->index) {
329 	case 0:
330 		if (data->disable_oc) {
331 			reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET;
332 			val = readl(reg) | MX53_BM_OVER_CUR_DIS_OTG;
333 			writel(val, reg);
334 		}
335 		break;
336 	case 1:
337 		if (data->disable_oc) {
338 			reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET;
339 			val = readl(reg) | MX53_BM_OVER_CUR_DIS_H1;
340 			writel(val, reg);
341 		}
342 		break;
343 	case 2:
344 		if (data->ulpi) {
345 			/* set USBH2 into ULPI-mode. */
346 			reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET;
347 			val = readl(reg) | MX53_USB_CTRL_1_UH2_ULPI_EN;
348 			/* select ULPI clock */
349 			val &= ~MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK;
350 			val |= MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI;
351 			writel(val, reg);
352 			/* Set interrupt wake up enable */
353 			reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET;
354 			val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN
355 				| MX53_USB_UHx_CTRL_ULPI_INT_EN;
356 			writel(val, reg);
357 			if (is_imx53_usbmisc(data)) {
358 				/* Disable internal 60Mhz clock */
359 				reg = usbmisc->base +
360 					MX53_USB_CLKONOFF_CTRL_OFFSET;
361 				val = readl(reg) |
362 					MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF;
363 				writel(val, reg);
364 			}
365 
366 		}
367 		if (data->disable_oc) {
368 			reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET;
369 			val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx;
370 			writel(val, reg);
371 		}
372 		break;
373 	case 3:
374 		if (data->ulpi) {
375 			/* set USBH3 into ULPI-mode. */
376 			reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET;
377 			val = readl(reg) | MX53_USB_CTRL_1_UH3_ULPI_EN;
378 			/* select ULPI clock */
379 			val &= ~MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK;
380 			val |= MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI;
381 			writel(val, reg);
382 			/* Set interrupt wake up enable */
383 			reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET;
384 			val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN
385 				| MX53_USB_UHx_CTRL_ULPI_INT_EN;
386 			writel(val, reg);
387 
388 			if (is_imx53_usbmisc(data)) {
389 				/* Disable internal 60Mhz clock */
390 				reg = usbmisc->base +
391 					MX53_USB_CLKONOFF_CTRL_OFFSET;
392 				val = readl(reg) |
393 					MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF;
394 				writel(val, reg);
395 			}
396 		}
397 		if (data->disable_oc) {
398 			reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET;
399 			val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx;
400 			writel(val, reg);
401 		}
402 		break;
403 	}
404 
405 	spin_unlock_irqrestore(&usbmisc->lock, flags);
406 
407 	return 0;
408 }
409 
usbmisc_wakeup_setting(struct imx_usbmisc_data * data)410 static u32 usbmisc_wakeup_setting(struct imx_usbmisc_data *data)
411 {
412 	u32 wakeup_setting = MX6_USB_OTG_WAKEUP_BITS;
413 
414 	if (data->ext_id || data->available_role != USB_DR_MODE_OTG)
415 		wakeup_setting &= ~MX6_BM_ID_WAKEUP;
416 
417 	if (data->ext_vbus || data->available_role == USB_DR_MODE_HOST)
418 		wakeup_setting &= ~MX6_BM_VBUS_WAKEUP;
419 
420 	return wakeup_setting;
421 }
422 
usbmisc_imx6q_set_wakeup(struct imx_usbmisc_data * data,bool enabled)423 static int usbmisc_imx6q_set_wakeup
424 	(struct imx_usbmisc_data *data, bool enabled)
425 {
426 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
427 	unsigned long flags;
428 	u32 val;
429 	int ret = 0;
430 
431 	if (data->index > 3)
432 		return -EINVAL;
433 
434 	spin_lock_irqsave(&usbmisc->lock, flags);
435 	val = readl(usbmisc->base + data->index * 4);
436 	if (enabled) {
437 		val &= ~MX6_USB_OTG_WAKEUP_BITS;
438 		val |= usbmisc_wakeup_setting(data);
439 	} else {
440 		if (val & MX6_BM_WAKEUP_INTR)
441 			pr_debug("wakeup int at ci_hdrc.%d\n", data->index);
442 		val &= ~MX6_USB_OTG_WAKEUP_BITS;
443 	}
444 	writel(val, usbmisc->base + data->index * 4);
445 	spin_unlock_irqrestore(&usbmisc->lock, flags);
446 
447 	return ret;
448 }
449 
usbmisc_imx6q_init(struct imx_usbmisc_data * data)450 static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
451 {
452 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
453 	unsigned long flags;
454 	u32 reg;
455 
456 	if (data->index > 3)
457 		return -EINVAL;
458 
459 	spin_lock_irqsave(&usbmisc->lock, flags);
460 
461 	reg = readl(usbmisc->base + data->index * 4);
462 	if (data->disable_oc) {
463 		reg |= MX6_BM_OVER_CUR_DIS;
464 	} else {
465 		reg &= ~MX6_BM_OVER_CUR_DIS;
466 
467 		/*
468 		 * If the polarity is not configured keep it as setup by the
469 		 * bootloader.
470 		 */
471 		if (data->oc_pol_configured && data->oc_pol_active_low)
472 			reg |= MX6_BM_OVER_CUR_POLARITY;
473 		else if (data->oc_pol_configured)
474 			reg &= ~MX6_BM_OVER_CUR_POLARITY;
475 	}
476 	/* If the polarity is not set keep it as setup by the bootloader */
477 	if (data->pwr_pol == 1)
478 		reg |= MX6_BM_PWR_POLARITY;
479 	writel(reg, usbmisc->base + data->index * 4);
480 
481 	/* SoC non-burst setting */
482 	reg = readl(usbmisc->base + data->index * 4);
483 	writel(reg | MX6_BM_NON_BURST_SETTING,
484 			usbmisc->base + data->index * 4);
485 
486 	/* For HSIC controller */
487 	if (data->hsic) {
488 		reg = readl(usbmisc->base + data->index * 4);
489 		writel(reg | MX6_BM_UTMI_ON_CLOCK,
490 			usbmisc->base + data->index * 4);
491 		reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
492 			+ (data->index - 2) * 4);
493 		reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON;
494 		writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
495 			+ (data->index - 2) * 4);
496 	}
497 
498 	spin_unlock_irqrestore(&usbmisc->lock, flags);
499 
500 	usbmisc_imx6q_set_wakeup(data, false);
501 
502 	return 0;
503 }
504 
usbmisc_imx6_hsic_get_reg_offset(struct imx_usbmisc_data * data)505 static int usbmisc_imx6_hsic_get_reg_offset(struct imx_usbmisc_data *data)
506 {
507 	int offset, ret = 0;
508 
509 	if (data->index == 2 || data->index == 3) {
510 		offset = (data->index - 2) * 4;
511 	} else if (data->index == 0) {
512 		/*
513 		 * For SoCs like i.MX7D and later, each USB controller has
514 		 * its own non-core register region. For SoCs before i.MX7D,
515 		 * the first two USB controllers are non-HSIC controllers.
516 		 */
517 		offset = 0;
518 	} else {
519 		dev_err(data->dev, "index is error for usbmisc\n");
520 		ret = -EINVAL;
521 	}
522 
523 	return ret ? ret : offset;
524 }
525 
usbmisc_imx6_hsic_set_connect(struct imx_usbmisc_data * data)526 static int usbmisc_imx6_hsic_set_connect(struct imx_usbmisc_data *data)
527 {
528 	unsigned long flags;
529 	u32 val;
530 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
531 	int offset;
532 
533 	spin_lock_irqsave(&usbmisc->lock, flags);
534 	offset = usbmisc_imx6_hsic_get_reg_offset(data);
535 	if (offset < 0) {
536 		spin_unlock_irqrestore(&usbmisc->lock, flags);
537 		return offset;
538 	}
539 
540 	val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset);
541 	if (!(val & MX6_BM_HSIC_DEV_CONN))
542 		writel(val | MX6_BM_HSIC_DEV_CONN,
543 			usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset);
544 
545 	spin_unlock_irqrestore(&usbmisc->lock, flags);
546 
547 	return 0;
548 }
549 
usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data * data,bool on)550 static int usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data *data, bool on)
551 {
552 	unsigned long flags;
553 	u32 val;
554 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
555 	int offset;
556 
557 	spin_lock_irqsave(&usbmisc->lock, flags);
558 	offset = usbmisc_imx6_hsic_get_reg_offset(data);
559 	if (offset < 0) {
560 		spin_unlock_irqrestore(&usbmisc->lock, flags);
561 		return offset;
562 	}
563 
564 	val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset);
565 	val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON;
566 	if (on)
567 		val |= MX6_BM_HSIC_CLK_ON;
568 	else
569 		val &= ~MX6_BM_HSIC_CLK_ON;
570 
571 	writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset);
572 	spin_unlock_irqrestore(&usbmisc->lock, flags);
573 
574 	return 0;
575 }
576 
577 
usbmisc_imx6sx_init(struct imx_usbmisc_data * data)578 static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data)
579 {
580 	void __iomem *reg = NULL;
581 	unsigned long flags;
582 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
583 	u32 val;
584 
585 	usbmisc_imx6q_init(data);
586 
587 	if (data->index == 0 || data->index == 1) {
588 		reg = usbmisc->base + MX6_USB_OTG1_PHY_CTRL + data->index * 4;
589 		spin_lock_irqsave(&usbmisc->lock, flags);
590 		/* Set vbus wakeup source as bvalid */
591 		val = readl(reg);
592 		writel(val | MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID, reg);
593 		/*
594 		 * Disable dp/dm wakeup in device mode when vbus is
595 		 * not there.
596 		 */
597 		val = readl(usbmisc->base + data->index * 4);
598 		writel(val & ~MX6SX_BM_DPDM_WAKEUP_EN,
599 			usbmisc->base + data->index * 4);
600 		spin_unlock_irqrestore(&usbmisc->lock, flags);
601 	}
602 
603 	/* For HSIC controller */
604 	if (data->hsic) {
605 		val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET);
606 		val |= MX6SX_BM_HSIC_AUTO_RESUME;
607 		writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET);
608 	}
609 
610 	return 0;
611 }
612 
usbmisc_vf610_init(struct imx_usbmisc_data * data)613 static int usbmisc_vf610_init(struct imx_usbmisc_data *data)
614 {
615 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
616 	u32 reg;
617 
618 	/*
619 	 * Vybrid only has one misc register set, but in two different
620 	 * areas. These is reflected in two instances of this driver.
621 	 */
622 	if (data->index >= 1)
623 		return -EINVAL;
624 
625 	if (data->disable_oc) {
626 		reg = readl(usbmisc->base);
627 		writel(reg | VF610_OVER_CUR_DIS, usbmisc->base);
628 	}
629 
630 	return 0;
631 }
632 
usbmisc_s32g_set_wakeup(struct imx_usbmisc_data * data,bool enabled)633 static int usbmisc_s32g_set_wakeup(struct imx_usbmisc_data *data, bool enabled)
634 {
635 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
636 	unsigned long flags;
637 	u32 reg;
638 
639 	spin_lock_irqsave(&usbmisc->lock, flags);
640 
641 	reg = readl(usbmisc->base);
642 	if (enabled)
643 		reg |= S32G_WAKEUP_BITS;
644 	else
645 		reg &= ~S32G_WAKEUP_BITS;
646 
647 	writel(reg, usbmisc->base);
648 	spin_unlock_irqrestore(&usbmisc->lock, flags);
649 
650 	return 0;
651 }
652 
usbmisc_s32g_init(struct imx_usbmisc_data * data,u32 extra_flags)653 static int usbmisc_s32g_init(struct imx_usbmisc_data *data, u32 extra_flags)
654 {
655 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
656 	unsigned long flags;
657 	u32 reg;
658 
659 	spin_lock_irqsave(&usbmisc->lock, flags);
660 
661 	reg = readl(usbmisc->base);
662 
663 	reg |= S32G_PWRFLTEN;
664 	reg |= extra_flags;
665 
666 	writel(reg, usbmisc->base);
667 
668 	spin_unlock_irqrestore(&usbmisc->lock, flags);
669 	usbmisc_s32g_set_wakeup(data, false);
670 
671 	return 0;
672 }
673 
usbmisc_s32g2_init(struct imx_usbmisc_data * data)674 static int usbmisc_s32g2_init(struct imx_usbmisc_data *data)
675 {
676 	return usbmisc_s32g_init(data, S32G_UCMALLBE);
677 }
678 
usbmisc_s32g3_init(struct imx_usbmisc_data * data)679 static int usbmisc_s32g3_init(struct imx_usbmisc_data *data)
680 {
681 	return usbmisc_s32g_init(data, 0);
682 }
683 
usbmisc_imx7d_set_wakeup(struct imx_usbmisc_data * data,bool enabled)684 static int usbmisc_imx7d_set_wakeup
685 	(struct imx_usbmisc_data *data, bool enabled)
686 {
687 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
688 	unsigned long flags;
689 	u32 val;
690 
691 	spin_lock_irqsave(&usbmisc->lock, flags);
692 	val = readl(usbmisc->base);
693 	if (enabled) {
694 		val &= ~MX6_USB_OTG_WAKEUP_BITS;
695 		val |= usbmisc_wakeup_setting(data);
696 		writel(val, usbmisc->base);
697 	} else {
698 		if (val & MX6_BM_WAKEUP_INTR)
699 			dev_dbg(data->dev, "wakeup int\n");
700 		writel(val & ~MX6_USB_OTG_WAKEUP_BITS, usbmisc->base);
701 	}
702 	spin_unlock_irqrestore(&usbmisc->lock, flags);
703 
704 	return 0;
705 }
706 
usbmisc_imx7d_init(struct imx_usbmisc_data * data)707 static int usbmisc_imx7d_init(struct imx_usbmisc_data *data)
708 {
709 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
710 	unsigned long flags;
711 	u32 reg;
712 
713 	if (data->index >= 1)
714 		return -EINVAL;
715 
716 	spin_lock_irqsave(&usbmisc->lock, flags);
717 	reg = readl(usbmisc->base);
718 	if (data->disable_oc) {
719 		reg |= MX6_BM_OVER_CUR_DIS;
720 	} else {
721 		reg &= ~MX6_BM_OVER_CUR_DIS;
722 
723 		/*
724 		 * If the polarity is not configured keep it as setup by the
725 		 * bootloader.
726 		 */
727 		if (data->oc_pol_configured && data->oc_pol_active_low)
728 			reg |= MX6_BM_OVER_CUR_POLARITY;
729 		else if (data->oc_pol_configured)
730 			reg &= ~MX6_BM_OVER_CUR_POLARITY;
731 	}
732 	/* If the polarity is not set keep it as setup by the bootloader */
733 	if (data->pwr_pol == 1)
734 		reg |= MX6_BM_PWR_POLARITY;
735 	writel(reg, usbmisc->base);
736 
737 	/* SoC non-burst setting */
738 	reg = readl(usbmisc->base);
739 	writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base);
740 
741 	if (!data->hsic) {
742 		reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
743 		reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK;
744 		writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID
745 			| MX7D_USBNC_AUTO_RESUME,
746 			usbmisc->base + MX7D_USBNC_USB_CTRL2);
747 		/* PHY tuning for signal quality */
748 		reg = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG1);
749 		if (data->emp_curr_control >= 0 &&
750 			data->emp_curr_control <=
751 			(TXPREEMPAMPTUNE0_MASK >> TXPREEMPAMPTUNE0_BIT)) {
752 			reg &= ~TXPREEMPAMPTUNE0_MASK;
753 			reg |= (data->emp_curr_control << TXPREEMPAMPTUNE0_BIT);
754 		}
755 
756 		if (data->dc_vol_level_adjust >= 0 &&
757 			data->dc_vol_level_adjust <=
758 			(TXVREFTUNE0_MASK >> TXVREFTUNE0_BIT)) {
759 			reg &= ~TXVREFTUNE0_MASK;
760 			reg |= (data->dc_vol_level_adjust << TXVREFTUNE0_BIT);
761 		}
762 
763 		if (data->rise_fall_time_adjust >= 0 &&
764 			data->rise_fall_time_adjust <=
765 			(TXRISETUNE0_MASK >> TXRISETUNE0_BIT)) {
766 			reg &= ~TXRISETUNE0_MASK;
767 			reg |= (data->rise_fall_time_adjust << TXRISETUNE0_BIT);
768 		}
769 
770 		writel(reg, usbmisc->base + MX7D_USB_OTG_PHY_CFG1);
771 	}
772 
773 	spin_unlock_irqrestore(&usbmisc->lock, flags);
774 
775 	usbmisc_imx7d_set_wakeup(data, false);
776 
777 	return 0;
778 }
779 
imx7d_charger_secondary_detection(struct imx_usbmisc_data * data)780 static int imx7d_charger_secondary_detection(struct imx_usbmisc_data *data)
781 {
782 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
783 	struct usb_phy *usb_phy = data->usb_phy;
784 	int val;
785 	unsigned long flags;
786 
787 	/* Clear VDATSRCENB0 to disable VDP_SRC and IDM_SNK required by BC 1.2 spec */
788 	spin_lock_irqsave(&usbmisc->lock, flags);
789 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
790 	val &= ~MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0;
791 	writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
792 	spin_unlock_irqrestore(&usbmisc->lock, flags);
793 
794 	/* TVDMSRC_DIS */
795 	msleep(20);
796 
797 	/* VDM_SRC is connected to D- and IDP_SINK is connected to D+ */
798 	spin_lock_irqsave(&usbmisc->lock, flags);
799 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
800 	writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 |
801 			MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 |
802 			MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL,
803 				usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
804 	spin_unlock_irqrestore(&usbmisc->lock, flags);
805 
806 	/* TVDMSRC_ON */
807 	msleep(40);
808 
809 	/*
810 	 * Per BC 1.2, check voltage of D+:
811 	 * DCP: if greater than VDAT_REF;
812 	 * CDP: if less than VDAT_REF.
813 	 */
814 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
815 	if (val & MX7D_USB_OTG_PHY_STATUS_CHRGDET) {
816 		dev_dbg(data->dev, "It is a dedicate charging port\n");
817 		usb_phy->chg_type = DCP_TYPE;
818 	} else {
819 		dev_dbg(data->dev, "It is a charging downstream port\n");
820 		usb_phy->chg_type = CDP_TYPE;
821 	}
822 
823 	return 0;
824 }
825 
imx7_disable_charger_detector(struct imx_usbmisc_data * data)826 static void imx7_disable_charger_detector(struct imx_usbmisc_data *data)
827 {
828 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
829 	unsigned long flags;
830 	u32 val;
831 
832 	spin_lock_irqsave(&usbmisc->lock, flags);
833 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
834 	val &= ~(MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB |
835 			MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 |
836 			MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 |
837 			MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL);
838 	writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
839 
840 	/* Set OPMODE to be 2'b00 and disable its override */
841 	val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
842 	val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK;
843 	writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
844 
845 	val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
846 	writel(val & ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN,
847 			usbmisc->base + MX7D_USBNC_USB_CTRL2);
848 	spin_unlock_irqrestore(&usbmisc->lock, flags);
849 }
850 
imx7d_charger_data_contact_detect(struct imx_usbmisc_data * data)851 static int imx7d_charger_data_contact_detect(struct imx_usbmisc_data *data)
852 {
853 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
854 	unsigned long flags;
855 	u32 val;
856 	int i, data_pin_contact_count = 0;
857 
858 	/* Enable Data Contact Detect (DCD) per the USB BC 1.2 */
859 	spin_lock_irqsave(&usbmisc->lock, flags);
860 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
861 	writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB,
862 			usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
863 	spin_unlock_irqrestore(&usbmisc->lock, flags);
864 
865 	for (i = 0; i < 100; i = i + 1) {
866 		val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
867 		if (!(val & MX7D_USB_OTG_PHY_STATUS_LINE_STATE0)) {
868 			if (data_pin_contact_count++ > 5)
869 				/* Data pin makes contact */
870 				break;
871 			usleep_range(5000, 10000);
872 		} else {
873 			data_pin_contact_count = 0;
874 			usleep_range(5000, 6000);
875 		}
876 	}
877 
878 	/* Disable DCD after finished data contact check */
879 	spin_lock_irqsave(&usbmisc->lock, flags);
880 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
881 	writel(val & ~MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB,
882 			usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
883 	spin_unlock_irqrestore(&usbmisc->lock, flags);
884 
885 	if (i == 100) {
886 		dev_err(data->dev,
887 			"VBUS is coming from a dedicated power supply.\n");
888 		return -ENXIO;
889 	}
890 
891 	return 0;
892 }
893 
imx7d_charger_primary_detection(struct imx_usbmisc_data * data)894 static int imx7d_charger_primary_detection(struct imx_usbmisc_data *data)
895 {
896 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
897 	struct usb_phy *usb_phy = data->usb_phy;
898 	unsigned long flags;
899 	u32 val;
900 
901 	/* VDP_SRC is connected to D+ and IDM_SINK is connected to D- */
902 	spin_lock_irqsave(&usbmisc->lock, flags);
903 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
904 	val &= ~MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL;
905 	writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 |
906 			MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0,
907 				usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
908 	spin_unlock_irqrestore(&usbmisc->lock, flags);
909 
910 	/* TVDPSRC_ON */
911 	msleep(40);
912 
913 	/* Check if D- is less than VDAT_REF to determine an SDP per BC 1.2 */
914 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
915 	if (!(val & MX7D_USB_OTG_PHY_STATUS_CHRGDET)) {
916 		dev_dbg(data->dev, "It is a standard downstream port\n");
917 		usb_phy->chg_type = SDP_TYPE;
918 	}
919 
920 	return 0;
921 }
922 
923 /*
924  * Whole charger detection process:
925  * 1. OPMODE override to be non-driving
926  * 2. Data contact check
927  * 3. Primary detection
928  * 4. Secondary detection
929  * 5. Disable charger detection
930  */
imx7d_charger_detection(struct imx_usbmisc_data * data)931 static int imx7d_charger_detection(struct imx_usbmisc_data *data)
932 {
933 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
934 	struct usb_phy *usb_phy = data->usb_phy;
935 	unsigned long flags;
936 	u32 val;
937 	int ret;
938 
939 	/* Check if vbus is valid */
940 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
941 	if (!(val & MX7D_USB_OTG_PHY_STATUS_VBUS_VLD)) {
942 		dev_err(data->dev, "vbus is error\n");
943 		return -EINVAL;
944 	}
945 
946 	/*
947 	 * Keep OPMODE to be non-driving mode during the whole
948 	 * charger detection process.
949 	 */
950 	spin_lock_irqsave(&usbmisc->lock, flags);
951 	val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
952 	val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK;
953 	val |= MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING;
954 	writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
955 
956 	val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
957 	writel(val | MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN,
958 			usbmisc->base + MX7D_USBNC_USB_CTRL2);
959 	spin_unlock_irqrestore(&usbmisc->lock, flags);
960 
961 	ret = imx7d_charger_data_contact_detect(data);
962 	if (ret)
963 		return ret;
964 
965 	ret = imx7d_charger_primary_detection(data);
966 	if (!ret && usb_phy->chg_type != SDP_TYPE)
967 		ret = imx7d_charger_secondary_detection(data);
968 
969 	imx7_disable_charger_detector(data);
970 
971 	return ret;
972 }
973 
usbmisc_imx7d_vbus_comparator_on(struct imx_usbmisc_data * data,bool on)974 static void usbmisc_imx7d_vbus_comparator_on(struct imx_usbmisc_data *data,
975 					     bool on)
976 {
977 	unsigned long flags;
978 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
979 	u32 val;
980 
981 	if (data->hsic)
982 		return;
983 
984 	spin_lock_irqsave(&usbmisc->lock, flags);
985 	/*
986 	 * Disable VBUS valid comparator when in suspend mode,
987 	 * when OTG is disabled and DRVVBUS0 is asserted case
988 	 * the Bandgap circuitry and VBUS Valid comparator are
989 	 * still powered, even in Suspend or Sleep mode.
990 	 */
991 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
992 	if (on)
993 		val |= MX7D_USB_OTG_PHY_CFG2_DRVVBUS0;
994 	else
995 		val &= ~MX7D_USB_OTG_PHY_CFG2_DRVVBUS0;
996 
997 	writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
998 	spin_unlock_irqrestore(&usbmisc->lock, flags);
999 }
1000 
usbmisc_imx7ulp_init(struct imx_usbmisc_data * data)1001 static int usbmisc_imx7ulp_init(struct imx_usbmisc_data *data)
1002 {
1003 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
1004 	unsigned long flags;
1005 	u32 reg;
1006 
1007 	if (data->index >= 1)
1008 		return -EINVAL;
1009 
1010 	spin_lock_irqsave(&usbmisc->lock, flags);
1011 	reg = readl(usbmisc->base);
1012 	if (data->disable_oc) {
1013 		reg |= MX6_BM_OVER_CUR_DIS;
1014 	} else {
1015 		reg &= ~MX6_BM_OVER_CUR_DIS;
1016 
1017 		/*
1018 		 * If the polarity is not configured keep it as setup by the
1019 		 * bootloader.
1020 		 */
1021 		if (data->oc_pol_configured && data->oc_pol_active_low)
1022 			reg |= MX6_BM_OVER_CUR_POLARITY;
1023 		else if (data->oc_pol_configured)
1024 			reg &= ~MX6_BM_OVER_CUR_POLARITY;
1025 	}
1026 	/* If the polarity is not set keep it as setup by the bootloader */
1027 	if (data->pwr_pol == 1)
1028 		reg |= MX6_BM_PWR_POLARITY;
1029 
1030 	writel(reg, usbmisc->base);
1031 
1032 	/* SoC non-burst setting */
1033 	reg = readl(usbmisc->base);
1034 	writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base);
1035 
1036 	if (data->hsic) {
1037 		reg = readl(usbmisc->base);
1038 		writel(reg | MX6_BM_UTMI_ON_CLOCK, usbmisc->base);
1039 
1040 		reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET);
1041 		reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON;
1042 		writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET);
1043 
1044 		/*
1045 		 * For non-HSIC controller, the autoresume is enabled
1046 		 * at MXS PHY driver (usbphy_ctrl bit18).
1047 		 */
1048 		reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
1049 		writel(reg | MX7D_USBNC_AUTO_RESUME,
1050 			usbmisc->base + MX7D_USBNC_USB_CTRL2);
1051 	} else {
1052 		reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
1053 		reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK;
1054 		writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID,
1055 			 usbmisc->base + MX7D_USBNC_USB_CTRL2);
1056 	}
1057 
1058 	spin_unlock_irqrestore(&usbmisc->lock, flags);
1059 
1060 	usbmisc_imx7d_set_wakeup(data, false);
1061 
1062 	return 0;
1063 }
1064 
usbmisc_imx7d_pullup(struct imx_usbmisc_data * data,bool on)1065 static void usbmisc_imx7d_pullup(struct imx_usbmisc_data *data, bool on)
1066 {
1067 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
1068 	unsigned long flags;
1069 	u32 val;
1070 
1071 	if (on)
1072 		return;
1073 
1074 	spin_lock_irqsave(&usbmisc->lock, flags);
1075 	val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
1076 	val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK;
1077 	val |= MX7D_USBNC_USB_CTRL2_OPMODE(1);
1078 	val |= MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN;
1079 	writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
1080 	spin_unlock_irqrestore(&usbmisc->lock, flags);
1081 
1082 	/* Last for at least 1 micro-frame to let host see disconnect signal */
1083 	usleep_range(125, 150);
1084 
1085 	spin_lock_irqsave(&usbmisc->lock, flags);
1086 	val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK;
1087 	val |= MX7D_USBNC_USB_CTRL2_OPMODE(0);
1088 	val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN;
1089 	writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
1090 	spin_unlock_irqrestore(&usbmisc->lock, flags);
1091 }
1092 
usbmisc_imx7d_power_lost_check(struct imx_usbmisc_data * data)1093 static int usbmisc_imx7d_power_lost_check(struct imx_usbmisc_data *data)
1094 {
1095 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
1096 	unsigned long flags;
1097 	u32 val;
1098 
1099 	spin_lock_irqsave(&usbmisc->lock, flags);
1100 	val = readl(usbmisc->base);
1101 	spin_unlock_irqrestore(&usbmisc->lock, flags);
1102 	/*
1103 	 * Here use a power on reset value to judge
1104 	 * if the controller experienced a power lost
1105 	 */
1106 	if (val == 0x30001000)
1107 		return 1;
1108 	else
1109 		return 0;
1110 }
1111 
usbmisc_imx6sx_power_lost_check(struct imx_usbmisc_data * data)1112 static int usbmisc_imx6sx_power_lost_check(struct imx_usbmisc_data *data)
1113 {
1114 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
1115 	unsigned long flags;
1116 	u32 val;
1117 
1118 	spin_lock_irqsave(&usbmisc->lock, flags);
1119 	val = readl(usbmisc->base + data->index * 4);
1120 	spin_unlock_irqrestore(&usbmisc->lock, flags);
1121 	/*
1122 	 * Here use a power on reset value to judge
1123 	 * if the controller experienced a power lost
1124 	 */
1125 	if (val == 0x30001000)
1126 		return 1;
1127 	else
1128 		return 0;
1129 }
1130 
usbmisc_s32g_power_lost_check(struct imx_usbmisc_data * data)1131 static int usbmisc_s32g_power_lost_check(struct imx_usbmisc_data *data)
1132 {
1133 	return 1;
1134 }
1135 
usbmisc_blkctl_wakeup_setting(struct imx_usbmisc_data * data)1136 static u32 usbmisc_blkctl_wakeup_setting(struct imx_usbmisc_data *data)
1137 {
1138 	u32 wakeup_setting = BLKCTL_WAKEUP_SOURCE;
1139 
1140 	if (data->ext_id || data->available_role != USB_DR_MODE_OTG)
1141 		wakeup_setting &= ~BLKCTL_OTG_ID_WAKEUP_EN;
1142 
1143 	if (data->ext_vbus || data->available_role == USB_DR_MODE_HOST)
1144 		wakeup_setting &= ~BLKCTL_OTG_VBUS_WAKEUP_EN;
1145 
1146 	/* Select session valid as VBUS wakeup source */
1147 	wakeup_setting |= BLKCTL_OTG_VBUS_SESSVALID;
1148 
1149 	return wakeup_setting;
1150 }
1151 
usbmisc_imx95_set_wakeup(struct imx_usbmisc_data * data,bool enabled)1152 static int usbmisc_imx95_set_wakeup(struct imx_usbmisc_data *data, bool enabled)
1153 {
1154 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
1155 	unsigned long flags;
1156 	u32 val;
1157 
1158 	if (!usbmisc->blkctl)
1159 		return 0;
1160 
1161 	spin_lock_irqsave(&usbmisc->lock, flags);
1162 	val = readl(usbmisc->blkctl + BLKCTL_USB_WAKEUP_CTRL);
1163 	val &= ~BLKCTL_WAKEUP_SOURCE;
1164 
1165 	if (enabled)
1166 		val |= usbmisc_blkctl_wakeup_setting(data);
1167 
1168 	writel(val, usbmisc->blkctl + BLKCTL_USB_WAKEUP_CTRL);
1169 	spin_unlock_irqrestore(&usbmisc->lock, flags);
1170 
1171 	return 0;
1172 }
1173 
1174 static const struct usbmisc_ops imx25_usbmisc_ops = {
1175 	.init = usbmisc_imx25_init,
1176 	.post = usbmisc_imx25_post,
1177 };
1178 
1179 static const struct usbmisc_ops imx27_usbmisc_ops = {
1180 	.init = usbmisc_imx27_init,
1181 };
1182 
1183 static const struct usbmisc_ops imx51_usbmisc_ops = {
1184 	.init = usbmisc_imx53_init,
1185 };
1186 
1187 static const struct usbmisc_ops imx53_usbmisc_ops = {
1188 	.init = usbmisc_imx53_init,
1189 };
1190 
1191 static const struct usbmisc_ops imx6q_usbmisc_ops = {
1192 	.set_wakeup = usbmisc_imx6q_set_wakeup,
1193 	.init = usbmisc_imx6q_init,
1194 	.hsic_set_connect = usbmisc_imx6_hsic_set_connect,
1195 	.hsic_set_clk   = usbmisc_imx6_hsic_set_clk,
1196 };
1197 
1198 static const struct usbmisc_ops vf610_usbmisc_ops = {
1199 	.init = usbmisc_vf610_init,
1200 };
1201 
1202 static const struct usbmisc_ops imx6sx_usbmisc_ops = {
1203 	.set_wakeup = usbmisc_imx6q_set_wakeup,
1204 	.init = usbmisc_imx6sx_init,
1205 	.hsic_set_connect = usbmisc_imx6_hsic_set_connect,
1206 	.hsic_set_clk = usbmisc_imx6_hsic_set_clk,
1207 	.power_lost_check = usbmisc_imx6sx_power_lost_check,
1208 };
1209 
1210 static const struct usbmisc_ops imx7d_usbmisc_ops = {
1211 	.init = usbmisc_imx7d_init,
1212 	.set_wakeup = usbmisc_imx7d_set_wakeup,
1213 	.charger_detection = imx7d_charger_detection,
1214 	.power_lost_check = usbmisc_imx7d_power_lost_check,
1215 	.pullup = usbmisc_imx7d_pullup,
1216 	.vbus_comparator_on = usbmisc_imx7d_vbus_comparator_on,
1217 };
1218 
1219 static const struct usbmisc_ops imx7ulp_usbmisc_ops = {
1220 	.init = usbmisc_imx7ulp_init,
1221 	.set_wakeup = usbmisc_imx7d_set_wakeup,
1222 	.hsic_set_connect = usbmisc_imx6_hsic_set_connect,
1223 	.hsic_set_clk = usbmisc_imx6_hsic_set_clk,
1224 	.power_lost_check = usbmisc_imx7d_power_lost_check,
1225 };
1226 
1227 static const struct usbmisc_ops imx95_usbmisc_ops = {
1228 	.init = usbmisc_imx7d_init,
1229 	.set_wakeup = usbmisc_imx95_set_wakeup,
1230 	.charger_detection = imx7d_charger_detection,
1231 	.power_lost_check = usbmisc_imx7d_power_lost_check,
1232 	.pullup = usbmisc_imx7d_pullup,
1233 	.vbus_comparator_on = usbmisc_imx7d_vbus_comparator_on,
1234 };
1235 
1236 static const struct usbmisc_ops s32g2_usbmisc_ops = {
1237 	.init = usbmisc_s32g2_init,
1238 	.set_wakeup = usbmisc_s32g_set_wakeup,
1239 	.power_lost_check = usbmisc_s32g_power_lost_check,
1240 };
1241 
1242 static const struct usbmisc_ops s32g3_usbmisc_ops = {
1243 	.init = usbmisc_s32g3_init,
1244 	.set_wakeup = usbmisc_s32g_set_wakeup,
1245 	.power_lost_check = usbmisc_s32g_power_lost_check,
1246 };
1247 
is_imx53_usbmisc(struct imx_usbmisc_data * data)1248 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data)
1249 {
1250 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
1251 
1252 	return usbmisc->ops == &imx53_usbmisc_ops;
1253 }
1254 
imx_usbmisc_init(struct imx_usbmisc_data * data)1255 int imx_usbmisc_init(struct imx_usbmisc_data *data)
1256 {
1257 	struct imx_usbmisc *usbmisc;
1258 
1259 	if (!data)
1260 		return 0;
1261 
1262 	usbmisc = dev_get_drvdata(data->dev);
1263 	if (!usbmisc->ops->init)
1264 		return 0;
1265 	return usbmisc->ops->init(data);
1266 }
1267 EXPORT_SYMBOL_GPL(imx_usbmisc_init);
1268 
imx_usbmisc_init_post(struct imx_usbmisc_data * data)1269 int imx_usbmisc_init_post(struct imx_usbmisc_data *data)
1270 {
1271 	struct imx_usbmisc *usbmisc;
1272 	int ret = 0;
1273 
1274 	if (!data)
1275 		return 0;
1276 
1277 	usbmisc = dev_get_drvdata(data->dev);
1278 	if (usbmisc->ops->post)
1279 		ret = usbmisc->ops->post(data);
1280 	if (ret) {
1281 		dev_err(data->dev, "post init failed, ret=%d\n", ret);
1282 		return ret;
1283 	}
1284 
1285 	if (usbmisc->ops->set_wakeup)
1286 		ret = usbmisc->ops->set_wakeup(data, false);
1287 	if (ret) {
1288 		dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret);
1289 		return ret;
1290 	}
1291 
1292 	return 0;
1293 }
1294 EXPORT_SYMBOL_GPL(imx_usbmisc_init_post);
1295 
imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data * data)1296 int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data)
1297 {
1298 	struct imx_usbmisc *usbmisc;
1299 
1300 	if (!data)
1301 		return 0;
1302 
1303 	usbmisc = dev_get_drvdata(data->dev);
1304 	if (!usbmisc->ops->hsic_set_connect || !data->hsic)
1305 		return 0;
1306 	return usbmisc->ops->hsic_set_connect(data);
1307 }
1308 EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_connect);
1309 
imx_usbmisc_charger_detection(struct imx_usbmisc_data * data,bool connect)1310 int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect)
1311 {
1312 	struct imx_usbmisc *usbmisc;
1313 	struct usb_phy *usb_phy;
1314 	int ret = 0;
1315 
1316 	if (!data)
1317 		return -EINVAL;
1318 
1319 	usbmisc = dev_get_drvdata(data->dev);
1320 	usb_phy = data->usb_phy;
1321 	if (!usbmisc->ops->charger_detection)
1322 		return -ENOTSUPP;
1323 
1324 	if (connect) {
1325 		ret = usbmisc->ops->charger_detection(data);
1326 		if (ret) {
1327 			dev_err(data->dev,
1328 					"Error occurs during detection: %d\n",
1329 					ret);
1330 			usb_phy->chg_state = USB_CHARGER_ABSENT;
1331 		} else {
1332 			usb_phy->chg_state = USB_CHARGER_PRESENT;
1333 		}
1334 	} else {
1335 		usb_phy->chg_state = USB_CHARGER_ABSENT;
1336 		usb_phy->chg_type = UNKNOWN_TYPE;
1337 	}
1338 	return ret;
1339 }
1340 EXPORT_SYMBOL_GPL(imx_usbmisc_charger_detection);
1341 
imx_usbmisc_pullup(struct imx_usbmisc_data * data,bool on)1342 int imx_usbmisc_pullup(struct imx_usbmisc_data *data, bool on)
1343 {
1344 	struct imx_usbmisc *usbmisc;
1345 
1346 	if (!data)
1347 		return 0;
1348 
1349 	usbmisc = dev_get_drvdata(data->dev);
1350 	if (usbmisc->ops->pullup)
1351 		usbmisc->ops->pullup(data, on);
1352 
1353 	return 0;
1354 }
1355 EXPORT_SYMBOL_GPL(imx_usbmisc_pullup);
1356 
imx_usbmisc_suspend(struct imx_usbmisc_data * data,bool wakeup)1357 int imx_usbmisc_suspend(struct imx_usbmisc_data *data, bool wakeup)
1358 {
1359 	struct imx_usbmisc *usbmisc;
1360 	int ret = 0;
1361 
1362 	if (!data)
1363 		return 0;
1364 
1365 	usbmisc = dev_get_drvdata(data->dev);
1366 
1367 	if (usbmisc->ops->vbus_comparator_on)
1368 		usbmisc->ops->vbus_comparator_on(data, false);
1369 
1370 	if (wakeup && usbmisc->ops->set_wakeup)
1371 		ret = usbmisc->ops->set_wakeup(data, true);
1372 	if (ret) {
1373 		dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret);
1374 		return ret;
1375 	}
1376 
1377 	if (usbmisc->ops->hsic_set_clk && data->hsic)
1378 		ret = usbmisc->ops->hsic_set_clk(data, false);
1379 	if (ret) {
1380 		dev_err(data->dev, "hsic_set_clk failed, ret=%d\n", ret);
1381 		return ret;
1382 	}
1383 
1384 	return ret;
1385 }
1386 EXPORT_SYMBOL_GPL(imx_usbmisc_suspend);
1387 
imx_usbmisc_resume(struct imx_usbmisc_data * data,bool wakeup)1388 int imx_usbmisc_resume(struct imx_usbmisc_data *data, bool wakeup)
1389 {
1390 	struct imx_usbmisc *usbmisc;
1391 	int ret = 0;
1392 
1393 	if (!data)
1394 		return 0;
1395 
1396 	usbmisc = dev_get_drvdata(data->dev);
1397 
1398 	if (usbmisc->ops->power_lost_check)
1399 		ret = usbmisc->ops->power_lost_check(data);
1400 	if (ret > 0) {
1401 		/* re-init if resume from power lost */
1402 		ret = imx_usbmisc_init(data);
1403 		if (ret) {
1404 			dev_err(data->dev, "re-init failed, ret=%d\n", ret);
1405 			return ret;
1406 		}
1407 	}
1408 
1409 	if (wakeup && usbmisc->ops->set_wakeup)
1410 		ret = usbmisc->ops->set_wakeup(data, false);
1411 	if (ret) {
1412 		dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret);
1413 		return ret;
1414 	}
1415 
1416 	if (usbmisc->ops->hsic_set_clk && data->hsic)
1417 		ret = usbmisc->ops->hsic_set_clk(data, true);
1418 	if (ret) {
1419 		dev_err(data->dev, "hsic_set_clk failed, ret=%d\n", ret);
1420 		goto hsic_set_clk_fail;
1421 	}
1422 
1423 	if (usbmisc->ops->vbus_comparator_on)
1424 		usbmisc->ops->vbus_comparator_on(data, true);
1425 
1426 	return 0;
1427 
1428 hsic_set_clk_fail:
1429 	if (wakeup && usbmisc->ops->set_wakeup)
1430 		usbmisc->ops->set_wakeup(data, true);
1431 	return ret;
1432 }
1433 EXPORT_SYMBOL_GPL(imx_usbmisc_resume);
1434 
1435 static const struct of_device_id usbmisc_imx_dt_ids[] = {
1436 	{
1437 		.compatible = "fsl,imx25-usbmisc",
1438 		.data = &imx25_usbmisc_ops,
1439 	},
1440 	{
1441 		.compatible = "fsl,imx35-usbmisc",
1442 		.data = &imx25_usbmisc_ops,
1443 	},
1444 	{
1445 		.compatible = "fsl,imx27-usbmisc",
1446 		.data = &imx27_usbmisc_ops,
1447 	},
1448 	{
1449 		.compatible = "fsl,imx51-usbmisc",
1450 		.data = &imx51_usbmisc_ops,
1451 	},
1452 	{
1453 		.compatible = "fsl,imx53-usbmisc",
1454 		.data = &imx53_usbmisc_ops,
1455 	},
1456 	{
1457 		.compatible = "fsl,imx6q-usbmisc",
1458 		.data = &imx6q_usbmisc_ops,
1459 	},
1460 	{
1461 		.compatible = "fsl,vf610-usbmisc",
1462 		.data = &vf610_usbmisc_ops,
1463 	},
1464 	{
1465 		.compatible = "fsl,imx6sx-usbmisc",
1466 		.data = &imx6sx_usbmisc_ops,
1467 	},
1468 	{
1469 		.compatible = "fsl,imx6ul-usbmisc",
1470 		.data = &imx6sx_usbmisc_ops,
1471 	},
1472 	{
1473 		.compatible = "fsl,imx7d-usbmisc",
1474 		.data = &imx7d_usbmisc_ops,
1475 	},
1476 	{
1477 		.compatible = "fsl,imx7ulp-usbmisc",
1478 		.data = &imx7ulp_usbmisc_ops,
1479 	},
1480 	{
1481 		.compatible = "fsl,imx8ulp-usbmisc",
1482 		.data = &imx7ulp_usbmisc_ops,
1483 	},
1484 	{
1485 		.compatible = "fsl,imx95-usbmisc",
1486 		.data = &imx95_usbmisc_ops,
1487 	},
1488 	{
1489 		.compatible = "nxp,s32g2-usbmisc",
1490 		.data = &s32g2_usbmisc_ops,
1491 	},
1492 	{
1493 		.compatible = "nxp,s32g3-usbmisc",
1494 		.data = &s32g3_usbmisc_ops,
1495 	},
1496 	{ /* sentinel */ }
1497 };
1498 MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);
1499 
usbmisc_imx_probe(struct platform_device * pdev)1500 static int usbmisc_imx_probe(struct platform_device *pdev)
1501 {
1502 	struct imx_usbmisc *data;
1503 	struct resource *res;
1504 
1505 	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
1506 	if (!data)
1507 		return -ENOMEM;
1508 
1509 	spin_lock_init(&data->lock);
1510 
1511 	data->base = devm_platform_ioremap_resource(pdev, 0);
1512 	if (IS_ERR(data->base))
1513 		return PTR_ERR(data->base);
1514 
1515 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1516 	if (res) {
1517 		data->blkctl = devm_ioremap_resource(&pdev->dev, res);
1518 		if (IS_ERR(data->blkctl))
1519 			return PTR_ERR(data->blkctl);
1520 	} else if (device_is_compatible(&pdev->dev, "fsl,imx95-usbmisc")) {
1521 		dev_warn(&pdev->dev, "wakeup setting is missing\n");
1522 	}
1523 
1524 	data->ops = of_device_get_match_data(&pdev->dev);
1525 	platform_set_drvdata(pdev, data);
1526 
1527 	return 0;
1528 }
1529 
1530 static struct platform_driver usbmisc_imx_driver = {
1531 	.probe = usbmisc_imx_probe,
1532 	.driver = {
1533 		.name = "usbmisc_imx",
1534 		.of_match_table = usbmisc_imx_dt_ids,
1535 	 },
1536 };
1537 
1538 module_platform_driver(usbmisc_imx_driver);
1539 
1540 MODULE_ALIAS("platform:usbmisc-imx");
1541 MODULE_LICENSE("GPL");
1542 MODULE_DESCRIPTION("driver for imx usb non-core registers");
1543 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");
1544