Lines Matching +full:ganged +full:- +full:port +full:- +full:switching
1 // SPDX-License-Identifier: GPL-1.0+
6 * (C) Copyright 2000-2005 David Brownell
7 * (C) Copyright 2002 Hewlett-Packard Company
13 * and on ohci-sa1111.c by Christopher Hoover <[email protected]>
19 #include <linux/dma-mapping.h>
28 #include <linux/platform_data/usb-omap1.h>
29 #include <linux/soc/ti/omap1-usb.h>
30 #include <linux/soc/ti/omap1-mux.h>
31 #include <linux/soc/ti/omap1-soc.h>
32 #include <linux/soc/ti/omap1-io.h>
40 #include <asm/mach-types.h>
51 static const char hcd_name[] = "ohci-omap";
55 ((struct ohci_omap_priv *)hcd_to_ohci(h)->priv)
60 clk_enable(priv->usb_dc_ck); in omap_ohci_clock_power()
61 clk_enable(priv->usb_host_ck); in omap_ohci_clock_power()
65 clk_disable(priv->usb_host_ck); in omap_ohci_clock_power()
66 clk_disable(priv->usb_dc_ck); in omap_ohci_clock_power()
73 const unsigned port = hcd->self.otg_port - 1; in start_hnp() local
77 otg_start_hnp(hcd->usb_phy->otg); in start_hnp()
80 hcd->usb_phy->otg->state = OTG_STATE_A_SUSPEND; in start_hnp()
81 writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]); in start_hnp()
88 /*-------------------------------------------------------------------------*/
93 struct omap_usb_config *config = dev_get_platdata(hcd->self.controller); in ohci_omap_reset()
95 int need_transceiver = (config->otg != 0); in ohci_omap_reset()
98 dev_dbg(hcd->self.controller, "starting USB Controller\n"); in ohci_omap_reset()
100 if (config->otg) { in ohci_omap_reset()
101 hcd->self.otg_port = config->otg; in ohci_omap_reset()
103 hcd->power_budget = 8; in ohci_omap_reset()
107 if (config->ocpi_enable) in ohci_omap_reset()
108 config->ocpi_enable(); in ohci_omap_reset()
111 hcd->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2); in ohci_omap_reset()
112 if (!IS_ERR_OR_NULL(hcd->usb_phy)) { in ohci_omap_reset()
113 int status = otg_set_host(hcd->usb_phy->otg, in ohci_omap_reset()
114 &ohci_to_hcd(ohci)->self); in ohci_omap_reset()
115 dev_dbg(hcd->self.controller, "init %s phy, status %d\n", in ohci_omap_reset()
116 hcd->usb_phy->label, status); in ohci_omap_reset()
118 usb_put_phy(hcd->usb_phy); in ohci_omap_reset()
122 return -EPROBE_DEFER; in ohci_omap_reset()
124 hcd->skip_phy_initialization = 1; in ohci_omap_reset()
125 ohci->start_hnp = start_hnp; in ohci_omap_reset()
130 if (config->lb_reset) in ohci_omap_reset()
131 config->lb_reset(); in ohci_omap_reset()
137 if (config->otg || config->rwc) { in ohci_omap_reset()
138 ohci->hc_control = OHCI_CTRL_RWC; in ohci_omap_reset()
139 writel(OHCI_CTRL_RWC, &ohci->regs->control); in ohci_omap_reset()
142 /* board-specific power switching and overcurrent support */ in ohci_omap_reset()
146 /* power switching (ganged by default) */ in ohci_omap_reset()
149 /* TPS2045 switch for internal transceiver (port 1) */ in ohci_omap_reset()
151 ohci_to_hcd(ohci)->power_budget = 250; in ohci_omap_reset()
161 ohci_writel(ohci, rh, &ohci->regs->roothub.a); in ohci_omap_reset()
162 ohci->flags &= ~OHCI_QUIRK_HUB_POWER; in ohci_omap_reset()
164 /* We require a self-powered hub, which should have in ohci_omap_reset()
166 ohci_to_hcd(ohci)->power_budget = 0; in ohci_omap_reset()
169 /* FIXME hub_wq hub requests should manage power switching */ in ohci_omap_reset()
170 if (config->transceiver_power) in ohci_omap_reset()
171 return config->transceiver_power(1); in ohci_omap_reset()
173 if (priv->power) in ohci_omap_reset()
174 gpiod_set_value_cansleep(priv->power, 0); in ohci_omap_reset()
184 /*-------------------------------------------------------------------------*/
187 * ohci_hcd_omap_probe - initialize OMAP-based HCDs
202 if (pdev->num_resources != 2) { in ohci_hcd_omap_probe()
203 dev_err(&pdev->dev, "invalid num_resources: %i\n", in ohci_hcd_omap_probe()
204 pdev->num_resources); in ohci_hcd_omap_probe()
205 return -ENODEV; in ohci_hcd_omap_probe()
208 if (pdev->resource[0].flags != IORESOURCE_MEM in ohci_hcd_omap_probe()
209 || pdev->resource[1].flags != IORESOURCE_IRQ) { in ohci_hcd_omap_probe()
210 dev_err(&pdev->dev, "invalid resource type\n"); in ohci_hcd_omap_probe()
211 return -ENODEV; in ohci_hcd_omap_probe()
214 hcd = usb_create_hcd(&ohci_omap_hc_driver, &pdev->dev, in ohci_hcd_omap_probe()
215 dev_name(&pdev->dev)); in ohci_hcd_omap_probe()
217 return -ENOMEM; in ohci_hcd_omap_probe()
219 hcd->rsrc_start = pdev->resource[0].start; in ohci_hcd_omap_probe()
220 hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; in ohci_hcd_omap_probe()
224 priv->power = devm_gpiod_get_optional(&pdev->dev, "power", GPIOD_ASIS); in ohci_hcd_omap_probe()
225 if (IS_ERR(priv->power)) { in ohci_hcd_omap_probe()
226 retval = PTR_ERR(priv->power); in ohci_hcd_omap_probe()
229 if (priv->power) in ohci_hcd_omap_probe()
230 gpiod_set_consumer_name(priv->power, "OHCI power"); in ohci_hcd_omap_probe()
237 priv->overcurrent = devm_gpiod_get_optional(&pdev->dev, "overcurrent", in ohci_hcd_omap_probe()
239 if (IS_ERR(priv->overcurrent)) { in ohci_hcd_omap_probe()
240 retval = PTR_ERR(priv->overcurrent); in ohci_hcd_omap_probe()
243 if (priv->overcurrent) in ohci_hcd_omap_probe()
244 gpiod_set_consumer_name(priv->overcurrent, "OHCI overcurrent"); in ohci_hcd_omap_probe()
246 priv->usb_host_ck = clk_get(&pdev->dev, "usb_hhc_ck"); in ohci_hcd_omap_probe()
247 if (IS_ERR(priv->usb_host_ck)) { in ohci_hcd_omap_probe()
248 retval = PTR_ERR(priv->usb_host_ck); in ohci_hcd_omap_probe()
252 retval = clk_prepare(priv->usb_host_ck); in ohci_hcd_omap_probe()
257 priv->usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck"); in ohci_hcd_omap_probe()
259 priv->usb_dc_ck = clk_get(&pdev->dev, "lb_ck"); in ohci_hcd_omap_probe()
261 if (IS_ERR(priv->usb_dc_ck)) { in ohci_hcd_omap_probe()
262 retval = PTR_ERR(priv->usb_dc_ck); in ohci_hcd_omap_probe()
266 retval = clk_prepare(priv->usb_dc_ck); in ohci_hcd_omap_probe()
270 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { in ohci_hcd_omap_probe()
271 dev_dbg(&pdev->dev, "request_mem_region failed\n"); in ohci_hcd_omap_probe()
272 retval = -EBUSY; in ohci_hcd_omap_probe()
276 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); in ohci_hcd_omap_probe()
277 if (!hcd->regs) { in ohci_hcd_omap_probe()
278 dev_err(&pdev->dev, "can't ioremap OHCI HCD\n"); in ohci_hcd_omap_probe()
279 retval = -ENOMEM; in ohci_hcd_omap_probe()
292 device_wakeup_enable(hcd->self.controller); in ohci_hcd_omap_probe()
295 iounmap(hcd->regs); in ohci_hcd_omap_probe()
297 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); in ohci_hcd_omap_probe()
299 clk_unprepare(priv->usb_dc_ck); in ohci_hcd_omap_probe()
301 clk_put(priv->usb_dc_ck); in ohci_hcd_omap_probe()
303 clk_unprepare(priv->usb_host_ck); in ohci_hcd_omap_probe()
305 clk_put(priv->usb_host_ck); in ohci_hcd_omap_probe()
315 * ohci_hcd_omap_remove - shutdown processing for OMAP-based HCDs
329 dev_dbg(hcd->self.controller, "stopping USB Controller\n"); in ohci_hcd_omap_remove()
332 if (!IS_ERR_OR_NULL(hcd->usb_phy)) { in ohci_hcd_omap_remove()
333 (void) otg_set_host(hcd->usb_phy->otg, 0); in ohci_hcd_omap_remove()
334 usb_put_phy(hcd->usb_phy); in ohci_hcd_omap_remove()
336 iounmap(hcd->regs); in ohci_hcd_omap_remove()
337 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); in ohci_hcd_omap_remove()
338 clk_unprepare(priv->usb_dc_ck); in ohci_hcd_omap_remove()
339 clk_put(priv->usb_dc_ck); in ohci_hcd_omap_remove()
340 clk_unprepare(priv->usb_host_ck); in ohci_hcd_omap_remove()
341 clk_put(priv->usb_host_ck); in ohci_hcd_omap_remove()
345 /*-------------------------------------------------------------------------*/
354 bool do_wakeup = device_may_wakeup(&pdev->dev); in ohci_omap_suspend()
357 if (time_before(jiffies, ohci->next_statechange)) in ohci_omap_suspend()
359 ohci->next_statechange = jiffies; in ohci_omap_suspend()
375 if (time_before(jiffies, ohci->next_statechange)) in ohci_omap_resume()
377 ohci->next_statechange = jiffies; in ohci_omap_resume()
386 /*-------------------------------------------------------------------------*/
413 return -ENODEV; in ohci_omap_init()