brcm_patchram_plus.c revision e1276c208588797c46cfe809f346becdb89eb9c0
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
1331725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries#define printf LOGD
1341725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries#undef fprintf
1351725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries#define fprintf(x, ...) \
1361725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries  { if(x==stderr) LOGE(__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		&param[0], &param[1], &param[2], &param[3], &param[4],
334e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte		&param[5], &param[6], &param[7], &param[8], &param[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", &param[0], &param[1], &param[2],
361e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte		&param[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
658ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	proc_reset();
659ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly}
660ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
661ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid
662ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_baudrate()
663ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{
664ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	hci_send_cmd(hci_update_baud_rate, sizeof(hci_update_baud_rate));
665ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
666ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	read_event(uart_fd, buffer);
667ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
668ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	cfsetospeed(&termios, termios_baudrate);
669ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	cfsetispeed(&termios, termios_baudrate);
670ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	tcsetattr(uart_fd, TCSANOW, &termios);
671ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
672ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	if (debug) {
673ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly		fprintf(stderr, "Done setting baudrate\n");
674ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	}
675ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly}
676ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
677ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid
678ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_bdaddr()
679ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{
680ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	hci_send_cmd(hci_write_bd_addr, sizeof(hci_write_bd_addr));
681ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
682ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	read_event(uart_fd, buffer);
683ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly}
684ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
685ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid
686ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_enable_lpm()
687ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{
688ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	hci_send_cmd(hci_write_sleep_mode, sizeof(hci_write_sleep_mode));
689ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
690ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	read_event(uart_fd, buffer);
691ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly}
692ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
693ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid
694e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harteproc_scopcm()
6951725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries{
696e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	hci_send_cmd(hci_write_sco_pcm_int,
697e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte		sizeof(hci_write_sco_pcm_int));
698e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte
699e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	read_event(uart_fd, buffer);
700e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte
701e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	hci_send_cmd(hci_write_pcm_data_format,
702e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte		sizeof(hci_write_pcm_data_format));
703e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte
704e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	read_event(uart_fd, buffer);
7051725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries}
7061725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries
7071725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Friesvoid
708e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harteproc_i2s()
7091725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries{
710e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	hci_send_cmd(hci_write_i2spcm_interface_param,
711e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte		sizeof(hci_write_i2spcm_interface_param));
712e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte
713e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	read_event(uart_fd, buffer);
7141725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries}
7151725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries
7161725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Friesvoid
717ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_enable_hci()
718ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{
719ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	int i = N_HCI;
720ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	int proto = HCI_UART_H4;
721ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	if (ioctl(uart_fd, TIOCSETD, &i) < 0) {
722ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly		fprintf(stderr, "Can't set line discipline\n");
723ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly		return;
724ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	}
725ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
726ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	if (ioctl(uart_fd, HCIUARTSETPROTO, proto) < 0) {
727ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly		fprintf(stderr, "Can't set hci protocol\n");
728ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly		return;
729ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	}
730ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	fprintf(stderr, "Done setting line discpline\n");
731ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	return;
732ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly}
733ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
734e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte#ifdef ANDROID
735db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pellyvoid
736db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pellyread_default_bdaddr()
737db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly{
738db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	int sz;
739db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	int fd;
740e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte
741db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	char path[PROPERTY_VALUE_MAX];
742e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte
743db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	char bdaddr[18];
744d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh	int len = 17;
745d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh	memset(bdaddr, 0, (len + 1) * sizeof(char));
746db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly
747db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	property_get("ro.bt.bdaddr_path", path, "");
748db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	if (path[0] == 0)
749db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly		return;
750db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly
751db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	fd = open(path, O_RDONLY);
752db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	if (fd < 0) {
753db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly		fprintf(stderr, "open(%s) failed: %s (%d)", path, strerror(errno),
754db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly				errno);
755db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly		return;
756db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	}
757db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly
758d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh	sz = read(fd, bdaddr, len);
759db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	if (sz < 0) {
760db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly		fprintf(stderr, "read(%s) failed: %s (%d)", path, strerror(errno),
761db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly				errno);
762db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly		close(fd);
763db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly		return;
764d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh	} else if (sz != len) {
765db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly		fprintf(stderr, "read(%s) unexpected size %d", path, sz);
766db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly		close(fd);
767db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly		return;
768db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	}
769db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly
770e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	if (debug) {
771d15a37448edcc1bd314873732ce5f3ea7ddad4baJaikumar Ganesh		printf("Read default bdaddr of %s\n", bdaddr);
772e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	}
773e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte
774db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	parse_bdaddr(bdaddr);
775db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly}
776e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte#endif
777e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte
778db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly
779ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint
780ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellymain (int argc, char **argv)
781ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{
782e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte#ifdef ANDROID
783db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly	read_default_bdaddr();
784e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte#endif
785db5ccf71519a49fbb36b915dba551aa0b3fa0db8Nick Pelly
786e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	if (parse_cmd_line(argc, argv)) {
787e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte		exit(1);
788e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	}
789ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
790ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	if (uart_fd < 0) {
791e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte		exit(2);
792ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	}
793ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
794ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	init_uart();
795ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
796ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	proc_reset();
797ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
798fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh	if (use_baudrate_for_download) {
799fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh		if (termios_baudrate) {
800fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh			proc_baudrate();
801fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh		}
802e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	}
803fff5ba85648ed4346d6feb3639aeafa6874bf640Jaikumar Ganesh
804e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	if (hcdfile_fd > 0) {
805e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte		proc_patchram();
806e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	}
807ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
808e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	if (termios_baudrate) {
809e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte		proc_baudrate();
810ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	}
811ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
812ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	if (bdaddr_flag) {
813ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly		proc_bdaddr();
814ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	}
815ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
816ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	if (enable_lpm) {
817ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly		proc_enable_lpm();
818ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	}
819ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
820e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	if (scopcm) {
821e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte		proc_scopcm();
822e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	}
823e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte
824e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte	if (i2s) {
825e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte		proc_i2s();
8261725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries	}
8271725ef80c89ba54e0b246d5d4d31e217496d01b5Chris Fries
828ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	if (enable_hci) {
829d4397861e745c5b6ae99fe547b841df9babf3085Nick Pelly		proc_enable_hci();
830e1276c208588797c46cfe809f346becdb89eb9c0Howard M. Harte
831ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly		while (1) {
832ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly			sleep(UINT_MAX);
833ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly		}
834ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	}
835ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly
836ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly	exit(0);
837ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly}
838