1 /* $NetBSD: ezload.c,v 1.11 2006/04/14 17:21:17 christos Exp $ */
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson <lennart@augustsson.net>.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: ezload.c,v 1.11 2006/04/14 17:21:17 christos Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/device.h>
41 #include <dev/usb/usb.h>
42 #include <dev/usb/usbdi.h>
43 #include <dev/usb/usbdi_util.h>
45 #include <dev/usb/ezload.h>
48 * Vendor specific request code for Anchor Upload/Download
51 /* This one is implemented in the core */
52 #define ANCHOR_LOAD_INTERNAL 0xA0
54 /* This is the highest internal RAM address for the AN2131Q */
55 #define ANCHOR_MAX_INTERNAL_ADDRESS 0x1B3F
58 * EZ-USB Control and Status Register. Bit 0 controls 8051 reset
60 #define ANCHOR_CPUCS_REG 0x7F92
61 #define ANCHOR_RESET 0x01
64 * Although USB does not limit you here, the Anchor docs
65 * quote 64 as a limit, and Mato@activewireinc.com suggested
68 #define ANCHOR_CHUNK 16
71 * This is a firmware loader for ezusb (Anchor) devices. When the firmware
72 * has been downloaded the device will simulate a disconnect and when it
73 * is next recognized by the USB software it will appear as another
78 #define DPRINTF(x) if (ezloaddebug) printf x
79 #define DPRINTFN(n,x) if (ezloaddebug>(n)) printf x
87 ezload_reset(usbd_device_handle dev
, int reset
)
89 usb_device_request_t req
;
92 DPRINTF(("ezload_reset: reset=%d\n", reset
));
94 rst
= reset
? ANCHOR_RESET
: 0;
95 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
96 req
.bRequest
= ANCHOR_LOAD_INTERNAL
;
97 USETW(req
.wValue
, ANCHOR_CPUCS_REG
);
99 USETW(req
.wLength
, 1);
100 return (usbd_do_request(dev
, &req
, &rst
));
104 ezload_download(usbd_device_handle dev
, const struct ezdata
*rec
)
106 usb_device_request_t req
;
107 const struct ezdata
*ptr
;
111 DPRINTF(("ezload_down record=%p\n", rec
));
113 for (ptr
= rec
; ptr
->length
!= 0; ptr
++) {
116 if (ptr
->address
+ ptr
->length
> ANCHOR_MAX_INTERNAL_ADDRESS
)
120 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
121 req
.bRequest
= ANCHOR_LOAD_INTERNAL
;
122 USETW(req
.wIndex
, 0);
123 for (offs
= 0; offs
< ptr
->length
; offs
+= ANCHOR_CHUNK
) {
124 len
= ptr
->length
- offs
;
125 if (len
> ANCHOR_CHUNK
)
127 USETW(req
.wValue
, ptr
->address
+ offs
);
128 USETW(req
.wLength
, len
);
129 DPRINTFN(2,("ezload_download: addr=0x%x len=%d\n",
130 ptr
->address
+ offs
, len
));
132 err
= usbd_do_request(dev
, &req
,
133 __UNCONST(ptr
->data
+ offs
));
143 ezload_downloads_and_reset(usbd_device_handle dev
, const struct ezdata
**recs
)
147 /*(void)ezload_reset(dev, 1);*/
148 err
= ezload_reset(dev
, 1);
151 usbd_delay_ms(dev
, 250);
152 while (*recs
!= NULL
) {
153 err
= ezload_download(dev
, *recs
++);
157 usbd_delay_ms(dev
, 250);
158 err
= ezload_reset(dev
, 0);
159 usbd_delay_ms(dev
, 250);