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 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <linux/kernel.h>
21 #include <linux/errno.h>
22 #include <linux/ctype.h>
23 #include <linux/delay.h>
24 #include <linux/firmware.h>
26 #include "as102_drv.h"
29 #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
30 char as102_st_fw1[] = "as102_data1_st.hex";
31 char as102_st_fw2[] = "as102_data2_st.hex";
32 char as102_dt_fw1[] = "as102_data1_dt.hex";
33 char as102_dt_fw2[] = "as102_data2_dt.hex";
35 static unsigned char atohx(unsigned char *dst, char *src)
37 unsigned char value = 0;
39 char msb = tolower(*src) - '0';
40 char lsb = tolower(*(src + 1)) - '0';
47 *dst = value = ((msb & 0xF) << 4) | (lsb & 0xF);
52 * Parse INTEL HEX firmware file to extract address and data.
54 static int parse_hex_line(unsigned char *fw_data, unsigned char *addr,
55 unsigned char *data, int *dataLength,
56 unsigned char *addr_has_changed) {
59 unsigned char *src, dst;
61 if (*fw_data++ != ':') {
62 printk(KERN_ERR "invalid firmware file\n");
66 /* locate end of line */
67 for (src = fw_data; *src != '\n'; src += 2) {
69 /* parse line to split addr / data */
81 /* check if data is an address */
83 *addr_has_changed = 1;
85 *addr_has_changed = 0;
89 if (*addr_has_changed)
90 addr[(count - 4)] = dst;
92 data[(count - 4)] = dst;
95 data[(count - 4)] = dst;
101 /* return read value + ':' + '\n' */
102 return (count * 2) + 2;
105 static int as102_firmware_upload(struct as102_bus_adapter_t *bus_adap,
107 const struct firmware *firmware) {
109 struct as10x_fw_pkt_t fw_pkt;
110 int total_read_bytes = 0, errno = 0;
111 unsigned char addr_has_changed = 0;
115 for (total_read_bytes = 0; total_read_bytes < firmware->size; ) {
116 int read_bytes = 0, data_len = 0;
118 /* parse intel hex line */
119 read_bytes = parse_hex_line(
120 (u8 *) (firmware->data + total_read_bytes),
129 /* detect the end of file */
130 total_read_bytes += read_bytes;
131 if (total_read_bytes == firmware->size) {
132 fw_pkt.u.request[0] = 0x00;
133 fw_pkt.u.request[1] = 0x03;
135 /* send EOF command */
136 errno = bus_adap->ops->upload_fw_pkt(bus_adap,
142 if (!addr_has_changed) {
143 /* prepare command to send */
144 fw_pkt.u.request[0] = 0x00;
145 fw_pkt.u.request[1] = 0x01;
147 data_len += sizeof(fw_pkt.u.request);
148 data_len += sizeof(fw_pkt.raw.address);
150 /* send cmd to device */
151 errno = bus_adap->ops->upload_fw_pkt(bus_adap,
163 return (errno == 0) ? total_read_bytes : errno;
166 int as102_fw_upload(struct as102_bus_adapter_t *bus_adap)
169 const struct firmware *firmware;
170 unsigned char *cmd_buf = NULL;
173 #if defined(CONFIG_AS102_USB)
174 struct usb_device *dev = bus_adap->usb_dev;
176 #if defined(CONFIG_AS102_SPI)
177 struct spi_device *dev = bus_adap->spi_dev;
181 /* select fw file to upload */
190 #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
191 /* allocate buffer to store firmware upload command and data */
192 cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL);
193 if (cmd_buf == NULL) {
198 /* request kernel to locate firmware file: part1 */
199 errno = request_firmware(&firmware, fw1, &dev->dev);
201 printk(KERN_ERR "%s: unable to locate firmware file: %s\n",
206 /* initiate firmware upload */
207 errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
209 printk(KERN_ERR "%s: error during firmware upload part1\n",
214 printk(KERN_INFO "%s: fimrware: %s loaded with success\n",
216 release_firmware(firmware);
218 /* wait for boot to complete */
221 /* request kernel to locate firmware file: part2 */
222 errno = request_firmware(&firmware, fw2, &dev->dev);
224 printk(KERN_ERR "%s: unable to locate firmware file: %s\n",
229 /* initiate firmware upload */
230 errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
232 printk(KERN_ERR "%s: error during firmware upload part2\n",
237 printk(KERN_INFO "%s: fimrware: %s loaded with success\n",
240 /* free data buffer */
242 /* release firmware if needed */
243 if (firmware != NULL)
244 release_firmware(firmware);
251 /* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */