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#include <linux/platform_device.h>
27#include <net/bluetooth/bluetooth.h>
28#include <net/bluetooth/hci_core.h>
29#include <net/bluetooth/hci.h>
30
31#include <linux/ti_wilink_st.h>
32#include <linux/module.h>
33#include <linux/of.h>
34
35
36#define VERSION "1.0"
37#define MAX_BT_CHNL_IDS 3
38
39
40
41
42#define BT_REGISTER_TIMEOUT 6000
43
44
45
46
47
48
49
50
51
52
53struct ti_st {
54 struct hci_dev *hdev;
55 int reg_status;
56 long (*st_write) (struct sk_buff *);
57 struct completion wait_reg_completion;
58};
59
60
61static inline void ti_st_tx_complete(struct ti_st *hst, int pkt_type)
62{
63 struct hci_dev *hdev = hst->hdev;
64
65
66 switch (pkt_type) {
67 case HCI_COMMAND_PKT:
68 hdev->stat.cmd_tx++;
69 break;
70
71 case HCI_ACLDATA_PKT:
72 hdev->stat.acl_tx++;
73 break;
74
75 case HCI_SCODATA_PKT:
76 hdev->stat.sco_tx++;
77 break;
78 }
79}
80
81
82
83
84
85
86
87static void st_reg_completion_cb(void *priv_data, int data)
88{
89 struct ti_st *lhst = priv_data;
90
91
92 lhst->reg_status = data;
93
94 complete(&lhst->wait_reg_completion);
95}
96
97
98
99static long st_receive(void *priv_data, struct sk_buff *skb)
100{
101 struct ti_st *lhst = priv_data;
102 int err;
103
104 if (!skb)
105 return -EFAULT;
106
107 if (!lhst) {
108 kfree_skb(skb);
109 return -EFAULT;
110 }
111
112
113 err = hci_recv_frame(lhst->hdev, skb);
114 if (err < 0) {
115 BT_ERR("Unable to push skb to HCI core(%d)", err);
116 return err;
117 }
118
119 lhst->hdev->stat.byte_rx += skb->len;
120
121 return 0;
122}
123
124
125
126static struct st_proto_s ti_st_proto[MAX_BT_CHNL_IDS] = {
127 {
128 .chnl_id = HCI_EVENT_PKT,
129 .hdr_len = sizeof(struct hci_event_hdr),
130 .offset_len_in_hdr = offsetof(struct hci_event_hdr, plen),
131 .len_size = 1,
132 .reserve = 8,
133 },
134 {
135 .chnl_id = HCI_ACLDATA_PKT,
136 .hdr_len = sizeof(struct hci_acl_hdr),
137 .offset_len_in_hdr = offsetof(struct hci_acl_hdr, dlen),
138 .len_size = 2,
139 .reserve = 8,
140 },
141 {
142 .chnl_id = HCI_SCODATA_PKT,
143 .hdr_len = sizeof(struct hci_sco_hdr),
144 .offset_len_in_hdr = offsetof(struct hci_sco_hdr, dlen),
145 .len_size = 1,
146 .reserve = 8,
147 },
148};
149
150
151static int ti_st_open(struct hci_dev *hdev)
152{
153 unsigned long timeleft;
154 struct ti_st *hst;
155 int err, i;
156
157 BT_DBG("%s %p", hdev->name, hdev);
158
159
160 hst = hci_get_drvdata(hdev);
161
162 for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
163 ti_st_proto[i].priv_data = hst;
164 ti_st_proto[i].max_frame_size = HCI_MAX_FRAME_SIZE;
165 ti_st_proto[i].recv = st_receive;
166 ti_st_proto[i].reg_complete_cb = st_reg_completion_cb;
167
168
169 init_completion(&hst->wait_reg_completion);
170
171
172
173
174
175 hst->reg_status = -EINPROGRESS;
176
177 err = st_register(&ti_st_proto[i]);
178 if (!err)
179 goto done;
180
181 if (err != -EINPROGRESS) {
182 BT_ERR("st_register failed %d", err);
183 return err;
184 }
185
186
187
188
189 BT_DBG("waiting for registration "
190 "completion signal from ST");
191 timeleft = wait_for_completion_timeout
192 (&hst->wait_reg_completion,
193 msecs_to_jiffies(BT_REGISTER_TIMEOUT));
194 if (!timeleft) {
195 BT_ERR("Timeout(%d sec),didn't get reg "
196 "completion signal from ST",
197 BT_REGISTER_TIMEOUT / 1000);
198 return -ETIMEDOUT;
199 }
200
201
202
203 if (hst->reg_status != 0) {
204 BT_ERR("ST registration completed with invalid "
205 "status %d", hst->reg_status);
206 return -EAGAIN;
207 }
208
209done:
210 hst->st_write = ti_st_proto[i].write;
211 if (!hst->st_write) {
212 BT_ERR("undefined ST write function");
213 for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
214
215 err = st_unregister(&ti_st_proto[i]);
216 if (err)
217 BT_ERR("st_unregister() failed with "
218 "error %d", err);
219 hst->st_write = NULL;
220 }
221 return -EIO;
222 }
223 }
224 return 0;
225}
226
227
228static int ti_st_close(struct hci_dev *hdev)
229{
230 int err, i;
231 struct ti_st *hst = hci_get_drvdata(hdev);
232
233 for (i = MAX_BT_CHNL_IDS-1; i >= 0; i--) {
234 err = st_unregister(&ti_st_proto[i]);
235 if (err)
236 BT_ERR("st_unregister(%d) failed with error %d",
237 ti_st_proto[i].chnl_id, err);
238 }
239
240 hst->st_write = NULL;
241
242 return err;
243}
244
245static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
246{
247 struct ti_st *hst;
248 long len;
249 int pkt_type;
250
251 hst = hci_get_drvdata(hdev);
252
253
254 memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
255
256 BT_DBG("%s: type %d len %d", hdev->name, hci_skb_pkt_type(skb),
257 skb->len);
258
259
260
261
262
263 pkt_type = hci_skb_pkt_type(skb);
264 len = hst->st_write(skb);
265 if (len < 0) {
266 kfree_skb(skb);
267 BT_ERR("ST write failed (%ld)", len);
268
269 return -EAGAIN;
270 }
271
272
273 hdev->stat.byte_tx += len;
274 ti_st_tx_complete(hst, pkt_type);
275
276 return 0;
277}
278
279static const struct of_device_id btwilink_of_match[] = {
280{
281 .compatible = "btwilink",
282 },
283 {}
284};
285MODULE_DEVICE_TABLE(of, btwilink_of_match);
286
287static int bt_ti_probe(struct platform_device *pdev)
288{
289 static struct ti_st *hst;
290 struct hci_dev *hdev;
291 int err;
292
293 hst = devm_kzalloc(&pdev->dev, sizeof(struct ti_st), GFP_KERNEL);
294 if (!hst)
295 return -ENOMEM;
296
297
298 hdev = hci_alloc_dev();
299 if (!hdev)
300 return -ENOMEM;
301
302 BT_DBG("hdev %p", hdev);
303
304 hst->hdev = hdev;
305 hdev->bus = HCI_UART;
306 hci_set_drvdata(hdev, hst);
307 hdev->open = ti_st_open;
308 hdev->close = ti_st_close;
309 hdev->flush = NULL;
310 hdev->send = ti_st_send_frame;
311
312 err = hci_register_dev(hdev);
313 if (err < 0) {
314 BT_ERR("Can't register HCI device error %d", err);
315 hci_free_dev(hdev);
316 return err;
317 }
318
319 BT_DBG("HCI device registered (hdev %p)", hdev);
320
321 dev_set_drvdata(&pdev->dev, hst);
322 return 0;
323}
324
325static int bt_ti_remove(struct platform_device *pdev)
326{
327 struct hci_dev *hdev;
328 struct ti_st *hst = dev_get_drvdata(&pdev->dev);
329
330 if (!hst)
331 return -EFAULT;
332
333 BT_DBG("%s", hst->hdev->name);
334
335 hdev = hst->hdev;
336 ti_st_close(hdev);
337 hci_unregister_dev(hdev);
338
339 hci_free_dev(hdev);
340
341 dev_set_drvdata(&pdev->dev, NULL);
342 return 0;
343}
344
345static struct platform_driver btwilink_driver = {
346 .probe = bt_ti_probe,
347 .remove = bt_ti_remove,
348 .driver = {
349 .name = "btwilink",
350 .of_match_table = of_match_ptr(btwilink_of_match),
351 },
352};
353
354module_platform_driver(btwilink_driver);
355
356
357
358MODULE_AUTHOR("Raja Mani <raja_mani@ti.com>");
359MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION);
360MODULE_VERSION(VERSION);
361MODULE_LICENSE("GPL");
362