summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2013-03-12 07:24:25 -0400
committerFelipe Balbi <balbi@ti.com>2013-03-18 05:15:12 -0400
commit0eba387973f521e57f00584e5e840e5328a61dda (patch)
treeea216d8038e2982dd79c8cc3b34cf9db116ed129
parent90f4232f31f087f86667da03b1a4f3c90a32cb4a (diff)
usb: phy: nop: Add device tree support and binding information
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>
-rw-r--r--Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt34
-rw-r--r--drivers/usb/otg/nop-usb-xceiv.c35
2 files changed, 61 insertions, 8 deletions
diff --git a/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt b/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt
new file mode 100644
index 000000000000..d7e272671c7e
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt
@@ -0,0 +1,34 @@
1USB NOP PHY
2
3Required properties:
4- compatible: should be usb-nop-xceiv
5
6Optional properties:
7- clocks: phandle to the PHY clock. Use as per Documentation/devicetree
8 /bindings/clock/clock-bindings.txt
9 This property is required if clock-frequency is specified.
10
11- clock-names: Should be "main_clk"
12
13- clock-frequency: the clock frequency (in Hz) that the PHY clock must
14 be configured to.
15
16- vcc-supply: phandle to the regulator that provides RESET to the PHY.
17
18- reset-supply: phandle to the regulator that provides power to the PHY.
19
20Example:
21
22 hsusb1_phy {
23 compatible = "usb-nop-xceiv";
24 clock-frequency = <19200000>;
25 clocks = <&osc 0>;
26 clock-names = "main_clk";
27 vcc-supply = <&hsusb1_vcc_regulator>;
28 reset-supply = <&hsusb1_reset_regulator>;
29 };
30
31hsusb1_phy is a NOP USB PHY device that gets its clock from an oscillator
32and expects that clock to be configured to 19.2MHz by the NOP PHY driver.
33hsusb1_vcc_regulator provides power to the PHY and hsusb1_reset_regulator
34controls RESET.
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
index fe7a46001854..b26b1c29194e 100644
--- a/drivers/usb/otg/nop-usb-xceiv.c
+++ b/drivers/usb/otg/nop-usb-xceiv.c
@@ -34,13 +34,14 @@
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/clk.h> 35#include <linux/clk.h>
36#include <linux/regulator/consumer.h> 36#include <linux/regulator/consumer.h>
37#include <linux/of.h>
37 38
38struct nop_usb_xceiv { 39struct nop_usb_xceiv {
39 struct usb_phy phy; 40 struct usb_phy phy;
40 struct device *dev; 41 struct device *dev;
41 struct clk *clk; 42 struct clk *clk;
42 struct regulator *vcc; 43 struct regulator *vcc;
43 struct regulator *reset; 44 struct regulator *reset;
44}; 45};
45 46
46static struct platform_device *pd; 47static struct platform_device *pd;
@@ -140,10 +141,12 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)
140 141
141static int nop_usb_xceiv_probe(struct platform_device *pdev) 142static int nop_usb_xceiv_probe(struct platform_device *pdev)
142{ 143{
144 struct device *dev = &pdev->dev;
143 struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data; 145 struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data;
144 struct nop_usb_xceiv *nop; 146 struct nop_usb_xceiv *nop;
145 enum usb_phy_type type = USB_PHY_TYPE_USB2; 147 enum usb_phy_type type = USB_PHY_TYPE_USB2;
146 int err; 148 int err;
149 u32 clk_rate = 0;
147 150
148 nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL); 151 nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL);
149 if (!nop) 152 if (!nop)
@@ -154,8 +157,16 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev)
154 if (!nop->phy.otg) 157 if (!nop->phy.otg)
155 return -ENOMEM; 158 return -ENOMEM;
156 159
157 if (pdata) 160 if (dev->of_node) {
161 struct device_node *node = dev->of_node;
162
163 if (of_property_read_u32(node, "clock-frequency", &clk_rate))
164 clk_rate = 0;
165
166 } else if (pdata) {
158 type = pdata->type; 167 type = pdata->type;
168 clk_rate = pdata->clk_rate;
169 }
159 170
160 nop->clk = devm_clk_get(&pdev->dev, "main_clk"); 171 nop->clk = devm_clk_get(&pdev->dev, "main_clk");
161 if (IS_ERR(nop->clk)) { 172 if (IS_ERR(nop->clk)) {
@@ -163,8 +174,8 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev)
163 PTR_ERR(nop->clk)); 174 PTR_ERR(nop->clk));
164 } 175 }
165 176
166 if (!IS_ERR(nop->clk) && pdata && pdata->clk_rate) { 177 if (!IS_ERR(nop->clk) && clk_rate) {
167 err = clk_set_rate(nop->clk, pdata->clk_rate); 178 err = clk_set_rate(nop->clk, clk_rate);
168 if (err) { 179 if (err) {
169 dev_err(&pdev->dev, "Error setting clock rate\n"); 180 dev_err(&pdev->dev, "Error setting clock rate\n");
170 return err; 181 return err;
@@ -237,12 +248,20 @@ static int nop_usb_xceiv_remove(struct platform_device *pdev)
237 return 0; 248 return 0;
238} 249}
239 250
251static const struct of_device_id nop_xceiv_dt_ids[] = {
252 { .compatible = "usb-nop-xceiv" },
253 { }
254};
255
256MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids);
257
240static struct platform_driver nop_usb_xceiv_driver = { 258static struct platform_driver nop_usb_xceiv_driver = {
241 .probe = nop_usb_xceiv_probe, 259 .probe = nop_usb_xceiv_probe,
242 .remove = nop_usb_xceiv_remove, 260 .remove = nop_usb_xceiv_remove,
243 .driver = { 261 .driver = {
244 .name = "nop_usb_xceiv", 262 .name = "nop_usb_xceiv",
245 .owner = THIS_MODULE, 263 .owner = THIS_MODULE,
264 .of_match_table = of_match_ptr(nop_xceiv_dt_ids),
246 }, 265 },
247}; 266};
248 267