Commit 74084844 authored by Matt Porter's avatar Matt Porter Committed by Felipe Balbi

usb: gadget: s3c-hsotg: enable generic phy support

Adds support for the generic PHY subsystem. Generic PHY
support is probed and then the driver falls back to checking
for an old style USB PHY and pdata if not found.
Signed-off-by: default avatarMatt Porter <mporter@linaro.org>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 0d33d825
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/phy/phy.h>
#include <linux/usb/phy.h>
#include <linux/usb/ch9.h> #include <linux/usb/ch9.h>
#include <linux/usb/gadget.h> #include <linux/usb/gadget.h>
...@@ -138,6 +140,7 @@ struct s3c_hsotg_ep { ...@@ -138,6 +140,7 @@ struct s3c_hsotg_ep {
* @dev: The parent device supplied to the probe function * @dev: The parent device supplied to the probe function
* @driver: USB gadget driver * @driver: USB gadget driver
* @phy: The otg phy transceiver structure for phy control. * @phy: The otg phy transceiver structure for phy control.
* @uphy: The otg phy transceiver structure for old USB phy control.
* @plat: The platform specific configuration data. This can be removed once * @plat: The platform specific configuration data. This can be removed once
* all SoCs support usb transceiver. * all SoCs support usb transceiver.
* @regs: The memory area mapped for accessing registers. * @regs: The memory area mapped for accessing registers.
...@@ -159,7 +162,8 @@ struct s3c_hsotg_ep { ...@@ -159,7 +162,8 @@ struct s3c_hsotg_ep {
struct s3c_hsotg { struct s3c_hsotg {
struct device *dev; struct device *dev;
struct usb_gadget_driver *driver; struct usb_gadget_driver *driver;
struct usb_phy *phy; struct phy *phy;
struct usb_phy *uphy;
struct s3c_hsotg_plat *plat; struct s3c_hsotg_plat *plat;
spinlock_t lock; spinlock_t lock;
...@@ -2909,8 +2913,11 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg) ...@@ -2909,8 +2913,11 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg)
dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev); dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
if (hsotg->phy) if (hsotg->phy) {
usb_phy_init(hsotg->phy); phy_init(hsotg->phy);
phy_power_on(hsotg->phy);
} else if (hsotg->uphy)
usb_phy_init(hsotg->uphy);
else if (hsotg->plat->phy_init) else if (hsotg->plat->phy_init)
hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
} }
...@@ -2926,8 +2933,11 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg) ...@@ -2926,8 +2933,11 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg)
{ {
struct platform_device *pdev = to_platform_device(hsotg->dev); struct platform_device *pdev = to_platform_device(hsotg->dev);
if (hsotg->phy) if (hsotg->phy) {
usb_phy_shutdown(hsotg->phy); phy_power_off(hsotg->phy);
phy_exit(hsotg->phy);
} else if (hsotg->uphy)
usb_phy_shutdown(hsotg->uphy);
else if (hsotg->plat->phy_exit) else if (hsotg->plat->phy_exit)
hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
} }
...@@ -3534,7 +3544,8 @@ static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg) ...@@ -3534,7 +3544,8 @@ static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg)
static int s3c_hsotg_probe(struct platform_device *pdev) static int s3c_hsotg_probe(struct platform_device *pdev)
{ {
struct s3c_hsotg_plat *plat = dev_get_platdata(&pdev->dev); struct s3c_hsotg_plat *plat = dev_get_platdata(&pdev->dev);
struct usb_phy *phy; struct phy *phy;
struct usb_phy *uphy;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct s3c_hsotg_ep *eps; struct s3c_hsotg_ep *eps;
struct s3c_hsotg *hsotg; struct s3c_hsotg *hsotg;
...@@ -3549,19 +3560,26 @@ static int s3c_hsotg_probe(struct platform_device *pdev) ...@@ -3549,19 +3560,26 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); /*
* Attempt to find a generic PHY, then look for an old style
* USB PHY, finally fall back to pdata
*/
phy = devm_phy_get(&pdev->dev, "usb2-phy");
if (IS_ERR(phy)) { if (IS_ERR(phy)) {
uphy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
if (IS_ERR(uphy)) {
/* Fallback for pdata */ /* Fallback for pdata */
plat = dev_get_platdata(&pdev->dev); plat = dev_get_platdata(&pdev->dev);
if (!plat) { if (!plat) {
dev_err(&pdev->dev, "no platform data or transceiver defined\n"); dev_err(&pdev->dev,
"no platform data or transceiver defined\n");
return -EPROBE_DEFER; return -EPROBE_DEFER;
} else {
hsotg->plat = plat;
} }
} else { hsotg->plat = plat;
} else
hsotg->uphy = uphy;
} else
hsotg->phy = phy; hsotg->phy = phy;
}
hsotg->dev = dev; hsotg->dev = dev;
...@@ -3628,6 +3646,9 @@ static int s3c_hsotg_probe(struct platform_device *pdev) ...@@ -3628,6 +3646,9 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
goto err_supplies; goto err_supplies;
} }
if (hsotg->phy)
phy_init(hsotg->phy);
/* usb phy enable */ /* usb phy enable */
s3c_hsotg_phy_enable(hsotg); s3c_hsotg_phy_enable(hsotg);
...@@ -3721,6 +3742,8 @@ static int s3c_hsotg_remove(struct platform_device *pdev) ...@@ -3721,6 +3742,8 @@ static int s3c_hsotg_remove(struct platform_device *pdev)
} }
s3c_hsotg_phy_disable(hsotg); s3c_hsotg_phy_disable(hsotg);
if (hsotg->phy)
phy_exit(hsotg->phy);
clk_disable_unprepare(hsotg->clk); clk_disable_unprepare(hsotg->clk);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment