2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 #include <linux/kernel.h>
17 #include <linux/errno.h>
18 #include <linux/ctype.h>
19 #include <linux/delay.h>
20 #include <linux/firmware.h>
22 #include "as102_drv.h"
25 static const char as102_st_fw1
[] = "as102_data1_st.hex";
26 static const char as102_st_fw2
[] = "as102_data2_st.hex";
27 static const char as102_dt_fw1
[] = "as102_data1_dt.hex";
28 static const char as102_dt_fw2
[] = "as102_data2_dt.hex";
30 static unsigned char atohx(unsigned char *dst
, char *src
)
32 unsigned char value
= 0;
34 char msb
= tolower(*src
) - '0';
35 char lsb
= tolower(*(src
+ 1)) - '0';
42 *dst
= value
= ((msb
& 0xF) << 4) | (lsb
& 0xF);
47 * Parse INTEL HEX firmware file to extract address and data.
49 static int parse_hex_line(unsigned char *fw_data
, unsigned char *addr
,
50 unsigned char *data
, int *dataLength
,
51 unsigned char *addr_has_changed
) {
54 unsigned char *src
, dst
;
56 if (*fw_data
++ != ':') {
57 pr_err("invalid firmware file\n");
61 /* locate end of line */
62 for (src
= fw_data
; *src
!= '\n'; src
+= 2) {
64 /* parse line to split addr / data */
76 /* check if data is an address */
78 *addr_has_changed
= 1;
80 *addr_has_changed
= 0;
84 if (*addr_has_changed
)
85 addr
[(count
- 4)] = dst
;
87 data
[(count
- 4)] = dst
;
90 data
[(count
- 4)] = dst
;
96 /* return read value + ':' + '\n' */
97 return (count
* 2) + 2;
100 static int as102_firmware_upload(struct as10x_bus_adapter_t
*bus_adap
,
102 const struct firmware
*firmware
) {
104 struct as10x_fw_pkt_t
*fw_pkt
;
105 int total_read_bytes
= 0, errno
= 0;
106 unsigned char addr_has_changed
= 0;
108 fw_pkt
= kmalloc(sizeof(*fw_pkt
), GFP_KERNEL
);
113 for (total_read_bytes
= 0; total_read_bytes
< firmware
->size
; ) {
114 int read_bytes
= 0, data_len
= 0;
116 /* parse intel hex line */
117 read_bytes
= parse_hex_line(
118 (u8
*) (firmware
->data
+ total_read_bytes
),
127 /* detect the end of file */
128 total_read_bytes
+= read_bytes
;
129 if (total_read_bytes
== firmware
->size
) {
130 fw_pkt
->u
.request
[0] = 0x00;
131 fw_pkt
->u
.request
[1] = 0x03;
133 /* send EOF command */
134 errno
= bus_adap
->ops
->upload_fw_pkt(bus_adap
,
140 if (!addr_has_changed
) {
141 /* prepare command to send */
142 fw_pkt
->u
.request
[0] = 0x00;
143 fw_pkt
->u
.request
[1] = 0x01;
145 data_len
+= sizeof(fw_pkt
->u
.request
);
146 data_len
+= sizeof(fw_pkt
->raw
.address
);
148 /* send cmd to device */
149 errno
= bus_adap
->ops
->upload_fw_pkt(bus_adap
,
161 return (errno
== 0) ? total_read_bytes
: errno
;
164 int as102_fw_upload(struct as10x_bus_adapter_t
*bus_adap
)
167 const struct firmware
*firmware
= NULL
;
168 unsigned char *cmd_buf
= NULL
;
169 const char *fw1
, *fw2
;
170 struct usb_device
*dev
= bus_adap
->usb_dev
;
172 /* select fw file to upload */
181 /* allocate buffer to store firmware upload command and data */
182 cmd_buf
= kzalloc(MAX_FW_PKT_SIZE
, GFP_KERNEL
);
183 if (cmd_buf
== NULL
) {
188 /* request kernel to locate firmware file: part1 */
189 errno
= request_firmware(&firmware
, fw1
, &dev
->dev
);
191 pr_err("%s: unable to locate firmware file: %s\n",
196 /* initiate firmware upload */
197 errno
= as102_firmware_upload(bus_adap
, cmd_buf
, firmware
);
199 pr_err("%s: error during firmware upload part1\n",
204 pr_info("%s: firmware: %s loaded with success\n",
206 release_firmware(firmware
);
209 /* wait for boot to complete */
212 /* request kernel to locate firmware file: part2 */
213 errno
= request_firmware(&firmware
, fw2
, &dev
->dev
);
215 pr_err("%s: unable to locate firmware file: %s\n",
220 /* initiate firmware upload */
221 errno
= as102_firmware_upload(bus_adap
, cmd_buf
, firmware
);
223 pr_err("%s: error during firmware upload part2\n",
228 pr_info("%s: firmware: %s loaded with success\n",
232 release_firmware(firmware
);