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