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