1 /******************************************************************************
2 *
3 * Copyright (C) 2009-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * Filename: hardware.c
22 *
23 * Description: Contains controller-specific functions, like
24 * firmware patch download
25 * low power mode operations
26 *
27 ******************************************************************************/
28
29 #define LOG_TAG "bt_hwcfg"
30
31 #include <utils/Log.h>
32 #include <sys/types.h>
33 #include <stdbool.h>
34 #include <sys/stat.h>
35 #include <signal.h>
36 #include <time.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <dirent.h>
40 #include <ctype.h>
41 #include <cutils/properties.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <stdio.h>
45 #include <unistd.h>
46 #include "bt_hci_bdroid.h"
47 #include "bt_vendor_brcm.h"
48 #include "esco_parameters.h"
49 #include "userial.h"
50 #include "userial_vendor.h"
51 #include "upio.h"
52
53 /******************************************************************************
54 ** Constants & Macros
55 ******************************************************************************/
56
57 #ifndef BTHW_DBG
58 #define BTHW_DBG FALSE
59 #endif
60
61 #if (BTHW_DBG == TRUE)
62 #define BTHWDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);}
63 #else
64 #define BTHWDBG(param, ...) {}
65 #endif
66
67 #define FW_PATCHFILE_EXTENSION ".hcd"
68 #define FW_PATCHFILE_EXTENSION_LEN 4
69 #define FW_PATCHFILE_PATH_MAXLEN 248 /* Local_Name length of return of
70 HCI_Read_Local_Name */
71
72 #define HCI_CMD_MAX_LEN 258
73
74 #define HCI_RESET 0x0C03
75 #define HCI_VSC_WRITE_UART_CLOCK_SETTING 0xFC45
76 #define HCI_VSC_UPDATE_BAUDRATE 0xFC18
77 #define HCI_READ_LOCAL_NAME 0x0C14
78 #define HCI_VSC_DOWNLOAD_MINIDRV 0xFC2E
79 #define HCI_VSC_WRITE_BD_ADDR 0xFC01
80 #define HCI_VSC_WRITE_SLEEP_MODE 0xFC27
81 #define HCI_VSC_WRITE_SCO_PCM_INT_PARAM 0xFC1C
82 #define HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM 0xFC1E
83 #define HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM 0xFC6D
84 #define HCI_VSC_ENABLE_WBS 0xFC7E
85 #define HCI_VSC_LAUNCH_RAM 0xFC4E
86 #define HCI_READ_LOCAL_BDADDR 0x1009
87
88 #define HCI_EVT_CMD_CMPL_STATUS_RET_BYTE 5
89 #define HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING 6
90 #define HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY 6
91 #define HCI_EVT_CMD_CMPL_OPCODE 3
92 #define LPM_CMD_PARAM_SIZE 12
93 #define UPDATE_BAUDRATE_CMD_PARAM_SIZE 6
94 #define HCI_CMD_PREAMBLE_SIZE 3
95 #define HCD_REC_PAYLOAD_LEN_BYTE 2
96 #define BD_ADDR_LEN 6
97 #define LOCAL_NAME_BUFFER_LEN 32
98 #define LOCAL_BDADDR_PATH_BUFFER_LEN 256
99
100 #define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;}
101 #define UINT8_TO_STREAM(p, u8) {*(p)++ = (uint8_t)(u8);}
102 #define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
103 #define UINT32_TO_STREAM(p, u32) {*(p)++ = (uint8_t)(u32); *(p)++ = (uint8_t)((u32) >> 8); *(p)++ = (uint8_t)((u32) >> 16); *(p)++ = (uint8_t)((u32) >> 24);}
104
105 #define SCO_INTERFACE_PCM 0
106 #define SCO_INTERFACE_I2S 1
107
108 /* one byte is for enable/disable
109 next 2 bytes are for codec type */
110 #define SCO_CODEC_PARAM_SIZE 3
111
112 /******************************************************************************
113 ** Local type definitions
114 ******************************************************************************/
115
116 /* Hardware Configuration State */
117 enum {
118 HW_CFG_START = 1,
119 HW_CFG_SET_UART_CLOCK,
120 HW_CFG_SET_UART_BAUD_1,
121 HW_CFG_READ_LOCAL_NAME,
122 HW_CFG_DL_MINIDRIVER,
123 HW_CFG_DL_FW_PATCH,
124 HW_CFG_SET_UART_BAUD_2,
125 HW_CFG_SET_BD_ADDR
126 #if (USE_CONTROLLER_BDADDR == TRUE)
127 , HW_CFG_READ_BD_ADDR
128 #endif
129 };
130
131 /* h/w config control block */
132 typedef struct
133 {
134 uint8_t state; /* Hardware configuration state */
135 int fw_fd; /* FW patch file fd */
136 uint8_t f_set_baud_2; /* Baud rate switch state */
137 char local_chip_name[LOCAL_NAME_BUFFER_LEN];
138 } bt_hw_cfg_cb_t;
139
140 /* low power mode parameters */
141 typedef struct
142 {
143 uint8_t sleep_mode; /* 0(disable),1(UART),9(H5) */
144 uint8_t host_stack_idle_threshold; /* Unit scale 300ms/25ms */
145 uint8_t host_controller_idle_threshold; /* Unit scale 300ms/25ms */
146 uint8_t bt_wake_polarity; /* 0=Active Low, 1= Active High */
147 uint8_t host_wake_polarity; /* 0=Active Low, 1= Active High */
148 uint8_t allow_host_sleep_during_sco;
149 uint8_t combine_sleep_mode_and_lpm;
150 uint8_t enable_uart_txd_tri_state; /* UART_TXD Tri-State */
151 uint8_t sleep_guard_time; /* sleep guard time in 12.5ms */
152 uint8_t wakeup_guard_time; /* wakeup guard time in 12.5ms */
153 uint8_t txd_config; /* TXD is high in sleep state */
154 uint8_t pulsed_host_wake; /* pulsed host wake if mode = 1 */
155 } bt_lpm_param_t;
156
157 /* Firmware re-launch settlement time */
158 typedef struct {
159 const char *chipset_name;
160 const uint32_t delay_time;
161 } fw_settlement_entry_t;
162
163
164 /******************************************************************************
165 ** Externs
166 ******************************************************************************/
167
168 void hw_config_cback(void *p_evt_buf);
169 extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN];
170
171
172 /******************************************************************************
173 ** Static variables
174 ******************************************************************************/
175
176 static char fw_patchfile_path[256] = FW_PATCHFILE_LOCATION;
177 static char fw_patchfile_name[128] = { 0 };
178 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
179 static int fw_patch_settlement_delay = -1;
180 #endif
181
182 static int wbs_sample_rate = SCO_WBS_SAMPLE_RATE;
183 static bt_hw_cfg_cb_t hw_cfg_cb;
184
185 static bt_lpm_param_t lpm_param =
186 {
187 LPM_SLEEP_MODE,
188 LPM_IDLE_THRESHOLD,
189 LPM_HC_IDLE_THRESHOLD,
190 LPM_BT_WAKE_POLARITY,
191 LPM_HOST_WAKE_POLARITY,
192 LPM_ALLOW_HOST_SLEEP_DURING_SCO,
193 LPM_COMBINE_SLEEP_MODE_AND_LPM,
194 LPM_ENABLE_UART_TXD_TRI_STATE,
195 0, /* not applicable */
196 0, /* not applicable */
197 0, /* not applicable */
198 LPM_PULSED_HOST_WAKE
199 };
200
201 /* need to update the bt_sco_i2spcm_param as well
202 bt_sco_i2spcm_param will be used for WBS setting
203 update the bt_sco_param and bt_sco_i2spcm_param */
204 static uint8_t bt_sco_param[SCO_PCM_PARAM_SIZE] =
205 {
206 SCO_PCM_ROUTING,
207 SCO_PCM_IF_CLOCK_RATE,
208 SCO_PCM_IF_FRAME_TYPE,
209 SCO_PCM_IF_SYNC_MODE,
210 SCO_PCM_IF_CLOCK_MODE
211 };
212
213 static uint8_t bt_pcm_data_fmt_param[PCM_DATA_FORMAT_PARAM_SIZE] =
214 {
215 PCM_DATA_FMT_SHIFT_MODE,
216 PCM_DATA_FMT_FILL_BITS,
217 PCM_DATA_FMT_FILL_METHOD,
218 PCM_DATA_FMT_FILL_NUM,
219 PCM_DATA_FMT_JUSTIFY_MODE
220 };
221
222 static uint8_t bt_sco_i2spcm_param[SCO_I2SPCM_PARAM_SIZE] =
223 {
224 SCO_I2SPCM_IF_MODE,
225 SCO_I2SPCM_IF_ROLE,
226 SCO_I2SPCM_IF_SAMPLE_RATE,
227 SCO_I2SPCM_IF_CLOCK_RATE
228 };
229
230 /*
231 * The look-up table of recommended firmware settlement delay (milliseconds) on
232 * known chipsets.
233 */
234 static const fw_settlement_entry_t fw_settlement_table[] = {
235 {"BCM43241", 200},
236 {"BCM43341", 100},
237 {(const char *) NULL, 100} // Giving the generic fw settlement delay setting.
238 };
239
240
241 /*
242 * NOTICE:
243 * If the platform plans to run I2S interface bus over I2S/PCM port of the
244 * BT Controller with the Host AP, explicitly set "SCO_USE_I2S_INTERFACE = TRUE"
245 * in the correspodning include/vnd_<target>.txt file.
246 * Otherwise, leave SCO_USE_I2S_INTERFACE undefined in the vnd_<target>.txt file.
247 * And, PCM interface will be set as the default bus format running over I2S/PCM
248 * port.
249 */
250 #if (defined(SCO_USE_I2S_INTERFACE) && SCO_USE_I2S_INTERFACE == TRUE)
251 static uint8_t sco_bus_interface = SCO_INTERFACE_I2S;
252 #else
253 static uint8_t sco_bus_interface = SCO_INTERFACE_PCM;
254 #endif
255
256 #define INVALID_SCO_CLOCK_RATE 0xFF
257 static uint8_t sco_bus_clock_rate = INVALID_SCO_CLOCK_RATE;
258 static uint8_t sco_bus_wbs_clock_rate = INVALID_SCO_CLOCK_RATE;
259
260 /******************************************************************************
261 ** Static functions
262 ******************************************************************************/
263 static void hw_sco_i2spcm_config(uint16_t codec);
264 static void hw_sco_i2spcm_config_from_command(void *p_mem, uint16_t codec);
265
266 /******************************************************************************
267 ** Controller Initialization Static Functions
268 ******************************************************************************/
269
270 /*******************************************************************************
271 **
272 ** Function look_up_fw_settlement_delay
273 **
274 ** Description If FW_PATCH_SETTLEMENT_DELAY_MS has not been explicitly
275 ** re-defined in the platform specific build-time configuration
276 ** file, we will search into the look-up table for a
277 ** recommended firmware settlement delay value.
278 **
279 ** Although the settlement time might be also related to board
280 ** configurations such as the crystal clocking speed.
281 **
282 ** Returns Firmware settlement delay
283 **
284 *******************************************************************************/
look_up_fw_settlement_delay(void)285 uint32_t look_up_fw_settlement_delay (void)
286 {
287 uint32_t ret_value;
288 fw_settlement_entry_t *p_entry;
289
290 if (FW_PATCH_SETTLEMENT_DELAY_MS > 0)
291 {
292 ret_value = FW_PATCH_SETTLEMENT_DELAY_MS;
293 }
294 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
295 else if (fw_patch_settlement_delay >= 0)
296 {
297 ret_value = fw_patch_settlement_delay;
298 }
299 #endif
300 else
301 {
302 p_entry = (fw_settlement_entry_t *)fw_settlement_table;
303
304 while (p_entry->chipset_name != NULL)
305 {
306 if (strstr(hw_cfg_cb.local_chip_name, p_entry->chipset_name)!=NULL)
307 {
308 break;
309 }
310
311 p_entry++;
312 }
313
314 ret_value = p_entry->delay_time;
315 }
316
317 BTHWDBG( "Settlement delay -- %d ms", ret_value);
318
319 return (ret_value);
320 }
321
322 /*******************************************************************************
323 **
324 ** Function ms_delay
325 **
326 ** Description sleep unconditionally for timeout milliseconds
327 **
328 ** Returns None
329 **
330 *******************************************************************************/
ms_delay(uint32_t timeout)331 void ms_delay (uint32_t timeout)
332 {
333 struct timespec delay;
334 int err;
335
336 if (timeout == 0)
337 return;
338
339 delay.tv_sec = timeout / 1000;
340 delay.tv_nsec = 1000 * 1000 * (timeout%1000);
341
342 /* [u]sleep can't be used because it uses SIGALRM */
343 do {
344 err = nanosleep(&delay, &delay);
345 } while (err < 0 && errno ==EINTR);
346 }
347
348 /*******************************************************************************
349 **
350 ** Function line_speed_to_userial_baud
351 **
352 ** Description helper function converts line speed number into USERIAL baud
353 ** rate symbol
354 **
355 ** Returns unit8_t (USERIAL baud symbol)
356 **
357 *******************************************************************************/
line_speed_to_userial_baud(uint32_t line_speed)358 uint8_t line_speed_to_userial_baud(uint32_t line_speed)
359 {
360 uint8_t baud;
361
362 if (line_speed == 4000000)
363 baud = USERIAL_BAUD_4M;
364 else if (line_speed == 3000000)
365 baud = USERIAL_BAUD_3M;
366 else if (line_speed == 2000000)
367 baud = USERIAL_BAUD_2M;
368 else if (line_speed == 1000000)
369 baud = USERIAL_BAUD_1M;
370 else if (line_speed == 921600)
371 baud = USERIAL_BAUD_921600;
372 else if (line_speed == 460800)
373 baud = USERIAL_BAUD_460800;
374 else if (line_speed == 230400)
375 baud = USERIAL_BAUD_230400;
376 else if (line_speed == 115200)
377 baud = USERIAL_BAUD_115200;
378 else if (line_speed == 57600)
379 baud = USERIAL_BAUD_57600;
380 else if (line_speed == 19200)
381 baud = USERIAL_BAUD_19200;
382 else if (line_speed == 9600)
383 baud = USERIAL_BAUD_9600;
384 else if (line_speed == 1200)
385 baud = USERIAL_BAUD_1200;
386 else if (line_speed == 600)
387 baud = USERIAL_BAUD_600;
388 else
389 {
390 ALOGE( "userial vendor: unsupported baud speed %d", line_speed);
391 baud = USERIAL_BAUD_115200;
392 }
393
394 return baud;
395 }
396
397
398 /*******************************************************************************
399 **
400 ** Function hw_strncmp
401 **
402 ** Description Used to compare two strings in caseless
403 **
404 ** Returns 0: match, otherwise: not match
405 **
406 *******************************************************************************/
hw_strncmp(const char * p_str1,const char * p_str2,const int len)407 static int hw_strncmp (const char *p_str1, const char *p_str2, const int len)
408 {
409 int i;
410
411 if (!p_str1 || !p_str2)
412 return (1);
413
414 for (i = 0; i < len; i++)
415 {
416 if (toupper(p_str1[i]) != toupper(p_str2[i]))
417 return (i+1);
418 }
419
420 return 0;
421 }
422
423 /*******************************************************************************
424 **
425 ** Function hw_config_findpatch
426 **
427 ** Description Search for a proper firmware patch file
428 ** The selected firmware patch file name with full path
429 ** will be stored in the input string parameter, i.e.
430 ** p_chip_id_str, when returns.
431 **
432 ** Returns TRUE when found the target patch file, otherwise FALSE
433 **
434 *******************************************************************************/
hw_config_findpatch(char * p_chip_id_str)435 static uint8_t hw_config_findpatch(char *p_chip_id_str)
436 {
437 DIR *dirp;
438 struct dirent *dp;
439 int filenamelen;
440 uint8_t retval = FALSE;
441
442 BTHWDBG("Target name = [%s]", p_chip_id_str);
443
444 if (strlen(fw_patchfile_name)> 0)
445 {
446 /* If specific filepath and filename have been given in run-time
447 * configuration /etc/bluetooth/bt_vendor.conf file, we will use them
448 * to concatenate the filename to open rather than searching a file
449 * matching to chipset name in the fw_patchfile_path folder.
450 */
451 sprintf(p_chip_id_str, "%s", fw_patchfile_path);
452 if (fw_patchfile_path[strlen(fw_patchfile_path)- 1] != '/')
453 {
454 strcat(p_chip_id_str, "/");
455 }
456 strcat(p_chip_id_str, fw_patchfile_name);
457
458 ALOGI("FW patchfile: %s", p_chip_id_str);
459 return TRUE;
460 }
461
462 if ((dirp = opendir(fw_patchfile_path)) != NULL)
463 {
464 /* Fetch next filename in patchfile directory */
465 while ((dp = readdir(dirp)) != NULL)
466 {
467 /* Check if filename starts with chip-id name */
468 if ((hw_strncmp(dp->d_name, p_chip_id_str, strlen(p_chip_id_str)) \
469 ) == 0)
470 {
471 /* Check if it has .hcd extenstion */
472 filenamelen = strlen(dp->d_name);
473 if ((filenamelen >= FW_PATCHFILE_EXTENSION_LEN) &&
474 ((hw_strncmp(
475 &dp->d_name[filenamelen-FW_PATCHFILE_EXTENSION_LEN], \
476 FW_PATCHFILE_EXTENSION, \
477 FW_PATCHFILE_EXTENSION_LEN) \
478 ) == 0))
479 {
480 ALOGI("Found patchfile: %s/%s", \
481 fw_patchfile_path, dp->d_name);
482
483 /* Make sure length does not exceed maximum */
484 if ((filenamelen + strlen(fw_patchfile_path)) > \
485 FW_PATCHFILE_PATH_MAXLEN)
486 {
487 ALOGE("Invalid patchfile name (too long)");
488 }
489 else
490 {
491 memset(p_chip_id_str, 0, FW_PATCHFILE_PATH_MAXLEN);
492 /* Found patchfile. Store location and name */
493 strcpy(p_chip_id_str, fw_patchfile_path);
494 if (fw_patchfile_path[ \
495 strlen(fw_patchfile_path)- 1 \
496 ] != '/')
497 {
498 strcat(p_chip_id_str, "/");
499 }
500 strcat(p_chip_id_str, dp->d_name);
501 retval = TRUE;
502 }
503 break;
504 }
505 }
506 }
507
508 closedir(dirp);
509
510 if (retval == FALSE)
511 {
512 /* Try again chip name without revision info */
513
514 int len = strlen(p_chip_id_str);
515 char *p = p_chip_id_str + len - 1;
516
517 /* Scan backward and look for the first alphabet
518 which is not M or m
519 */
520 while (len > 3) // BCM****
521 {
522 if ((isdigit(*p)==0) && (*p != 'M') && (*p != 'm'))
523 break;
524
525 p--;
526 len--;
527 }
528
529 if (len > 3)
530 {
531 *p = 0;
532 retval = hw_config_findpatch(p_chip_id_str);
533 }
534 }
535 }
536 else
537 {
538 ALOGE("Could not open %s", fw_patchfile_path);
539 }
540
541 return (retval);
542 }
543
544 /*******************************************************************************
545 **
546 ** Function hw_config_set_bdaddr
547 **
548 ** Description Program controller's Bluetooth Device Address
549 **
550 ** Returns TRUE, if valid address is sent
551 ** FALSE, otherwise
552 **
553 *******************************************************************************/
hw_config_set_bdaddr(HC_BT_HDR * p_buf)554 static uint8_t hw_config_set_bdaddr(HC_BT_HDR *p_buf)
555 {
556 uint8_t retval = FALSE;
557 uint8_t *p = (uint8_t *) (p_buf + 1);
558
559 ALOGI("Setting local bd addr to %02X:%02X:%02X:%02X:%02X:%02X",
560 vnd_local_bd_addr[0], vnd_local_bd_addr[1], vnd_local_bd_addr[2],
561 vnd_local_bd_addr[3], vnd_local_bd_addr[4], vnd_local_bd_addr[5]);
562
563 UINT16_TO_STREAM(p, HCI_VSC_WRITE_BD_ADDR);
564 *p++ = BD_ADDR_LEN; /* parameter length */
565 *p++ = vnd_local_bd_addr[5];
566 *p++ = vnd_local_bd_addr[4];
567 *p++ = vnd_local_bd_addr[3];
568 *p++ = vnd_local_bd_addr[2];
569 *p++ = vnd_local_bd_addr[1];
570 *p = vnd_local_bd_addr[0];
571
572 p_buf->len = HCI_CMD_PREAMBLE_SIZE + BD_ADDR_LEN;
573 hw_cfg_cb.state = HW_CFG_SET_BD_ADDR;
574
575 retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_BD_ADDR, p_buf, \
576 hw_config_cback);
577
578 return (retval);
579 }
580
581 #if (USE_CONTROLLER_BDADDR == TRUE)
582 /*******************************************************************************
583 **
584 ** Function hw_config_read_bdaddr
585 **
586 ** Description Read controller's Bluetooth Device Address
587 **
588 ** Returns TRUE, if valid address is sent
589 ** FALSE, otherwise
590 **
591 *******************************************************************************/
hw_config_read_bdaddr(HC_BT_HDR * p_buf)592 static uint8_t hw_config_read_bdaddr(HC_BT_HDR *p_buf)
593 {
594 uint8_t retval = FALSE;
595 uint8_t *p = (uint8_t *) (p_buf + 1);
596
597 UINT16_TO_STREAM(p, HCI_READ_LOCAL_BDADDR);
598 *p = 0; /* parameter length */
599
600 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
601 hw_cfg_cb.state = HW_CFG_READ_BD_ADDR;
602
603 retval = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_BDADDR, p_buf, \
604 hw_config_cback);
605
606 return (retval);
607 }
608 #endif // (USE_CONTROLLER_BDADDR == TRUE)
609
610 /*******************************************************************************
611 **
612 ** Function hw_config_cback
613 **
614 ** Description Callback function for controller configuration
615 **
616 ** Returns None
617 **
618 *******************************************************************************/
hw_config_cback(void * p_mem)619 void hw_config_cback(void *p_mem)
620 {
621 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
622 char *p_name, *p_tmp;
623 uint8_t *p, status;
624 uint16_t opcode;
625 HC_BT_HDR *p_buf=NULL;
626 uint8_t is_proceeding = FALSE;
627 int i;
628 int delay=100;
629 #if (USE_CONTROLLER_BDADDR == TRUE)
630 const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0};
631 #endif
632
633 status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
634 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
635 STREAM_TO_UINT16(opcode,p);
636
637 /* Ask a new buffer big enough to hold any HCI commands sent in here */
638 if ((status == 0) && bt_vendor_cbacks)
639 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
640 HCI_CMD_MAX_LEN);
641
642 if (p_buf != NULL)
643 {
644 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
645 p_buf->offset = 0;
646 p_buf->len = 0;
647 p_buf->layer_specific = 0;
648
649 p = (uint8_t *) (p_buf + 1);
650
651 switch (hw_cfg_cb.state)
652 {
653 case HW_CFG_SET_UART_BAUD_1:
654 /* update baud rate of host's UART port */
655 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE);
656 userial_vendor_set_baud( \
657 line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
658 );
659
660 /* read local name */
661 UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME);
662 *p = 0; /* parameter length */
663
664 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
665 hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME;
666
667 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \
668 p_buf, hw_config_cback);
669 break;
670
671 case HW_CFG_READ_LOCAL_NAME:
672 p_tmp = p_name = (char *) (p_evt_buf + 1) + \
673 HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING;
674
675 for (i=0; (i < LOCAL_NAME_BUFFER_LEN)||(*(p_name+i) != 0); i++)
676 *(p_name+i) = toupper(*(p_name+i));
677
678 if ((p_name = strstr(p_name, "BCM")) != NULL)
679 {
680 strncpy(hw_cfg_cb.local_chip_name, p_name, \
681 LOCAL_NAME_BUFFER_LEN-1);
682 }
683 #ifdef USE_BLUETOOTH_BCM4343
684 else if ((p_name = strstr(p_tmp, "4343")) != NULL)
685 {
686 snprintf(hw_cfg_cb.local_chip_name,
687 LOCAL_NAME_BUFFER_LEN-1, "BCM%s", p_name);
688 strncpy(p_name, hw_cfg_cb.local_chip_name,
689 LOCAL_NAME_BUFFER_LEN-1);
690 }
691 #endif
692 else
693 {
694 strncpy(hw_cfg_cb.local_chip_name, "UNKNOWN", \
695 LOCAL_NAME_BUFFER_LEN-1);
696 p_name = p_tmp;
697 }
698
699 hw_cfg_cb.local_chip_name[LOCAL_NAME_BUFFER_LEN-1] = 0;
700
701 BTHWDBG("Chipset %s", hw_cfg_cb.local_chip_name);
702
703 if ((status = hw_config_findpatch(p_name)) == TRUE)
704 {
705 if ((hw_cfg_cb.fw_fd = open(p_name, O_RDONLY)) == -1)
706 {
707 ALOGE("vendor lib preload failed to open [%s]", p_name);
708 }
709 else
710 {
711 /* vsc_download_minidriver */
712 UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV);
713 *p = 0; /* parameter length */
714
715 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
716 hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER;
717
718 is_proceeding = bt_vendor_cbacks->xmit_cb( \
719 HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \
720 hw_config_cback);
721 }
722 }
723 else
724 {
725 ALOGE( \
726 "vendor lib preload failed to locate firmware patch file" \
727 );
728 }
729
730 if (is_proceeding == FALSE)
731 {
732 is_proceeding = hw_config_set_bdaddr(p_buf);
733 }
734 break;
735
736 case HW_CFG_DL_MINIDRIVER:
737 /* give time for placing firmware in download mode */
738 ms_delay(50);
739 hw_cfg_cb.state = HW_CFG_DL_FW_PATCH;
740 /* fall through intentionally */
741 case HW_CFG_DL_FW_PATCH:
742 if (hw_cfg_cb.fw_fd >= 0)
743 {
744 int ret = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE);
745 if (ret > 0)
746 {
747 if ((ret < HCI_CMD_PREAMBLE_SIZE) || \
748 (opcode == HCI_VSC_LAUNCH_RAM))
749 {
750 ALOGW("firmware patch file might be altered!");
751 }
752 else
753 {
754 p_buf->len = ret;
755 ret = read(hw_cfg_cb.fw_fd, \
756 p+HCI_CMD_PREAMBLE_SIZE,\
757 *(p+HCD_REC_PAYLOAD_LEN_BYTE));
758 if (ret >= 0)
759 {
760 p_buf->len += ret;
761 STREAM_TO_UINT16(opcode,p);
762 is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \
763 p_buf, hw_config_cback);
764 break;
765 }
766 }
767 }
768 if (ret < 0)
769 {
770 ALOGE("firmware patch file read failed (%s)", strerror(errno));
771 }
772 close(hw_cfg_cb.fw_fd);
773 hw_cfg_cb.fw_fd = -1;
774 }
775 /* Normally the firmware patch configuration file
776 * sets the new starting baud rate at 115200.
777 * So, we need update host's baud rate accordingly.
778 */
779 ALOGI("bt vendor lib: set UART baud 115200");
780 userial_vendor_set_baud(USERIAL_BAUD_115200);
781
782 /* Next, we would like to boost baud rate up again
783 * to desired working speed.
784 */
785 hw_cfg_cb.f_set_baud_2 = TRUE;
786
787 /* Check if we need to pause a few hundred milliseconds
788 * before sending down any HCI command.
789 */
790 delay = look_up_fw_settlement_delay();
791 ALOGI("Setting fw settlement delay to %d ", delay);
792 ms_delay(delay);
793
794 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
795 UINT16_TO_STREAM(p, HCI_RESET);
796 *p = 0; /* parameter length */
797 hw_cfg_cb.state = HW_CFG_START;
798 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback);
799 break;
800
801 case HW_CFG_START:
802 if (UART_TARGET_BAUD_RATE > 3000000)
803 {
804 /* set UART clock to 48MHz */
805 UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING);
806 *p++ = 1; /* parameter length */
807 *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */
808
809 p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1;
810 hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK;
811
812 is_proceeding = bt_vendor_cbacks->xmit_cb( \
813 HCI_VSC_WRITE_UART_CLOCK_SETTING, \
814 p_buf, hw_config_cback);
815 break;
816 }
817 /* fall through intentionally */
818 case HW_CFG_SET_UART_CLOCK:
819 /* set controller's UART baud rate to 3M */
820 UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE);
821 *p++ = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */
822 *p++ = 0; /* encoded baud rate */
823 *p++ = 0; /* use encoded form */
824 UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE);
825
826 p_buf->len = HCI_CMD_PREAMBLE_SIZE + \
827 UPDATE_BAUDRATE_CMD_PARAM_SIZE;
828 hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \
829 HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1;
830
831 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \
832 p_buf, hw_config_cback);
833 break;
834
835 case HW_CFG_SET_UART_BAUD_2:
836 /* update baud rate of host's UART port */
837 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE);
838 userial_vendor_set_baud( \
839 line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
840 );
841
842 #if (USE_CONTROLLER_BDADDR == TRUE)
843 if ((is_proceeding = hw_config_read_bdaddr(p_buf)) == TRUE)
844 break;
845 #else
846 if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE)
847 break;
848 #endif
849 /* fall through intentionally */
850 case HW_CFG_SET_BD_ADDR:
851 ALOGI("vendor lib fwcfg completed");
852 bt_vendor_cbacks->dealloc(p_buf);
853 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
854
855 hw_cfg_cb.state = 0;
856
857 if (hw_cfg_cb.fw_fd != -1)
858 {
859 close(hw_cfg_cb.fw_fd);
860 hw_cfg_cb.fw_fd = -1;
861 }
862
863 is_proceeding = TRUE;
864 break;
865
866 #if (USE_CONTROLLER_BDADDR == TRUE)
867 case HW_CFG_READ_BD_ADDR:
868 p_tmp = (char *) (p_evt_buf + 1) + \
869 HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY;
870
871 if (memcmp(p_tmp, null_bdaddr, BD_ADDR_LEN) == 0)
872 {
873 // Controller does not have a valid OTP BDADDR!
874 // Set the BTIF initial BDADDR instead.
875 if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE)
876 break;
877 }
878 else
879 {
880 ALOGI("Controller OTP bdaddr %02X:%02X:%02X:%02X:%02X:%02X",
881 *(p_tmp+5), *(p_tmp+4), *(p_tmp+3),
882 *(p_tmp+2), *(p_tmp+1), *p_tmp);
883 }
884
885 ALOGI("vendor lib fwcfg completed");
886 bt_vendor_cbacks->dealloc(p_buf);
887 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
888
889 hw_cfg_cb.state = 0;
890
891 if (hw_cfg_cb.fw_fd != -1)
892 {
893 close(hw_cfg_cb.fw_fd);
894 hw_cfg_cb.fw_fd = -1;
895 }
896
897 is_proceeding = TRUE;
898 break;
899 #endif // (USE_CONTROLLER_BDADDR == TRUE)
900 } // switch(hw_cfg_cb.state)
901 } // if (p_buf != NULL)
902
903 /* Free the RX event buffer */
904 if (bt_vendor_cbacks)
905 bt_vendor_cbacks->dealloc(p_evt_buf);
906
907 if (is_proceeding == FALSE)
908 {
909 ALOGE("vendor lib fwcfg aborted!!!");
910 if (bt_vendor_cbacks)
911 {
912 if (p_buf != NULL)
913 bt_vendor_cbacks->dealloc(p_buf);
914
915 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
916 }
917
918 if (hw_cfg_cb.fw_fd != -1)
919 {
920 close(hw_cfg_cb.fw_fd);
921 hw_cfg_cb.fw_fd = -1;
922 }
923
924 hw_cfg_cb.state = 0;
925 }
926 }
927
928 /******************************************************************************
929 ** LPM Static Functions
930 ******************************************************************************/
931
932 /*******************************************************************************
933 **
934 ** Function hw_lpm_ctrl_cback
935 **
936 ** Description Callback function for lpm enable/disable rquest
937 **
938 ** Returns None
939 **
940 *******************************************************************************/
hw_lpm_ctrl_cback(void * p_mem)941 void hw_lpm_ctrl_cback(void *p_mem)
942 {
943 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
944 bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL;
945
946 if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0)
947 {
948 status = BT_VND_OP_RESULT_SUCCESS;
949 }
950
951 if (bt_vendor_cbacks)
952 {
953 bt_vendor_cbacks->lpm_cb(status);
954 bt_vendor_cbacks->dealloc(p_evt_buf);
955 }
956 }
957
958
959 #if (SCO_CFG_INCLUDED == TRUE)
960 /*****************************************************************************
961 ** SCO Configuration Static Functions
962 *****************************************************************************/
963
964 /*******************************************************************************
965 **
966 ** Function hw_sco_i2spcm_cfg_cback
967 **
968 ** Description Callback function for SCO I2S/PCM configuration rquest
969 **
970 ** Returns None
971 **
972 *******************************************************************************/
hw_sco_i2spcm_cfg_cback(void * p_mem)973 static void hw_sco_i2spcm_cfg_cback(void *p_mem)
974 {
975 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem;
976 uint8_t *p;
977 uint16_t opcode;
978 HC_BT_HDR *p_buf = NULL;
979 bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL;
980
981 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
982 STREAM_TO_UINT16(opcode,p);
983
984 if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0)
985 {
986 status = BT_VND_OP_RESULT_SUCCESS;
987 }
988
989 /* Free the RX event buffer */
990 if (bt_vendor_cbacks)
991 bt_vendor_cbacks->dealloc(p_evt_buf);
992
993 if (status == BT_VND_OP_RESULT_SUCCESS)
994 {
995 if ((opcode == HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM) &&
996 (SCO_INTERFACE_PCM == sco_bus_interface))
997 {
998 uint8_t ret = FALSE;
999
1000 /* Ask a new buffer to hold WRITE_SCO_PCM_INT_PARAM command */
1001 if (bt_vendor_cbacks)
1002 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(
1003 BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE);
1004 if (p_buf)
1005 {
1006 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1007 p_buf->offset = 0;
1008 p_buf->layer_specific = 0;
1009 p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE;
1010 p = (uint8_t *)(p_buf + 1);
1011
1012 /* do we need this VSC for I2S??? */
1013 UINT16_TO_STREAM(p, HCI_VSC_WRITE_SCO_PCM_INT_PARAM);
1014 *p++ = SCO_PCM_PARAM_SIZE;
1015 memcpy(p, &bt_sco_param, SCO_PCM_PARAM_SIZE);
1016 ALOGI("SCO PCM configure {0x%x, 0x%x, 0x%x, 0x%x, 0x%x}",
1017 bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3],
1018 bt_sco_param[4]);
1019 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SCO_PCM_INT_PARAM, p_buf,
1020 hw_sco_i2spcm_cfg_cback)) == FALSE)
1021 {
1022 bt_vendor_cbacks->dealloc(p_buf);
1023 }
1024 else
1025 return;
1026 }
1027 status = BT_VND_OP_RESULT_FAIL;
1028 }
1029 else if ((opcode == HCI_VSC_WRITE_SCO_PCM_INT_PARAM) &&
1030 (SCO_INTERFACE_PCM == sco_bus_interface))
1031 {
1032 uint8_t ret = FALSE;
1033
1034 /* Ask a new buffer to hold WRITE_PCM_DATA_FORMAT_PARAM command */
1035 if (bt_vendor_cbacks)
1036 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(
1037 BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE);
1038 if (p_buf)
1039 {
1040 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1041 p_buf->offset = 0;
1042 p_buf->layer_specific = 0;
1043 p_buf->len = HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE;
1044
1045 p = (uint8_t *)(p_buf + 1);
1046 UINT16_TO_STREAM(p, HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM);
1047 *p++ = PCM_DATA_FORMAT_PARAM_SIZE;
1048 memcpy(p, &bt_pcm_data_fmt_param, PCM_DATA_FORMAT_PARAM_SIZE);
1049
1050 ALOGI("SCO PCM data format {0x%x, 0x%x, 0x%x, 0x%x, 0x%x}",
1051 bt_pcm_data_fmt_param[0], bt_pcm_data_fmt_param[1],
1052 bt_pcm_data_fmt_param[2], bt_pcm_data_fmt_param[3],
1053 bt_pcm_data_fmt_param[4]);
1054
1055 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM,
1056 p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE)
1057 {
1058 bt_vendor_cbacks->dealloc(p_buf);
1059 }
1060 else
1061 return;
1062 }
1063 status = BT_VND_OP_RESULT_FAIL;
1064 }
1065 }
1066
1067 ALOGI("sco I2S/PCM config result %d [0-Success, 1-Fail]", status);
1068 if (bt_vendor_cbacks)
1069 {
1070 bt_vendor_cbacks->audio_state_cb(status);
1071 }
1072 }
1073
1074 /*******************************************************************************
1075 **
1076 ** Function hw_set_MSBC_codec_cback
1077 **
1078 ** Description Callback function for setting WBS codec
1079 **
1080 ** Returns None
1081 **
1082 *******************************************************************************/
hw_set_MSBC_codec_cback(void * p_mem)1083 static void hw_set_MSBC_codec_cback(void *p_mem)
1084 {
1085 /* whenever update the codec enable/disable, need to update I2SPCM */
1086 ALOGI("SCO I2S interface change the sample rate to 16K");
1087 hw_sco_i2spcm_config_from_command(p_mem, SCO_CODEC_MSBC);
1088 }
1089
1090 /*******************************************************************************
1091 **
1092 ** Function hw_set_CVSD_codec_cback
1093 **
1094 ** Description Callback function for setting NBS codec
1095 **
1096 ** Returns None
1097 **
1098 *******************************************************************************/
hw_set_CVSD_codec_cback(void * p_mem)1099 static void hw_set_CVSD_codec_cback(void *p_mem)
1100 {
1101 /* whenever update the codec enable/disable, need to update I2SPCM */
1102 ALOGI("SCO I2S interface change the sample rate to 8K");
1103 hw_sco_i2spcm_config_from_command(p_mem, SCO_CODEC_CVSD);
1104 }
1105
1106 #endif // SCO_CFG_INCLUDED
1107
1108 /*****************************************************************************
1109 ** Hardware Configuration Interface Functions
1110 *****************************************************************************/
1111
1112
1113 /*******************************************************************************
1114 **
1115 ** Function hw_config_start
1116 **
1117 ** Description Kick off controller initialization process
1118 **
1119 ** Returns None
1120 **
1121 *******************************************************************************/
hw_config_start(void)1122 void hw_config_start(void)
1123 {
1124 HC_BT_HDR *p_buf = NULL;
1125 uint8_t *p;
1126
1127 hw_cfg_cb.state = 0;
1128 hw_cfg_cb.fw_fd = -1;
1129 hw_cfg_cb.f_set_baud_2 = FALSE;
1130
1131 /* Start from sending HCI_RESET */
1132
1133 if (bt_vendor_cbacks)
1134 {
1135 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
1136 HCI_CMD_PREAMBLE_SIZE);
1137 }
1138
1139 if (p_buf)
1140 {
1141 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1142 p_buf->offset = 0;
1143 p_buf->layer_specific = 0;
1144 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
1145
1146 p = (uint8_t *) (p_buf + 1);
1147 UINT16_TO_STREAM(p, HCI_RESET);
1148 *p = 0; /* parameter length */
1149
1150 hw_cfg_cb.state = HW_CFG_START;
1151
1152 bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback);
1153 }
1154 else
1155 {
1156 if (bt_vendor_cbacks)
1157 {
1158 ALOGE("vendor lib fw conf aborted [no buffer]");
1159 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
1160 }
1161 }
1162 }
1163
1164 /*******************************************************************************
1165 **
1166 ** Function hw_lpm_enable
1167 **
1168 ** Description Enalbe/Disable LPM
1169 **
1170 ** Returns TRUE/FALSE
1171 **
1172 *******************************************************************************/
hw_lpm_enable(uint8_t turn_on)1173 uint8_t hw_lpm_enable(uint8_t turn_on)
1174 {
1175 HC_BT_HDR *p_buf = NULL;
1176 uint8_t *p;
1177 uint8_t ret = FALSE;
1178
1179 if (bt_vendor_cbacks)
1180 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
1181 HCI_CMD_PREAMBLE_SIZE + \
1182 LPM_CMD_PARAM_SIZE);
1183
1184 if (p_buf)
1185 {
1186 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1187 p_buf->offset = 0;
1188 p_buf->layer_specific = 0;
1189 p_buf->len = HCI_CMD_PREAMBLE_SIZE + LPM_CMD_PARAM_SIZE;
1190
1191 p = (uint8_t *) (p_buf + 1);
1192 UINT16_TO_STREAM(p, HCI_VSC_WRITE_SLEEP_MODE);
1193 *p++ = LPM_CMD_PARAM_SIZE; /* parameter length */
1194
1195 if (turn_on)
1196 {
1197 memcpy(p, &lpm_param, LPM_CMD_PARAM_SIZE);
1198 upio_set(UPIO_LPM_MODE, UPIO_ASSERT, 0);
1199 }
1200 else
1201 {
1202 memset(p, 0, LPM_CMD_PARAM_SIZE);
1203 upio_set(UPIO_LPM_MODE, UPIO_DEASSERT, 0);
1204 }
1205
1206 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SLEEP_MODE, p_buf, \
1207 hw_lpm_ctrl_cback)) == FALSE)
1208 {
1209 bt_vendor_cbacks->dealloc(p_buf);
1210 }
1211 }
1212
1213 if ((ret == FALSE) && bt_vendor_cbacks)
1214 bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_FAIL);
1215
1216 return ret;
1217 }
1218
1219 /*******************************************************************************
1220 **
1221 ** Function hw_lpm_get_idle_timeout
1222 **
1223 ** Description Calculate idle time based on host stack idle threshold
1224 **
1225 ** Returns idle timeout value
1226 **
1227 *******************************************************************************/
hw_lpm_get_idle_timeout(void)1228 uint32_t hw_lpm_get_idle_timeout(void)
1229 {
1230 uint32_t timeout_ms;
1231
1232 /* set idle time to be LPM_IDLE_TIMEOUT_MULTIPLE times of
1233 * host stack idle threshold (in 300ms/25ms)
1234 */
1235 timeout_ms = (uint32_t)lpm_param.host_stack_idle_threshold \
1236 * LPM_IDLE_TIMEOUT_MULTIPLE;
1237 if (strstr(hw_cfg_cb.local_chip_name, "BCM4325") != NULL)
1238 timeout_ms *= 25; // 12.5 or 25 ?
1239 else if (strstr(hw_cfg_cb.local_chip_name, "BCM4358") != NULL)
1240 timeout_ms *= 50;
1241 else
1242 timeout_ms *= 300;
1243
1244 return timeout_ms;
1245 }
1246
1247 /*******************************************************************************
1248 **
1249 ** Function hw_lpm_set_wake_state
1250 **
1251 ** Description Assert/Deassert BT_WAKE
1252 **
1253 ** Returns None
1254 **
1255 *******************************************************************************/
hw_lpm_set_wake_state(uint8_t wake_assert)1256 void hw_lpm_set_wake_state(uint8_t wake_assert)
1257 {
1258 uint8_t state = (wake_assert) ? UPIO_ASSERT : UPIO_DEASSERT;
1259
1260 upio_set(UPIO_BT_WAKE, state, lpm_param.bt_wake_polarity);
1261 }
1262
1263 #if (SCO_CFG_INCLUDED == TRUE)
1264 /*******************************************************************************
1265 **
1266 ** Function hw_sco_config
1267 **
1268 ** Description Configure SCO related hardware settings
1269 **
1270 ** Returns None
1271 **
1272 *******************************************************************************/
hw_sco_config(void)1273 void hw_sco_config(void)
1274 {
1275 if (SCO_INTERFACE_I2S == sco_bus_interface)
1276 {
1277 /* 'Enable' I2S mode */
1278 bt_sco_i2spcm_param[0] = 1;
1279
1280 /* set nbs clock rate as the value in SCO_I2SPCM_IF_CLOCK_RATE field */
1281 sco_bus_clock_rate = bt_sco_i2spcm_param[3];
1282 }
1283 else
1284 {
1285 /* 'Disable' I2S mode */
1286 bt_sco_i2spcm_param[0] = 0;
1287
1288 /* set nbs clock rate as the value in SCO_PCM_IF_CLOCK_RATE field */
1289 sco_bus_clock_rate = bt_sco_param[1];
1290
1291 /* sync up clock mode setting */
1292 bt_sco_i2spcm_param[1] = bt_sco_param[4];
1293 }
1294
1295 if (sco_bus_wbs_clock_rate == INVALID_SCO_CLOCK_RATE)
1296 {
1297 /* set default wbs clock rate */
1298 sco_bus_wbs_clock_rate = SCO_I2SPCM_IF_CLOCK_RATE4WBS;
1299
1300 if (sco_bus_wbs_clock_rate < sco_bus_clock_rate)
1301 sco_bus_wbs_clock_rate = sco_bus_clock_rate;
1302 }
1303
1304 /*
1305 * To support I2S/PCM port multiplexing signals for sharing Bluetooth audio
1306 * and FM on the same PCM pins, we defer Bluetooth audio (SCO/eSCO)
1307 * configuration till SCO/eSCO is being established;
1308 * i.e. in hw_set_audio_state() call.
1309 * When configured as I2S only, Bluetooth audio configuration is executed
1310 * immediately with SCO_CODEC_CVSD by default.
1311 */
1312
1313 if (SCO_INTERFACE_I2S == sco_bus_interface) {
1314 hw_sco_i2spcm_config(SCO_CODEC_CVSD);
1315 }
1316
1317 if (bt_vendor_cbacks)
1318 {
1319 bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
1320 }
1321 }
1322
hw_sco_i2spcm_config_from_command(void * p_mem,uint16_t codec)1323 static void hw_sco_i2spcm_config_from_command(void *p_mem, uint16_t codec) {
1324 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem;
1325 bool command_success = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0;
1326
1327 /* Free the RX event buffer */
1328 if (bt_vendor_cbacks)
1329 bt_vendor_cbacks->dealloc(p_evt_buf);
1330
1331 if (command_success)
1332 hw_sco_i2spcm_config(codec);
1333 else if (bt_vendor_cbacks)
1334 bt_vendor_cbacks->audio_state_cb(BT_VND_OP_RESULT_FAIL);
1335 }
1336
1337
1338 /*******************************************************************************
1339 **
1340 ** Function hw_sco_i2spcm_config
1341 **
1342 ** Description Configure SCO over I2S or PCM
1343 **
1344 ** Returns None
1345 **
1346 *******************************************************************************/
hw_sco_i2spcm_config(uint16_t codec)1347 static void hw_sco_i2spcm_config(uint16_t codec)
1348 {
1349 HC_BT_HDR *p_buf = NULL;
1350 uint8_t *p, ret;
1351 uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE;
1352
1353 if (bt_vendor_cbacks)
1354 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + cmd_u16);
1355
1356 if (p_buf)
1357 {
1358 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1359 p_buf->offset = 0;
1360 p_buf->layer_specific = 0;
1361 p_buf->len = cmd_u16;
1362
1363 p = (uint8_t *)(p_buf + 1);
1364
1365 UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM);
1366 *p++ = SCO_I2SPCM_PARAM_SIZE;
1367 if (codec == SCO_CODEC_CVSD)
1368 {
1369 bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE 8k */
1370 bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate;
1371 }
1372 else if (codec == SCO_CODEC_MSBC)
1373 {
1374 bt_sco_i2spcm_param[2] = wbs_sample_rate; /* SCO_I2SPCM_IF_SAMPLE_RATE 16K */
1375 bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_wbs_clock_rate;
1376 }
1377 else
1378 {
1379 bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE 8k */
1380 bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate;
1381 ALOGE("wrong codec is use in hw_sco_i2spcm_config, goes default NBS");
1382 }
1383 memcpy(p, &bt_sco_i2spcm_param, SCO_I2SPCM_PARAM_SIZE);
1384 cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM;
1385 ALOGI("I2SPCM config {0x%x, 0x%x, 0x%x, 0x%x}",
1386 bt_sco_i2spcm_param[0], bt_sco_i2spcm_param[1],
1387 bt_sco_i2spcm_param[2], bt_sco_i2spcm_param[3]);
1388
1389 if ((ret = bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE)
1390 {
1391 bt_vendor_cbacks->dealloc(p_buf);
1392 }
1393 else
1394 return;
1395 }
1396
1397 bt_vendor_cbacks->audio_state_cb(BT_VND_OP_RESULT_FAIL);
1398 }
1399
1400 /*******************************************************************************
1401 **
1402 ** Function hw_set_SCO_codec
1403 **
1404 ** Description This functgion sends command to the controller to setup
1405 ** WBS/NBS codec for the upcoming eSCO connection.
1406 **
1407 ** Returns -1 : Failed to send VSC
1408 ** 0 : Success
1409 **
1410 *******************************************************************************/
hw_set_SCO_codec(uint16_t codec)1411 static int hw_set_SCO_codec(uint16_t codec)
1412 {
1413 HC_BT_HDR *p_buf = NULL;
1414 uint8_t *p;
1415 uint8_t ret;
1416 int ret_val = 0;
1417 tINT_CMD_CBACK p_set_SCO_codec_cback;
1418
1419 BTHWDBG( "hw_set_SCO_codec 0x%x", codec);
1420
1421 if (bt_vendor_cbacks)
1422 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(
1423 BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE);
1424
1425 if (p_buf)
1426 {
1427 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1428 p_buf->offset = 0;
1429 p_buf->layer_specific = 0;
1430 p = (uint8_t *)(p_buf + 1);
1431
1432 UINT16_TO_STREAM(p, HCI_VSC_ENABLE_WBS);
1433
1434 if (codec == SCO_CODEC_MSBC)
1435 {
1436 /* Enable mSBC */
1437 *p++ = SCO_CODEC_PARAM_SIZE; /* set the parameter size */
1438 UINT8_TO_STREAM(p,1); /* enable */
1439 UINT16_TO_STREAM(p, codec);
1440
1441 /* set the totall size of this packet */
1442 p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE;
1443
1444 p_set_SCO_codec_cback = hw_set_MSBC_codec_cback;
1445 }
1446 else
1447 {
1448 /* Disable mSBC */
1449 *p++ = (SCO_CODEC_PARAM_SIZE - 2); /* set the parameter size */
1450 UINT8_TO_STREAM(p,0); /* disable */
1451
1452 /* set the totall size of this packet */
1453 p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE - 2;
1454
1455 p_set_SCO_codec_cback = hw_set_CVSD_codec_cback;
1456 if ((codec != SCO_CODEC_CVSD) && (codec != SCO_CODEC_NONE))
1457 {
1458 ALOGW("SCO codec setting is wrong: codec: 0x%x", codec);
1459 }
1460 }
1461
1462 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_ENABLE_WBS, p_buf, p_set_SCO_codec_cback))\
1463 == FALSE)
1464 {
1465 bt_vendor_cbacks->dealloc(p_buf);
1466 ret_val = -1;
1467 }
1468 }
1469 else
1470 {
1471 ret_val = -1;
1472 }
1473
1474 return ret_val;
1475 }
1476
1477 /*******************************************************************************
1478 **
1479 ** Function hw_set_audio_state
1480 **
1481 ** Description This function configures audio base on provided audio state
1482 **
1483 ** Paramters pointer to audio state structure
1484 **
1485 ** Returns 0: ok, -1: error
1486 **
1487 *******************************************************************************/
hw_set_audio_state(bt_vendor_op_audio_state_t * p_state)1488 int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state)
1489 {
1490 int ret_val = -1;
1491
1492 if (!bt_vendor_cbacks)
1493 return ret_val;
1494
1495 ret_val = hw_set_SCO_codec(p_state->peer_codec);
1496 return ret_val;
1497 }
1498
1499 #else // SCO_CFG_INCLUDED
hw_set_audio_state(bt_vendor_op_audio_state_t * p_state)1500 int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state)
1501 {
1502 return -256;
1503 }
1504 #endif
1505 /*******************************************************************************
1506 **
1507 ** Function hw_set_patch_file_path
1508 **
1509 ** Description Set the location of firmware patch file
1510 **
1511 ** Returns 0 : Success
1512 ** Otherwise : Fail
1513 **
1514 *******************************************************************************/
hw_set_patch_file_path(char * p_conf_name,char * p_conf_value,int param)1515 int hw_set_patch_file_path(char *p_conf_name, char *p_conf_value, int param)
1516 {
1517
1518 strcpy(fw_patchfile_path, p_conf_value);
1519
1520 return 0;
1521 }
1522
1523 /*******************************************************************************
1524 **
1525 ** Function hw_set_patch_file_name
1526 **
1527 ** Description Give the specific firmware patch filename
1528 **
1529 ** Returns 0 : Success
1530 ** Otherwise : Fail
1531 **
1532 *******************************************************************************/
hw_set_patch_file_name(char * p_conf_name,char * p_conf_value,int param)1533 int hw_set_patch_file_name(char *p_conf_name, char *p_conf_value, int param)
1534 {
1535
1536 strcpy(fw_patchfile_name, p_conf_value);
1537
1538 return 0;
1539 }
1540
1541 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
1542 /*******************************************************************************
1543 **
1544 ** Function hw_set_patch_settlement_delay
1545 **
1546 ** Description Give the specific firmware patch settlement time in milliseconds
1547 **
1548 ** Returns 0 : Success
1549 ** Otherwise : Fail
1550 **
1551 *******************************************************************************/
hw_set_patch_settlement_delay(char * p_conf_name,char * p_conf_value,int param)1552 int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int param)
1553 {
1554 fw_patch_settlement_delay = atoi(p_conf_value);
1555
1556 return 0;
1557 }
1558 #endif //VENDOR_LIB_RUNTIME_TUNING_ENABLED
1559
1560 /*****************************************************************************
1561 ** Sample Codes Section
1562 *****************************************************************************/
1563
1564 #if (HW_END_WITH_HCI_RESET == TRUE)
1565 /*******************************************************************************
1566 **
1567 ** Function hw_epilog_cback
1568 **
1569 ** Description Callback function for Command Complete Events from HCI
1570 ** commands sent in epilog process.
1571 **
1572 ** Returns None
1573 **
1574 *******************************************************************************/
hw_epilog_cback(void * p_mem)1575 void hw_epilog_cback(void *p_mem)
1576 {
1577 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
1578 uint8_t *p, status;
1579 uint16_t opcode;
1580
1581 status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
1582 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
1583 STREAM_TO_UINT16(opcode,p);
1584
1585 BTHWDBG("%s Opcode:0x%04X Status: %d", __FUNCTION__, opcode, status);
1586
1587 if (bt_vendor_cbacks)
1588 {
1589 /* Must free the RX event buffer */
1590 bt_vendor_cbacks->dealloc(p_evt_buf);
1591
1592 /* Once epilog process is done, must call epilog_cb callback
1593 to notify caller */
1594 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
1595 }
1596 }
1597
1598 /*******************************************************************************
1599 **
1600 ** Function hw_epilog_process
1601 **
1602 ** Description Sample implementation of epilog process
1603 **
1604 ** Returns None
1605 **
1606 *******************************************************************************/
hw_epilog_process(void)1607 void hw_epilog_process(void)
1608 {
1609 HC_BT_HDR *p_buf = NULL;
1610 uint8_t *p;
1611
1612 BTHWDBG("hw_epilog_process");
1613
1614 /* Sending a HCI_RESET */
1615 if (bt_vendor_cbacks)
1616 {
1617 /* Must allocate command buffer via HC's alloc API */
1618 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
1619 HCI_CMD_PREAMBLE_SIZE);
1620 }
1621
1622 if (p_buf)
1623 {
1624 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1625 p_buf->offset = 0;
1626 p_buf->layer_specific = 0;
1627 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
1628
1629 p = (uint8_t *) (p_buf + 1);
1630 UINT16_TO_STREAM(p, HCI_RESET);
1631 *p = 0; /* parameter length */
1632
1633 /* Send command via HC's xmit_cb API */
1634 bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_epilog_cback);
1635 }
1636 else
1637 {
1638 if (bt_vendor_cbacks)
1639 {
1640 ALOGE("vendor lib epilog process aborted [no buffer]");
1641 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_FAIL);
1642 }
1643 }
1644 }
1645 #endif // (HW_END_WITH_HCI_RESET == TRUE)
1646