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 ******************************************************************************/
51 extern int hw_config(int nState);
52 
53 extern int is_hw_ready();
54 extern int rome_soc_init(int fd, char *bdaddr);
55 extern int check_embedded_mode(int fd);
56 extern int rome_get_addon_feature_list(int fd);
57 extern int rome_ver;
58 extern int enable_controller_log(int fd);
59 /******************************************************************************
60 **  Variables
61 ******************************************************************************/
62 int pFd[2] = {0,};
63 #ifdef BT_SOC_TYPE_ROME
64 int ant_fd;
65 #endif
66 bt_vendor_callbacks_t *bt_vendor_cbacks = NULL;
67 uint8_t vnd_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
68 static int btSocType = BT_SOC_DEFAULT;
69 static int rfkill_id = -1;
70 static char *rfkill_state = NULL;
71 bool enable_extldo = FALSE;
72 
73 static 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)
80 void 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 
89 static const char WIFI_PROP_NAME[]    = "wlan.driver.status";
90 static const char SERVICE_PROP_NAME[]    = "bluetooth.hsic_ctrl";
91 static const char BT_STATUS_NAME[]    = "bluetooth.enabled";
92 static const char WIFI_SERVICE_PROP[] = "wlan.hsic_ctrl";
93 
94 #define WIFI_BT_STATUS_LOCK    "/data/connectivity/wifi_bt_lock"
95 int isInit=0;
96 #endif /* WIFI_BT_STATUS_SYNC */
97 bool 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 ******************************************************************************/
106 int readTrpState();
107 int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti);
108 int userial_clock_operation(int fd, int cmd);
109 int rome_soc_init(int fd, char *bdaddr);
110 void lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity);
111 int userial_vendor_get_baud(void);
112 
113 
114 /******************************************************************************
115 **  Functions
116 ******************************************************************************/
117 #ifdef WIFI_BT_STATUS_SYNC
bt_semaphore_create(void)118 int 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 
bt_semaphore_get(int fd)130 int 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 
bt_semaphore_release(int fd)146 int 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 
bt_semaphore_destroy(int fd)162 int bt_semaphore_destroy(int fd)
163 {
164     if (fd < 0)
165         return -1;
166 
167     return close (fd);
168 }
169 
bt_wait_for_service_done(void)170 int 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 */
get_bt_soc_type()194 static 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 
can_perform_action(char action)223 bool 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 
stop_hci_filter()270 void 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 
start_hci_filter()286 void 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 */
bt_powerup(int en)318 static 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 
480 done:
481     if (fd >= 0)
482         close(fd);
483 
484     return 0;
485 }
486 
487 /*****************************************************************************
488 **
489 **   BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS
490 **
491 *****************************************************************************/
492 
init(const bt_vendor_callbacks_t * p_cb,unsigned char * local_bdaddr)493 static 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
validate_tok(char * bdaddr_tok)548 static 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 
connect_to_local_socket(char * name)574 int 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 
is_soc_initialized()596 bool 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 */
op(bt_vendor_opcode_t opcode,void * param)619 static 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                         if(nState == BT_VND_PWR_ON && property_get_bool("wc_transport.vnd_power", 0)) {
668                                 bt_powerup(BT_VND_PWR_OFF);
669                         }
670                         retval = bt_powerup(nState);
671                         if(retval == 0)
672                             property_set("wc_transport.vnd_power", nState == BT_VND_PWR_ON ? "1" : "0");
673                     default:
674                         break;
675                 }
676             }
677             break;
678 
679         case BT_VND_OP_FW_CFG:
680             {
681                 // call hciattach to initalize the stack
682                 if(bt_vendor_cbacks){
683                    ALOGI("Bluetooth Firmware and transport layer are initialized");
684                    bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
685                 }
686                 else{
687                    ALOGE("bt_vendor_cbacks is null");
688                    ALOGE("Error : hci, smd initialization Error");
689                    retval = -1;
690                 }
691             }
692             break;
693 
694         case BT_VND_OP_SCO_CFG:
695             {
696                 if (bt_vendor_cbacks)
697                     bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
698             }
699             break;
700 #ifdef BT_SOC_TYPE_ROME
701 #ifdef ENABLE_ANT
702         case BT_VND_OP_ANT_USERIAL_OPEN:
703                 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_OPEN");
704                 is_ant_req = true;
705                 //fall through
706 #endif
707 #endif
708         case BT_VND_OP_USERIAL_OPEN:
709             {
710                 int (*fd_array)[] = (int (*)[]) param;
711                 int fd = -1, fd_filter = -1;
712                 ALOGI("bt-vendor : BT_VND_OP_USERIAL_OPEN");
713                 switch(btSocType)
714                 {
715                     case BT_SOC_DEFAULT:
716                         {
717                             if(bt_hci_init_transport(pFd) != -1){
718                                 int (*fd_array)[] = (int (*) []) param;
719 
720                                     (*fd_array)[CH_CMD] = pFd[0];
721                                     (*fd_array)[CH_EVT] = pFd[0];
722                                     (*fd_array)[CH_ACL_OUT] = pFd[1];
723                                     (*fd_array)[CH_ACL_IN] = pFd[1];
724                             }
725                             else {
726                                 retval = -1;
727                                 break;
728                             }
729                             retval = 2;
730                         }
731                         break;
732                     case BT_SOC_AR3K:
733                         {
734                             int idx;
735                             fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
736                             if (fd != -1) {
737                                 for (idx=0; idx < CH_MAX; idx++)
738                                     (*fd_array)[idx] = fd;
739                                 retval = 1;
740                             }
741                             else {
742                                 retval = -1;
743                                 break;
744                             }
745 
746                             /* Vendor Specific Process should happened during userial_open process
747                                 After userial_open, rx read thread is running immediately,
748                                 so it will affect VS event read process.
749                             */
750                             if(ath3k_init(fd,3000000,115200,NULL,&vnd_userial.termios)<0)
751                                 retval = -1;
752                         }
753                         break;
754                     case BT_SOC_ROME:
755                         {
756                             int idx;
757                             property_get("persist.BT3_2.version", bt_version, false);
758                             if (!is_soc_initialized()) {
759                                 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
760                                 if (fd < 0) {
761                                     ALOGE("userial_vendor_open returns err");
762                                     retval = -1;
763                                 } else {
764                                     /* Clock on */
765                                     userial_clock_operation(fd, USERIAL_OP_CLK_ON);
766                                     ALOGD("userial clock on");
767                                     if(strcmp(bt_version, "true") == 0) {
768                                         property_get("ro.bluetooth.wipower", wipower_status, false);
769                                         if(strcmp(wipower_status, "true") == 0) {
770                                             check_embedded_mode(fd);
771                                         } else {
772                                             ALOGI("Wipower not enabled");
773                                         }
774                                     }
775                                     ALOGV("rome_soc_init is started");
776                                     property_set("wc_transport.soc_initialized", "0");
777 #ifdef READ_BT_ADDR_FROM_PROP
778                                     /*Give priority to read BD address from boot property*/
779                                     ignore_boot_prop = FALSE;
780                                     if (property_get(BLUETOOTH_MAC_ADDR_BOOT_PROPERTY, bd_addr, NULL)) {
781                                         ALOGV("BD address read from Boot property: %s\n", bd_addr);
782                                         tok =  strtok(bd_addr, ":");
783                                         while (tok != NULL) {
784                                             ALOGV("bd add [%d]: %d ", i, strtol(tok, NULL, 16));
785                                             if (i>=6) {
786                                                 ALOGE("bd property of invalid length");
787                                                 ignore_boot_prop = TRUE;
788                                                 break;
789                                             }
790                                             if (!validate_tok(tok)) {
791                                                 ALOGE("Invalid token in BD address");
792                                                 ignore_boot_prop = TRUE;
793                                                 break;
794                                             }
795                                             local_bd_addr_from_prop[5-i] = strtol(tok, NULL, 16);
796                                             tok = strtok(NULL, ":");
797                                             i++;
798                                         }
799                                         if (i == 6 && !ignore_boot_prop) {
800                                             ALOGV("Valid BD address read from prop");
801                                             memcpy(vnd_local_bd_addr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr));
802                                             ignore_boot_prop = FALSE;
803                                         } else {
804                                             ALOGE("There are not enough tokens in BD addr");
805                                             ignore_boot_prop = TRUE;
806                                         }
807                                     } else {
808                                         ALOGE("BD address boot property not set");
809                                         ignore_boot_prop = TRUE;
810                                     }
811 #endif //READ_BT_ADDR_FROM_PROP
812 #ifdef BT_NV_SUPPORT
813                                     /* Always read BD address from NV file */
814                                     if(ignore_boot_prop && !bt_vendor_nv_read(1, vnd_local_bd_addr))
815                                     {
816                                        /* Since the BD address is configured in boot time We should not be here */
817                                        ALOGI("Failed to read BD address. Use the one from bluedroid stack/ftm");
818                                     }
819 #endif //BT_NV_SUPPORT
820                                     if(rome_soc_init(fd,vnd_local_bd_addr)<0) {
821                                         retval = -1;
822                                     } else {
823                                         ALOGV("rome_soc_init is completed");
824                                         property_set("wc_transport.soc_initialized", "1");
825                                         skip_init = false;
826                                     }
827                                 }
828                             }
829 
830                             property_set("wc_transport.clean_up","0");
831                             if (retval != -1) {
832 #ifdef BT_SOC_TYPE_ROME
833                                  start_hci_filter();
834                                  if (is_ant_req) {
835                                      ALOGV("connect to ant channel");
836                                      ant_fd = fd_filter = connect_to_local_socket("ant_sock");
837                                  }
838                                  else
839 #endif
840                                  {
841                                      ALOGV("connect to bt channel");
842                                      vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock");
843                                  }
844 
845                                  if (fd_filter != -1) {
846                                      ALOGV("%s: received the socket fd: %d is_ant_req: %d\n",
847                                                                  __func__, fd_filter, is_ant_req);
848                                      if((strcmp(bt_version, "true") == 0) && !is_ant_req) {
849                                          if (rome_ver >= ROME_VER_3_0) {
850                                              /*  get rome supported feature request */
851                                              ALOGE("%s: %x08 %0x", __FUNCTION__,rome_ver, ROME_VER_3_0);
852                                              rome_get_addon_feature_list(fd_filter);
853                                          }
854                                      }
855 
856                                      if (!skip_init) {
857                                          /* skip if already sent */
858                                          enable_controller_log(fd_filter);
859                                          skip_init = true;
860                                      }
861 
862                                      for (idx=0; idx < CH_MAX; idx++)
863                                          (*fd_array)[idx] = fd_filter;
864                                      retval = 1;
865                                  }
866                                  else {
867                                      retval = -1;
868                                  }
869                              }
870 
871                              if (fd >= 0) {
872                                  userial_clock_operation(fd, USERIAL_OP_CLK_OFF);
873                                  close(fd);
874                              }
875                         }
876                         break;
877                     default:
878                         ALOGE("Unknown btSocType: 0x%x", btSocType);
879                         break;
880                 }
881             }
882             break;
883 #ifdef BT_SOC_TYPE_ROME
884 #ifdef ENABLE_ANT
885         case BT_VND_OP_ANT_USERIAL_CLOSE:
886             {
887                 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_CLOSE");
888                 property_set("wc_transport.clean_up","1");
889                 if (ant_fd != -1) {
890                     ALOGE("closing ant_fd");
891                     close(ant_fd);
892                     ant_fd = -1;
893                 }
894             }
895             break;
896 #endif
897 #endif
898         case BT_VND_OP_USERIAL_CLOSE:
899             {
900                 ALOGI("bt-vendor : BT_VND_OP_USERIAL_CLOSE btSocType: %d", btSocType);
901                 switch(btSocType)
902                 {
903                     case BT_SOC_DEFAULT:
904                          bt_hci_deinit_transport(pFd);
905                          break;
906 
907                      case BT_SOC_ROME:
908                      case BT_SOC_AR3K:
909                         property_set("wc_transport.clean_up","1");
910                         userial_vendor_close();
911                         break;
912                     default:
913                         ALOGE("Unknown btSocType: 0x%x", btSocType);
914                         break;
915                 }
916             }
917             break;
918 
919         case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
920             {
921                 uint32_t *timeout_ms = (uint32_t *) param;
922                 *timeout_ms = 1000;
923             }
924             break;
925 
926         case BT_VND_OP_LPM_SET_MODE:
927             if(btSocType ==  BT_SOC_AR3K) {
928                 uint8_t *mode = (uint8_t *) param;
929 
930                 if (*mode) {
931                     lpm_set_ar3k(UPIO_LPM_MODE, UPIO_ASSERT, 0);
932                 }
933                 else {
934                     lpm_set_ar3k(UPIO_LPM_MODE, UPIO_DEASSERT, 0);
935                 }
936                 if (bt_vendor_cbacks )
937                     bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
938             }
939             else {
940                 if (bt_vendor_cbacks)
941                     bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
942             }
943             break;
944 
945         case BT_VND_OP_LPM_WAKE_SET_STATE:
946             {
947                 switch(btSocType)
948                 {
949                     case BT_SOC_ROME:
950                         {
951                             uint8_t *state = (uint8_t *) param;
952                             uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
953                                 BT_VND_LPM_WAKE_ASSERT : BT_VND_LPM_WAKE_DEASSERT;
954 
955                             if (wake_assert == 0)
956                                 ALOGV("ASSERT: Waking up BT-Device");
957                             else if (wake_assert == 1)
958                                 ALOGV("DEASSERT: Allowing BT-Device to Sleep");
959 
960 #ifdef QCOM_BT_SIBS_ENABLE
961                             if(bt_vendor_cbacks){
962                                 ALOGI("Invoking HCI H4 callback function");
963                                bt_vendor_cbacks->lpm_set_state_cb(wake_assert);
964                             }
965 #endif
966                         }
967                         break;
968                     case BT_SOC_AR3K:
969                         {
970                             uint8_t *state = (uint8_t *) param;
971                             uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
972                                                         UPIO_ASSERT : UPIO_DEASSERT;
973                             lpm_set_ar3k(UPIO_BT_WAKE, wake_assert, 0);
974                         }
975                     case BT_SOC_DEFAULT:
976                         break;
977                     default:
978                         ALOGE("Unknown btSocType: 0x%x", btSocType);
979                         break;
980                     }
981             }
982             break;
983         case BT_VND_OP_EPILOG:
984             {
985 #if (HW_NEED_END_WITH_HCI_RESET == FALSE)
986                 if (bt_vendor_cbacks)
987                 {
988                     bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
989                 }
990 #else
991                 switch(btSocType)
992                 {
993                   case BT_SOC_ROME:
994                        {
995                            char value[PROPERTY_VALUE_MAX] = {'\0'};
996                            property_get("wc_transport.hci_filter_status", value, "0");
997                            if(is_soc_initialized()&& (strcmp(value,"1") == 0))
998                            {
999                               hw_epilog_process();
1000                            }
1001                            else
1002                            {
1003                              if (bt_vendor_cbacks)
1004                                {
1005                                  ALOGE("vendor lib epilog process aborted");
1006                                  bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
1007                                }
1008                            }
1009                        }
1010                        break;
1011                   default:
1012                        hw_epilog_process();
1013                        break;
1014                 }
1015 #endif
1016             }
1017             break;
1018         case BT_VND_OP_GET_LINESPEED:
1019             {
1020                 retval = -1;
1021                 switch(btSocType)
1022                 {
1023                     case BT_SOC_ROME:
1024                         if(!is_soc_initialized()) {
1025                             ALOGE("BT_VND_OP_GET_LINESPEED: error"
1026                             " - transport driver not initialized!");
1027                         }else {
1028                             retval = 3000000;
1029                         }
1030                         break;
1031                     default:
1032                         retval = userial_vendor_get_baud();
1033                         break;
1034                  }
1035                 break;
1036             }
1037     }
1038 
1039     return retval;
1040 }
1041 
ssr_cleanup(void)1042 static void ssr_cleanup(void) {
1043     int pwr_state=BT_VND_PWR_OFF;
1044 
1045     ALOGI("ssr_cleanup");
1046 
1047     if ((btSocType = get_bt_soc_type()) < 0) {
1048         ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__);
1049         return;
1050     }
1051 
1052     if (btSocType == BT_SOC_ROME) {
1053 #ifdef BT_SOC_TYPE_ROME
1054 #ifdef ENABLE_ANT
1055         /*Close both ANT channel*/
1056         op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL);
1057 #endif
1058 #endif
1059         /*Close both ANT channel*/
1060         op(BT_VND_OP_USERIAL_CLOSE, NULL);
1061         /*CTRL OFF twice to make sure hw
1062          * turns off*/
1063         op(BT_VND_OP_POWER_CTRL, &pwr_state);
1064 
1065     }
1066 
1067 #ifdef BT_SOC_TYPE_ROME
1068     /*Generally switching of chip should be enough*/
1069     op(BT_VND_OP_POWER_CTRL, &pwr_state);
1070 #endif
1071     bt_vendor_cbacks = NULL;
1072 }
1073 
1074 
1075 /** Closes the interface */
cleanup(void)1076 static void cleanup( void )
1077 {
1078     ALOGI("cleanup");
1079     bt_vendor_cbacks = NULL;
1080 
1081 #ifdef WIFI_BT_STATUS_SYNC
1082     isInit = 0;
1083 #endif /* WIFI_BT_STATUS_SYNC */
1084 }
1085 
1086 // Entry point of DLib
1087 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
1088     sizeof(bt_vendor_interface_t),
1089     init,
1090     op,
1091     cleanup,
1092     ssr_cleanup
1093 };
1094