Skip to content

Commit

Permalink
usb: phy: nop: Add device tree support and binding information
Browse files Browse the repository at this point in the history
The PHY clock, clock rate, VCC regulator and RESET regulator
can now be provided via device tree.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
  • Loading branch information
Roger Quadros authored and Felipe Balbi committed Mar 18, 2013
1 parent 90f4232 commit 0eba387
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 8 deletions.
34 changes: 34 additions & 0 deletions Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
USB NOP PHY

Required properties:
- compatible: should be usb-nop-xceiv

Optional properties:
- clocks: phandle to the PHY clock. Use as per Documentation/devicetree
/bindings/clock/clock-bindings.txt
This property is required if clock-frequency is specified.

- clock-names: Should be "main_clk"

- clock-frequency: the clock frequency (in Hz) that the PHY clock must
be configured to.

- vcc-supply: phandle to the regulator that provides RESET to the PHY.

- reset-supply: phandle to the regulator that provides power to the PHY.

Example:

hsusb1_phy {
compatible = "usb-nop-xceiv";
clock-frequency = <19200000>;
clocks = <&osc 0>;
clock-names = "main_clk";
vcc-supply = <&hsusb1_vcc_regulator>;
reset-supply = <&hsusb1_reset_regulator>;
};

hsusb1_phy is a NOP USB PHY device that gets its clock from an oscillator
and expects that clock to be configured to 19.2MHz by the NOP PHY driver.
hsusb1_vcc_regulator provides power to the PHY and hsusb1_reset_regulator
controls RESET.
35 changes: 27 additions & 8 deletions drivers/usb/otg/nop-usb-xceiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/regulator/consumer.h>
#include <linux/of.h>

struct nop_usb_xceiv {
struct usb_phy phy;
struct device *dev;
struct clk *clk;
struct regulator *vcc;
struct regulator *reset;
struct usb_phy phy;
struct device *dev;
struct clk *clk;
struct regulator *vcc;
struct regulator *reset;
};

static struct platform_device *pd;
Expand Down Expand Up @@ -140,10 +141,12 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)

static int nop_usb_xceiv_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data;
struct nop_usb_xceiv *nop;
enum usb_phy_type type = USB_PHY_TYPE_USB2;
int err;
u32 clk_rate = 0;

nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL);
if (!nop)
Expand All @@ -154,17 +157,25 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev)
if (!nop->phy.otg)
return -ENOMEM;

if (pdata)
if (dev->of_node) {
struct device_node *node = dev->of_node;

if (of_property_read_u32(node, "clock-frequency", &clk_rate))
clk_rate = 0;

} else if (pdata) {
type = pdata->type;
clk_rate = pdata->clk_rate;
}

nop->clk = devm_clk_get(&pdev->dev, "main_clk");
if (IS_ERR(nop->clk)) {
dev_dbg(&pdev->dev, "Can't get phy clock: %ld\n",
PTR_ERR(nop->clk));
}

if (!IS_ERR(nop->clk) && pdata && pdata->clk_rate) {
err = clk_set_rate(nop->clk, pdata->clk_rate);
if (!IS_ERR(nop->clk) && clk_rate) {
err = clk_set_rate(nop->clk, clk_rate);
if (err) {
dev_err(&pdev->dev, "Error setting clock rate\n");
return err;
Expand Down Expand Up @@ -237,12 +248,20 @@ static int nop_usb_xceiv_remove(struct platform_device *pdev)
return 0;
}

static const struct of_device_id nop_xceiv_dt_ids[] = {
{ .compatible = "usb-nop-xceiv" },
{ }
};

MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids);

static struct platform_driver nop_usb_xceiv_driver = {
.probe = nop_usb_xceiv_probe,
.remove = nop_usb_xceiv_remove,
.driver = {
.name = "nop_usb_xceiv",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(nop_xceiv_dt_ids),
},
};

Expand Down

0 comments on commit 0eba387

Please sign in to comment.