** <--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:
#include <termios.h>
#else
#include <sys/termios.h>
+#include <sys/ioctl.h>
+#include <limits.h>
#endif
#include <string.h>
#include <signal.h>
-#include <cutils/properties.h>
-
#ifdef ANDROID
+#include <cutils/properties.h>
#define LOG_TAG "brcm_patchram_plus"
#include <cutils/log.h>
#undef printf
#define HCI_UART_H4DS 3
#define HCI_UART_LL 4
+typedef unsigned char uchar;
int uart_fd = -1;
int hcdfile_fd = -1;
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)
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 {
hci_write_bd_addr[4 + i] = bd_addr[i];
}
- bdaddr_flag = 1;
+ bdaddr_flag = 1;
return(0);
}
}
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;
{"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}
};
printf (" with arg %s", optarg);
printf ("\n");
}
- (*parse_param[option_index])(optarg);
+
+ ret = (*parse[option_index])(optarg);
+
break;
case 'd':
debug = 1;
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]);
}
void
-dump(unsigned char *out, int len)
+dump(uchar *out, int len)
{
int i;
}
void
-read_event(int fd, unsigned char *buffer)
+read_event(int fd, uchar *buffer)
{
int i = 0;
int len = 3;
}
void
-hci_send_cmd(unsigned char *buf, int len)
+hci_send_cmd(uchar *buf, int len)
{
if (debug) {
fprintf(stderr, "writing\n");
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;
}
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
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));
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();
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) {
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);
}