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 if (strstr(hw_cfg_cb.local_chip_name, "BCM43013") != NULL)
1242         timeout_ms *= 1;
1243     else
1244         timeout_ms *= 300;
1245 
1246     return timeout_ms;
1247 }
1248 
1249 /*******************************************************************************
1250 **
1251 ** Function        hw_lpm_set_wake_state
1252 **
1253 ** Description     Assert/Deassert BT_WAKE
1254 **
1255 ** Returns         None
1256 **
1257 *******************************************************************************/
hw_lpm_set_wake_state(uint8_t wake_assert)1258 void hw_lpm_set_wake_state(uint8_t wake_assert)
1259 {
1260     uint8_t state = (wake_assert) ? UPIO_ASSERT : UPIO_DEASSERT;
1261 
1262     upio_set(UPIO_BT_WAKE, state, lpm_param.bt_wake_polarity);
1263 }
1264 
1265 #if (SCO_CFG_INCLUDED == TRUE)
1266 /*******************************************************************************
1267 **
1268 ** Function         hw_sco_config
1269 **
1270 ** Description      Configure SCO related hardware settings
1271 **
1272 ** Returns          None
1273 **
1274 *******************************************************************************/
hw_sco_config(void)1275 void hw_sco_config(void)
1276 {
1277     if (SCO_INTERFACE_I2S == sco_bus_interface)
1278     {
1279         /* 'Enable' I2S mode */
1280         bt_sco_i2spcm_param[0] = 1;
1281 
1282         /* set nbs clock rate as the value in SCO_I2SPCM_IF_CLOCK_RATE field */
1283         sco_bus_clock_rate = bt_sco_i2spcm_param[3];
1284     }
1285     else
1286     {
1287         /* 'Disable' I2S mode */
1288         bt_sco_i2spcm_param[0] = 0;
1289 
1290         /* set nbs clock rate as the value in SCO_PCM_IF_CLOCK_RATE field */
1291         sco_bus_clock_rate = bt_sco_param[1];
1292 
1293         /* sync up clock mode setting */
1294         bt_sco_i2spcm_param[1] = bt_sco_param[4];
1295     }
1296 
1297     if (sco_bus_wbs_clock_rate == INVALID_SCO_CLOCK_RATE)
1298     {
1299         /* set default wbs clock rate */
1300         sco_bus_wbs_clock_rate = SCO_I2SPCM_IF_CLOCK_RATE4WBS;
1301 
1302         if (sco_bus_wbs_clock_rate < sco_bus_clock_rate)
1303             sco_bus_wbs_clock_rate = sco_bus_clock_rate;
1304     }
1305 
1306     /*
1307      *  To support I2S/PCM port multiplexing signals for sharing Bluetooth audio
1308      *  and FM on the same PCM pins, we defer Bluetooth audio (SCO/eSCO)
1309      *  configuration till SCO/eSCO is being established;
1310      *  i.e. in hw_set_audio_state() call.
1311      *  When configured as I2S only, Bluetooth audio configuration is executed
1312      *  immediately with SCO_CODEC_CVSD by default.
1313      */
1314 
1315     if (SCO_INTERFACE_I2S == sco_bus_interface) {
1316         hw_sco_i2spcm_config(SCO_CODEC_CVSD);
1317     }
1318 
1319     if (bt_vendor_cbacks)
1320     {
1321         bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
1322     }
1323 }
1324 
hw_sco_i2spcm_config_from_command(void * p_mem,uint16_t codec)1325 static void hw_sco_i2spcm_config_from_command(void *p_mem, uint16_t codec) {
1326     HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem;
1327     bool command_success = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0;
1328 
1329     /* Free the RX event buffer */
1330     if (bt_vendor_cbacks)
1331         bt_vendor_cbacks->dealloc(p_evt_buf);
1332 
1333     if (command_success)
1334         hw_sco_i2spcm_config(codec);
1335     else if (bt_vendor_cbacks)
1336         bt_vendor_cbacks->audio_state_cb(BT_VND_OP_RESULT_FAIL);
1337 }
1338 
1339 
1340 /*******************************************************************************
1341 **
1342 ** Function         hw_sco_i2spcm_config
1343 **
1344 ** Description      Configure SCO over I2S or PCM
1345 **
1346 ** Returns          None
1347 **
1348 *******************************************************************************/
hw_sco_i2spcm_config(uint16_t codec)1349 static void hw_sco_i2spcm_config(uint16_t codec)
1350 {
1351     HC_BT_HDR *p_buf = NULL;
1352     uint8_t *p, ret;
1353     uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE;
1354 
1355     if (bt_vendor_cbacks)
1356         p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + cmd_u16);
1357 
1358     if (p_buf)
1359     {
1360         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1361         p_buf->offset = 0;
1362         p_buf->layer_specific = 0;
1363         p_buf->len = cmd_u16;
1364 
1365         p = (uint8_t *)(p_buf + 1);
1366 
1367         UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM);
1368         *p++ = SCO_I2SPCM_PARAM_SIZE;
1369         if (codec == SCO_CODEC_CVSD)
1370         {
1371             bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE  8k */
1372             bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate;
1373         }
1374         else if (codec == SCO_CODEC_MSBC)
1375         {
1376             bt_sco_i2spcm_param[2] = wbs_sample_rate; /* SCO_I2SPCM_IF_SAMPLE_RATE 16K */
1377             bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_wbs_clock_rate;
1378         }
1379         else
1380         {
1381             bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE  8k */
1382             bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate;
1383             ALOGE("wrong codec is use in hw_sco_i2spcm_config, goes default NBS");
1384         }
1385         memcpy(p, &bt_sco_i2spcm_param, SCO_I2SPCM_PARAM_SIZE);
1386         cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM;
1387         ALOGI("I2SPCM config {0x%x, 0x%x, 0x%x, 0x%x}",
1388                 bt_sco_i2spcm_param[0], bt_sco_i2spcm_param[1],
1389                 bt_sco_i2spcm_param[2], bt_sco_i2spcm_param[3]);
1390 
1391         if ((ret = bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE)
1392         {
1393             bt_vendor_cbacks->dealloc(p_buf);
1394         }
1395         else
1396             return;
1397     }
1398 
1399     bt_vendor_cbacks->audio_state_cb(BT_VND_OP_RESULT_FAIL);
1400 }
1401 
1402 /*******************************************************************************
1403 **
1404 ** Function         hw_set_SCO_codec
1405 **
1406 ** Description      This functgion sends command to the controller to setup
1407 **                              WBS/NBS codec for the upcoming eSCO connection.
1408 **
1409 ** Returns          -1 : Failed to send VSC
1410 **                   0 : Success
1411 **
1412 *******************************************************************************/
hw_set_SCO_codec(uint16_t codec)1413 static int hw_set_SCO_codec(uint16_t codec)
1414 {
1415     HC_BT_HDR   *p_buf = NULL;
1416     uint8_t     *p;
1417     uint8_t     ret;
1418     int         ret_val = 0;
1419     tINT_CMD_CBACK p_set_SCO_codec_cback;
1420 
1421     BTHWDBG( "hw_set_SCO_codec 0x%x", codec);
1422 
1423     if (bt_vendor_cbacks)
1424         p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(
1425                 BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE);
1426 
1427     if (p_buf)
1428     {
1429         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1430         p_buf->offset = 0;
1431         p_buf->layer_specific = 0;
1432         p = (uint8_t *)(p_buf + 1);
1433 
1434         UINT16_TO_STREAM(p, HCI_VSC_ENABLE_WBS);
1435 
1436         if (codec == SCO_CODEC_MSBC)
1437         {
1438             /* Enable mSBC */
1439             *p++ = SCO_CODEC_PARAM_SIZE; /* set the parameter size */
1440             UINT8_TO_STREAM(p,1); /* enable */
1441             UINT16_TO_STREAM(p, codec);
1442 
1443             /* set the totall size of this packet */
1444             p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE;
1445 
1446             p_set_SCO_codec_cback = hw_set_MSBC_codec_cback;
1447         }
1448         else
1449         {
1450             /* Disable mSBC */
1451             *p++ = (SCO_CODEC_PARAM_SIZE - 2); /* set the parameter size */
1452             UINT8_TO_STREAM(p,0); /* disable */
1453 
1454             /* set the totall size of this packet */
1455             p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE - 2;
1456 
1457             p_set_SCO_codec_cback = hw_set_CVSD_codec_cback;
1458             if ((codec != SCO_CODEC_CVSD) && (codec != SCO_CODEC_NONE))
1459             {
1460                 ALOGW("SCO codec setting is wrong: codec: 0x%x", codec);
1461             }
1462         }
1463 
1464         if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_ENABLE_WBS, p_buf, p_set_SCO_codec_cback))\
1465               == FALSE)
1466         {
1467             bt_vendor_cbacks->dealloc(p_buf);
1468             ret_val = -1;
1469         }
1470     }
1471     else
1472     {
1473         ret_val = -1;
1474     }
1475 
1476     return ret_val;
1477 }
1478 
1479 /*******************************************************************************
1480 **
1481 ** Function         hw_set_audio_state
1482 **
1483 ** Description      This function configures audio base on provided audio state
1484 **
1485 ** Paramters        pointer to audio state structure
1486 **
1487 ** Returns          0: ok, -1: error
1488 **
1489 *******************************************************************************/
hw_set_audio_state(bt_vendor_op_audio_state_t * p_state)1490 int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state)
1491 {
1492     int ret_val = -1;
1493 
1494     if (!bt_vendor_cbacks)
1495         return ret_val;
1496 
1497     ret_val = hw_set_SCO_codec(p_state->peer_codec);
1498     return ret_val;
1499 }
1500 
1501 #else  // SCO_CFG_INCLUDED
hw_set_audio_state(bt_vendor_op_audio_state_t * p_state)1502 int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state)
1503 {
1504     return -256;
1505 }
1506 #endif
1507 /*******************************************************************************
1508 **
1509 ** Function        hw_set_patch_file_path
1510 **
1511 ** Description     Set the location of firmware patch file
1512 **
1513 ** Returns         0 : Success
1514 **                 Otherwise : Fail
1515 **
1516 *******************************************************************************/
hw_set_patch_file_path(char * p_conf_name,char * p_conf_value,int param)1517 int hw_set_patch_file_path(char *p_conf_name, char *p_conf_value, int param)
1518 {
1519 
1520     strcpy(fw_patchfile_path, p_conf_value);
1521 
1522     return 0;
1523 }
1524 
1525 /*******************************************************************************
1526 **
1527 ** Function        hw_set_patch_file_name
1528 **
1529 ** Description     Give the specific firmware patch filename
1530 **
1531 ** Returns         0 : Success
1532 **                 Otherwise : Fail
1533 **
1534 *******************************************************************************/
hw_set_patch_file_name(char * p_conf_name,char * p_conf_value,int param)1535 int hw_set_patch_file_name(char *p_conf_name, char *p_conf_value, int param)
1536 {
1537 
1538     strcpy(fw_patchfile_name, p_conf_value);
1539 
1540     return 0;
1541 }
1542 
1543 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
1544 /*******************************************************************************
1545 **
1546 ** Function        hw_set_patch_settlement_delay
1547 **
1548 ** Description     Give the specific firmware patch settlement time in milliseconds
1549 **
1550 ** Returns         0 : Success
1551 **                 Otherwise : Fail
1552 **
1553 *******************************************************************************/
hw_set_patch_settlement_delay(char * p_conf_name,char * p_conf_value,int param)1554 int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int param)
1555 {
1556     fw_patch_settlement_delay = atoi(p_conf_value);
1557 
1558     return 0;
1559 }
1560 #endif  //VENDOR_LIB_RUNTIME_TUNING_ENABLED
1561 
1562 /*****************************************************************************
1563 **   Sample Codes Section
1564 *****************************************************************************/
1565 
1566 #if (HW_END_WITH_HCI_RESET == TRUE)
1567 /*******************************************************************************
1568 **
1569 ** Function         hw_epilog_cback
1570 **
1571 ** Description      Callback function for Command Complete Events from HCI
1572 **                  commands sent in epilog process.
1573 **
1574 ** Returns          None
1575 **
1576 *******************************************************************************/
hw_epilog_cback(void * p_mem)1577 void hw_epilog_cback(void *p_mem)
1578 {
1579     HC_BT_HDR   *p_evt_buf = (HC_BT_HDR *) p_mem;
1580     uint8_t     *p, status;
1581     uint16_t    opcode;
1582 
1583     status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
1584     p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
1585     STREAM_TO_UINT16(opcode,p);
1586 
1587     BTHWDBG("%s Opcode:0x%04X Status: %d", __FUNCTION__, opcode, status);
1588 
1589     if (bt_vendor_cbacks)
1590     {
1591         /* Must free the RX event buffer */
1592         bt_vendor_cbacks->dealloc(p_evt_buf);
1593 
1594         /* Once epilog process is done, must call epilog_cb callback
1595            to notify caller */
1596         bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
1597     }
1598 }
1599 
1600 /*******************************************************************************
1601 **
1602 ** Function         hw_epilog_process
1603 **
1604 ** Description      Sample implementation of epilog process
1605 **
1606 ** Returns          None
1607 **
1608 *******************************************************************************/
hw_epilog_process(void)1609 void hw_epilog_process(void)
1610 {
1611     HC_BT_HDR  *p_buf = NULL;
1612     uint8_t     *p;
1613 
1614     BTHWDBG("hw_epilog_process");
1615 
1616     /* Sending a HCI_RESET */
1617     if (bt_vendor_cbacks)
1618     {
1619         /* Must allocate command buffer via HC's alloc API */
1620         p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
1621                                                        HCI_CMD_PREAMBLE_SIZE);
1622     }
1623 
1624     if (p_buf)
1625     {
1626         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1627         p_buf->offset = 0;
1628         p_buf->layer_specific = 0;
1629         p_buf->len = HCI_CMD_PREAMBLE_SIZE;
1630 
1631         p = (uint8_t *) (p_buf + 1);
1632         UINT16_TO_STREAM(p, HCI_RESET);
1633         *p = 0; /* parameter length */
1634 
1635         /* Send command via HC's xmit_cb API */
1636         bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_epilog_cback);
1637     }
1638     else
1639     {
1640         if (bt_vendor_cbacks)
1641         {
1642             ALOGE("vendor lib epilog process aborted [no buffer]");
1643             bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_FAIL);
1644         }
1645     }
1646 }
1647 #endif // (HW_END_WITH_HCI_RESET == TRUE)
1648