brcm_patchram.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. /*******************************************************************************
  2. *
  3. * Copyright (C) 2009-2011 Broadcom Corporation
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. ******************************************************************************/
  18. /*****************************************************************************
  19. **
  20. ** Name: brcm_patchram_plus.c
  21. **
  22. ** Description: This program downloads a patchram files in the HCD format
  23. ** to Broadcom Bluetooth based silicon and combo chips and
  24. ** and other utility functions.
  25. **
  26. ** It can be invoked from the command line in the form
  27. ** <-d> to print a debug log
  28. ** <--patchram patchram_file>
  29. ** <--baudrate baud_rate>
  30. ** <--bd_addr bd_address>
  31. ** <--enable_lpm>
  32. ** <--enable_hci>
  33. ** <--use_baudrate_for_download>
  34. ** <--scopcm=sco_routing,pcm_interface_rate,frame_type,
  35. ** sync_mode,clock_mode,lsb_first,fill_bits,
  36. ** fill_method,fill_num,right_justify>
  37. **
  38. ** Where
  39. **
  40. ** sco_routing is 0 for PCM, 1 for Transport,
  41. ** 2 for Codec and 3 for I2S,
  42. **
  43. ** pcm_interface_rate is 0 for 128KBps, 1 for
  44. ** 256 KBps, 2 for 512KBps, 3 for 1024KBps,
  45. ** and 4 for 2048Kbps,
  46. **
  47. ** frame_type is 0 for short and 1 for long,
  48. **
  49. ** sync_mode is 0 for slave and 1 for master,
  50. **
  51. ** clock_mode is 0 for slabe and 1 for master,
  52. **
  53. ** lsb_first is 0 for false aand 1 for true,
  54. **
  55. ** fill_bits is the value in decimal for unused bits,
  56. **
  57. ** fill_method is 0 for 0's and 1 for 1's, 2 for
  58. ** signed and 3 for programmable,
  59. **
  60. ** fill_num is the number or bits to fill,
  61. **
  62. ** right_justify is 0 for false and 1 for true
  63. **
  64. ** <--i2s=i2s_enable,is_master,sample_rate,clock_rate>
  65. **
  66. ** Where
  67. **
  68. ** i2s_enable is 0 for disable and 1 for enable,
  69. **
  70. ** is_master is 0 for slave and 1 for master,
  71. **
  72. ** sample_rate is 0 for 8KHz, 1 for 16Khz and
  73. ** 2 for 4 KHz,
  74. **
  75. ** clock_rate is 0 for 128KHz, 1 for 256KHz, 3 for
  76. ** 1024 KHz and 4 for 2048 KHz.
  77. **
  78. ** <--no2bytes skips waiting for two byte confirmation
  79. ** before starting patchram download. Newer chips
  80. ** do not generate these two bytes.>
  81. ** <--tosleep=number of microsseconds to sleep before
  82. ** patchram download begins.>
  83. ** uart_device_name
  84. **
  85. ** For example:
  86. **
  87. ** brcm_patchram_plus -d --patchram \
  88. ** BCM2045B2_002.002.011.0348.0349.hcd /dev/ttyHS0
  89. **
  90. ** It will return 0 for success and a number greater than 0
  91. ** for any errors.
  92. **
  93. ** For Android, this program invoked using a
  94. ** "system(2)" call from the beginning of the bt_enable
  95. ** function inside the file
  96. ** system/bluetooth/bluedroid/bluetooth.c.
  97. **
  98. ** If the Android system property "ro.bt.bcm_bdaddr_path" is
  99. ** set, then the bd_addr will be read from this path.
  100. ** This is overridden by --bd_addr on the command line.
  101. **
  102. ******************************************************************************/
  103. #include <stdio.h>
  104. #include <getopt.h>
  105. #include <errno.h>
  106. #include <sys/types.h>
  107. #include <sys/stat.h>
  108. #include <fcntl.h>
  109. #include <stdlib.h>
  110. #ifdef ANDROID
  111. #include <termios.h>
  112. #else
  113. #include <sys/termios.h>
  114. #include <sys/ioctl.h>
  115. #include <limits.h>
  116. #endif
  117. #include <string.h>
  118. #include <signal.h>
  119. #ifdef ANDROID
  120. #include <cutils/properties.h>
  121. #define LOG_TAG "brcm_patchram_plus"
  122. #include <cutils/log.h>
  123. #undef printf
  124. #define printf LOGD
  125. #undef fprintf
  126. #define fprintf(x, ...) \
  127. { if(x==stderr) LOGE(__VA_ARGS__); else fprintf(x, __VA_ARGS__); }
  128. #endif //ANDROID
  129. #ifndef N_HCI
  130. #define N_HCI 15
  131. #endif
  132. #define HCIUARTSETPROTO _IOW('U', 200, int)
  133. #define HCIUARTGETPROTO _IOR('U', 201, int)
  134. #define HCIUARTGETDEVICE _IOR('U', 202, int)
  135. #define HCI_UART_H4 0
  136. #define HCI_UART_BCSP 1
  137. #define HCI_UART_3WIRE 2
  138. #define HCI_UART_H4DS 3
  139. #define HCI_UART_LL 4
  140. typedef unsigned char uchar;
  141. int uart_fd = -1;
  142. int hcdfile_fd = -1;
  143. int termios_baudrate = 0;
  144. int bdaddr_flag = 0;
  145. int enable_lpm = 0;
  146. int enable_hci = 0;
  147. int use_baudrate_for_download = 0;
  148. int debug = 0;
  149. int scopcm = 0;
  150. int i2s = 0;
  151. int no2bytes = 0;
  152. int tosleep = 0;
  153. int baudrate = 0;
  154. struct termios termios;
  155. uchar buffer[1024];
  156. uchar hci_reset[] = { 0x01, 0x03, 0x0c, 0x00 };
  157. uchar hci_download_minidriver[] = { 0x01, 0x2e, 0xfc, 0x00 };
  158. uchar hci_update_baud_rate[] = { 0x01, 0x18, 0xfc, 0x06, 0x00, 0x00,
  159. 0x00, 0x00, 0x00, 0x00 };
  160. uchar hci_write_bd_addr[] = { 0x01, 0x01, 0xfc, 0x06,
  161. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  162. uchar hci_write_sleep_mode[] = { 0x01, 0x27, 0xfc, 0x0c,
  163. 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
  164. 0x00, 0x00 };
  165. uchar hci_write_sco_pcm_int[] =
  166. { 0x01, 0x1C, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
  167. uchar hci_write_pcm_data_format[] =
  168. { 0x01, 0x1e, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
  169. uchar hci_write_i2spcm_interface_param[] =
  170. { 0x01, 0x6d, 0xFC, 0x04, 0x00, 0x00, 0x00, 0x00 };
  171. uchar hci_write_uart_clock_setting_48Mhz[] =
  172. { 0x01, 0x45, 0xfc, 0x01, 0x01 };
  173. int
  174. parse_patchram(char *optarg)
  175. {
  176. char *p;
  177. if (!(p = strrchr(optarg, '.'))) {
  178. fprintf(stderr, "file %s not an HCD file\n", optarg);
  179. exit(3);
  180. }
  181. p++;
  182. if (strcasecmp("hcd", p) != 0) {
  183. fprintf(stderr, "file %s not an HCD file\n", optarg);
  184. exit(4);
  185. }
  186. if ((hcdfile_fd = open(optarg, O_RDONLY)) == -1) {
  187. fprintf(stderr, "file %s could not be opened, error %d\n", optarg, errno);
  188. exit(5);
  189. }
  190. return(0);
  191. }
  192. void
  193. BRCM_encode_baud_rate(uint baud_rate, uchar *encoded_baud)
  194. {
  195. if(baud_rate == 0 || encoded_baud == NULL) {
  196. fprintf(stderr, "Baudrate not supported!");
  197. return;
  198. }
  199. encoded_baud[3] = (uchar)(baud_rate >> 24);
  200. encoded_baud[2] = (uchar)(baud_rate >> 16);
  201. encoded_baud[1] = (uchar)(baud_rate >> 8);
  202. encoded_baud[0] = (uchar)(baud_rate & 0xFF);
  203. }
  204. typedef struct {
  205. int baud_rate;
  206. int termios_value;
  207. } tBaudRates;
  208. tBaudRates baud_rates[] = {
  209. { 115200, B115200 },
  210. { 230400, B230400 },
  211. { 460800, B460800 },
  212. { 500000, B500000 },
  213. { 576000, B576000 },
  214. { 921600, B921600 },
  215. { 1000000, B1000000 },
  216. { 1152000, B1152000 },
  217. { 1500000, B1500000 },
  218. { 2000000, B2000000 },
  219. { 2500000, B2500000 },
  220. { 3000000, B3000000 },
  221. #ifndef __CYGWIN__
  222. { 3500000, B3500000 },
  223. { 4000000, B4000000 }
  224. #endif
  225. };
  226. int
  227. validate_baudrate(int baud_rate, int *value)
  228. {
  229. unsigned int i;
  230. for (i = 0; i < (sizeof(baud_rates) / sizeof(tBaudRates)); i++) {
  231. if (baud_rates[i].baud_rate == baud_rate) {
  232. *value = baud_rates[i].termios_value;
  233. return(1);
  234. }
  235. }
  236. return(0);
  237. }
  238. int
  239. parse_baudrate(char *optarg)
  240. {
  241. baudrate = atoi(optarg);
  242. if (validate_baudrate(baudrate, &termios_baudrate)) {
  243. BRCM_encode_baud_rate(baudrate, &hci_update_baud_rate[6]);
  244. } else {
  245. return(1);
  246. }
  247. return(0);
  248. }
  249. int
  250. parse_bdaddr(char *optarg)
  251. {
  252. int bd_addr[6];
  253. int i;
  254. sscanf(optarg, "%02X:%02X:%02X:%02X:%02X:%02X",
  255. &bd_addr[5], &bd_addr[4], &bd_addr[3],
  256. &bd_addr[2], &bd_addr[1], &bd_addr[0]);
  257. for (i = 0; i < 6; i++) {
  258. hci_write_bd_addr[4 + i] = bd_addr[i];
  259. }
  260. bdaddr_flag = 1;
  261. return(0);
  262. }
  263. int
  264. parse_enable_lpm(char *optarg)
  265. {
  266. enable_lpm = 1;
  267. return(0);
  268. }
  269. int
  270. parse_use_baudrate_for_download(char *optarg)
  271. {
  272. use_baudrate_for_download = 1;
  273. return(0);
  274. }
  275. int
  276. parse_enable_hci(char *optarg)
  277. {
  278. enable_hci = 1;
  279. return(0);
  280. }
  281. int
  282. parse_scopcm(char *optarg)
  283. {
  284. int param[10];
  285. int ret;
  286. int i;
  287. ret = sscanf(optarg, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
  288. &param[0], &param[1], &param[2], &param[3], &param[4],
  289. &param[5], &param[6], &param[7], &param[8], &param[9]);
  290. if (ret != 10) {
  291. return(1);
  292. }
  293. scopcm = 1;
  294. for (i = 0; i < 5; i++) {
  295. hci_write_sco_pcm_int[4 + i] = param[i];
  296. }
  297. for (i = 0; i < 5; i++) {
  298. hci_write_pcm_data_format[4 + i] = param[5 + i];
  299. }
  300. return(0);
  301. }
  302. int
  303. parse_i2s(char *optarg)
  304. {
  305. int param[4];
  306. int ret;
  307. int i;
  308. ret = sscanf(optarg, "%d,%d,%d,%d", &param[0], &param[1], &param[2],
  309. &param[3]);
  310. if (ret != 4) {
  311. return(1);
  312. }
  313. i2s = 1;
  314. for (i = 0; i < 4; i++) {
  315. hci_write_i2spcm_interface_param[4 + i] = param[i];
  316. }
  317. return(0);
  318. }
  319. int
  320. parse_no2bytes(char *optarg)
  321. {
  322. no2bytes = 1;
  323. return(0);
  324. }
  325. int
  326. parse_tosleep(char *optarg)
  327. {
  328. tosleep = atoi(optarg);
  329. if (tosleep <= 0) {
  330. return(1);
  331. }
  332. return(0);
  333. }
  334. void
  335. usage(char *argv0)
  336. {
  337. printf("Usage %s:\n", argv0);
  338. printf("\t<-d> to print a debug log\n");
  339. printf("\t<--patchram patchram_file>\n");
  340. printf("\t<--baudrate baud_rate>\n");
  341. printf("\t<--bd_addr bd_address>\n");
  342. printf("\t<--enable_lpm>\n");
  343. printf("\t<--enable_hci>\n");
  344. printf("\t<--use_baudrate_for_download> - Uses the\n");
  345. printf("\t\tbaudrate for downloading the firmware\n");
  346. printf("\t<--scopcm=sco_routing,pcm_interface_rate,frame_type,\n");
  347. printf("\t\tsync_mode,clock_mode,lsb_first,fill_bits,\n");
  348. printf("\t\tfill_method,fill_num,right_justify>\n");
  349. printf("\n\t\tWhere\n");
  350. printf("\n\t\tsco_routing is 0 for PCM, 1 for Transport,\n");
  351. printf("\t\t2 for Codec and 3 for I2S,\n");
  352. printf("\n\t\tpcm_interface_rate is 0 for 128KBps, 1 for\n");
  353. printf("\t\t256 KBps, 2 for 512KBps, 3 for 1024KBps,\n");
  354. printf("\t\tand 4 for 2048Kbps,\n");
  355. printf("\n\t\tframe_type is 0 for short and 1 for long,\n");
  356. printf("\t\tsync_mode is 0 for slave and 1 for master,\n");
  357. printf("\n\t\tclock_mode is 0 for slabe and 1 for master,\n");
  358. printf("\n\t\tlsb_first is 0 for false aand 1 for true,\n");
  359. printf("\n\t\tfill_bits is the value in decimal for unused bits,\n");
  360. printf("\n\t\tfill_method is 0 for 0's and 1 for 1's, 2 for\n");
  361. printf("\t\tsigned and 3 for programmable,\n");
  362. printf("\n\t\tfill_num is the number or bits to fill,\n");
  363. printf("\n\t\tright_justify is 0 for false and 1 for true\n");
  364. printf("\n\t<--i2s=i2s_enable,is_master,sample_rate,clock_rate>\n");
  365. printf("\n\t\tWhere\n");
  366. printf("\n\t\ti2s_enable is 0 for disable and 1 for enable,\n");
  367. printf("\n\t\tis_master is 0 for slave and 1 for master,\n");
  368. printf("\n\t\tsample_rate is 0 for 8KHz, 1 for 16Khz and\n");
  369. printf("\t\t2 for 4 KHz,\n");
  370. printf("\n\t\tclock_rate is 0 for 128KHz, 1 for 256KHz, 3 for\n");
  371. printf("\t\t1024 KHz and 4 for 2048 KHz.\n\n");
  372. printf("\t<--no2bytes skips waiting for two byte confirmation\n");
  373. printf("\t\tbefore starting patchram download. Newer chips\n");
  374. printf("\t\tdo not generate these two bytes.>\n");
  375. printf("\t<--tosleep=microseconds>\n");
  376. printf("\tuart_device_name\n");
  377. }
  378. int
  379. parse_cmd_line(int argc, char **argv)
  380. {
  381. int c;
  382. int ret = 0;
  383. typedef int (*PFI)();
  384. PFI parse[] = { parse_patchram, parse_baudrate,
  385. parse_bdaddr, parse_enable_lpm, parse_enable_hci,
  386. parse_use_baudrate_for_download,
  387. parse_scopcm, parse_i2s, parse_no2bytes, parse_tosleep};
  388. while (1) {
  389. int this_option_optind = optind ? optind : 1;
  390. int option_index = 0;
  391. static struct option long_options[] = {
  392. {"patchram", 1, 0, 0},
  393. {"baudrate", 1, 0, 0},
  394. {"bd_addr", 1, 0, 0},
  395. {"enable_lpm", 0, 0, 0},
  396. {"enable_hci", 0, 0, 0},
  397. {"use_baudrate_for_download", 0, 0, 0},
  398. {"scopcm", 1, 0, 0},
  399. {"i2s", 1, 0, 0},
  400. {"no2bytes", 0, 0, 0},
  401. {"tosleep", 1, 0, 0},
  402. {0, 0, 0, 0}
  403. };
  404. c = getopt_long_only (argc, argv, "d", long_options,
  405. &option_index);
  406. if (c == -1) {
  407. break;
  408. }
  409. switch (c) {
  410. case 0:
  411. if (debug) {
  412. printf ("option %s",
  413. long_options[option_index].name);
  414. if (optarg)
  415. printf (" with arg %s", optarg);
  416. printf ("\n");
  417. }
  418. ret = (*parse[option_index])(optarg);
  419. break;
  420. case 'd':
  421. debug = 1;
  422. break;
  423. case '?':
  424. //nobreak
  425. default:
  426. usage(argv[0]);
  427. break;
  428. }
  429. if (ret) {
  430. usage(argv[0]);
  431. break;
  432. }
  433. }
  434. if (ret) {
  435. return(1);
  436. }
  437. if (optind < argc) {
  438. if (debug)
  439. printf ("%s \n", argv[optind]);
  440. if ((uart_fd = open(argv[optind], O_RDWR | O_NOCTTY)) == -1) {
  441. fprintf(stderr, "port %s could not be opened, error %d\n",
  442. argv[optind], errno);
  443. }
  444. }
  445. return(0);
  446. }
  447. void
  448. init_uart()
  449. {
  450. tcflush(uart_fd, TCIOFLUSH);
  451. tcgetattr(uart_fd, &termios);
  452. #ifndef __CYGWIN__
  453. cfmakeraw(&termios);
  454. #else
  455. termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
  456. | INLCR | IGNCR | ICRNL | IXON);
  457. termios.c_oflag &= ~OPOST;
  458. termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
  459. termios.c_cflag &= ~(CSIZE | PARENB);
  460. termios.c_cflag |= CS8;
  461. #endif
  462. termios.c_cflag |= CRTSCTS;
  463. tcsetattr(uart_fd, TCSANOW, &termios);
  464. tcflush(uart_fd, TCIOFLUSH);
  465. tcsetattr(uart_fd, TCSANOW, &termios);
  466. tcflush(uart_fd, TCIOFLUSH);
  467. tcflush(uart_fd, TCIOFLUSH);
  468. cfsetospeed(&termios, B115200);
  469. cfsetispeed(&termios, B115200);
  470. tcsetattr(uart_fd, TCSANOW, &termios);
  471. }
  472. void
  473. dump(uchar *out, int len)
  474. {
  475. int i;
  476. for (i = 0; i < len; i++) {
  477. if (i && !(i % 16)) {
  478. fprintf(stderr, "\n");
  479. }
  480. fprintf(stderr, "%02x ", out[i]);
  481. }
  482. fprintf(stderr, "\n");
  483. }
  484. void
  485. read_event(int fd, uchar *buffer)
  486. {
  487. int i = 0;
  488. int len = 3;
  489. int count;
  490. while ((count = read(fd, &buffer[i], len)) < len) {
  491. i += count;
  492. len -= count;
  493. }
  494. i += count;
  495. len = buffer[2];
  496. while ((count = read(fd, &buffer[i], len)) < len) {
  497. i += count;
  498. len -= count;
  499. }
  500. if (debug) {
  501. count += i;
  502. fprintf(stderr, "received %d\n", count);
  503. dump(buffer, count);
  504. }
  505. }
  506. void
  507. hci_send_cmd(uchar *buf, int len)
  508. {
  509. if (debug) {
  510. fprintf(stderr, "writing\n");
  511. dump(buf, len);
  512. }
  513. write(uart_fd, buf, len);
  514. }
  515. void
  516. expired(int sig)
  517. {
  518. hci_send_cmd(hci_reset, sizeof(hci_reset));
  519. alarm(4);
  520. }
  521. void
  522. proc_reset()
  523. {
  524. signal(SIGALRM, expired);
  525. hci_send_cmd(hci_reset, sizeof(hci_reset));
  526. alarm(4);
  527. read_event(uart_fd, buffer);
  528. alarm(0);
  529. }
  530. void
  531. proc_patchram()
  532. {
  533. int len;
  534. hci_send_cmd(hci_download_minidriver, sizeof(hci_download_minidriver));
  535. read_event(uart_fd, buffer);
  536. if (!no2bytes) {
  537. read(uart_fd, &buffer[0], 2);
  538. }
  539. if (tosleep) {
  540. usleep(tosleep);
  541. }
  542. while (read(hcdfile_fd, &buffer[1], 3)) {
  543. buffer[0] = 0x01;
  544. len = buffer[3];
  545. read(hcdfile_fd, &buffer[4], len);
  546. hci_send_cmd(buffer, len + 4);
  547. read_event(uart_fd, buffer);
  548. }
  549. if (use_baudrate_for_download) {
  550. cfsetospeed(&termios, B115200);
  551. cfsetispeed(&termios, B115200);
  552. tcsetattr(uart_fd, TCSANOW, &termios);
  553. }
  554. proc_reset();
  555. }
  556. void
  557. proc_baudrate()
  558. {
  559. if (baudrate > 3000000) {
  560. hci_send_cmd(hci_write_uart_clock_setting_48Mhz,
  561. sizeof(hci_write_uart_clock_setting_48Mhz));
  562. read_event(uart_fd, buffer);
  563. }
  564. hci_send_cmd(hci_update_baud_rate, sizeof(hci_update_baud_rate));
  565. read_event(uart_fd, buffer);
  566. cfsetospeed(&termios, termios_baudrate);
  567. cfsetispeed(&termios, termios_baudrate);
  568. tcsetattr(uart_fd, TCSANOW, &termios);
  569. if (debug) {
  570. fprintf(stderr, "Done setting baudrate\n");
  571. }
  572. }
  573. void
  574. proc_bdaddr()
  575. {
  576. hci_send_cmd(hci_write_bd_addr, sizeof(hci_write_bd_addr));
  577. read_event(uart_fd, buffer);
  578. }
  579. void
  580. proc_enable_lpm()
  581. {
  582. hci_send_cmd(hci_write_sleep_mode, sizeof(hci_write_sleep_mode));
  583. read_event(uart_fd, buffer);
  584. }
  585. void
  586. proc_scopcm()
  587. {
  588. hci_send_cmd(hci_write_sco_pcm_int,
  589. sizeof(hci_write_sco_pcm_int));
  590. read_event(uart_fd, buffer);
  591. hci_send_cmd(hci_write_pcm_data_format,
  592. sizeof(hci_write_pcm_data_format));
  593. read_event(uart_fd, buffer);
  594. }
  595. void
  596. proc_i2s()
  597. {
  598. hci_send_cmd(hci_write_i2spcm_interface_param,
  599. sizeof(hci_write_i2spcm_interface_param));
  600. read_event(uart_fd, buffer);
  601. }
  602. void
  603. proc_enable_hci()
  604. {
  605. int i = N_HCI;
  606. int proto = HCI_UART_H4;
  607. if (ioctl(uart_fd, TIOCSETD, &i) < 0) {
  608. fprintf(stderr, "Can't set line discipline\n");
  609. return;
  610. }
  611. if (ioctl(uart_fd, HCIUARTSETPROTO, proto) < 0) {
  612. fprintf(stderr, "Can't set hci protocol\n");
  613. return;
  614. }
  615. fprintf(stderr, "Done setting line discpline\n");
  616. return;
  617. }
  618. #ifdef ANDROID
  619. void
  620. read_default_bdaddr()
  621. {
  622. int sz;
  623. int fd;
  624. char path[PROPERTY_VALUE_MAX];
  625. char bdaddr[18];
  626. int len = 17;
  627. memset(bdaddr, 0, (len + 1) * sizeof(char));
  628. property_get("ro.bt.bdaddr_path", path, "");
  629. if (path[0] == 0)
  630. return;
  631. fd = open(path, O_RDONLY);
  632. if (fd < 0) {
  633. fprintf(stderr, "open(%s) failed: %s (%d)", path, strerror(errno),
  634. errno);
  635. return;
  636. }
  637. sz = read(fd, bdaddr, len);
  638. if (sz < 0) {
  639. fprintf(stderr, "read(%s) failed: %s (%d)", path, strerror(errno),
  640. errno);
  641. close(fd);
  642. return;
  643. } else if (sz != len) {
  644. fprintf(stderr, "read(%s) unexpected size %d", path, sz);
  645. close(fd);
  646. return;
  647. }
  648. if (debug) {
  649. printf("Read default bdaddr of %s\n", bdaddr);
  650. }
  651. parse_bdaddr(bdaddr);
  652. }
  653. #endif
  654. int
  655. main (int argc, char **argv)
  656. {
  657. #ifdef ANDROID
  658. read_default_bdaddr();
  659. #endif
  660. if (parse_cmd_line(argc, argv)) {
  661. exit(1);
  662. }
  663. if (uart_fd < 0) {
  664. exit(2);
  665. }
  666. init_uart();
  667. proc_reset();
  668. if (use_baudrate_for_download) {
  669. if (termios_baudrate) {
  670. proc_baudrate();
  671. }
  672. }
  673. if (hcdfile_fd > 0) {
  674. proc_patchram();
  675. }
  676. if (termios_baudrate) {
  677. proc_baudrate();
  678. }
  679. if (bdaddr_flag) {
  680. proc_bdaddr();
  681. }
  682. if (enable_lpm) {
  683. proc_enable_lpm();
  684. }
  685. if (scopcm) {
  686. proc_scopcm();
  687. }
  688. if (i2s) {
  689. proc_i2s();
  690. }
  691. if (enable_hci) {
  692. proc_enable_hci();
  693. while (1) {
  694. sleep(UINT_MAX);
  695. }
  696. }
  697. exit(0);
  698. }