1ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev/*
2ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev * Copyright 2012 The Android Open Source Project
3ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev *
4ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License");
5ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev * you may not use this file except in compliance with the License.
6ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev * You may obtain a copy of the License at
7ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev *
8ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev *      http://www.apache.org/licenses/LICENSE-2.0
9ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev *
10ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev * Unless required by applicable law or agreed to in writing, software
11ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS,
12ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev * See the License for the specific language governing permissions and
14ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev * limitations under the License.
15ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev */
16ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
17ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev/******************************************************************************
18ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev *
19ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev *  Filename:      bt_vendor_brcm.c
20ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev *
21ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev *  Description:   Broadcom vendor specific library implementation
22ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev *
23ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev ******************************************************************************/
24ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
25ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev#define LOG_TAG "bt_vendor"
26ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
27ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev#include <utils/Log.h>
28ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev#include <fcntl.h>
29ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev#include <termios.h>
30ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev#include "bt_vendor_qcom.h"
31ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev#include "userial_vendor.h"
32ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
33ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev/******************************************************************************
34ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev**  Externs
35ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev******************************************************************************/
36ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchevextern int hw_config(int nState);
37ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
38ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchevextern int is_hw_ready();
39ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
40ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev/******************************************************************************
41ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev**  Variables
42ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev******************************************************************************/
43ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchevint pFd[2] = {0,};
44ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchevbt_hci_transport_device_type bt_hci_transport_device;
45ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
46ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchevbt_vendor_callbacks_t *bt_vendor_cbacks = NULL;
47ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchevuint8_t vnd_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
48ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
495faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie#if (HW_NEED_END_WITH_HCI_RESET == TRUE)
505faa2a529b07625c341ee8cee4040c87e030f050Matthew Xievoid hw_epilog_process(void);
515faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie#endif
525faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie
535faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie
54ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev/******************************************************************************
55ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev**  Local type definitions
56ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev******************************************************************************/
57ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
58ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
59ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev/******************************************************************************
60ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev**  Functions
61ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev******************************************************************************/
62ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
63ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev/*****************************************************************************
64ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev**
65ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev**   BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS
66ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev**
67ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev*****************************************************************************/
68ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
69ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchevstatic int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr)
70ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev{
71ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    ALOGI("bt-vendor : init");
72ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
73ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    if (p_cb == NULL)
74ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    {
75ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev        ALOGE("init failed with no user callbacks!");
76ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev        return -1;
77ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    }
78ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
79ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    //userial_vendor_init();
80ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    //upio_init();
81ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
82ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    //vnd_load_conf(VENDOR_LIB_CONF_FILE);
83ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
84ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    /* store reference to user callbacks */
85ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb;
86ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
87ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    /* This is handed over from the stack */
88ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    memcpy(vnd_local_bd_addr, local_bdaddr, 6);
89ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
90ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    return 0;
91ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev}
92ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
93ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
94ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev/** Requested operations */
95ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchevstatic int op(bt_vendor_opcode_t opcode, void *param)
96ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev{
97ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    int retval = 0;
98ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    int nCnt = 0;
99ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    int nState = -1;
100ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
101ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    ALOGV("bt-vendor : op for %d", opcode);
102ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
103ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    switch(opcode)
104ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    {
105ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev        case BT_VND_OP_POWER_CTRL:
106ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            {
107ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                nState = *(int *) param;
108ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                retval = hw_config(nState);
109ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                if(nState == BT_VND_PWR_ON
110ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                   && retval == 0
111ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                   && is_hw_ready() == TRUE){
112ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                    retval = 0;
113ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                }
114ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                else {
115ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                    retval = -1;
116ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                }
117ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            }
118ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            break;
119ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
120ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev        case BT_VND_OP_FW_CFG:
121ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            {
122ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                // call hciattach to initalize the stack
123ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                if(bt_vendor_cbacks){
124ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                   ALOGI("Bluetooth Firmware and smd is initialized");
125ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                   bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
126ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                }
127ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                else{
128ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                   ALOGE("Error : hci, smd initialization Error");
129ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                   bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
130ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                }
131ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            }
132ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            break;
133ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
134ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev        case BT_VND_OP_SCO_CFG:
135ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            {
136ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
137ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            }
138ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            break;
139ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
140ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev        case BT_VND_OP_USERIAL_OPEN:
141ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            {
142ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                if(bt_hci_init_transport(pFd) != -1){
143ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                    int (*fd_array)[] = (int (*) []) param;
144ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
145ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                        (*fd_array)[CH_CMD] = pFd[0];
146ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                        (*fd_array)[CH_EVT] = pFd[0];
147ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                        (*fd_array)[CH_ACL_OUT] = pFd[1];
148ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                        (*fd_array)[CH_ACL_IN] = pFd[1];
149ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                }
150ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                else {
151ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                    retval = -1;
152ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                    break;
153ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                }
154ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                retval = 2;
155ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            }
156ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            break;
157ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
158ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev        case BT_VND_OP_USERIAL_CLOSE:
159ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            {
160ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                 bt_hci_deinit_transport(pFd);
161ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            }
162ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            break;
163ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
164ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev        case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
165ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            break;
166ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
167ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev        case BT_VND_OP_LPM_SET_MODE:
168ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            {
169ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev                bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
170ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            }
171ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            break;
172ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
173ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev        case BT_VND_OP_LPM_WAKE_SET_STATE:
174ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev            break;
1755faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie        case BT_VND_OP_EPILOG:
1765faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie            {
1775faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie#if (HW_NEED_END_WITH_HCI_RESET == FALSE)
1785faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie                if (bt_vendor_cbacks)
1795faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie                {
1805faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie                    bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
1815faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie                }
1825faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie#else
1835faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie                hw_epilog_process();
1845faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie#endif
1855faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie            }
1865faa2a529b07625c341ee8cee4040c87e030f050Matthew Xie            break;
187ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    }
188ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
189ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    return retval;
190ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev}
191ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
192ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev/** Closes the interface */
193ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchevstatic void cleanup( void )
194ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev{
195ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    ALOGI("cleanup");
196ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
197ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    //upio_cleanup();
198ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
199ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    bt_vendor_cbacks = NULL;
200ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev}
201ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev
202ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev// Entry point of DLib
203ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchevconst bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
204ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    sizeof(bt_vendor_interface_t),
205ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    init,
206ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    op,
207ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev    cleanup
208ad7eab092dae95101a71f1dd758086ad042dcf1dIliyan Malchev};
209