Commit d6eae7b0b172b3ef31a3f816ce946857f382ac4e

Authored by Lukasz Majewski
Committed by Marek Vasut
1 parent 7b412ab31f

usb:g_dnl: Add name parameter to g_dnl_bind_fixup function

New parameter, namely *name has been added to g_dnl_bind_fixup().
It is necessary (for compatibility reasons) to assign new USB idProduct
and idVendor for different usb functions.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Cc: Marek Vasut <marex@denx.de>

Showing 3 changed files with 4 additions and 4 deletions Inline Diff

board/siemens/common/factoryset.c
1 /* 1 /*
2 * 2 *
3 * Read FactorySet information from EEPROM into global structure. 3 * Read FactorySet information from EEPROM into global structure.
4 * (C) Copyright 2013 Siemens Schweiz AG 4 * (C) Copyright 2013 Siemens Schweiz AG
5 * 5 *
6 * SPDX-License-Identifier: GPL-2.0+ 6 * SPDX-License-Identifier: GPL-2.0+
7 */ 7 */
8 8
9 #if !defined(CONFIG_SPL_BUILD) 9 #if !defined(CONFIG_SPL_BUILD)
10 10
11 #include <common.h> 11 #include <common.h>
12 #include <i2c.h> 12 #include <i2c.h>
13 #include <asm/io.h> 13 #include <asm/io.h>
14 #include <asm/arch/cpu.h> 14 #include <asm/arch/cpu.h>
15 #include <asm/arch/sys_proto.h> 15 #include <asm/arch/sys_proto.h>
16 #include <asm/unaligned.h> 16 #include <asm/unaligned.h>
17 #include <net.h> 17 #include <net.h>
18 #include <usbdescriptors.h> 18 #include <usbdescriptors.h>
19 #include "factoryset.h" 19 #include "factoryset.h"
20 20
21 #define EEPR_PG_SZ 0x80 21 #define EEPR_PG_SZ 0x80
22 #define EEPROM_FATORYSET_OFFSET 0x400 22 #define EEPROM_FATORYSET_OFFSET 0x400
23 #define OFF_PG EEPROM_FATORYSET_OFFSET/EEPR_PG_SZ 23 #define OFF_PG EEPROM_FATORYSET_OFFSET/EEPR_PG_SZ
24 24
25 /* Global variable that contains necessary information from FactorySet */ 25 /* Global variable that contains necessary information from FactorySet */
26 struct factorysetcontainer factory_dat; 26 struct factorysetcontainer factory_dat;
27 27
28 #define fact_get_char(i) *((char *)&eeprom_buf[i]) 28 #define fact_get_char(i) *((char *)&eeprom_buf[i])
29 29
30 static int fact_match(unsigned char *eeprom_buf, uchar *s1, int i2) 30 static int fact_match(unsigned char *eeprom_buf, uchar *s1, int i2)
31 { 31 {
32 if (s1 == NULL) 32 if (s1 == NULL)
33 return -1; 33 return -1;
34 34
35 while (*s1 == fact_get_char(i2++)) 35 while (*s1 == fact_get_char(i2++))
36 if (*s1++ == '=') 36 if (*s1++ == '=')
37 return i2; 37 return i2;
38 38
39 if (*s1 == '\0' && fact_get_char(i2-1) == '=') 39 if (*s1 == '\0' && fact_get_char(i2-1) == '=')
40 return i2; 40 return i2;
41 41
42 return -1; 42 return -1;
43 } 43 }
44 44
45 static int get_factory_val(unsigned char *eeprom_buf, int size, uchar *name, 45 static int get_factory_val(unsigned char *eeprom_buf, int size, uchar *name,
46 uchar *buf, int len) 46 uchar *buf, int len)
47 { 47 {
48 int i, nxt = 0; 48 int i, nxt = 0;
49 49
50 for (i = 0; fact_get_char(i) != '\0'; i = nxt + 1) { 50 for (i = 0; fact_get_char(i) != '\0'; i = nxt + 1) {
51 int val, n; 51 int val, n;
52 52
53 for (nxt = i; fact_get_char(nxt) != '\0'; ++nxt) { 53 for (nxt = i; fact_get_char(nxt) != '\0'; ++nxt) {
54 if (nxt >= size) 54 if (nxt >= size)
55 return -1; 55 return -1;
56 } 56 }
57 57
58 val = fact_match(eeprom_buf, (uchar *)name, i); 58 val = fact_match(eeprom_buf, (uchar *)name, i);
59 if (val < 0) 59 if (val < 0)
60 continue; 60 continue;
61 61
62 /* found; copy out */ 62 /* found; copy out */
63 for (n = 0; n < len; ++n, ++buf) { 63 for (n = 0; n < len; ++n, ++buf) {
64 *buf = fact_get_char(val++); 64 *buf = fact_get_char(val++);
65 if (*buf == '\0') 65 if (*buf == '\0')
66 return n; 66 return n;
67 } 67 }
68 68
69 if (n) 69 if (n)
70 *--buf = '\0'; 70 *--buf = '\0';
71 71
72 printf("env_buf [%d bytes] too small for value of \"%s\"\n", 72 printf("env_buf [%d bytes] too small for value of \"%s\"\n",
73 len, name); 73 len, name);
74 74
75 return n; 75 return n;
76 } 76 }
77 return -1; 77 return -1;
78 } 78 }
79 79
80 static 80 static
81 int get_factory_record_val(unsigned char *eeprom_buf, int size, uchar *record, 81 int get_factory_record_val(unsigned char *eeprom_buf, int size, uchar *record,
82 uchar *name, uchar *buf, int len) 82 uchar *name, uchar *buf, int len)
83 { 83 {
84 int ret = -1; 84 int ret = -1;
85 int i, nxt = 0; 85 int i, nxt = 0;
86 int c; 86 int c;
87 unsigned char end = 0xff; 87 unsigned char end = 0xff;
88 88
89 for (i = 0; fact_get_char(i) != end; i = nxt) { 89 for (i = 0; fact_get_char(i) != end; i = nxt) {
90 nxt = i + 1; 90 nxt = i + 1;
91 if (fact_get_char(i) == '>') { 91 if (fact_get_char(i) == '>') {
92 int pos; 92 int pos;
93 int endpos; 93 int endpos;
94 int z; 94 int z;
95 95
96 c = strncmp((char *)&eeprom_buf[i + 1], (char *)record, 96 c = strncmp((char *)&eeprom_buf[i + 1], (char *)record,
97 strlen((char *)record)); 97 strlen((char *)record));
98 if (c == 0) { 98 if (c == 0) {
99 /* record found */ 99 /* record found */
100 pos = i + strlen((char *)record) + 2; 100 pos = i + strlen((char *)record) + 2;
101 nxt = pos; 101 nxt = pos;
102 /* search for "<" */ 102 /* search for "<" */
103 c = -1; 103 c = -1;
104 for (z = pos; fact_get_char(z) != end; z++) { 104 for (z = pos; fact_get_char(z) != end; z++) {
105 if ((fact_get_char(z) == '<') || 105 if ((fact_get_char(z) == '<') ||
106 (fact_get_char(z) == '>')) { 106 (fact_get_char(z) == '>')) {
107 endpos = z; 107 endpos = z;
108 nxt = endpos; 108 nxt = endpos;
109 c = 0; 109 c = 0;
110 break; 110 break;
111 } 111 }
112 } 112 }
113 } 113 }
114 if (c == 0) { 114 if (c == 0) {
115 /* end found -> call get_factory_val */ 115 /* end found -> call get_factory_val */
116 eeprom_buf[endpos] = end; 116 eeprom_buf[endpos] = end;
117 ret = get_factory_val(&eeprom_buf[pos], 117 ret = get_factory_val(&eeprom_buf[pos],
118 size - pos, name, buf, len); 118 size - pos, name, buf, len);
119 /* fix buffer */ 119 /* fix buffer */
120 eeprom_buf[endpos] = '<'; 120 eeprom_buf[endpos] = '<';
121 debug("%s: %s.%s = %s\n", 121 debug("%s: %s.%s = %s\n",
122 __func__, record, name, buf); 122 __func__, record, name, buf);
123 return ret; 123 return ret;
124 } 124 }
125 } 125 }
126 } 126 }
127 return ret; 127 return ret;
128 } 128 }
129 129
130 int factoryset_read_eeprom(int i2c_addr) 130 int factoryset_read_eeprom(int i2c_addr)
131 { 131 {
132 int i, pages = 0, size = 0; 132 int i, pages = 0, size = 0;
133 unsigned char eeprom_buf[0x3c00], hdr[4], buf[MAX_STRING_LENGTH]; 133 unsigned char eeprom_buf[0x3c00], hdr[4], buf[MAX_STRING_LENGTH];
134 unsigned char *cp, *cp1; 134 unsigned char *cp, *cp1;
135 135
136 #if defined(CONFIG_DFU_FUNCTION) 136 #if defined(CONFIG_DFU_FUNCTION)
137 factory_dat.usb_vendor_id = CONFIG_G_DNL_VENDOR_NUM; 137 factory_dat.usb_vendor_id = CONFIG_G_DNL_VENDOR_NUM;
138 factory_dat.usb_product_id = CONFIG_G_DNL_PRODUCT_NUM; 138 factory_dat.usb_product_id = CONFIG_G_DNL_PRODUCT_NUM;
139 #endif 139 #endif
140 if (i2c_probe(i2c_addr)) 140 if (i2c_probe(i2c_addr))
141 goto err; 141 goto err;
142 142
143 if (i2c_read(i2c_addr, EEPROM_FATORYSET_OFFSET, 2, hdr, sizeof(hdr))) 143 if (i2c_read(i2c_addr, EEPROM_FATORYSET_OFFSET, 2, hdr, sizeof(hdr)))
144 goto err; 144 goto err;
145 145
146 if ((hdr[0] != 0x99) || (hdr[1] != 0x80)) { 146 if ((hdr[0] != 0x99) || (hdr[1] != 0x80)) {
147 printf("FactorySet is not right in eeprom.\n"); 147 printf("FactorySet is not right in eeprom.\n");
148 return 1; 148 return 1;
149 } 149 }
150 150
151 /* get FactorySet size */ 151 /* get FactorySet size */
152 size = (hdr[2] << 8) + hdr[3] + sizeof(hdr); 152 size = (hdr[2] << 8) + hdr[3] + sizeof(hdr);
153 if (size > 0x3bfa) 153 if (size > 0x3bfa)
154 size = 0x3bfa; 154 size = 0x3bfa;
155 155
156 pages = size / EEPR_PG_SZ; 156 pages = size / EEPR_PG_SZ;
157 157
158 /* 158 /*
159 * read the eeprom using i2c 159 * read the eeprom using i2c
160 * I can not read entire eeprom in once, so separate into several 160 * I can not read entire eeprom in once, so separate into several
161 * times. Furthermore, fetch eeprom take longer time, so we fetch 161 * times. Furthermore, fetch eeprom take longer time, so we fetch
162 * data after every time we got a record from eeprom 162 * data after every time we got a record from eeprom
163 */ 163 */
164 debug("Read eeprom page :\n"); 164 debug("Read eeprom page :\n");
165 for (i = 0; i < pages; i++) 165 for (i = 0; i < pages; i++)
166 if (i2c_read(i2c_addr, (OFF_PG + i) * EEPR_PG_SZ, 2, 166 if (i2c_read(i2c_addr, (OFF_PG + i) * EEPR_PG_SZ, 2,
167 eeprom_buf + (i * EEPR_PG_SZ), EEPR_PG_SZ)) 167 eeprom_buf + (i * EEPR_PG_SZ), EEPR_PG_SZ))
168 goto err; 168 goto err;
169 169
170 if (size % EEPR_PG_SZ) 170 if (size % EEPR_PG_SZ)
171 if (i2c_read(i2c_addr, (OFF_PG + pages) * EEPR_PG_SZ, 2, 171 if (i2c_read(i2c_addr, (OFF_PG + pages) * EEPR_PG_SZ, 2,
172 eeprom_buf + (pages * EEPR_PG_SZ), 172 eeprom_buf + (pages * EEPR_PG_SZ),
173 (size % EEPR_PG_SZ))) 173 (size % EEPR_PG_SZ)))
174 goto err; 174 goto err;
175 175
176 /* we do below just for eeprom align */ 176 /* we do below just for eeprom align */
177 for (i = 0; i < size; i++) 177 for (i = 0; i < size; i++)
178 if (eeprom_buf[i] == '\n') 178 if (eeprom_buf[i] == '\n')
179 eeprom_buf[i] = 0; 179 eeprom_buf[i] = 0;
180 180
181 /* skip header */ 181 /* skip header */
182 size -= sizeof(hdr); 182 size -= sizeof(hdr);
183 cp = (uchar *)eeprom_buf + sizeof(hdr); 183 cp = (uchar *)eeprom_buf + sizeof(hdr);
184 184
185 /* get mac address */ 185 /* get mac address */
186 get_factory_record_val(cp, size, (uchar *)"ETH1", (uchar *)"mac", 186 get_factory_record_val(cp, size, (uchar *)"ETH1", (uchar *)"mac",
187 buf, MAX_STRING_LENGTH); 187 buf, MAX_STRING_LENGTH);
188 cp1 = buf; 188 cp1 = buf;
189 for (i = 0; i < 6; i++) { 189 for (i = 0; i < 6; i++) {
190 factory_dat.mac[i] = simple_strtoul((char *)cp1, NULL, 16); 190 factory_dat.mac[i] = simple_strtoul((char *)cp1, NULL, 16);
191 cp1 += 3; 191 cp1 += 3;
192 } 192 }
193 193
194 #if defined(CONFIG_DFU_FUNCTION) 194 #if defined(CONFIG_DFU_FUNCTION)
195 /* read vid and pid for dfu mode */ 195 /* read vid and pid for dfu mode */
196 if (0 <= get_factory_record_val(cp, size, (uchar *)"USBD1", 196 if (0 <= get_factory_record_val(cp, size, (uchar *)"USBD1",
197 (uchar *)"vid", buf, 197 (uchar *)"vid", buf,
198 MAX_STRING_LENGTH)) { 198 MAX_STRING_LENGTH)) {
199 factory_dat.usb_vendor_id = simple_strtoul((char *)buf, 199 factory_dat.usb_vendor_id = simple_strtoul((char *)buf,
200 NULL, 16); 200 NULL, 16);
201 } 201 }
202 202
203 if (0 <= get_factory_record_val(cp, size, (uchar *)"USBD1", 203 if (0 <= get_factory_record_val(cp, size, (uchar *)"USBD1",
204 (uchar *)"pid", buf, 204 (uchar *)"pid", buf,
205 MAX_STRING_LENGTH)) { 205 MAX_STRING_LENGTH)) {
206 factory_dat.usb_product_id = simple_strtoul((char *)buf, 206 factory_dat.usb_product_id = simple_strtoul((char *)buf,
207 NULL, 16); 207 NULL, 16);
208 } 208 }
209 printf("DFU USB: VID = 0x%4x, PID = 0x%4x\n", factory_dat.usb_vendor_id, 209 printf("DFU USB: VID = 0x%4x, PID = 0x%4x\n", factory_dat.usb_vendor_id,
210 factory_dat.usb_product_id); 210 factory_dat.usb_product_id);
211 #endif 211 #endif
212 if (0 <= get_factory_record_val(cp, size, (uchar *)"DEV", 212 if (0 <= get_factory_record_val(cp, size, (uchar *)"DEV",
213 (uchar *)"id", buf, 213 (uchar *)"id", buf,
214 MAX_STRING_LENGTH)) { 214 MAX_STRING_LENGTH)) {
215 if (strncmp((const char *)buf, "PXM50", 5) == 0) 215 if (strncmp((const char *)buf, "PXM50", 5) == 0)
216 factory_dat.pxm50 = 1; 216 factory_dat.pxm50 = 1;
217 else 217 else
218 factory_dat.pxm50 = 0; 218 factory_dat.pxm50 = 0;
219 } 219 }
220 debug("PXM50: %d\n", factory_dat.pxm50); 220 debug("PXM50: %d\n", factory_dat.pxm50);
221 #if defined(CONFIG_VIDEO) 221 #if defined(CONFIG_VIDEO)
222 if (0 <= get_factory_record_val(cp, size, (uchar *)"DISP1", 222 if (0 <= get_factory_record_val(cp, size, (uchar *)"DISP1",
223 (uchar *)"name", factory_dat.disp_name, 223 (uchar *)"name", factory_dat.disp_name,
224 MAX_STRING_LENGTH)) { 224 MAX_STRING_LENGTH)) {
225 debug("display name: %s\n", factory_dat.disp_name); 225 debug("display name: %s\n", factory_dat.disp_name);
226 } 226 }
227 227
228 #endif 228 #endif
229 return 0; 229 return 0;
230 230
231 err: 231 err:
232 printf("Could not read the EEPROM; something fundamentally wrong on the I2C bus.\n"); 232 printf("Could not read the EEPROM; something fundamentally wrong on the I2C bus.\n");
233 return 1; 233 return 1;
234 } 234 }
235 235
236 static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; 236 static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
237 237
238 static int factoryset_mac_setenv(void) 238 static int factoryset_mac_setenv(void)
239 { 239 {
240 uint8_t mac_addr[6]; 240 uint8_t mac_addr[6];
241 241
242 debug("FactorySet: Set mac address\n"); 242 debug("FactorySet: Set mac address\n");
243 if (is_valid_ether_addr(factory_dat.mac)) { 243 if (is_valid_ether_addr(factory_dat.mac)) {
244 memcpy(mac_addr, factory_dat.mac, 6); 244 memcpy(mac_addr, factory_dat.mac, 6);
245 } else { 245 } else {
246 uint32_t mac_hi, mac_lo; 246 uint32_t mac_hi, mac_lo;
247 247
248 debug("Warning: FactorySet: <ethaddr> not set. Fallback to E-fuse\n"); 248 debug("Warning: FactorySet: <ethaddr> not set. Fallback to E-fuse\n");
249 mac_lo = readl(&cdev->macid0l); 249 mac_lo = readl(&cdev->macid0l);
250 mac_hi = readl(&cdev->macid0h); 250 mac_hi = readl(&cdev->macid0h);
251 251
252 mac_addr[0] = mac_hi & 0xFF; 252 mac_addr[0] = mac_hi & 0xFF;
253 mac_addr[1] = (mac_hi & 0xFF00) >> 8; 253 mac_addr[1] = (mac_hi & 0xFF00) >> 8;
254 mac_addr[2] = (mac_hi & 0xFF0000) >> 16; 254 mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
255 mac_addr[3] = (mac_hi & 0xFF000000) >> 24; 255 mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
256 mac_addr[4] = mac_lo & 0xFF; 256 mac_addr[4] = mac_lo & 0xFF;
257 mac_addr[5] = (mac_lo & 0xFF00) >> 8; 257 mac_addr[5] = (mac_lo & 0xFF00) >> 8;
258 if (!is_valid_ether_addr(mac_addr)) { 258 if (!is_valid_ether_addr(mac_addr)) {
259 printf("Warning: ethaddr not set by FactorySet or E-fuse. Set <ethaddr> variable to overcome this.\n"); 259 printf("Warning: ethaddr not set by FactorySet or E-fuse. Set <ethaddr> variable to overcome this.\n");
260 return -1; 260 return -1;
261 } 261 }
262 } 262 }
263 263
264 eth_setenv_enetaddr("ethaddr", mac_addr); 264 eth_setenv_enetaddr("ethaddr", mac_addr);
265 return 0; 265 return 0;
266 } 266 }
267 267
268 int factoryset_setenv(void) 268 int factoryset_setenv(void)
269 { 269 {
270 int ret = 0; 270 int ret = 0;
271 271
272 if (factoryset_mac_setenv() < 0) 272 if (factoryset_mac_setenv() < 0)
273 ret = -1; 273 ret = -1;
274 274
275 return ret; 275 return ret;
276 } 276 }
277 277
278 int g_dnl_bind_fixup(struct usb_device_descriptor *dev) 278 int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
279 { 279 {
280 put_unaligned(factory_dat.usb_vendor_id, &dev->idVendor); 280 put_unaligned(factory_dat.usb_vendor_id, &dev->idVendor);
281 put_unaligned(factory_dat.usb_product_id, &dev->idProduct); 281 put_unaligned(factory_dat.usb_product_id, &dev->idProduct);
282 return 0; 282 return 0;
283 } 283 }
284 #endif /* defined(CONFIG_SPL_BUILD) */ 284 #endif /* defined(CONFIG_SPL_BUILD) */
285 285
drivers/usb/gadget/g_dnl.c
1 /* 1 /*
2 * g_dnl.c -- USB Downloader Gadget 2 * g_dnl.c -- USB Downloader Gadget
3 * 3 *
4 * Copyright (C) 2012 Samsung Electronics 4 * Copyright (C) 2012 Samsung Electronics
5 * Lukasz Majewski <l.majewski@samsung.com> 5 * Lukasz Majewski <l.majewski@samsung.com>
6 * 6 *
7 * SPDX-License-Identifier: GPL-2.0+ 7 * SPDX-License-Identifier: GPL-2.0+
8 */ 8 */
9 9
10 #include <common.h> 10 #include <common.h>
11 #include <malloc.h> 11 #include <malloc.h>
12 12
13 #include <mmc.h> 13 #include <mmc.h>
14 #include <part.h> 14 #include <part.h>
15 15
16 #include <g_dnl.h> 16 #include <g_dnl.h>
17 #include <usb_mass_storage.h> 17 #include <usb_mass_storage.h>
18 #include <dfu.h> 18 #include <dfu.h>
19 19
20 #include "gadget_chips.h" 20 #include "gadget_chips.h"
21 #include "composite.c" 21 #include "composite.c"
22 22
23 /* 23 /*
24 * One needs to define the following: 24 * One needs to define the following:
25 * CONFIG_G_DNL_VENDOR_NUM 25 * CONFIG_G_DNL_VENDOR_NUM
26 * CONFIG_G_DNL_PRODUCT_NUM 26 * CONFIG_G_DNL_PRODUCT_NUM
27 * CONFIG_G_DNL_MANUFACTURER 27 * CONFIG_G_DNL_MANUFACTURER
28 * at e.g. ./include/configs/<board>.h 28 * at e.g. ./include/configs/<board>.h
29 */ 29 */
30 30
31 #define STRING_MANUFACTURER 25 31 #define STRING_MANUFACTURER 25
32 #define STRING_PRODUCT 2 32 #define STRING_PRODUCT 2
33 /* Index of String Descriptor describing this configuration */ 33 /* Index of String Descriptor describing this configuration */
34 #define STRING_USBDOWN 2 34 #define STRING_USBDOWN 2
35 /* Number of supported configurations */ 35 /* Number of supported configurations */
36 #define CONFIGURATION_NUMBER 1 36 #define CONFIGURATION_NUMBER 1
37 37
38 #define DRIVER_VERSION "usb_dnl 2.0" 38 #define DRIVER_VERSION "usb_dnl 2.0"
39 39
40 static const char shortname[] = "usb_dnl_"; 40 static const char shortname[] = "usb_dnl_";
41 static const char product[] = "USB download gadget"; 41 static const char product[] = "USB download gadget";
42 static const char manufacturer[] = CONFIG_G_DNL_MANUFACTURER; 42 static const char manufacturer[] = CONFIG_G_DNL_MANUFACTURER;
43 43
44 static struct usb_device_descriptor device_desc = { 44 static struct usb_device_descriptor device_desc = {
45 .bLength = sizeof device_desc, 45 .bLength = sizeof device_desc,
46 .bDescriptorType = USB_DT_DEVICE, 46 .bDescriptorType = USB_DT_DEVICE,
47 47
48 .bcdUSB = __constant_cpu_to_le16(0x0200), 48 .bcdUSB = __constant_cpu_to_le16(0x0200),
49 .bDeviceClass = USB_CLASS_COMM, 49 .bDeviceClass = USB_CLASS_COMM,
50 .bDeviceSubClass = 0x02, /*0x02:CDC-modem , 0x00:CDC-serial*/ 50 .bDeviceSubClass = 0x02, /*0x02:CDC-modem , 0x00:CDC-serial*/
51 51
52 .idVendor = __constant_cpu_to_le16(CONFIG_G_DNL_VENDOR_NUM), 52 .idVendor = __constant_cpu_to_le16(CONFIG_G_DNL_VENDOR_NUM),
53 .idProduct = __constant_cpu_to_le16(CONFIG_G_DNL_PRODUCT_NUM), 53 .idProduct = __constant_cpu_to_le16(CONFIG_G_DNL_PRODUCT_NUM),
54 .iProduct = STRING_PRODUCT, 54 .iProduct = STRING_PRODUCT,
55 .bNumConfigurations = 1, 55 .bNumConfigurations = 1,
56 }; 56 };
57 57
58 /* 58 /*
59 * static strings, in UTF-8 59 * static strings, in UTF-8
60 * IDs for those strings are assigned dynamically at g_dnl_bind() 60 * IDs for those strings are assigned dynamically at g_dnl_bind()
61 */ 61 */
62 static struct usb_string g_dnl_string_defs[] = { 62 static struct usb_string g_dnl_string_defs[] = {
63 {.s = manufacturer}, 63 {.s = manufacturer},
64 {.s = product}, 64 {.s = product},
65 { } /* end of list */ 65 { } /* end of list */
66 }; 66 };
67 67
68 static struct usb_gadget_strings g_dnl_string_tab = { 68 static struct usb_gadget_strings g_dnl_string_tab = {
69 .language = 0x0409, /* en-us */ 69 .language = 0x0409, /* en-us */
70 .strings = g_dnl_string_defs, 70 .strings = g_dnl_string_defs,
71 }; 71 };
72 72
73 static struct usb_gadget_strings *g_dnl_composite_strings[] = { 73 static struct usb_gadget_strings *g_dnl_composite_strings[] = {
74 &g_dnl_string_tab, 74 &g_dnl_string_tab,
75 NULL, 75 NULL,
76 }; 76 };
77 77
78 static int g_dnl_unbind(struct usb_composite_dev *cdev) 78 static int g_dnl_unbind(struct usb_composite_dev *cdev)
79 { 79 {
80 struct usb_gadget *gadget = cdev->gadget; 80 struct usb_gadget *gadget = cdev->gadget;
81 81
82 free(cdev->config); 82 free(cdev->config);
83 cdev->config = NULL; 83 cdev->config = NULL;
84 debug("%s: calling usb_gadget_disconnect for " 84 debug("%s: calling usb_gadget_disconnect for "
85 "controller '%s'\n", shortname, gadget->name); 85 "controller '%s'\n", shortname, gadget->name);
86 usb_gadget_disconnect(gadget); 86 usb_gadget_disconnect(gadget);
87 87
88 return 0; 88 return 0;
89 } 89 }
90 90
91 static int g_dnl_do_config(struct usb_configuration *c) 91 static int g_dnl_do_config(struct usb_configuration *c)
92 { 92 {
93 const char *s = c->cdev->driver->name; 93 const char *s = c->cdev->driver->name;
94 int ret = -1; 94 int ret = -1;
95 95
96 debug("%s: configuration: 0x%p composite dev: 0x%p\n", 96 debug("%s: configuration: 0x%p composite dev: 0x%p\n",
97 __func__, c, c->cdev); 97 __func__, c, c->cdev);
98 98
99 printf("GADGET DRIVER: %s\n", s); 99 printf("GADGET DRIVER: %s\n", s);
100 if (!strcmp(s, "usb_dnl_dfu")) 100 if (!strcmp(s, "usb_dnl_dfu"))
101 ret = dfu_add(c); 101 ret = dfu_add(c);
102 else if (!strcmp(s, "usb_dnl_ums")) 102 else if (!strcmp(s, "usb_dnl_ums"))
103 ret = fsg_add(c); 103 ret = fsg_add(c);
104 104
105 return ret; 105 return ret;
106 } 106 }
107 107
108 static int g_dnl_config_register(struct usb_composite_dev *cdev) 108 static int g_dnl_config_register(struct usb_composite_dev *cdev)
109 { 109 {
110 struct usb_configuration *config; 110 struct usb_configuration *config;
111 const char *name = "usb_dnload"; 111 const char *name = "usb_dnload";
112 112
113 config = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*config)); 113 config = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*config));
114 if (!config) 114 if (!config)
115 return -ENOMEM; 115 return -ENOMEM;
116 116
117 memset(config, 0, sizeof(*config)); 117 memset(config, 0, sizeof(*config));
118 118
119 config->label = name; 119 config->label = name;
120 config->bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER; 120 config->bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER;
121 config->bConfigurationValue = CONFIGURATION_NUMBER; 121 config->bConfigurationValue = CONFIGURATION_NUMBER;
122 config->iConfiguration = STRING_USBDOWN; 122 config->iConfiguration = STRING_USBDOWN;
123 config->bind = g_dnl_do_config; 123 config->bind = g_dnl_do_config;
124 124
125 return usb_add_config(cdev, config); 125 return usb_add_config(cdev, config);
126 } 126 }
127 127
128 __weak 128 __weak
129 int g_dnl_bind_fixup(struct usb_device_descriptor *dev) 129 int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
130 { 130 {
131 return 0; 131 return 0;
132 } 132 }
133 133
134 static int g_dnl_bind(struct usb_composite_dev *cdev) 134 static int g_dnl_bind(struct usb_composite_dev *cdev)
135 { 135 {
136 struct usb_gadget *gadget = cdev->gadget; 136 struct usb_gadget *gadget = cdev->gadget;
137 int id, ret; 137 int id, ret;
138 int gcnum; 138 int gcnum;
139 139
140 debug("%s: gadget: 0x%p cdev: 0x%p\n", __func__, gadget, cdev); 140 debug("%s: gadget: 0x%p cdev: 0x%p\n", __func__, gadget, cdev);
141 141
142 id = usb_string_id(cdev); 142 id = usb_string_id(cdev);
143 143
144 if (id < 0) 144 if (id < 0)
145 return id; 145 return id;
146 g_dnl_string_defs[0].id = id; 146 g_dnl_string_defs[0].id = id;
147 device_desc.iManufacturer = id; 147 device_desc.iManufacturer = id;
148 148
149 id = usb_string_id(cdev); 149 id = usb_string_id(cdev);
150 if (id < 0) 150 if (id < 0)
151 return id; 151 return id;
152 152
153 g_dnl_string_defs[1].id = id; 153 g_dnl_string_defs[1].id = id;
154 device_desc.iProduct = id; 154 device_desc.iProduct = id;
155 155
156 g_dnl_bind_fixup(&device_desc); 156 g_dnl_bind_fixup(&device_desc, cdev->driver->name);
157 ret = g_dnl_config_register(cdev); 157 ret = g_dnl_config_register(cdev);
158 if (ret) 158 if (ret)
159 goto error; 159 goto error;
160 160
161 gcnum = usb_gadget_controller_number(gadget); 161 gcnum = usb_gadget_controller_number(gadget);
162 162
163 debug("gcnum: %d\n", gcnum); 163 debug("gcnum: %d\n", gcnum);
164 if (gcnum >= 0) 164 if (gcnum >= 0)
165 device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); 165 device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
166 else { 166 else {
167 debug("%s: controller '%s' not recognized\n", 167 debug("%s: controller '%s' not recognized\n",
168 shortname, gadget->name); 168 shortname, gadget->name);
169 device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); 169 device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
170 } 170 }
171 171
172 debug("%s: calling usb_gadget_connect for " 172 debug("%s: calling usb_gadget_connect for "
173 "controller '%s'\n", shortname, gadget->name); 173 "controller '%s'\n", shortname, gadget->name);
174 usb_gadget_connect(gadget); 174 usb_gadget_connect(gadget);
175 175
176 return 0; 176 return 0;
177 177
178 error: 178 error:
179 g_dnl_unbind(cdev); 179 g_dnl_unbind(cdev);
180 return -ENOMEM; 180 return -ENOMEM;
181 } 181 }
182 182
183 static struct usb_composite_driver g_dnl_driver = { 183 static struct usb_composite_driver g_dnl_driver = {
184 .name = NULL, 184 .name = NULL,
185 .dev = &device_desc, 185 .dev = &device_desc,
186 .strings = g_dnl_composite_strings, 186 .strings = g_dnl_composite_strings,
187 187
188 .bind = g_dnl_bind, 188 .bind = g_dnl_bind,
189 .unbind = g_dnl_unbind, 189 .unbind = g_dnl_unbind,
190 }; 190 };
191 191
192 int g_dnl_register(const char *type) 192 int g_dnl_register(const char *type)
193 { 193 {
194 /* We only allow "dfu" atm, so 3 should be enough */ 194 /* We only allow "dfu" atm, so 3 should be enough */
195 static char name[sizeof(shortname) + 3]; 195 static char name[sizeof(shortname) + 3];
196 int ret; 196 int ret;
197 197
198 if (!strcmp(type, "dfu")) { 198 if (!strcmp(type, "dfu")) {
199 strcpy(name, shortname); 199 strcpy(name, shortname);
200 strcat(name, type); 200 strcat(name, type);
201 } else if (!strcmp(type, "ums")) { 201 } else if (!strcmp(type, "ums")) {
202 strcpy(name, shortname); 202 strcpy(name, shortname);
203 strcat(name, type); 203 strcat(name, type);
204 } else { 204 } else {
205 printf("%s: unknown command: %s\n", __func__, type); 205 printf("%s: unknown command: %s\n", __func__, type);
206 return -EINVAL; 206 return -EINVAL;
207 } 207 }
208 208
209 g_dnl_driver.name = name; 209 g_dnl_driver.name = name;
210 210
211 debug("%s: g_dnl_driver.name: %s\n", __func__, g_dnl_driver.name); 211 debug("%s: g_dnl_driver.name: %s\n", __func__, g_dnl_driver.name);
212 ret = usb_composite_register(&g_dnl_driver); 212 ret = usb_composite_register(&g_dnl_driver);
213 213
214 if (ret) { 214 if (ret) {
215 printf("%s: failed!, error: %d\n", __func__, ret); 215 printf("%s: failed!, error: %d\n", __func__, ret);
216 return ret; 216 return ret;
217 } 217 }
218 218
219 return 0; 219 return 0;
220 } 220 }
221 221
222 void g_dnl_unregister(void) 222 void g_dnl_unregister(void)
223 { 223 {
224 usb_composite_unregister(&g_dnl_driver); 224 usb_composite_unregister(&g_dnl_driver);
225 } 225 }
226 226
1 /* 1 /*
2 * Copyright (C) 2012 Samsung Electronics 2 * Copyright (C) 2012 Samsung Electronics
3 * Lukasz Majewski <l.majewski@samsung.com> 3 * Lukasz Majewski <l.majewski@samsung.com>
4 * 4 *
5 * SPDX-License-Identifier: GPL-2.0+ 5 * SPDX-License-Identifier: GPL-2.0+
6 */ 6 */
7 7
8 #ifndef __G_DOWNLOAD_H_ 8 #ifndef __G_DOWNLOAD_H_
9 #define __G_DOWNLOAD_H_ 9 #define __G_DOWNLOAD_H_
10 10
11 #include <linux/usb/ch9.h> 11 #include <linux/usb/ch9.h>
12 #include <linux/usb/gadget.h> 12 #include <linux/usb/gadget.h>
13 int g_dnl_bind_fixup(struct usb_device_descriptor *); 13 int g_dnl_bind_fixup(struct usb_device_descriptor *, const char *);
14 int g_dnl_register(const char *s); 14 int g_dnl_register(const char *s);
15 void g_dnl_unregister(void); 15 void g_dnl_unregister(void);
16 16
17 #endif /* __G_DOWNLOAD_H_ */ 17 #endif /* __G_DOWNLOAD_H_ */
18 18