Lines Matching +full:self +full:- +full:powered
1 // SPDX-License-Identifier: GPL-2.0
5 * TI DA8xx (OMAP-L1x) Bus Glue
7 * Derived from: ohci-omap.c and ohci-s3c2410.c
8 * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
19 #include <linux/platform_data/usb-davinci.h>
28 #define DRV_NAME "ohci-da8xx"
45 #define to_da8xx_ohci(hcd) (struct da8xx_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
47 /* Over-current indicator change bitmask */
55 ret = clk_prepare_enable(da8xx_ohci->usb11_clk); in ohci_da8xx_enable()
59 ret = phy_init(da8xx_ohci->usb11_phy); in ohci_da8xx_enable()
63 ret = phy_power_on(da8xx_ohci->usb11_phy); in ohci_da8xx_enable()
70 phy_exit(da8xx_ohci->usb11_phy); in ohci_da8xx_enable()
72 clk_disable_unprepare(da8xx_ohci->usb11_clk); in ohci_da8xx_enable()
81 phy_power_off(da8xx_ohci->usb11_phy); in ohci_da8xx_disable()
82 phy_exit(da8xx_ohci->usb11_phy); in ohci_da8xx_disable()
83 clk_disable_unprepare(da8xx_ohci->usb11_clk); in ohci_da8xx_disable()
89 struct device *dev = hcd->self.controller; in ohci_da8xx_set_power()
93 if (hub && hub->set_power) in ohci_da8xx_set_power()
94 return hub->set_power(1, on); in ohci_da8xx_set_power()
96 if (!da8xx_ohci->vbus_reg) in ohci_da8xx_set_power()
99 if (on && !da8xx_ohci->reg_enabled) { in ohci_da8xx_set_power()
100 ret = regulator_enable(da8xx_ohci->vbus_reg); in ohci_da8xx_set_power()
105 da8xx_ohci->reg_enabled = 1; in ohci_da8xx_set_power()
107 } else if (!on && da8xx_ohci->reg_enabled) { in ohci_da8xx_set_power()
108 ret = regulator_disable(da8xx_ohci->vbus_reg); in ohci_da8xx_set_power()
113 da8xx_ohci->reg_enabled = 0; in ohci_da8xx_set_power()
122 struct device *dev = hcd->self.controller; in ohci_da8xx_get_power()
125 if (hub && hub->get_power) in ohci_da8xx_get_power()
126 return hub->get_power(1); in ohci_da8xx_get_power()
128 if (da8xx_ohci->vbus_reg) in ohci_da8xx_get_power()
129 return regulator_is_enabled(da8xx_ohci->vbus_reg); in ohci_da8xx_get_power()
137 struct device *dev = hcd->self.controller; in ohci_da8xx_get_oci()
142 if (hub && hub->get_oci) in ohci_da8xx_get_oci()
143 return hub->get_oci(1); in ohci_da8xx_get_oci()
145 if (!da8xx_ohci->vbus_reg) in ohci_da8xx_get_oci()
148 ret = regulator_get_error_flags(da8xx_ohci->vbus_reg, &flags); in ohci_da8xx_get_oci()
161 struct device *dev = hcd->self.controller; in ohci_da8xx_has_set_power()
164 if (hub && hub->set_power) in ohci_da8xx_has_set_power()
167 if (da8xx_ohci->vbus_reg) in ohci_da8xx_has_set_power()
176 struct device *dev = hcd->self.controller; in ohci_da8xx_has_oci()
179 if (hub && hub->get_oci) in ohci_da8xx_has_oci()
182 if (da8xx_ohci->vbus_reg) in ohci_da8xx_has_oci()
190 struct device *dev = hcd->self.controller; in ohci_da8xx_has_potpgt()
193 if (hub && hub->potpgt) in ohci_da8xx_has_potpgt()
200 * Handle the port over-current indicator change.
207 /* Once over-current is detected, the port needs to be powered down */ in ohci_da8xx_ocic_handler()
208 if (hub->get_oci(port) > 0) in ohci_da8xx_ocic_handler()
209 hub->set_power(port, 0); in ohci_da8xx_ocic_handler()
220 ohci_da8xx_set_power(da8xx_ohci->hcd, 0); in ohci_da8xx_regulator_event()
229 struct device *dev = hcd->self.controller; in ohci_da8xx_register_notify()
233 if (hub && hub->ocic_notify) { in ohci_da8xx_register_notify()
234 ret = hub->ocic_notify(ohci_da8xx_ocic_handler); in ohci_da8xx_register_notify()
235 } else if (da8xx_ohci->vbus_reg) { in ohci_da8xx_register_notify()
236 da8xx_ohci->nb.notifier_call = ohci_da8xx_regulator_event; in ohci_da8xx_register_notify()
237 ret = devm_regulator_register_notifier(da8xx_ohci->vbus_reg, in ohci_da8xx_register_notify()
238 &da8xx_ohci->nb); in ohci_da8xx_register_notify()
249 struct device *dev = hcd->self.controller; in ohci_da8xx_unregister_notify()
252 if (hub && hub->ocic_notify) in ohci_da8xx_unregister_notify()
253 hub->ocic_notify(NULL); in ohci_da8xx_unregister_notify()
258 struct device *dev = hcd->self.controller; in ohci_da8xx_reset()
274 ohci->num_ports = 1; in ohci_da8xx_reset()
283 * Since we're providing a board-specific root hub port power control in ohci_da8xx_reset()
284 * and over-current reporting, we have to override the HC root hub A in ohci_da8xx_reset()
288 rh_a = ohci_readl(ohci, &ohci->regs->roothub.a); in ohci_da8xx_reset()
299 rh_a |= hub->potpgt << 24; in ohci_da8xx_reset()
301 ohci_writel(ohci, rh_a, &ohci->regs->roothub.a); in ohci_da8xx_reset()
307 * Update the status data from the hub with the over-current indicator change.
315 dev_dbg(hcd->self.controller, "over-current indicator change " in ohci_da8xx_hub_status_data()
332 struct device *dev = hcd->self.controller; in ohci_da8xx_hub_control()
343 temp = roothub_portstatus(hcd_to_ohci(hcd), wIndex - 1); in ohci_da8xx_hub_control()
349 /* The port over-current indicator (POCI) bit is always 0 */ in ohci_da8xx_hub_control()
353 /* The over-current indicator change (OCIC) bit is 0 too */ in ohci_da8xx_hub_control()
375 return ohci_da8xx_set_power(hcd, temp) ? -EPIPE : 0; in ohci_da8xx_hub_control()
393 /*-------------------------------------------------------------------------*/
396 { .compatible = "ti,da830-ohci" },
408 hcd = usb_create_hcd(&ohci_da8xx_hc_driver, &pdev->dev, in ohci_da8xx_probe()
409 dev_name(&pdev->dev)); in ohci_da8xx_probe()
411 return -ENOMEM; in ohci_da8xx_probe()
414 da8xx_ohci->hcd = hcd; in ohci_da8xx_probe()
416 da8xx_ohci->usb11_clk = devm_clk_get(&pdev->dev, NULL); in ohci_da8xx_probe()
417 if (IS_ERR(da8xx_ohci->usb11_clk)) { in ohci_da8xx_probe()
418 error = PTR_ERR(da8xx_ohci->usb11_clk); in ohci_da8xx_probe()
419 if (error != -EPROBE_DEFER) in ohci_da8xx_probe()
420 dev_err(&pdev->dev, "Failed to get clock.\n"); in ohci_da8xx_probe()
424 da8xx_ohci->usb11_phy = devm_phy_get(&pdev->dev, "usb-phy"); in ohci_da8xx_probe()
425 if (IS_ERR(da8xx_ohci->usb11_phy)) { in ohci_da8xx_probe()
426 error = PTR_ERR(da8xx_ohci->usb11_phy); in ohci_da8xx_probe()
427 if (error != -EPROBE_DEFER) in ohci_da8xx_probe()
428 dev_err(&pdev->dev, "Failed to get phy.\n"); in ohci_da8xx_probe()
432 da8xx_ohci->vbus_reg = devm_regulator_get_optional(&pdev->dev, "vbus"); in ohci_da8xx_probe()
433 if (IS_ERR(da8xx_ohci->vbus_reg)) { in ohci_da8xx_probe()
434 error = PTR_ERR(da8xx_ohci->vbus_reg); in ohci_da8xx_probe()
435 if (error == -ENODEV) { in ohci_da8xx_probe()
436 da8xx_ohci->vbus_reg = NULL; in ohci_da8xx_probe()
437 } else if (error == -EPROBE_DEFER) { in ohci_da8xx_probe()
440 dev_err(&pdev->dev, "Failed to get regulator\n"); in ohci_da8xx_probe()
446 hcd->regs = devm_ioremap_resource(&pdev->dev, mem); in ohci_da8xx_probe()
447 if (IS_ERR(hcd->regs)) { in ohci_da8xx_probe()
448 error = PTR_ERR(hcd->regs); in ohci_da8xx_probe()
451 hcd->rsrc_start = mem->start; in ohci_da8xx_probe()
452 hcd->rsrc_len = resource_size(mem); in ohci_da8xx_probe()
456 error = -ENODEV; in ohci_da8xx_probe()
464 device_wakeup_enable(hcd->self.controller); in ohci_da8xx_probe()
496 bool do_wakeup = device_may_wakeup(&pdev->dev); in ohci_da8xx_suspend()
500 if (time_before(jiffies, ohci->next_statechange)) in ohci_da8xx_suspend()
502 ohci->next_statechange = jiffies; in ohci_da8xx_suspend()
509 hcd->state = HC_STATE_SUSPENDED; in ohci_da8xx_suspend()
520 if (time_before(jiffies, ohci->next_statechange)) in ohci_da8xx_resume()
522 ohci->next_statechange = jiffies; in ohci_da8xx_resume()
560 return -ENODEV; in ohci_da8xx_init()
567 * da8xx-specific workarounds. We override certain hc_driver in ohci_da8xx_init()