[Warnings] Fix build warnings.
[platform/adaptation/bluetooth-firmware-bcm.git] / tools / bcmtool_4358a1.c
1 /*****************************************************************************
2 **
3 **  Name:          bcmtool.c
4 **
5 **  Description:   Download a patchram files for the HCD format
6 **
7 **  Copyright (c) 2000-2009, Broadcom Corp., All Rights Reserved.
8 ******************************************************************************/
9
10 #include <stdio.h>
11 #include <errno.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <stdlib.h>
16 #include <time.h>
17 #include <string.h>
18 #include <signal.h>
19 #include <unistd.h>
20 #include <sys/termios.h>
21 #include <sys/ioctl.h>
22 #include <limits.h>
23
24 #define N_HCI   15
25 #define HCI_UART_H4             0
26 #define HCI_UART_BCSP   1
27 #define HCI_UART_3WIRE  2
28 #define HCI_UART_H4DS   3
29 #define HCI_UART_LL             4
30 #define HCIUARTSETPROTO         _IOW('U', 200, int)
31 #define HCIUARTGETPROTO         _IOR('U', 201, int)
32 #define HCIUARTGETDEVICE        _IOR('U', 202, int)
33
34 /* Pre baudrate change for fast download */
35 #define HIGH_SPEED_PATCHRAM_DOWNLOAD  TRUE
36
37 /* Host Stack Idle Threshold */
38 #define HCILP_IDLE_THRESHOLD          0x01
39
40 /* Host Controller Idle Threshold */
41 #define HCILP_HC_IDLE_THRESHOLD       0x01
42
43 /* BT_WAKE Polarity - 0=Active Low, 1= Active High */
44 #define HCILP_BT_WAKE_POLARITY        1
45
46 /* HOST_WAKE Polarity - 0=Active Low, 1= Active High */
47 #define HCILP_HOST_WAKE_POLARITY      1
48
49 /* Local Feature */
50 #define BCM_DISABLE_RF_PWRCTRL        FALSE
51
52
53
54
55 #define RELEASE_DATE "2011.02.07"
56 #define DEBUG 1
57
58 typedef unsigned char   UINT8;
59 typedef unsigned short  UINT16;
60 typedef unsigned long   UINT32;
61 typedef signed   long   INT32;
62 typedef signed   char   INT8;
63 typedef signed   short  INT16;
64 typedef unsigned char   BOOLEAN;
65
66 #define FALSE    0
67 #define TRUE     (!FALSE)
68
69 #define BD_ADDR_LEN     6                   /* Device address length */
70 typedef UINT8 BD_ADDR[BD_ADDR_LEN];         /* Device address */
71
72
73
74 #define HCI_GRP_LINK_CONTROL_CMDS                 (0x01 << 10)
75 #define HCI_GRP_LINK_POLICY_CMDS                  (0x02 << 10)
76 #define HCI_GRP_HOST_CONT_BASEBAND_CMDS           (0x03 << 10)
77 #define HCI_GRP_INFORMATIONAL_PARAMS              (0x04 << 10)
78 #define HCI_GRP_STATUS_PARAMS                     (0x05 << 10)
79 #define HCI_GRP_TESTING_CMDS                      (0x06 << 10)
80 #define HCI_GRP_L2CAP_CMDS                        (0x07 << 10)
81 #define HCI_GRP_L2CAP_HCI_EVTS                    (0x08 << 10)
82 #define HCI_GRP_VENDOR_SPECIFIC                   (0x3F << 10)
83
84
85 #define HCI_RESET                                 (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
86 #define HCI_SET_EVENT_FILTER                      (0x0005 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
87 #define HCI_READ_SCAN_ENABLE                      (0x0019 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
88 #define HCI_WRITE_SCAN_ENABLE                     (0x001A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
89
90 #define HCI_READ_LOCAL_VERSION_INFO               (0x0001 | HCI_GRP_INFORMATIONAL_PARAMS)
91 #define HCI_READ_LOCAL_FEATURES                   (0x0003 | HCI_GRP_INFORMATIONAL_PARAMS)
92
93 #define HCI_ENABLE_DEV_UNDER_TEST_MODE            (0x0003 | HCI_GRP_TESTING_CMDS)
94
95 #define HCI_BRCM_SUPER_PEEK_POKE                  (0x000A | HCI_GRP_VENDOR_SPECIFIC)
96 #define VSC_WRITE_BD_ADDR                         (0x0001 | HCI_GRP_VENDOR_SPECIFIC)
97 #define VSC_HCI_CMD_SET_LOC_FEATURES_CMD          (0x000B | HCI_GRP_VENDOR_SPECIFIC)
98 #define HCI_BRCM_UPDATE_BAUDRATE_CMD              (0x0018 | HCI_GRP_VENDOR_SPECIFIC)
99 #define HCI_BRCM_WRITE_SCO_PCM_INT_PARAM          (0x001C | HCI_GRP_VENDOR_SPECIFIC)
100 #define VSC_WRITE_PCM_DATA_FORMAT_PARAM           (0x001E | HCI_GRP_VENDOR_SPECIFIC)
101 #define HCI_BRCM_WRITE_SLEEP_MODE                 (0x0027 | HCI_GRP_VENDOR_SPECIFIC)
102 #define HCI_BRCM_DOWNLOAD_MINI_DRV                (0x002E | HCI_GRP_VENDOR_SPECIFIC)
103 #define VSC_WRITE_UART_CLOCK_SETTING              (0x0045 | HCI_GRP_VENDOR_SPECIFIC)
104
105
106 #define VOICE_SETTING_MU_LAW_MD                   0x0100
107 #define VOICE_SETTING_LINEAR_MD                   0x0060
108
109 #define HCI_ARM_MEM_PEEK                          0x04
110 #define HCI_ARM_MEM_POKE                          0x05
111
112 #define BTUI_MAX_STRING_LENGTH_PER_LINE           255
113 #define HCI_BRCM_WRITE_SLEEP_MODE_LENGTH          10
114
115 #define HCI_BRCM_UPDATE_BAUD_RATE_ENCODED_LENGTH    0x02
116 #define HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH  0x06
117
118 #define VSC_WRITE_UART_CLOCK_SETTING_LEN          1
119
120 /* print string with time stamp */
121 #define TDEBUG0(m)                               if(debug_mode) {print_time();fprintf(stderr,m);}
122 #define TDEBUG1(m,n1)                            if(debug_mode) {print_time();fprintf(stderr,m,n1);}
123 #define TDEBUG2(m,n1,n2)                         if(debug_mode) {print_time();fprintf(stderr,m,n1,n2);}
124 #define TDEBUG3(m,n1,n2,n3)                      if(debug_mode) {print_time();fprintf(stderr,m,n1,n2,n3);}
125 #define TDEBUG4(m,n1,n2,n3,n4)                   if(debug_mode) {print_time();fprintf(stderr,m,n1,n2,n3,n4);}
126 #define TDEBUG5(m,n1,n2,n3,n4,n5)                if(debug_mode) {print_time();fprintf(stderr,m,n1,n2,n3,n4,n5);}
127 #define TDEBUG6(m,n1,n2,n3,n4,n5,n6)             if(debug_mode) {print_time();fprintf(stderr,m,n1,n2,n3,n4,n5,n6);}
128
129 /* print just string */
130 #define DEBUG0(m)                               if(debug_mode) {fprintf(stderr,m);}
131 #define DEBUG1(m,n1)                            if(debug_mode) {fprintf(stderr,m,n1);}
132 #define DEBUG2(m,n1,n2)                         if(debug_mode) {fprintf(stderr,m,n1,n2);}
133 #define DEBUG3(m,n1,n2,n3)                      if(debug_mode) {fprintf(stderr,m,n1,n2,n3);}
134 #define DEBUG4(m,n1,n2,n3,n4)                   if(debug_mode) {fprintf(stderr,m,n1,n2,n3,n4);}
135 #define DEBUG5(m,n1,n2,n3,n4,n5)                if(debug_mode) {fprintf(stderr,m,n1,n2,n3,n4,n5);}
136 #define DEBUG6(m,n1,n2,n3,n4,n5,n6)             if(debug_mode) {fprintf(stderr,m,n1,n2,n3,n4,n5,n6);}
137
138
139 #define STREAM_TO_UINT8(u8, p)   {u8 = (UINT8)(*(p)); (p) += 1;}
140 #define STREAM_TO_UINT16(u16, p) {u16 = ((UINT16)(*(p)) + (((UINT16)(*((p) + 1))) << 8)); (p) += 2;}
141 #define STREAM_TO_UINT32(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) + ((((UINT32)(*((p) + 3)))) << 24)); (p) += 4;}
142
143 #define ROTATE_BD_ADDR(p1, p2)    \
144                                                                         do                 \
145                                                                         {                                                       \
146                                                                                 p1[0] = p2[5];          \
147                                                                                 p1[1] = p2[4];          \
148                                                                                 p1[2] = p2[3];          \
149                                                                                 p1[3] = p2[2];          \
150                                                                                 p1[4] = p2[1];          \
151                                                                                 p1[5] = p2[0];          \
152                                                                         } while (0)     
153
154
155 UINT8 vsc_for_pcm_config[5] = {0x00, 0x00, 0x03, 0x03, 0x00};
156 /*
157                     Byte1 -- 0 for MSb first
158                     Byte2 -- 0 Fill value
159                     Byte3 -- 1 Fill option (0:0's, 1:1's , 2:Signed, 3:Programmable)
160                     Byte4 -- 1 Number of fill bits
161                     Byte5 -- 1 Right justified (0 for left justified)
162 */
163
164 UINT8 vsc_for_sco_pcm[5]    = {0x00, 0x01, 0x00, 0x01, 0x01};
165 /*
166                     Neverland : PCM, 256, short, master ,master
167                     Volance   : PCM, 256, short, master ,master
168                     
169                     Byte1 -- 0 for PCM 1 for UART or USB
170                     Byte2 -- 0 : 128, 1: 256, 2:512, 3:1024, 4:2048 Khz
171                     Byte3 -- 0 for short frame sync 1 for long frame sync
172                     Byte4 -- 0 Clock direction 0 for same as sync 1 for opposite direction
173                     Byte5 -- 0 for slave 1 for master
174 */                    
175
176 int fd;    /* HCI handle */
177
178 BOOLEAN debug_mode = FALSE;    /* Debug Mode Enable */
179
180 unsigned char buffer[1024];
181
182 struct termios termios;
183
184 void ChangeBaudRate(UINT32 baudrate);
185
186
187 void exit_err(UINT8 err)
188 {
189 #if ( HIGH_SPEED_PATCHRAM_DOWNLOAD == TRUE )
190     ChangeBaudRate(115200);
191 #endif
192     exit(err);
193 }
194
195 void print_time(void)
196 {
197 #if 0
198     struct timespec tp;
199     int rs;
200
201     rs = clock_gettime(CLOCK_REALTIME,&tp);
202     fprintf(stderr, "[%04d : %06d]\n", tp.tv_sec, tp.tv_nsec/1000);
203     return;
204 #endif
205 }
206
207 void dump(unsigned char *out, int len)
208 {
209     int i;
210     
211     for (i = 0; i < len; i++)
212     {
213         if (!(i % 16)) 
214         {
215             DEBUG0( "\n");
216         }    
217         DEBUG1( "%02x ", out[i]);
218     }
219     DEBUG0( "\n\n");
220 }
221
222 UINT8 SendCommand(UINT16 opcode, UINT8 param_len, UINT8 *p_param_buf)
223 {
224     UINT8 pbuf[255] = {0,};
225     UINT8 i=0;
226     UINT8 ret = 0;
227     
228     pbuf[0] = 0x1;
229     pbuf[1] = (UINT8)(opcode);
230     pbuf[2] = (UINT8)(opcode >>8);
231     pbuf[3] = param_len;
232
233     for (i=0; i<param_len; i++)
234     {        
235         pbuf[i+4] = *p_param_buf++;
236     }
237
238     DEBUG1( "Send %d",param_len+4);     
239
240     dump(pbuf, param_len+4);
241
242     ret = write(fd, pbuf, param_len+4);
243     if (ret != 0)
244         return -1;
245
246     return 0;
247 }
248
249 void expired(int sig)
250 {
251     static UINT8 count = 0;
252     DEBUG0( "expired try again\n");
253     SendCommand(HCI_RESET, 0, NULL);
254     alarm(1);
255     count++;
256
257     if(count > 3)
258     {
259         fprintf(stderr, "[ERR] HCI reset time expired\n");
260         exit(1);
261     }
262 }
263
264 void read_event(int fd, unsigned char *buffer)
265 {
266     int i = 0;
267     int len = 3;
268     int count;
269
270     while ((count = read(fd, &buffer[i], len)) < len) 
271     {
272         i += count;
273         len -= count;
274     }
275
276     i += count;
277     len = buffer[2];
278
279     while ((count = read(fd, &buffer[i], len)) < len) 
280     {
281         i += count;
282         len -= count;
283     }
284
285 #ifdef DEBUG
286     count += i;
287
288     DEBUG1( "\nreceived %d", count);
289     dump(buffer, count);
290 #endif
291 }
292
293 INT32 filesize (char *name) 
294 {
295     INT32 size;
296     int flag;
297     struct stat buf;
298
299     flag = stat (name,&buf);
300     if (flag == -1) 
301         return -1;
302
303     size = buf.st_size;
304     return (size);
305 }
306
307 void DisplayProgress(int total, int val)
308 {
309 #if 0
310     #define PROGRESS_NUM 20
311     
312     int p;
313     int i;
314     char text[PROGRESS_NUM+2]={0,};
315     
316     text[0]='[';
317     text[PROGRESS_NUM+1]=']';
318     p=(val*PROGRESS_NUM)/total;
319     
320     for ( i=1; i<=p; i++)
321     {
322         text[i]='=';
323     }
324     
325     for ( i=p+1; i<=PROGRESS_NUM; i++)
326     {
327         text[i]=' ';
328     }
329     
330     
331     for ( i=0; i<=(PROGRESS_NUM+1); i++)
332     {
333         fprintf(stderr, "%c",text[i]);
334     }
335     
336     if( p >= PROGRESS_NUM)
337         fprintf(stderr, "  %6d/%6d\n",val,total);
338     else
339         fprintf(stderr, "  %6d/%6d\r",val,total);
340 #else
341     if( val == total)
342         fprintf(stderr, " %6d/%6d\n",val,total);
343     else
344         fprintf(stderr, " %6d/%6d\r",val,total);
345 #endif
346 }
347
348 UINT8 DownloadPatchram( char *patchram1 )
349 {
350     UINT32 len;
351     char   prm[128] ={0,};
352     FILE* pFile = NULL;
353
354     INT32 FileSize=0;
355     INT32 SentSize=0;
356     INT8 ret = 0;
357     
358     DEBUG1( "\n%s\n", patchram1);
359
360     /* HCI reset */
361     DEBUG0( "HCI reset\n");
362     SendCommand(HCI_RESET, 0, NULL);
363     alarm(1);
364     read_event(fd, buffer);
365     alarm(0);
366     
367 #if ( HIGH_SPEED_PATCHRAM_DOWNLOAD == TRUE )
368     ChangeBaudRate(921600);
369 #endif
370
371     strcpy(prm, patchram1);    
372
373     fprintf(stderr, "Download Start\n");
374
375     if ((pFile = fopen(prm, "r")) == NULL) 
376     {
377         fprintf(stderr, "file %s could not be opened, error %d\n", prm, errno);
378         exit_err(1);
379     }
380     FileSize = filesize(prm);
381         
382     SendCommand(HCI_BRCM_DOWNLOAD_MINI_DRV, 0, NULL);
383     read_event(fd, buffer);
384
385         usleep(50000);
386
387     while (fread(&buffer[1], sizeof(UINT8), 3 ,pFile)) 
388     {
389         buffer[0] = 0x01;
390
391         len = buffer[3];
392
393         ret = fread(&buffer[4],sizeof(UINT8),len, pFile);
394          if (ret != 0)
395              return -1;
396
397          ret = write(fd, buffer, len + 4);
398          if (ret != 0)
399              return -1;
400
401         /* dispaly progress*/
402         SentSize += (len + 3);
403         DisplayProgress(FileSize,SentSize);
404         /* dispaly progress*/
405         
406         read_event(fd, buffer);
407
408     }
409     fclose(pFile);
410
411     usleep(100000);    /*100ms delay */
412
413     tcflush(fd, TCIOFLUSH);
414     tcgetattr(fd, &termios);
415     cfmakeraw(&termios);
416     termios.c_cflag |= CRTSCTS;
417     tcsetattr(fd, TCSANOW, &termios);
418     tcflush(fd, TCIOFLUSH);
419     tcsetattr(fd, TCSANOW, &termios);
420     tcflush(fd, TCIOFLUSH);
421     tcflush(fd, TCIOFLUSH);
422     cfsetospeed(&termios, B115200);
423     cfsetispeed(&termios, B115200);
424     tcsetattr(fd, TCSANOW, &termios);
425
426     /* Send HCI_RESET Command and process event */
427     DEBUG0( "HCI reset\n");
428     SendCommand(HCI_RESET, 0, NULL);
429     alarm(1);
430     read_event(fd, buffer);
431     alarm(0);
432     fprintf(stderr,"Download Complete\n");
433
434     return 0;
435 }
436
437 void SetScanEnable(void)
438 {
439     UINT8 scan_data[1] ;
440
441    /* 0x00: No scan enabled                            */
442    /* 0x01: Inquiry scan enabled  | Page scan disabled */
443    /* 0x02: Inquiry scan disabled | Page scan enabled  */
444    /* 0x03: Inquiry scan enabled  | Page scan enabled  */
445
446     scan_data[0]= 0x03;
447     SendCommand(HCI_WRITE_SCAN_ENABLE, 1, &scan_data[0]);
448     read_event(fd, buffer);
449 }
450
451 void SetAudio(void)
452 {
453     fprintf(stderr,"Write Audio parameter\n");
454
455     DEBUG5( "vsc_for_sco_pcm = {%d,%d,%d,%d,%d}\n", vsc_for_sco_pcm[0],
456                                          vsc_for_sco_pcm[1],vsc_for_sco_pcm[2],
457                                          vsc_for_sco_pcm[3],vsc_for_sco_pcm[4]);
458
459     SendCommand(HCI_BRCM_WRITE_SCO_PCM_INT_PARAM, 5, (UINT8 *)vsc_for_sco_pcm);
460     read_event(fd, buffer);
461
462     DEBUG5( "vsc_for_pcm_config = {%d,%d,%d,%d,%d}\n", vsc_for_pcm_config[0],
463                                         vsc_for_pcm_config[1], vsc_for_pcm_config[2],
464                                         vsc_for_pcm_config[3], vsc_for_pcm_config[4]);
465
466     SendCommand(VSC_WRITE_PCM_DATA_FORMAT_PARAM, 5, (UINT8 *)vsc_for_pcm_config);
467     read_event(fd, buffer);
468 }
469
470 void SetPcmConf( UINT8 p0, UINT8 p1, UINT8 p2, UINT8 p3, UINT8 p4 )
471 {
472     vsc_for_pcm_config[0] = p0;
473     vsc_for_pcm_config[1] = p1;
474     vsc_for_pcm_config[2] = p2;
475     vsc_for_pcm_config[3] = p3;
476     vsc_for_pcm_config[4] = p4;
477 }
478
479 void SetScoConf( UINT8 p0, UINT8 p1, UINT8 p2, UINT8 p3, UINT8 p4 )
480 {
481     vsc_for_sco_pcm[0] = p0;
482     vsc_for_sco_pcm[1] = p1;
483     vsc_for_sco_pcm[2] = p2;
484     vsc_for_sco_pcm[3] = p3;
485     vsc_for_sco_pcm[4] = p4;
486 }
487
488 void HCILP_Enable(BOOLEAN on)
489 {
490     fprintf(stderr,"Set Low Power mode %d\n",on);
491     UINT8 data[HCI_BRCM_WRITE_SLEEP_MODE_LENGTH] = {
492     0x01,                        /* Sleep Mode algorithm 1 */
493     HCILP_IDLE_THRESHOLD,        /* Host Idle Treshold in 300ms */
494     HCILP_HC_IDLE_THRESHOLD,     /* Host Controller Idle Treshold in 300ms */ /* this should be less than scan interval.*/
495     HCILP_BT_WAKE_POLARITY,      /* BT_WAKE Polarity - 0=Active Low, 1= Active High*/
496     HCILP_HOST_WAKE_POLARITY,    /* HOST_WAKE Polarity - 0=Active Low, 1= Active High */
497     0x01,                        /* Allow host Sleep during SCO */
498     0x01,                        /* Combine Sleep Mode and LPM - The device will not sleep in mode 0 if this flag is set to 1,*/
499     0x00,                        /* UART_TXD Tri-State : 0x00 = Do not tri-state UART_TXD in sleep mode */
500     0x00,                        /* NA to Mode 1 */
501     0x00,                        /* NA to Mode 1 */
502     };
503
504     if(on)
505     {
506         data[0] = 0x01;
507     }
508     else
509     {
510         data[0] = 0x00;
511     }
512
513     SendCommand(HCI_BRCM_WRITE_SLEEP_MODE, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH, (UINT8 *)data);
514     read_event(fd, buffer);
515 }
516
517 UINT32 uart_speed(UINT32 Speed)
518 {
519         switch (Speed) 
520         {
521         case 115200:
522                 return B115200;
523         case 230400:
524                 return B230400;
525         case 460800:
526                 return B460800;
527         case 921600:
528                 return B921600;
529         case 1000000:
530                 return B1000000;
531         case 1500000:
532                 return B1500000;
533         case 2000000:
534                 return B2000000;
535         case 2500000:
536                 return B2500000;
537         case 3000000:
538                 return B3000000;
539         case 4000000:
540                 return B4000000;
541         default:
542                 return B115200;
543         }
544 }
545
546 void ChangeBaudRate(UINT32 baudrate)
547 {
548     UINT8 hci_data[HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
549     UINT8 uart_clock_24 = 0x2;    /* 0x1 - UART Clock 48MHz, 0x2 - UART Clock 24MHz */    
550     UINT8 uart_clock_48 = 0x1;    /* 0x1 - UART Clock 48MHz, 0x2 - UART Clock 24MHz */
551
552     switch(baudrate)
553     {
554         case 115200:
555         case 230400:
556         case 460800:
557         case 921600:
558         case 1000000:
559         case 1500000:
560         case 2000000:
561         case 2500000:
562             /* Write UART Clock setting of 24MHz */
563             DEBUG0( "Change UART_CLOCK 24Mhz\n");    
564             SendCommand( VSC_WRITE_UART_CLOCK_SETTING, VSC_WRITE_UART_CLOCK_SETTING_LEN, (UINT8 *)&uart_clock_24);
565             read_event(fd, buffer);        
566             break;        
567
568         case 3000000:
569         case 4000000:
570             /* Write UART Clock setting of 48MHz */
571             DEBUG0( "Change UART_CLOCK 48Mh\nz");    
572             SendCommand( VSC_WRITE_UART_CLOCK_SETTING, VSC_WRITE_UART_CLOCK_SETTING_LEN, (UINT8 *)&uart_clock_48);
573             read_event(fd, buffer);        
574             break;
575             
576         default:
577             fprintf(stderr,"Not Support baudrate = %ld\n", baudrate);
578             exit_err(1);
579             break;
580     }
581
582     hci_data[2] = baudrate & 0xFF;
583     hci_data[3] = (baudrate >> 8) & 0xFF;
584     hci_data[4] = (baudrate >> 16) & 0xFF;
585     hci_data[5] = (baudrate >> 24) & 0xFF;
586     
587     DEBUG1( "Change Baudrate %ld\n",baudrate);    
588
589     SendCommand( HCI_BRCM_UPDATE_BAUDRATE_CMD, HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH, (UINT8 *)hci_data);
590     read_event(fd, buffer);
591
592     
593     tcflush(fd, TCIOFLUSH);
594     tcgetattr(fd, &termios);
595     cfmakeraw(&termios);
596     termios.c_cflag |= CRTSCTS;
597     tcsetattr(fd, TCSANOW, &termios);
598     tcflush(fd, TCIOFLUSH);
599     tcsetattr(fd, TCSANOW, &termios);
600     tcflush(fd, TCIOFLUSH);
601     tcflush(fd, TCIOFLUSH);
602     cfsetospeed(&termios, uart_speed(baudrate));
603     cfsetispeed(&termios, uart_speed(baudrate));
604     tcsetattr(fd, TCSANOW, &termios);
605
606 }
607
608 void EnableTestMode(void)
609 {
610     UINT8 filter_data[] = { 0x02, 0x00, 0x02 };
611     
612     /* bt sleep  disable */
613     HCILP_Enable(FALSE);
614
615     /* Enable both Inquiry & Page Scans */
616     SetScanEnable();
617
618     /* Set Event Filter: Enable Auto Connect */
619     SendCommand( HCI_SET_EVENT_FILTER, 0x03, (UINT8 *)filter_data);
620     read_event(fd, buffer);
621
622     /* Enable Device under test */
623     SendCommand( HCI_ENABLE_DEV_UNDER_TEST_MODE, 0x0, NULL);
624     read_event(fd, buffer);
625
626     fprintf(stderr,"Enable Device Under Test\n");
627 }
628
629 void SetLocalFeatures(void)
630 {
631     UINT8  *data = NULL;
632
633     DEBUG0("Read Local Feature\n");    
634     SendCommand(HCI_READ_LOCAL_FEATURES, 0, NULL);
635     read_event(fd, buffer);
636
637     data = &buffer[7];
638
639 #if (BCM_DISABLE_RF_PWRCTRL == TRUE)
640     fprintf(stderr,"Remove Power Control\n");
641     data[2] &= 0xFB;    /* Power contrel */
642 #endif
643     DEBUG0("Write Local Feature\n");    
644     SendCommand(VSC_HCI_CMD_SET_LOC_FEATURES_CMD, 0x08, (UINT8 *)data);
645     read_event(fd, buffer);
646 }
647
648 void EnbleHCI(void)
649 {
650     int i = N_HCI;
651     int proto = HCI_UART_H4;
652
653     if (ioctl(fd, TIOCSETD, &i) < 0) 
654     {
655         fprintf(stderr, "Can't set line discipline\n");
656         return;
657     }
658     
659     if (ioctl(fd, HCIUARTSETPROTO, proto) < 0) 
660     {
661         fprintf(stderr, "Can't set hci protocol\n");
662         return;
663     }
664     fprintf(stderr, "Done setting line discpline\n");
665     return;
666     
667 }
668 void print_usage( void )
669 {
670     fprintf(stderr,"\n");
671     fprintf(stderr,"BRCM BT tool for Linux    release %s\n",RELEASE_DATE);
672     fprintf(stderr,"\n");
673     fprintf(stderr," Usage: bcmtool <tty Device> <command> [command parameter],....\n\n");    
674     fprintf(stderr,"  -FILE    Patchram file name     EX) -FILE=BCM43xx_xxx.hcd\n");
675     fprintf(stderr,"  -BAUD    Set Baudrate           EX) -BAUD=3000000\n");
676     fprintf(stderr,"  -ADDR    BD addr file name      EX) -ADDR=.bdaddr\n");
677     fprintf(stderr,"  -SCO     Enable SCO/PCM config  EX) -SCO\n");
678     fprintf(stderr,"  -SETSCO  SCO/PCM values verify  EX) -SETSCO=0,1,0,1,1,0,0,3,3,0\n");
679     fprintf(stderr,"  -LP      Enable Low power       EX) -LP\n");
680     fprintf(stderr,"  -FEATURE Set local Feature      EX) -FEATURE\n");
681     fprintf(stderr,"  -DUT     Enable DUT mode(do not use with -LP) EX) -DUT\n");
682     fprintf(stderr,"  -ATTACH  Attach BT controller to BlueZ stack  EX) -ATTACH\n");    
683     fprintf(stderr,"  -DEBUG   Debug message          EX) -DEBUG\n");
684     fprintf(stderr,"\n");
685 }
686
687 int main(int argc, char *argv[])
688 {
689     UINT8 i = 0;
690     
691     if (argc < 2) 
692     {
693         print_usage();
694         exit(1);
695     }
696     else
697     {
698         fprintf(stderr,"BRCM BT tool for Linux    release %s\n",RELEASE_DATE);
699     }
700     
701     /* Open dev port */
702     if ((fd = open(argv[1], O_RDWR | O_NOCTTY)) == -1) 
703     {
704         fprintf(stderr, "port %s could not be opened, error %d\n", argv[1], errno);
705         exit(2);
706     }
707     
708     tcflush(fd, TCIOFLUSH);
709     tcgetattr(fd, &termios);
710     cfmakeraw(&termios);
711     termios.c_cflag |= CRTSCTS;
712     tcsetattr(fd, TCSANOW, &termios);
713     tcflush(fd, TCIOFLUSH);
714     tcsetattr(fd, TCSANOW, &termios);
715     tcflush(fd, TCIOFLUSH);
716     tcflush(fd, TCIOFLUSH);
717     cfsetospeed(&termios, B115200);
718     cfsetispeed(&termios, B115200);
719     tcsetattr(fd, TCSANOW, &termios);
720     
721     signal(SIGALRM, expired);
722
723     for( i=2; i<argc; i++ )
724     {
725         char *ptr = argv[i];
726
727         if( strstr(ptr,"-DEBUG") )
728         {
729             debug_mode = TRUE;
730             DEBUG0("DEBUG On\n");
731             break;
732         }
733     }
734     
735     for( i=2; i<argc; i++ )
736     {
737         char *ptr = argv[i];
738         
739         if(ptr == NULL)
740                 continue;
741         
742         fprintf(stderr,"[%d] %s\n", i-1, ptr);
743         
744         if( strstr(ptr,"-FILE=") )
745         {
746             char prm_name[128];
747
748             ptr += 6;
749
750             strncpy(prm_name,ptr, 127);
751             DownloadPatchram( prm_name );
752
753         }
754         else if( strstr(ptr,"-BAUD=") )
755         {
756             UINT32  baudrate;
757
758             ptr += 6;
759             baudrate = atoi(ptr);
760
761             ChangeBaudRate(baudrate);
762         }
763         else if( strstr(ptr,"-ADDR=") )
764         {
765             char *bdaddr_filename;
766             FILE* pFile = NULL;
767
768             int bdaddr[10];         /* Displayed BD Address */
769             
770             BD_ADDR local_addr;       /* BD Address for write */
771
772 #if 0            
773             ptr += 6;
774             if( sscanf(ptr,"%02X:%02X:%02X:%02X:%02X:%02X",&bdaddr[0],&bdaddr[1],&bdaddr[2],&bdaddr[3],&bdaddr[4],&bdaddr[5]) != 6 )
775             {
776                 fprintf(stderr,"-ADDR: Parameter error");
777                 exit_err(1);
778             }
779             bte_write_bdaddr(bdaddr);
780 #endif
781             ptr += 6;
782             bdaddr_filename = ptr;
783
784             if(bdaddr_filename)
785             {
786                pFile = fopen(bdaddr_filename, "r");
787             }          
788
789             if(pFile)
790             {
791                 char text[BTUI_MAX_STRING_LENGTH_PER_LINE];
792
793                 if ((fgets(text, BTUI_MAX_STRING_LENGTH_PER_LINE, pFile))!= NULL)
794                     sscanf(text,"%02x%02x",&bdaddr[0],&bdaddr[1]);
795
796                 if ((fgets(text, BTUI_MAX_STRING_LENGTH_PER_LINE, pFile)) != NULL)
797                     sscanf(text,"%02x",&bdaddr[2]);
798
799                 if ((fgets(text, BTUI_MAX_STRING_LENGTH_PER_LINE, pFile)) != NULL)
800                     sscanf(text,"%02x%02x%02x",&bdaddr[3],&bdaddr[4],&bdaddr[5]);
801
802                 fprintf(stderr,"Writing B/D Address = %02X:%02X:%02X:%02X:%02X:%02X\n",bdaddr[0],bdaddr[1],bdaddr[2],bdaddr[3],bdaddr[4],bdaddr[5]);
803
804                 ROTATE_BD_ADDR(local_addr,bdaddr);
805
806                 SendCommand(VSC_WRITE_BD_ADDR, BD_ADDR_LEN, (UINT8 *)local_addr);
807                 read_event(fd, buffer);
808             }    
809             else
810             {
811                 fprintf(stderr, "-ADDR: file open fail\n");
812                 exit_err(1);
813             }
814
815         }
816         else if( strstr(ptr,"-SCO") )
817         {
818             SetAudio();
819         
820         }
821         else if( strstr(ptr,"-SETSCO=") )
822         {
823             ptr += 8;
824             int value[10];
825             
826             if( sscanf(ptr,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",&value[0],&value[1],&value[2],&value[3],&value[4],
827                                                            &value[5],&value[6],&value[7],&value[8],&value[9]) != 10 )
828             {
829                 DEBUG0("PCM / SCO configuration value err\n");
830                 DEBUG0("SCO_Routing,PCM_Interface_Rate,Frame_Type,Sync_Mode,Clock_Mode,LSB_First,Fill_bits,Fill_Method,Fill_Num,Right_Justify\n");
831                 exit_err(1);
832             }
833
834             SetScoConf( value[0],value[1],value[2],value[3],value[4] );
835             SetPcmConf( value[5],value[6],value[7],value[8],value[9] );
836             SetAudio();
837         }
838         else if( strstr(ptr,"-LP") )
839         {
840             HCILP_Enable(TRUE);
841         }
842         else if( strstr(ptr,"-DUT") )
843         {
844             EnableTestMode();
845         }
846         else if( strstr(ptr,"-FEATURE") )
847         {
848             SetLocalFeatures();
849         }
850         else if( strstr(ptr,"-ATTACH") )
851         {
852             EnbleHCI();
853             while (1) 
854             {
855                 sleep(UINT_MAX);
856             }            
857         }
858         else if( strstr(ptr,"-DEBUG") )
859         {
860
861         }
862         else
863         {
864             fprintf(stderr,"Invalid parameter(s)!\n");
865             exit_err(1);
866         }
867     }
868
869     fprintf(stderr, "EXIT\n");
870     close(fd);
871     exit(0);
872
873     return 0;
874 }