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