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