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