libftdi: (tomj) userspace URB processing (I'm hardcore...)
[libftdi] / ftdi / ftdi.c
CommitLineData
a3da1d95
GE
1/***************************************************************************
2 ftdi.c - description
3 -------------------
4 begin : Fri Apr 4 2003
5 copyright : (C) 2003 by Intra2net AG
5fdb1cb1 6 email : opensource@intra2net.com
a3da1d95
GE
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU Lesser General Public License *
13 * version 2.1 as published by the Free Software Foundation; *
14 * *
15 ***************************************************************************/
0e302db6 16#define _GNU_SOURCE
d9f0cce7 17
a3da1d95 18#include "ftdi.h"
0e302db6
TJ
19#include <sys/ioctl.h>
20#include <sys/time.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23
24/* Internal USB devfs functions. Do not use outside libftdi */
25static struct usbdevfs_urb * ftdi_usbdev_alloc_urb(int iso_packets);
26static int ftdi_usbdev_submit_urb(int fd, struct usbdevfs_urb *urb);
27static int ftdi_usbdev_reap_urb_ndelay(int fd, struct usbdevfs_urb **urb_return);
28
a3da1d95 29
948f9ada
TJ
30/* ftdi_init return codes:
31 0: all fine
6d9aa99f 32 -1: couldn't allocate read buffer
948f9ada 33*/
0e302db6
TJ
34int ftdi_init(struct ftdi_context *ftdi)
35{
a3da1d95 36 ftdi->usb_dev = NULL;
545820ce
TJ
37 ftdi->usb_read_timeout = 5000;
38 ftdi->usb_write_timeout = 5000;
a3da1d95 39
53ad271d 40 ftdi->type = TYPE_BM; /* chip type */
a3da1d95
GE
41 ftdi->baudrate = -1;
42 ftdi->bitbang_enabled = 0;
43
948f9ada
TJ
44 ftdi->readbuffer = NULL;
45 ftdi->readbuffer_offset = 0;
46 ftdi->readbuffer_remaining = 0;
47 ftdi->writebuffer_chunksize = 4096;
48
545820ce
TJ
49 ftdi->interface = 0;
50 ftdi->index = 0;
51 ftdi->in_ep = 0x02;
52 ftdi->out_ep = 0x81;
3119537f 53 ftdi->bitbang_mode = 1; /* 1: Normal bitbang mode, 2: SPI bitbang mode */
53ad271d 54
a3da1d95
GE
55 ftdi->error_str = NULL;
56
0e302db6
TJ
57 ftdi->urb = ftdi_usbdev_alloc_urb(0);
58 if (!ftdi->urb) {
59 ftdi->error_str = "out of memory for read URB";
60 return -1;
61 }
62
948f9ada
TJ
63 // all fine. Now allocate the readbuffer
64 return ftdi_read_data_set_chunksize(ftdi, 4096);
65}
66
67
0e302db6
TJ
68void ftdi_deinit(struct ftdi_context *ftdi)
69{
948f9ada 70 if (ftdi->readbuffer != NULL) {
d9f0cce7
TJ
71 free(ftdi->readbuffer);
72 ftdi->readbuffer = NULL;
948f9ada 73 }
0e302db6
TJ
74
75 if (ftdi->urb != NULL) {
76 free (ftdi->urb);
77 ftdi->urb = NULL;
78 }
a3da1d95
GE
79}
80
81
0e302db6
TJ
82void ftdi_set_usbdev (struct ftdi_context *ftdi, usb_dev_handle *usb)
83{
a3da1d95
GE
84 ftdi->usb_dev = usb;
85}
86
a3da1d95
GE
87/* ftdi_usb_open return codes:
88 0: all fine
89 -1: usb_find_busses() failed
90 -2: usb_find_devices() failed
91 -3: usb device not found
92 -4: unable to open device
93 -5: unable to claim device
94 -6: reset failed
95 -7: set baudrate failed
96*/
97int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product) {
98 struct usb_bus *bus;
99 struct usb_device *dev;
100
101 usb_init();
102
103 if (usb_find_busses() < 0) {
104 ftdi->error_str = "usb_find_busses() failed";
105 return -1;
106 }
107
108 if (usb_find_devices() < 0) {
109 ftdi->error_str = "usb_find_devices() failed";
110 return -2;
111 }
112
113 for (bus = usb_busses; bus; bus = bus->next) {
114 for (dev = bus->devices; dev; dev = dev->next) {
115 if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) {
116 ftdi->usb_dev = usb_open(dev);
117 if (ftdi->usb_dev) {
545820ce 118 if (usb_claim_interface(ftdi->usb_dev, ftdi->interface) != 0) {
53ad271d 119 ftdi->error_str = "unable to claim usb device. Make sure ftdi_sio is unloaded!";
a3da1d95
GE
120 return -5;
121 }
122
123 if (ftdi_usb_reset (ftdi) != 0)
d9f0cce7 124 return -6;
a3da1d95
GE
125
126 if (ftdi_set_baudrate (ftdi, 9600) != 0)
d9f0cce7 127 return -7;
a3da1d95 128
de22df10
TJ
129 // Try to guess chip type
130 // Bug in the BM type chips: bcdDevice is 0x200 for serial == 0
131 if (dev->descriptor.bcdDevice == 0x400 || (dev->descriptor.bcdDevice == 0x200
132 && dev->descriptor.iSerialNumber == 0))
133 ftdi->type = TYPE_BM;
134 else if (dev->descriptor.bcdDevice == 0x200)
135 ftdi->type = TYPE_AM;
136 else if (dev->descriptor.bcdDevice == 0x500)
137 ftdi->type = TYPE_2232C;
138
a3da1d95
GE
139 return 0;
140 } else {
141 ftdi->error_str = "usb_open() failed";
142 return -4;
143 }
144 }
145 }
146
147 }
148
149 // device not found
150 return -3;
151}
152
153
154int ftdi_usb_reset(struct ftdi_context *ftdi) {
545820ce 155 if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 0, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
156 ftdi->error_str = "FTDI reset failed";
157 return -1;
158 }
545820ce 159 // Invalidate data in the readbuffer
bfcee05b
TJ
160 ftdi->readbuffer_offset = 0;
161 ftdi->readbuffer_remaining = 0;
162
a3da1d95
GE
163 return 0;
164}
165
a60be878 166int ftdi_usb_purge_buffers(struct ftdi_context *ftdi) {
545820ce 167 if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 1, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a60be878
TJ
168 ftdi->error_str = "FTDI purge of RX buffer failed";
169 return -1;
170 }
545820ce 171 // Invalidate data in the readbuffer
bfcee05b
TJ
172 ftdi->readbuffer_offset = 0;
173 ftdi->readbuffer_remaining = 0;
a60be878 174
545820ce 175 if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 2, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a60be878
TJ
176 ftdi->error_str = "FTDI purge of TX buffer failed";
177 return -1;
178 }
179
545820ce 180
a60be878
TJ
181 return 0;
182}
a3da1d95
GE
183
184/* ftdi_usb_close return codes
185 0: all fine
186 -1: usb_release failed
187 -2: usb_close failed
188*/
189int ftdi_usb_close(struct ftdi_context *ftdi) {
190 int rtn = 0;
191
545820ce 192 if (usb_release_interface(ftdi->usb_dev, ftdi->interface) != 0)
a3da1d95
GE
193 rtn = -1;
194
195 if (usb_close (ftdi->usb_dev) != 0)
196 rtn = -2;
197
198 return rtn;
199}
200
201
202/*
53ad271d
TJ
203 ftdi_convert_baudrate returns nearest supported baud rate to that requested.
204 Function is only used internally
205*/
0126d22e 206static int ftdi_convert_baudrate(int baudrate, struct ftdi_context *ftdi,
53ad271d
TJ
207 unsigned short *value, unsigned short *index) {
208 static const char am_adjust_up[8] = {0, 0, 0, 1, 0, 3, 2, 1};
209 static const char am_adjust_dn[8] = {0, 0, 0, 1, 0, 1, 2, 3};
210 static const char frac_code[8] = {0, 3, 2, 4, 1, 5, 6, 7};
211 int divisor, best_divisor, best_baud, best_baud_diff;
212 unsigned long encoded_divisor;
213 int i;
214
215 if (baudrate <= 0) {
216 // Return error
217 return -1;
218 }
219
220 divisor = 24000000 / baudrate;
221
0126d22e 222 if (ftdi->type == TYPE_AM) {
53ad271d
TJ
223 // Round down to supported fraction (AM only)
224 divisor -= am_adjust_dn[divisor & 7];
225 }
226
227 // Try this divisor and the one above it (because division rounds down)
228 best_divisor = 0;
229 best_baud = 0;
230 best_baud_diff = 0;
231 for (i = 0; i < 2; i++) {
232 int try_divisor = divisor + i;
233 int baud_estimate;
234 int baud_diff;
235
236 // Round up to supported divisor value
237 if (try_divisor < 8) {
238 // Round up to minimum supported divisor
239 try_divisor = 8;
0126d22e 240 } else if (ftdi->type != TYPE_AM && try_divisor < 12) {
53ad271d
TJ
241 // BM doesn't support divisors 9 through 11 inclusive
242 try_divisor = 12;
243 } else if (divisor < 16) {
244 // AM doesn't support divisors 9 through 15 inclusive
245 try_divisor = 16;
246 } else {
0126d22e 247 if (ftdi->type == TYPE_AM) {
53ad271d
TJ
248 // Round up to supported fraction (AM only)
249 try_divisor += am_adjust_up[try_divisor & 7];
250 if (try_divisor > 0x1FFF8) {
251 // Round down to maximum supported divisor value (for AM)
252 try_divisor = 0x1FFF8;
253 }
254 } else {
255 if (try_divisor > 0x1FFFF) {
256 // Round down to maximum supported divisor value (for BM)
257 try_divisor = 0x1FFFF;
258 }
259 }
260 }
261 // Get estimated baud rate (to nearest integer)
262 baud_estimate = (24000000 + (try_divisor / 2)) / try_divisor;
263 // Get absolute difference from requested baud rate
264 if (baud_estimate < baudrate) {
265 baud_diff = baudrate - baud_estimate;
266 } else {
267 baud_diff = baud_estimate - baudrate;
268 }
269 if (i == 0 || baud_diff < best_baud_diff) {
270 // Closest to requested baud rate so far
271 best_divisor = try_divisor;
272 best_baud = baud_estimate;
273 best_baud_diff = baud_diff;
274 if (baud_diff == 0) {
275 // Spot on! No point trying
276 break;
277 }
278 }
279 }
280 // Encode the best divisor value
281 encoded_divisor = (best_divisor >> 3) | (frac_code[best_divisor & 7] << 14);
282 // Deal with special cases for encoded value
283 if (encoded_divisor == 1) {
284 encoded_divisor = 0; // 3000000 baud
285 } else if (encoded_divisor == 0x4001) {
286 encoded_divisor = 1; // 2000000 baud (BM only)
287 }
288 // Split into "value" and "index" values
289 *value = (unsigned short)(encoded_divisor & 0xFFFF);
de22df10 290 if(ftdi->type == TYPE_2232C) {
0126d22e
TJ
291 *index = (unsigned short)(encoded_divisor >> 8);
292 *index &= 0xFF00;
293 *index |= ftdi->interface;
294 }
295 else
296 *index = (unsigned short)(encoded_divisor >> 16);
297
53ad271d
TJ
298 // Return the nearest baud rate
299 return best_baud;
300}
301
302/*
a3da1d95
GE
303 ftdi_set_baudrate return codes:
304 0: all fine
305 -1: invalid baudrate
306 -2: setting baudrate failed
307*/
308int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate) {
53ad271d
TJ
309 unsigned short value, index;
310 int actual_baudrate;
a3da1d95
GE
311
312 if (ftdi->bitbang_enabled) {
313 baudrate = baudrate*4;
314 }
315
25707904 316 actual_baudrate = ftdi_convert_baudrate(baudrate, ftdi, &value, &index);
53ad271d
TJ
317 if (actual_baudrate <= 0) {
318 ftdi->error_str = "Silly baudrate <= 0.";
a3da1d95
GE
319 return -1;
320 }
321
53ad271d
TJ
322 // Check within tolerance (about 5%)
323 if ((actual_baudrate * 2 < baudrate /* Catch overflows */ )
324 || ((actual_baudrate < baudrate)
325 ? (actual_baudrate * 21 < baudrate * 20)
326 : (baudrate * 21 < actual_baudrate * 20))) {
327 ftdi->error_str = "Unsupported baudrate. Note: bitbang baudrates are automatically multiplied by 4";
328 return -1;
329 }
545820ce 330
53ad271d 331 if (usb_control_msg(ftdi->usb_dev, 0x40, 3, value, index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
332 ftdi->error_str = "Setting new baudrate failed";
333 return -2;
334 }
335
336 ftdi->baudrate = baudrate;
337 return 0;
338}
339
340
be5d7eec 341int ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
a3da1d95
GE
342 int ret;
343 int offset = 0;
545820ce 344 int total_written = 0;
a3da1d95 345 while (offset < size) {
948f9ada 346 int write_size = ftdi->writebuffer_chunksize;
a3da1d95
GE
347
348 if (offset+write_size > size)
349 write_size = size-offset;
350
545820ce 351 ret = usb_bulk_write(ftdi->usb_dev, ftdi->in_ep, buf+offset, write_size, ftdi->usb_write_timeout);
cbabb7d3 352 if (ret == -1) {
d9f0cce7 353 ftdi->error_str = "bulk write failed";
a3da1d95 354 return -1;
d9f0cce7 355 }
545820ce 356 total_written += ret;
a3da1d95
GE
357
358 offset += write_size;
359 }
360
545820ce 361 return total_written;
a3da1d95
GE
362}
363
364
948f9ada
TJ
365int ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
366 ftdi->writebuffer_chunksize = chunksize;
367 return 0;
368}
369
370
371int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize) {
372 *chunksize = ftdi->writebuffer_chunksize;
373 return 0;
374}
cbabb7d3 375
948f9ada
TJ
376
377int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
0e302db6
TJ
378 struct timeval tv, tv_ref, tv_now;
379 struct usbdevfs_urb *returned_urb;
380 int offset = 0, ret = 1, waiting;
d9f0cce7 381
948f9ada
TJ
382 // everything we want is still in the readbuffer?
383 if (size <= ftdi->readbuffer_remaining) {
d9f0cce7
TJ
384 memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, size);
385
386 // Fix offsets
387 ftdi->readbuffer_remaining -= size;
388 ftdi->readbuffer_offset += size;
389
545820ce 390 /* printf("Returning bytes from buffer: %d - remaining: %d\n", size, ftdi->readbuffer_remaining); */
d9f0cce7
TJ
391
392 return size;
979a145c 393 }
948f9ada
TJ
394 // something still in the readbuffer, but not enough to satisfy 'size'?
395 if (ftdi->readbuffer_remaining != 0) {
d9f0cce7 396 memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, ftdi->readbuffer_remaining);
979a145c 397
d9f0cce7
TJ
398 // Fix offset
399 offset += ftdi->readbuffer_remaining;
948f9ada 400 }
0e302db6 401
948f9ada 402 // do the actual USB read
cbabb7d3 403 while (offset < size && ret > 0) {
d9f0cce7
TJ
404 ftdi->readbuffer_remaining = 0;
405 ftdi->readbuffer_offset = 0;
0e302db6
TJ
406
407 /*
408 // Old read functions, not status byte safe!
409 // returns how much received
410 ret = usb_bulk_read (ftdi->usb_dev, ftdi->out_ep, ftdi->readbuffer,
411 ftdi->readbuffer_chunksize, ftdi->usb_read_timeout);
412 */
413
414 /* Real userspace URB processing to cope with
415 a race condition where two or more status bytes
416 could already be in the kernel USB buffer */
417 memset(ftdi->urb, 0, sizeof(struct usbdevfs_urb));
418
419 ftdi->urb->type = USBDEVFS_URB_TYPE_BULK;
420 ftdi->urb->endpoint = ftdi->out_ep | USB_DIR_IN;
421 ftdi->urb->buffer = ftdi->readbuffer;
422 ftdi->urb->buffer_length = ftdi->readbuffer_chunksize;
423
424 /* Submit URB to USB layer */
425 if (ftdi_usbdev_submit_urb(ftdi->usb_dev->fd, ftdi->urb) == -1) {
426 ftdi->error_str = "ftdi_usbdev_submit_urb for bulk read failed";
cbabb7d3 427 return -1;
d9f0cce7 428 }
0e302db6
TJ
429
430 /* Wait for the result to come in.
431 Timer stuff is borrowed from libusb's interrupt transfer */
432 gettimeofday(&tv_ref, NULL);
433 tv_ref.tv_sec = tv_ref.tv_sec + ftdi->usb_read_timeout / 1000;
434 tv_ref.tv_usec = tv_ref.tv_usec + (ftdi->usb_read_timeout % 1000) * 1000;
435
436 if (tv_ref.tv_usec > 1e6) {
437 tv_ref.tv_usec -= 1e6;
438 tv_ref.tv_sec++;
439 }
440
441 waiting = 1;
442 memset (&tv, 0, sizeof (struct timeval));
443 while (((ret = ftdi_usbdev_reap_urb_ndelay(ftdi->usb_dev->fd, &returned_urb)) == -1) && waiting) {
444 tv.tv_sec = 0;
445 tv.tv_usec = 1000; // 1 msec
446 select(0, NULL, NULL, NULL, &tv); //sub second wait
447
448 /* compare with actual time, as the select timeout is not that precise */
449 gettimeofday(&tv_now, NULL);
450
451 if ((tv_now.tv_sec > tv_ref.tv_sec) ||
452 ((tv_now.tv_sec == tv_ref.tv_sec) && (tv_now.tv_usec >= tv_ref.tv_usec)))
453 waiting = 0;
454 }
455
456 if (!waiting) {
457 ftdi->error_str = "timeout during ftdi_read_data";
458 return -1;
459 }
460
461 if (ret < 0) {
462 ftdi->error_str = "ftdi_usbdev_reap_urb for bulk read failed";
463 return -1;
464 }
465
466 if (returned_urb->status) {
467 ftdi->error_str = "URB return status not OK";
468 return -1;
469 }
470
471 /* Paranoia check */
472 if (returned_urb->buffer != ftdi->readbuffer) {
473 ftdi->error_str = "buffer paranoia check failed";
474 return -1;
475 }
476
477 ret = returned_urb->actual_length;
d9f0cce7
TJ
478 if (ret > 2) {
479 // skip FTDI status bytes.
480 // Maybe stored in the future to enable modem use
481 ftdi->readbuffer_offset += 2;
482 ret -= 2;
483 } else if (ret <= 2) {
484 // no more data to read?
485 return offset;
486 }
d9f0cce7
TJ
487 if (ret > 0) {
488 // data still fits in buf?
489 if (offset+ret <= size) {
490 memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, ret);
545820ce 491 //printf("buf[0] = %X, buf[1] = %X\n", buf[0], buf[1]);
d9f0cce7
TJ
492 offset += ret;
493
53ad271d 494 /* Did we read exactly the right amount of bytes? */
d9f0cce7
TJ
495 if (offset == size)
496 return offset;
497 } else {
498 // only copy part of the data or size <= readbuffer_chunksize
499 int part_size = size-offset;
500 memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, part_size);
0e302db6 501
d9f0cce7
TJ
502 ftdi->readbuffer_offset += part_size;
503 ftdi->readbuffer_remaining = ret-part_size;
504 offset += part_size;
505
53ad271d
TJ
506 /* printf("Returning part: %d - size: %d - offset: %d - ret: %d - remaining: %d\n",
507 part_size, size, offset, ret, ftdi->readbuffer_remaining); */
d9f0cce7
TJ
508
509 return offset;
510 }
511 }
cbabb7d3 512 }
948f9ada
TJ
513 // never reached
514 return -2;
a3da1d95
GE
515}
516
517
948f9ada
TJ
518int ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
519 // Invalidate all remaining data
520 ftdi->readbuffer_offset = 0;
521 ftdi->readbuffer_remaining = 0;
522
523 unsigned char *new_buf;
524 if ((new_buf = (unsigned char *)realloc(ftdi->readbuffer, chunksize)) == NULL) {
d9f0cce7
TJ
525 ftdi->error_str = "out of memory for readbuffer";
526 return -1;
948f9ada 527 }
d9f0cce7 528
948f9ada
TJ
529 ftdi->readbuffer = new_buf;
530 ftdi->readbuffer_chunksize = chunksize;
531
532 return 0;
533}
534
535
25707904 536int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize) {
948f9ada
TJ
537 *chunksize = ftdi->readbuffer_chunksize;
538 return 0;
539}
540
541
542
a3da1d95
GE
543int ftdi_enable_bitbang(struct ftdi_context *ftdi, unsigned char bitmask) {
544 unsigned short usb_val;
545
d9f0cce7 546 usb_val = bitmask; // low byte: bitmask
3119537f
TJ
547 /* FT2232C: Set bitbang_mode to 2 to enable SPI */
548 usb_val |= (ftdi->bitbang_mode << 8);
549
545820ce 550 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
551 ftdi->error_str = "Unable to enter bitbang mode. Perhaps not a BM type chip?";
552 return -1;
553 }
a3da1d95
GE
554 ftdi->bitbang_enabled = 1;
555 return 0;
556}
557
558
559int ftdi_disable_bitbang(struct ftdi_context *ftdi) {
545820ce 560 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, 0, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
561 ftdi->error_str = "Unable to leave bitbang mode. Perhaps not a BM type chip?";
562 return -1;
563 }
564
565 ftdi->bitbang_enabled = 0;
566 return 0;
567}
568
569
570int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins) {
571 unsigned short usb_val;
545820ce 572 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0C, 0, ftdi->index, (char *)&usb_val, 1, ftdi->usb_read_timeout) != 1) {
a3da1d95
GE
573 ftdi->error_str = "Read pins failed";
574 return -1;
575 }
576
577 *pins = (unsigned char)usb_val;
578 return 0;
579}
580
581
582int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency) {
583 unsigned short usb_val;
584
585 if (latency < 1) {
d9f0cce7
TJ
586 ftdi->error_str = "Latency out of range. Only valid for 1-255";
587 return -1;
a3da1d95
GE
588 }
589
d79d2e68 590 usb_val = latency;
545820ce 591 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x09, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
d9f0cce7
TJ
592 ftdi->error_str = "Unable to set latency timer";
593 return -2;
a3da1d95
GE
594 }
595 return 0;
596}
597
598
599int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency) {
600 unsigned short usb_val;
545820ce 601 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0A, 0, ftdi->index, (char *)&usb_val, 1, ftdi->usb_read_timeout) != 1) {
a3da1d95
GE
602 ftdi->error_str = "Reading latency timer failed";
603 return -1;
604 }
605
606 *latency = (unsigned char)usb_val;
607 return 0;
608}
609
610
b8aa7b35 611void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom) {
f396dbad
TJ
612 eeprom->vendor_id = 0x0403;
613 eeprom->product_id = 0x6001;
d9f0cce7 614
b8aa7b35
TJ
615 eeprom->self_powered = 1;
616 eeprom->remote_wakeup = 1;
617 eeprom->BM_type_chip = 1;
d9f0cce7 618
b8aa7b35
TJ
619 eeprom->in_is_isochronous = 0;
620 eeprom->out_is_isochronous = 0;
621 eeprom->suspend_pull_downs = 0;
d9f0cce7 622
b8aa7b35
TJ
623 eeprom->use_serial = 0;
624 eeprom->change_usb_version = 0;
f396dbad 625 eeprom->usb_version = 0x0200;
b8aa7b35 626 eeprom->max_power = 0;
d9f0cce7 627
b8aa7b35
TJ
628 eeprom->manufacturer = NULL;
629 eeprom->product = NULL;
630 eeprom->serial = NULL;
631}
632
633
634/*
635 ftdi_eeprom_build return codes:
8ed61121 636 positive value: used eeprom size
b8aa7b35
TJ
637 -1: eeprom size (128 bytes) exceeded by custom strings
638*/
639int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output) {
640 unsigned char i, j;
641 unsigned short checksum, value;
642 unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0;
643 int size_check;
644
645 if (eeprom->manufacturer != NULL)
d9f0cce7 646 manufacturer_size = strlen(eeprom->manufacturer);
b8aa7b35 647 if (eeprom->product != NULL)
d9f0cce7 648 product_size = strlen(eeprom->product);
b8aa7b35 649 if (eeprom->serial != NULL)
d9f0cce7 650 serial_size = strlen(eeprom->serial);
b8aa7b35 651
d9f0cce7
TJ
652 size_check = 128; // eeprom is 128 bytes
653 size_check -= 28; // 28 are always in use (fixed)
b8aa7b35
TJ
654 size_check -= manufacturer_size*2;
655 size_check -= product_size*2;
656 size_check -= serial_size*2;
657
658 // eeprom size exceeded?
659 if (size_check < 0)
d9f0cce7 660 return (-1);
b8aa7b35
TJ
661
662 // empty eeprom
663 memset (output, 0, 128);
664
665 // Addr 00: Stay 00 00
666 // Addr 02: Vendor ID
667 output[0x02] = eeprom->vendor_id;
668 output[0x03] = eeprom->vendor_id >> 8;
669
670 // Addr 04: Product ID
671 output[0x04] = eeprom->product_id;
672 output[0x05] = eeprom->product_id >> 8;
673
674 // Addr 06: Device release number (0400h for BM features)
675 output[0x06] = 0x00;
d9f0cce7 676
b8aa7b35 677 if (eeprom->BM_type_chip == 1)
d9f0cce7 678 output[0x07] = 0x04;
b8aa7b35 679 else
d9f0cce7 680 output[0x07] = 0x02;
b8aa7b35
TJ
681
682 // Addr 08: Config descriptor
683 // Bit 1: remote wakeup if 1
684 // Bit 0: self powered if 1
685 //
686 j = 0;
687 if (eeprom->self_powered == 1)
d9f0cce7 688 j = j | 1;
b8aa7b35 689 if (eeprom->remote_wakeup == 1)
d9f0cce7 690 j = j | 2;
b8aa7b35
TJ
691 output[0x08] = j;
692
693 // Addr 09: Max power consumption: max power = value * 2 mA
d9f0cce7
TJ
694 output[0x09] = eeprom->max_power;
695 ;
696
b8aa7b35
TJ
697 // Addr 0A: Chip configuration
698 // Bit 7: 0 - reserved
699 // Bit 6: 0 - reserved
700 // Bit 5: 0 - reserved
701 // Bit 4: 1 - Change USB version
702 // Bit 3: 1 - Use the serial number string
703 // Bit 2: 1 - Enable suspend pull downs for lower power
704 // Bit 1: 1 - Out EndPoint is Isochronous
705 // Bit 0: 1 - In EndPoint is Isochronous
706 //
707 j = 0;
708 if (eeprom->in_is_isochronous == 1)
d9f0cce7 709 j = j | 1;
b8aa7b35 710 if (eeprom->out_is_isochronous == 1)
d9f0cce7 711 j = j | 2;
b8aa7b35 712 if (eeprom->suspend_pull_downs == 1)
d9f0cce7 713 j = j | 4;
b8aa7b35 714 if (eeprom->use_serial == 1)
d9f0cce7 715 j = j | 8;
b8aa7b35 716 if (eeprom->change_usb_version == 1)
d9f0cce7 717 j = j | 16;
b8aa7b35 718 output[0x0A] = j;
d9f0cce7 719
b8aa7b35
TJ
720 // Addr 0B: reserved
721 output[0x0B] = 0x00;
d9f0cce7 722
b8aa7b35
TJ
723 // Addr 0C: USB version low byte when 0x0A bit 4 is set
724 // Addr 0D: USB version high byte when 0x0A bit 4 is set
725 if (eeprom->change_usb_version == 1) {
726 output[0x0C] = eeprom->usb_version;
d9f0cce7 727 output[0x0D] = eeprom->usb_version >> 8;
b8aa7b35
TJ
728 }
729
730
731 // Addr 0E: Offset of the manufacturer string + 0x80
732 output[0x0E] = 0x14 + 0x80;
733
734 // Addr 0F: Length of manufacturer string
735 output[0x0F] = manufacturer_size*2 + 2;
736
737 // Addr 10: Offset of the product string + 0x80, calculated later
738 // Addr 11: Length of product string
739 output[0x11] = product_size*2 + 2;
740
741 // Addr 12: Offset of the serial string + 0x80, calculated later
742 // Addr 13: Length of serial string
743 output[0x13] = serial_size*2 + 2;
744
745 // Dynamic content
a862ddcf 746 output[0x14] = manufacturer_size*2 + 2;
d9f0cce7
TJ
747 output[0x15] = 0x03; // type: string
748
b8aa7b35 749 i = 0x16, j = 0;
d9f0cce7 750
b8aa7b35
TJ
751 // Output manufacturer
752 for (j = 0; j < manufacturer_size; j++) {
d9f0cce7
TJ
753 output[i] = eeprom->manufacturer[j], i++;
754 output[i] = 0x00, i++;
b8aa7b35
TJ
755 }
756
757 // Output product name
d9f0cce7 758 output[0x10] = i + 0x80; // calculate offset
b8aa7b35
TJ
759 output[i] = product_size*2 + 2, i++;
760 output[i] = 0x03, i++;
761 for (j = 0; j < product_size; j++) {
d9f0cce7
TJ
762 output[i] = eeprom->product[j], i++;
763 output[i] = 0x00, i++;
b8aa7b35 764 }
d9f0cce7 765
b8aa7b35 766 // Output serial
d9f0cce7 767 output[0x12] = i + 0x80; // calculate offset
b8aa7b35
TJ
768 output[i] = serial_size*2 + 2, i++;
769 output[i] = 0x03, i++;
770 for (j = 0; j < serial_size; j++) {
d9f0cce7
TJ
771 output[i] = eeprom->serial[j], i++;
772 output[i] = 0x00, i++;
b8aa7b35
TJ
773 }
774
775 // calculate checksum
776 checksum = 0xAAAA;
d9f0cce7 777
b8aa7b35 778 for (i = 0; i < 63; i++) {
d9f0cce7
TJ
779 value = output[i*2];
780 value += output[(i*2)+1] << 8;
b8aa7b35 781
d9f0cce7
TJ
782 checksum = value^checksum;
783 checksum = (checksum << 1) | (checksum >> 15);
b8aa7b35
TJ
784 }
785
786 output[0x7E] = checksum;
d9f0cce7 787 output[0x7F] = checksum >> 8;
b8aa7b35 788
8ed61121 789 return size_check;
b8aa7b35
TJ
790}
791
792
be5d7eec 793int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
a3da1d95
GE
794 int i;
795
796 for (i = 0; i < 64; i++) {
545820ce 797 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, i, eeprom+(i*2), 2, ftdi->usb_read_timeout) != 2) {
d9f0cce7
TJ
798 ftdi->error_str = "Reading eeprom failed";
799 return -1;
a3da1d95
GE
800 }
801 }
802
803 return 0;
804}
805
806
be5d7eec 807int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
a3da1d95
GE
808 unsigned short usb_val;
809 int i;
810
811 for (i = 0; i < 64; i++) {
d9f0cce7
TJ
812 usb_val = eeprom[i*2];
813 usb_val += eeprom[(i*2)+1] << 8;
545820ce 814 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x91, usb_val, i, NULL, 0, ftdi->usb_write_timeout) != 0) {
d9f0cce7
TJ
815 ftdi->error_str = "Unable to write eeprom";
816 return -1;
817 }
a3da1d95
GE
818 }
819
820 return 0;
821}
822
823
824int ftdi_erase_eeprom(struct ftdi_context *ftdi) {
545820ce 825 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x92, 0, 0, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
826 ftdi->error_str = "Unable to erase eeprom";
827 return -1;
828 }
829
830 return 0;
831}
0e302db6
TJ
832
833
834/* Functions needed for userspace URB processing */
835static struct usbdevfs_urb * ftdi_usbdev_alloc_urb(int iso_packets)
836{
837 return calloc(sizeof(struct usbdevfs_urb)
838 + iso_packets * sizeof(struct usbdevfs_iso_packet_desc),
839 1);
840}
841
842
843static int ftdi_usbdev_submit_urb(int fd, struct usbdevfs_urb *urb)
844{
845 return ioctl(fd, USBDEVFS_SUBMITURB, urb);
846}
847
848
849static int ftdi_usbdev_reap_urb_ndelay(int fd, struct usbdevfs_urb **urb_return)
850{
851 return ioctl(fd, USBDEVFS_REAPURBNDELAY, urb_return);
852}