1/*
2 * Copyright 2012 The Android Open Source Project
3 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
4 * Not a Contribution.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/******************************************************************************
20 *
21 *  Filename:      bt_vendor_qcom.c
22 *
23 *  Description:   vendor specific library implementation
24 *
25 ******************************************************************************/
26
27#define LOG_TAG "bt_vendor"
28#define BLUETOOTH_MAC_ADDR_BOOT_PROPERTY "ro.boot.btmacaddr"
29
30#include <utils/Log.h>
31#include <cutils/properties.h>
32#include <fcntl.h>
33#include <termios.h>
34#include "bt_vendor_qcom.h"
35#include "hci_uart.h"
36#include "hci_smd.h"
37#include <sys/socket.h>
38#include <cutils/sockets.h>
39#include <linux/un.h>
40#ifdef BT_NV_SUPPORT
41#include "bt_vendor_persist.h"
42#endif
43#include "hw_rome.h"
44
45#define WAIT_TIMEOUT 200000
46#define BT_VND_OP_GET_LINESPEED 12
47
48/******************************************************************************
49**  Externs
50******************************************************************************/
51extern int hw_config(int nState);
52
53extern int is_hw_ready();
54extern int rome_soc_init(int fd, char *bdaddr);
55extern int check_embedded_mode(int fd);
56extern int rome_get_addon_feature_list(int fd);
57extern int rome_ver;
58extern int enable_controller_log(int fd);
59/******************************************************************************
60**  Variables
61******************************************************************************/
62int pFd[2] = {0,};
63#ifdef BT_SOC_TYPE_ROME
64int ant_fd;
65#endif
66bt_vendor_callbacks_t *bt_vendor_cbacks = NULL;
67uint8_t vnd_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
68static int btSocType = BT_SOC_DEFAULT;
69static int rfkill_id = -1;
70static char *rfkill_state = NULL;
71bool enable_extldo = FALSE;
72
73static const tUSERIAL_CFG userial_init_cfg =
74{
75    (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1),
76    USERIAL_BAUD_115200
77};
78
79#if (HW_NEED_END_WITH_HCI_RESET == TRUE)
80void hw_epilog_process(void);
81#endif
82
83#ifdef WIFI_BT_STATUS_SYNC
84#include <string.h>
85#include <errno.h>
86#include <dlfcn.h>
87#include "cutils/properties.h"
88
89static const char WIFI_PROP_NAME[]    = "wlan.driver.status";
90static const char SERVICE_PROP_NAME[]    = "bluetooth.hsic_ctrl";
91static const char BT_STATUS_NAME[]    = "bluetooth.enabled";
92static const char WIFI_SERVICE_PROP[] = "wlan.hsic_ctrl";
93
94#define WIFI_BT_STATUS_LOCK    "/data/connectivity/wifi_bt_lock"
95int isInit=0;
96#endif /* WIFI_BT_STATUS_SYNC */
97bool is_soc_initialized(void);
98
99/******************************************************************************
100**  Local type definitions
101******************************************************************************/
102
103/******************************************************************************
104**  TODO: Cleanup to use header file. Declare externally used functions.
105******************************************************************************/
106int readTrpState();
107int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti);
108int userial_clock_operation(int fd, int cmd);
109int rome_soc_init(int fd, char *bdaddr);
110void lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity);
111int userial_vendor_get_baud(void);
112
113
114/******************************************************************************
115**  Functions
116******************************************************************************/
117#ifdef WIFI_BT_STATUS_SYNC
118int bt_semaphore_create(void)
119{
120    int fd;
121
122    fd = open(WIFI_BT_STATUS_LOCK, O_RDONLY);
123
124    if (fd < 0)
125        ALOGE("can't create file\n");
126
127    return fd;
128}
129
130int bt_semaphore_get(int fd)
131{
132    int ret;
133
134    if (fd < 0)
135        return -1;
136
137    ret = flock(fd, LOCK_EX);
138    if (ret != 0) {
139        ALOGE("can't hold lock: %s\n", strerror(errno));
140        return -1;
141    }
142
143    return ret;
144}
145
146int bt_semaphore_release(int fd)
147{
148    int ret;
149
150    if (fd < 0)
151        return -1;
152
153    ret = flock(fd, LOCK_UN);
154    if (ret != 0) {
155        ALOGE("can't release lock: %s\n", strerror(errno));
156        return -1;
157    }
158
159    return ret;
160}
161
162int bt_semaphore_destroy(int fd)
163{
164    if (fd < 0)
165        return -1;
166
167    return close (fd);
168}
169
170int bt_wait_for_service_done(void)
171{
172    char service_status[PROPERTY_VALUE_MAX];
173    int count = 30;
174
175    ALOGE("%s: check\n", __func__);
176
177    /* wait for service done */
178    while (count-- > 0) {
179        property_get(WIFI_SERVICE_PROP, service_status, NULL);
180
181        if (strcmp(service_status, "") != 0) {
182            usleep(200000);
183        } else {
184            break;
185        }
186    }
187
188    return 0;
189}
190
191#endif /* WIFI_BT_STATUS_SYNC */
192
193/** Get Bluetooth SoC type from system setting */
194static int get_bt_soc_type()
195{
196    int ret = 0;
197    char bt_soc_type[PROPERTY_VALUE_MAX];
198
199    ALOGI("bt-vendor : get_bt_soc_type");
200
201    ret = property_get("qcom.bluetooth.soc", bt_soc_type, NULL);
202    if (ret != 0) {
203        ALOGI("qcom.bluetooth.soc set to %s\n", bt_soc_type);
204        if (!strncasecmp(bt_soc_type, "rome", sizeof("rome"))) {
205            return BT_SOC_ROME;
206        }
207        else if (!strncasecmp(bt_soc_type, "ath3k", sizeof("ath3k"))) {
208            return BT_SOC_AR3K;
209        }
210        else {
211            ALOGI("qcom.bluetooth.soc not set, so using default.\n");
212            return BT_SOC_DEFAULT;
213        }
214    }
215    else {
216        ALOGE("%s: Failed to get soc type", __FUNCTION__);
217        ret = BT_SOC_DEFAULT;
218    }
219
220    return ret;
221}
222
223bool can_perform_action(char action) {
224    bool can_perform = false;
225    char ref_count[PROPERTY_VALUE_MAX];
226    int value, ret;
227
228    property_get("wc_transport.ref_count", ref_count, "0");
229
230    value = atoi(ref_count);
231    ALOGV("%s: ref_count: %s\n",__func__,  ref_count);
232
233    if(action == '1') {
234        ALOGV("%s: on : value is: %d", __func__, value);
235        if(value == 1)
236        {
237          if(is_soc_initialized() == true)
238          {
239            value++;
240            ALOGV("%s: on : value is incremented to : %d", __func__, value);
241          }
242        }
243        else
244        {
245             value++;
246        }
247        if (value == 1)
248           can_perform = true;
249        else if (value > 2) return false;
250    } else  {
251        ALOGV("%s: off : value is: %d", __func__, value);
252        value--;
253        if (value == 0)
254           can_perform = true;
255        else if (value < 0) return false;
256    }
257
258    snprintf(ref_count, 3, "%d", value);
259    ALOGV("%s: updated ref_count is: %s", __func__, ref_count);
260
261    ret  = property_set("wc_transport.ref_count", ref_count);
262    if (ret < 0) {
263        ALOGE("%s: Error while updating property: %d\n", __func__, ret);
264        return false;
265    }
266    ALOGV("%s returning %d", __func__, can_perform);
267    return can_perform;
268}
269
270void stop_hci_filter() {
271       char value[PROPERTY_VALUE_MAX] = {'\0'};
272       ALOGV("%s: Entry ", __func__);
273
274       property_get("wc_transport.start_hci", value, "false");
275
276       if (strcmp(value, "false") == 0) {
277           ALOGV("%s: hci_filter has been stopped already", __func__);
278           return;
279       }
280
281       property_set("wc_transport.start_hci", "false");
282       property_set("wc_transport.hci_filter_status", "0");
283       ALOGV("%s: Exit ", __func__);
284}
285
286void start_hci_filter() {
287       ALOGV("%s: Entry ", __func__);
288       int i, init_success = 0;
289       char value[PROPERTY_VALUE_MAX] = {'\0'};
290
291
292       property_get("wc_transport.start_hci", value, false);
293
294       if (strcmp(value, "true") == 0) {
295           ALOGV("%s: hci_filter has been started already", __func__);
296           return;
297       }
298
299       property_set("wc_transport.hci_filter_status", "0");
300
301       property_set("wc_transport.start_hci", "true");
302       //sched_yield();
303       for(i=0; i<45; i++) {
304          property_get("wc_transport.hci_filter_status", value, "0");
305          if (strcmp(value, "1") == 0) {
306               init_success = 1;
307               break;
308           } else {
309               usleep(WAIT_TIMEOUT);
310           }
311        }
312        ALOGV("start_hcifilter status:%d after %f seconds \n", init_success, 0.2*i);
313
314        ALOGV("%s: Exit ", __func__);
315}
316
317/** Bluetooth Controller power up or shutdown */
318static int bt_powerup(int en )
319{
320    char rfkill_type[64], *enable_ldo_path = NULL;
321    char type[16], enable_ldo[6];
322    int fd, size, i, ret, fd_ldo;
323
324    char disable[PROPERTY_VALUE_MAX];
325    char state;
326    char on = (en)?'1':'0';
327
328#ifdef WIFI_BT_STATUS_SYNC
329    char wifi_status[PROPERTY_VALUE_MAX];
330    int lock_fd;
331#endif /*WIFI_BT_STATUS_SYNC*/
332
333    ALOGI("bt_powerup: %c", on);
334
335    /* Check if rfkill has been disabled */
336    ret = property_get("ro.rfkilldisabled", disable, "0");
337    if (!ret ){
338        ALOGE("Couldn't get ro.rfkilldisabled (%d)", ret);
339        return -1;
340    }
341    /* In case rfkill disabled, then no control power*/
342    if (strcmp(disable, "1") == 0) {
343        ALOGI("ro.rfkilldisabled : %s", disable);
344        return -1;
345    }
346
347#ifdef WIFI_BT_STATUS_SYNC
348    lock_fd = bt_semaphore_create();
349    bt_semaphore_get(lock_fd);
350    bt_wait_for_service_done();
351#endif
352
353    /* Assign rfkill_id and find bluetooth rfkill state path*/
354    for(i=0;(rfkill_id == -1) && (rfkill_state == NULL);i++)
355    {
356        snprintf(rfkill_type, sizeof(rfkill_type), "/sys/class/rfkill/rfkill%d/type", i);
357        if ((fd = open(rfkill_type, O_RDONLY)) < 0)
358        {
359            ALOGE("open(%s) failed: %s (%d)\n", rfkill_type, strerror(errno), errno);
360
361#ifdef WIFI_BT_STATUS_SYNC
362            bt_semaphore_release(lock_fd);
363            bt_semaphore_destroy(lock_fd);
364#endif
365            return -1;
366        }
367
368        size = read(fd, &type, sizeof(type));
369        close(fd);
370
371        if ((size >= 9) && !memcmp(type, "bluetooth", 9))
372        {
373            asprintf(&rfkill_state, "/sys/class/rfkill/rfkill%d/state", rfkill_id = i);
374            break;
375        }
376    }
377
378    /* Get rfkill State to control */
379    if (rfkill_state != NULL)
380    {
381        if ((fd = open(rfkill_state, O_RDWR)) < 0)
382        {
383            ALOGE("open(%s) for write failed: %s (%d)",rfkill_state, strerror(errno), errno);
384#ifdef WIFI_BT_STATUS_SYNC
385            bt_semaphore_release(lock_fd);
386            bt_semaphore_destroy(lock_fd);
387#endif
388
389            return -1;
390        }
391    }
392#ifdef BT_SOC_TYPE_ROME
393    if(can_perform_action(on) == false) {
394        ALOGE("%s:can't perform action as it is being used by other clients", __func__);
395#ifdef WIFI_BT_STATUS_SYNC
396        bt_semaphore_release(lock_fd);
397        bt_semaphore_destroy(lock_fd);
398#endif
399        goto done;
400    }
401#endif
402    ret = asprintf(&enable_ldo_path, "/sys/class/rfkill/rfkill%d/device/extldo", rfkill_id);
403    if( (ret < 0 ) || (enable_ldo_path == NULL) )
404    {
405        ALOGE("Memory Allocation failure");
406        return -1;
407    }
408    if ((fd_ldo = open(enable_ldo_path, O_RDWR)) < 0) {
409        ALOGE("open(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno);
410        return -1;
411    }
412    size = read(fd_ldo, &enable_ldo, sizeof(enable_ldo));
413    close(fd_ldo);
414    if (size <= 0) {
415        ALOGE("read(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno);
416        return -1;
417    }
418    if (!memcmp(enable_ldo, "true", 4)) {
419        ALOGI("External LDO has been configured");
420        enable_extldo = TRUE;
421    }
422
423    ALOGE("Write %c to rfkill\n", on);
424
425    /* Write value to control rfkill */
426    if ((size = write(fd, &on, 1)) < 0) {
427        ALOGE("write(%s) failed: %s (%d)",rfkill_state, strerror(errno),errno);
428#ifdef WIFI_BT_STATUS_SYNC
429        bt_semaphore_release(lock_fd);
430        bt_semaphore_destroy(lock_fd);
431#endif
432        return -1;
433    }
434#ifdef BT_SOC_TYPE_ROME
435    if(on == '0'){
436        ALOGE("Stopping HCI filter as part of CTRL:OFF");
437        stop_hci_filter();
438        property_set("wc_transport.soc_initialized", "0");
439    }
440#endif
441#ifdef WIFI_BT_STATUS_SYNC
442    /* query wifi status */
443    property_get(WIFI_PROP_NAME, wifi_status, "");
444
445    ALOGE("bt get wifi status: %s, isInit: %d\n",  wifi_status, isInit);
446
447    /* If wlan driver is not loaded, and bt is changed from off => on */
448    if (strncmp(wifi_status, "unloaded", strlen("unloaded")) == 0 || strlen(wifi_status) == 0) {
449        if (on == '1') {
450            ALOGI("%s: BT_VND_PWR_ON\n", __func__);
451            if(property_set(SERVICE_PROP_NAME, "load_wlan") < 0) {
452                ALOGE("%s Property setting failed", SERVICE_PROP_NAME);
453                close(fd);
454                bt_semaphore_release(lock_fd);
455                bt_semaphore_destroy(lock_fd);
456                return -1;
457            }
458        }
459        else if (isInit == 0 && on == '0') {
460            ALOGI("%s: BT_VND_PWR_OFF\n", __func__);
461            if(property_set(SERVICE_PROP_NAME, "unbind_hsic") < 0) {
462                ALOGE("%s Property setting failed", SERVICE_PROP_NAME);
463                close(fd);
464                bt_semaphore_release(lock_fd);
465                bt_semaphore_destroy(lock_fd);
466                return -1;
467            }
468       }
469    }
470
471    if (isInit == 0 && on == '0')
472        property_set(BT_STATUS_NAME, "false");
473    else if (on == '1')
474        property_set(BT_STATUS_NAME, "true");
475
476    bt_semaphore_release(lock_fd);
477    bt_semaphore_destroy(lock_fd);
478#endif /* WIFI_BT_STATUS_SYNC */
479
480done:
481    if (fd >= 0)
482        close(fd);
483
484    return 0;
485}
486
487/*****************************************************************************
488**
489**   BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS
490**
491*****************************************************************************/
492
493static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr)
494{
495    int i;
496
497    ALOGI("bt-vendor : init");
498
499    if (p_cb == NULL)
500    {
501        ALOGE("init failed with no user callbacks!");
502        return -1;
503    }
504
505    if ((btSocType = get_bt_soc_type()) < 0) {
506        ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__);
507        return -1;
508    }
509
510    switch(btSocType)
511    {
512        case BT_SOC_ROME:
513        case BT_SOC_AR3K:
514            ALOGI("bt-vendor : Initializing UART transport layer");
515            userial_vendor_init();
516            break;
517        case BT_SOC_DEFAULT:
518            break;
519        default:
520            ALOGE("Unknown btSocType: 0x%x", btSocType);
521            break;
522    }
523
524    /* store reference to user callbacks */
525    bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb;
526
527    /* Copy BD Address as little-endian byte order */
528    if(local_bdaddr)
529        for(i=0;i<6;i++)
530            vnd_local_bd_addr[i] = *(local_bdaddr + (5-i));
531
532    ALOGI("%s: Local BD Address : %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", __FUNCTION__,
533                                                vnd_local_bd_addr[0],
534                                                vnd_local_bd_addr[1],
535                                                vnd_local_bd_addr[2],
536                                                vnd_local_bd_addr[3],
537                                                vnd_local_bd_addr[4],
538                                                vnd_local_bd_addr[5]);
539
540#ifdef WIFI_BT_STATUS_SYNC
541    isInit = 1;
542#endif /* WIFI_BT_STATUS_SYNC */
543
544    return 0;
545}
546
547#ifdef READ_BT_ADDR_FROM_PROP
548static bool validate_tok(char* bdaddr_tok) {
549    int i = 0;
550    bool ret;
551
552    if (strlen(bdaddr_tok) != 2) {
553        ret = FALSE;
554        ALOGE("Invalid token length");
555    } else {
556        ret = TRUE;
557        for (i=0; i<2; i++) {
558            if ((bdaddr_tok[i] >= '0' && bdaddr_tok[i] <= '9') ||
559                (bdaddr_tok[i] >= 'A' && bdaddr_tok[i] <= 'F') ||
560                (bdaddr_tok[i] >= 'a' && bdaddr_tok[i] <= 'f')) {
561                ret = TRUE;
562                ALOGV("%s: tok %s @ %d is good", __func__, bdaddr_tok, i);
563             } else {
564                ret = FALSE;
565                ALOGE("invalid character in tok: %s at ind: %d", bdaddr_tok, i);
566                break;
567             }
568        }
569    }
570    return ret;
571}
572#endif /*READ_BT_ADDR_FROM_PROP*/
573
574int connect_to_local_socket(char* name) {
575       socklen_t len; int sk = -1;
576
577       ALOGE("%s: ACCEPT ", __func__);
578       sk  = socket(AF_LOCAL, SOCK_STREAM, 0);
579       if (sk < 0) {
580           ALOGE("Socket creation failure");
581           return -1;
582       }
583
584        if(socket_local_client_connect(sk, name,
585            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0)
586        {
587             ALOGE("failed to connect (%s)", strerror(errno));
588             close(sk);
589             sk = -1;
590        } else {
591                ALOGE("%s: Connection succeeded\n", __func__);
592        }
593        return sk;
594}
595
596bool is_soc_initialized() {
597    bool init = false;
598    char init_value[PROPERTY_VALUE_MAX];
599    int ret;
600
601    ALOGI("bt-vendor : is_soc_initialized");
602
603    ret = property_get("wc_transport.soc_initialized", init_value, NULL);
604    if (ret != 0) {
605        ALOGI("wc_transport.soc_initialized set to %s\n", init_value);
606        if (!strncasecmp(init_value, "1", sizeof("1"))) {
607            init = true;
608        }
609    }
610    else {
611        ALOGE("%s: Failed to get wc_transport.soc_initialized", __FUNCTION__);
612    }
613
614    return init;
615}
616
617
618/** Requested operations */
619static int op(bt_vendor_opcode_t opcode, void *param)
620{
621    int retval = 0;
622    int nCnt = 0;
623    int nState = -1;
624    bool is_ant_req = false;
625    char wipower_status[PROPERTY_VALUE_MAX];
626    char bt_version[PROPERTY_VALUE_MAX];
627    bool ignore_boot_prop = TRUE;
628#ifdef READ_BT_ADDR_FROM_PROP
629    int i = 0;
630    static char bd_addr[PROPERTY_VALUE_MAX];
631    uint8_t local_bd_addr_from_prop[6];
632    char* tok;
633#endif
634    bool skip_init = true;
635
636    ALOGV("bt-vendor : op for %d", opcode);
637
638    switch(opcode)
639    {
640        case BT_VND_OP_POWER_CTRL:
641            {
642                nState = *(int *) param;
643                ALOGI("bt-vendor : BT_VND_OP_POWER_CTRL: %s",
644                        (nState == BT_VND_PWR_ON)? "On" : "Off" );
645
646                switch(btSocType)
647                {
648                    case BT_SOC_DEFAULT:
649                        if (readTrpState())
650                        {
651                           ALOGI("bt-vendor : resetting BT status");
652                           hw_config(BT_VND_PWR_OFF);
653                        }
654                        retval = hw_config(nState);
655                        if(nState == BT_VND_PWR_ON
656                           && retval == 0
657                           && is_hw_ready() == TRUE){
658                            retval = 0;
659                        }
660                        else {
661                            retval = -1;
662                        }
663                        break;
664                    case BT_SOC_ROME:
665                    case BT_SOC_AR3K:
666                        /* BT Chipset Power Control through Device Tree Node */
667                        retval = bt_powerup(nState);
668                    default:
669                        break;
670                }
671            }
672            break;
673
674        case BT_VND_OP_FW_CFG:
675            {
676                // call hciattach to initalize the stack
677                if(bt_vendor_cbacks){
678                   ALOGI("Bluetooth Firmware and transport layer are initialized");
679                   bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
680                }
681                else{
682                   ALOGE("bt_vendor_cbacks is null");
683                   ALOGE("Error : hci, smd initialization Error");
684                   retval = -1;
685                }
686            }
687            break;
688
689        case BT_VND_OP_SCO_CFG:
690            {
691                if (bt_vendor_cbacks)
692                    bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
693            }
694            break;
695#ifdef BT_SOC_TYPE_ROME
696#ifdef ENABLE_ANT
697        case BT_VND_OP_ANT_USERIAL_OPEN:
698                ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_OPEN");
699                is_ant_req = true;
700                //fall through
701#endif
702#endif
703        case BT_VND_OP_USERIAL_OPEN:
704            {
705                int (*fd_array)[] = (int (*)[]) param;
706                int fd = -1, fd_filter = -1;
707                ALOGI("bt-vendor : BT_VND_OP_USERIAL_OPEN");
708                switch(btSocType)
709                {
710                    case BT_SOC_DEFAULT:
711                        {
712                            if(bt_hci_init_transport(pFd) != -1){
713                                int (*fd_array)[] = (int (*) []) param;
714
715                                    (*fd_array)[CH_CMD] = pFd[0];
716                                    (*fd_array)[CH_EVT] = pFd[0];
717                                    (*fd_array)[CH_ACL_OUT] = pFd[1];
718                                    (*fd_array)[CH_ACL_IN] = pFd[1];
719                            }
720                            else {
721                                retval = -1;
722                                break;
723                            }
724                            retval = 2;
725                        }
726                        break;
727                    case BT_SOC_AR3K:
728                        {
729                            int idx;
730                            fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
731                            if (fd != -1) {
732                                for (idx=0; idx < CH_MAX; idx++)
733                                    (*fd_array)[idx] = fd;
734                                retval = 1;
735                            }
736                            else {
737                                retval = -1;
738                                break;
739                            }
740
741                            /* Vendor Specific Process should happened during userial_open process
742                                After userial_open, rx read thread is running immediately,
743                                so it will affect VS event read process.
744                            */
745                            if(ath3k_init(fd,3000000,115200,NULL,&vnd_userial.termios)<0)
746                                retval = -1;
747                        }
748                        break;
749                    case BT_SOC_ROME:
750                        {
751                            int idx;
752                            property_get("persist.BT3_2.version", bt_version, false);
753                            if (!is_soc_initialized()) {
754                                fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
755                                if (fd < 0) {
756                                    ALOGE("userial_vendor_open returns err");
757                                    retval = -1;
758                                } else {
759                                    /* Clock on */
760                                    userial_clock_operation(fd, USERIAL_OP_CLK_ON);
761                                    ALOGD("userial clock on");
762                                    if(strcmp(bt_version, "true") == 0) {
763                                        property_get("ro.bluetooth.wipower", wipower_status, false);
764                                        if(strcmp(wipower_status, "true") == 0) {
765                                            check_embedded_mode(fd);
766                                        } else {
767                                            ALOGI("Wipower not enabled");
768                                        }
769                                    }
770                                    ALOGV("rome_soc_init is started");
771                                    property_set("wc_transport.soc_initialized", "0");
772#ifdef READ_BT_ADDR_FROM_PROP
773                                    /*Give priority to read BD address from boot property*/
774                                    ignore_boot_prop = FALSE;
775                                    if (property_get(BLUETOOTH_MAC_ADDR_BOOT_PROPERTY, bd_addr, NULL)) {
776                                        ALOGV("BD address read from Boot property: %s\n", bd_addr);
777                                        tok =  strtok(bd_addr, ":");
778                                        while (tok != NULL) {
779                                            ALOGV("bd add [%d]: %d ", i, strtol(tok, NULL, 16));
780                                            if (i>=6) {
781                                                ALOGE("bd property of invalid length");
782                                                ignore_boot_prop = TRUE;
783                                                break;
784                                            }
785                                            if (!validate_tok(tok)) {
786                                                ALOGE("Invalid token in BD address");
787                                                ignore_boot_prop = TRUE;
788                                                break;
789                                            }
790                                            local_bd_addr_from_prop[5-i] = strtol(tok, NULL, 16);
791                                            tok = strtok(NULL, ":");
792                                            i++;
793                                        }
794                                        if (i == 6 && !ignore_boot_prop) {
795                                            ALOGV("Valid BD address read from prop");
796                                            memcpy(vnd_local_bd_addr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr));
797                                            ignore_boot_prop = FALSE;
798                                        } else {
799                                            ALOGE("There are not enough tokens in BD addr");
800                                            ignore_boot_prop = TRUE;
801                                        }
802                                    } else {
803                                        ALOGE("BD address boot property not set");
804                                        ignore_boot_prop = TRUE;
805                                    }
806#endif //READ_BT_ADDR_FROM_PROP
807#ifdef BT_NV_SUPPORT
808                                    /* Always read BD address from NV file */
809                                    if(ignore_boot_prop && !bt_vendor_nv_read(1, vnd_local_bd_addr))
810                                    {
811                                       /* Since the BD address is configured in boot time We should not be here */
812                                       ALOGI("Failed to read BD address. Use the one from bluedroid stack/ftm");
813                                    }
814#endif //BT_NV_SUPPORT
815                                    if(rome_soc_init(fd,vnd_local_bd_addr)<0) {
816                                        retval = -1;
817                                    } else {
818                                        ALOGV("rome_soc_init is completed");
819                                        property_set("wc_transport.soc_initialized", "1");
820                                        skip_init = false;
821                                    }
822                                }
823                            }
824
825                            property_set("wc_transport.clean_up","0");
826                            if (retval != -1) {
827#ifdef BT_SOC_TYPE_ROME
828                                 start_hci_filter();
829                                 if (is_ant_req) {
830                                     ALOGV("connect to ant channel");
831                                     ant_fd = fd_filter = connect_to_local_socket("ant_sock");
832                                 }
833                                 else
834#endif
835                                 {
836                                     ALOGV("connect to bt channel");
837                                     vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock");
838                                 }
839
840                                 if (fd_filter != -1) {
841                                     ALOGV("%s: received the socket fd: %d is_ant_req: %d\n",
842                                                                 __func__, fd_filter, is_ant_req);
843                                     if((strcmp(bt_version, "true") == 0) && !is_ant_req) {
844                                         if (rome_ver >= ROME_VER_3_0) {
845                                             /*  get rome supported feature request */
846                                             ALOGE("%s: %x08 %0x", __FUNCTION__,rome_ver, ROME_VER_3_0);
847                                             rome_get_addon_feature_list(fd_filter);
848                                         }
849                                     }
850
851                                     if (!skip_init) {
852                                         /* skip if already sent */
853                                         enable_controller_log(fd_filter);
854                                         skip_init = true;
855                                     }
856
857                                     for (idx=0; idx < CH_MAX; idx++)
858                                         (*fd_array)[idx] = fd_filter;
859                                     retval = 1;
860                                 }
861                                 else {
862                                     retval = -1;
863                                 }
864                             }
865
866                             if (fd >= 0) {
867                                 userial_clock_operation(fd, USERIAL_OP_CLK_OFF);
868                                 close(fd);
869                             }
870                        }
871                        break;
872                    default:
873                        ALOGE("Unknown btSocType: 0x%x", btSocType);
874                        break;
875                }
876            }
877            break;
878#ifdef BT_SOC_TYPE_ROME
879#ifdef ENABLE_ANT
880        case BT_VND_OP_ANT_USERIAL_CLOSE:
881            {
882                ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_CLOSE");
883                property_set("wc_transport.clean_up","1");
884                if (ant_fd != -1) {
885                    ALOGE("closing ant_fd");
886                    close(ant_fd);
887                    ant_fd = -1;
888                }
889            }
890            break;
891#endif
892#endif
893        case BT_VND_OP_USERIAL_CLOSE:
894            {
895                ALOGI("bt-vendor : BT_VND_OP_USERIAL_CLOSE btSocType: %d", btSocType);
896                switch(btSocType)
897                {
898                    case BT_SOC_DEFAULT:
899                         bt_hci_deinit_transport(pFd);
900                         break;
901
902                     case BT_SOC_ROME:
903                     case BT_SOC_AR3K:
904                        property_set("wc_transport.clean_up","1");
905                        userial_vendor_close();
906                        break;
907                    default:
908                        ALOGE("Unknown btSocType: 0x%x", btSocType);
909                        break;
910                }
911            }
912            break;
913
914        case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
915            if (btSocType ==  BT_SOC_AR3K) {
916                uint32_t *timeout_ms = (uint32_t *) param;
917                *timeout_ms = 1000;
918            }
919            break;
920
921        case BT_VND_OP_LPM_SET_MODE:
922            if(btSocType ==  BT_SOC_AR3K) {
923                uint8_t *mode = (uint8_t *) param;
924
925                if (*mode) {
926                    lpm_set_ar3k(UPIO_LPM_MODE, UPIO_ASSERT, 0);
927                }
928                else {
929                    lpm_set_ar3k(UPIO_LPM_MODE, UPIO_DEASSERT, 0);
930                }
931                if (bt_vendor_cbacks )
932                    bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
933            }
934            else {
935                if (bt_vendor_cbacks)
936                    bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
937            }
938            break;
939
940        case BT_VND_OP_LPM_WAKE_SET_STATE:
941            {
942                switch(btSocType)
943                {
944                    case BT_SOC_ROME:
945                        {
946                            uint8_t *state = (uint8_t *) param;
947                            uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
948                                BT_VND_LPM_WAKE_ASSERT : BT_VND_LPM_WAKE_DEASSERT;
949
950                            if (wake_assert == 0)
951                                ALOGV("ASSERT: Waking up BT-Device");
952                            else if (wake_assert == 1)
953                                ALOGV("DEASSERT: Allowing BT-Device to Sleep");
954
955#ifdef QCOM_BT_SIBS_ENABLE
956                            if(bt_vendor_cbacks){
957                                ALOGI("Invoking HCI H4 callback function");
958                               bt_vendor_cbacks->lpm_set_state_cb(wake_assert);
959                            }
960#endif
961                        }
962                        break;
963                    case BT_SOC_AR3K:
964                        {
965                            uint8_t *state = (uint8_t *) param;
966                            uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
967                                                        UPIO_ASSERT : UPIO_DEASSERT;
968                            lpm_set_ar3k(UPIO_BT_WAKE, wake_assert, 0);
969                        }
970                    case BT_SOC_DEFAULT:
971                        break;
972                    default:
973                        ALOGE("Unknown btSocType: 0x%x", btSocType);
974                        break;
975                    }
976            }
977            break;
978        case BT_VND_OP_EPILOG:
979            {
980#if (HW_NEED_END_WITH_HCI_RESET == FALSE)
981                if (bt_vendor_cbacks)
982                {
983                    bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
984                }
985#else
986                switch(btSocType)
987                {
988                  case BT_SOC_ROME:
989                       {
990                           char value[PROPERTY_VALUE_MAX] = {'\0'};
991                           property_get("wc_transport.hci_filter_status", value, "0");
992                           if(is_soc_initialized()&& (strcmp(value,"1") == 0))
993                           {
994                              hw_epilog_process();
995                           }
996                           else
997                           {
998                             if (bt_vendor_cbacks)
999                               {
1000                                 ALOGE("vendor lib epilog process aborted");
1001                                 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
1002                               }
1003                           }
1004                       }
1005                       break;
1006                  default:
1007                       hw_epilog_process();
1008                       break;
1009                }
1010#endif
1011            }
1012            break;
1013        case BT_VND_OP_GET_LINESPEED:
1014            {
1015                retval = -1;
1016                switch(btSocType)
1017                {
1018                    case BT_SOC_ROME:
1019                        if(!is_soc_initialized()) {
1020                            ALOGE("BT_VND_OP_GET_LINESPEED: error"
1021                            " - transport driver not initialized!");
1022                        }else {
1023                            retval = 3000000;
1024                        }
1025                        break;
1026                    default:
1027                        retval = userial_vendor_get_baud();
1028                        break;
1029                 }
1030                break;
1031            }
1032    }
1033
1034    return retval;
1035}
1036
1037static void ssr_cleanup(void) {
1038    int pwr_state=BT_VND_PWR_OFF;
1039
1040    ALOGI("ssr_cleanup");
1041
1042    if ((btSocType = get_bt_soc_type()) < 0) {
1043        ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__);
1044        return;
1045    }
1046
1047    if (btSocType == BT_SOC_ROME) {
1048#ifdef BT_SOC_TYPE_ROME
1049#ifdef ENABLE_ANT
1050        /*Close both ANT channel*/
1051        op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL);
1052#endif
1053#endif
1054        /*Close both ANT channel*/
1055        op(BT_VND_OP_USERIAL_CLOSE, NULL);
1056        /*CTRL OFF twice to make sure hw
1057         * turns off*/
1058        op(BT_VND_OP_POWER_CTRL, &pwr_state);
1059
1060    }
1061
1062#ifdef BT_SOC_TYPE_ROME
1063    /*Generally switching of chip should be enough*/
1064    op(BT_VND_OP_POWER_CTRL, &pwr_state);
1065#endif
1066    bt_vendor_cbacks = NULL;
1067}
1068
1069
1070/** Closes the interface */
1071static void cleanup( void )
1072{
1073    ALOGI("cleanup");
1074    bt_vendor_cbacks = NULL;
1075
1076#ifdef WIFI_BT_STATUS_SYNC
1077    isInit = 0;
1078#endif /* WIFI_BT_STATUS_SYNC */
1079}
1080
1081// Entry point of DLib
1082const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
1083    sizeof(bt_vendor_interface_t),
1084    init,
1085    op,
1086    cleanup,
1087    ssr_cleanup
1088};
1089