brcm_patchram_plus.c revision fd8ee4744176894d5a8ee28645fa342b859f4893
1fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte/******************************************************************************* 2ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * 3fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * Copyright (C) 2009-2011 Broadcom Corporation 4ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * 5fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * Licensed under the Apache License, Version 2.0 (the "License"); 6fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * you may not use this file except in compliance with the License. 7fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * You may obtain a copy of the License at 8fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * 9fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * http://www.apache.org/licenses/LICENSE-2.0 10fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * 11fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * Unless required by applicable law or agreed to in writing, software 12fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * distributed under the License is distributed on an "AS IS" BASIS, 13fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * See the License for the specific language governing permissions and 15fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * limitations under the License. 16fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte * 17fd8ee4744176894d5a8ee28645fa342b859f4893Howard M. Harte ******************************************************************************/ 18ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 19ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly/***************************************************************************** 20ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 21ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** Name: brcm_patchram_plus.c 22ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 23ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** Description: This program downloads a patchram files in the HCD format 24ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** to Broadcom Bluetooth based silicon and combo chips and 25ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** and other utility functions. 26ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 27ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** It can be invoked from the command line in the form 28ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** <-d> to print a debug log 29ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** <--patchram patchram_file> 30ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** <--baudrate baud_rate> 31ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** <--bd_addr bd_address> 32ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** <--enable_lpm> 33ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** <--enable_hci> 341725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries** <--pcm_role master|slave> 35fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh** <--use_baudrate_for_download> 36ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** uart_device_name 37ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 38ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** For example: 39ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 40ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** brcm_patchram_plus -d --patchram \ 41ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** BCM2045B2_002.002.011.0348.0349.hcd /dev/ttyHS0 42ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 43ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** It will return 0 for success and a number greater than 0 44ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** for any errors. 45ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 46ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** For Android, this program invoked using a 47ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** "system(2)" call from the beginning of the bt_enable 48ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** function inside the file 49db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly** system/bluetooth/bluedroid/bluetooth.c. 50ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 51db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly** If the Android system property "ro.bt.bcm_bdaddr_path" is 52db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly** set, then the bd_addr will be read from this path. 53db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly** This is overridden by --bd_addr on the command line. 54ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 55ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly******************************************************************************/ 56ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 57ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly// TODO: Integrate BCM support into Bluez hciattach 58ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 59ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <stdio.h> 60ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <getopt.h> 61ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <errno.h> 62ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 63ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <sys/types.h> 64ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <sys/stat.h> 65ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <fcntl.h> 66ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 67ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <stdlib.h> 68ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 69ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#ifdef ANDROID 70ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <termios.h> 71ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#else 72ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <sys/termios.h> 73ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#endif 74ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 75ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <string.h> 76ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <signal.h> 77ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 78db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly#include <cutils/properties.h> 79db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly 801725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries#ifdef ANDROID 811725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries#define LOG_TAG "brcm_patchram_plus" 821725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries#include <cutils/log.h> 831725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries#undef printf 841725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries#define printf LOGD 851725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries#undef fprintf 861725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries#define fprintf(x, ...) \ 871725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries { if(x==stderr) LOGE(__VA_ARGS__); else fprintf(x, __VA_ARGS__); } 881725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries 891725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries#endif //ANDROID 901725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries 91ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#ifndef N_HCI 92ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define N_HCI 15 93ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#endif 94ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 95ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCIUARTSETPROTO _IOW('U', 200, int) 96ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCIUARTGETPROTO _IOR('U', 201, int) 97ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCIUARTGETDEVICE _IOR('U', 202, int) 98ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 99ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCI_UART_H4 0 100ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCI_UART_BCSP 1 101ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCI_UART_3WIRE 2 102ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCI_UART_H4DS 3 103ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCI_UART_LL 4 104ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 105ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 106ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint uart_fd = -1; 107ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint hcdfile_fd = -1; 108ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint termios_baudrate = 0; 109ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint bdaddr_flag = 0; 110ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint enable_lpm = 0; 111ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint enable_hci = 0; 1121725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Friesint pcm_slave = 0; 1131725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Friesint pcm_master = 0; 114fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganeshint use_baudrate_for_download = 0; 115ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint debug = 0; 116ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 117ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellystruct termios termios; 118ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyunsigned char buffer[1024]; 119ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 120ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyunsigned char hci_reset[] = { 0x01, 0x03, 0x0c, 0x00 }; 121ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 122ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyunsigned char hci_download_minidriver[] = { 0x01, 0x2e, 0xfc, 0x00 }; 123ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 124ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyunsigned char hci_update_baud_rate[] = { 0x01, 0x18, 0xfc, 0x06, 0x00, 0x00, 125ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 0x00, 0x00, 0x00, 0x00 }; 126ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 127ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyunsigned char hci_write_bd_addr[] = { 0x01, 0x01, 0xfc, 0x06, 128db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 129ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 130ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyunsigned char hci_write_sleep_mode[] = { 0x01, 0x27, 0xfc, 0x0c, 131d4397861e745c5b6ae99fe547b841df9babf3085Nick Pelly 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 132ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 0x00, 0x00 }; 133ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 1341725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries// HCI_COMMAND_PKT = 0x01 1351725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries// unpacked ogf/ocf: 0x3F 0x1C 1361725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries// ... ((ocf & 0x03ff)|(ogf << 10)) => 0xFC1C (0x1C 0xFC) 1371725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries// packet data len: 0x5 1381725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries// Data for the Write_SCO_PCM_Int_Param Message: 1391725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries// 00 (Use PCM) 1401725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries// 0x (02== 512 KHz bit clock, 03==1024 KHz bit clock, 04==2048 KHz) 1411725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries// 01 (Long FS) 1421725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries// 00 (Slave frame sync) 1431725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries// 00 (Slave bit clock) 1441725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Friesunsigned char hci_write_pcm_slave_mode[] = 1451725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries { 0x01, 0x1C, 0xFC, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00 }; 1461725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Friesunsigned char hci_write_pcm_master_mode[] = 1471725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries { 0x01, 0x1C, 0xFC, 0x05, 0x00, 0x02, 0x00, 0x01, 0x01 }; 1481725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries 149ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 150ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyparse_patchram(char *optarg) 151ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 152ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly char *p; 153ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 154ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (!(p = strrchr(optarg, '.'))) { 155ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "file %s not an HCD file\n", optarg); 156ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly exit(3); 157ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 158ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 159ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly p++; 160ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 161ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (strcasecmp("hcd", p) != 0) { 162ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "file %s not an HCD file\n", optarg); 163ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly exit(4); 164ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 165ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 166ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if ((hcdfile_fd = open(optarg, O_RDONLY)) == -1) { 167ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "file %s could not be opened, error %d\n", optarg, errno); 168ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly exit(5); 169ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 170ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 171ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 172ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 173ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 174ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 175ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick PellyBRCM_encode_baud_rate(uint baud_rate, unsigned char *encoded_baud) 176ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 177ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if(baud_rate == 0 || encoded_baud == NULL) { 178ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "Baudrate not supported!"); 179ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return; 180ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 181ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 182ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly encoded_baud[3] = (unsigned char)(baud_rate >> 24); 183ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly encoded_baud[2] = (unsigned char)(baud_rate >> 16); 184ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly encoded_baud[1] = (unsigned char)(baud_rate >> 8); 185ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly encoded_baud[0] = (unsigned char)(baud_rate & 0xFF); 186ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 187ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 188ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellytypedef struct { 189ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int baud_rate; 190ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int termios_value; 191ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} tBaudRates; 192ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 193ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick PellytBaudRates baud_rates[] = { 194ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 115200, B115200 }, 195ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 230400, B230400 }, 196ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 460800, B460800 }, 197ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 500000, B500000 }, 198ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 576000, B576000 }, 199ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 921600, B921600 }, 200ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 1000000, B1000000 }, 201ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 1152000, B1152000 }, 202ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 1500000, B1500000 }, 203ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 2000000, B2000000 }, 204ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 2500000, B2500000 }, 205ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 3000000, B3000000 }, 206ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#ifndef __CYGWIN__ 207ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 3500000, B3500000 }, 208ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 4000000, B4000000 } 209ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#endif 210ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly}; 211ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 212ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 213ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvalidate_baudrate(int baud_rate, int *value) 214ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 215ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly unsigned int i; 216ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 217ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly for (i = 0; i < (sizeof(baud_rates) / sizeof(tBaudRates)); i++) { 218ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (baud_rates[i].baud_rate == baud_rate) { 219ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly *value = baud_rates[i].termios_value; 220ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(1); 221ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 222ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 223ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 224ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 225ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 226ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 227ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 228ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyparse_baudrate(char *optarg) 229ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 230ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int baudrate = atoi(optarg); 231ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 232ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (validate_baudrate(baudrate, &termios_baudrate)) { 233ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly BRCM_encode_baud_rate(baudrate, &hci_update_baud_rate[6]); 234ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 235ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 236ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 237ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 238ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 239ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 240ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyparse_bdaddr(char *optarg) 241ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 242ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int bd_addr[6]; 243ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int i; 244ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 245db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly sscanf(optarg, "%02X:%02X:%02X:%02X:%02X:%02X", 246db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly &bd_addr[5], &bd_addr[4], &bd_addr[3], 247db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly &bd_addr[2], &bd_addr[1], &bd_addr[0]); 248ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 249ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly for (i = 0; i < 6; i++) { 250ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_write_bd_addr[4 + i] = bd_addr[i]; 251ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 252ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 253ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly bdaddr_flag = 1; 254ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 255ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 256ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 257ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 258ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 259ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyparse_enable_lpm(char *optarg) 260ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 261ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly enable_lpm = 1; 262ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 263ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 264ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 265ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 266fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganeshparse_use_baudrate_for_download(char *optarg) 267fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh{ 268fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh use_baudrate_for_download = 1; 269fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh return(0); 270fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh} 271fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh 272fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganeshint 273ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyparse_enable_hci(char *optarg) 274ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 275ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly enable_hci = 1; 276ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 277ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 278ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 279ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 2801725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Friesparse_pcm_role(char *optarg) { 2811725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries if(!strcmp(optarg, "master")) { 2821725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries pcm_master = 1; 2831725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries } else if (!strcmp(optarg, "slave")) { 2841725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries pcm_slave = 1; 2851725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries } else { 2861725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries printf("Unknown PCM Role received: %s\n", optarg); 2871725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries } 2881725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries if (pcm_master && pcm_slave) { 2891725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries fprintf(stderr, "Illegal command line- pcm role master && slave\n"); 2901725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries exit(6); 2911725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries } 2921725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries return(0); 2931725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries} 2941725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries 2951725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Friesint 296ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyparse_cmd_line(int argc, char **argv) 297ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 298ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int c; 299ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int digit_optind = 0; 300ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 301ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly typedef int (*PFI)(); 302ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 303ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly PFI parse_param[] = { parse_patchram, parse_baudrate, 3041725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries parse_bdaddr, parse_enable_lpm, parse_enable_hci, 305fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh parse_pcm_role, parse_use_baudrate_for_download}; 306ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 307d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh while (1) 308d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh { 309d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh int this_option_optind = optind ? optind : 1; 310d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh int option_index = 0; 311d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh 312d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh static struct option long_options[] = { 313d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh {"patchram", 1, 0, 0}, 314d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh {"baudrate", 1, 0, 0}, 315d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh {"bd_addr", 1, 0, 0}, 316d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh {"enable_lpm", 0, 0, 0}, 317d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh {"enable_hci", 0, 0, 0}, 318d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh {"pcm_role", 1, 0, 0}, 319d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh {"use_baudrate_for_download", 0, 0, 0}, 320d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh {0, 0, 0, 0} 321d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh }; 322d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh 323d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh c = getopt_long_only (argc, argv, "d", long_options, 324d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh &option_index); 325d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh 326d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh if (c == -1) { 327d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh break; 328ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 329ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 330d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh switch (c) { 331d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh case 0: 332d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh if (debug) { 333d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf ("option %s", 334d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh long_options[option_index].name); 335d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh if (optarg) 336d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf (" with arg %s", optarg); 337d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf ("\n"); 338d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh } 339d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh (*parse_param[option_index])(optarg); 340d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh break; 341d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh case 'd': 342d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh debug = 1; 343d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh break; 344d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh 345d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh case '?': 346d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh //nobreak 347d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh default: 348d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("Usage %s:\n", argv[0]); 349d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("\t<-d> to print a debug log\n"); 350d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("\t<--patchram patchram_file>\n"); 351d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("\t<--baudrate baud_rate>\n"); 352d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("\t<--bd_addr bd_address>\n"); 353d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("\t<--enable_lpm>\n"); 354d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("\t<--enable_hci>\n"); 355d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("\t<--pcm_role slave|master>\n"); 356d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("\t<--use_baudrate_for_download> - Uses the\ 357d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh baudrate for downloading the\ 358d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh firmware\n"); 359d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("\tuart_device_name\n"); 360d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh break; 361d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh } 362ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 363d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh if (optind < argc) { 364d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh if (debug) 365d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf ("%s \n", argv[optind]); 366d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh if ((uart_fd = open(argv[optind], O_RDWR | O_NOCTTY)) == -1) { 367d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh fprintf(stderr, "port %s could not be opened, error %d\n", 368d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh argv[2], errno); 369ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 370d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh } 371ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 372ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 373ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 374ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 375ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 376ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyinit_uart() 377ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 378ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcflush(uart_fd, TCIOFLUSH); 379ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcgetattr(uart_fd, &termios); 380ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 381ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#ifndef __CYGWIN__ 382ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly cfmakeraw(&termios); 383ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#else 384ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP 385ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly | INLCR | IGNCR | ICRNL | IXON); 386ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly termios.c_oflag &= ~OPOST; 387ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 388ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly termios.c_cflag &= ~(CSIZE | PARENB); 389ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly termios.c_cflag |= CS8; 390ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#endif 391ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 392ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly termios.c_cflag |= CRTSCTS; 393ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcsetattr(uart_fd, TCSANOW, &termios); 394ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcflush(uart_fd, TCIOFLUSH); 395ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcsetattr(uart_fd, TCSANOW, &termios); 396ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcflush(uart_fd, TCIOFLUSH); 397ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcflush(uart_fd, TCIOFLUSH); 398ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly cfsetospeed(&termios, B115200); 399ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly cfsetispeed(&termios, B115200); 400ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcsetattr(uart_fd, TCSANOW, &termios); 401ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 402ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 403ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 404ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellydump(unsigned char *out, int len) 405ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 406ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int i; 407ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 408ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly for (i = 0; i < len; i++) { 409ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (i && !(i % 16)) { 410ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "\n"); 411ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 412ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 413ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "%02x ", out[i]); 414ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 415ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 416ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "\n"); 417ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 418ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 419ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 420ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyread_event(int fd, unsigned char *buffer) 421ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 422ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int i = 0; 423ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int len = 3; 424ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int count; 425ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 426ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly while ((count = read(fd, &buffer[i], len)) < len) { 427ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly i += count; 428ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly len -= count; 429ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 430ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 431ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly i += count; 432ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly len = buffer[2]; 433ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 434ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly while ((count = read(fd, &buffer[i], len)) < len) { 435ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly i += count; 436ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly len -= count; 437ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 438ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 439ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (debug) { 440ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly count += i; 441ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 442ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "received %d\n", count); 443ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly dump(buffer, count); 444ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 445ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 446ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 447ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 448ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyhci_send_cmd(unsigned char *buf, int len) 449ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 450ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (debug) { 451ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "writing\n"); 452ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly dump(buf, len); 453ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 454ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 455ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly write(uart_fd, buf, len); 456ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 457ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 458ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 459ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyexpired(int sig) 460ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 461ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(hci_reset, sizeof(hci_reset)); 462ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly alarm(4); 463ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 464ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 465ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 466ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_reset() 467ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 468ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly signal(SIGALRM, expired); 469ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 470ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 471ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(hci_reset, sizeof(hci_reset)); 472ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 473ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly alarm(4); 474ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 475ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read_event(uart_fd, buffer); 476ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 477ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly alarm(0); 478ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 479ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 480ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 481ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_patchram() 482ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 483ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int len; 484ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 485ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(hci_download_minidriver, sizeof(hci_download_minidriver)); 486ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 487ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read_event(uart_fd, buffer); 488ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 489ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read(uart_fd, &buffer[0], 2); 490ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 491deaab6fa4a94c31494ebb6770dd0532198d0cbcaNick Pelly usleep(50000); 492deaab6fa4a94c31494ebb6770dd0532198d0cbcaNick Pelly 493ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly while (read(hcdfile_fd, &buffer[1], 3)) { 494ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly buffer[0] = 0x01; 495ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 496ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly len = buffer[3]; 497ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 498ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read(hcdfile_fd, &buffer[4], len); 499ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 500ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(buffer, len + 4); 501ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 502ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read_event(uart_fd, buffer); 503ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 504ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 505ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly proc_reset(); 506ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 507ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 508ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 509ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_baudrate() 510ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 511ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(hci_update_baud_rate, sizeof(hci_update_baud_rate)); 512ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 513ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read_event(uart_fd, buffer); 514ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 515ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly cfsetospeed(&termios, termios_baudrate); 516ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly cfsetispeed(&termios, termios_baudrate); 517ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcsetattr(uart_fd, TCSANOW, &termios); 518ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 519ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (debug) { 520ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "Done setting baudrate\n"); 521ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 522ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 523ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 524ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 525ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_bdaddr() 526ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 527ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(hci_write_bd_addr, sizeof(hci_write_bd_addr)); 528ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 529ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read_event(uart_fd, buffer); 530ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 531ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 532ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 533ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_enable_lpm() 534ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 535ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(hci_write_sleep_mode, sizeof(hci_write_sleep_mode)); 536ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 537ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read_event(uart_fd, buffer); 538ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 539ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 540ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 5411725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Friesproc_pcm_slave() 5421725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries{ 543d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh if (debug) 544d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("Configuring PCM Interface as slave.\n"); 5451725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries hci_send_cmd(hci_write_pcm_slave_mode, sizeof(hci_write_pcm_slave_mode)); 5461725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries} 5471725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries 5481725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Friesvoid 5491725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Friesproc_pcm_master() 5501725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries{ 551d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh if (debug) 552d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("Configuring PCM Interface as master.\n"); 5531725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries hci_send_cmd(hci_write_pcm_master_mode, sizeof(hci_write_pcm_master_mode)); 5541725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries} 5551725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries 5561725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Friesvoid 557ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_enable_hci() 558ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 559ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int i = N_HCI; 560ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int proto = HCI_UART_H4; 561ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (ioctl(uart_fd, TIOCSETD, &i) < 0) { 562ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "Can't set line discipline\n"); 563ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return; 564ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 565ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 566ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (ioctl(uart_fd, HCIUARTSETPROTO, proto) < 0) { 567ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "Can't set hci protocol\n"); 568ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return; 569ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 570ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "Done setting line discpline\n"); 571ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return; 572ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 573ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 574db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pellyvoid 575db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pellyread_default_bdaddr() 576db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly{ 577db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly int sz; 578db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly int fd; 579db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly char path[PROPERTY_VALUE_MAX]; 580db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly char bdaddr[18]; 581d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh int len = 17; 582d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh memset(bdaddr, 0, (len + 1) * sizeof(char)); 583db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly 584db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly property_get("ro.bt.bdaddr_path", path, ""); 585db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly if (path[0] == 0) 586db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly return; 587db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly 588db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly fd = open(path, O_RDONLY); 589db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly if (fd < 0) { 590db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly fprintf(stderr, "open(%s) failed: %s (%d)", path, strerror(errno), 591db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly errno); 592db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly return; 593db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly } 594db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly 595d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh sz = read(fd, bdaddr, len); 596db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly if (sz < 0) { 597db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly fprintf(stderr, "read(%s) failed: %s (%d)", path, strerror(errno), 598db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly errno); 599db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly close(fd); 600db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly return; 601d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh } else if (sz != len) { 602db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly fprintf(stderr, "read(%s) unexpected size %d", path, sz); 603db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly close(fd); 604db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly return; 605db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly } 606db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly 607d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh if (debug) 608d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh printf("Read default bdaddr of %s\n", bdaddr); 609db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly parse_bdaddr(bdaddr); 610db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly} 611db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly 612ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 613ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellymain (int argc, char **argv) 614ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 615db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly read_default_bdaddr(); 616db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly 617ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly parse_cmd_line(argc, argv); 618ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 619ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (uart_fd < 0) { 620ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly exit(1); 621ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 622ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 623ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly init_uart(); 624ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 625ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly proc_reset(); 626ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 627fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh if (use_baudrate_for_download) { 628fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh if (termios_baudrate) { 629fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh proc_baudrate(); 630fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh } 631fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh 632fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh if (hcdfile_fd > 0) { 633fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh proc_patchram(); 634fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh } 635fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh } else { 636fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh if (hcdfile_fd > 0) { 637fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh proc_patchram(); 638fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh } 639ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 640fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh if (termios_baudrate) { 641fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh proc_baudrate(); 642fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh } 643ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 644ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 645ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (bdaddr_flag) { 646ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly proc_bdaddr(); 647ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 648ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 649ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (enable_lpm) { 650ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly proc_enable_lpm(); 651ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 652ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 6531725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries if (pcm_slave) { 6541725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries proc_pcm_slave(); 6551725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries } else if (pcm_master) { 6561725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries proc_pcm_master(); 6571725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries } 6581725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries 659ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (enable_hci) { 660d4397861e745c5b6ae99fe547b841df9babf3085Nick Pelly proc_enable_hci(); 661ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly while (1) { 662ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly sleep(UINT_MAX); 663ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 664ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 665ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 666ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly exit(0); 667ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 668