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