1 // SPDX-License-Identifier: GPL-1.0+ 2 /* 3 * Renesas USB driver R-Car Gen. 2 initialization and power control 4 * 5 * Copyright (C) 2014 Ulrich Hecht 6 */ 7 8 #include <linux/gpio.h> 9 #include <linux/of_gpio.h> 10 #include <linux/phy/phy.h> 11 #include <linux/usb/phy.h> 12 #include "common.h" 13 #include "rcar2.h" 14 15 static int usbhs_rcar2_hardware_init(struct platform_device *pdev) 16 { 17 struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); 18 19 if (IS_ENABLED(CONFIG_GENERIC_PHY)) { 20 struct phy *phy = phy_get(&pdev->dev, "usb"); 21 22 if (IS_ERR(phy)) 23 return PTR_ERR(phy); 24 25 priv->phy = phy; 26 return 0; 27 } 28 29 if (IS_ENABLED(CONFIG_USB_PHY)) { 30 struct usb_phy *usb_phy = usb_get_phy_dev(&pdev->dev, 0); 31 32 if (IS_ERR(usb_phy)) 33 return PTR_ERR(usb_phy); 34 35 priv->usb_phy = usb_phy; 36 return 0; 37 } 38 39 return -ENXIO; 40 } 41 42 static int usbhs_rcar2_hardware_exit(struct platform_device *pdev) 43 { 44 struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); 45 46 if (priv->phy) { 47 phy_put(priv->phy); 48 priv->phy = NULL; 49 } 50 51 if (priv->usb_phy) { 52 usb_put_phy(priv->usb_phy); 53 priv->usb_phy = NULL; 54 } 55 56 return 0; 57 } 58 59 static int usbhs_rcar2_power_ctrl(struct platform_device *pdev, 60 void __iomem *base, int enable) 61 { 62 struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); 63 int retval = -ENODEV; 64 65 if (priv->phy) { 66 if (enable) { 67 retval = phy_init(priv->phy); 68 69 if (!retval) 70 retval = phy_power_on(priv->phy); 71 } else { 72 phy_power_off(priv->phy); 73 phy_exit(priv->phy); 74 retval = 0; 75 } 76 } 77 78 if (priv->usb_phy) { 79 if (enable) { 80 retval = usb_phy_init(priv->usb_phy); 81 82 if (!retval) 83 retval = usb_phy_set_suspend(priv->usb_phy, 0); 84 } else { 85 usb_phy_set_suspend(priv->usb_phy, 1); 86 usb_phy_shutdown(priv->usb_phy); 87 retval = 0; 88 } 89 } 90 91 return retval; 92 } 93 94 static int usbhs_rcar2_get_id(struct platform_device *pdev) 95 { 96 return USBHS_GADGET; 97 } 98 99 const struct renesas_usbhs_platform_callback usbhs_rcar2_ops = { 100 .hardware_init = usbhs_rcar2_hardware_init, 101 .hardware_exit = usbhs_rcar2_hardware_exit, 102 .power_ctrl = usbhs_rcar2_power_ctrl, 103 .get_id = usbhs_rcar2_get_id, 104 }; 105