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