1*20828bbaSJean-Jacques Hiblot // SPDX-License-Identifier: GPL-2.0+ 2*20828bbaSJean-Jacques Hiblot /* 3*20828bbaSJean-Jacques Hiblot * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com 4*20828bbaSJean-Jacques Hiblot * Written by Jean-Jacques Hiblot <jjhiblot@ti.com> 5*20828bbaSJean-Jacques Hiblot */ 6*20828bbaSJean-Jacques Hiblot 7*20828bbaSJean-Jacques Hiblot #include <common.h> 8*20828bbaSJean-Jacques Hiblot #include <dm.h> 9*20828bbaSJean-Jacques Hiblot #include <dm/device-internal.h> 10*20828bbaSJean-Jacques Hiblot #include <linux/usb/gadget.h> 11*20828bbaSJean-Jacques Hiblot 12*20828bbaSJean-Jacques Hiblot #define MAX_UDC_DEVICES 4 13*20828bbaSJean-Jacques Hiblot static struct udevice *dev_array[MAX_UDC_DEVICES]; 14*20828bbaSJean-Jacques Hiblot int usb_gadget_initialize(int index) 15*20828bbaSJean-Jacques Hiblot { 16*20828bbaSJean-Jacques Hiblot int ret; 17*20828bbaSJean-Jacques Hiblot struct udevice *dev = NULL; 18*20828bbaSJean-Jacques Hiblot 19*20828bbaSJean-Jacques Hiblot if (index < 0 || index >= ARRAY_SIZE(dev_array)) 20*20828bbaSJean-Jacques Hiblot return -EINVAL; 21*20828bbaSJean-Jacques Hiblot if (dev_array[index]) 22*20828bbaSJean-Jacques Hiblot return 0; 23*20828bbaSJean-Jacques Hiblot ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, index, &dev); 24*20828bbaSJean-Jacques Hiblot if (!dev || ret) { 25*20828bbaSJean-Jacques Hiblot pr_err("No USB device found\n"); 26*20828bbaSJean-Jacques Hiblot return -ENODEV; 27*20828bbaSJean-Jacques Hiblot } 28*20828bbaSJean-Jacques Hiblot dev_array[index] = dev; 29*20828bbaSJean-Jacques Hiblot return 0; 30*20828bbaSJean-Jacques Hiblot } 31*20828bbaSJean-Jacques Hiblot 32*20828bbaSJean-Jacques Hiblot int usb_gadget_release(int index) 33*20828bbaSJean-Jacques Hiblot { 34*20828bbaSJean-Jacques Hiblot #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) 35*20828bbaSJean-Jacques Hiblot int ret; 36*20828bbaSJean-Jacques Hiblot if (index < 0 || index >= ARRAY_SIZE(dev_array)) 37*20828bbaSJean-Jacques Hiblot return -EINVAL; 38*20828bbaSJean-Jacques Hiblot 39*20828bbaSJean-Jacques Hiblot ret = device_remove(dev_array[index], DM_REMOVE_NORMAL); 40*20828bbaSJean-Jacques Hiblot if (!ret) 41*20828bbaSJean-Jacques Hiblot dev_array[index] = NULL; 42*20828bbaSJean-Jacques Hiblot return ret; 43*20828bbaSJean-Jacques Hiblot #else 44*20828bbaSJean-Jacques Hiblot return -ENOTSUPP; 45*20828bbaSJean-Jacques Hiblot #endif 46*20828bbaSJean-Jacques Hiblot } 47*20828bbaSJean-Jacques Hiblot 48*20828bbaSJean-Jacques Hiblot int usb_gadget_handle_interrupts(int index) 49*20828bbaSJean-Jacques Hiblot { 50*20828bbaSJean-Jacques Hiblot if (index < 0 || index >= ARRAY_SIZE(dev_array)) 51*20828bbaSJean-Jacques Hiblot return -EINVAL; 52*20828bbaSJean-Jacques Hiblot return dm_usb_gadget_handle_interrupts(dev_array[index]); 53*20828bbaSJean-Jacques Hiblot } 54*20828bbaSJean-Jacques Hiblot 55*20828bbaSJean-Jacques Hiblot UCLASS_DRIVER(usb_gadget_generic) = { 56*20828bbaSJean-Jacques Hiblot .id = UCLASS_USB_GADGET_GENERIC, 57*20828bbaSJean-Jacques Hiblot .name = "usb_gadget_generic", 58*20828bbaSJean-Jacques Hiblot }; 59