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