as102_fw.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  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>
  5. *
  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)
  9. * any later version.
  10. *
  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.
  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. #include "as102_drv.h"
  22. #include "as102_fw.h"
  23. static const char as102_st_fw1[] = "as102_data1_st.hex";
  24. static const char as102_st_fw2[] = "as102_data2_st.hex";
  25. static const char as102_dt_fw1[] = "as102_data1_dt.hex";
  26. static const char as102_dt_fw2[] = "as102_data2_dt.hex";
  27. static unsigned char atohx(unsigned char *dst, char *src)
  28. {
  29. unsigned char value = 0;
  30. char msb = tolower(*src) - '0';
  31. char lsb = tolower(*(src + 1)) - '0';
  32. if (msb > 9)
  33. msb -= 7;
  34. if (lsb > 9)
  35. lsb -= 7;
  36. *dst = value = ((msb & 0xF) << 4) | (lsb & 0xF);
  37. return value;
  38. }
  39. /*
  40. * Parse INTEL HEX firmware file to extract address and data.
  41. */
  42. static int parse_hex_line(unsigned char *fw_data, unsigned char *addr,
  43. unsigned char *data, int *dataLength,
  44. unsigned char *addr_has_changed) {
  45. int count = 0;
  46. unsigned char *src, dst;
  47. if (*fw_data++ != ':') {
  48. pr_err("invalid firmware file\n");
  49. return -EFAULT;
  50. }
  51. /* locate end of line */
  52. for (src = fw_data; *src != '\n'; src += 2) {
  53. atohx(&dst, src);
  54. /* parse line to split addr / data */
  55. switch (count) {
  56. case 0:
  57. *dataLength = dst;
  58. break;
  59. case 1:
  60. addr[2] = dst;
  61. break;
  62. case 2:
  63. addr[3] = dst;
  64. break;
  65. case 3:
  66. /* check if data is an address */
  67. if (dst == 0x04)
  68. *addr_has_changed = 1;
  69. else
  70. *addr_has_changed = 0;
  71. break;
  72. case 4:
  73. case 5:
  74. if (*addr_has_changed)
  75. addr[(count - 4)] = dst;
  76. else
  77. data[(count - 4)] = dst;
  78. break;
  79. default:
  80. data[(count - 4)] = dst;
  81. break;
  82. }
  83. count++;
  84. }
  85. /* return read value + ':' + '\n' */
  86. return (count * 2) + 2;
  87. }
  88. static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap,
  89. unsigned char *cmd,
  90. const struct firmware *firmware) {
  91. struct as10x_fw_pkt_t *fw_pkt;
  92. int total_read_bytes = 0, errno = 0;
  93. unsigned char addr_has_changed = 0;
  94. fw_pkt = kmalloc(sizeof(*fw_pkt), GFP_KERNEL);
  95. if (!fw_pkt)
  96. return -ENOMEM;
  97. for (total_read_bytes = 0; total_read_bytes < firmware->size; ) {
  98. int read_bytes = 0, data_len = 0;
  99. /* parse intel hex line */
  100. read_bytes = parse_hex_line(
  101. (u8 *) (firmware->data + total_read_bytes),
  102. fw_pkt->raw.address,
  103. fw_pkt->raw.data,
  104. &data_len,
  105. &addr_has_changed);
  106. if (read_bytes <= 0)
  107. goto error;
  108. /* detect the end of file */
  109. total_read_bytes += read_bytes;
  110. if (total_read_bytes == firmware->size) {
  111. fw_pkt->u.request[0] = 0x00;
  112. fw_pkt->u.request[1] = 0x03;
  113. /* send EOF command */
  114. errno = bus_adap->ops->upload_fw_pkt(bus_adap,
  115. (uint8_t *)
  116. fw_pkt, 2, 0);
  117. if (errno < 0)
  118. goto error;
  119. } else {
  120. if (!addr_has_changed) {
  121. /* prepare command to send */
  122. fw_pkt->u.request[0] = 0x00;
  123. fw_pkt->u.request[1] = 0x01;
  124. data_len += sizeof(fw_pkt->u.request);
  125. data_len += sizeof(fw_pkt->raw.address);
  126. /* send cmd to device */
  127. errno = bus_adap->ops->upload_fw_pkt(bus_adap,
  128. (uint8_t *)
  129. fw_pkt,
  130. data_len,
  131. 0);
  132. if (errno < 0)
  133. goto error;
  134. }
  135. }
  136. }
  137. error:
  138. kfree(fw_pkt);
  139. return (errno == 0) ? total_read_bytes : errno;
  140. }
  141. int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap)
  142. {
  143. int errno = -EFAULT;
  144. const struct firmware *firmware = NULL;
  145. unsigned char *cmd_buf = NULL;
  146. const char *fw1, *fw2;
  147. struct usb_device *dev = bus_adap->usb_dev;
  148. /* select fw file to upload */
  149. if (dual_tuner) {
  150. fw1 = as102_dt_fw1;
  151. fw2 = as102_dt_fw2;
  152. } else {
  153. fw1 = as102_st_fw1;
  154. fw2 = as102_st_fw2;
  155. }
  156. /* allocate buffer to store firmware upload command and data */
  157. cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL);
  158. if (cmd_buf == NULL) {
  159. errno = -ENOMEM;
  160. goto error;
  161. }
  162. /* request kernel to locate firmware file: part1 */
  163. errno = request_firmware(&firmware, fw1, &dev->dev);
  164. if (errno < 0) {
  165. pr_err("%s: unable to locate firmware file: %s\n",
  166. DRIVER_NAME, fw1);
  167. goto error;
  168. }
  169. /* initiate firmware upload */
  170. errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
  171. if (errno < 0) {
  172. pr_err("%s: error during firmware upload part1\n",
  173. DRIVER_NAME);
  174. goto error;
  175. }
  176. pr_info("%s: firmware: %s loaded with success\n",
  177. DRIVER_NAME, fw1);
  178. release_firmware(firmware);
  179. /* wait for boot to complete */
  180. mdelay(100);
  181. /* request kernel to locate firmware file: part2 */
  182. errno = request_firmware(&firmware, fw2, &dev->dev);
  183. if (errno < 0) {
  184. pr_err("%s: unable to locate firmware file: %s\n",
  185. DRIVER_NAME, fw2);
  186. goto error;
  187. }
  188. /* initiate firmware upload */
  189. errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
  190. if (errno < 0) {
  191. pr_err("%s: error during firmware upload part2\n",
  192. DRIVER_NAME);
  193. goto error;
  194. }
  195. pr_info("%s: firmware: %s loaded with success\n",
  196. DRIVER_NAME, fw2);
  197. error:
  198. kfree(cmd_buf);
  199. release_firmware(firmware);
  200. return errno;
  201. }