diff options
author | Roger Quadros <rogerq@ti.com> | 2013-10-03 11:12:31 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-10-03 18:47:30 -0400 |
commit | 6cb9310a3290beb8c0d31703a2e76b90a10b4ca0 (patch) | |
tree | c748ea598aa00e38474a483281fee7093e1efd59 /drivers/usb/phy | |
parent | 4fd06af96b9397fc54eb6b1a013a60c34693eef0 (diff) |
usb: phy: omap: Add new device types and remove omap_control_usb3_phy_power()
Add support for new device types and in the process rid of "ti,type"
device tree property. The correct type of device will be determined
from the compatible string instead.
Introduce a compatible string for each device type. At the moment
we support 4 types OTGHS, USB2, PIPE3 (e.g. USB3) and DRA7USB2.
Update DT binding information to reflect these changes.
Also get rid of omap_control_usb3_phy_power(). Just one function
i.e. omap_control_usb_phy_power() will now take care of all PHY types.
Signed-off-by: Roger Quadros <rogerq@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/phy')
-rw-r--r-- | drivers/usb/phy/phy-omap-control.c | 173 | ||||
-rw-r--r-- | drivers/usb/phy/phy-omap-usb3.c | 6 |
2 files changed, 103 insertions, 76 deletions
diff --git a/drivers/usb/phy/phy-omap-control.c b/drivers/usb/phy/phy-omap-control.c index 977259252a8e..1c8a7c5ccb9b 100644 --- a/drivers/usb/phy/phy-omap-control.c +++ b/drivers/usb/phy/phy-omap-control.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/of.h> | 22 | #include <linux/of.h> |
23 | #include <linux/of_device.h> | ||
23 | #include <linux/err.h> | 24 | #include <linux/err.h> |
24 | #include <linux/io.h> | 25 | #include <linux/io.h> |
25 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
@@ -46,61 +47,70 @@ struct device *omap_get_control_dev(void) | |||
46 | EXPORT_SYMBOL_GPL(omap_get_control_dev); | 47 | EXPORT_SYMBOL_GPL(omap_get_control_dev); |
47 | 48 | ||
48 | /** | 49 | /** |
49 | * omap_control_usb3_phy_power - power on/off the serializer using control | 50 | * omap_control_usb_phy_power - power on/off the phy using control module reg |
50 | * module | ||
51 | * @dev: the control module device | 51 | * @dev: the control module device |
52 | * @on: 0 to off and 1 to on based on powering on or off the PHY | 52 | * @on: 0 or 1, based on powering on or off the PHY |
53 | * | ||
54 | * usb3 PHY driver should call this API to power on or off the PHY. | ||
55 | */ | 53 | */ |
56 | void omap_control_usb3_phy_power(struct device *dev, bool on) | 54 | void omap_control_usb_phy_power(struct device *dev, int on) |
57 | { | 55 | { |
58 | u32 val; | 56 | u32 val; |
59 | unsigned long rate; | 57 | unsigned long rate; |
60 | struct omap_control_usb *control_usb = dev_get_drvdata(dev); | 58 | struct omap_control_usb *control_usb; |
61 | 59 | ||
62 | if (control_usb->type != OMAP_CTRL_DEV_TYPE2) | 60 | if (IS_ERR(dev) || !dev) { |
61 | pr_err("%s: invalid device\n", __func__); | ||
63 | return; | 62 | return; |
63 | } | ||
64 | 64 | ||
65 | rate = clk_get_rate(control_usb->sys_clk); | 65 | control_usb = dev_get_drvdata(dev); |
66 | rate = rate/1000000; | 66 | if (!control_usb) { |
67 | 67 | dev_err(dev, "%s: invalid control usb device\n", __func__); | |
68 | val = readl(control_usb->phy_power); | 68 | return; |
69 | |||
70 | if (on) { | ||
71 | val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK | | ||
72 | OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK); | ||
73 | val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON << | ||
74 | OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; | ||
75 | val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT; | ||
76 | } else { | ||
77 | val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK; | ||
78 | val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF << | ||
79 | OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; | ||
80 | } | 69 | } |
81 | 70 | ||
82 | writel(val, control_usb->phy_power); | 71 | if (control_usb->type == OMAP_CTRL_TYPE_OTGHS) |
83 | } | 72 | return; |
84 | EXPORT_SYMBOL_GPL(omap_control_usb3_phy_power); | ||
85 | 73 | ||
86 | /** | 74 | val = readl(control_usb->power); |
87 | * omap_control_usb_phy_power - power on/off the phy using control module reg | 75 | |
88 | * @dev: the control module device | 76 | switch (control_usb->type) { |
89 | * @on: 0 or 1, based on powering on or off the PHY | 77 | case OMAP_CTRL_TYPE_USB2: |
90 | */ | 78 | if (on) |
91 | void omap_control_usb_phy_power(struct device *dev, int on) | 79 | val &= ~OMAP_CTRL_DEV_PHY_PD; |
92 | { | 80 | else |
93 | u32 val; | 81 | val |= OMAP_CTRL_DEV_PHY_PD; |
94 | struct omap_control_usb *control_usb = dev_get_drvdata(dev); | 82 | break; |
95 | 83 | ||
96 | val = readl(control_usb->dev_conf); | 84 | case OMAP_CTRL_TYPE_PIPE3: |
85 | rate = clk_get_rate(control_usb->sys_clk); | ||
86 | rate = rate/1000000; | ||
87 | |||
88 | if (on) { | ||
89 | val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK | | ||
90 | OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK); | ||
91 | val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON << | ||
92 | OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; | ||
93 | val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT; | ||
94 | } else { | ||
95 | val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK; | ||
96 | val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF << | ||
97 | OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; | ||
98 | } | ||
99 | break; | ||
97 | 100 | ||
98 | if (on) | 101 | case OMAP_CTRL_TYPE_DRA7USB2: |
99 | val &= ~OMAP_CTRL_DEV_PHY_PD; | 102 | if (on) |
100 | else | 103 | val &= ~OMAP_CTRL_USB2_PHY_PD; |
101 | val |= OMAP_CTRL_DEV_PHY_PD; | 104 | else |
105 | val |= OMAP_CTRL_USB2_PHY_PD; | ||
106 | break; | ||
107 | default: | ||
108 | dev_err(dev, "%s: type %d not recognized\n", | ||
109 | __func__, control_usb->type); | ||
110 | break; | ||
111 | } | ||
102 | 112 | ||
103 | writel(val, control_usb->dev_conf); | 113 | writel(val, control_usb->power); |
104 | } | 114 | } |
105 | EXPORT_SYMBOL_GPL(omap_control_usb_phy_power); | 115 | EXPORT_SYMBOL_GPL(omap_control_usb_phy_power); |
106 | 116 | ||
@@ -172,7 +182,7 @@ void omap_control_usb_set_mode(struct device *dev, | |||
172 | { | 182 | { |
173 | struct omap_control_usb *ctrl_usb; | 183 | struct omap_control_usb *ctrl_usb; |
174 | 184 | ||
175 | if (IS_ERR(dev) || control_usb->type != OMAP_CTRL_DEV_TYPE1) | 185 | if (IS_ERR(dev) || control_usb->type != OMAP_CTRL_TYPE_OTGHS) |
176 | return; | 186 | return; |
177 | 187 | ||
178 | ctrl_usb = dev_get_drvdata(dev); | 188 | ctrl_usb = dev_get_drvdata(dev); |
@@ -193,10 +203,45 @@ void omap_control_usb_set_mode(struct device *dev, | |||
193 | } | 203 | } |
194 | EXPORT_SYMBOL_GPL(omap_control_usb_set_mode); | 204 | EXPORT_SYMBOL_GPL(omap_control_usb_set_mode); |
195 | 205 | ||
206 | #ifdef CONFIG_OF | ||
207 | |||
208 | static const enum omap_control_usb_type otghs_data = OMAP_CTRL_TYPE_OTGHS; | ||
209 | static const enum omap_control_usb_type usb2_data = OMAP_CTRL_TYPE_USB2; | ||
210 | static const enum omap_control_usb_type pipe3_data = OMAP_CTRL_TYPE_PIPE3; | ||
211 | static const enum omap_control_usb_type dra7usb2_data = OMAP_CTRL_TYPE_DRA7USB2; | ||
212 | |||
213 | static const struct of_device_id omap_control_usb_id_table[] = { | ||
214 | { | ||
215 | .compatible = "ti,control-phy-otghs", | ||
216 | .data = &otghs_data, | ||
217 | }, | ||
218 | { | ||
219 | .compatible = "ti,control-phy-usb2", | ||
220 | .data = &usb2_data, | ||
221 | }, | ||
222 | { | ||
223 | .compatible = "ti,control-phy-pipe3", | ||
224 | .data = &pipe3_data, | ||
225 | }, | ||
226 | { | ||
227 | .compatible = "ti,control-phy-dra7usb2", | ||
228 | .data = &dra7usb2_data, | ||
229 | }, | ||
230 | {}, | ||
231 | }; | ||
232 | MODULE_DEVICE_TABLE(of, omap_control_usb_id_table); | ||
233 | #endif | ||
234 | |||
235 | |||
196 | static int omap_control_usb_probe(struct platform_device *pdev) | 236 | static int omap_control_usb_probe(struct platform_device *pdev) |
197 | { | 237 | { |
198 | struct resource *res; | 238 | struct resource *res; |
199 | struct device_node *np = pdev->dev.of_node; | 239 | const struct of_device_id *of_id; |
240 | |||
241 | of_id = of_match_device(of_match_ptr(omap_control_usb_id_table), | ||
242 | &pdev->dev); | ||
243 | if (!of_id) | ||
244 | return -EINVAL; | ||
200 | 245 | ||
201 | control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb), | 246 | control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb), |
202 | GFP_KERNEL); | 247 | GFP_KERNEL); |
@@ -205,36 +250,27 @@ static int omap_control_usb_probe(struct platform_device *pdev) | |||
205 | return -ENOMEM; | 250 | return -ENOMEM; |
206 | } | 251 | } |
207 | 252 | ||
208 | if (np) | 253 | control_usb->dev = &pdev->dev; |
209 | of_property_read_u32(np, "ti,type", &control_usb->type); | 254 | control_usb->type = *(enum omap_control_usb_type *)of_id->data; |
210 | else | ||
211 | return -EINVAL; /* We only support DT boot */ | ||
212 | |||
213 | control_usb->dev = &pdev->dev; | ||
214 | 255 | ||
215 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 256 | if (control_usb->type == OMAP_CTRL_TYPE_OTGHS) { |
216 | "control_dev_conf"); | ||
217 | control_usb->dev_conf = devm_ioremap_resource(&pdev->dev, res); | ||
218 | if (IS_ERR(control_usb->dev_conf)) | ||
219 | return PTR_ERR(control_usb->dev_conf); | ||
220 | |||
221 | if (control_usb->type == OMAP_CTRL_DEV_TYPE1) { | ||
222 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 257 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
223 | "otghs_control"); | 258 | "otghs_control"); |
224 | control_usb->otghs_control = devm_ioremap_resource( | 259 | control_usb->otghs_control = devm_ioremap_resource( |
225 | &pdev->dev, res); | 260 | &pdev->dev, res); |
226 | if (IS_ERR(control_usb->otghs_control)) | 261 | if (IS_ERR(control_usb->otghs_control)) |
227 | return PTR_ERR(control_usb->otghs_control); | 262 | return PTR_ERR(control_usb->otghs_control); |
228 | } | 263 | } else { |
229 | |||
230 | if (control_usb->type == OMAP_CTRL_DEV_TYPE2) { | ||
231 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 264 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
232 | "phy_power_usb"); | 265 | "power"); |
233 | control_usb->phy_power = devm_ioremap_resource( | 266 | control_usb->power = devm_ioremap_resource(&pdev->dev, res); |
234 | &pdev->dev, res); | 267 | if (IS_ERR(control_usb->power)) { |
235 | if (IS_ERR(control_usb->phy_power)) | 268 | dev_err(&pdev->dev, "Couldn't get power register\n"); |
236 | return PTR_ERR(control_usb->phy_power); | 269 | return PTR_ERR(control_usb->power); |
270 | } | ||
271 | } | ||
237 | 272 | ||
273 | if (control_usb->type == OMAP_CTRL_TYPE_PIPE3) { | ||
238 | control_usb->sys_clk = devm_clk_get(control_usb->dev, | 274 | control_usb->sys_clk = devm_clk_get(control_usb->dev, |
239 | "sys_clkin"); | 275 | "sys_clkin"); |
240 | if (IS_ERR(control_usb->sys_clk)) { | 276 | if (IS_ERR(control_usb->sys_clk)) { |
@@ -243,20 +279,11 @@ static int omap_control_usb_probe(struct platform_device *pdev) | |||
243 | } | 279 | } |
244 | } | 280 | } |
245 | 281 | ||
246 | |||
247 | dev_set_drvdata(control_usb->dev, control_usb); | 282 | dev_set_drvdata(control_usb->dev, control_usb); |
248 | 283 | ||
249 | return 0; | 284 | return 0; |
250 | } | 285 | } |
251 | 286 | ||
252 | #ifdef CONFIG_OF | ||
253 | static const struct of_device_id omap_control_usb_id_table[] = { | ||
254 | { .compatible = "ti,omap-control-usb" }, | ||
255 | {} | ||
256 | }; | ||
257 | MODULE_DEVICE_TABLE(of, omap_control_usb_id_table); | ||
258 | #endif | ||
259 | |||
260 | static struct platform_driver omap_control_usb_driver = { | 287 | static struct platform_driver omap_control_usb_driver = { |
261 | .probe = omap_control_usb_probe, | 288 | .probe = omap_control_usb_probe, |
262 | .driver = { | 289 | .driver = { |
diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/usb/phy/phy-omap-usb3.c index 4e8a0405f956..0824be42cd18 100644 --- a/drivers/usb/phy/phy-omap-usb3.c +++ b/drivers/usb/phy/phy-omap-usb3.c | |||
@@ -100,7 +100,7 @@ static int omap_usb3_suspend(struct usb_phy *x, int suspend) | |||
100 | udelay(1); | 100 | udelay(1); |
101 | } while (--timeout); | 101 | } while (--timeout); |
102 | 102 | ||
103 | omap_control_usb3_phy_power(phy->control_dev, 0); | 103 | omap_control_usb_phy_power(phy->control_dev, 0); |
104 | 104 | ||
105 | phy->is_suspended = 1; | 105 | phy->is_suspended = 1; |
106 | } else if (!suspend && phy->is_suspended) { | 106 | } else if (!suspend && phy->is_suspended) { |
@@ -189,7 +189,7 @@ static int omap_usb3_init(struct usb_phy *x) | |||
189 | if (ret) | 189 | if (ret) |
190 | return ret; | 190 | return ret; |
191 | 191 | ||
192 | omap_control_usb3_phy_power(phy->control_dev, 1); | 192 | omap_control_usb_phy_power(phy->control_dev, 1); |
193 | 193 | ||
194 | return 0; | 194 | return 0; |
195 | } | 195 | } |
@@ -245,7 +245,7 @@ static int omap_usb3_probe(struct platform_device *pdev) | |||
245 | return -ENODEV; | 245 | return -ENODEV; |
246 | } | 246 | } |
247 | 247 | ||
248 | omap_control_usb3_phy_power(phy->control_dev, 0); | 248 | omap_control_usb_phy_power(phy->control_dev, 0); |
249 | usb_add_phy_dev(&phy->phy); | 249 | usb_add_phy_dev(&phy->phy); |
250 | 250 | ||
251 | platform_set_drvdata(pdev, phy); | 251 | platform_set_drvdata(pdev, phy); |