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