xref: /aosp_15_r20/external/coreboot/payloads/libpayload/drivers/usb/quirks.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /*
2  *
3  * Copyright (C) 2010 coresystems GmbH
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 //#define USB_DEBUG
30 
31 #include <libpayload-config.h>
32 #include <usb/usb.h>
33 
34 typedef struct {
35 	u16 vendor, device;
36 	u32 quirks;
37 	int interface;
38 } usb_quirks_t;
39 
40 // IDs without a quirk don't need to be mentioned in this list
41 // but some are here for easier testing.
42 
43 usb_quirks_t usb_quirks[] = {
44 	/* Working chips,... remove before next release */
45 	{ 0x3538, 0x0054, USB_QUIRK_NONE, 0 },	// PQI 1GB
46 	{ 0x13fd, 0x0841, USB_QUIRK_NONE, 0 },	// Samsung SE-S084
47 
48 	/* Silence the warning for known devices with more
49 	 * than one interface. The 'interface' value should specify the
50 	 * interface we want to use (interface numbers usually start at 0).
51 	 */
52 	{ 0x1267, 0x0103, USB_QUIRK_NONE, 0 },	// Keyboard Trust KB-1800S
53 	{ 0x0a12, 0x0001, USB_QUIRK_NONE, 0 },	// Bluetooth Allnet ALL1575
54 
55 	/* Currently unsupported, possibly interesting devices:
56 	 * FTDI serial: device 0x0403:0x6001 is USB 1.10 (class ff)
57 	 * UPEK TouchChip: device 0x147e:0x2016 is USB 1.0 (class ff)
58 	 */
59 };
60 
61 #if CONFIG(LP_USB_PCI)
62 usb_quirks_t pci_quirks[] = {
63 	/* QEMU XHCI root hub does not implement port change detect */
64 	{ 0x1b36, 0x000d, USB_QUIRK_HUB_NO_USBSTS_PCD, 0 },
65 };
66 
pci_quirk_check(pcidev_t controller)67 u32 pci_quirk_check(pcidev_t controller)
68 {
69 	int i;
70 	u16 vendor = pci_read_config16(controller, REG_VENDOR_ID);
71 	u16 device = pci_read_config16(controller, REG_DEVICE_ID);
72 
73 	for (i = 0; i < ARRAY_SIZE(pci_quirks); i++) {
74 		if ((pci_quirks[i].vendor == vendor) &&
75 		    (pci_quirks[i].device == device)) {
76 			printf("PCI quirks enabled: %08x\n", pci_quirks[i].quirks);
77 			return pci_quirks[i].quirks;
78 		}
79 	}
80 
81 	return USB_QUIRK_NONE;
82 }
83 #endif
84 
usb_quirk_check(u16 vendor,u16 device)85 u32 usb_quirk_check(u16 vendor, u16 device)
86 {
87 	int i;
88 	for (i = 0; i < ARRAY_SIZE(usb_quirks); i++) {
89 		if ((usb_quirks[i].vendor == vendor) &&
90 				(usb_quirks[i].device == device)) {
91 			usb_debug("USB quirks enabled: %08x\n",
92 					usb_quirks[i].quirks);
93 			return usb_quirks[i].quirks;
94 		}
95 	}
96 
97 	return USB_QUIRK_NONE;
98 }
99 
usb_interface_check(u16 vendor,u16 device)100 int usb_interface_check(u16 vendor, u16 device)
101 {
102 	int i;
103 	for (i = 0; i < ARRAY_SIZE(usb_quirks); i++) {
104 		if ((usb_quirks[i].vendor == vendor) &&
105 				(usb_quirks[i].device == device)) {
106 			return usb_quirks[i].interface;
107 		}
108 	}
109 
110 	return -1;
111 }
112