mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 14:44:10 +08:00
phy: exynos-usb2: add vbus regulator support
Exynos USB2 PHY has separate power supply, which is usually provided by VBUS regulator. This patch adds support for it. VBUS regulator is optional, to keep compatibility with boards, which have VBUS provided from some always-on power source. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
This commit is contained in:
parent
6ff33f3902
commit
a007ddbaef
@ -44,6 +44,9 @@ Required properties:
|
|||||||
- the "ref" clock is used to get the rate of the clock provided to the
|
- the "ref" clock is used to get the rate of the clock provided to the
|
||||||
PHY module
|
PHY module
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- vbus-supply: power-supply phandle for vbus power source
|
||||||
|
|
||||||
The first phandle argument in the PHY specifier identifies the PHY, its
|
The first phandle argument in the PHY specifier identifies the PHY, its
|
||||||
meaning is compatible dependent. For the currently supported SoCs (Exynos 4210
|
meaning is compatible dependent. For the currently supported SoCs (Exynos 4210
|
||||||
and Exynos 4212) it is as follows:
|
and Exynos 4212) it is as follows:
|
||||||
|
@ -27,6 +27,13 @@ static int samsung_usb2_phy_power_on(struct phy *phy)
|
|||||||
|
|
||||||
dev_dbg(drv->dev, "Request to power_on \"%s\" usb phy\n",
|
dev_dbg(drv->dev, "Request to power_on \"%s\" usb phy\n",
|
||||||
inst->cfg->label);
|
inst->cfg->label);
|
||||||
|
|
||||||
|
if (drv->vbus) {
|
||||||
|
ret = regulator_enable(drv->vbus);
|
||||||
|
if (ret)
|
||||||
|
goto err_regulator;
|
||||||
|
}
|
||||||
|
|
||||||
ret = clk_prepare_enable(drv->clk);
|
ret = clk_prepare_enable(drv->clk);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_main_clk;
|
goto err_main_clk;
|
||||||
@ -48,6 +55,9 @@ err_power_on:
|
|||||||
err_instance_clk:
|
err_instance_clk:
|
||||||
clk_disable_unprepare(drv->clk);
|
clk_disable_unprepare(drv->clk);
|
||||||
err_main_clk:
|
err_main_clk:
|
||||||
|
if (drv->vbus)
|
||||||
|
regulator_disable(drv->vbus);
|
||||||
|
err_regulator:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +65,7 @@ static int samsung_usb2_phy_power_off(struct phy *phy)
|
|||||||
{
|
{
|
||||||
struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy);
|
struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy);
|
||||||
struct samsung_usb2_phy_driver *drv = inst->drv;
|
struct samsung_usb2_phy_driver *drv = inst->drv;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n",
|
dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n",
|
||||||
inst->cfg->label);
|
inst->cfg->label);
|
||||||
@ -68,7 +78,10 @@ static int samsung_usb2_phy_power_off(struct phy *phy)
|
|||||||
}
|
}
|
||||||
clk_disable_unprepare(drv->ref_clk);
|
clk_disable_unprepare(drv->ref_clk);
|
||||||
clk_disable_unprepare(drv->clk);
|
clk_disable_unprepare(drv->clk);
|
||||||
return 0;
|
if (drv->vbus)
|
||||||
|
ret = regulator_disable(drv->vbus);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct phy_ops samsung_usb2_phy_ops = {
|
static const struct phy_ops samsung_usb2_phy_ops = {
|
||||||
@ -203,6 +216,14 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drv->vbus = devm_regulator_get(dev, "vbus");
|
||||||
|
if (IS_ERR(drv->vbus)) {
|
||||||
|
ret = PTR_ERR(drv->vbus);
|
||||||
|
if (ret == -EPROBE_DEFER)
|
||||||
|
return ret;
|
||||||
|
drv->vbus = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < drv->cfg->num_phys; i++) {
|
for (i = 0; i < drv->cfg->num_phys; i++) {
|
||||||
char *label = drv->cfg->phys[i].label;
|
char *label = drv->cfg->phys[i].label;
|
||||||
struct samsung_usb2_phy_instance *p = &drv->instances[i];
|
struct samsung_usb2_phy_instance *p = &drv->instances[i];
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/regulator/consumer.h>
|
||||||
|
|
||||||
#define KHZ 1000
|
#define KHZ 1000
|
||||||
#define MHZ (KHZ * KHZ)
|
#define MHZ (KHZ * KHZ)
|
||||||
@ -37,6 +38,7 @@ struct samsung_usb2_phy_driver {
|
|||||||
const struct samsung_usb2_phy_config *cfg;
|
const struct samsung_usb2_phy_config *cfg;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
struct clk *ref_clk;
|
struct clk *ref_clk;
|
||||||
|
struct regulator *vbus;
|
||||||
unsigned long ref_rate;
|
unsigned long ref_rate;
|
||||||
u32 ref_reg_val;
|
u32 ref_reg_val;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
Loading…
Reference in New Issue
Block a user