101311624SJean-Jacques Hiblot // SPDX-License-Identifier: GPL-2.0+
201311624SJean-Jacques Hiblot /*
301311624SJean-Jacques Hiblot  * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
401311624SJean-Jacques Hiblot  * Written by Jean-Jacques Hiblot <jjhiblot@ti.com>
501311624SJean-Jacques Hiblot  */
601311624SJean-Jacques Hiblot 
701311624SJean-Jacques Hiblot #include <common.h>
801311624SJean-Jacques Hiblot #include <dm.h>
901311624SJean-Jacques Hiblot #include <dm/device-internal.h>
1001311624SJean-Jacques Hiblot #include <linux/usb/gadget.h>
1101311624SJean-Jacques Hiblot 
12b3c518a8SJean-Jacques Hiblot #if CONFIG_IS_ENABLED(DM_USB_GADGET)
1301311624SJean-Jacques Hiblot #define MAX_UDC_DEVICES 4
1401311624SJean-Jacques Hiblot static struct udevice *dev_array[MAX_UDC_DEVICES];
usb_gadget_initialize(int index)1501311624SJean-Jacques Hiblot int usb_gadget_initialize(int index)
1601311624SJean-Jacques Hiblot {
1701311624SJean-Jacques Hiblot 	int ret;
1801311624SJean-Jacques Hiblot 	struct udevice *dev = NULL;
1901311624SJean-Jacques Hiblot 
2001311624SJean-Jacques Hiblot 	if (index < 0 || index >= ARRAY_SIZE(dev_array))
2101311624SJean-Jacques Hiblot 		return -EINVAL;
2201311624SJean-Jacques Hiblot 	if (dev_array[index])
2301311624SJean-Jacques Hiblot 		return 0;
24801f1fa4SJean-Jacques Hiblot 	ret = uclass_get_device_by_seq(UCLASS_USB_GADGET_GENERIC, index, &dev);
2501311624SJean-Jacques Hiblot 	if (!dev || ret) {
26*e81d9de5SJean-Jacques Hiblot 		ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, index, &dev);
27*e81d9de5SJean-Jacques Hiblot 		if (!dev || ret) {
2801311624SJean-Jacques Hiblot 			pr_err("No USB device found\n");
2901311624SJean-Jacques Hiblot 			return -ENODEV;
3001311624SJean-Jacques Hiblot 		}
31*e81d9de5SJean-Jacques Hiblot 	}
3201311624SJean-Jacques Hiblot 	dev_array[index] = dev;
3301311624SJean-Jacques Hiblot 	return 0;
3401311624SJean-Jacques Hiblot }
3501311624SJean-Jacques Hiblot 
usb_gadget_release(int index)3601311624SJean-Jacques Hiblot int usb_gadget_release(int index)
3701311624SJean-Jacques Hiblot {
3801311624SJean-Jacques Hiblot #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
3901311624SJean-Jacques Hiblot 	int ret;
4001311624SJean-Jacques Hiblot 	if (index < 0 || index >= ARRAY_SIZE(dev_array))
4101311624SJean-Jacques Hiblot 		return -EINVAL;
4201311624SJean-Jacques Hiblot 
4301311624SJean-Jacques Hiblot 	ret = device_remove(dev_array[index], DM_REMOVE_NORMAL);
4401311624SJean-Jacques Hiblot 	if (!ret)
4501311624SJean-Jacques Hiblot 		dev_array[index] = NULL;
4601311624SJean-Jacques Hiblot 	return ret;
4701311624SJean-Jacques Hiblot #else
4801311624SJean-Jacques Hiblot 	return -ENOTSUPP;
4901311624SJean-Jacques Hiblot #endif
5001311624SJean-Jacques Hiblot }
5101311624SJean-Jacques Hiblot 
usb_gadget_handle_interrupts(int index)5201311624SJean-Jacques Hiblot int usb_gadget_handle_interrupts(int index)
5301311624SJean-Jacques Hiblot {
5401311624SJean-Jacques Hiblot 	if (index < 0 || index >= ARRAY_SIZE(dev_array))
5501311624SJean-Jacques Hiblot 		return -EINVAL;
5601311624SJean-Jacques Hiblot 	return dm_usb_gadget_handle_interrupts(dev_array[index]);
5701311624SJean-Jacques Hiblot }
58b3c518a8SJean-Jacques Hiblot #endif
5901311624SJean-Jacques Hiblot 
6001311624SJean-Jacques Hiblot UCLASS_DRIVER(usb_gadget_generic) = {
6101311624SJean-Jacques Hiblot 	.id		= UCLASS_USB_GADGET_GENERIC,
62801f1fa4SJean-Jacques Hiblot 	.name		= "usb",
63801f1fa4SJean-Jacques Hiblot 	.flags		= DM_UC_FLAG_SEQ_ALIAS,
6401311624SJean-Jacques Hiblot };
65