From: Howard M. Harte Date: Fri, 17 Jun 2011 03:39:55 +0000 (-0700) Subject: Bluetooth BRCM script updates for new chipsets. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=e1276c208588797c46cfe809f346becdb89eb9c0;p=android-x86%2Fsystem-bluetooth.git Bluetooth BRCM script updates for new chipsets. 1) add support for configuration of the SCO PCM interface 2) add support for configuration of the I2S interface 3) add support for different patchram download initialization for newer chips 4) Address review comments from change 22918. Change-Id: I7b764a65d1d7bbcaa46a7a5100566047d1ce3165 --- diff --git a/brcm_patchram_plus/Android.mk b/brcm_patchram_plus/Android.mk index 0d2e4eb..4ab55b8 100644 --- a/brcm_patchram_plus/Android.mk +++ b/brcm_patchram_plus/Android.mk @@ -14,6 +14,9 @@ LOCAL_MODULE := brcm_patchram_plus LOCAL_SHARED_LIBRARIES := libcutils liblog +LOCAL_C_FLAGS := \ + -DANDROID + include $(BUILD_EXECUTABLE) endif diff --git a/brcm_patchram_plus/brcm_patchram_plus.c b/brcm_patchram_plus/brcm_patchram_plus.c index 68355d2..bb15841 100644 --- a/brcm_patchram_plus/brcm_patchram_plus.c +++ b/brcm_patchram_plus/brcm_patchram_plus.c @@ -31,8 +31,56 @@ ** <--bd_addr bd_address> ** <--enable_lpm> ** <--enable_hci> -** <--pcm_role master|slave> ** <--use_baudrate_for_download> +** <--scopcm=sco_routing,pcm_interface_rate,frame_type, +** sync_mode,clock_mode,lsb_first,fill_bits, +** fill_method,fill_num,right_justify> +** +** Where +** +** sco_routing is 0 for PCM, 1 for Transport, +** 2 for Codec and 3 for I2S, +** +** pcm_interface_rate is 0 for 128KBps, 1 for +** 256 KBps, 2 for 512KBps, 3 for 1024KBps, +** and 4 for 2048Kbps, +** +** frame_type is 0 for short and 1 for long, +** +** sync_mode is 0 for slave and 1 for master, +** +** clock_mode is 0 for slabe and 1 for master, +** +** lsb_first is 0 for false aand 1 for true, +** +** fill_bits is the value in decimal for unused bits, +** +** fill_method is 0 for 0's and 1 for 1's, 2 for +** signed and 3 for programmable, +** +** fill_num is the number or bits to fill, +** +** right_justify is 0 for false and 1 for true +** +** <--i2s=i2s_enable,is_master,sample_rate,clock_rate> +** +** Where +** +** i2s_enable is 0 for disable and 1 for enable, +** +** is_master is 0 for slave and 1 for master, +** +** sample_rate is 0 for 8KHz, 1 for 16Khz and +** 2 for 4 KHz, +** +** clock_rate is 0 for 128KHz, 1 for 256KHz, 3 for +** 1024 KHz and 4 for 2048 KHz. +** +** <--no2bytes skips waiting for two byte confirmation +** before starting patchram download. Newer chips +** do not generate these two bytes.> +** <--tosleep=number of microsseconds to sleep before +** patchram download begins.> ** uart_device_name ** ** For example: @@ -70,14 +118,15 @@ #include #else #include +#include +#include #endif #include #include -#include - #ifdef ANDROID +#include #define LOG_TAG "brcm_patchram_plus" #include #undef printf @@ -102,6 +151,7 @@ #define HCI_UART_H4DS 3 #define HCI_UART_LL 4 +typedef unsigned char uchar; int uart_fd = -1; int hcdfile_fd = -1; @@ -109,42 +159,38 @@ int termios_baudrate = 0; int bdaddr_flag = 0; int enable_lpm = 0; int enable_hci = 0; -int pcm_slave = 0; -int pcm_master = 0; int use_baudrate_for_download = 0; int debug = 0; +int scopcm = 0; +int i2s = 0; +int no2bytes = 0; +int tosleep = 0; struct termios termios; -unsigned char buffer[1024]; +uchar buffer[1024]; -unsigned char hci_reset[] = { 0x01, 0x03, 0x0c, 0x00 }; +uchar hci_reset[] = { 0x01, 0x03, 0x0c, 0x00 }; -unsigned char hci_download_minidriver[] = { 0x01, 0x2e, 0xfc, 0x00 }; +uchar hci_download_minidriver[] = { 0x01, 0x2e, 0xfc, 0x00 }; -unsigned char hci_update_baud_rate[] = { 0x01, 0x18, 0xfc, 0x06, 0x00, 0x00, +uchar hci_update_baud_rate[] = { 0x01, 0x18, 0xfc, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -unsigned char hci_write_bd_addr[] = { 0x01, 0x01, 0xfc, 0x06, +uchar hci_write_bd_addr[] = { 0x01, 0x01, 0xfc, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -unsigned char hci_write_sleep_mode[] = { 0x01, 0x27, 0xfc, 0x0c, +uchar hci_write_sleep_mode[] = { 0x01, 0x27, 0xfc, 0x0c, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; -// HCI_COMMAND_PKT = 0x01 -// unpacked ogf/ocf: 0x3F 0x1C -// ... ((ocf & 0x03ff)|(ogf << 10)) => 0xFC1C (0x1C 0xFC) -// packet data len: 0x5 -// Data for the Write_SCO_PCM_Int_Param Message: -// 00 (Use PCM) -// 0x (02== 512 KHz bit clock, 03==1024 KHz bit clock, 04==2048 KHz) -// 01 (Long FS) -// 00 (Slave frame sync) -// 00 (Slave bit clock) -unsigned char hci_write_pcm_slave_mode[] = - { 0x01, 0x1C, 0xFC, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00 }; -unsigned char hci_write_pcm_master_mode[] = - { 0x01, 0x1C, 0xFC, 0x05, 0x00, 0x02, 0x00, 0x01, 0x01 }; +uchar hci_write_sco_pcm_int[] = + { 0x01, 0x1C, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +uchar hci_write_pcm_data_format[] = + { 0x01, 0x1e, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +uchar hci_write_i2spcm_interface_param[] = + { 0x01, 0x6d, 0xFC, 0x04, 0x00, 0x00, 0x00, 0x00 }; int parse_patchram(char *optarg) @@ -171,18 +217,18 @@ parse_patchram(char *optarg) return(0); } -void -BRCM_encode_baud_rate(uint baud_rate, unsigned char *encoded_baud) +void +BRCM_encode_baud_rate(uint baud_rate, uchar *encoded_baud) { if(baud_rate == 0 || encoded_baud == NULL) { fprintf(stderr, "Baudrate not supported!"); - return; + return; } - encoded_baud[3] = (unsigned char)(baud_rate >> 24); - encoded_baud[2] = (unsigned char)(baud_rate >> 16); - encoded_baud[1] = (unsigned char)(baud_rate >> 8); - encoded_baud[0] = (unsigned char)(baud_rate & 0xFF); + encoded_baud[3] = (uchar)(baud_rate >> 24); + encoded_baud[2] = (uchar)(baud_rate >> 16); + encoded_baud[1] = (uchar)(baud_rate >> 8); + encoded_baud[0] = (uchar)(baud_rate & 0xFF); } typedef struct { @@ -250,7 +296,7 @@ parse_bdaddr(char *optarg) hci_write_bd_addr[4 + i] = bd_addr[i]; } - bdaddr_flag = 1; + bdaddr_flag = 1; return(0); } @@ -277,35 +323,134 @@ parse_enable_hci(char *optarg) } int -parse_pcm_role(char *optarg) { - if(!strcmp(optarg, "master")) { - pcm_master = 1; - } else if (!strcmp(optarg, "slave")) { - pcm_slave = 1; - } else { - printf("Unknown PCM Role received: %s\n", optarg); - } - if (pcm_master && pcm_slave) { - fprintf(stderr, "Illegal command line- pcm role master && slave\n"); - exit(6); +parse_scopcm(char *optarg) +{ + int param[10]; + int ret; + int i; + + ret = sscanf(optarg, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", + ¶m[0], ¶m[1], ¶m[2], ¶m[3], ¶m[4], + ¶m[5], ¶m[6], ¶m[7], ¶m[8], ¶m[9]); + + if (ret != 10) { + return(1); + } + + scopcm = 1; + + for (i = 0; i < 5; i++) { + hci_write_sco_pcm_int[4 + i] = param[i]; + } + + for (i = 0; i < 5; i++) { + hci_write_pcm_data_format[4 + i] = param[5 + i]; + } + + return(0); +} + +int +parse_i2s(char *optarg) +{ + int param[4]; + int ret; + int i; + + ret = sscanf(optarg, "%d,%d,%d,%d", ¶m[0], ¶m[1], ¶m[2], + ¶m[3]); + + if (ret != 4) { + return(1); + } + + i2s = 1; + + for (i = 0; i < 4; i++) { + hci_write_i2spcm_interface_param[4 + i] = param[i]; } + + return(0); +} + +int +parse_no2bytes(char *optarg) +{ + no2bytes = 1; return(0); } int +parse_tosleep(char *optarg) +{ + tosleep = atoi(optarg); + + if (tosleep <= 0) { + return(1); + } + + return(0); +} + +void +usage(char *argv0) +{ + printf("Usage %s:\n", argv0); + printf("\t<-d> to print a debug log\n"); + printf("\t<--patchram patchram_file>\n"); + printf("\t<--baudrate baud_rate>\n"); + printf("\t<--bd_addr bd_address>\n"); + printf("\t<--enable_lpm>\n"); + printf("\t<--enable_hci>\n"); + printf("\t<--use_baudrate_for_download> - Uses the\n"); + printf("\t\tbaudrate for downloading the firmware\n"); + printf("\t<--scopcm=sco_routing,pcm_interface_rate,frame_type,\n"); + printf("\t\tsync_mode,clock_mode,lsb_first,fill_bits,\n"); + printf("\t\tfill_method,fill_num,right_justify>\n"); + printf("\n\t\tWhere\n"); + printf("\n\t\tsco_routing is 0 for PCM, 1 for Transport,\n"); + printf("\t\t2 for Codec and 3 for I2S,\n"); + printf("\n\t\tpcm_interface_rate is 0 for 128KBps, 1 for\n"); + printf("\t\t256 KBps, 2 for 512KBps, 3 for 1024KBps,\n"); + printf("\t\tand 4 for 2048Kbps,\n"); + printf("\n\t\tframe_type is 0 for short and 1 for long,\n"); + printf("\t\tsync_mode is 0 for slave and 1 for master,\n"); + printf("\n\t\tclock_mode is 0 for slabe and 1 for master,\n"); + printf("\n\t\tlsb_first is 0 for false aand 1 for true,\n"); + printf("\n\t\tfill_bits is the value in decimal for unused bits,\n"); + printf("\n\t\tfill_method is 0 for 0's and 1 for 1's, 2 for\n"); + printf("\t\tsigned and 3 for programmable,\n"); + printf("\n\t\tfill_num is the number or bits to fill,\n"); + printf("\n\t\tright_justify is 0 for false and 1 for true\n"); + printf("\n\t<--i2s=i2s_enable,is_master,sample_rate,clock_rate>\n"); + printf("\n\t\tWhere\n"); + printf("\n\t\ti2s_enable is 0 for disable and 1 for enable,\n"); + printf("\n\t\tis_master is 0 for slave and 1 for master,\n"); + printf("\n\t\tsample_rate is 0 for 8KHz, 1 for 16Khz and\n"); + printf("\t\t2 for 4 KHz,\n"); + printf("\n\t\tclock_rate is 0 for 128KHz, 1 for 256KHz, 3 for\n"); + printf("\t\t1024 KHz and 4 for 2048 KHz.\n\n"); + printf("\t<--no2bytes skips waiting for two byte confirmation\n"); + printf("\t\tbefore starting patchram download. Newer chips\n"); + printf("\t\tdo not generate these two bytes.>\n"); + printf("\t<--tosleep=microseconds>\n"); + printf("\tuart_device_name\n"); +} + +int parse_cmd_line(int argc, char **argv) { int c; - int digit_optind = 0; + int ret = 0; typedef int (*PFI)(); - PFI parse_param[] = { parse_patchram, parse_baudrate, + PFI parse[] = { parse_patchram, parse_baudrate, parse_bdaddr, parse_enable_lpm, parse_enable_hci, - parse_pcm_role, parse_use_baudrate_for_download}; + parse_use_baudrate_for_download, + parse_scopcm, parse_i2s, parse_no2bytes, parse_tosleep}; - while (1) - { + while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; @@ -315,8 +460,11 @@ parse_cmd_line(int argc, char **argv) {"bd_addr", 1, 0, 0}, {"enable_lpm", 0, 0, 0}, {"enable_hci", 0, 0, 0}, - {"pcm_role", 1, 0, 0}, {"use_baudrate_for_download", 0, 0, 0}, + {"scopcm", 1, 0, 0}, + {"i2s", 1, 0, 0}, + {"no2bytes", 0, 0, 0}, + {"tosleep", 1, 0, 0}, {0, 0, 0, 0} }; @@ -336,7 +484,9 @@ parse_cmd_line(int argc, char **argv) printf (" with arg %s", optarg); printf ("\n"); } - (*parse_param[option_index])(optarg); + + ret = (*parse[option_index])(optarg); + break; case 'd': debug = 1; @@ -345,21 +495,20 @@ parse_cmd_line(int argc, char **argv) case '?': //nobreak default: - printf("Usage %s:\n", argv[0]); - printf("\t<-d> to print a debug log\n"); - printf("\t<--patchram patchram_file>\n"); - printf("\t<--baudrate baud_rate>\n"); - printf("\t<--bd_addr bd_address>\n"); - printf("\t<--enable_lpm>\n"); - printf("\t<--enable_hci>\n"); - printf("\t<--pcm_role slave|master>\n"); - printf("\t<--use_baudrate_for_download> - Uses the\ - baudrate for downloading the\ - firmware\n"); - printf("\tuart_device_name\n"); + usage(argv[0]); break; } + + if (ret) { + usage(argv[0]); + break; + } } + + if (ret) { + return(1); + } + if (optind < argc) { if (debug) printf ("%s \n", argv[optind]); @@ -401,7 +550,7 @@ init_uart() } void -dump(unsigned char *out, int len) +dump(uchar *out, int len) { int i; @@ -417,7 +566,7 @@ dump(unsigned char *out, int len) } void -read_event(int fd, unsigned char *buffer) +read_event(int fd, uchar *buffer) { int i = 0; int len = 3; @@ -445,7 +594,7 @@ read_event(int fd, unsigned char *buffer) } void -hci_send_cmd(unsigned char *buf, int len) +hci_send_cmd(uchar *buf, int len) { if (debug) { fprintf(stderr, "writing\n"); @@ -486,9 +635,13 @@ proc_patchram() read_event(uart_fd, buffer); - read(uart_fd, &buffer[0], 2); + if (!no2bytes) { + read(uart_fd, &buffer[0], 2); + } - usleep(50000); + if (tosleep) { + usleep(tosleep); + } while (read(hcdfile_fd, &buffer[1], 3)) { buffer[0] = 0x01; @@ -538,19 +691,26 @@ proc_enable_lpm() } void -proc_pcm_slave() +proc_scopcm() { - if (debug) - printf("Configuring PCM Interface as slave.\n"); - hci_send_cmd(hci_write_pcm_slave_mode, sizeof(hci_write_pcm_slave_mode)); + hci_send_cmd(hci_write_sco_pcm_int, + sizeof(hci_write_sco_pcm_int)); + + read_event(uart_fd, buffer); + + hci_send_cmd(hci_write_pcm_data_format, + sizeof(hci_write_pcm_data_format)); + + read_event(uart_fd, buffer); } void -proc_pcm_master() +proc_i2s() { - if (debug) - printf("Configuring PCM Interface as master.\n"); - hci_send_cmd(hci_write_pcm_master_mode, sizeof(hci_write_pcm_master_mode)); + hci_send_cmd(hci_write_i2spcm_interface_param, + sizeof(hci_write_i2spcm_interface_param)); + + read_event(uart_fd, buffer); } void @@ -571,12 +731,15 @@ proc_enable_hci() return; } +#ifdef ANDROID void read_default_bdaddr() { int sz; int fd; + char path[PROPERTY_VALUE_MAX]; + char bdaddr[18]; int len = 17; memset(bdaddr, 0, (len + 1) * sizeof(char)); @@ -604,20 +767,28 @@ read_default_bdaddr() return; } - if (debug) + if (debug) { printf("Read default bdaddr of %s\n", bdaddr); + } + parse_bdaddr(bdaddr); } +#endif + int main (int argc, char **argv) { +#ifdef ANDROID read_default_bdaddr(); +#endif - parse_cmd_line(argc, argv); + if (parse_cmd_line(argc, argv)) { + exit(1); + } if (uart_fd < 0) { - exit(1); + exit(2); } init_uart(); @@ -628,18 +799,14 @@ main (int argc, char **argv) if (termios_baudrate) { proc_baudrate(); } + } - if (hcdfile_fd > 0) { - proc_patchram(); - } - } else { - if (hcdfile_fd > 0) { - proc_patchram(); - } + if (hcdfile_fd > 0) { + proc_patchram(); + } - if (termios_baudrate) { - proc_baudrate(); - } + if (termios_baudrate) { + proc_baudrate(); } if (bdaddr_flag) { @@ -650,14 +817,17 @@ main (int argc, char **argv) proc_enable_lpm(); } - if (pcm_slave) { - proc_pcm_slave(); - } else if (pcm_master) { - proc_pcm_master(); + if (scopcm) { + proc_scopcm(); + } + + if (i2s) { + proc_i2s(); } if (enable_hci) { proc_enable_hci(); + while (1) { sleep(UINT_MAX); }