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 
48 void hw_config_start(void);
49 uint8_t hw_lpm_enable(uint8_t turn_on);
50 uint32_t hw_lpm_get_idle_timeout(void);
51 void hw_lpm_set_wake_state(uint8_t wake_assert);
52 #if (SCO_CFG_INCLUDED == TRUE)
53 void hw_sco_config(void);
54 #endif
55 void vnd_load_conf(const char *p_path);
56 #if (HW_END_WITH_HCI_RESET == TRUE)
57 void hw_epilog_process(void);
58 #endif
59 
60 /******************************************************************************
61 **  Variables
62 ******************************************************************************/
63 
64 bt_vendor_callbacks_t *bt_vendor_cbacks = NULL;
65 uint8_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 
75 static 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 
init(const bt_vendor_callbacks_t * p_cb,unsigned char * local_bdaddr)91 static 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 */
op(bt_vendor_opcode_t opcode,void * param)130 static 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 */
cleanup(void)234 static void cleanup( void )
235 {
236     BTVNDDBG("cleanup");
237 
238     upio_cleanup();
239 
240     bt_vendor_cbacks = NULL;
241 }
242 
243 // Entry point of DLib
244 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
245     sizeof(bt_vendor_interface_t),
246     init,
247     op,
248     cleanup
249 };
250