summaryrefslogtreecommitdiff
path: root/src/hardware.c (plain)
blob: c9bcc88f13e002c9bbe0615f4b57e42f5887a007
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 "bt_hci_bdroid.h"
43#include "bt_vendor_brcm.h"
44#include "userial.h"
45#include "userial_vendor.h"
46#include "upio.h"
47
48/******************************************************************************
49** Constants & Macros
50******************************************************************************/
51
52#ifndef BTHW_DBG
53#define BTHW_DBG FALSE
54#endif
55
56#if (BTHW_DBG == TRUE)
57#define BTHWDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);}
58#else
59#define BTHWDBG(param, ...) {}
60#endif
61
62#define FW_PATCHFILE_EXTENSION ".hcd"
63#define FW_PATCHFILE_EXTENSION_LEN 4
64#define FW_PATCHFILE_PATH_MAXLEN 248 /* Local_Name length of return of
65 HCI_Read_Local_Name */
66
67#define HCI_CMD_MAX_LEN 258
68
69#define HCI_RESET 0x0C03
70#define HCI_VSC_WRITE_UART_CLOCK_SETTING 0xFC45
71#define HCI_VSC_UPDATE_BAUDRATE 0xFC18
72#define HCI_READ_LOCAL_NAME 0x0C14
73#define HCI_VSC_DOWNLOAD_MINIDRV 0xFC2E
74#define HCI_VSC_WRITE_BD_ADDR 0xFC01
75#define HCI_VSC_WRITE_SLEEP_MODE 0xFC27
76#define HCI_VSC_WRITE_SCO_PCM_INT_PARAM 0xFC1C
77#define HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM 0xFC1E
78#define HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM 0xFC6D
79#define HCI_VSC_LAUNCH_RAM 0xFC4E
80#define HCI_READ_LOCAL_BDADDR 0x1009
81
82#define HCI_EVT_CMD_CMPL_STATUS_RET_BYTE 5
83#define HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING 6
84#define HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY 6
85#define HCI_EVT_CMD_CMPL_OPCODE 3
86#define LPM_CMD_PARAM_SIZE 12
87#define UPDATE_BAUDRATE_CMD_PARAM_SIZE 6
88#define HCI_CMD_PREAMBLE_SIZE 3
89#define HCD_REC_PAYLOAD_LEN_BYTE 2
90#define BD_ADDR_LEN 6
91#define LOCAL_NAME_BUFFER_LEN 32
92#define LOCAL_BDADDR_PATH_BUFFER_LEN 256
93
94#define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;}
95#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
96#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);}
97
98/******************************************************************************
99** Local type definitions
100******************************************************************************/
101
102/* Hardware Configuration State */
103enum {
104 HW_CFG_START = 1,
105 HW_CFG_SET_UART_CLOCK,
106 HW_CFG_SET_UART_BAUD_1,
107 HW_CFG_READ_LOCAL_NAME,
108 HW_CFG_DL_MINIDRIVER,
109 HW_CFG_DL_FW_PATCH,
110 HW_CFG_SET_UART_BAUD_2,
111 HW_CFG_SET_BD_ADDR
112#if (USE_CONTROLLER_BDADDR == TRUE)
113 , HW_CFG_READ_BD_ADDR
114#endif
115};
116
117/* h/w config control block */
118typedef struct
119{
120 uint8_t state; /* Hardware configuration state */
121 int fw_fd; /* FW patch file fd */
122 uint8_t f_set_baud_2; /* Baud rate switch state */
123 char local_chip_name[LOCAL_NAME_BUFFER_LEN];
124} bt_hw_cfg_cb_t;
125
126/* low power mode parameters */
127typedef struct
128{
129 uint8_t sleep_mode; /* 0(disable),1(UART),9(H5) */
130 uint8_t host_stack_idle_threshold; /* Unit scale 300ms/25ms */
131 uint8_t host_controller_idle_threshold; /* Unit scale 300ms/25ms */
132 uint8_t bt_wake_polarity; /* 0=Active Low, 1= Active High */
133 uint8_t host_wake_polarity; /* 0=Active Low, 1= Active High */
134 uint8_t allow_host_sleep_during_sco;
135 uint8_t combine_sleep_mode_and_lpm;
136 uint8_t enable_uart_txd_tri_state; /* UART_TXD Tri-State */
137 uint8_t sleep_guard_time; /* sleep guard time in 12.5ms */
138 uint8_t wakeup_guard_time; /* wakeup guard time in 12.5ms */
139 uint8_t txd_config; /* TXD is high in sleep state */
140 uint8_t pulsed_host_wake; /* pulsed host wake if mode = 1 */
141} bt_lpm_param_t;
142
143/* Firmware re-launch settlement time */
144typedef struct {
145 const char *chipset_name;
146 const uint32_t delay_time;
147} fw_settlement_entry_t;
148
149
150/******************************************************************************
151** Externs
152******************************************************************************/
153
154void hw_config_cback(void *p_evt_buf);
155extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN];
156
157
158/******************************************************************************
159** Static variables
160******************************************************************************/
161
162static char fw_patchfile_path[256] = FW_PATCHFILE_LOCATION;
163static char fw_patchfile_name[128] = {0};
164#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
165static int fw_patch_settlement_delay = -1;
166#endif
167
168static bt_hw_cfg_cb_t hw_cfg_cb;
169
170static bt_lpm_param_t lpm_param =
171{
172 LPM_SLEEP_MODE,
173 LPM_IDLE_THRESHOLD,
174 LPM_HC_IDLE_THRESHOLD,
175 LPM_BT_WAKE_POLARITY,
176 LPM_HOST_WAKE_POLARITY,
177 LPM_ALLOW_HOST_SLEEP_DURING_SCO,
178 LPM_COMBINE_SLEEP_MODE_AND_LPM,
179 LPM_ENABLE_UART_TXD_TRI_STATE,
180 0, /* not applicable */
181 0, /* not applicable */
182 0, /* not applicable */
183 LPM_PULSED_HOST_WAKE
184};
185
186#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE))
187static uint8_t bt_sco_param[SCO_PCM_PARAM_SIZE] =
188{
189 SCO_PCM_ROUTING,
190 SCO_PCM_IF_CLOCK_RATE,
191 SCO_PCM_IF_FRAME_TYPE,
192 SCO_PCM_IF_SYNC_MODE,
193 SCO_PCM_IF_CLOCK_MODE
194};
195
196static uint8_t bt_pcm_data_fmt_param[PCM_DATA_FORMAT_PARAM_SIZE] =
197{
198 PCM_DATA_FMT_SHIFT_MODE,
199 PCM_DATA_FMT_FILL_BITS,
200 PCM_DATA_FMT_FILL_METHOD,
201 PCM_DATA_FMT_FILL_NUM,
202 PCM_DATA_FMT_JUSTIFY_MODE
203};
204#else
205static uint8_t bt_sco_param[SCO_I2SPCM_PARAM_SIZE] =
206{
207 SCO_I2SPCM_IF_MODE,
208 SCO_I2SPCM_IF_ROLE,
209 SCO_I2SPCM_IF_SAMPLE_RATE,
210 SCO_I2SPCM_IF_CLOCK_RATE
211};
212#endif
213
214/*
215 * The look-up table of recommended firmware settlement delay (milliseconds) on
216 * known chipsets.
217 */
218static const fw_settlement_entry_t fw_settlement_table[] = {
219 {"BCM43241", 200},
220 {(const char *) NULL, 100} // Giving the generic fw settlement delay setting.
221};
222
223/******************************************************************************
224** Static functions
225******************************************************************************/
226
227/******************************************************************************
228** Controller Initialization Static Functions
229******************************************************************************/
230
231/*******************************************************************************
232**
233** Function look_up_fw_settlement_delay
234**
235** Description If FW_PATCH_SETTLEMENT_DELAY_MS has not been explicitly
236** re-defined in the platform specific build-time configuration
237** file, we will search into the look-up table for a
238** recommended firmware settlement delay value.
239**
240** Although the settlement time might be also related to board
241** configurations such as the crystal clocking speed.
242**
243** Returns Firmware settlement delay
244**
245*******************************************************************************/
246uint32_t look_up_fw_settlement_delay (void)
247{
248 uint32_t ret_value;
249 fw_settlement_entry_t *p_entry;
250
251 if (FW_PATCH_SETTLEMENT_DELAY_MS > 0)
252 {
253 ret_value = FW_PATCH_SETTLEMENT_DELAY_MS;
254 }
255#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
256 else if (fw_patch_settlement_delay >= 0)
257 {
258 ret_value = fw_patch_settlement_delay;
259 }
260#endif
261 else
262 {
263 p_entry = (fw_settlement_entry_t *)fw_settlement_table;
264
265 while (p_entry->chipset_name != NULL)
266 {
267 if (strstr(hw_cfg_cb.local_chip_name, p_entry->chipset_name)!=NULL)
268 {
269 break;
270 }
271
272 p_entry++;
273 }
274
275 ret_value = p_entry->delay_time;
276 }
277
278 BTHWDBG( "Settlement delay -- %d ms", ret_value);
279
280 return (ret_value);
281}
282
283/*******************************************************************************
284**
285** Function ms_delay
286**
287** Description sleep unconditionally for timeout milliseconds
288**
289** Returns None
290**
291*******************************************************************************/
292void ms_delay (uint32_t timeout)
293{
294 struct timespec delay;
295 int err;
296
297 if (timeout == 0)
298 return;
299
300 delay.tv_sec = timeout / 1000;
301 delay.tv_nsec = 1000 * 1000 * (timeout%1000);
302
303 /* [u]sleep can't be used because it uses SIGALRM */
304 do {
305 err = nanosleep(&delay, &delay);
306 } while (err < 0 && errno ==EINTR);
307}
308
309/*******************************************************************************
310**
311** Function line_speed_to_userial_baud
312**
313** Description helper function converts line speed number into USERIAL baud
314** rate symbol
315**
316** Returns unit8_t (USERIAL baud symbol)
317**
318*******************************************************************************/
319uint8_t line_speed_to_userial_baud(uint32_t line_speed)
320{
321 uint8_t baud;
322
323 if (line_speed == 4000000)
324 baud = USERIAL_BAUD_4M;
325 else if (line_speed == 3000000)
326 baud = USERIAL_BAUD_3M;
327 else if (line_speed == 2000000)
328 baud = USERIAL_BAUD_2M;
329 else if (line_speed == 1000000)
330 baud = USERIAL_BAUD_1M;
331 else if (line_speed == 921600)
332 baud = USERIAL_BAUD_921600;
333 else if (line_speed == 460800)
334 baud = USERIAL_BAUD_460800;
335 else if (line_speed == 230400)
336 baud = USERIAL_BAUD_230400;
337 else if (line_speed == 115200)
338 baud = USERIAL_BAUD_115200;
339 else if (line_speed == 57600)
340 baud = USERIAL_BAUD_57600;
341 else if (line_speed == 19200)
342 baud = USERIAL_BAUD_19200;
343 else if (line_speed == 9600)
344 baud = USERIAL_BAUD_9600;
345 else if (line_speed == 1200)
346 baud = USERIAL_BAUD_1200;
347 else if (line_speed == 600)
348 baud = USERIAL_BAUD_600;
349 else
350 {
351 ALOGE( "userial vendor: unsupported baud speed %d", line_speed);
352 baud = USERIAL_BAUD_115200;
353 }
354
355 return baud;
356}
357
358
359/*******************************************************************************
360**
361** Function hw_strncmp
362**
363** Description Used to compare two strings in caseless
364**
365** Returns 0: match, otherwise: not match
366**
367*******************************************************************************/
368static int hw_strncmp (const char *p_str1, const char *p_str2, const int len)
369{
370 int i;
371
372 if (!p_str1 || !p_str2)
373 return (1);
374
375 for (i = 0; i < len; i++)
376 {
377 if (toupper(p_str1[i]) != toupper(p_str2[i]))
378 return (i+1);
379 }
380
381 return 0;
382}
383
384/*******************************************************************************
385**
386** Function hw_config_findpatch
387**
388** Description Search for a proper firmware patch file
389** The selected firmware patch file name with full path
390** will be stored in the input string parameter, i.e.
391** p_chip_id_str, when returns.
392**
393** Returns TRUE when found the target patch file, otherwise FALSE
394**
395*******************************************************************************/
396static uint8_t hw_config_findpatch(char *p_chip_id_str)
397{
398 DIR *dirp;
399 struct dirent *dp;
400 int filenamelen;
401 uint8_t retval = FALSE;
402
403 BTHWDBG("Target name = [%s]", p_chip_id_str);
404
405 if (strlen(fw_patchfile_name)> 0)
406 {
407 /* If specific filepath and filename have been given in run-time
408 * configuration /etc/bluetooth/bt_vendor.conf file, we will use them
409 * to concatenate the filename to open rather than searching a file
410 * matching to chipset name in the fw_patchfile_path folder.
411 */
412 sprintf(p_chip_id_str, "%s", fw_patchfile_path);
413 if (fw_patchfile_path[strlen(fw_patchfile_path)- 1] != '/')
414 {
415 strcat(p_chip_id_str, "/");
416 }
417 strcat(p_chip_id_str, fw_patchfile_name);
418
419 ALOGI("FW patchfile: %s", p_chip_id_str);
420 return TRUE;
421 }
422
423 if ((dirp = opendir(fw_patchfile_path)) != NULL)
424 {
425 /* Fetch next filename in patchfile directory */
426 while ((dp = readdir(dirp)) != NULL)
427 {
428 /* Check if filename starts with chip-id name */
429 if ((hw_strncmp(dp->d_name, p_chip_id_str, strlen(p_chip_id_str)) \
430 ) == 0)
431 {
432 /* Check if it has .hcd extenstion */
433 filenamelen = strlen(dp->d_name);
434 if ((filenamelen >= FW_PATCHFILE_EXTENSION_LEN) &&
435 ((hw_strncmp(
436 &dp->d_name[filenamelen-FW_PATCHFILE_EXTENSION_LEN], \
437 FW_PATCHFILE_EXTENSION, \
438 FW_PATCHFILE_EXTENSION_LEN) \
439 ) == 0))
440 {
441 ALOGI("Found patchfile: %s/%s", \
442 fw_patchfile_path, dp->d_name);
443
444 /* Make sure length does not exceed maximum */
445 if ((filenamelen + strlen(fw_patchfile_path)) > \
446 FW_PATCHFILE_PATH_MAXLEN)
447 {
448 ALOGE("Invalid patchfile name (too long)");
449 }
450 else
451 {
452 memset(p_chip_id_str, 0, FW_PATCHFILE_PATH_MAXLEN);
453 /* Found patchfile. Store location and name */
454 strcpy(p_chip_id_str, fw_patchfile_path);
455 if (fw_patchfile_path[ \
456 strlen(fw_patchfile_path)- 1 \
457 ] != '/')
458 {
459 strcat(p_chip_id_str, "/");
460 }
461 strcat(p_chip_id_str, dp->d_name);
462 retval = TRUE;
463 }
464 break;
465 }
466 }
467 }
468
469 closedir(dirp);
470
471 if (retval == FALSE)
472 {
473 /* Try again chip name without revision info */
474
475 int len = strlen(p_chip_id_str);
476 char *p = p_chip_id_str + len - 1;
477
478 /* Scan backward and look for the first alphabet
479 which is not M or m
480 */
481 while (len > 3) // BCM****
482 {
483 if ((isdigit(*p)==0) && (*p != 'M') && (*p != 'm'))
484 break;
485
486 p--;
487 len--;
488 }
489
490 if (len > 3)
491 {
492 *p = 0;
493 retval = hw_config_findpatch(p_chip_id_str);
494 }
495 }
496 }
497 else
498 {
499 ALOGE("Could not open %s", fw_patchfile_path);
500 }
501
502 return (retval);
503}
504
505/*******************************************************************************
506**
507** Function hw_config_set_bdaddr
508**
509** Description Program controller's Bluetooth Device Address
510**
511** Returns TRUE, if valid address is sent
512** FALSE, otherwise
513**
514*******************************************************************************/
515static uint8_t hw_config_set_bdaddr(HC_BT_HDR *p_buf)
516{
517 uint8_t retval = FALSE;
518 uint8_t *p = (uint8_t *) (p_buf + 1);
519
520 ALOGI("Setting local bd addr to %02X:%02X:%02X:%02X:%02X:%02X",
521 vnd_local_bd_addr[0], vnd_local_bd_addr[1], vnd_local_bd_addr[2],
522 vnd_local_bd_addr[3], vnd_local_bd_addr[4], vnd_local_bd_addr[5]);
523
524 UINT16_TO_STREAM(p, HCI_VSC_WRITE_BD_ADDR);
525 *p++ = BD_ADDR_LEN; /* parameter length */
526 *p++ = vnd_local_bd_addr[5];
527 *p++ = vnd_local_bd_addr[4];
528 *p++ = vnd_local_bd_addr[3];
529 *p++ = vnd_local_bd_addr[2];
530 *p++ = vnd_local_bd_addr[1];
531 *p = vnd_local_bd_addr[0];
532
533 p_buf->len = HCI_CMD_PREAMBLE_SIZE + BD_ADDR_LEN;
534 hw_cfg_cb.state = HW_CFG_SET_BD_ADDR;
535
536 retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_BD_ADDR, p_buf, \
537 hw_config_cback);
538
539 return (retval);
540}
541
542#if (USE_CONTROLLER_BDADDR == TRUE)
543/*******************************************************************************
544**
545** Function hw_config_read_bdaddr
546**
547** Description Read controller's Bluetooth Device Address
548**
549** Returns TRUE, if valid address is sent
550** FALSE, otherwise
551**
552*******************************************************************************/
553static uint8_t hw_config_read_bdaddr(HC_BT_HDR *p_buf)
554{
555 uint8_t retval = FALSE;
556 uint8_t *p = (uint8_t *) (p_buf + 1);
557
558 UINT16_TO_STREAM(p, HCI_READ_LOCAL_BDADDR);
559 *p = 0; /* parameter length */
560
561 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
562 hw_cfg_cb.state = HW_CFG_READ_BD_ADDR;
563
564 retval = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_BDADDR, p_buf, \
565 hw_config_cback);
566
567 return (retval);
568}
569#endif // (USE_CONTROLLER_BDADDR == TRUE)
570
571/*******************************************************************************
572**
573** Function hw_config_cback
574**
575** Description Callback function for controller configuration
576**
577** Returns None
578**
579*******************************************************************************/
580void hw_config_cback(void *p_mem)
581{
582 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
583 char *p_name, *p_tmp;
584 uint8_t *p, status;
585 uint16_t opcode;
586 HC_BT_HDR *p_buf=NULL;
587 uint8_t is_proceeding = FALSE;
588 int i;
589#if (USE_CONTROLLER_BDADDR == TRUE)
590 const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0};
591#endif
592
593 status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
594 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
595 STREAM_TO_UINT16(opcode,p);
596
597 /* Ask a new buffer big enough to hold any HCI commands sent in here */
598 if ((status == 0) && bt_vendor_cbacks)
599 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
600 HCI_CMD_MAX_LEN);
601
602 if (p_buf != NULL)
603 {
604 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
605 p_buf->offset = 0;
606 p_buf->len = 0;
607 p_buf->layer_specific = 0;
608
609 p = (uint8_t *) (p_buf + 1);
610
611 switch (hw_cfg_cb.state)
612 {
613 case HW_CFG_SET_UART_BAUD_1:
614 /* update baud rate of host's UART port */
615 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE);
616 userial_vendor_set_baud( \
617 line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
618 );
619
620 /* read local name */
621 UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME);
622 *p = 0; /* parameter length */
623
624 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
625 hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME;
626 ms_delay(50);
627 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \
628 p_buf, hw_config_cback);
629 break;
630
631 case HW_CFG_READ_LOCAL_NAME:
632 p_tmp = p_name = (char *) (p_evt_buf + 1) + \
633 HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING;
634
635 for (i=0; (i < LOCAL_NAME_BUFFER_LEN)||(*(p_name+i) != 0); i++)
636 *(p_name+i) = toupper(*(p_name+i));
637
638 if ((p_name = strstr(p_name, "BCM")) != NULL)
639 {
640 strncpy(hw_cfg_cb.local_chip_name, p_name, \
641 LOCAL_NAME_BUFFER_LEN-1);
642 }
643 else
644 {
645 strncpy(hw_cfg_cb.local_chip_name, "UNKNOWN", \
646 LOCAL_NAME_BUFFER_LEN-1);
647 p_name = p_tmp;
648 }
649
650 hw_cfg_cb.local_chip_name[LOCAL_NAME_BUFFER_LEN-1] = 0;
651
652 BTHWDBG("Chipset %s", hw_cfg_cb.local_chip_name);
653
654 if ((status = hw_config_findpatch(p_name)) == TRUE)
655 {
656 if ((hw_cfg_cb.fw_fd = open(p_name, O_RDONLY)) == -1)
657 {
658 ALOGE("vendor lib preload failed to open [%s]", p_name);
659 }
660 else
661 {
662 /* vsc_download_minidriver */
663 UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV);
664 *p = 0; /* parameter length */
665
666 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
667 hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER;
668
669 is_proceeding = bt_vendor_cbacks->xmit_cb( \
670 HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \
671 hw_config_cback);
672 }
673 }
674 else
675 {
676 ALOGE( \
677 "vendor lib preload failed to locate firmware patch file" \
678 );
679 }
680
681 if (is_proceeding == FALSE)
682 {
683 is_proceeding = hw_config_set_bdaddr(p_buf);
684 }
685 break;
686
687 case HW_CFG_DL_MINIDRIVER:
688 /* give time for placing firmware in download mode */
689 ms_delay(50);
690 hw_cfg_cb.state = HW_CFG_DL_FW_PATCH;
691 /* fall through intentionally */
692 case HW_CFG_DL_FW_PATCH:
693 p_buf->len = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE);
694 if (p_buf->len > 0)
695 {
696 if ((p_buf->len < HCI_CMD_PREAMBLE_SIZE) || \
697 (opcode == HCI_VSC_LAUNCH_RAM))
698 {
699 ALOGW("firmware patch file might be altered!");
700 }
701 else
702 {
703 p_buf->len += read(hw_cfg_cb.fw_fd, \
704 p+HCI_CMD_PREAMBLE_SIZE,\
705 *(p+HCD_REC_PAYLOAD_LEN_BYTE));
706 STREAM_TO_UINT16(opcode,p);
707 is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \
708 p_buf, hw_config_cback);
709 break;
710 }
711 }
712
713 close(hw_cfg_cb.fw_fd);
714 hw_cfg_cb.fw_fd = -1;
715
716 /* Normally the firmware patch configuration file
717 * sets the new starting baud rate at 115200.
718 * So, we need update host's baud rate accordingly.
719 */
720 ALOGI("bt vendor lib: set UART baud 115200");
721 userial_vendor_set_baud(USERIAL_BAUD_115200);
722
723 /* Next, we would like to boost baud rate up again
724 * to desired working speed.
725 */
726 hw_cfg_cb.f_set_baud_2 = TRUE;
727
728 /* Check if we need to pause a few hundred milliseconds
729 * before sending down any HCI command.
730 */
731 ms_delay(look_up_fw_settlement_delay());
732
733 /* fall through intentionally */
734 case HW_CFG_START:
735 if (UART_TARGET_BAUD_RATE > 3000000)
736 {
737 /* set UART clock to 48MHz */
738 UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING);
739 *p++ = 1; /* parameter length */
740 *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */
741
742 p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1;
743 hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK;
744
745 is_proceeding = bt_vendor_cbacks->xmit_cb( \
746 HCI_VSC_WRITE_UART_CLOCK_SETTING, \
747 p_buf, hw_config_cback);
748 break;
749 }
750 /* fall through intentionally */
751 case HW_CFG_SET_UART_CLOCK:
752 /* set controller's UART baud rate to 3M */
753 UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE);
754 *p++ = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */
755 *p++ = 0; /* encoded baud rate */
756 *p++ = 0; /* use encoded form */
757 UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE);
758
759 p_buf->len = HCI_CMD_PREAMBLE_SIZE + \
760 UPDATE_BAUDRATE_CMD_PARAM_SIZE;
761 hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \
762 HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1;
763
764 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \
765 p_buf, hw_config_cback);
766 break;
767
768 case HW_CFG_SET_UART_BAUD_2:
769 /* update baud rate of host's UART port */
770 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE);
771 userial_vendor_set_baud( \
772 line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
773 );
774
775#if (USE_CONTROLLER_BDADDR == TRUE)
776 if ((is_proceeding = hw_config_read_bdaddr(p_buf)) == TRUE)
777 break;
778#else
779 if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE)
780 break;
781#endif
782 /* fall through intentionally */
783 case HW_CFG_SET_BD_ADDR:
784 ALOGI("vendor lib fwcfg completed");
785 bt_vendor_cbacks->dealloc(p_buf);
786 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
787
788 hw_cfg_cb.state = 0;
789
790 if (hw_cfg_cb.fw_fd != -1)
791 {
792 close(hw_cfg_cb.fw_fd);
793 hw_cfg_cb.fw_fd = -1;
794 }
795
796 is_proceeding = TRUE;
797 break;
798
799#if (USE_CONTROLLER_BDADDR == TRUE)
800 case HW_CFG_READ_BD_ADDR:
801 p_tmp = (char *) (p_evt_buf + 1) + \
802 HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY;
803
804 if (memcmp(p_tmp, null_bdaddr, BD_ADDR_LEN) == 0)
805 {
806 // Controller does not have a valid OTP BDADDR!
807 // Set the BTIF initial BDADDR instead.
808 if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE)
809 break;
810 }
811 else
812 {
813 ALOGI("Controller OTP bdaddr %02X:%02X:%02X:%02X:%02X:%02X",
814 *(p_tmp+5), *(p_tmp+4), *(p_tmp+3),
815 *(p_tmp+2), *(p_tmp+1), *p_tmp);
816 }
817
818 ALOGI("vendor lib fwcfg completed");
819 bt_vendor_cbacks->dealloc(p_buf);
820 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
821
822 hw_cfg_cb.state = 0;
823
824 if (hw_cfg_cb.fw_fd != -1)
825 {
826 close(hw_cfg_cb.fw_fd);
827 hw_cfg_cb.fw_fd = -1;
828 }
829
830 is_proceeding = TRUE;
831 break;
832#endif // (USE_CONTROLLER_BDADDR == TRUE)
833 } // switch(hw_cfg_cb.state)
834 } // if (p_buf != NULL)
835
836 /* Free the RX event buffer */
837 if (bt_vendor_cbacks)
838 bt_vendor_cbacks->dealloc(p_evt_buf);
839
840 if (is_proceeding == FALSE)
841 {
842 ALOGE("vendor lib fwcfg aborted!!!");
843 if (bt_vendor_cbacks)
844 {
845 if (p_buf != NULL)
846 bt_vendor_cbacks->dealloc(p_buf);
847
848 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
849 }
850
851 if (hw_cfg_cb.fw_fd != -1)
852 {
853 close(hw_cfg_cb.fw_fd);
854 hw_cfg_cb.fw_fd = -1;
855 }
856
857 hw_cfg_cb.state = 0;
858 }
859}
860
861/******************************************************************************
862** LPM Static Functions
863******************************************************************************/
864
865/*******************************************************************************
866**
867** Function hw_lpm_ctrl_cback
868**
869** Description Callback function for lpm enable/disable rquest
870**
871** Returns None
872**
873*******************************************************************************/
874void hw_lpm_ctrl_cback(void *p_mem)
875{
876 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
877 bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL;
878
879 if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0)
880 {
881 status = BT_VND_OP_RESULT_SUCCESS;
882 }
883
884 if (bt_vendor_cbacks)
885 {
886 bt_vendor_cbacks->lpm_cb(status);
887 bt_vendor_cbacks->dealloc(p_evt_buf);
888 }
889}
890
891
892#if (SCO_CFG_INCLUDED == TRUE)
893/*****************************************************************************
894** SCO Configuration Static Functions
895*****************************************************************************/
896
897/*******************************************************************************
898**
899** Function hw_sco_cfg_cback
900**
901** Description Callback function for SCO configuration rquest
902**
903** Returns None
904**
905*******************************************************************************/
906void hw_sco_cfg_cback(void *p_mem)
907{
908 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
909 uint8_t *p;
910 uint16_t opcode;
911 HC_BT_HDR *p_buf=NULL;
912
913 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
914 STREAM_TO_UINT16(opcode,p);
915
916 /* Free the RX event buffer */
917 if (bt_vendor_cbacks)
918 bt_vendor_cbacks->dealloc(p_evt_buf);
919
920#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE))
921 if (opcode == HCI_VSC_WRITE_SCO_PCM_INT_PARAM)
922 {
923 uint8_t ret = FALSE;
924
925 /* Ask a new buffer to hold WRITE_PCM_DATA_FORMAT_PARAM command */
926 if (bt_vendor_cbacks)
927 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
928 HCI_CMD_PREAMBLE_SIZE + \
929 PCM_DATA_FORMAT_PARAM_SIZE);
930 if (p_buf)
931 {
932 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
933 p_buf->offset = 0;
934 p_buf->layer_specific = 0;
935 p_buf->len = HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE;
936
937 p = (uint8_t *) (p_buf + 1);
938 UINT16_TO_STREAM(p, HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM);
939 *p++ = PCM_DATA_FORMAT_PARAM_SIZE;
940 memcpy(p, &bt_pcm_data_fmt_param, PCM_DATA_FORMAT_PARAM_SIZE);
941
942 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM,\
943 p_buf, hw_sco_cfg_cback)) == FALSE)
944 {
945 bt_vendor_cbacks->dealloc(p_buf);
946 }
947 else
948 return;
949 }
950 }
951#endif // !SCO_USE_I2S_INTERFACE
952
953if (bt_vendor_cbacks)
954 bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
955}
956#endif // SCO_CFG_INCLUDED
957
958/*****************************************************************************
959** Hardware Configuration Interface Functions
960*****************************************************************************/
961
962
963/*******************************************************************************
964**
965** Function hw_config_start
966**
967** Description Kick off controller initialization process
968**
969** Returns None
970**
971*******************************************************************************/
972void hw_config_start(void)
973{
974 HC_BT_HDR *p_buf = NULL;
975 uint8_t *p;
976
977 hw_cfg_cb.state = 0;
978 hw_cfg_cb.fw_fd = -1;
979 hw_cfg_cb.f_set_baud_2 = FALSE;
980
981 /* Start from sending HCI_RESET */
982
983 if (bt_vendor_cbacks)
984 {
985 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
986 HCI_CMD_PREAMBLE_SIZE);
987 }
988
989 if (p_buf)
990 {
991 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
992 p_buf->offset = 0;
993 p_buf->layer_specific = 0;
994 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
995
996 p = (uint8_t *) (p_buf + 1);
997 UINT16_TO_STREAM(p, HCI_RESET);
998 *p = 0; /* parameter length */
999
1000 hw_cfg_cb.state = HW_CFG_START;
1001
1002 bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback);
1003 }
1004 else
1005 {
1006 if (bt_vendor_cbacks)
1007 {
1008 ALOGE("vendor lib fw conf aborted [no buffer]");
1009 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
1010 }
1011 }
1012}
1013
1014/*******************************************************************************
1015**
1016** Function hw_lpm_enable
1017**
1018** Description Enalbe/Disable LPM
1019**
1020** Returns TRUE/FALSE
1021**
1022*******************************************************************************/
1023uint8_t hw_lpm_enable(uint8_t turn_on)
1024{
1025 HC_BT_HDR *p_buf = NULL;
1026 uint8_t *p;
1027 uint8_t ret = FALSE;
1028
1029 if (bt_vendor_cbacks)
1030 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
1031 HCI_CMD_PREAMBLE_SIZE + \
1032 LPM_CMD_PARAM_SIZE);
1033
1034 if (p_buf)
1035 {
1036 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1037 p_buf->offset = 0;
1038 p_buf->layer_specific = 0;
1039 p_buf->len = HCI_CMD_PREAMBLE_SIZE + LPM_CMD_PARAM_SIZE;
1040
1041 p = (uint8_t *) (p_buf + 1);
1042 UINT16_TO_STREAM(p, HCI_VSC_WRITE_SLEEP_MODE);
1043 *p++ = LPM_CMD_PARAM_SIZE; /* parameter length */
1044
1045 if (turn_on)
1046 {
1047 memcpy(p, &lpm_param, LPM_CMD_PARAM_SIZE);
1048 }
1049 else
1050 {
1051 memset(p, 0, LPM_CMD_PARAM_SIZE);
1052 }
1053
1054 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SLEEP_MODE, p_buf, \
1055 hw_lpm_ctrl_cback)) == FALSE)
1056 {
1057 bt_vendor_cbacks->dealloc(p_buf);
1058 }
1059 }
1060
1061 if ((ret == FALSE) && bt_vendor_cbacks)
1062 bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_FAIL);
1063
1064 return ret;
1065}
1066
1067/*******************************************************************************
1068**
1069** Function hw_lpm_get_idle_timeout
1070**
1071** Description Calculate idle time based on host stack idle threshold
1072**
1073** Returns idle timeout value
1074**
1075*******************************************************************************/
1076uint32_t hw_lpm_get_idle_timeout(void)
1077{
1078 uint32_t timeout_ms;
1079
1080 /* set idle time to be LPM_IDLE_TIMEOUT_MULTIPLE times of
1081 * host stack idle threshold (in 300ms/25ms)
1082 */
1083 timeout_ms = (uint32_t)lpm_param.host_stack_idle_threshold \
1084 * LPM_IDLE_TIMEOUT_MULTIPLE;
1085
1086 if (strstr(hw_cfg_cb.local_chip_name, "BCM4325") != NULL)
1087 timeout_ms *= 25; // 12.5 or 25 ?
1088 else
1089 timeout_ms *= 300;
1090
1091 return timeout_ms;
1092}
1093
1094/*******************************************************************************
1095**
1096** Function hw_lpm_set_wake_state
1097**
1098** Description Assert/Deassert BT_WAKE
1099**
1100** Returns None
1101**
1102*******************************************************************************/
1103void hw_lpm_set_wake_state(uint8_t wake_assert)
1104{
1105 uint8_t state = (wake_assert) ? UPIO_ASSERT : UPIO_DEASSERT;
1106
1107 upio_set(UPIO_BT_WAKE, state, lpm_param.bt_wake_polarity);
1108}
1109
1110#if (SCO_CFG_INCLUDED == TRUE)
1111/*******************************************************************************
1112**
1113** Function hw_sco_config
1114**
1115** Description Configure SCO related hardware settings
1116**
1117** Returns None
1118**
1119*******************************************************************************/
1120void hw_sco_config(void)
1121{
1122 HC_BT_HDR *p_buf = NULL;
1123 uint8_t *p, ret;
1124
1125#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE))
1126 uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE;
1127#else
1128 uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE;
1129#endif
1130
1131 if (bt_vendor_cbacks)
1132 p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE+cmd_u16);
1133
1134 if (p_buf)
1135 {
1136 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1137 p_buf->offset = 0;
1138 p_buf->layer_specific = 0;
1139 p_buf->len = cmd_u16;
1140
1141 p = (uint8_t *) (p_buf + 1);
1142#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE))
1143 UINT16_TO_STREAM(p, HCI_VSC_WRITE_SCO_PCM_INT_PARAM);
1144 *p++ = SCO_PCM_PARAM_SIZE;
1145 memcpy(p, &bt_sco_param, SCO_PCM_PARAM_SIZE);
1146 cmd_u16 = HCI_VSC_WRITE_SCO_PCM_INT_PARAM;
1147 ALOGI("SCO PCM configure {%d, %d, %d, %d, %d}",
1148 bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3], \
1149 bt_sco_param[4]);
1150
1151#else
1152 UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM);
1153 *p++ = SCO_I2SPCM_PARAM_SIZE;
1154 memcpy(p, &bt_sco_param, SCO_I2SPCM_PARAM_SIZE);
1155 cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM;
1156 ALOGI("SCO over I2SPCM interface {%d, %d, %d, %d}",
1157 bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3]);
1158#endif
1159
1160 if ((ret=bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_cfg_cback)) \
1161 == FALSE)
1162 {
1163 bt_vendor_cbacks->dealloc(p_buf);
1164 }
1165 else
1166 return;
1167 }
1168
1169 if (bt_vendor_cbacks)
1170 {
1171 ALOGE("vendor lib scocfg aborted");
1172 bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_FAIL);
1173 }
1174}
1175#endif // SCO_CFG_INCLUDED
1176
1177/*******************************************************************************
1178**
1179** Function hw_set_patch_file_path
1180**
1181** Description Set the location of firmware patch file
1182**
1183** Returns 0 : Success
1184** Otherwise : Fail
1185**
1186*******************************************************************************/
1187int hw_set_patch_file_path(char *p_conf_name, char *p_conf_value, int param)
1188{
1189
1190 strcpy(fw_patchfile_path, p_conf_value);
1191
1192 return 0;
1193}
1194
1195/*******************************************************************************
1196**
1197** Function hw_set_patch_file_name
1198**
1199** Description Give the specific firmware patch filename
1200**
1201** Returns 0 : Success
1202** Otherwise : Fail
1203**
1204*******************************************************************************/
1205int hw_set_patch_file_name(char *p_conf_name, char *p_conf_value, int param)
1206{
1207
1208 strcpy(fw_patchfile_name, p_conf_value);
1209
1210 return 0;
1211}
1212
1213#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
1214/*******************************************************************************
1215**
1216** Function hw_set_patch_settlement_delay
1217**
1218** Description Give the specific firmware patch settlement time in milliseconds
1219**
1220** Returns 0 : Success
1221** Otherwise : Fail
1222**
1223*******************************************************************************/
1224int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int param)
1225{
1226 fw_patch_settlement_delay = atoi(p_conf_value);
1227
1228 return 0;
1229}
1230#endif //VENDOR_LIB_RUNTIME_TUNING_ENABLED
1231
1232