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:      bt_vendor_brcm.c
22 *
23 *  Description:   Broadcom vendor specific library implementation
24 *
25 ******************************************************************************/
26
27#define LOG_TAG "bt_vendor"
28
29#include <utils/Log.h>
30#include "bt_vendor_brcm.h"
31#include "upio.h"
32#include "userial_vendor.h"
33
34#ifndef BTVND_DBG
35#define BTVND_DBG FALSE
36#endif
37
38#if (BTVND_DBG == TRUE)
39#define BTVNDDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);}
40#else
41#define BTVNDDBG(param, ...) {}
42#endif
43
44/******************************************************************************
45**  Externs
46******************************************************************************/
47
48void hw_config_start(void);
49uint8_t hw_lpm_enable(uint8_t turn_on);
50uint32_t hw_lpm_get_idle_timeout(void);
51void hw_lpm_set_wake_state(uint8_t wake_assert);
52#if (SCO_CFG_INCLUDED == TRUE)
53void hw_sco_config(void);
54#endif
55void vnd_load_conf(const char *p_path);
56#if (HW_END_WITH_HCI_RESET == TRUE)
57void hw_epilog_process(void);
58#endif
59
60/******************************************************************************
61**  Variables
62******************************************************************************/
63
64bt_vendor_callbacks_t *bt_vendor_cbacks = NULL;
65uint8_t vnd_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
66
67/******************************************************************************
68**  Local type definitions
69******************************************************************************/
70
71/******************************************************************************
72**  Static Variables
73******************************************************************************/
74
75static const tUSERIAL_CFG userial_init_cfg =
76{
77    (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1),
78    USERIAL_BAUD_115200
79};
80
81/******************************************************************************
82**  Functions
83******************************************************************************/
84
85/*****************************************************************************
86**
87**   BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS
88**
89*****************************************************************************/
90
91static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr)
92{
93    ALOGI("init");
94
95    if (p_cb == NULL)
96    {
97        ALOGE("init failed with no user callbacks!");
98        return -1;
99    }
100
101#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
102    ALOGW("*****************************************************************");
103    ALOGW("*****************************************************************");
104    ALOGW("** Warning - BT Vendor Lib is loaded in debug tuning mode!");
105    ALOGW("**");
106    ALOGW("** If this is not intentional, rebuild libbt-vendor.so ");
107    ALOGW("** with VENDOR_LIB_RUNTIME_TUNING_ENABLED=FALSE and ");
108    ALOGW("** check if any run-time tuning parameters needed to be");
109    ALOGW("** carried to the build-time configuration accordingly.");
110    ALOGW("*****************************************************************");
111    ALOGW("*****************************************************************");
112#endif
113
114    userial_vendor_init();
115    upio_init();
116
117    vnd_load_conf(VENDOR_LIB_CONF_FILE);
118
119    /* store reference to user callbacks */
120    bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb;
121
122    /* This is handed over from the stack */
123    memcpy(vnd_local_bd_addr, local_bdaddr, 6);
124
125    return 0;
126}
127
128
129/** Requested operations */
130static int op(bt_vendor_opcode_t opcode, void *param)
131{
132    int retval = 0;
133
134    BTVNDDBG("op for %d", opcode);
135
136    switch(opcode)
137    {
138        case BT_VND_OP_POWER_CTRL:
139            {
140                int *state = (int *) param;
141                if (*state == BT_VND_PWR_OFF)
142                    upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
143                else if (*state == BT_VND_PWR_ON)
144                    upio_set_bluetooth_power(UPIO_BT_POWER_ON);
145            }
146            break;
147
148        case BT_VND_OP_FW_CFG:
149            {
150                hw_config_start();
151            }
152            break;
153
154        case BT_VND_OP_SCO_CFG:
155            {
156#if (SCO_CFG_INCLUDED == TRUE)
157                hw_sco_config();
158#else
159                retval = -1;
160#endif
161            }
162            break;
163
164        case BT_VND_OP_USERIAL_OPEN:
165            {
166                int (*fd_array)[] = (int (*)[]) param;
167                int fd, idx;
168                fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
169                if (fd != -1)
170                {
171                    for (idx=0; idx < CH_MAX; idx++)
172                        (*fd_array)[idx] = fd;
173
174                    retval = 1;
175                }
176                /* retval contains numbers of open fd of HCI channels */
177            }
178            break;
179
180        case BT_VND_OP_USERIAL_CLOSE:
181            {
182                userial_vendor_close();
183            }
184            break;
185
186        case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
187            {
188                uint32_t *timeout_ms = (uint32_t *) param;
189                *timeout_ms = hw_lpm_get_idle_timeout();
190            }
191            break;
192
193        case BT_VND_OP_LPM_SET_MODE:
194            {
195                uint8_t *mode = (uint8_t *) param;
196                retval = hw_lpm_enable(*mode);
197            }
198            break;
199
200        case BT_VND_OP_LPM_WAKE_SET_STATE:
201            {
202                uint8_t *state = (uint8_t *) param;
203                uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
204                                        TRUE : FALSE;
205
206                hw_lpm_set_wake_state(wake_assert);
207            }
208            break;
209
210         case BT_VND_OP_SET_AUDIO_STATE:
211            {
212                retval = hw_set_audio_state((bt_vendor_op_audio_state_t *)param);
213            }
214            break;
215
216        case BT_VND_OP_EPILOG:
217            {
218#if (HW_END_WITH_HCI_RESET == FALSE)
219                if (bt_vendor_cbacks)
220                {
221                    bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
222                }
223#else
224                hw_epilog_process();
225#endif
226            }
227            break;
228    }
229
230    return retval;
231}
232
233/** Closes the interface */
234static void cleanup( void )
235{
236    BTVNDDBG("cleanup");
237
238    upio_cleanup();
239
240    bt_vendor_cbacks = NULL;
241}
242
243// Entry point of DLib
244const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
245    sizeof(bt_vendor_interface_t),
246    init,
247    op,
248    cleanup
249};
250