summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/udc/udc-uclass.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/udc/udc-uclass.c')
-rw-r--r--drivers/usb/gadget/udc/udc-uclass.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/drivers/usb/gadget/udc/udc-uclass.c b/drivers/usb/gadget/udc/udc-uclass.c
new file mode 100644
index 00000000000..723d1cdfd78
--- /dev/null
+++ b/drivers/usb/gadget/udc/udc-uclass.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com
+ * Written by Jean-Jacques Hiblot <jjhiblot@ti.com>
+ */
+
+#define LOG_CATEGORY UCLASS_USB_GADGET_GENERIC
+
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <linux/printk.h>
+#include <linux/usb/gadget.h>
+
+#if CONFIG_IS_ENABLED(DM_USB_GADGET)
+static inline const struct usb_gadget_generic_ops *
+usb_gadget_generic_dev_ops(struct udevice *dev)
+{
+ return (const struct usb_gadget_generic_ops *)dev->driver->ops;
+}
+
+int dm_usb_gadget_handle_interrupts(struct udevice *dev)
+{
+ const struct usb_gadget_generic_ops *ops;
+
+ ops = usb_gadget_generic_dev_ops(dev);
+ if (!ops)
+ return -EFAULT;
+ if (!ops->handle_interrupts)
+ return -ENOSYS;
+
+ return ops->handle_interrupts(dev);
+}
+
+int udc_device_get_by_index(int index, struct udevice **udev)
+{
+ struct udevice *dev = NULL;
+ int ret;
+
+ ret = uclass_get_device_by_seq(UCLASS_USB_GADGET_GENERIC, index, &dev);
+ if (!ret && dev) {
+ *udev = dev;
+ return 0;
+ }
+
+ ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, index, &dev);
+ if (!ret && dev) {
+ *udev = dev;
+ return 0;
+ }
+
+ pr_err("No USB device found\n");
+ return -ENODEV;
+}
+
+int udc_device_put(struct udevice *udev)
+{
+#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
+ return device_remove(udev, DM_REMOVE_NORMAL);
+#else
+ return -ENOSYS;
+#endif
+}
+#else
+/* Backwards hardware compatibility -- switch to DM_USB_GADGET */
+static int legacy_index;
+int udc_device_get_by_index(int index, struct udevice **udev)
+{
+ legacy_index = index;
+ return board_usb_init(index, USB_INIT_DEVICE);
+}
+
+int udc_device_put(struct udevice *udev)
+{
+ return board_usb_cleanup(legacy_index, USB_INIT_DEVICE);
+}
+
+__weak int dm_usb_gadget_handle_interrupts(struct udevice *dev)
+{
+ return 0;
+}
+#endif
+
+#if CONFIG_IS_ENABLED(DM)
+UCLASS_DRIVER(usb_gadget_generic) = {
+ .id = UCLASS_USB_GADGET_GENERIC,
+ .name = "usb_gadget",
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
+};
+#endif