1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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>
21
22#include "as102_drv.h"
23#include "as102_fw.h"
24
25static const char as102_st_fw1[] = "as102_data1_st.hex";
26static const char as102_st_fw2[] = "as102_data2_st.hex";
27static const char as102_dt_fw1[] = "as102_data1_dt.hex";
28static const char as102_dt_fw2[] = "as102_data2_dt.hex";
29
30static unsigned char atohx(unsigned char *dst, char *src)
31{
32 unsigned char value = 0;
33
34 char msb = tolower(*src) - '0';
35 char lsb = tolower(*(src + 1)) - '0';
36
37 if (msb > 9)
38 msb -= 7;
39 if (lsb > 9)
40 lsb -= 7;
41
42 *dst = value = ((msb & 0xF) << 4) | (lsb & 0xF);
43 return value;
44}
45
46
47
48
49static int parse_hex_line(unsigned char *fw_data, unsigned char *addr,
50 unsigned char *data, int *dataLength,
51 unsigned char *addr_has_changed) {
52
53 int count = 0;
54 unsigned char *src, dst;
55
56 if (*fw_data++ != ':') {
57 pr_err("invalid firmware file\n");
58 return -EFAULT;
59 }
60
61
62 for (src = fw_data; *src != '\n'; src += 2) {
63 atohx(&dst, src);
64
65 switch (count) {
66 case 0:
67 *dataLength = dst;
68 break;
69 case 1:
70 addr[2] = dst;
71 break;
72 case 2:
73 addr[3] = dst;
74 break;
75 case 3:
76
77 if (dst == 0x04)
78 *addr_has_changed = 1;
79 else
80 *addr_has_changed = 0;
81 break;
82 case 4:
83 case 5:
84 if (*addr_has_changed)
85 addr[(count - 4)] = dst;
86 else
87 data[(count - 4)] = dst;
88 break;
89 default:
90 data[(count - 4)] = dst;
91 break;
92 }
93 count++;
94 }
95
96
97 return (count * 2) + 2;
98}
99
100static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap,
101 unsigned char *cmd,
102 const struct firmware *firmware) {
103
104 struct as10x_fw_pkt_t *fw_pkt;
105 int total_read_bytes = 0, errno = 0;
106 unsigned char addr_has_changed = 0;
107
108 fw_pkt = kmalloc(sizeof(*fw_pkt), GFP_KERNEL);
109 if (!fw_pkt)
110 return -ENOMEM;
111
112
113 for (total_read_bytes = 0; total_read_bytes < firmware->size; ) {
114 int read_bytes = 0, data_len = 0;
115
116
117 read_bytes = parse_hex_line(
118 (u8 *) (firmware->data + total_read_bytes),
119 fw_pkt->raw.address,
120 fw_pkt->raw.data,
121 &data_len,
122 &addr_has_changed);
123
124 if (read_bytes <= 0)
125 goto error;
126
127
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;
132
133
134 errno = bus_adap->ops->upload_fw_pkt(bus_adap,
135 (uint8_t *)
136 fw_pkt, 2, 0);
137 if (errno < 0)
138 goto error;
139 } else {
140 if (!addr_has_changed) {
141
142 fw_pkt->u.request[0] = 0x00;
143 fw_pkt->u.request[1] = 0x01;
144
145 data_len += sizeof(fw_pkt->u.request);
146 data_len += sizeof(fw_pkt->raw.address);
147
148
149 errno = bus_adap->ops->upload_fw_pkt(bus_adap,
150 (uint8_t *)
151 fw_pkt,
152 data_len,
153 0);
154 if (errno < 0)
155 goto error;
156 }
157 }
158 }
159error:
160 kfree(fw_pkt);
161 return (errno == 0) ? total_read_bytes : errno;
162}
163
164int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap)
165{
166 int errno = -EFAULT;
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;
171
172
173 if (dual_tuner) {
174 fw1 = as102_dt_fw1;
175 fw2 = as102_dt_fw2;
176 } else {
177 fw1 = as102_st_fw1;
178 fw2 = as102_st_fw2;
179 }
180
181
182 cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL);
183 if (cmd_buf == NULL) {
184 errno = -ENOMEM;
185 goto error;
186 }
187
188
189 errno = request_firmware(&firmware, fw1, &dev->dev);
190 if (errno < 0) {
191 pr_err("%s: unable to locate firmware file: %s\n",
192 DRIVER_NAME, fw1);
193 goto error;
194 }
195
196
197 errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
198 if (errno < 0) {
199 pr_err("%s: error during firmware upload part1\n",
200 DRIVER_NAME);
201 goto error;
202 }
203
204 pr_info("%s: firmware: %s loaded with success\n",
205 DRIVER_NAME, fw1);
206 release_firmware(firmware);
207 firmware = NULL;
208
209
210 mdelay(100);
211
212
213 errno = request_firmware(&firmware, fw2, &dev->dev);
214 if (errno < 0) {
215 pr_err("%s: unable to locate firmware file: %s\n",
216 DRIVER_NAME, fw2);
217 goto error;
218 }
219
220
221 errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
222 if (errno < 0) {
223 pr_err("%s: error during firmware upload part2\n",
224 DRIVER_NAME);
225 goto error;
226 }
227
228 pr_info("%s: firmware: %s loaded with success\n",
229 DRIVER_NAME, fw2);
230error:
231 kfree(cmd_buf);
232 release_firmware(firmware);
233
234 return errno;
235}
236