Lines Matching +full:usb2 +full:- +full:phy +full:- +full:r8a7795
1 // SPDX-License-Identifier: GPL-2.0
3 * Renesas R-Car Gen3 for USB2.0 PHY driver
5 * Copyright (C) 2015-2017 Renesas Electronics Corporation
7 * This is based on the phy-rcar-gen2 driver:
12 #include <linux/extcon-provider.h>
18 #include <linux/phy/phy.h>
26 /******* USB2.0 Host registers (original offset is +0x200) *******/
100 struct phy *phy; member
135 * ---------------------+---------------++--------------+------------
146 if (ch->extcon_host) { in rcar_gen3_phy_usb2_work()
147 extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, true); in rcar_gen3_phy_usb2_work()
148 extcon_set_state_sync(ch->extcon, EXTCON_USB, false); in rcar_gen3_phy_usb2_work()
150 extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, false); in rcar_gen3_phy_usb2_work()
151 extcon_set_state_sync(ch->extcon, EXTCON_USB, true); in rcar_gen3_phy_usb2_work()
157 void __iomem *usb2_base = ch->base; in rcar_gen3_set_host_mode()
160 dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, host); in rcar_gen3_set_host_mode()
170 void __iomem *usb2_base = ch->base; in rcar_gen3_set_linectrl()
173 dev_vdbg(ch->dev, "%s: %08x, %d, %d\n", __func__, val, dp, dm); in rcar_gen3_set_linectrl()
184 void __iomem *usb2_base = ch->base; in rcar_gen3_enable_vbus_ctrl()
189 dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus); in rcar_gen3_enable_vbus_ctrl()
190 if (ch->soc_no_adp_ctrl) { in rcar_gen3_enable_vbus_ctrl()
205 void __iomem *usb2_base = ch->base; in rcar_gen3_control_otg_irq()
208 if (ch->uses_otg_pins && enable) in rcar_gen3_control_otg_irq()
209 val |= ch->obint_enable_bits; in rcar_gen3_control_otg_irq()
211 val &= ~ch->obint_enable_bits; in rcar_gen3_control_otg_irq()
221 ch->extcon_host = true; in rcar_gen3_init_for_host()
222 schedule_work(&ch->work); in rcar_gen3_init_for_host()
231 ch->extcon_host = false; in rcar_gen3_init_for_peri()
232 schedule_work(&ch->work); in rcar_gen3_init_for_peri()
237 void __iomem *usb2_base = ch->base; in rcar_gen3_init_for_b_host()
270 if (!ch->uses_otg_pins) in rcar_gen3_check_id()
271 return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true; in rcar_gen3_check_id()
273 if (ch->soc_no_adp_ctrl) in rcar_gen3_check_id()
274 return !!(readl(ch->base + USB2_LINECTRL1) & USB2_LINECTRL1_USB2_IDMON); in rcar_gen3_check_id()
276 return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); in rcar_gen3_check_id()
289 return !(readl(ch->base + USB2_COMMCTRL) & USB2_COMMCTRL_OTG_PERI); in rcar_gen3_is_host()
305 if (ch->rphys[i].initialized) in rcar_gen3_is_any_rphy_initialized()
317 if (ch->rphys[i].otg_initialized) in rcar_gen3_needs_init_otg()
329 if (ch->rphys[i].powered) in rcar_gen3_are_all_rphys_power_off()
343 if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch)) in role_store()
344 return -EIO; in role_store()
351 return -EINVAL; in role_store()
353 /* is_b_device: true is B-Device. false is A-Device. */ in role_store()
359 return -EINVAL; in role_store()
362 if (!is_b_device) /* A-Peripheral */ in role_store()
364 else /* B-Peripheral */ in role_store()
367 if (!is_b_device) /* A-Host */ in role_store()
369 else /* B-Host */ in role_store()
381 if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch)) in role_show()
382 return -EIO; in role_show()
391 void __iomem *usb2_base = ch->base; in rcar_gen3_init_otg()
394 /* Should not use functions of read-modify-write a register */ in rcar_gen3_init_otg()
400 if (!ch->soc_no_adp_ctrl) { in rcar_gen3_init_otg()
410 writel(ch->obint_enable_bits, usb2_base + USB2_OBINTEN); in rcar_gen3_init_otg()
418 void __iomem *usb2_base = ch->base; in rcar_gen3_phy_usb2_irq()
422 if (status & ch->obint_enable_bits) { in rcar_gen3_phy_usb2_irq()
423 dev_vdbg(ch->dev, "%s: %08x\n", __func__, status); in rcar_gen3_phy_usb2_irq()
424 writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA); in rcar_gen3_phy_usb2_irq()
432 static int rcar_gen3_phy_usb2_init(struct phy *p) in rcar_gen3_phy_usb2_init()
435 struct rcar_gen3_chan *channel = rphy->ch; in rcar_gen3_phy_usb2_init()
436 void __iomem *usb2_base = channel->base; in rcar_gen3_phy_usb2_init()
440 if (!rcar_gen3_is_any_rphy_initialized(channel) && channel->irq >= 0) { in rcar_gen3_phy_usb2_init()
441 INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); in rcar_gen3_phy_usb2_init()
442 ret = request_irq(channel->irq, rcar_gen3_phy_usb2_irq, in rcar_gen3_phy_usb2_init()
443 IRQF_SHARED, dev_name(channel->dev), channel); in rcar_gen3_phy_usb2_init()
445 dev_err(channel->dev, "No irq handler (%d)\n", channel->irq); in rcar_gen3_phy_usb2_init()
450 /* Initialize USB2 part */ in rcar_gen3_phy_usb2_init()
452 val |= USB2_INT_ENABLE_UCOM_INTEN | rphy->int_enable_bits; in rcar_gen3_phy_usb2_init()
458 if (channel->is_otg_channel) { in rcar_gen3_phy_usb2_init()
461 rphy->otg_initialized = true; in rcar_gen3_phy_usb2_init()
464 rphy->initialized = true; in rcar_gen3_phy_usb2_init()
469 static int rcar_gen3_phy_usb2_exit(struct phy *p) in rcar_gen3_phy_usb2_exit()
472 struct rcar_gen3_chan *channel = rphy->ch; in rcar_gen3_phy_usb2_exit()
473 void __iomem *usb2_base = channel->base; in rcar_gen3_phy_usb2_exit()
476 rphy->initialized = false; in rcar_gen3_phy_usb2_exit()
478 if (channel->is_otg_channel) in rcar_gen3_phy_usb2_exit()
479 rphy->otg_initialized = false; in rcar_gen3_phy_usb2_exit()
482 val &= ~rphy->int_enable_bits; in rcar_gen3_phy_usb2_exit()
487 if (channel->irq >= 0 && !rcar_gen3_is_any_rphy_initialized(channel)) in rcar_gen3_phy_usb2_exit()
488 free_irq(channel->irq, channel); in rcar_gen3_phy_usb2_exit()
493 static int rcar_gen3_phy_usb2_power_on(struct phy *p) in rcar_gen3_phy_usb2_power_on()
496 struct rcar_gen3_chan *channel = rphy->ch; in rcar_gen3_phy_usb2_power_on()
497 void __iomem *usb2_base = channel->base; in rcar_gen3_phy_usb2_power_on()
501 mutex_lock(&channel->lock); in rcar_gen3_phy_usb2_power_on()
505 if (channel->vbus) { in rcar_gen3_phy_usb2_power_on()
506 ret = regulator_enable(channel->vbus); in rcar_gen3_phy_usb2_power_on()
519 rphy->powered = true; in rcar_gen3_phy_usb2_power_on()
520 mutex_unlock(&channel->lock); in rcar_gen3_phy_usb2_power_on()
525 static int rcar_gen3_phy_usb2_power_off(struct phy *p) in rcar_gen3_phy_usb2_power_off()
528 struct rcar_gen3_chan *channel = rphy->ch; in rcar_gen3_phy_usb2_power_off()
531 mutex_lock(&channel->lock); in rcar_gen3_phy_usb2_power_off()
532 rphy->powered = false; in rcar_gen3_phy_usb2_power_off()
537 if (channel->vbus) in rcar_gen3_phy_usb2_power_off()
538 ret = regulator_disable(channel->vbus); in rcar_gen3_phy_usb2_power_off()
541 mutex_unlock(&channel->lock); in rcar_gen3_phy_usb2_power_off()
577 .compatible = "renesas,usb2-phy-r8a77470",
581 .compatible = "renesas,usb2-phy-r8a7795",
585 .compatible = "renesas,usb2-phy-r8a7796",
589 .compatible = "renesas,usb2-phy-r8a77965",
593 .compatible = "renesas,rzg2l-usb2-phy",
597 .compatible = "renesas,rcar-gen3-usb2-phy",
610 static struct phy *rcar_gen3_phy_usb2_xlate(struct device *dev, in rcar_gen3_phy_usb2_xlate()
615 if (args->args_count == 0) /* For old version dts */ in rcar_gen3_phy_usb2_xlate()
616 return ch->rphys[PHY_INDEX_BOTH_HC].phy; in rcar_gen3_phy_usb2_xlate()
617 else if (args->args_count > 1) /* Prevent invalid args count */ in rcar_gen3_phy_usb2_xlate()
618 return ERR_PTR(-ENODEV); in rcar_gen3_phy_usb2_xlate()
620 if (args->args[0] >= NUM_OF_PHYS) in rcar_gen3_phy_usb2_xlate()
621 return ERR_PTR(-ENODEV); in rcar_gen3_phy_usb2_xlate()
623 return ch->rphys[args->args[0]].phy; in rcar_gen3_phy_usb2_xlate()
653 struct device *dev = &pdev->dev; in rcar_gen3_phy_usb2_probe()
658 if (!dev->of_node) { in rcar_gen3_phy_usb2_probe()
660 return -EINVAL; in rcar_gen3_phy_usb2_probe()
665 return -ENOMEM; in rcar_gen3_phy_usb2_probe()
667 channel->base = devm_platform_ioremap_resource(pdev, 0); in rcar_gen3_phy_usb2_probe()
668 if (IS_ERR(channel->base)) in rcar_gen3_phy_usb2_probe()
669 return PTR_ERR(channel->base); in rcar_gen3_phy_usb2_probe()
671 channel->obint_enable_bits = USB2_OBINT_BITS; in rcar_gen3_phy_usb2_probe()
673 channel->irq = platform_get_irq_optional(pdev, 0); in rcar_gen3_phy_usb2_probe()
674 channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node); in rcar_gen3_phy_usb2_probe()
675 if (channel->dr_mode != USB_DR_MODE_UNKNOWN) { in rcar_gen3_phy_usb2_probe()
676 channel->is_otg_channel = true; in rcar_gen3_phy_usb2_probe()
677 channel->uses_otg_pins = !of_property_read_bool(dev->of_node, in rcar_gen3_phy_usb2_probe()
678 "renesas,no-otg-pins"); in rcar_gen3_phy_usb2_probe()
679 channel->extcon = devm_extcon_dev_allocate(dev, in rcar_gen3_phy_usb2_probe()
681 if (IS_ERR(channel->extcon)) in rcar_gen3_phy_usb2_probe()
682 return PTR_ERR(channel->extcon); in rcar_gen3_phy_usb2_probe()
684 ret = devm_extcon_dev_register(dev, channel->extcon); in rcar_gen3_phy_usb2_probe()
692 * devm_phy_create() will call pm_runtime_enable(&phy->dev); in rcar_gen3_phy_usb2_probe()
693 * And then, phy-core will manage runtime pm for this device. in rcar_gen3_phy_usb2_probe()
699 ret = -EINVAL; in rcar_gen3_phy_usb2_probe()
703 channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl; in rcar_gen3_phy_usb2_probe()
704 if (phy_data->no_adp_ctrl) in rcar_gen3_phy_usb2_probe()
705 channel->obint_enable_bits = USB2_OBINT_IDCHG_EN; in rcar_gen3_phy_usb2_probe()
707 mutex_init(&channel->lock); in rcar_gen3_phy_usb2_probe()
709 channel->rphys[i].phy = devm_phy_create(dev, NULL, in rcar_gen3_phy_usb2_probe()
710 phy_data->phy_usb2_ops); in rcar_gen3_phy_usb2_probe()
711 if (IS_ERR(channel->rphys[i].phy)) { in rcar_gen3_phy_usb2_probe()
712 dev_err(dev, "Failed to create USB2 PHY\n"); in rcar_gen3_phy_usb2_probe()
713 ret = PTR_ERR(channel->rphys[i].phy); in rcar_gen3_phy_usb2_probe()
716 channel->rphys[i].ch = channel; in rcar_gen3_phy_usb2_probe()
717 channel->rphys[i].int_enable_bits = rcar_gen3_int_enable[i]; in rcar_gen3_phy_usb2_probe()
718 phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]); in rcar_gen3_phy_usb2_probe()
721 channel->vbus = devm_regulator_get_optional(dev, "vbus"); in rcar_gen3_phy_usb2_probe()
722 if (IS_ERR(channel->vbus)) { in rcar_gen3_phy_usb2_probe()
723 if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) { in rcar_gen3_phy_usb2_probe()
724 ret = PTR_ERR(channel->vbus); in rcar_gen3_phy_usb2_probe()
727 channel->vbus = NULL; in rcar_gen3_phy_usb2_probe()
731 channel->dev = dev; in rcar_gen3_phy_usb2_probe()
735 dev_err(dev, "Failed to register PHY provider\n"); in rcar_gen3_phy_usb2_probe()
738 } else if (channel->is_otg_channel) { in rcar_gen3_phy_usb2_probe()
756 if (channel->is_otg_channel) in rcar_gen3_phy_usb2_remove()
757 device_remove_file(&pdev->dev, &dev_attr_role); in rcar_gen3_phy_usb2_remove()
759 pm_runtime_disable(&pdev->dev); in rcar_gen3_phy_usb2_remove()
773 MODULE_DESCRIPTION("Renesas R-Car Gen3 USB 2.0 PHY");