blob: fbe62bbce477fd08c95d187e63f8b19fc7ad3e82 [file] [log] [blame]
Jean-Jacques Hiblot9dc0d5c2018-11-29 10:52:46 +01001// SPDX-License-Identifier: GPL-2.0+
2/*
Nishanth Menoneaa39c62023-11-01 15:56:03 -05003 * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com
Jean-Jacques Hiblot9dc0d5c2018-11-29 10:52:46 +01004 * Written by Jean-Jacques Hiblot <jjhiblot@ti.com>
5 */
6
Patrick Delaunay81313352021-04-27 11:02:19 +02007#define LOG_CATEGORY UCLASS_USB_GADGET_GENERIC
8
Jean-Jacques Hiblot9dc0d5c2018-11-29 10:52:46 +01009#include <dm.h>
10#include <dm/device-internal.h>
Simon Glassbdd5f812023-09-14 18:21:46 -060011#include <linux/printk.h>
Jean-Jacques Hiblot9dc0d5c2018-11-29 10:52:46 +010012#include <linux/usb/gadget.h>
13
Jean-Jacques Hiblotdb994e02018-12-21 09:50:21 +010014#if CONFIG_IS_ENABLED(DM_USB_GADGET)
Marek Vasutcf25f662024-06-14 02:51:16 +020015static inline const struct usb_gadget_generic_ops *
16usb_gadget_generic_dev_ops(struct udevice *dev)
17{
18 return (const struct usb_gadget_generic_ops *)dev->driver->ops;
19}
20
Marek Vasut5d3df202024-06-14 02:51:26 +020021int dm_usb_gadget_handle_interrupts(struct udevice *dev)
Marek Vasutcf25f662024-06-14 02:51:16 +020022{
23 const struct usb_gadget_generic_ops *ops;
24
25 ops = usb_gadget_generic_dev_ops(dev);
26 if (!ops)
27 return -EFAULT;
28 if (!ops->handle_interrupts)
29 return -ENOSYS;
30
31 return ops->handle_interrupts(dev);
32}
33
Marek Vasutb3972032023-09-01 11:49:47 +020034int udc_device_get_by_index(int index, struct udevice **udev)
35{
36 struct udevice *dev = NULL;
37 int ret;
38
39 ret = uclass_get_device_by_seq(UCLASS_USB_GADGET_GENERIC, index, &dev);
40 if (!ret && dev) {
41 *udev = dev;
42 return 0;
43 }
44
45 ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, index, &dev);
46 if (!ret && dev) {
47 *udev = dev;
48 return 0;
49 }
50
51 pr_err("No USB device found\n");
52 return -ENODEV;
53}
54
55int udc_device_put(struct udevice *udev)
56{
57#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
58 return device_remove(udev, DM_REMOVE_NORMAL);
59#else
60 return -ENOSYS;
61#endif
62}
Marek Vasutb3972032023-09-01 11:49:47 +020063#else
64/* Backwards hardware compatibility -- switch to DM_USB_GADGET */
65static int legacy_index;
66int udc_device_get_by_index(int index, struct udevice **udev)
67{
68 legacy_index = index;
69 return board_usb_init(index, USB_INIT_DEVICE);
70}
71
72int udc_device_put(struct udevice *udev)
73{
74 return board_usb_cleanup(legacy_index, USB_INIT_DEVICE);
75}
Marek Vasutcf25f662024-06-14 02:51:16 +020076
77__weak int dm_usb_gadget_handle_interrupts(struct udevice *dev)
78{
79 return 0;
80}
Jean-Jacques Hiblotdb994e02018-12-21 09:50:21 +010081#endif
Jean-Jacques Hiblot9dc0d5c2018-11-29 10:52:46 +010082
Marek Vasutb3972032023-09-01 11:49:47 +020083#if CONFIG_IS_ENABLED(DM)
Jean-Jacques Hiblot9dc0d5c2018-11-29 10:52:46 +010084UCLASS_DRIVER(usb_gadget_generic) = {
85 .id = UCLASS_USB_GADGET_GENERIC,
Jean-Jacques Hiblot2934dc12018-12-15 17:43:27 +010086 .name = "usb",
87 .flags = DM_UC_FLAG_SEQ_ALIAS,
Jean-Jacques Hiblot9dc0d5c2018-11-29 10:52:46 +010088};
Marek Vasutb3972032023-09-01 11:49:47 +020089#endif