Revert "[Warnings] Fix build warnings."
[platform/adaptation/bluetooth-firmware-bcm.git] / tools / bcmtool_4330b1.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     
227     pbuf[0] = 0x1;
228     pbuf[1] = (UINT8)(opcode);
229     pbuf[2] = (UINT8)(opcode >>8);
230     pbuf[3] = param_len;
231
232     for (i=0; i<param_len; i++)
233     {        
234         pbuf[i+4] = *p_param_buf++;
235     }
236
237     DEBUG1( "Send %d",param_len+4);     
238
239     dump(pbuf, param_len+4);
240
241     write(fd, pbuf, param_len+4);
242     return 0;
243 }
244
245 void expired(int sig)
246 {
247     static UINT8 count = 0;
248     DEBUG0( "expired try again\n");
249     SendCommand(HCI_RESET, 0, NULL);
250     alarm(1);
251     count++;
252
253     if(count > 3)
254     {
255         fprintf(stderr, "[ERR] HCI reset time expired\n");
256         exit(1);
257     }
258 }
259
260 void read_event(int fd, unsigned char *buffer)
261 {
262     int i = 0;
263     int len = 3;
264     int count;
265
266     while ((count = read(fd, &buffer[i], len)) < len) 
267     {
268         i += count;
269         len -= count;
270     }
271
272     i += count;
273     len = buffer[2];
274
275     while ((count = read(fd, &buffer[i], len)) < len) 
276     {
277         i += count;
278         len -= count;
279     }
280
281 #ifdef DEBUG
282     count += i;
283
284     DEBUG1( "\nreceived %d", count);
285     dump(buffer, count);
286 #endif
287 }
288
289 INT32 filesize (char *name) 
290 {
291     INT32 size;
292     int flag;
293     struct stat buf;
294
295     flag = stat (name,&buf);
296     if (flag == -1) 
297         return -1;
298
299     size = buf.st_size;
300     return (size);
301 }
302
303 void DisplayProgress(int total, int val)
304 {
305 #if 0
306     #define PROGRESS_NUM 20
307     
308     int p;
309     int i;
310     char text[PROGRESS_NUM+2]={0,};
311     
312     text[0]='[';
313     text[PROGRESS_NUM+1]=']';
314     p=(val*PROGRESS_NUM)/total;
315     
316     for ( i=1; i<=p; i++)
317     {
318         text[i]='=';
319     }
320     
321     for ( i=p+1; i<=PROGRESS_NUM; i++)
322     {
323         text[i]=' ';
324     }
325     
326     
327     for ( i=0; i<=(PROGRESS_NUM+1); i++)
328     {
329         fprintf(stderr, "%c",text[i]);
330     }
331     
332     if( p >= PROGRESS_NUM)
333         fprintf(stderr, "  %6d/%6d\n",val,total);
334     else
335         fprintf(stderr, "  %6d/%6d\r",val,total);
336 #else
337     if( val == total)
338         fprintf(stderr, " %6d/%6d\n",val,total);
339     else
340         fprintf(stderr, " %6d/%6d\r",val,total);
341 #endif
342 }
343
344 UINT8 DownloadPatchram( char *patchram1 )
345 {
346     UINT32 len;
347     char   prm[128] ={0,};
348     FILE* pFile = NULL;
349
350     INT32 FileSize=0;
351     INT32 SentSize=0;
352     
353     DEBUG1( "\n%s\n", patchram1);
354
355     /* HCI reset */
356     DEBUG0( "HCI reset\n");
357     SendCommand(HCI_RESET, 0, NULL);
358     alarm(1);
359     read_event(fd, buffer);
360     alarm(0);
361     
362 #if ( HIGH_SPEED_PATCHRAM_DOWNLOAD == TRUE )
363     ChangeBaudRate(921600);
364 #endif
365
366     strcpy(prm, patchram1);    
367
368     fprintf(stderr, "Download Start\n");
369
370     if ((pFile = fopen(prm, "r")) == NULL) 
371     {
372         fprintf(stderr, "file %s could not be opened, error %d\n", prm, errno);
373         exit_err(1);
374     }
375     FileSize = filesize(prm);
376         
377     SendCommand(HCI_BRCM_DOWNLOAD_MINI_DRV, 0, NULL);
378     read_event(fd, buffer);
379
380         usleep(50000);
381
382     while (fread(&buffer[1], sizeof(UINT8), 3 ,pFile)) 
383     {
384         buffer[0] = 0x01;
385
386         len = buffer[3];
387
388         fread(&buffer[4],sizeof(UINT8),len, pFile);
389
390         write(fd, buffer, len + 4);
391
392         /* dispaly progress*/
393         SentSize += (len + 3);
394         DisplayProgress(FileSize,SentSize);
395         /* dispaly progress*/
396         
397         read_event(fd, buffer);
398
399     }
400     fclose(pFile);
401
402     usleep(100000);    /*100ms delay */
403
404     tcflush(fd, TCIOFLUSH);
405     tcgetattr(fd, &termios);
406     cfmakeraw(&termios);
407     termios.c_cflag |= CRTSCTS;
408     tcsetattr(fd, TCSANOW, &termios);
409     tcflush(fd, TCIOFLUSH);
410     tcsetattr(fd, TCSANOW, &termios);
411     tcflush(fd, TCIOFLUSH);
412     tcflush(fd, TCIOFLUSH);
413     cfsetospeed(&termios, B115200);
414     cfsetispeed(&termios, B115200);
415     tcsetattr(fd, TCSANOW, &termios);
416
417     /* Send HCI_RESET Command and process event */
418     DEBUG0( "HCI reset\n");
419     SendCommand(HCI_RESET, 0, NULL);
420     alarm(1);
421     read_event(fd, buffer);
422     alarm(0);
423     fprintf(stderr,"Download Complete\n");
424
425     return 0;
426 }
427
428 void SetScanEnable(void)
429 {
430     UINT8 scan_data[1] ;
431
432    /* 0x00: No scan enabled                            */
433    /* 0x01: Inquiry scan enabled  | Page scan disabled */
434    /* 0x02: Inquiry scan disabled | Page scan enabled  */
435    /* 0x03: Inquiry scan enabled  | Page scan enabled  */
436
437     scan_data[0]= 0x03;
438     SendCommand(HCI_WRITE_SCAN_ENABLE, 1, &scan_data[0]);
439     read_event(fd, buffer);
440 }
441
442 void SetAudio(void)
443 {
444     fprintf(stderr,"Write Audio parameter\n");
445
446     DEBUG5( "vsc_for_sco_pcm = {%d,%d,%d,%d,%d}\n", vsc_for_sco_pcm[0],
447                                          vsc_for_sco_pcm[1],vsc_for_sco_pcm[2],
448                                          vsc_for_sco_pcm[3],vsc_for_sco_pcm[4]);
449
450     SendCommand(HCI_BRCM_WRITE_SCO_PCM_INT_PARAM, 5, (UINT8 *)vsc_for_sco_pcm);
451     read_event(fd, buffer);
452
453     DEBUG5( "vsc_for_pcm_config = {%d,%d,%d,%d,%d}\n", vsc_for_pcm_config[0],
454                                         vsc_for_pcm_config[1], vsc_for_pcm_config[2],
455                                         vsc_for_pcm_config[3], vsc_for_pcm_config[4]);
456
457     SendCommand(VSC_WRITE_PCM_DATA_FORMAT_PARAM, 5, (UINT8 *)vsc_for_pcm_config);
458     read_event(fd, buffer);
459 }
460
461 void SetPcmConf( UINT8 p0, UINT8 p1, UINT8 p2, UINT8 p3, UINT8 p4 )
462 {
463     vsc_for_pcm_config[0] = p0;
464     vsc_for_pcm_config[1] = p1;
465     vsc_for_pcm_config[2] = p2;
466     vsc_for_pcm_config[3] = p3;
467     vsc_for_pcm_config[4] = p4;
468 }
469
470 void SetScoConf( UINT8 p0, UINT8 p1, UINT8 p2, UINT8 p3, UINT8 p4 )
471 {
472     vsc_for_sco_pcm[0] = p0;
473     vsc_for_sco_pcm[1] = p1;
474     vsc_for_sco_pcm[2] = p2;
475     vsc_for_sco_pcm[3] = p3;
476     vsc_for_sco_pcm[4] = p4;
477 }
478
479 void HCILP_Enable(BOOLEAN on)
480 {
481     fprintf(stderr,"Set Low Power mode %d\n",on);
482     UINT8 data[HCI_BRCM_WRITE_SLEEP_MODE_LENGTH] = {
483     0x01,                        /* Sleep Mode algorithm 1 */
484     HCILP_IDLE_THRESHOLD,        /* Host Idle Treshold in 300ms */
485     HCILP_HC_IDLE_THRESHOLD,     /* Host Controller Idle Treshold in 300ms */ /* this should be less than scan interval.*/
486     HCILP_BT_WAKE_POLARITY,      /* BT_WAKE Polarity - 0=Active Low, 1= Active High*/
487     HCILP_HOST_WAKE_POLARITY,    /* HOST_WAKE Polarity - 0=Active Low, 1= Active High */
488     0x01,                        /* Allow host Sleep during SCO */
489     0x01,                        /* Combine Sleep Mode and LPM - The device will not sleep in mode 0 if this flag is set to 1,*/
490     0x00,                        /* UART_TXD Tri-State : 0x00 = Do not tri-state UART_TXD in sleep mode */
491     0x00,                        /* NA to Mode 1 */
492     0x00,                        /* NA to Mode 1 */
493     };
494
495     if(on)
496     {
497         data[0] = 0x01;
498     }
499     else
500     {
501         data[0] = 0x00;
502     }
503
504     SendCommand(HCI_BRCM_WRITE_SLEEP_MODE, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH, (UINT8 *)data);
505     read_event(fd, buffer);
506 }
507
508 UINT32 uart_speed(UINT32 Speed)
509 {
510         switch (Speed) 
511         {
512         case 115200:
513                 return B115200;
514         case 230400:
515                 return B230400;
516         case 460800:
517                 return B460800;
518         case 921600:
519                 return B921600;
520         case 1000000:
521                 return B1000000;
522         case 1500000:
523                 return B1500000;
524         case 2000000:
525                 return B2000000;
526         case 2500000:
527                 return B2500000;
528         case 3000000:
529                 return B3000000;
530         case 4000000:
531                 return B4000000;
532         default:
533                 return B115200;
534         }
535 }
536
537 void ChangeBaudRate(UINT32 baudrate)
538 {
539     UINT8 hci_data[HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
540     UINT8 uart_clock_24 = 0x2;    /* 0x1 - UART Clock 48MHz, 0x2 - UART Clock 24MHz */    
541     UINT8 uart_clock_48 = 0x1;    /* 0x1 - UART Clock 48MHz, 0x2 - UART Clock 24MHz */
542
543     switch(baudrate)
544     {
545         case 115200:
546         case 230400:
547         case 460800:
548         case 921600:
549         case 1000000:
550         case 1500000:
551         case 2000000:
552         case 2500000:
553             /* Write UART Clock setting of 24MHz */
554             DEBUG0( "Change UART_CLOCK 24Mhz\n");    
555             SendCommand( VSC_WRITE_UART_CLOCK_SETTING, VSC_WRITE_UART_CLOCK_SETTING_LEN, (UINT8 *)&uart_clock_24);
556             read_event(fd, buffer);        
557             break;        
558
559         case 3000000:
560         case 4000000:
561             /* Write UART Clock setting of 48MHz */
562             DEBUG0( "Change UART_CLOCK 48Mh\nz");    
563             SendCommand( VSC_WRITE_UART_CLOCK_SETTING, VSC_WRITE_UART_CLOCK_SETTING_LEN, (UINT8 *)&uart_clock_48);
564             read_event(fd, buffer);        
565             break;
566             
567         default:
568             fprintf(stderr,"Not Support baudrate = %ld\n", baudrate);
569             exit_err(1);
570             break;
571     }
572
573     hci_data[2] = baudrate & 0xFF;
574     hci_data[3] = (baudrate >> 8) & 0xFF;
575     hci_data[4] = (baudrate >> 16) & 0xFF;
576     hci_data[5] = (baudrate >> 24) & 0xFF;
577     
578     DEBUG1( "Change Baudrate %ld\n",baudrate);    
579
580     SendCommand( HCI_BRCM_UPDATE_BAUDRATE_CMD, HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH, (UINT8 *)hci_data);
581     read_event(fd, buffer);
582
583     
584     tcflush(fd, TCIOFLUSH);
585     tcgetattr(fd, &termios);
586     cfmakeraw(&termios);
587     termios.c_cflag |= CRTSCTS;
588     tcsetattr(fd, TCSANOW, &termios);
589     tcflush(fd, TCIOFLUSH);
590     tcsetattr(fd, TCSANOW, &termios);
591     tcflush(fd, TCIOFLUSH);
592     tcflush(fd, TCIOFLUSH);
593     cfsetospeed(&termios, uart_speed(baudrate));
594     cfsetispeed(&termios, uart_speed(baudrate));
595     tcsetattr(fd, TCSANOW, &termios);
596
597 }
598
599 void EnableTestMode(void)
600 {
601     UINT8 filter_data[] = { 0x02, 0x00, 0x02 };
602     
603     /* bt sleep  disable */
604     HCILP_Enable(FALSE);
605
606     /* Enable both Inquiry & Page Scans */
607     SetScanEnable();
608
609     /* Set Event Filter: Enable Auto Connect */
610     SendCommand( HCI_SET_EVENT_FILTER, 0x03, (UINT8 *)filter_data);
611     read_event(fd, buffer);
612
613     /* Enable Device under test */
614     SendCommand( HCI_ENABLE_DEV_UNDER_TEST_MODE, 0x0, NULL);
615     read_event(fd, buffer);
616
617     fprintf(stderr,"Enable Device Under Test\n");
618 }
619
620 void SetLocalFeatures(void)
621 {
622     UINT8  *data = NULL;
623
624     DEBUG0("Read Local Feature\n");    
625     SendCommand(HCI_READ_LOCAL_FEATURES, 0, NULL);
626     read_event(fd, buffer);
627
628     data = &buffer[7];
629
630 #if (BCM_DISABLE_RF_PWRCTRL == TRUE)
631     fprintf(stderr,"Remove Power Control\n");
632     data[2] &= 0xFB;    /* Power contrel */
633 #endif
634     DEBUG0("Write Local Feature\n");    
635     SendCommand(VSC_HCI_CMD_SET_LOC_FEATURES_CMD, 0x08, (UINT8 *)data);
636     read_event(fd, buffer);
637 }
638
639 void EnbleHCI(void)
640 {
641     int i = N_HCI;
642     int proto = HCI_UART_H4;
643
644     if (ioctl(fd, TIOCSETD, &i) < 0) 
645     {
646         fprintf(stderr, "Can't set line discipline\n");
647         return;
648     }
649     
650     if (ioctl(fd, HCIUARTSETPROTO, proto) < 0) 
651     {
652         fprintf(stderr, "Can't set hci protocol\n");
653         return;
654     }
655     fprintf(stderr, "Done setting line discpline\n");
656     return;
657     
658 }
659 void print_usage( void )
660 {
661     fprintf(stderr,"\n");
662     fprintf(stderr,"BRCM BT tool for Linux    release %s\n",RELEASE_DATE);
663     fprintf(stderr,"\n");
664     fprintf(stderr," Usage: bcmtool <tty Device> <command> [command parameter],....\n\n");    
665     fprintf(stderr,"  -FILE    Patchram file name     EX) -FILE=BCM43xx_xxx.hcd\n");
666     fprintf(stderr,"  -BAUD    Set Baudrate           EX) -BAUD=3000000\n");
667     fprintf(stderr,"  -ADDR    BD addr file name      EX) -ADDR=.bdaddr\n");
668     fprintf(stderr,"  -SCO     Enable SCO/PCM config  EX) -SCO\n");
669     fprintf(stderr,"  -SETSCO  SCO/PCM values verify  EX) -SETSCO=0,1,0,1,1,0,0,3,3,0\n");
670     fprintf(stderr,"  -LP      Enable Low power       EX) -LP\n");
671     fprintf(stderr,"  -FEATURE Set local Feature      EX) -FEATURE\n");
672     fprintf(stderr,"  -DUT     Enable DUT mode(do not use with -LP) EX) -DUT\n");
673     fprintf(stderr,"  -ATTACH  Attach BT controller to BlueZ stack  EX) -ATTACH\n");    
674     fprintf(stderr,"  -DEBUG   Debug message          EX) -DEBUG\n");
675     fprintf(stderr,"\n");
676 }
677
678 int main(int argc, char *argv[])
679 {
680     UINT8 i = 0;
681     
682     if (argc < 2) 
683     {
684         print_usage();
685         exit(1);
686     }
687     else
688     {
689         fprintf(stderr,"BRCM BT tool for Linux    release %s\n",RELEASE_DATE);
690     }
691     
692     /* Open dev port */
693     if ((fd = open(argv[1], O_RDWR | O_NOCTTY)) == -1) 
694     {
695         fprintf(stderr, "port %s could not be opened, error %d\n", argv[1], errno);
696         exit(2);
697     }
698     
699     tcflush(fd, TCIOFLUSH);
700     tcgetattr(fd, &termios);
701     cfmakeraw(&termios);
702     termios.c_cflag |= CRTSCTS;
703     tcsetattr(fd, TCSANOW, &termios);
704     tcflush(fd, TCIOFLUSH);
705     tcsetattr(fd, TCSANOW, &termios);
706     tcflush(fd, TCIOFLUSH);
707     tcflush(fd, TCIOFLUSH);
708     cfsetospeed(&termios, B115200);
709     cfsetispeed(&termios, B115200);
710     tcsetattr(fd, TCSANOW, &termios);
711     
712     signal(SIGALRM, expired);
713
714     for( i=2; i<argc; i++ )
715     {
716         char *ptr = argv[i];
717
718         if( strstr(ptr,"-DEBUG") )
719         {
720             debug_mode = TRUE;
721             DEBUG0("DEBUG On\n");
722             break;
723         }
724     }
725     
726     for( i=2; i<argc; i++ )
727     {
728         char *ptr = argv[i];
729         
730         if(ptr == NULL)
731                 continue;
732         
733         fprintf(stderr,"[%d] %s\n", i-1, ptr);
734         
735         if( strstr(ptr,"-FILE=") )
736         {
737             char prm_name[128];
738
739             ptr += 6;
740
741             strncpy(prm_name,ptr, 127);
742             DownloadPatchram( prm_name );
743
744         }
745         else if( strstr(ptr,"-BAUD=") )
746         {
747             UINT32  baudrate;
748
749             ptr += 6;
750             baudrate = atoi(ptr);
751
752             ChangeBaudRate(baudrate);
753         }
754         else if( strstr(ptr,"-ADDR=") )
755         {
756             char *bdaddr_filename;
757             FILE* pFile = NULL;
758
759             int bdaddr[10];         /* Displayed BD Address */
760             
761             BD_ADDR local_addr;       /* BD Address for write */
762
763 #if 0            
764             ptr += 6;
765             if( sscanf(ptr,"%02X:%02X:%02X:%02X:%02X:%02X",&bdaddr[0],&bdaddr[1],&bdaddr[2],&bdaddr[3],&bdaddr[4],&bdaddr[5]) != 6 )
766             {
767                 fprintf(stderr,"-ADDR: Parameter error");
768                 exit_err(1);
769             }
770             bte_write_bdaddr(bdaddr);
771 #endif
772             ptr += 6;
773             bdaddr_filename = ptr;
774
775             if(bdaddr_filename)
776             {
777                pFile = fopen(bdaddr_filename, "r");
778             }          
779
780             if(pFile)
781             {
782                 char text[BTUI_MAX_STRING_LENGTH_PER_LINE];
783
784                 fgets(text, BTUI_MAX_STRING_LENGTH_PER_LINE, pFile);
785                 sscanf(text,"%02x%02x",&bdaddr[0],&bdaddr[1]);
786
787                 fgets(text, BTUI_MAX_STRING_LENGTH_PER_LINE, pFile);
788                 sscanf(text,"%02x",&bdaddr[2]);
789
790                 fgets(text, BTUI_MAX_STRING_LENGTH_PER_LINE, pFile);
791                 sscanf(text,"%02x%02x%02x",&bdaddr[3],&bdaddr[4],&bdaddr[5]);
792
793                 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]);
794
795                 ROTATE_BD_ADDR(local_addr,bdaddr);
796
797                 SendCommand(VSC_WRITE_BD_ADDR, BD_ADDR_LEN, (UINT8 *)local_addr);
798                 read_event(fd, buffer);
799             }    
800             else
801             {
802                 fprintf(stderr, "-ADDR: file open fail\n");
803                 exit_err(1);
804             }
805
806         }
807         else if( strstr(ptr,"-SCO") )
808         {
809             SetAudio();
810         
811         }
812         else if( strstr(ptr,"-SETSCO=") )
813         {
814             ptr += 8;
815             int value[10];
816             
817             if( sscanf(ptr,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",&value[0],&value[1],&value[2],&value[3],&value[4],
818                                                            &value[5],&value[6],&value[7],&value[8],&value[9]) != 10 )
819             {
820                 DEBUG0("PCM / SCO configuration value err\n");
821                 DEBUG0("SCO_Routing,PCM_Interface_Rate,Frame_Type,Sync_Mode,Clock_Mode,LSB_First,Fill_bits,Fill_Method,Fill_Num,Right_Justify\n");
822                 exit_err(1);
823             }
824
825             SetScoConf( value[0],value[1],value[2],value[3],value[4] );
826             SetPcmConf( value[5],value[6],value[7],value[8],value[9] );
827             SetAudio();
828         }
829         else if( strstr(ptr,"-LP") )
830         {
831             HCILP_Enable(TRUE);
832         }
833         else if( strstr(ptr,"-DUT") )
834         {
835             EnableTestMode();
836         }
837         else if( strstr(ptr,"-FEATURE") )
838         {
839             SetLocalFeatures();
840         }
841         else if( strstr(ptr,"-ATTACH") )
842         {
843             EnbleHCI();
844             while (1) 
845             {
846                 sleep(UINT_MAX);
847             }            
848         }
849         else if( strstr(ptr,"-DEBUG") )
850         {
851
852         }
853         else
854         {
855             fprintf(stderr,"Invalid parameter(s)!\n");
856             exit_err(1);
857         }
858     }
859
860     fprintf(stderr, "EXIT\n");
861     close(fd);
862     exit(0);
863
864     return 0;
865 }