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