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