Lines Matching +full:reg +full:- +full:data

1 // SPDX-License-Identifier: GPL-2.0+
86 /* For imx6dql, it is host-only controller, for later imx6, it is otg's */
104 /* The default DM/DP value is pull-down */
142 int (*init)(struct imx_usbmisc_data *data);
144 int (*post)(struct imx_usbmisc_data *data);
146 int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled);
148 int (*hsic_set_connect)(struct imx_usbmisc_data *data);
150 int (*hsic_set_clk)(struct imx_usbmisc_data *data, bool enabled);
152 int (*charger_detection)(struct imx_usbmisc_data *data);
161 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data);
163 static int usbmisc_imx25_init(struct imx_usbmisc_data *data) in usbmisc_imx25_init() argument
165 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_imx25_init()
169 if (data->index > 1) in usbmisc_imx25_init()
170 return -EINVAL; in usbmisc_imx25_init()
172 spin_lock_irqsave(&usbmisc->lock, flags); in usbmisc_imx25_init()
173 switch (data->index) { in usbmisc_imx25_init()
175 val = readl(usbmisc->base); in usbmisc_imx25_init()
184 if (data->oc_pol_configured && data->oc_pol_active_low) in usbmisc_imx25_init()
187 writel(val, usbmisc->base); in usbmisc_imx25_init()
190 val = readl(usbmisc->base); in usbmisc_imx25_init()
200 if (data->oc_pol_configured && data->oc_pol_active_low) in usbmisc_imx25_init()
203 writel(val, usbmisc->base); in usbmisc_imx25_init()
207 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx25_init()
212 static int usbmisc_imx25_post(struct imx_usbmisc_data *data) in usbmisc_imx25_post() argument
214 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_imx25_post()
215 void __iomem *reg; in usbmisc_imx25_post() local
219 if (data->index > 2) in usbmisc_imx25_post()
220 return -EINVAL; in usbmisc_imx25_post()
222 if (data->index) in usbmisc_imx25_post()
225 spin_lock_irqsave(&usbmisc->lock, flags); in usbmisc_imx25_post()
226 reg = usbmisc->base + MX25_USB_PHY_CTRL_OFFSET; in usbmisc_imx25_post()
227 val = readl(reg); in usbmisc_imx25_post()
229 if (data->evdo) in usbmisc_imx25_post()
234 writel(val, reg); in usbmisc_imx25_post()
235 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx25_post()
241 static int usbmisc_imx27_init(struct imx_usbmisc_data *data) in usbmisc_imx27_init() argument
243 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_imx27_init()
247 switch (data->index) { in usbmisc_imx27_init()
258 return -EINVAL; in usbmisc_imx27_init()
261 spin_lock_irqsave(&usbmisc->lock, flags); in usbmisc_imx27_init()
262 if (data->disable_oc) in usbmisc_imx27_init()
263 val = readl(usbmisc->base) | val; in usbmisc_imx27_init()
265 val = readl(usbmisc->base) & ~val; in usbmisc_imx27_init()
266 writel(val, usbmisc->base); in usbmisc_imx27_init()
267 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx27_init()
272 static int usbmisc_imx53_init(struct imx_usbmisc_data *data) in usbmisc_imx53_init() argument
274 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_imx53_init()
275 void __iomem *reg = NULL; in usbmisc_imx53_init() local
279 if (data->index > 3) in usbmisc_imx53_init()
280 return -EINVAL; in usbmisc_imx53_init()
283 val = readl(usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); in usbmisc_imx53_init()
286 writel(val, usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); in usbmisc_imx53_init()
288 spin_lock_irqsave(&usbmisc->lock, flags); in usbmisc_imx53_init()
290 switch (data->index) { in usbmisc_imx53_init()
292 if (data->disable_oc) { in usbmisc_imx53_init()
293 reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET; in usbmisc_imx53_init()
294 val = readl(reg) | MX53_BM_OVER_CUR_DIS_OTG; in usbmisc_imx53_init()
295 writel(val, reg); in usbmisc_imx53_init()
299 if (data->disable_oc) { in usbmisc_imx53_init()
300 reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET; in usbmisc_imx53_init()
301 val = readl(reg) | MX53_BM_OVER_CUR_DIS_H1; in usbmisc_imx53_init()
302 writel(val, reg); in usbmisc_imx53_init()
306 if (data->ulpi) { in usbmisc_imx53_init()
307 /* set USBH2 into ULPI-mode. */ in usbmisc_imx53_init()
308 reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET; in usbmisc_imx53_init()
309 val = readl(reg) | MX53_USB_CTRL_1_UH2_ULPI_EN; in usbmisc_imx53_init()
313 writel(val, reg); in usbmisc_imx53_init()
315 reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; in usbmisc_imx53_init()
316 val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN in usbmisc_imx53_init()
318 writel(val, reg); in usbmisc_imx53_init()
319 if (is_imx53_usbmisc(data)) { in usbmisc_imx53_init()
321 reg = usbmisc->base + in usbmisc_imx53_init()
323 val = readl(reg) | in usbmisc_imx53_init()
325 writel(val, reg); in usbmisc_imx53_init()
329 if (data->disable_oc) { in usbmisc_imx53_init()
330 reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; in usbmisc_imx53_init()
331 val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx; in usbmisc_imx53_init()
332 writel(val, reg); in usbmisc_imx53_init()
336 if (data->ulpi) { in usbmisc_imx53_init()
337 /* set USBH3 into ULPI-mode. */ in usbmisc_imx53_init()
338 reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET; in usbmisc_imx53_init()
339 val = readl(reg) | MX53_USB_CTRL_1_UH3_ULPI_EN; in usbmisc_imx53_init()
343 writel(val, reg); in usbmisc_imx53_init()
345 reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; in usbmisc_imx53_init()
346 val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN in usbmisc_imx53_init()
348 writel(val, reg); in usbmisc_imx53_init()
350 if (is_imx53_usbmisc(data)) { in usbmisc_imx53_init()
352 reg = usbmisc->base + in usbmisc_imx53_init()
354 val = readl(reg) | in usbmisc_imx53_init()
356 writel(val, reg); in usbmisc_imx53_init()
359 if (data->disable_oc) { in usbmisc_imx53_init()
360 reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; in usbmisc_imx53_init()
361 val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx; in usbmisc_imx53_init()
362 writel(val, reg); in usbmisc_imx53_init()
367 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx53_init()
372 static u32 usbmisc_wakeup_setting(struct imx_usbmisc_data *data) in usbmisc_wakeup_setting() argument
376 if (data->ext_id || data->available_role != USB_DR_MODE_OTG) in usbmisc_wakeup_setting()
379 if (data->ext_vbus || data->available_role == USB_DR_MODE_HOST) in usbmisc_wakeup_setting()
386 (struct imx_usbmisc_data *data, bool enabled) in usbmisc_imx6q_set_wakeup() argument
388 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_imx6q_set_wakeup()
393 if (data->index > 3) in usbmisc_imx6q_set_wakeup()
394 return -EINVAL; in usbmisc_imx6q_set_wakeup()
396 spin_lock_irqsave(&usbmisc->lock, flags); in usbmisc_imx6q_set_wakeup()
397 val = readl(usbmisc->base + data->index * 4); in usbmisc_imx6q_set_wakeup()
400 val |= usbmisc_wakeup_setting(data); in usbmisc_imx6q_set_wakeup()
403 pr_debug("wakeup int at ci_hdrc.%d\n", data->index); in usbmisc_imx6q_set_wakeup()
406 writel(val, usbmisc->base + data->index * 4); in usbmisc_imx6q_set_wakeup()
407 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx6q_set_wakeup()
412 static int usbmisc_imx6q_init(struct imx_usbmisc_data *data) in usbmisc_imx6q_init() argument
414 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_imx6q_init()
416 u32 reg; in usbmisc_imx6q_init() local
418 if (data->index > 3) in usbmisc_imx6q_init()
419 return -EINVAL; in usbmisc_imx6q_init()
421 spin_lock_irqsave(&usbmisc->lock, flags); in usbmisc_imx6q_init()
423 reg = readl(usbmisc->base + data->index * 4); in usbmisc_imx6q_init()
424 if (data->disable_oc) { in usbmisc_imx6q_init()
425 reg |= MX6_BM_OVER_CUR_DIS; in usbmisc_imx6q_init()
427 reg &= ~MX6_BM_OVER_CUR_DIS; in usbmisc_imx6q_init()
433 if (data->oc_pol_configured && data->oc_pol_active_low) in usbmisc_imx6q_init()
434 reg |= MX6_BM_OVER_CUR_POLARITY; in usbmisc_imx6q_init()
435 else if (data->oc_pol_configured) in usbmisc_imx6q_init()
436 reg &= ~MX6_BM_OVER_CUR_POLARITY; in usbmisc_imx6q_init()
439 if (data->pwr_pol == 1) in usbmisc_imx6q_init()
440 reg |= MX6_BM_PWR_POLARITY; in usbmisc_imx6q_init()
441 writel(reg, usbmisc->base + data->index * 4); in usbmisc_imx6q_init()
443 /* SoC non-burst setting */ in usbmisc_imx6q_init()
444 reg = readl(usbmisc->base + data->index * 4); in usbmisc_imx6q_init()
445 writel(reg | MX6_BM_NON_BURST_SETTING, in usbmisc_imx6q_init()
446 usbmisc->base + data->index * 4); in usbmisc_imx6q_init()
449 if (data->hsic) { in usbmisc_imx6q_init()
450 reg = readl(usbmisc->base + data->index * 4); in usbmisc_imx6q_init()
451 writel(reg | MX6_BM_UTMI_ON_CLOCK, in usbmisc_imx6q_init()
452 usbmisc->base + data->index * 4); in usbmisc_imx6q_init()
453 reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET in usbmisc_imx6q_init()
454 + (data->index - 2) * 4); in usbmisc_imx6q_init()
455 reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; in usbmisc_imx6q_init()
456 writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET in usbmisc_imx6q_init()
457 + (data->index - 2) * 4); in usbmisc_imx6q_init()
460 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx6q_init()
462 usbmisc_imx6q_set_wakeup(data, false); in usbmisc_imx6q_init()
467 static int usbmisc_imx6_hsic_get_reg_offset(struct imx_usbmisc_data *data) in usbmisc_imx6_hsic_get_reg_offset() argument
471 if (data->index == 2 || data->index == 3) { in usbmisc_imx6_hsic_get_reg_offset()
472 offset = (data->index - 2) * 4; in usbmisc_imx6_hsic_get_reg_offset()
473 } else if (data->index == 0) { in usbmisc_imx6_hsic_get_reg_offset()
476 * its own non-core register region. For SoCs before i.MX7D, in usbmisc_imx6_hsic_get_reg_offset()
477 * the first two USB controllers are non-HSIC controllers. in usbmisc_imx6_hsic_get_reg_offset()
481 dev_err(data->dev, "index is error for usbmisc\n"); in usbmisc_imx6_hsic_get_reg_offset()
482 ret = -EINVAL; in usbmisc_imx6_hsic_get_reg_offset()
488 static int usbmisc_imx6_hsic_set_connect(struct imx_usbmisc_data *data) in usbmisc_imx6_hsic_set_connect() argument
492 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_imx6_hsic_set_connect()
495 spin_lock_irqsave(&usbmisc->lock, flags); in usbmisc_imx6_hsic_set_connect()
496 offset = usbmisc_imx6_hsic_get_reg_offset(data); in usbmisc_imx6_hsic_set_connect()
498 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx6_hsic_set_connect()
502 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); in usbmisc_imx6_hsic_set_connect()
505 usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); in usbmisc_imx6_hsic_set_connect()
507 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx6_hsic_set_connect()
512 static int usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data *data, bool on) in usbmisc_imx6_hsic_set_clk() argument
516 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_imx6_hsic_set_clk()
519 spin_lock_irqsave(&usbmisc->lock, flags); in usbmisc_imx6_hsic_set_clk()
520 offset = usbmisc_imx6_hsic_get_reg_offset(data); in usbmisc_imx6_hsic_set_clk()
522 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx6_hsic_set_clk()
526 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); in usbmisc_imx6_hsic_set_clk()
533 writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); in usbmisc_imx6_hsic_set_clk()
534 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx6_hsic_set_clk()
540 static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data) in usbmisc_imx6sx_init() argument
542 void __iomem *reg = NULL; in usbmisc_imx6sx_init() local
544 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_imx6sx_init()
547 usbmisc_imx6q_init(data); in usbmisc_imx6sx_init()
549 if (data->index == 0 || data->index == 1) { in usbmisc_imx6sx_init()
550 reg = usbmisc->base + MX6_USB_OTG1_PHY_CTRL + data->index * 4; in usbmisc_imx6sx_init()
551 spin_lock_irqsave(&usbmisc->lock, flags); in usbmisc_imx6sx_init()
553 val = readl(reg); in usbmisc_imx6sx_init()
554 writel(val | MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID, reg); in usbmisc_imx6sx_init()
559 val = readl(usbmisc->base + data->index * 4); in usbmisc_imx6sx_init()
561 usbmisc->base + data->index * 4); in usbmisc_imx6sx_init()
562 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx6sx_init()
566 if (data->hsic) { in usbmisc_imx6sx_init()
567 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); in usbmisc_imx6sx_init()
569 writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); in usbmisc_imx6sx_init()
575 static int usbmisc_vf610_init(struct imx_usbmisc_data *data) in usbmisc_vf610_init() argument
577 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_vf610_init()
578 u32 reg; in usbmisc_vf610_init() local
584 if (data->index >= 1) in usbmisc_vf610_init()
585 return -EINVAL; in usbmisc_vf610_init()
587 if (data->disable_oc) { in usbmisc_vf610_init()
588 reg = readl(usbmisc->base); in usbmisc_vf610_init()
589 writel(reg | VF610_OVER_CUR_DIS, usbmisc->base); in usbmisc_vf610_init()
596 (struct imx_usbmisc_data *data, bool enabled) in usbmisc_imx7d_set_wakeup() argument
598 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_imx7d_set_wakeup()
602 spin_lock_irqsave(&usbmisc->lock, flags); in usbmisc_imx7d_set_wakeup()
603 val = readl(usbmisc->base); in usbmisc_imx7d_set_wakeup()
606 val |= usbmisc_wakeup_setting(data); in usbmisc_imx7d_set_wakeup()
607 writel(val, usbmisc->base); in usbmisc_imx7d_set_wakeup()
610 dev_dbg(data->dev, "wakeup int\n"); in usbmisc_imx7d_set_wakeup()
611 writel(val & ~MX6_USB_OTG_WAKEUP_BITS, usbmisc->base); in usbmisc_imx7d_set_wakeup()
613 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx7d_set_wakeup()
618 static int usbmisc_imx7d_init(struct imx_usbmisc_data *data) in usbmisc_imx7d_init() argument
620 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_imx7d_init()
622 u32 reg; in usbmisc_imx7d_init() local
624 if (data->index >= 1) in usbmisc_imx7d_init()
625 return -EINVAL; in usbmisc_imx7d_init()
627 spin_lock_irqsave(&usbmisc->lock, flags); in usbmisc_imx7d_init()
628 reg = readl(usbmisc->base); in usbmisc_imx7d_init()
629 if (data->disable_oc) { in usbmisc_imx7d_init()
630 reg |= MX6_BM_OVER_CUR_DIS; in usbmisc_imx7d_init()
632 reg &= ~MX6_BM_OVER_CUR_DIS; in usbmisc_imx7d_init()
638 if (data->oc_pol_configured && data->oc_pol_active_low) in usbmisc_imx7d_init()
639 reg |= MX6_BM_OVER_CUR_POLARITY; in usbmisc_imx7d_init()
640 else if (data->oc_pol_configured) in usbmisc_imx7d_init()
641 reg &= ~MX6_BM_OVER_CUR_POLARITY; in usbmisc_imx7d_init()
644 if (data->pwr_pol == 1) in usbmisc_imx7d_init()
645 reg |= MX6_BM_PWR_POLARITY; in usbmisc_imx7d_init()
646 writel(reg, usbmisc->base); in usbmisc_imx7d_init()
648 /* SoC non-burst setting */ in usbmisc_imx7d_init()
649 reg = readl(usbmisc->base); in usbmisc_imx7d_init()
650 writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base); in usbmisc_imx7d_init()
652 if (!data->hsic) { in usbmisc_imx7d_init()
653 reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); in usbmisc_imx7d_init()
654 reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; in usbmisc_imx7d_init()
655 writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID in usbmisc_imx7d_init()
657 usbmisc->base + MX7D_USBNC_USB_CTRL2); in usbmisc_imx7d_init()
659 reg = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG1); in usbmisc_imx7d_init()
660 if (data->emp_curr_control && data->emp_curr_control <= in usbmisc_imx7d_init()
662 reg &= ~TXPREEMPAMPTUNE0_MASK; in usbmisc_imx7d_init()
663 reg |= (data->emp_curr_control << TXPREEMPAMPTUNE0_BIT); in usbmisc_imx7d_init()
666 if (data->dc_vol_level_adjust && data->dc_vol_level_adjust <= in usbmisc_imx7d_init()
668 reg &= ~TXVREFTUNE0_MASK; in usbmisc_imx7d_init()
669 reg |= (data->dc_vol_level_adjust << TXVREFTUNE0_BIT); in usbmisc_imx7d_init()
672 writel(reg, usbmisc->base + MX7D_USB_OTG_PHY_CFG1); in usbmisc_imx7d_init()
675 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx7d_init()
677 usbmisc_imx7d_set_wakeup(data, false); in usbmisc_imx7d_init()
682 static int imx7d_charger_secondary_detection(struct imx_usbmisc_data *data) in imx7d_charger_secondary_detection() argument
684 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in imx7d_charger_secondary_detection()
685 struct usb_phy *usb_phy = data->usb_phy; in imx7d_charger_secondary_detection()
690 spin_lock_irqsave(&usbmisc->lock, flags); in imx7d_charger_secondary_detection()
691 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); in imx7d_charger_secondary_detection()
693 writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2); in imx7d_charger_secondary_detection()
694 spin_unlock_irqrestore(&usbmisc->lock, flags); in imx7d_charger_secondary_detection()
699 /* VDM_SRC is connected to D- and IDP_SINK is connected to D+ */ in imx7d_charger_secondary_detection()
700 spin_lock_irqsave(&usbmisc->lock, flags); in imx7d_charger_secondary_detection()
701 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); in imx7d_charger_secondary_detection()
705 usbmisc->base + MX7D_USB_OTG_PHY_CFG2); in imx7d_charger_secondary_detection()
706 spin_unlock_irqrestore(&usbmisc->lock, flags); in imx7d_charger_secondary_detection()
716 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); in imx7d_charger_secondary_detection()
718 dev_dbg(data->dev, "It is a dedicate charging port\n"); in imx7d_charger_secondary_detection()
719 usb_phy->chg_type = DCP_TYPE; in imx7d_charger_secondary_detection()
721 dev_dbg(data->dev, "It is a charging downstream port\n"); in imx7d_charger_secondary_detection()
722 usb_phy->chg_type = CDP_TYPE; in imx7d_charger_secondary_detection()
728 static void imx7_disable_charger_detector(struct imx_usbmisc_data *data) in imx7_disable_charger_detector() argument
730 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in imx7_disable_charger_detector()
734 spin_lock_irqsave(&usbmisc->lock, flags); in imx7_disable_charger_detector()
735 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); in imx7_disable_charger_detector()
740 writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2); in imx7_disable_charger_detector()
743 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); in imx7_disable_charger_detector()
745 writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); in imx7_disable_charger_detector()
747 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); in imx7_disable_charger_detector()
749 usbmisc->base + MX7D_USBNC_USB_CTRL2); in imx7_disable_charger_detector()
750 spin_unlock_irqrestore(&usbmisc->lock, flags); in imx7_disable_charger_detector()
753 static int imx7d_charger_data_contact_detect(struct imx_usbmisc_data *data) in imx7d_charger_data_contact_detect() argument
755 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in imx7d_charger_data_contact_detect()
760 /* Enable Data Contact Detect (DCD) per the USB BC 1.2 */ in imx7d_charger_data_contact_detect()
761 spin_lock_irqsave(&usbmisc->lock, flags); in imx7d_charger_data_contact_detect()
762 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); in imx7d_charger_data_contact_detect()
764 usbmisc->base + MX7D_USB_OTG_PHY_CFG2); in imx7d_charger_data_contact_detect()
765 spin_unlock_irqrestore(&usbmisc->lock, flags); in imx7d_charger_data_contact_detect()
768 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); in imx7d_charger_data_contact_detect()
771 /* Data pin makes contact */ in imx7d_charger_data_contact_detect()
780 /* Disable DCD after finished data contact check */ in imx7d_charger_data_contact_detect()
781 spin_lock_irqsave(&usbmisc->lock, flags); in imx7d_charger_data_contact_detect()
782 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); in imx7d_charger_data_contact_detect()
784 usbmisc->base + MX7D_USB_OTG_PHY_CFG2); in imx7d_charger_data_contact_detect()
785 spin_unlock_irqrestore(&usbmisc->lock, flags); in imx7d_charger_data_contact_detect()
788 dev_err(data->dev, in imx7d_charger_data_contact_detect()
790 return -ENXIO; in imx7d_charger_data_contact_detect()
796 static int imx7d_charger_primary_detection(struct imx_usbmisc_data *data) in imx7d_charger_primary_detection() argument
798 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in imx7d_charger_primary_detection()
799 struct usb_phy *usb_phy = data->usb_phy; in imx7d_charger_primary_detection()
803 /* VDP_SRC is connected to D+ and IDM_SINK is connected to D- */ in imx7d_charger_primary_detection()
804 spin_lock_irqsave(&usbmisc->lock, flags); in imx7d_charger_primary_detection()
805 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); in imx7d_charger_primary_detection()
809 usbmisc->base + MX7D_USB_OTG_PHY_CFG2); in imx7d_charger_primary_detection()
810 spin_unlock_irqrestore(&usbmisc->lock, flags); in imx7d_charger_primary_detection()
815 /* Check if D- is less than VDAT_REF to determine an SDP per BC 1.2 */ in imx7d_charger_primary_detection()
816 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); in imx7d_charger_primary_detection()
818 dev_dbg(data->dev, "It is a standard downstream port\n"); in imx7d_charger_primary_detection()
819 usb_phy->chg_type = SDP_TYPE; in imx7d_charger_primary_detection()
827 * 1. OPMODE override to be non-driving
828 * 2. Data contact check
833 static int imx7d_charger_detection(struct imx_usbmisc_data *data) in imx7d_charger_detection() argument
835 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in imx7d_charger_detection()
836 struct usb_phy *usb_phy = data->usb_phy; in imx7d_charger_detection()
842 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); in imx7d_charger_detection()
844 dev_err(data->dev, "vbus is error\n"); in imx7d_charger_detection()
845 return -EINVAL; in imx7d_charger_detection()
849 * Keep OPMODE to be non-driving mode during the whole in imx7d_charger_detection()
852 spin_lock_irqsave(&usbmisc->lock, flags); in imx7d_charger_detection()
853 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); in imx7d_charger_detection()
856 writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); in imx7d_charger_detection()
858 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); in imx7d_charger_detection()
860 usbmisc->base + MX7D_USBNC_USB_CTRL2); in imx7d_charger_detection()
861 spin_unlock_irqrestore(&usbmisc->lock, flags); in imx7d_charger_detection()
863 ret = imx7d_charger_data_contact_detect(data); in imx7d_charger_detection()
867 ret = imx7d_charger_primary_detection(data); in imx7d_charger_detection()
868 if (!ret && usb_phy->chg_type != SDP_TYPE) in imx7d_charger_detection()
869 ret = imx7d_charger_secondary_detection(data); in imx7d_charger_detection()
871 imx7_disable_charger_detector(data); in imx7d_charger_detection()
876 static int usbmisc_imx7ulp_init(struct imx_usbmisc_data *data) in usbmisc_imx7ulp_init() argument
878 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in usbmisc_imx7ulp_init()
880 u32 reg; in usbmisc_imx7ulp_init() local
882 if (data->index >= 1) in usbmisc_imx7ulp_init()
883 return -EINVAL; in usbmisc_imx7ulp_init()
885 spin_lock_irqsave(&usbmisc->lock, flags); in usbmisc_imx7ulp_init()
886 reg = readl(usbmisc->base); in usbmisc_imx7ulp_init()
887 if (data->disable_oc) { in usbmisc_imx7ulp_init()
888 reg |= MX6_BM_OVER_CUR_DIS; in usbmisc_imx7ulp_init()
890 reg &= ~MX6_BM_OVER_CUR_DIS; in usbmisc_imx7ulp_init()
896 if (data->oc_pol_configured && data->oc_pol_active_low) in usbmisc_imx7ulp_init()
897 reg |= MX6_BM_OVER_CUR_POLARITY; in usbmisc_imx7ulp_init()
898 else if (data->oc_pol_configured) in usbmisc_imx7ulp_init()
899 reg &= ~MX6_BM_OVER_CUR_POLARITY; in usbmisc_imx7ulp_init()
902 if (data->pwr_pol == 1) in usbmisc_imx7ulp_init()
903 reg |= MX6_BM_PWR_POLARITY; in usbmisc_imx7ulp_init()
905 writel(reg, usbmisc->base); in usbmisc_imx7ulp_init()
907 /* SoC non-burst setting */ in usbmisc_imx7ulp_init()
908 reg = readl(usbmisc->base); in usbmisc_imx7ulp_init()
909 writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base); in usbmisc_imx7ulp_init()
911 if (data->hsic) { in usbmisc_imx7ulp_init()
912 reg = readl(usbmisc->base); in usbmisc_imx7ulp_init()
913 writel(reg | MX6_BM_UTMI_ON_CLOCK, usbmisc->base); in usbmisc_imx7ulp_init()
915 reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); in usbmisc_imx7ulp_init()
916 reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; in usbmisc_imx7ulp_init()
917 writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); in usbmisc_imx7ulp_init()
920 * For non-HSIC controller, the autoresume is enabled in usbmisc_imx7ulp_init()
923 reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); in usbmisc_imx7ulp_init()
924 writel(reg | MX7D_USBNC_AUTO_RESUME, in usbmisc_imx7ulp_init()
925 usbmisc->base + MX7D_USBNC_USB_CTRL2); in usbmisc_imx7ulp_init()
927 reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); in usbmisc_imx7ulp_init()
928 reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; in usbmisc_imx7ulp_init()
929 writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID, in usbmisc_imx7ulp_init()
930 usbmisc->base + MX7D_USBNC_USB_CTRL2); in usbmisc_imx7ulp_init()
933 spin_unlock_irqrestore(&usbmisc->lock, flags); in usbmisc_imx7ulp_init()
935 usbmisc_imx7d_set_wakeup(data, false); in usbmisc_imx7ulp_init()
988 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data) in is_imx53_usbmisc() argument
990 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); in is_imx53_usbmisc()
992 return usbmisc->ops == &imx53_usbmisc_ops; in is_imx53_usbmisc()
995 int imx_usbmisc_init(struct imx_usbmisc_data *data) in imx_usbmisc_init() argument
999 if (!data) in imx_usbmisc_init()
1002 usbmisc = dev_get_drvdata(data->dev); in imx_usbmisc_init()
1003 if (!usbmisc->ops->init) in imx_usbmisc_init()
1005 return usbmisc->ops->init(data); in imx_usbmisc_init()
1009 int imx_usbmisc_init_post(struct imx_usbmisc_data *data) in imx_usbmisc_init_post() argument
1013 if (!data) in imx_usbmisc_init_post()
1016 usbmisc = dev_get_drvdata(data->dev); in imx_usbmisc_init_post()
1017 if (!usbmisc->ops->post) in imx_usbmisc_init_post()
1019 return usbmisc->ops->post(data); in imx_usbmisc_init_post()
1023 int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *data, bool enabled) in imx_usbmisc_set_wakeup() argument
1027 if (!data) in imx_usbmisc_set_wakeup()
1030 usbmisc = dev_get_drvdata(data->dev); in imx_usbmisc_set_wakeup()
1031 if (!usbmisc->ops->set_wakeup) in imx_usbmisc_set_wakeup()
1033 return usbmisc->ops->set_wakeup(data, enabled); in imx_usbmisc_set_wakeup()
1037 int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data) in imx_usbmisc_hsic_set_connect() argument
1041 if (!data) in imx_usbmisc_hsic_set_connect()
1044 usbmisc = dev_get_drvdata(data->dev); in imx_usbmisc_hsic_set_connect()
1045 if (!usbmisc->ops->hsic_set_connect || !data->hsic) in imx_usbmisc_hsic_set_connect()
1047 return usbmisc->ops->hsic_set_connect(data); in imx_usbmisc_hsic_set_connect()
1051 int imx_usbmisc_hsic_set_clk(struct imx_usbmisc_data *data, bool on) in imx_usbmisc_hsic_set_clk() argument
1055 if (!data) in imx_usbmisc_hsic_set_clk()
1058 usbmisc = dev_get_drvdata(data->dev); in imx_usbmisc_hsic_set_clk()
1059 if (!usbmisc->ops->hsic_set_clk || !data->hsic) in imx_usbmisc_hsic_set_clk()
1061 return usbmisc->ops->hsic_set_clk(data, on); in imx_usbmisc_hsic_set_clk()
1065 int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect) in imx_usbmisc_charger_detection() argument
1071 if (!data) in imx_usbmisc_charger_detection()
1072 return -EINVAL; in imx_usbmisc_charger_detection()
1074 usbmisc = dev_get_drvdata(data->dev); in imx_usbmisc_charger_detection()
1075 usb_phy = data->usb_phy; in imx_usbmisc_charger_detection()
1076 if (!usbmisc->ops->charger_detection) in imx_usbmisc_charger_detection()
1077 return -ENOTSUPP; in imx_usbmisc_charger_detection()
1080 ret = usbmisc->ops->charger_detection(data); in imx_usbmisc_charger_detection()
1082 dev_err(data->dev, in imx_usbmisc_charger_detection()
1085 usb_phy->chg_state = USB_CHARGER_ABSENT; in imx_usbmisc_charger_detection()
1087 usb_phy->chg_state = USB_CHARGER_PRESENT; in imx_usbmisc_charger_detection()
1090 usb_phy->chg_state = USB_CHARGER_ABSENT; in imx_usbmisc_charger_detection()
1091 usb_phy->chg_type = UNKNOWN_TYPE; in imx_usbmisc_charger_detection()
1099 .compatible = "fsl,imx25-usbmisc",
1100 .data = &imx25_usbmisc_ops,
1103 .compatible = "fsl,imx35-usbmisc",
1104 .data = &imx25_usbmisc_ops,
1107 .compatible = "fsl,imx27-usbmisc",
1108 .data = &imx27_usbmisc_ops,
1111 .compatible = "fsl,imx51-usbmisc",
1112 .data = &imx51_usbmisc_ops,
1115 .compatible = "fsl,imx53-usbmisc",
1116 .data = &imx53_usbmisc_ops,
1119 .compatible = "fsl,imx6q-usbmisc",
1120 .data = &imx6q_usbmisc_ops,
1123 .compatible = "fsl,vf610-usbmisc",
1124 .data = &vf610_usbmisc_ops,
1127 .compatible = "fsl,imx6sx-usbmisc",
1128 .data = &imx6sx_usbmisc_ops,
1131 .compatible = "fsl,imx6ul-usbmisc",
1132 .data = &imx6sx_usbmisc_ops,
1135 .compatible = "fsl,imx7d-usbmisc",
1136 .data = &imx7d_usbmisc_ops,
1139 .compatible = "fsl,imx7ulp-usbmisc",
1140 .data = &imx7ulp_usbmisc_ops,
1148 struct imx_usbmisc *data; in usbmisc_imx_probe() local
1150 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); in usbmisc_imx_probe()
1151 if (!data) in usbmisc_imx_probe()
1152 return -ENOMEM; in usbmisc_imx_probe()
1154 spin_lock_init(&data->lock); in usbmisc_imx_probe()
1156 data->base = devm_platform_ioremap_resource(pdev, 0); in usbmisc_imx_probe()
1157 if (IS_ERR(data->base)) in usbmisc_imx_probe()
1158 return PTR_ERR(data->base); in usbmisc_imx_probe()
1160 data->ops = of_device_get_match_data(&pdev->dev); in usbmisc_imx_probe()
1161 platform_set_drvdata(pdev, data); in usbmisc_imx_probe()
1182 MODULE_ALIAS("platform:usbmisc-imx");
1184 MODULE_DESCRIPTION("driver for imx usb non-core registers");