Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
bluetooth
hci_ath.c
Go to the documentation of this file.
1
/*
2
* Atheros Communication Bluetooth HCIATH3K UART protocol
3
*
4
* HCIATH3K (HCI Atheros AR300x Protocol) is a Atheros Communication's
5
* power management protocol extension to H4 to support AR300x Bluetooth Chip.
6
*
7
* Copyright (c) 2009-2010 Atheros Communications Inc.
8
*
9
* Acknowledgements:
10
* This file is based on hci_h4.c, which was written
11
* by Maxim Krasnyansky and Marcel Holtmann.
12
*
13
* This program is free software; you can redistribute it and/or modify
14
* it under the terms of the GNU General Public License as published by
15
* the Free Software Foundation; either version 2 of the License, or
16
* (at your option) any later version.
17
*
18
* This program is distributed in the hope that it will be useful,
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
* GNU General Public License for more details.
22
*
23
* You should have received a copy of the GNU General Public License
24
* along with this program; if not, write to the Free Software
25
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
*
27
*/
28
29
#include <linux/module.h>
30
#include <linux/kernel.h>
31
32
#include <
linux/init.h
>
33
#include <linux/slab.h>
34
#include <linux/tty.h>
35
#include <linux/errno.h>
36
#include <
linux/ioctl.h
>
37
#include <
linux/skbuff.h
>
38
39
#include <
net/bluetooth/bluetooth.h
>
40
#include <
net/bluetooth/hci_core.h
>
41
42
#include "
hci_uart.h
"
43
44
struct
ath_struct
{
45
struct
hci_uart
*
hu
;
46
unsigned
int
cur_sleep
;
47
48
struct
sk_buff_head
txq
;
49
struct
work_struct
ctxtsw
;
50
};
51
52
static
int
ath_wakeup_ar3k(
struct
tty_struct
*tty)
53
{
54
struct
ktermios
ktermios
;
55
int
status
= tty->
driver
->ops->tiocmget(tty);
56
57
if
(status &
TIOCM_CTS
)
58
return
status
;
59
60
/* Disable Automatic RTSCTS */
61
ktermios
= tty->termios;
62
ktermios
.
c_cflag
&= ~
CRTSCTS
;
63
tty_set_termios
(tty, &
ktermios
);
64
65
/* Clear RTS first */
66
status = tty->
driver
->ops->tiocmget(tty);
67
tty->
driver
->ops->tiocmset(tty, 0x00,
TIOCM_RTS
);
68
mdelay
(20);
69
70
/* Set RTS, wake up board */
71
status = tty->
driver
->ops->tiocmget(tty);
72
tty->
driver
->ops->tiocmset(tty,
TIOCM_RTS
, 0x00);
73
mdelay
(20);
74
75
status = tty->
driver
->ops->tiocmget(tty);
76
77
/* Disable Automatic RTSCTS */
78
ktermios
.
c_cflag
|=
CRTSCTS
;
79
status =
tty_set_termios
(tty, &
ktermios
);
80
81
return
status
;
82
}
83
84
static
void
ath_hci_uart_work(
struct
work_struct
*
work
)
85
{
86
int
status
;
87
struct
ath_struct
*ath;
88
struct
hci_uart
*hu;
89
struct
tty_struct
*tty;
90
91
ath =
container_of
(work,
struct
ath_struct
, ctxtsw);
92
93
hu = ath->
hu
;
94
tty = hu->
tty
;
95
96
/* verify and wake up controller */
97
if
(ath->
cur_sleep
) {
98
status = ath_wakeup_ar3k(tty);
99
if
(!(status & TIOCM_CTS))
100
return
;
101
}
102
103
/* Ready to send Data */
104
clear_bit
(
HCI_UART_SENDING
, &hu->
tx_state
);
105
hci_uart_tx_wakeup
(hu);
106
}
107
108
/* Initialize protocol */
109
static
int
ath_open(
struct
hci_uart
*hu)
110
{
111
struct
ath_struct
*ath;
112
113
BT_DBG
(
"hu %p"
, hu);
114
115
ath = kzalloc(
sizeof
(*ath),
GFP_KERNEL
);
116
if
(!ath)
117
return
-
ENOMEM
;
118
119
skb_queue_head_init(&ath->
txq
);
120
121
hu->
priv
= ath;
122
ath->
hu
=
hu
;
123
124
INIT_WORK
(&ath->
ctxtsw
, ath_hci_uart_work);
125
126
return
0;
127
}
128
129
/* Flush protocol data */
130
static
int
ath_flush(
struct
hci_uart
*hu)
131
{
132
struct
ath_struct
*ath = hu->
priv
;
133
134
BT_DBG
(
"hu %p"
, hu);
135
136
skb_queue_purge
(&ath->
txq
);
137
138
return
0;
139
}
140
141
/* Close protocol */
142
static
int
ath_close(
struct
hci_uart
*hu)
143
{
144
struct
ath_struct
*ath = hu->
priv
;
145
146
BT_DBG
(
"hu %p"
, hu);
147
148
skb_queue_purge
(&ath->
txq
);
149
150
cancel_work_sync
(&ath->
ctxtsw
);
151
152
hu->
priv
=
NULL
;
153
kfree
(ath);
154
155
return
0;
156
}
157
158
#define HCI_OP_ATH_SLEEP 0xFC04
159
160
/* Enqueue frame for transmittion */
161
static
int
ath_enqueue(
struct
hci_uart
*hu,
struct
sk_buff
*
skb
)
162
{
163
struct
ath_struct
*ath = hu->
priv
;
164
165
if
(
bt_cb
(skb)->pkt_type ==
HCI_SCODATA_PKT
) {
166
kfree_skb
(skb);
167
return
0;
168
}
169
170
/*
171
* Update power management enable flag with parameters of
172
* HCI sleep enable vendor specific HCI command.
173
*/
174
if
(
bt_cb
(skb)->pkt_type ==
HCI_COMMAND_PKT
) {
175
struct
hci_command_hdr
*
hdr
= (
void
*)skb->
data
;
176
177
if
(
__le16_to_cpu
(hdr->
opcode
) ==
HCI_OP_ATH_SLEEP
)
178
ath->
cur_sleep
= skb->
data
[
HCI_COMMAND_HDR_SIZE
];
179
}
180
181
BT_DBG
(
"hu %p skb %p"
, hu, skb);
182
183
/* Prepend skb with frame type */
184
memcpy
(
skb_push
(skb, 1), &
bt_cb
(skb)->pkt_type, 1);
185
186
skb_queue_tail
(&ath->
txq
, skb);
187
set_bit
(
HCI_UART_SENDING
, &hu->
tx_state
);
188
189
schedule_work
(&ath->
ctxtsw
);
190
191
return
0;
192
}
193
194
static
struct
sk_buff
*ath_dequeue(
struct
hci_uart
*hu)
195
{
196
struct
ath_struct
*ath = hu->
priv
;
197
198
return
skb_dequeue
(&ath->
txq
);
199
}
200
201
/* Recv data */
202
static
int
ath_recv(
struct
hci_uart
*hu,
void
*
data
,
int
count
)
203
{
204
int
ret
;
205
206
ret =
hci_recv_stream_fragment
(hu->
hdev
, data, count);
207
if
(ret < 0) {
208
BT_ERR
(
"Frame Reassembly Failed"
);
209
return
ret
;
210
}
211
212
return
count
;
213
}
214
215
static
struct
hci_uart_proto
athp = {
216
.id =
HCI_UART_ATH3K
,
217
.open = ath_open,
218
.close = ath_close,
219
.recv = ath_recv,
220
.enqueue = ath_enqueue,
221
.dequeue = ath_dequeue,
222
.flush = ath_flush,
223
};
224
225
int
__init
ath_init
(
void
)
226
{
227
int
err
=
hci_uart_register_proto
(&athp);
228
229
if
(!err)
230
BT_INFO
(
"HCIATH3K protocol initialized"
);
231
else
232
BT_ERR
(
"HCIATH3K protocol registration failed"
);
233
234
return
err
;
235
}
236
237
int
__exit
ath_deinit
(
void
)
238
{
239
return
hci_uart_unregister_proto
(&athp);
240
}
Generated on Thu Jan 10 2013 13:27:19 for Linux Kernel by
1.8.2