Lines Matching +full:can +full:- +full:transceiver
1 // SPDX-License-Identifier: GPL-2.0+
3 * NOP USB transceiver for all USB transceiver which are either built-in
10 * This provides a "nop" transceiver for PHYs which are
16 #include <linux/dma-mapping.h>
28 #include "phy-generic.h"
49 struct usb_phy_generic *nop = dev_get_drvdata(x->dev); in nop_set_suspend()
51 if (!IS_ERR(nop->clk)) { in nop_set_suspend()
53 clk_disable_unprepare(nop->clk); in nop_set_suspend()
55 clk_prepare_enable(nop->clk); in nop_set_suspend()
63 if (!nop->gpiod_reset) in nop_reset()
66 gpiod_set_value_cansleep(nop->gpiod_reset, 1); in nop_reset()
68 gpiod_set_value_cansleep(nop->gpiod_reset, 0); in nop_reset()
74 struct regulator *vbus_draw = nop->vbus_draw; in nop_set_vbus_draw()
81 enabled = nop->vbus_draw_enabled; in nop_set_vbus_draw()
88 nop->vbus_draw_enabled = 1; in nop_set_vbus_draw()
95 nop->vbus_draw_enabled = 0; in nop_set_vbus_draw()
98 nop->mA = mA; in nop_set_vbus_draw()
105 struct usb_otg *otg = nop->phy.otg; in nop_gpio_vbus_thread()
108 vbus = gpiod_get_value(nop->gpiod_vbus); in nop_gpio_vbus_thread()
109 if ((vbus ^ nop->vbus) == 0) in nop_gpio_vbus_thread()
111 nop->vbus = vbus; in nop_gpio_vbus_thread()
115 otg->state = OTG_STATE_B_PERIPHERAL; in nop_gpio_vbus_thread()
116 nop->phy.last_event = status; in nop_gpio_vbus_thread()
121 atomic_notifier_call_chain(&nop->phy.notifier, status, in nop_gpio_vbus_thread()
122 otg->gadget); in nop_gpio_vbus_thread()
127 otg->state = OTG_STATE_B_IDLE; in nop_gpio_vbus_thread()
128 nop->phy.last_event = status; in nop_gpio_vbus_thread()
130 atomic_notifier_call_chain(&nop->phy.notifier, status, in nop_gpio_vbus_thread()
131 otg->gadget); in nop_gpio_vbus_thread()
138 struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); in usb_gen_phy_init()
141 if (!IS_ERR(nop->vcc)) { in usb_gen_phy_init()
142 if (regulator_enable(nop->vcc)) in usb_gen_phy_init()
143 dev_err(phy->dev, "Failed to enable power\n"); in usb_gen_phy_init()
146 if (!IS_ERR(nop->clk)) { in usb_gen_phy_init()
147 ret = clk_prepare_enable(nop->clk); in usb_gen_phy_init()
160 struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); in usb_gen_phy_shutdown()
162 gpiod_set_value_cansleep(nop->gpiod_reset, 1); in usb_gen_phy_shutdown()
164 if (!IS_ERR(nop->clk)) in usb_gen_phy_shutdown()
165 clk_disable_unprepare(nop->clk); in usb_gen_phy_shutdown()
167 if (!IS_ERR(nop->vcc)) { in usb_gen_phy_shutdown()
168 if (regulator_disable(nop->vcc)) in usb_gen_phy_shutdown()
169 dev_err(phy->dev, "Failed to disable power\n"); in usb_gen_phy_shutdown()
177 return -ENODEV; in nop_set_peripheral()
180 otg->gadget = NULL; in nop_set_peripheral()
181 return -ENODEV; in nop_set_peripheral()
184 otg->gadget = gadget; in nop_set_peripheral()
185 if (otg->state == OTG_STATE_B_PERIPHERAL) in nop_set_peripheral()
186 atomic_notifier_call_chain(&otg->usb_phy->notifier, in nop_set_peripheral()
187 USB_EVENT_VBUS, otg->gadget); in nop_set_peripheral()
189 otg->state = OTG_STATE_B_IDLE; in nop_set_peripheral()
196 return -ENODEV; in nop_set_host()
199 otg->host = NULL; in nop_set_host()
200 return -ENODEV; in nop_set_host()
203 otg->host = host; in nop_set_host()
216 if (dev->of_node) { in usb_phy_gen_create_phy()
217 struct device_node *node = dev->of_node; in usb_phy_gen_create_phy()
219 if (of_property_read_u32(node, "clock-frequency", &clk_rate)) in usb_phy_gen_create_phy()
222 needs_vcc = of_property_read_bool(node, "vcc-supply"); in usb_phy_gen_create_phy()
224 nop->gpiod_reset = devm_gpiod_get_optional(dev, "reset", in usb_phy_gen_create_phy()
226 err = PTR_ERR_OR_ZERO(nop->gpiod_reset); in usb_phy_gen_create_phy()
228 nop->gpiod_vbus = devm_gpiod_get_optional(dev, in usb_phy_gen_create_phy()
229 "vbus-detect", in usb_phy_gen_create_phy()
231 err = PTR_ERR_OR_ZERO(nop->gpiod_vbus); in usb_phy_gen_create_phy()
234 type = pdata->type; in usb_phy_gen_create_phy()
235 clk_rate = pdata->clk_rate; in usb_phy_gen_create_phy()
236 needs_vcc = pdata->needs_vcc; in usb_phy_gen_create_phy()
237 if (gpio_is_valid(pdata->gpio_reset)) { in usb_phy_gen_create_phy()
238 err = devm_gpio_request_one(dev, pdata->gpio_reset, in usb_phy_gen_create_phy()
242 nop->gpiod_reset = in usb_phy_gen_create_phy()
243 gpio_to_desc(pdata->gpio_reset); in usb_phy_gen_create_phy()
245 nop->gpiod_vbus = pdata->gpiod_vbus; in usb_phy_gen_create_phy()
248 if (err == -EPROBE_DEFER) in usb_phy_gen_create_phy()
249 return -EPROBE_DEFER; in usb_phy_gen_create_phy()
254 if (nop->gpiod_reset) in usb_phy_gen_create_phy()
255 gpiod_direction_output(nop->gpiod_reset, 1); in usb_phy_gen_create_phy()
257 nop->phy.otg = devm_kzalloc(dev, sizeof(*nop->phy.otg), in usb_phy_gen_create_phy()
259 if (!nop->phy.otg) in usb_phy_gen_create_phy()
260 return -ENOMEM; in usb_phy_gen_create_phy()
262 nop->clk = devm_clk_get(dev, "main_clk"); in usb_phy_gen_create_phy()
263 if (IS_ERR(nop->clk)) { in usb_phy_gen_create_phy()
264 dev_dbg(dev, "Can't get phy clock: %ld\n", in usb_phy_gen_create_phy()
265 PTR_ERR(nop->clk)); in usb_phy_gen_create_phy()
267 return PTR_ERR(nop->clk); in usb_phy_gen_create_phy()
270 if (!IS_ERR(nop->clk) && clk_rate) { in usb_phy_gen_create_phy()
271 err = clk_set_rate(nop->clk, clk_rate); in usb_phy_gen_create_phy()
278 nop->vcc = devm_regulator_get(dev, "vcc"); in usb_phy_gen_create_phy()
279 if (IS_ERR(nop->vcc)) { in usb_phy_gen_create_phy()
281 PTR_ERR(nop->vcc)); in usb_phy_gen_create_phy()
283 return -EPROBE_DEFER; in usb_phy_gen_create_phy()
286 nop->dev = dev; in usb_phy_gen_create_phy()
287 nop->phy.dev = nop->dev; in usb_phy_gen_create_phy()
288 nop->phy.label = "nop-xceiv"; in usb_phy_gen_create_phy()
289 nop->phy.set_suspend = nop_set_suspend; in usb_phy_gen_create_phy()
290 nop->phy.type = type; in usb_phy_gen_create_phy()
292 nop->phy.otg->state = OTG_STATE_UNDEFINED; in usb_phy_gen_create_phy()
293 nop->phy.otg->usb_phy = &nop->phy; in usb_phy_gen_create_phy()
294 nop->phy.otg->set_host = nop_set_host; in usb_phy_gen_create_phy()
295 nop->phy.otg->set_peripheral = nop_set_peripheral; in usb_phy_gen_create_phy()
303 struct device *dev = &pdev->dev; in usb_phy_generic_probe()
309 return -ENOMEM; in usb_phy_generic_probe()
311 err = usb_phy_gen_create_phy(dev, nop, dev_get_platdata(&pdev->dev)); in usb_phy_generic_probe()
314 if (nop->gpiod_vbus) { in usb_phy_generic_probe()
315 err = devm_request_threaded_irq(&pdev->dev, in usb_phy_generic_probe()
316 gpiod_to_irq(nop->gpiod_vbus), in usb_phy_generic_probe()
321 dev_err(&pdev->dev, "can't request irq %i, err: %d\n", in usb_phy_generic_probe()
322 gpiod_to_irq(nop->gpiod_vbus), err); in usb_phy_generic_probe()
325 nop->phy.otg->state = gpiod_get_value(nop->gpiod_vbus) ? in usb_phy_generic_probe()
329 nop->phy.init = usb_gen_phy_init; in usb_phy_generic_probe()
330 nop->phy.shutdown = usb_gen_phy_shutdown; in usb_phy_generic_probe()
332 err = usb_add_phy_dev(&nop->phy); in usb_phy_generic_probe()
334 dev_err(&pdev->dev, "can't register transceiver, err: %d\n", in usb_phy_generic_probe()
348 usb_remove_phy(&nop->phy); in usb_phy_generic_remove()
354 { .compatible = "usb-nop-xceiv" },
383 MODULE_DESCRIPTION("NOP USB Transceiver driver");