summaryrefslogtreecommitdiff
path: root/libbt-vendor/bt_vendor_mrvl.c
blob: 93664ccbffebef7b56a676e28f66afe7eb14d26f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/******************************************************************************
 *
 *  Copyright (C) 2012 Marvell International Ltd.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

#include <time.h>
#include <errno.h>
#include <sched.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/mman.h>
#include <pthread.h>
#include "bt_vendor_lib.h"

/* ioctl command to release the read thread before driver close */
#define MBTCHAR_IOCTL_RELEASE _IO  ('M',1)

#define VERSION "M001"

static bt_vendor_callbacks_t *vnd_cb = NULL;

static unsigned char bdaddr[6];

static char mchar_port[] = "/dev/mbtchar0";

static int mchar_fd = -1;

int bt_vnd_mrvl_if_init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr)
{
    vnd_cb = p_cb;
    memcpy(bdaddr, local_bdaddr, sizeof(bdaddr));
    return 0;
}

int bt_vnd_mrvl_if_op(bt_vendor_opcode_t opcode, void *param)
{
    int ret = 0;
    int power_state;
    int local_st = 0;

    switch (opcode) {
    case BT_VND_OP_POWER_CTRL:
        power_state = (int *)param;
        if (BT_VND_PWR_OFF == power_state) {
        } else if (BT_VND_PWR_ON == power_state) {
        } else {
            ret = -1;
        }
        break;
    case BT_VND_OP_FW_CFG:
        // TODO: Perform any vendor specific initialization or configuration on the BT Controller
        // ret = xxx
        if (vnd_cb) {
            vnd_cb->fwcfg_cb(ret);
        }
        break;
    case BT_VND_OP_SCO_CFG:
        // TODO:  Perform any vendor specific SCO/PCM configuration on the BT Controller.
        // ret = xxx
        if (vnd_cb) {
            vnd_cb->scocfg_cb(ret);
        }
        break;
    case BT_VND_OP_USERIAL_OPEN:
        mchar_fd = open(mchar_port, O_RDWR|O_NOCTTY);
        if (mchar_fd < 0) {
            ret = -1;
        } else {
            ret = 1;
        }
        ((int *)param)[0] = mchar_fd;
        break;
    case BT_VND_OP_USERIAL_CLOSE:
        if (mchar_fd < 0) {
            ret = -1;
        } else {
            /* mbtchar port is blocked on read. Release the port before we close it */
            ioctl(mchar_fd,MBTCHAR_IOCTL_RELEASE,&local_st);
            /* Give it sometime before we close the mbtchar */
            usleep(1000);
            if (close(mchar_fd) < 0) {
                ret = -1;
            } else {
                mchar_fd = -1; /* closed successfully */
            }
        }
        break;
    case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
        break;
    case BT_VND_OP_LPM_SET_MODE:
        // TODO: Enable or disable LPM mode on BT Controller.
        // ret = xx;
        if (vnd_cb) {
            vnd_cb->lpm_cb(ret);
        }
        break;
    case BT_VND_OP_LPM_WAKE_SET_STATE:
        break;
    default:
        ret = -1;
        break;
    }
    return ret;
}

void bt_vnd_mrvl_if_cleanup(void)
{
    return;
}

const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
    sizeof(bt_vendor_interface_t),
    bt_vnd_mrvl_if_init,
    bt_vnd_mrvl_if_op,
    bt_vnd_mrvl_if_cleanup,
};