Lines Matching +full:rcar +full:- +full:gen2 +full:- +full:usb +full:- +full:phy
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>
24 #include <linux/usb/of.h>
106 struct phy *phy; member
143 * ---------------------+---------------++--------------+------------
154 if (ch->extcon_host) { in rcar_gen3_phy_usb2_work()
155 extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, true); in rcar_gen3_phy_usb2_work()
156 extcon_set_state_sync(ch->extcon, EXTCON_USB, false); in rcar_gen3_phy_usb2_work()
158 extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, false); in rcar_gen3_phy_usb2_work()
159 extcon_set_state_sync(ch->extcon, EXTCON_USB, true); in rcar_gen3_phy_usb2_work()
165 void __iomem *usb2_base = ch->base; in rcar_gen3_set_host_mode()
168 dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, host); in rcar_gen3_set_host_mode()
178 void __iomem *usb2_base = ch->base; in rcar_gen3_set_linectrl()
181 dev_vdbg(ch->dev, "%s: %08x, %d, %d\n", __func__, val, dp, dm); in rcar_gen3_set_linectrl()
192 void __iomem *usb2_base = ch->base; in rcar_gen3_enable_vbus_ctrl()
197 dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus); in rcar_gen3_enable_vbus_ctrl()
198 if (ch->soc_no_adp_ctrl) { in rcar_gen3_enable_vbus_ctrl()
199 if (ch->vbus) in rcar_gen3_enable_vbus_ctrl()
200 regulator_hardware_enable(ch->vbus, vbus); in rcar_gen3_enable_vbus_ctrl()
216 void __iomem *usb2_base = ch->base; in rcar_gen3_control_otg_irq()
219 if (ch->uses_otg_pins && enable) in rcar_gen3_control_otg_irq()
220 val |= ch->obint_enable_bits; in rcar_gen3_control_otg_irq()
222 val &= ~ch->obint_enable_bits; in rcar_gen3_control_otg_irq()
232 ch->extcon_host = true; in rcar_gen3_init_for_host()
233 schedule_work(&ch->work); in rcar_gen3_init_for_host()
242 ch->extcon_host = false; in rcar_gen3_init_for_peri()
243 schedule_work(&ch->work); in rcar_gen3_init_for_peri()
248 void __iomem *usb2_base = ch->base; in rcar_gen3_init_for_b_host()
281 if (!ch->uses_otg_pins) in rcar_gen3_check_id()
282 return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true; in rcar_gen3_check_id()
284 if (ch->soc_no_adp_ctrl) in rcar_gen3_check_id()
285 return !!(readl(ch->base + USB2_LINECTRL1) & USB2_LINECTRL1_USB2_IDMON); in rcar_gen3_check_id()
287 return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); in rcar_gen3_check_id()
300 return !(readl(ch->base + USB2_COMMCTRL) & USB2_COMMCTRL_OTG_PERI); in rcar_gen3_is_host()
316 if (ch->rphys[i].initialized) in rcar_gen3_is_any_rphy_initialized()
328 if (ch->rphys[i].otg_initialized) in rcar_gen3_needs_init_otg()
340 if (ch->rphys[i].powered) in rcar_gen3_are_all_rphys_power_off()
354 if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch)) in role_store()
355 return -EIO; in role_store()
362 return -EINVAL; in role_store()
364 /* is_b_device: true is B-Device. false is A-Device. */ in role_store()
370 return -EINVAL; in role_store()
373 if (!is_b_device) /* A-Peripheral */ in role_store()
375 else /* B-Peripheral */ in role_store()
378 if (!is_b_device) /* A-Host */ in role_store()
380 else /* B-Host */ in role_store()
392 if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch)) in role_show()
393 return -EIO; in role_show()
402 void __iomem *usb2_base = ch->base; in rcar_gen3_init_otg()
405 /* Should not use functions of read-modify-write a register */ in rcar_gen3_init_otg()
411 if (!ch->soc_no_adp_ctrl) { in rcar_gen3_init_otg()
421 writel(ch->obint_enable_bits, usb2_base + USB2_OBINTEN); in rcar_gen3_init_otg()
429 void __iomem *usb2_base = ch->base; in rcar_gen3_phy_usb2_irq()
433 if (status & ch->obint_enable_bits) { in rcar_gen3_phy_usb2_irq()
434 dev_vdbg(ch->dev, "%s: %08x\n", __func__, status); in rcar_gen3_phy_usb2_irq()
435 writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA); in rcar_gen3_phy_usb2_irq()
443 static int rcar_gen3_phy_usb2_init(struct phy *p) in rcar_gen3_phy_usb2_init()
446 struct rcar_gen3_chan *channel = rphy->ch; in rcar_gen3_phy_usb2_init()
447 void __iomem *usb2_base = channel->base; in rcar_gen3_phy_usb2_init()
451 if (!rcar_gen3_is_any_rphy_initialized(channel) && channel->irq >= 0) { in rcar_gen3_phy_usb2_init()
452 INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); in rcar_gen3_phy_usb2_init()
453 ret = request_irq(channel->irq, rcar_gen3_phy_usb2_irq, in rcar_gen3_phy_usb2_init()
454 IRQF_SHARED, dev_name(channel->dev), channel); in rcar_gen3_phy_usb2_init()
456 dev_err(channel->dev, "No irq handler (%d)\n", channel->irq); in rcar_gen3_phy_usb2_init()
463 val |= USB2_INT_ENABLE_UCOM_INTEN | rphy->int_enable_bits; in rcar_gen3_phy_usb2_init()
469 if (channel->is_otg_channel) { in rcar_gen3_phy_usb2_init()
472 rphy->otg_initialized = true; in rcar_gen3_phy_usb2_init()
475 rphy->initialized = true; in rcar_gen3_phy_usb2_init()
480 static int rcar_gen3_phy_usb2_exit(struct phy *p) in rcar_gen3_phy_usb2_exit()
483 struct rcar_gen3_chan *channel = rphy->ch; in rcar_gen3_phy_usb2_exit()
484 void __iomem *usb2_base = channel->base; in rcar_gen3_phy_usb2_exit()
487 rphy->initialized = false; in rcar_gen3_phy_usb2_exit()
489 if (channel->is_otg_channel) in rcar_gen3_phy_usb2_exit()
490 rphy->otg_initialized = false; in rcar_gen3_phy_usb2_exit()
493 val &= ~rphy->int_enable_bits; in rcar_gen3_phy_usb2_exit()
498 if (channel->irq >= 0 && !rcar_gen3_is_any_rphy_initialized(channel)) in rcar_gen3_phy_usb2_exit()
499 free_irq(channel->irq, channel); in rcar_gen3_phy_usb2_exit()
504 static int rcar_gen3_phy_usb2_power_on(struct phy *p) in rcar_gen3_phy_usb2_power_on()
507 struct rcar_gen3_chan *channel = rphy->ch; in rcar_gen3_phy_usb2_power_on()
508 void __iomem *usb2_base = channel->base; in rcar_gen3_phy_usb2_power_on()
512 mutex_lock(&channel->lock); in rcar_gen3_phy_usb2_power_on()
516 if (channel->vbus) { in rcar_gen3_phy_usb2_power_on()
517 ret = regulator_enable(channel->vbus); in rcar_gen3_phy_usb2_power_on()
530 rphy->powered = true; in rcar_gen3_phy_usb2_power_on()
531 mutex_unlock(&channel->lock); in rcar_gen3_phy_usb2_power_on()
536 static int rcar_gen3_phy_usb2_power_off(struct phy *p) in rcar_gen3_phy_usb2_power_off()
539 struct rcar_gen3_chan *channel = rphy->ch; in rcar_gen3_phy_usb2_power_off()
542 mutex_lock(&channel->lock); in rcar_gen3_phy_usb2_power_off()
543 rphy->powered = false; in rcar_gen3_phy_usb2_power_off()
548 if (channel->vbus) in rcar_gen3_phy_usb2_power_off()
549 ret = regulator_disable(channel->vbus); in rcar_gen3_phy_usb2_power_off()
552 mutex_unlock(&channel->lock); in rcar_gen3_phy_usb2_power_off()
594 .compatible = "renesas,usb2-phy-r8a77470",
598 .compatible = "renesas,usb2-phy-r8a7795",
602 .compatible = "renesas,usb2-phy-r8a7796",
606 .compatible = "renesas,usb2-phy-r8a77965",
610 .compatible = "renesas,rzg2l-usb2-phy",
614 .compatible = "renesas,usb2-phy-r9a08g045",
618 .compatible = "renesas,rcar-gen3-usb2-phy",
631 static struct phy *rcar_gen3_phy_usb2_xlate(struct device *dev, in rcar_gen3_phy_usb2_xlate()
636 if (args->args_count == 0) /* For old version dts */ in rcar_gen3_phy_usb2_xlate()
637 return ch->rphys[PHY_INDEX_BOTH_HC].phy; in rcar_gen3_phy_usb2_xlate()
638 else if (args->args_count > 1) /* Prevent invalid args count */ in rcar_gen3_phy_usb2_xlate()
639 return ERR_PTR(-ENODEV); in rcar_gen3_phy_usb2_xlate()
641 if (args->args[0] >= NUM_OF_PHYS) in rcar_gen3_phy_usb2_xlate()
642 return ERR_PTR(-ENODEV); in rcar_gen3_phy_usb2_xlate()
644 return ch->rphys[args->args[0]].phy; in rcar_gen3_phy_usb2_xlate()
673 struct device *dev = channel->dev; in rcar_gen3_phy_usb2_init_bus()
677 channel->rstc = devm_reset_control_array_get_shared(dev); in rcar_gen3_phy_usb2_init_bus()
678 if (IS_ERR(channel->rstc)) in rcar_gen3_phy_usb2_init_bus()
679 return PTR_ERR(channel->rstc); in rcar_gen3_phy_usb2_init_bus()
685 ret = reset_control_deassert(channel->rstc); in rcar_gen3_phy_usb2_init_bus()
689 val = readl(channel->base + USB2_AHB_BUS_CTR); in rcar_gen3_phy_usb2_init_bus()
692 writel(val, channel->base + USB2_AHB_BUS_CTR); in rcar_gen3_phy_usb2_init_bus()
703 struct device *dev = &pdev->dev; in rcar_gen3_phy_usb2_probe()
708 if (!dev->of_node) { in rcar_gen3_phy_usb2_probe()
710 return -EINVAL; in rcar_gen3_phy_usb2_probe()
715 return -ENOMEM; in rcar_gen3_phy_usb2_probe()
717 channel->base = devm_platform_ioremap_resource(pdev, 0); in rcar_gen3_phy_usb2_probe()
718 if (IS_ERR(channel->base)) in rcar_gen3_phy_usb2_probe()
719 return PTR_ERR(channel->base); in rcar_gen3_phy_usb2_probe()
721 channel->obint_enable_bits = USB2_OBINT_BITS; in rcar_gen3_phy_usb2_probe()
723 channel->irq = platform_get_irq_optional(pdev, 0); in rcar_gen3_phy_usb2_probe()
724 channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node); in rcar_gen3_phy_usb2_probe()
725 if (channel->dr_mode != USB_DR_MODE_UNKNOWN) { in rcar_gen3_phy_usb2_probe()
726 channel->is_otg_channel = true; in rcar_gen3_phy_usb2_probe()
727 channel->uses_otg_pins = !of_property_read_bool(dev->of_node, in rcar_gen3_phy_usb2_probe()
728 "renesas,no-otg-pins"); in rcar_gen3_phy_usb2_probe()
729 channel->extcon = devm_extcon_dev_allocate(dev, in rcar_gen3_phy_usb2_probe()
731 if (IS_ERR(channel->extcon)) in rcar_gen3_phy_usb2_probe()
732 return PTR_ERR(channel->extcon); in rcar_gen3_phy_usb2_probe()
734 ret = devm_extcon_dev_register(dev, channel->extcon); in rcar_gen3_phy_usb2_probe()
742 * devm_phy_create() will call pm_runtime_enable(&phy->dev); in rcar_gen3_phy_usb2_probe()
743 * And then, phy-core will manage runtime pm for this device. in rcar_gen3_phy_usb2_probe()
749 ret = -EINVAL; in rcar_gen3_phy_usb2_probe()
754 channel->dev = dev; in rcar_gen3_phy_usb2_probe()
756 if (phy_data->init_bus) { in rcar_gen3_phy_usb2_probe()
762 channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl; in rcar_gen3_phy_usb2_probe()
763 if (phy_data->no_adp_ctrl) in rcar_gen3_phy_usb2_probe()
764 channel->obint_enable_bits = USB2_OBINT_IDCHG_EN; in rcar_gen3_phy_usb2_probe()
766 mutex_init(&channel->lock); in rcar_gen3_phy_usb2_probe()
768 channel->rphys[i].phy = devm_phy_create(dev, NULL, in rcar_gen3_phy_usb2_probe()
769 phy_data->phy_usb2_ops); in rcar_gen3_phy_usb2_probe()
770 if (IS_ERR(channel->rphys[i].phy)) { in rcar_gen3_phy_usb2_probe()
771 dev_err(dev, "Failed to create USB2 PHY\n"); in rcar_gen3_phy_usb2_probe()
772 ret = PTR_ERR(channel->rphys[i].phy); in rcar_gen3_phy_usb2_probe()
775 channel->rphys[i].ch = channel; in rcar_gen3_phy_usb2_probe()
776 channel->rphys[i].int_enable_bits = rcar_gen3_int_enable[i]; in rcar_gen3_phy_usb2_probe()
777 phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]); in rcar_gen3_phy_usb2_probe()
780 if (channel->soc_no_adp_ctrl && channel->is_otg_channel) in rcar_gen3_phy_usb2_probe()
781 channel->vbus = devm_regulator_get_exclusive(dev, "vbus"); in rcar_gen3_phy_usb2_probe()
783 channel->vbus = devm_regulator_get_optional(dev, "vbus"); in rcar_gen3_phy_usb2_probe()
784 if (IS_ERR(channel->vbus)) { in rcar_gen3_phy_usb2_probe()
785 if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) { in rcar_gen3_phy_usb2_probe()
786 ret = PTR_ERR(channel->vbus); in rcar_gen3_phy_usb2_probe()
789 channel->vbus = NULL; in rcar_gen3_phy_usb2_probe()
794 dev_err(dev, "Failed to register PHY provider\n"); in rcar_gen3_phy_usb2_probe()
797 } else if (channel->is_otg_channel) { in rcar_gen3_phy_usb2_probe()
815 if (channel->is_otg_channel) in rcar_gen3_phy_usb2_remove()
816 device_remove_file(&pdev->dev, &dev_attr_role); in rcar_gen3_phy_usb2_remove()
818 reset_control_assert(channel->rstc); in rcar_gen3_phy_usb2_remove()
819 pm_runtime_disable(&pdev->dev); in rcar_gen3_phy_usb2_remove()
833 MODULE_DESCRIPTION("Renesas R-Car Gen3 USB 2.0 PHY");