Commit | Line | Data |
---|---|---|
7bb31868 SR |
1 | /* |
2 | * Bluetooth HCI UART H4 driver with Nokia Extensions AKA Nokia H4+ | |
3 | * | |
4 | * Copyright (C) 2015 Marcel Holtmann <marcel@holtmann.org> | |
5 | * Copyright (C) 2015-2017 Sebastian Reichel <sre@kernel.org> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | */ | |
17 | ||
18 | #include <linux/clk.h> | |
19 | #include <linux/errno.h> | |
20 | #include <linux/firmware.h> | |
21 | #include <linux/gpio/consumer.h> | |
22 | #include <linux/interrupt.h> | |
23 | #include <linux/kernel.h> | |
24 | #include <linux/module.h> | |
25 | #include <linux/of.h> | |
26 | #include <linux/pm_runtime.h> | |
27 | #include <linux/serdev.h> | |
28 | #include <linux/skbuff.h> | |
29 | #include <linux/slab.h> | |
30 | #include <linux/string.h> | |
31 | #include <linux/types.h> | |
32 | #include <linux/unaligned/le_struct.h> | |
33 | #include <net/bluetooth/bluetooth.h> | |
34 | #include <net/bluetooth/hci_core.h> | |
35 | ||
36 | #include "hci_uart.h" | |
37 | #include "btbcm.h" | |
38 | ||
377a6eac FD |
39 | #define VERSION "0.1" |
40 | ||
7bb31868 SR |
41 | #define NOKIA_ID_BCM2048 0x04 |
42 | #define NOKIA_ID_TI1271 0x31 | |
43 | ||
44 | #define FIRMWARE_BCM2048 "nokia/bcmfw.bin" | |
45 | #define FIRMWARE_TI1271 "nokia/ti1273.bin" | |
46 | ||
47 | #define HCI_NOKIA_NEG_PKT 0x06 | |
48 | #define HCI_NOKIA_ALIVE_PKT 0x07 | |
49 | #define HCI_NOKIA_RADIO_PKT 0x08 | |
50 | ||
51 | #define HCI_NOKIA_NEG_HDR_SIZE 1 | |
52 | #define HCI_NOKIA_MAX_NEG_SIZE 255 | |
53 | #define HCI_NOKIA_ALIVE_HDR_SIZE 1 | |
54 | #define HCI_NOKIA_MAX_ALIVE_SIZE 255 | |
55 | #define HCI_NOKIA_RADIO_HDR_SIZE 2 | |
56 | #define HCI_NOKIA_MAX_RADIO_SIZE 255 | |
57 | ||
58 | #define NOKIA_PROTO_PKT 0x44 | |
59 | #define NOKIA_PROTO_BYTE 0x4c | |
60 | ||
61 | #define NOKIA_NEG_REQ 0x00 | |
62 | #define NOKIA_NEG_ACK 0x20 | |
63 | #define NOKIA_NEG_NAK 0x40 | |
64 | ||
65 | #define H4_TYPE_SIZE 1 | |
66 | ||
67 | #define NOKIA_RECV_ALIVE \ | |
68 | .type = HCI_NOKIA_ALIVE_PKT, \ | |
69 | .hlen = HCI_NOKIA_ALIVE_HDR_SIZE, \ | |
70 | .loff = 0, \ | |
71 | .lsize = 1, \ | |
72 | .maxlen = HCI_NOKIA_MAX_ALIVE_SIZE \ | |
73 | ||
74 | #define NOKIA_RECV_NEG \ | |
75 | .type = HCI_NOKIA_NEG_PKT, \ | |
76 | .hlen = HCI_NOKIA_NEG_HDR_SIZE, \ | |
77 | .loff = 0, \ | |
78 | .lsize = 1, \ | |
79 | .maxlen = HCI_NOKIA_MAX_NEG_SIZE \ | |
80 | ||
81 | #define NOKIA_RECV_RADIO \ | |
82 | .type = HCI_NOKIA_RADIO_PKT, \ | |
83 | .hlen = HCI_NOKIA_RADIO_HDR_SIZE, \ | |
84 | .loff = 1, \ | |
85 | .lsize = 1, \ | |
86 | .maxlen = HCI_NOKIA_MAX_RADIO_SIZE \ | |
87 | ||
88 | struct hci_nokia_neg_hdr { | |
89 | u8 dlen; | |
90 | } __packed; | |
91 | ||
92 | struct hci_nokia_neg_cmd { | |
93 | u8 ack; | |
94 | u16 baud; | |
95 | u16 unused1; | |
96 | u8 proto; | |
97 | u16 sys_clk; | |
98 | u16 unused2; | |
99 | } __packed; | |
100 | ||
101 | #define NOKIA_ALIVE_REQ 0x55 | |
102 | #define NOKIA_ALIVE_RESP 0xcc | |
103 | ||
104 | struct hci_nokia_alive_hdr { | |
105 | u8 dlen; | |
106 | } __packed; | |
107 | ||
108 | struct hci_nokia_alive_pkt { | |
109 | u8 mid; | |
110 | u8 unused; | |
111 | } __packed; | |
112 | ||
113 | struct hci_nokia_neg_evt { | |
114 | u8 ack; | |
115 | u16 baud; | |
116 | u16 unused1; | |
117 | u8 proto; | |
118 | u16 sys_clk; | |
119 | u16 unused2; | |
120 | u8 man_id; | |
121 | u8 ver_id; | |
122 | } __packed; | |
123 | ||
124 | #define MAX_BAUD_RATE 3692300 | |
125 | #define SETUP_BAUD_RATE 921600 | |
126 | #define INIT_BAUD_RATE 120000 | |
127 | ||
128 | struct hci_nokia_radio_hdr { | |
129 | u8 evt; | |
130 | u8 dlen; | |
131 | } __packed; | |
132 | ||
133 | struct nokia_bt_dev { | |
134 | struct hci_uart hu; | |
135 | struct serdev_device *serdev; | |
136 | ||
137 | struct gpio_desc *reset; | |
138 | struct gpio_desc *wakeup_host; | |
139 | struct gpio_desc *wakeup_bt; | |
140 | unsigned long sysclk_speed; | |
141 | ||
142 | int wake_irq; | |
143 | struct sk_buff *rx_skb; | |
144 | struct sk_buff_head txq; | |
145 | bdaddr_t bdaddr; | |
146 | ||
147 | int init_error; | |
148 | struct completion init_completion; | |
149 | ||
150 | u8 man_id; | |
151 | u8 ver_id; | |
152 | ||
153 | bool initialized; | |
154 | bool tx_enabled; | |
155 | bool rx_enabled; | |
156 | }; | |
157 | ||
158 | static int nokia_enqueue(struct hci_uart *hu, struct sk_buff *skb); | |
159 | ||
160 | static void nokia_flow_control(struct serdev_device *serdev, bool enable) | |
161 | { | |
162 | if (enable) { | |
163 | serdev_device_set_rts(serdev, true); | |
164 | serdev_device_set_flow_control(serdev, true); | |
165 | } else { | |
166 | serdev_device_set_flow_control(serdev, false); | |
167 | serdev_device_set_rts(serdev, false); | |
168 | } | |
169 | } | |
170 | ||
171 | static irqreturn_t wakeup_handler(int irq, void *data) | |
172 | { | |
173 | struct nokia_bt_dev *btdev = data; | |
174 | struct device *dev = &btdev->serdev->dev; | |
175 | int wake_state = gpiod_get_value(btdev->wakeup_host); | |
176 | ||
177 | if (btdev->rx_enabled == wake_state) | |
178 | return IRQ_HANDLED; | |
179 | ||
180 | if (wake_state) | |
181 | pm_runtime_get(dev); | |
182 | else | |
183 | pm_runtime_put(dev); | |
184 | ||
185 | btdev->rx_enabled = wake_state; | |
186 | ||
187 | return IRQ_HANDLED; | |
188 | } | |
189 | ||
190 | static int nokia_reset(struct hci_uart *hu) | |
191 | { | |
192 | struct nokia_bt_dev *btdev = hu->priv; | |
193 | struct device *dev = &btdev->serdev->dev; | |
194 | int err; | |
195 | ||
196 | /* reset routine */ | |
197 | gpiod_set_value_cansleep(btdev->reset, 1); | |
198 | gpiod_set_value_cansleep(btdev->wakeup_bt, 1); | |
199 | ||
200 | msleep(100); | |
201 | ||
202 | /* safety check */ | |
203 | err = gpiod_get_value_cansleep(btdev->wakeup_host); | |
204 | if (err == 1) { | |
205 | dev_err(dev, "reset: host wakeup not low!"); | |
206 | return -EPROTO; | |
207 | } | |
208 | ||
209 | /* flush queue */ | |
210 | serdev_device_write_flush(btdev->serdev); | |
211 | ||
212 | /* init uart */ | |
213 | nokia_flow_control(btdev->serdev, false); | |
214 | serdev_device_set_baudrate(btdev->serdev, INIT_BAUD_RATE); | |
215 | ||
216 | gpiod_set_value_cansleep(btdev->reset, 0); | |
217 | ||
218 | /* wait for cts */ | |
219 | err = serdev_device_wait_for_cts(btdev->serdev, true, 200); | |
220 | if (err < 0) { | |
221 | dev_err(dev, "CTS not received: %d", err); | |
222 | return err; | |
223 | } | |
224 | ||
225 | nokia_flow_control(btdev->serdev, true); | |
226 | ||
227 | return 0; | |
228 | } | |
229 | ||
230 | static int nokia_send_alive_packet(struct hci_uart *hu) | |
231 | { | |
232 | struct nokia_bt_dev *btdev = hu->priv; | |
233 | struct device *dev = &btdev->serdev->dev; | |
234 | struct hci_nokia_alive_hdr *hdr; | |
235 | struct hci_nokia_alive_pkt *pkt; | |
236 | struct sk_buff *skb; | |
237 | int len; | |
238 | ||
239 | init_completion(&btdev->init_completion); | |
240 | ||
241 | len = H4_TYPE_SIZE + sizeof(*hdr) + sizeof(*pkt); | |
242 | skb = bt_skb_alloc(len, GFP_KERNEL); | |
243 | if (!skb) | |
244 | return -ENOMEM; | |
245 | ||
246 | hci_skb_pkt_type(skb) = HCI_NOKIA_ALIVE_PKT; | |
247 | memset(skb->data, 0x00, len); | |
248 | ||
4df864c1 | 249 | hdr = skb_put(skb, sizeof(*hdr)); |
7bb31868 | 250 | hdr->dlen = sizeof(*pkt); |
4df864c1 | 251 | pkt = skb_put(skb, sizeof(*pkt)); |
7bb31868 SR |
252 | pkt->mid = NOKIA_ALIVE_REQ; |
253 | ||
254 | nokia_enqueue(hu, skb); | |
255 | hci_uart_tx_wakeup(hu); | |
256 | ||
257 | dev_dbg(dev, "Alive sent"); | |
258 | ||
259 | if (!wait_for_completion_interruptible_timeout(&btdev->init_completion, | |
260 | msecs_to_jiffies(1000))) { | |
261 | return -ETIMEDOUT; | |
262 | } | |
263 | ||
264 | if (btdev->init_error < 0) | |
265 | return btdev->init_error; | |
266 | ||
267 | return 0; | |
268 | } | |
269 | ||
270 | static int nokia_send_negotiation(struct hci_uart *hu) | |
271 | { | |
272 | struct nokia_bt_dev *btdev = hu->priv; | |
273 | struct device *dev = &btdev->serdev->dev; | |
274 | struct hci_nokia_neg_cmd *neg_cmd; | |
275 | struct hci_nokia_neg_hdr *neg_hdr; | |
276 | struct sk_buff *skb; | |
277 | int len, err; | |
278 | u16 baud = DIV_ROUND_CLOSEST(btdev->sysclk_speed * 10, SETUP_BAUD_RATE); | |
279 | int sysclk = btdev->sysclk_speed / 1000; | |
280 | ||
281 | len = H4_TYPE_SIZE + sizeof(*neg_hdr) + sizeof(*neg_cmd); | |
282 | skb = bt_skb_alloc(len, GFP_KERNEL); | |
283 | if (!skb) | |
284 | return -ENOMEM; | |
285 | ||
286 | hci_skb_pkt_type(skb) = HCI_NOKIA_NEG_PKT; | |
287 | ||
4df864c1 | 288 | neg_hdr = skb_put(skb, sizeof(*neg_hdr)); |
7bb31868 SR |
289 | neg_hdr->dlen = sizeof(*neg_cmd); |
290 | ||
4df864c1 | 291 | neg_cmd = skb_put(skb, sizeof(*neg_cmd)); |
7bb31868 SR |
292 | neg_cmd->ack = NOKIA_NEG_REQ; |
293 | neg_cmd->baud = cpu_to_le16(baud); | |
294 | neg_cmd->unused1 = 0x0000; | |
295 | neg_cmd->proto = NOKIA_PROTO_BYTE; | |
296 | neg_cmd->sys_clk = cpu_to_le16(sysclk); | |
297 | neg_cmd->unused2 = 0x0000; | |
298 | ||
299 | btdev->init_error = 0; | |
300 | init_completion(&btdev->init_completion); | |
301 | ||
302 | nokia_enqueue(hu, skb); | |
303 | hci_uart_tx_wakeup(hu); | |
304 | ||
305 | dev_dbg(dev, "Negotiation sent"); | |
306 | ||
307 | if (!wait_for_completion_interruptible_timeout(&btdev->init_completion, | |
308 | msecs_to_jiffies(10000))) { | |
309 | return -ETIMEDOUT; | |
310 | } | |
311 | ||
312 | if (btdev->init_error < 0) | |
313 | return btdev->init_error; | |
314 | ||
315 | /* Change to previously negotiated speed. Flow Control | |
316 | * is disabled until bluetooth adapter is ready to avoid | |
317 | * broken bytes being received. | |
318 | */ | |
319 | nokia_flow_control(btdev->serdev, false); | |
320 | serdev_device_set_baudrate(btdev->serdev, SETUP_BAUD_RATE); | |
321 | err = serdev_device_wait_for_cts(btdev->serdev, true, 200); | |
322 | if (err < 0) { | |
323 | dev_err(dev, "CTS not received: %d", err); | |
324 | return err; | |
325 | } | |
326 | nokia_flow_control(btdev->serdev, true); | |
327 | ||
328 | dev_dbg(dev, "Negotiation successful"); | |
329 | ||
330 | return 0; | |
331 | } | |
332 | ||
333 | static int nokia_setup_fw(struct hci_uart *hu) | |
334 | { | |
335 | struct nokia_bt_dev *btdev = hu->priv; | |
336 | struct device *dev = &btdev->serdev->dev; | |
337 | const char *fwname; | |
338 | const struct firmware *fw; | |
339 | const u8 *fw_ptr; | |
340 | size_t fw_size; | |
341 | int err; | |
342 | ||
343 | dev_dbg(dev, "setup firmware"); | |
344 | ||
345 | if (btdev->man_id == NOKIA_ID_BCM2048) { | |
346 | fwname = FIRMWARE_BCM2048; | |
347 | } else if (btdev->man_id == NOKIA_ID_TI1271) { | |
348 | fwname = FIRMWARE_TI1271; | |
349 | } else { | |
350 | dev_err(dev, "Unsupported bluetooth device!"); | |
351 | return -ENODEV; | |
352 | } | |
353 | ||
354 | err = request_firmware(&fw, fwname, dev); | |
355 | if (err < 0) { | |
356 | dev_err(dev, "%s: Failed to load Nokia firmware file (%d)", | |
357 | hu->hdev->name, err); | |
358 | return err; | |
359 | } | |
360 | ||
361 | fw_ptr = fw->data; | |
362 | fw_size = fw->size; | |
363 | ||
364 | while (fw_size >= 4) { | |
365 | u16 pkt_size = get_unaligned_le16(fw_ptr); | |
366 | u8 pkt_type = fw_ptr[2]; | |
367 | const struct hci_command_hdr *cmd; | |
368 | u16 opcode; | |
369 | struct sk_buff *skb; | |
370 | ||
371 | switch (pkt_type) { | |
372 | case HCI_COMMAND_PKT: | |
373 | cmd = (struct hci_command_hdr *)(fw_ptr + 3); | |
374 | opcode = le16_to_cpu(cmd->opcode); | |
375 | ||
376 | skb = __hci_cmd_sync(hu->hdev, opcode, cmd->plen, | |
377 | fw_ptr + 3 + HCI_COMMAND_HDR_SIZE, | |
378 | HCI_INIT_TIMEOUT); | |
379 | if (IS_ERR(skb)) { | |
380 | err = PTR_ERR(skb); | |
381 | dev_err(dev, "%s: FW command %04x failed (%d)", | |
382 | hu->hdev->name, opcode, err); | |
383 | goto done; | |
384 | } | |
385 | kfree_skb(skb); | |
386 | break; | |
387 | case HCI_NOKIA_RADIO_PKT: | |
388 | case HCI_NOKIA_NEG_PKT: | |
389 | case HCI_NOKIA_ALIVE_PKT: | |
390 | break; | |
391 | } | |
392 | ||
393 | fw_ptr += pkt_size + 2; | |
394 | fw_size -= pkt_size + 2; | |
395 | } | |
396 | ||
397 | done: | |
398 | release_firmware(fw); | |
399 | return err; | |
400 | } | |
401 | ||
402 | static int nokia_setup(struct hci_uart *hu) | |
403 | { | |
404 | struct nokia_bt_dev *btdev = hu->priv; | |
405 | struct device *dev = &btdev->serdev->dev; | |
406 | int err; | |
407 | ||
408 | btdev->initialized = false; | |
409 | ||
410 | nokia_flow_control(btdev->serdev, false); | |
411 | ||
412 | pm_runtime_get_sync(dev); | |
413 | ||
414 | if (btdev->tx_enabled) { | |
415 | gpiod_set_value_cansleep(btdev->wakeup_bt, 0); | |
416 | pm_runtime_put(&btdev->serdev->dev); | |
417 | btdev->tx_enabled = false; | |
418 | } | |
419 | ||
420 | dev_dbg(dev, "protocol setup"); | |
421 | ||
422 | /* 0. reset connection */ | |
423 | err = nokia_reset(hu); | |
424 | if (err < 0) { | |
425 | dev_err(dev, "Reset failed: %d", err); | |
426 | goto out; | |
427 | } | |
428 | ||
429 | /* 1. negotiate speed etc */ | |
430 | err = nokia_send_negotiation(hu); | |
431 | if (err < 0) { | |
432 | dev_err(dev, "Negotiation failed: %d", err); | |
433 | goto out; | |
434 | } | |
435 | ||
436 | /* 2. verify correct setup using alive packet */ | |
437 | err = nokia_send_alive_packet(hu); | |
438 | if (err < 0) { | |
439 | dev_err(dev, "Alive check failed: %d", err); | |
440 | goto out; | |
441 | } | |
442 | ||
443 | /* 3. send firmware */ | |
444 | err = nokia_setup_fw(hu); | |
445 | if (err < 0) { | |
446 | dev_err(dev, "Could not setup FW: %d", err); | |
447 | goto out; | |
448 | } | |
449 | ||
450 | nokia_flow_control(btdev->serdev, false); | |
451 | serdev_device_set_baudrate(btdev->serdev, MAX_BAUD_RATE); | |
452 | nokia_flow_control(btdev->serdev, true); | |
453 | ||
454 | if (btdev->man_id == NOKIA_ID_BCM2048) { | |
455 | hu->hdev->set_bdaddr = btbcm_set_bdaddr; | |
456 | set_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks); | |
457 | dev_dbg(dev, "bcm2048 has invalid bluetooth address!"); | |
458 | } | |
459 | ||
460 | dev_dbg(dev, "protocol setup done!"); | |
461 | ||
462 | gpiod_set_value_cansleep(btdev->wakeup_bt, 0); | |
463 | pm_runtime_put(dev); | |
464 | btdev->tx_enabled = false; | |
465 | btdev->initialized = true; | |
466 | ||
467 | return 0; | |
468 | out: | |
469 | pm_runtime_put(dev); | |
470 | ||
471 | return err; | |
472 | } | |
473 | ||
474 | static int nokia_open(struct hci_uart *hu) | |
475 | { | |
476 | struct device *dev = &hu->serdev->dev; | |
477 | ||
478 | dev_dbg(dev, "protocol open"); | |
479 | ||
480 | serdev_device_open(hu->serdev); | |
481 | ||
482 | pm_runtime_enable(dev); | |
483 | ||
484 | return 0; | |
485 | } | |
486 | ||
487 | static int nokia_flush(struct hci_uart *hu) | |
488 | { | |
489 | struct nokia_bt_dev *btdev = hu->priv; | |
490 | ||
491 | dev_dbg(&btdev->serdev->dev, "flush device"); | |
492 | ||
493 | skb_queue_purge(&btdev->txq); | |
494 | ||
495 | return 0; | |
496 | } | |
497 | ||
498 | static int nokia_close(struct hci_uart *hu) | |
499 | { | |
500 | struct nokia_bt_dev *btdev = hu->priv; | |
501 | struct device *dev = &btdev->serdev->dev; | |
502 | ||
503 | dev_dbg(dev, "close device"); | |
504 | ||
505 | btdev->initialized = false; | |
506 | ||
507 | skb_queue_purge(&btdev->txq); | |
508 | ||
509 | kfree_skb(btdev->rx_skb); | |
510 | ||
511 | /* disable module */ | |
512 | gpiod_set_value(btdev->reset, 1); | |
513 | gpiod_set_value(btdev->wakeup_bt, 0); | |
514 | ||
515 | pm_runtime_disable(&btdev->serdev->dev); | |
516 | serdev_device_close(btdev->serdev); | |
517 | ||
518 | return 0; | |
519 | } | |
520 | ||
521 | /* Enqueue frame for transmittion (padding, crc, etc) */ | |
522 | static int nokia_enqueue(struct hci_uart *hu, struct sk_buff *skb) | |
523 | { | |
524 | struct nokia_bt_dev *btdev = hu->priv; | |
525 | int err; | |
526 | ||
527 | /* Prepend skb with frame type */ | |
528 | memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); | |
529 | ||
530 | /* Packets must be word aligned */ | |
531 | if (skb->len % 2) { | |
532 | err = skb_pad(skb, 1); | |
533 | if (err) | |
534 | return err; | |
634fef61 | 535 | skb_put_u8(skb, 0x00); |
7bb31868 SR |
536 | } |
537 | ||
538 | skb_queue_tail(&btdev->txq, skb); | |
539 | ||
540 | return 0; | |
541 | } | |
542 | ||
543 | static int nokia_recv_negotiation_packet(struct hci_dev *hdev, | |
544 | struct sk_buff *skb) | |
545 | { | |
546 | struct hci_uart *hu = hci_get_drvdata(hdev); | |
547 | struct nokia_bt_dev *btdev = hu->priv; | |
548 | struct device *dev = &btdev->serdev->dev; | |
549 | struct hci_nokia_neg_hdr *hdr; | |
550 | struct hci_nokia_neg_evt *evt; | |
551 | int ret = 0; | |
552 | ||
553 | hdr = (struct hci_nokia_neg_hdr *)skb->data; | |
554 | if (hdr->dlen != sizeof(*evt)) { | |
555 | btdev->init_error = -EIO; | |
556 | ret = -EIO; | |
557 | goto finish_neg; | |
558 | } | |
559 | ||
af72868b | 560 | evt = skb_pull(skb, sizeof(*hdr)); |
7bb31868 SR |
561 | |
562 | if (evt->ack != NOKIA_NEG_ACK) { | |
563 | dev_err(dev, "Negotiation received: wrong reply"); | |
564 | btdev->init_error = -EINVAL; | |
565 | ret = -EINVAL; | |
566 | goto finish_neg; | |
567 | } | |
568 | ||
569 | btdev->man_id = evt->man_id; | |
570 | btdev->ver_id = evt->ver_id; | |
571 | ||
572 | dev_dbg(dev, "Negotiation received: baud=%u:clk=%u:manu=%u:vers=%u", | |
573 | evt->baud, evt->sys_clk, evt->man_id, evt->ver_id); | |
574 | ||
575 | finish_neg: | |
576 | complete(&btdev->init_completion); | |
577 | kfree_skb(skb); | |
578 | return ret; | |
579 | } | |
580 | ||
581 | static int nokia_recv_alive_packet(struct hci_dev *hdev, struct sk_buff *skb) | |
582 | { | |
583 | struct hci_uart *hu = hci_get_drvdata(hdev); | |
584 | struct nokia_bt_dev *btdev = hu->priv; | |
585 | struct device *dev = &btdev->serdev->dev; | |
586 | struct hci_nokia_alive_hdr *hdr; | |
587 | struct hci_nokia_alive_pkt *pkt; | |
588 | int ret = 0; | |
589 | ||
590 | hdr = (struct hci_nokia_alive_hdr *)skb->data; | |
591 | if (hdr->dlen != sizeof(*pkt)) { | |
592 | dev_err(dev, "Corrupted alive message"); | |
593 | btdev->init_error = -EIO; | |
594 | ret = -EIO; | |
595 | goto finish_alive; | |
596 | } | |
597 | ||
af72868b | 598 | pkt = skb_pull(skb, sizeof(*hdr)); |
7bb31868 SR |
599 | |
600 | if (pkt->mid != NOKIA_ALIVE_RESP) { | |
601 | dev_err(dev, "Alive received: invalid response: 0x%02x!", | |
602 | pkt->mid); | |
603 | btdev->init_error = -EINVAL; | |
604 | ret = -EINVAL; | |
605 | goto finish_alive; | |
606 | } | |
607 | ||
608 | dev_dbg(dev, "Alive received"); | |
609 | ||
610 | finish_alive: | |
611 | complete(&btdev->init_completion); | |
612 | kfree_skb(skb); | |
613 | return ret; | |
614 | } | |
615 | ||
616 | static int nokia_recv_radio(struct hci_dev *hdev, struct sk_buff *skb) | |
617 | { | |
618 | /* Packets received on the dedicated radio channel are | |
619 | * HCI events and so feed them back into the core. | |
620 | */ | |
621 | hci_skb_pkt_type(skb) = HCI_EVENT_PKT; | |
622 | return hci_recv_frame(hdev, skb); | |
623 | } | |
624 | ||
625 | /* Recv data */ | |
626 | static const struct h4_recv_pkt nokia_recv_pkts[] = { | |
627 | { H4_RECV_ACL, .recv = hci_recv_frame }, | |
628 | { H4_RECV_SCO, .recv = hci_recv_frame }, | |
629 | { H4_RECV_EVENT, .recv = hci_recv_frame }, | |
630 | { NOKIA_RECV_ALIVE, .recv = nokia_recv_alive_packet }, | |
631 | { NOKIA_RECV_NEG, .recv = nokia_recv_negotiation_packet }, | |
632 | { NOKIA_RECV_RADIO, .recv = nokia_recv_radio }, | |
633 | }; | |
634 | ||
635 | static int nokia_recv(struct hci_uart *hu, const void *data, int count) | |
636 | { | |
637 | struct nokia_bt_dev *btdev = hu->priv; | |
638 | struct device *dev = &btdev->serdev->dev; | |
639 | int err; | |
640 | ||
641 | if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) | |
642 | return -EUNATCH; | |
643 | ||
644 | btdev->rx_skb = h4_recv_buf(hu->hdev, btdev->rx_skb, data, count, | |
645 | nokia_recv_pkts, ARRAY_SIZE(nokia_recv_pkts)); | |
646 | if (IS_ERR(btdev->rx_skb)) { | |
647 | err = PTR_ERR(btdev->rx_skb); | |
648 | dev_err(dev, "Frame reassembly failed (%d)", err); | |
649 | btdev->rx_skb = NULL; | |
650 | return err; | |
651 | } | |
652 | ||
653 | return count; | |
654 | } | |
655 | ||
656 | static struct sk_buff *nokia_dequeue(struct hci_uart *hu) | |
657 | { | |
658 | struct nokia_bt_dev *btdev = hu->priv; | |
659 | struct device *dev = &btdev->serdev->dev; | |
660 | struct sk_buff *result = skb_dequeue(&btdev->txq); | |
661 | ||
662 | if (!btdev->initialized) | |
663 | return result; | |
664 | ||
665 | if (btdev->tx_enabled == !!result) | |
666 | return result; | |
667 | ||
668 | if (result) { | |
669 | pm_runtime_get_sync(dev); | |
670 | gpiod_set_value_cansleep(btdev->wakeup_bt, 1); | |
671 | } else { | |
672 | serdev_device_wait_until_sent(btdev->serdev, 0); | |
673 | gpiod_set_value_cansleep(btdev->wakeup_bt, 0); | |
674 | pm_runtime_put(dev); | |
675 | } | |
676 | ||
677 | btdev->tx_enabled = !!result; | |
678 | ||
679 | return result; | |
680 | } | |
681 | ||
682 | static const struct hci_uart_proto nokia_proto = { | |
683 | .id = HCI_UART_NOKIA, | |
684 | .name = "Nokia", | |
685 | .open = nokia_open, | |
686 | .close = nokia_close, | |
687 | .recv = nokia_recv, | |
688 | .enqueue = nokia_enqueue, | |
689 | .dequeue = nokia_dequeue, | |
690 | .flush = nokia_flush, | |
691 | .setup = nokia_setup, | |
692 | .manufacturer = 1, | |
693 | }; | |
694 | ||
695 | static int nokia_bluetooth_serdev_probe(struct serdev_device *serdev) | |
696 | { | |
697 | struct device *dev = &serdev->dev; | |
698 | struct nokia_bt_dev *btdev; | |
699 | struct clk *sysclk; | |
700 | int err = 0; | |
701 | ||
702 | btdev = devm_kzalloc(dev, sizeof(*btdev), GFP_KERNEL); | |
703 | if (!btdev) | |
704 | return -ENOMEM; | |
705 | ||
706 | btdev->hu.serdev = btdev->serdev = serdev; | |
707 | serdev_device_set_drvdata(serdev, btdev); | |
708 | ||
709 | btdev->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); | |
710 | if (IS_ERR(btdev->reset)) { | |
711 | err = PTR_ERR(btdev->reset); | |
712 | dev_err(dev, "could not get reset gpio: %d", err); | |
713 | return err; | |
714 | } | |
715 | ||
716 | btdev->wakeup_host = devm_gpiod_get(dev, "host-wakeup", GPIOD_IN); | |
717 | if (IS_ERR(btdev->wakeup_host)) { | |
718 | err = PTR_ERR(btdev->wakeup_host); | |
719 | dev_err(dev, "could not get host wakeup gpio: %d", err); | |
720 | return err; | |
721 | } | |
722 | ||
723 | btdev->wake_irq = gpiod_to_irq(btdev->wakeup_host); | |
724 | ||
725 | err = devm_request_threaded_irq(dev, btdev->wake_irq, NULL, | |
726 | wakeup_handler, | |
727 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | |
728 | "wakeup", btdev); | |
729 | if (err) { | |
730 | dev_err(dev, "could request wakeup irq: %d", err); | |
731 | return err; | |
732 | } | |
733 | ||
734 | btdev->wakeup_bt = devm_gpiod_get(dev, "bluetooth-wakeup", | |
735 | GPIOD_OUT_LOW); | |
736 | if (IS_ERR(btdev->wakeup_bt)) { | |
737 | err = PTR_ERR(btdev->wakeup_bt); | |
738 | dev_err(dev, "could not get BT wakeup gpio: %d", err); | |
739 | return err; | |
740 | } | |
741 | ||
742 | sysclk = devm_clk_get(dev, "sysclk"); | |
743 | if (IS_ERR(sysclk)) { | |
744 | err = PTR_ERR(sysclk); | |
745 | dev_err(dev, "could not get sysclk: %d", err); | |
746 | return err; | |
747 | } | |
748 | ||
749 | clk_prepare_enable(sysclk); | |
750 | btdev->sysclk_speed = clk_get_rate(sysclk); | |
751 | clk_disable_unprepare(sysclk); | |
752 | ||
753 | skb_queue_head_init(&btdev->txq); | |
754 | ||
755 | btdev->hu.priv = btdev; | |
756 | btdev->hu.alignment = 2; /* Nokia H4+ is word aligned */ | |
757 | ||
758 | err = hci_uart_register_device(&btdev->hu, &nokia_proto); | |
759 | if (err) { | |
760 | dev_err(dev, "could not register bluetooth uart: %d", err); | |
761 | return err; | |
762 | } | |
763 | ||
764 | return 0; | |
765 | } | |
766 | ||
767 | static void nokia_bluetooth_serdev_remove(struct serdev_device *serdev) | |
768 | { | |
769 | struct nokia_bt_dev *btdev = serdev_device_get_drvdata(serdev); | |
7bb31868 | 770 | |
05f2a0bc | 771 | hci_uart_unregister_device(&btdev->hu); |
7bb31868 SR |
772 | } |
773 | ||
774 | static int nokia_bluetooth_runtime_suspend(struct device *dev) | |
775 | { | |
776 | struct serdev_device *serdev = to_serdev_device(dev); | |
777 | ||
778 | nokia_flow_control(serdev, false); | |
779 | return 0; | |
780 | } | |
781 | ||
782 | static int nokia_bluetooth_runtime_resume(struct device *dev) | |
783 | { | |
784 | struct serdev_device *serdev = to_serdev_device(dev); | |
785 | ||
786 | nokia_flow_control(serdev, true); | |
787 | return 0; | |
788 | } | |
789 | ||
790 | static const struct dev_pm_ops nokia_bluetooth_pm_ops = { | |
791 | SET_RUNTIME_PM_OPS(nokia_bluetooth_runtime_suspend, | |
792 | nokia_bluetooth_runtime_resume, | |
793 | NULL) | |
794 | }; | |
795 | ||
796 | #ifdef CONFIG_OF | |
797 | static const struct of_device_id nokia_bluetooth_of_match[] = { | |
798 | { .compatible = "nokia,h4p-bluetooth", }, | |
799 | {}, | |
800 | }; | |
801 | MODULE_DEVICE_TABLE(of, nokia_bluetooth_of_match); | |
802 | #endif | |
803 | ||
804 | static struct serdev_device_driver nokia_bluetooth_serdev_driver = { | |
805 | .probe = nokia_bluetooth_serdev_probe, | |
806 | .remove = nokia_bluetooth_serdev_remove, | |
807 | .driver = { | |
808 | .name = "nokia-bluetooth", | |
809 | .pm = &nokia_bluetooth_pm_ops, | |
810 | .of_match_table = of_match_ptr(nokia_bluetooth_of_match), | |
811 | }, | |
812 | }; | |
813 | ||
814 | module_serdev_device_driver(nokia_bluetooth_serdev_driver); | |
377a6eac FD |
815 | |
816 | MODULE_AUTHOR("Sebastian Reichel <sre@kernel.org>"); | |
817 | MODULE_DESCRIPTION("Bluetooth HCI UART Nokia H4+ driver ver " VERSION); | |
818 | MODULE_VERSION(VERSION); | |
819 | MODULE_LICENSE("GPL"); |