Add missing copyright header
[maemo-rb.git] / utils / imx_hid_recovery / imx_hid_recovery.c
blobba4645f8abc20f33b09a2591659d1b30735314df
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2010 Amaury Pouly
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <libusb.h>
25 #include <stdint.h>
27 void put32le(uint8_t *buf, uint32_t i)
29 *buf++ = i & 0xff;
30 *buf++ = (i >> 8) & 0xff;
31 *buf++ = (i >> 16) & 0xff;
32 *buf++ = (i >> 24) & 0xff;
35 void put32be(uint8_t *buf, uint32_t i)
37 *buf++ = (i >> 24) & 0xff;
38 *buf++ = (i >> 16) & 0xff;
39 *buf++ = (i >> 8) & 0xff;
40 *buf++ = i & 0xff;
43 int main(int argc, char **argv)
45 int ret;
46 uint8_t msg[0x20];
47 uint8_t *p;
48 FILE *f;
49 int i, xfer_size, nr_xfers, recv_size;
51 if(argc != 3)
53 printf("usage: %s <xfer size> <file>\n", argv[0]);
54 return 1;
57 char *end;
58 xfer_size = strtol(argv[1], &end, 0);
59 if(end != (argv[1] + strlen(argv[1])))
61 printf("Invalid transfer size !\n");
62 return 1;
65 libusb_device_handle *dev;
67 libusb_init(NULL);
69 libusb_set_debug(NULL, 3);
71 /* MX23 */
72 dev = libusb_open_device_with_vid_pid(NULL, 0x066F, 0x3780);
73 if(dev == NULL)
74 /* MX28 */
75 dev = libusb_open_device_with_vid_pid(NULL, 0x15A2, 0x004F);
76 if(dev == NULL)
78 printf("Cannot open device\n");
79 return 1;
82 libusb_detach_kernel_driver(dev, 0);
83 libusb_detach_kernel_driver(dev, 4);
85 libusb_claim_interface (dev, 0);
86 libusb_claim_interface (dev, 4);
88 if (!dev)
90 printf("No dev\n");
91 exit(1);
94 f = fopen(argv[2], "r");
95 if(f == NULL)
97 perror("cannot open file");
98 return 1;
100 fseek(f, 0, SEEK_END);
101 size_t size = ftell(f);
102 fseek(f, 0, SEEK_SET);
104 printf("Transfer size: %d\n", xfer_size);
105 nr_xfers = (size + xfer_size - 1) / xfer_size;
106 uint8_t *file_buf = malloc(nr_xfers * xfer_size);
107 memset(file_buf, 0xff, nr_xfers * xfer_size); // pad with 0xff
108 if(fread(file_buf, size, 1, f) != 1)
110 perror("read error");
111 fclose(f);
112 return 1;
114 fclose(f);
116 memset(msg, 0, 0x20);
118 p = msg;
120 *p++ = 0x01; // Init upload command
121 *p++ = 'B'; // Signature
122 *p++ = 'L';
123 *p++ = 'T';
124 *p++ = 'C';
125 put32le(p, 0x1); // I guess version or sub-command
126 p += 4;
127 put32le(p, size); // Payload size
129 // The second command starts at 0x20
131 p = &msg[0x10];
133 *p++ = 0x02; // Start upload
134 put32be(p, size); // Payload size, again
136 ret = libusb_control_transfer(dev,
137 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 0x9, 0x201, 0,
138 msg, 0x20, 1000);
139 if(ret < 0)
141 printf("transfer error at init step\n");
142 return 1;
145 uint8_t *xfer_buf = malloc(1 + xfer_size);
147 for(i = 0; i < nr_xfers; i++)
149 xfer_buf[0] = 0x2;
150 memcpy(&xfer_buf[1], &file_buf[i * xfer_size], xfer_size);
152 ret = libusb_control_transfer(dev,
153 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
154 0x9, 0x202, 0, xfer_buf, xfer_size + 1, 1000);
155 if(ret < 0)
157 printf("transfer error at send step %d\n", i);
158 return 1;
162 ret = libusb_interrupt_transfer(dev, 0x81, xfer_buf, xfer_size, &recv_size,
163 1000);
164 if(ret < 0)
166 printf("transfer error at final stage\n");
167 return 1;
170 printf("ret %i\n", ret);
172 return 0;