|
22 | 22 | #include <linux/platform_device.h> |
23 | 23 | #include <linux/pm_runtime.h> |
24 | 24 | #include <linux/regulator/consumer.h> |
| 25 | +#include <linux/regulator/driver.h> |
25 | 26 | #include <linux/reset.h> |
26 | 27 | #include <linux/string.h> |
27 | 28 | #include <linux/usb/of.h> |
@@ -141,6 +142,7 @@ struct rcar_gen3_chan { |
141 | 142 | bool extcon_host; |
142 | 143 | bool is_otg_channel; |
143 | 144 | bool uses_otg_pins; |
| 145 | + bool otg_internal_reg; |
144 | 146 | }; |
145 | 147 |
|
146 | 148 | struct rcar_gen3_phy_drv_data { |
@@ -225,6 +227,11 @@ static void rcar_gen3_phy_usb2_set_vbus(struct rcar_gen3_chan *ch, |
225 | 227 |
|
226 | 228 | static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus) |
227 | 229 | { |
| 230 | + if (ch->otg_internal_reg) { |
| 231 | + regulator_hardware_enable(ch->vbus, vbus); |
| 232 | + return; |
| 233 | + } |
| 234 | + |
228 | 235 | if (ch->phy_data->no_adp_ctrl || ch->phy_data->vblvl_ctrl) { |
229 | 236 | if (ch->vbus) |
230 | 237 | regulator_hardware_enable(ch->vbus, vbus); |
@@ -593,7 +600,7 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p) |
593 | 600 | u32 val; |
594 | 601 | int ret = 0; |
595 | 602 |
|
596 | | - if (channel->vbus) { |
| 603 | + if (channel->vbus && !channel->otg_internal_reg) { |
597 | 604 | ret = regulator_enable(channel->vbus); |
598 | 605 | if (ret) |
599 | 606 | return ret; |
@@ -634,7 +641,7 @@ static int rcar_gen3_phy_usb2_power_off(struct phy *p) |
634 | 641 | } |
635 | 642 | } |
636 | 643 |
|
637 | | - if (channel->vbus) |
| 644 | + if (channel->vbus && !channel->otg_internal_reg) |
638 | 645 | ret = regulator_disable(channel->vbus); |
639 | 646 |
|
640 | 647 | return ret; |
@@ -809,6 +816,128 @@ static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel) |
809 | 816 | return 0; |
810 | 817 | } |
811 | 818 |
|
| 819 | +static int rcar_gen3_phy_usb2_regulator_endisable(struct regulator_dev *rdev, |
| 820 | + bool enable) |
| 821 | +{ |
| 822 | + struct rcar_gen3_chan *channel = rdev_get_drvdata(rdev); |
| 823 | + struct device *dev = channel->dev; |
| 824 | + int ret; |
| 825 | + |
| 826 | + ret = pm_runtime_resume_and_get(dev); |
| 827 | + if (ret < 0) { |
| 828 | + dev_warn(dev, "pm_runtime_get failed: %i\n", ret); |
| 829 | + return ret; |
| 830 | + } |
| 831 | + |
| 832 | + rcar_gen3_phy_usb2_set_vbus(channel, USB2_VBCTRL, |
| 833 | + USB2_VBCTRL_VBOUT, enable); |
| 834 | + pm_runtime_put_noidle(dev); |
| 835 | + |
| 836 | + return ret; |
| 837 | +} |
| 838 | + |
| 839 | +static int rcar_gen3_phy_usb2_regulator_enable(struct regulator_dev *rdev) |
| 840 | +{ |
| 841 | + return rcar_gen3_phy_usb2_regulator_endisable(rdev, true); |
| 842 | +} |
| 843 | + |
| 844 | +static int rcar_gen3_phy_usb2_regulator_disable(struct regulator_dev *rdev) |
| 845 | +{ |
| 846 | + return rcar_gen3_phy_usb2_regulator_endisable(rdev, false); |
| 847 | +} |
| 848 | + |
| 849 | +static int rcar_gen3_phy_usb2_regulator_is_enabled(struct regulator_dev *rdev) |
| 850 | +{ |
| 851 | + struct rcar_gen3_chan *channel = rdev_get_drvdata(rdev); |
| 852 | + void __iomem *usb2_base = channel->base; |
| 853 | + struct device *dev = channel->dev; |
| 854 | + u32 vbus_ctrl_reg = USB2_VBCTRL; |
| 855 | + u32 val; |
| 856 | + int ret; |
| 857 | + |
| 858 | + ret = pm_runtime_resume_and_get(dev); |
| 859 | + if (ret < 0) { |
| 860 | + dev_warn(dev, "pm_runtime_get failed: %i\n", ret); |
| 861 | + return ret; |
| 862 | + } |
| 863 | + |
| 864 | + val = readl(usb2_base + vbus_ctrl_reg); |
| 865 | + |
| 866 | + pm_runtime_put_noidle(dev); |
| 867 | + dev_dbg(channel->dev, "%s: %08x\n", __func__, val); |
| 868 | + |
| 869 | + return (val & USB2_VBCTRL_VBOUT) ? 1 : 0; |
| 870 | +} |
| 871 | + |
| 872 | +static const struct regulator_ops rcar_gen3_phy_usb2_regulator_ops = { |
| 873 | + .enable = rcar_gen3_phy_usb2_regulator_enable, |
| 874 | + .disable = rcar_gen3_phy_usb2_regulator_disable, |
| 875 | + .is_enabled = rcar_gen3_phy_usb2_regulator_is_enabled, |
| 876 | +}; |
| 877 | + |
| 878 | +static const struct regulator_desc rcar_gen3_phy_usb2_regulator = { |
| 879 | + .name = "otg-vbus-regulator", |
| 880 | + .of_match = of_match_ptr("vbus-regulator"), |
| 881 | + .ops = &rcar_gen3_phy_usb2_regulator_ops, |
| 882 | + .type = REGULATOR_VOLTAGE, |
| 883 | + .owner = THIS_MODULE, |
| 884 | + .fixed_uV = 5000000, |
| 885 | + .n_voltages = 1, |
| 886 | +}; |
| 887 | + |
| 888 | +static void rcar_gen3_phy_usb2_vbus_disable_action(void *data) |
| 889 | +{ |
| 890 | + struct regulator *vbus = data; |
| 891 | + |
| 892 | + regulator_disable(vbus); |
| 893 | +} |
| 894 | + |
| 895 | +static int rcar_gen3_phy_usb2_vbus_regulator_get_exclusive_enable(struct rcar_gen3_chan *channel, |
| 896 | + bool enable) |
| 897 | +{ |
| 898 | + struct device *dev = channel->dev; |
| 899 | + int ret; |
| 900 | + |
| 901 | + channel->vbus = devm_regulator_get_exclusive(dev, "vbus"); |
| 902 | + if (IS_ERR(channel->vbus)) |
| 903 | + return PTR_ERR(channel->vbus); |
| 904 | + |
| 905 | + if (!enable) |
| 906 | + return 0; |
| 907 | + |
| 908 | + ret = regulator_enable(channel->vbus); |
| 909 | + if (ret) |
| 910 | + return ret; |
| 911 | + |
| 912 | + return devm_add_action_or_reset(dev, rcar_gen3_phy_usb2_vbus_disable_action, |
| 913 | + channel->vbus); |
| 914 | +} |
| 915 | + |
| 916 | +static int rcar_gen3_phy_usb2_vbus_regulator_register(struct rcar_gen3_chan *channel) |
| 917 | +{ |
| 918 | + struct device *dev = channel->dev; |
| 919 | + struct regulator_config rcfg = { .dev = dev, }; |
| 920 | + struct regulator_dev *rdev; |
| 921 | + bool enable = false; |
| 922 | + |
| 923 | + rcfg.of_node = of_get_available_child_by_name(dev->of_node, |
| 924 | + "vbus-regulator"); |
| 925 | + if (rcfg.of_node) { |
| 926 | + rcfg.driver_data = channel; |
| 927 | + rdev = devm_regulator_register(dev, &rcar_gen3_phy_usb2_regulator, |
| 928 | + &rcfg); |
| 929 | + of_node_put(rcfg.of_node); |
| 930 | + if (IS_ERR(rdev)) |
| 931 | + return dev_err_probe(dev, PTR_ERR(rdev), |
| 932 | + "Failed to create vbus-regulator\n"); |
| 933 | + |
| 934 | + channel->otg_internal_reg = true; |
| 935 | + enable = true; |
| 936 | + } |
| 937 | + |
| 938 | + return rcar_gen3_phy_usb2_vbus_regulator_get_exclusive_enable(channel, enable); |
| 939 | +} |
| 940 | + |
812 | 941 | static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) |
813 | 942 | { |
814 | 943 | struct device *dev = &pdev->dev; |
@@ -890,10 +1019,13 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) |
890 | 1019 | phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]); |
891 | 1020 | } |
892 | 1021 |
|
893 | | - if (channel->phy_data->no_adp_ctrl && channel->is_otg_channel) |
894 | | - channel->vbus = devm_regulator_get_exclusive(dev, "vbus"); |
895 | | - else |
| 1022 | + if (channel->phy_data->no_adp_ctrl && channel->is_otg_channel) { |
| 1023 | + ret = rcar_gen3_phy_usb2_vbus_regulator_register(channel); |
| 1024 | + if (ret) |
| 1025 | + return ret; |
| 1026 | + } else { |
896 | 1027 | channel->vbus = devm_regulator_get_optional(dev, "vbus"); |
| 1028 | + } |
897 | 1029 | if (IS_ERR(channel->vbus)) { |
898 | 1030 | if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) |
899 | 1031 | return PTR_ERR(channel->vbus); |
|
0 commit comments