1 From e7eaf003090c6b2e56ce1d39b30b221ed7283de3 Mon Sep 17 00:00:00 2001
2 From: Alvin Park <alvin.park.pv@renesas.com>
3 Date: Thu, 17 Mar 2022 19:39:57 +0900
4 Subject: [PATCH] Support for Renesas Bluetooth Low Energy HCI over UART
7 drivers/bluetooth/Kconfig | 13 +
8 drivers/bluetooth/Makefile | 1 +
9 drivers/bluetooth/hci_ldisc.c | 6 +
10 drivers/bluetooth/hci_renesas.c | 474 ++++++++++++++++++++++++++++++++
11 drivers/bluetooth/hci_uart.h | 8 +-
12 5 files changed, 501 insertions(+), 1 deletion(-)
13 create mode 100644 drivers/bluetooth/hci_renesas.c
15 --- a/drivers/bluetooth/Kconfig
16 +++ b/drivers/bluetooth/Kconfig
17 @@ -257,6 +257,19 @@ config BT_HCIUART_MRVL
19 Say Y here to compile support for HCI MRVL protocol.
21 +config BT_HCIUART_RENESAS
22 + bool "Renesas protocol support"
23 + depends on BT_HCIUART
24 + depends on BT_HCIUART_SERDEV
25 + select BT_HCIUART_H4
27 + The Renesas protocol support enables Bluetooth Low Energy HCI
29 + This protocol is required for the Renesas Bluetooth Low Energy
30 + devices with UART interface.
32 + Say Y here to compile support for HCI Renesas protocol.
35 tristate "HCI BCM203x USB driver"
37 --- a/drivers/bluetooth/Makefile
38 +++ b/drivers/bluetooth/Makefile
39 @@ -47,4 +47,5 @@ hci_uart-$(CONFIG_BT_HCIUART_BCM) += hci
40 hci_uart-$(CONFIG_BT_HCIUART_QCA) += hci_qca.o
41 hci_uart-$(CONFIG_BT_HCIUART_AG6XX) += hci_ag6xx.o
42 hci_uart-$(CONFIG_BT_HCIUART_MRVL) += hci_mrvl.o
43 +hci_uart-$(CONFIG_BT_HCIUART_RENESAS) += hci_renesas.o
44 hci_uart-objs := $(hci_uart-y)
45 --- a/drivers/bluetooth/hci_ldisc.c
46 +++ b/drivers/bluetooth/hci_ldisc.c
47 @@ -880,6 +880,9 @@ static int __init hci_uart_init(void)
48 #ifdef CONFIG_BT_HCIUART_MRVL
51 +#ifdef CONFIG_BT_HCIUART_RENESAS
57 @@ -916,6 +919,9 @@ static void __exit hci_uart_exit(void)
58 #ifdef CONFIG_BT_HCIUART_MRVL
61 +#ifdef CONFIG_BT_HCIUART_RENESAS
65 tty_unregister_ldisc(&hci_uart_ldisc);
68 +++ b/drivers/bluetooth/hci_renesas.c
70 +// SPDX-License-Identifier: GPL-2.0-or-later
72 + * Renesas Bluetooth Low Energy HCI UART driver
74 + * Copyright (C) 2022 Renesas Electroics Corp.
76 + * Alvin Park <alvin.park.pv@renesas.com>
78 + * This file is subject to the terms and conditions of the GNU General Public
79 + * License. See the file "COPYING" in the main directory of this archive
83 +#include <linux/kernel.h>
84 +#include <linux/errno.h>
85 +#include <linux/skbuff.h>
86 +#include <linux/firmware.h>
87 +#include <linux/module.h>
88 +#include <linux/of.h>
89 +#include <linux/serdev.h>
90 +#include <net/bluetooth/bluetooth.h>
91 +#include <net/bluetooth/hci_core.h>
93 +#include "hci_uart.h"
96 + STATE_FW_STX_PENDING,
97 + STATE_FW_ACK_PENDING,
98 + STATE_FW_CRC_PENDING
113 +#define CRC_INIT 0x00
115 +struct renesas_serdev {
116 + struct hci_uart hu;
119 +struct renesas_data {
120 + struct sk_buff *rx_skb;
121 + struct sk_buff_head txq;
122 + struct sk_buff_head rawq;
123 + unsigned long flags;
124 + unsigned int state;
125 + u8 id, rev, fw_crc;
128 +static const struct h4_recv_pkt renesas_recv_pkts[] = {
129 + { H4_RECV_ACL, .recv = hci_recv_frame },
130 + { H4_RECV_SCO, .recv = hci_recv_frame },
131 + { H4_RECV_EVENT, .recv = hci_recv_frame },
134 +static int renesas_open(struct hci_uart *hu)
136 + struct renesas_data *rdata;
139 + BT_DBG("hu %p", hu);
141 + if (!hci_uart_has_flow_control(hu))
142 + return -EOPNOTSUPP;
144 + rdata = kzalloc(sizeof(*rdata), GFP_KERNEL);
148 + skb_queue_head_init(&rdata->txq);
149 + skb_queue_head_init(&rdata->rawq);
154 + ret = serdev_device_open(hu->serdev);
164 +static int renesas_close(struct hci_uart *hu)
166 + struct renesas_data *rdata = hu->priv;
168 + BT_DBG("hu %p", hu);
171 + serdev_device_close(hu->serdev);
173 + skb_queue_purge(&rdata->txq);
174 + skb_queue_purge(&rdata->rawq);
175 + kfree_skb(rdata->rx_skb);
182 +static int renesas_flush(struct hci_uart *hu)
184 + struct renesas_data *rdata = hu->priv;
186 + BT_DBG("hu %p", hu);
188 + skb_queue_purge(&rdata->txq);
189 + skb_queue_purge(&rdata->rawq);
194 +static int renesas_send_ack(struct hci_uart *hu, unsigned char type)
196 + struct renesas_data *rdata = hu->priv;
197 + struct sk_buff *skb;
199 + skb = alloc_skb(1, GFP_ATOMIC);
201 + bt_dev_err(hu->hdev, "Unable to alloc ack/nak packet");
204 + skb_put_u8(skb, type);
206 + skb_queue_tail(&rdata->rawq, skb);
207 + hci_uart_tx_wakeup(hu);
212 +static int renesas_send_fw_size(struct hci_uart *hu, u16 length)
214 + struct renesas_data *rdata = hu->priv;
215 + struct sk_buff *skb;
217 + skb = alloc_skb(3, GFP_ATOMIC);
219 + bt_dev_err(hu->hdev, "Failed to alloc mem for FW size packet");
223 + skb_put_u8(skb, SOH);
224 + skb_put_u8(skb, length);
225 + skb_put_u8(skb, length>>8);
227 + skb_queue_tail(&rdata->rawq, skb);
228 + hci_uart_tx_wakeup(hu);
233 +static int renesas_load_firmware(struct hci_dev *hdev, const char *name)
235 + struct hci_uart *hu = hci_get_drvdata(hdev);
236 + struct renesas_data *rdata = hu->priv;
237 + const struct firmware *fw = NULL;
238 + const u8 *fw_ptr, *fw_max;
242 + err = request_firmware(&fw, name, &hdev->dev);
244 + bt_dev_err(hdev, "Failed to load firmware file %s", name);
249 + fw_max = fw->data + fw->size;
250 + fw_size = fw->size;
252 + bt_dev_info(hdev, "Loading %s", name);
255 + for (i = 0; i < fw->size; i++)
256 + rdata->fw_crc ^= fw_ptr[i];
258 + rdata->state = STATE_FW_INIT;
259 + set_bit(STATE_FW_STX_PENDING, &rdata->flags);
261 + while (rdata->state != STATE_FW_DONE) {
262 + struct sk_buff *skb;
264 + /* Controller drives the firmware load by sending firmware
265 + * request packets containing the expected fragment size.
267 + err = wait_on_bit_timeout(&rdata->flags, STATE_FW_STX_PENDING,
268 + TASK_INTERRUPTIBLE,
269 + msecs_to_jiffies(5000));
271 + bt_dev_err(hdev, "Firmware load interrupted");
275 + bt_dev_err(hdev, "Firmware request timeout");
280 + switch(rdata->state) {
281 + case STATE_FW_INIT:
282 + bt_dev_dbg(hdev, "Firmware request, expecting %d bytes",
285 + set_bit(STATE_FW_ACK_PENDING, &rdata->flags);
286 + err = renesas_send_fw_size(hu, fw_size);
291 + rdata->state = STATE_FW_SIZE;
294 + case STATE_FW_SIZE:
295 + err = wait_on_bit_timeout(&rdata->flags, STATE_FW_ACK_PENDING,
296 + TASK_INTERRUPTIBLE,
297 + msecs_to_jiffies(2000));
299 + bt_dev_err(hdev, "Firmware load interrupted");
303 + bt_dev_err(hdev, "Firmware request timeout");
308 + set_bit(STATE_FW_CRC_PENDING, &rdata->flags);
310 + skb = alloc_skb(fw_size, GFP_KERNEL);
312 + bt_dev_err(hdev, "Failed to alloc mem for FW packet");
316 + skb_put_data(skb, fw_ptr, fw_size);
317 + skb_queue_tail(&rdata->rawq, skb);
318 + hci_uart_tx_wakeup(hu);
320 + rdata->state = STATE_FW_PROG;
323 + case STATE_FW_PROG:
324 + err = wait_on_bit_timeout(&rdata->flags, STATE_FW_CRC_PENDING,
325 + TASK_INTERRUPTIBLE,
326 + msecs_to_jiffies(2000));
328 + bt_dev_err(hdev, "Firmware load interrupted");
332 + bt_dev_err(hdev, "Firmware request timeout");
337 + err = renesas_send_ack(hu, ACK);
342 + bt_dev_dbg(hdev, "Firmware has been loaded");
344 + set_bit(STATE_FW_STX_PENDING, &rdata->flags);
345 + rdata->state = STATE_FW_DONE;
357 + release_firmware(fw);
361 +static int renesas_setup(struct hci_uart *hu)
363 + struct renesas_data *rdata = hu->priv;
366 + hci_uart_set_flow_control(hu, true);
368 + err = renesas_load_firmware(hu->hdev, "renesas/hci_531.bin");
372 + /* wait for HCI application to start */
373 + usleep_range(8000, 10000);
375 + rdata->state = STATE_FW_BOOTED;
377 + hci_uart_set_flow_control(hu, false);
382 +static int renesas_recv(struct hci_uart *hu, const void *data, int count)
384 + struct renesas_data *rdata = hu->priv;
385 + u8 *data_ptr = (u8 *)data;
387 + switch(rdata->state) {
388 + case STATE_FW_INIT:
389 + if (*data_ptr == STX) {
390 + if (!test_bit(STATE_FW_STX_PENDING, &rdata->flags)) {
391 + bt_dev_err(hu->hdev, "Received unexpected STX");
394 + clear_bit(STATE_FW_STX_PENDING, &rdata->flags);
395 + wake_up_bit(&rdata->flags, STATE_FW_STX_PENDING);
399 + case STATE_FW_SIZE:
400 + if (*data_ptr == ACK) {
401 + if (!test_bit(STATE_FW_ACK_PENDING, &rdata->flags)) {
402 + bt_dev_err(hu->hdev, "Received unexpected ACK");
405 + clear_bit(STATE_FW_ACK_PENDING, &rdata->flags);
406 + wake_up_bit(&rdata->flags, STATE_FW_ACK_PENDING);
408 + bt_dev_err(hu->hdev, "Received unexpected data (%x)", *data_ptr);
413 + case STATE_FW_PROG:
414 + if (!test_bit(STATE_FW_CRC_PENDING, &rdata->flags)) {
415 + bt_dev_err(hu->hdev, "Received unexpected CRC");
419 + if (rdata->fw_crc != *data_ptr) {
420 + bt_dev_err(hu->hdev, "Received CRC %02x, "
421 + "which does not match "
422 + "computed CRC %02x.\n",
423 + *data_ptr, rdata->fw_crc);
427 + clear_bit(STATE_FW_CRC_PENDING, &rdata->flags);
428 + wake_up_bit(&rdata->flags, STATE_FW_CRC_PENDING);
431 + case STATE_FW_DONE:
435 + case STATE_FW_BOOTED:
436 + rdata->rx_skb = h4_recv_buf(hu->hdev, rdata->rx_skb, data, count,
438 + ARRAY_SIZE(renesas_recv_pkts));
439 + if (IS_ERR(rdata->rx_skb)) {
440 + int err = PTR_ERR(rdata->rx_skb);
441 + bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
442 + rdata->rx_skb = NULL;
448 + bt_dev_err(hu->hdev, "Unknown state (%d)", rdata->state);
455 +static int renesas_enqueue(struct hci_uart *hu, struct sk_buff *skb)
457 + struct renesas_data *rdata = hu->priv;
459 + skb_queue_tail(&rdata->txq, skb);
463 +static struct sk_buff *renesas_dequeue(struct hci_uart *hu)
465 + struct renesas_data *rdata = hu->priv;
466 + struct sk_buff *skb;
468 + skb = skb_dequeue(&rdata->txq);
470 + /* Any raw data ? */
471 + skb = skb_dequeue(&rdata->rawq);
473 + /* Prepend skb with frame type */
474 + memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
480 +static const struct hci_uart_proto renesas_proto = {
481 + .id = HCI_UART_RENESAS,
483 + .init_speed = 115200,
484 + .open = renesas_open,
485 + .close = renesas_close,
486 + .flush = renesas_flush,
487 + .setup = renesas_setup,
488 + .recv = renesas_recv,
489 + .enqueue = renesas_enqueue,
490 + .dequeue = renesas_dequeue,
493 +static int renesas_serdev_probe(struct serdev_device *serdev)
495 + struct renesas_serdev *rdatadev;
497 + rdatadev = devm_kzalloc(&serdev->dev, sizeof(*rdatadev), GFP_KERNEL);
501 + rdatadev->hu.serdev = serdev;
502 + serdev_device_set_drvdata(serdev, rdatadev);
504 + return hci_uart_register_device(&rdatadev->hu, &renesas_proto);
507 +static void renesas_serdev_remove(struct serdev_device *serdev)
509 + struct renesas_serdev *rdatadev = serdev_device_get_drvdata(serdev);
511 + hci_uart_unregister_device(&rdatadev->hu);
515 +static const struct of_device_id renesas_bluetooth_of_match[] = {
516 + { .compatible = "renesas,DA14531" },
519 +MODULE_DEVICE_TABLE(of, renesas_bluetooth_of_match);
522 +static struct serdev_device_driver renesas_serdev_driver = {
523 + .probe = renesas_serdev_probe,
524 + .remove = renesas_serdev_remove,
526 + .name = "hci_uart_renesas",
527 + .of_match_table = of_match_ptr(renesas_bluetooth_of_match),
531 +int __init renesas_init(void)
533 + serdev_device_driver_register(&renesas_serdev_driver);
535 + return hci_uart_register_proto(&renesas_proto);
538 +int __exit renesas_deinit(void)
540 + serdev_device_driver_unregister(&renesas_serdev_driver);
542 + return hci_uart_unregister_proto(&renesas_proto);
544 --- a/drivers/bluetooth/hci_uart.h
545 +++ b/drivers/bluetooth/hci_uart.h
547 #define HCIUARTGETFLAGS _IOR('U', 204, int)
550 -#define HCI_UART_MAX_PROTO 12
551 +#define HCI_UART_MAX_PROTO 13
553 #define HCI_UART_H4 0
554 #define HCI_UART_BCSP 1
556 #define HCI_UART_AG6XX 9
557 #define HCI_UART_NOKIA 10
558 #define HCI_UART_MRVL 11
559 +#define HCI_UART_RENESAS 12
561 #define HCI_UART_RAW_DEVICE 0
562 #define HCI_UART_RESET_ON_INIT 1
563 @@ -200,3 +201,8 @@ int ag6xx_deinit(void);
565 int mrvl_deinit(void);
568 +#ifdef CONFIG_BT_HCIUART_RENESAS
569 +int renesas_init(void);
570 +int renesas_deinit(void);