162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  Texas Instruments' Bluetooth HCILL UART protocol
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  HCILL (HCI Low Level) is a Texas Instruments' power management
662306a36Sopenharmony_ci *  protocol extension to H4.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci *  Copyright (C) 2007 Texas Instruments, Inc.
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci *  Written by Ohad Ben-Cohen <ohad@bencohen.org>
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci *  Acknowledgements:
1362306a36Sopenharmony_ci *  This file is based on hci_h4.c, which was written
1462306a36Sopenharmony_ci *  by Maxim Krasnyansky and Marcel Holtmann.
1562306a36Sopenharmony_ci */
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include <linux/module.h>
1862306a36Sopenharmony_ci#include <linux/kernel.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include <linux/init.h>
2162306a36Sopenharmony_ci#include <linux/sched.h>
2262306a36Sopenharmony_ci#include <linux/types.h>
2362306a36Sopenharmony_ci#include <linux/fcntl.h>
2462306a36Sopenharmony_ci#include <linux/firmware.h>
2562306a36Sopenharmony_ci#include <linux/interrupt.h>
2662306a36Sopenharmony_ci#include <linux/ptrace.h>
2762306a36Sopenharmony_ci#include <linux/poll.h>
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#include <linux/slab.h>
3062306a36Sopenharmony_ci#include <linux/errno.h>
3162306a36Sopenharmony_ci#include <linux/string.h>
3262306a36Sopenharmony_ci#include <linux/signal.h>
3362306a36Sopenharmony_ci#include <linux/ioctl.h>
3462306a36Sopenharmony_ci#include <linux/of.h>
3562306a36Sopenharmony_ci#include <linux/serdev.h>
3662306a36Sopenharmony_ci#include <linux/skbuff.h>
3762306a36Sopenharmony_ci#include <linux/ti_wilink_st.h>
3862306a36Sopenharmony_ci#include <linux/clk.h>
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#include <net/bluetooth/bluetooth.h>
4162306a36Sopenharmony_ci#include <net/bluetooth/hci_core.h>
4262306a36Sopenharmony_ci#include <linux/gpio/consumer.h>
4362306a36Sopenharmony_ci#include <linux/nvmem-consumer.h>
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#include "hci_uart.h"
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci/* Vendor-specific HCI commands */
4862306a36Sopenharmony_ci#define HCI_VS_WRITE_BD_ADDR			0xfc06
4962306a36Sopenharmony_ci#define HCI_VS_UPDATE_UART_HCI_BAUDRATE		0xff36
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci/* HCILL commands */
5262306a36Sopenharmony_ci#define HCILL_GO_TO_SLEEP_IND	0x30
5362306a36Sopenharmony_ci#define HCILL_GO_TO_SLEEP_ACK	0x31
5462306a36Sopenharmony_ci#define HCILL_WAKE_UP_IND	0x32
5562306a36Sopenharmony_ci#define HCILL_WAKE_UP_ACK	0x33
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/* HCILL states */
5862306a36Sopenharmony_cienum hcill_states_e {
5962306a36Sopenharmony_ci	HCILL_ASLEEP,
6062306a36Sopenharmony_ci	HCILL_ASLEEP_TO_AWAKE,
6162306a36Sopenharmony_ci	HCILL_AWAKE,
6262306a36Sopenharmony_ci	HCILL_AWAKE_TO_ASLEEP
6362306a36Sopenharmony_ci};
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cistruct ll_device {
6662306a36Sopenharmony_ci	struct hci_uart hu;
6762306a36Sopenharmony_ci	struct serdev_device *serdev;
6862306a36Sopenharmony_ci	struct gpio_desc *enable_gpio;
6962306a36Sopenharmony_ci	struct clk *ext_clk;
7062306a36Sopenharmony_ci	bdaddr_t bdaddr;
7162306a36Sopenharmony_ci};
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_cistruct ll_struct {
7462306a36Sopenharmony_ci	struct sk_buff *rx_skb;
7562306a36Sopenharmony_ci	struct sk_buff_head txq;
7662306a36Sopenharmony_ci	spinlock_t hcill_lock;		/* HCILL state lock	*/
7762306a36Sopenharmony_ci	unsigned long hcill_state;	/* HCILL power state	*/
7862306a36Sopenharmony_ci	struct sk_buff_head tx_wait_q;	/* HCILL wait queue	*/
7962306a36Sopenharmony_ci};
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci/*
8262306a36Sopenharmony_ci * Builds and sends an HCILL command packet.
8362306a36Sopenharmony_ci * These are very simple packets with only 1 cmd byte
8462306a36Sopenharmony_ci */
8562306a36Sopenharmony_cistatic int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
8662306a36Sopenharmony_ci{
8762306a36Sopenharmony_ci	int err = 0;
8862306a36Sopenharmony_ci	struct sk_buff *skb = NULL;
8962306a36Sopenharmony_ci	struct ll_struct *ll = hu->priv;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	BT_DBG("hu %p cmd 0x%x", hu, cmd);
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	/* allocate packet */
9462306a36Sopenharmony_ci	skb = bt_skb_alloc(1, GFP_ATOMIC);
9562306a36Sopenharmony_ci	if (!skb) {
9662306a36Sopenharmony_ci		BT_ERR("cannot allocate memory for HCILL packet");
9762306a36Sopenharmony_ci		err = -ENOMEM;
9862306a36Sopenharmony_ci		goto out;
9962306a36Sopenharmony_ci	}
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	/* prepare packet */
10262306a36Sopenharmony_ci	skb_put_u8(skb, cmd);
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	/* send packet */
10562306a36Sopenharmony_ci	skb_queue_tail(&ll->txq, skb);
10662306a36Sopenharmony_ciout:
10762306a36Sopenharmony_ci	return err;
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci/* Initialize protocol */
11162306a36Sopenharmony_cistatic int ll_open(struct hci_uart *hu)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	struct ll_struct *ll;
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	BT_DBG("hu %p", hu);
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	ll = kzalloc(sizeof(*ll), GFP_KERNEL);
11862306a36Sopenharmony_ci	if (!ll)
11962306a36Sopenharmony_ci		return -ENOMEM;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	skb_queue_head_init(&ll->txq);
12262306a36Sopenharmony_ci	skb_queue_head_init(&ll->tx_wait_q);
12362306a36Sopenharmony_ci	spin_lock_init(&ll->hcill_lock);
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	ll->hcill_state = HCILL_AWAKE;
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	hu->priv = ll;
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	if (hu->serdev) {
13062306a36Sopenharmony_ci		struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev);
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci		if (!IS_ERR(lldev->ext_clk))
13362306a36Sopenharmony_ci			clk_prepare_enable(lldev->ext_clk);
13462306a36Sopenharmony_ci	}
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	return 0;
13762306a36Sopenharmony_ci}
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci/* Flush protocol data */
14062306a36Sopenharmony_cistatic int ll_flush(struct hci_uart *hu)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	struct ll_struct *ll = hu->priv;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	BT_DBG("hu %p", hu);
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	skb_queue_purge(&ll->tx_wait_q);
14762306a36Sopenharmony_ci	skb_queue_purge(&ll->txq);
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	return 0;
15062306a36Sopenharmony_ci}
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci/* Close protocol */
15362306a36Sopenharmony_cistatic int ll_close(struct hci_uart *hu)
15462306a36Sopenharmony_ci{
15562306a36Sopenharmony_ci	struct ll_struct *ll = hu->priv;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	BT_DBG("hu %p", hu);
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	skb_queue_purge(&ll->tx_wait_q);
16062306a36Sopenharmony_ci	skb_queue_purge(&ll->txq);
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	kfree_skb(ll->rx_skb);
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci	if (hu->serdev) {
16562306a36Sopenharmony_ci		struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev);
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci		gpiod_set_value_cansleep(lldev->enable_gpio, 0);
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci		clk_disable_unprepare(lldev->ext_clk);
17062306a36Sopenharmony_ci	}
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	hu->priv = NULL;
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	kfree(ll);
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	return 0;
17762306a36Sopenharmony_ci}
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci/*
18062306a36Sopenharmony_ci * internal function, which does common work of the device wake up process:
18162306a36Sopenharmony_ci * 1. places all pending packets (waiting in tx_wait_q list) in txq list.
18262306a36Sopenharmony_ci * 2. changes internal state to HCILL_AWAKE.
18362306a36Sopenharmony_ci * Note: assumes that hcill_lock spinlock is taken,
18462306a36Sopenharmony_ci * shouldn't be called otherwise!
18562306a36Sopenharmony_ci */
18662306a36Sopenharmony_cistatic void __ll_do_awake(struct ll_struct *ll)
18762306a36Sopenharmony_ci{
18862306a36Sopenharmony_ci	struct sk_buff *skb = NULL;
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	while ((skb = skb_dequeue(&ll->tx_wait_q)))
19162306a36Sopenharmony_ci		skb_queue_tail(&ll->txq, skb);
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	ll->hcill_state = HCILL_AWAKE;
19462306a36Sopenharmony_ci}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci/*
19762306a36Sopenharmony_ci * Called upon a wake-up-indication from the device
19862306a36Sopenharmony_ci */
19962306a36Sopenharmony_cistatic void ll_device_want_to_wakeup(struct hci_uart *hu)
20062306a36Sopenharmony_ci{
20162306a36Sopenharmony_ci	unsigned long flags;
20262306a36Sopenharmony_ci	struct ll_struct *ll = hu->priv;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	BT_DBG("hu %p", hu);
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	/* lock hcill state */
20762306a36Sopenharmony_ci	spin_lock_irqsave(&ll->hcill_lock, flags);
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	switch (ll->hcill_state) {
21062306a36Sopenharmony_ci	case HCILL_ASLEEP_TO_AWAKE:
21162306a36Sopenharmony_ci		/*
21262306a36Sopenharmony_ci		 * This state means that both the host and the BRF chip
21362306a36Sopenharmony_ci		 * have simultaneously sent a wake-up-indication packet.
21462306a36Sopenharmony_ci		 * Traditionally, in this case, receiving a wake-up-indication
21562306a36Sopenharmony_ci		 * was enough and an additional wake-up-ack wasn't needed.
21662306a36Sopenharmony_ci		 * This has changed with the BRF6350, which does require an
21762306a36Sopenharmony_ci		 * explicit wake-up-ack. Other BRF versions, which do not
21862306a36Sopenharmony_ci		 * require an explicit ack here, do accept it, thus it is
21962306a36Sopenharmony_ci		 * perfectly safe to always send one.
22062306a36Sopenharmony_ci		 */
22162306a36Sopenharmony_ci		BT_DBG("dual wake-up-indication");
22262306a36Sopenharmony_ci		fallthrough;
22362306a36Sopenharmony_ci	case HCILL_ASLEEP:
22462306a36Sopenharmony_ci		/* acknowledge device wake up */
22562306a36Sopenharmony_ci		if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) {
22662306a36Sopenharmony_ci			BT_ERR("cannot acknowledge device wake up");
22762306a36Sopenharmony_ci			goto out;
22862306a36Sopenharmony_ci		}
22962306a36Sopenharmony_ci		break;
23062306a36Sopenharmony_ci	default:
23162306a36Sopenharmony_ci		/* any other state is illegal */
23262306a36Sopenharmony_ci		BT_ERR("received HCILL_WAKE_UP_IND in state %ld",
23362306a36Sopenharmony_ci		       ll->hcill_state);
23462306a36Sopenharmony_ci		break;
23562306a36Sopenharmony_ci	}
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	/* send pending packets and change state to HCILL_AWAKE */
23862306a36Sopenharmony_ci	__ll_do_awake(ll);
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ciout:
24162306a36Sopenharmony_ci	spin_unlock_irqrestore(&ll->hcill_lock, flags);
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	/* actually send the packets */
24462306a36Sopenharmony_ci	hci_uart_tx_wakeup(hu);
24562306a36Sopenharmony_ci}
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci/*
24862306a36Sopenharmony_ci * Called upon a sleep-indication from the device
24962306a36Sopenharmony_ci */
25062306a36Sopenharmony_cistatic void ll_device_want_to_sleep(struct hci_uart *hu)
25162306a36Sopenharmony_ci{
25262306a36Sopenharmony_ci	unsigned long flags;
25362306a36Sopenharmony_ci	struct ll_struct *ll = hu->priv;
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	BT_DBG("hu %p", hu);
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	/* lock hcill state */
25862306a36Sopenharmony_ci	spin_lock_irqsave(&ll->hcill_lock, flags);
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci	/* sanity check */
26162306a36Sopenharmony_ci	if (ll->hcill_state != HCILL_AWAKE)
26262306a36Sopenharmony_ci		BT_ERR("ERR: HCILL_GO_TO_SLEEP_IND in state %ld",
26362306a36Sopenharmony_ci		       ll->hcill_state);
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	/* acknowledge device sleep */
26662306a36Sopenharmony_ci	if (send_hcill_cmd(HCILL_GO_TO_SLEEP_ACK, hu) < 0) {
26762306a36Sopenharmony_ci		BT_ERR("cannot acknowledge device sleep");
26862306a36Sopenharmony_ci		goto out;
26962306a36Sopenharmony_ci	}
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci	/* update state */
27262306a36Sopenharmony_ci	ll->hcill_state = HCILL_ASLEEP;
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ciout:
27562306a36Sopenharmony_ci	spin_unlock_irqrestore(&ll->hcill_lock, flags);
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci	/* actually send the sleep ack packet */
27862306a36Sopenharmony_ci	hci_uart_tx_wakeup(hu);
27962306a36Sopenharmony_ci}
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci/*
28262306a36Sopenharmony_ci * Called upon wake-up-acknowledgement from the device
28362306a36Sopenharmony_ci */
28462306a36Sopenharmony_cistatic void ll_device_woke_up(struct hci_uart *hu)
28562306a36Sopenharmony_ci{
28662306a36Sopenharmony_ci	unsigned long flags;
28762306a36Sopenharmony_ci	struct ll_struct *ll = hu->priv;
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	BT_DBG("hu %p", hu);
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	/* lock hcill state */
29262306a36Sopenharmony_ci	spin_lock_irqsave(&ll->hcill_lock, flags);
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci	/* sanity check */
29562306a36Sopenharmony_ci	if (ll->hcill_state != HCILL_ASLEEP_TO_AWAKE)
29662306a36Sopenharmony_ci		BT_ERR("received HCILL_WAKE_UP_ACK in state %ld",
29762306a36Sopenharmony_ci		       ll->hcill_state);
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	/* send pending packets and change state to HCILL_AWAKE */
30062306a36Sopenharmony_ci	__ll_do_awake(ll);
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci	spin_unlock_irqrestore(&ll->hcill_lock, flags);
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	/* actually send the packets */
30562306a36Sopenharmony_ci	hci_uart_tx_wakeup(hu);
30662306a36Sopenharmony_ci}
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci/* Enqueue frame for transmittion (padding, crc, etc) */
30962306a36Sopenharmony_ci/* may be called from two simultaneous tasklets */
31062306a36Sopenharmony_cistatic int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
31162306a36Sopenharmony_ci{
31262306a36Sopenharmony_ci	unsigned long flags = 0;
31362306a36Sopenharmony_ci	struct ll_struct *ll = hu->priv;
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	BT_DBG("hu %p skb %p", hu, skb);
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	/* Prepend skb with frame type */
31862306a36Sopenharmony_ci	memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	/* lock hcill state */
32162306a36Sopenharmony_ci	spin_lock_irqsave(&ll->hcill_lock, flags);
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci	/* act according to current state */
32462306a36Sopenharmony_ci	switch (ll->hcill_state) {
32562306a36Sopenharmony_ci	case HCILL_AWAKE:
32662306a36Sopenharmony_ci		BT_DBG("device awake, sending normally");
32762306a36Sopenharmony_ci		skb_queue_tail(&ll->txq, skb);
32862306a36Sopenharmony_ci		break;
32962306a36Sopenharmony_ci	case HCILL_ASLEEP:
33062306a36Sopenharmony_ci		BT_DBG("device asleep, waking up and queueing packet");
33162306a36Sopenharmony_ci		/* save packet for later */
33262306a36Sopenharmony_ci		skb_queue_tail(&ll->tx_wait_q, skb);
33362306a36Sopenharmony_ci		/* awake device */
33462306a36Sopenharmony_ci		if (send_hcill_cmd(HCILL_WAKE_UP_IND, hu) < 0) {
33562306a36Sopenharmony_ci			BT_ERR("cannot wake up device");
33662306a36Sopenharmony_ci			break;
33762306a36Sopenharmony_ci		}
33862306a36Sopenharmony_ci		ll->hcill_state = HCILL_ASLEEP_TO_AWAKE;
33962306a36Sopenharmony_ci		break;
34062306a36Sopenharmony_ci	case HCILL_ASLEEP_TO_AWAKE:
34162306a36Sopenharmony_ci		BT_DBG("device waking up, queueing packet");
34262306a36Sopenharmony_ci		/* transient state; just keep packet for later */
34362306a36Sopenharmony_ci		skb_queue_tail(&ll->tx_wait_q, skb);
34462306a36Sopenharmony_ci		break;
34562306a36Sopenharmony_ci	default:
34662306a36Sopenharmony_ci		BT_ERR("illegal hcill state: %ld (losing packet)",
34762306a36Sopenharmony_ci		       ll->hcill_state);
34862306a36Sopenharmony_ci		dev_kfree_skb_irq(skb);
34962306a36Sopenharmony_ci		break;
35062306a36Sopenharmony_ci	}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	spin_unlock_irqrestore(&ll->hcill_lock, flags);
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	return 0;
35562306a36Sopenharmony_ci}
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_cistatic int ll_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
35862306a36Sopenharmony_ci{
35962306a36Sopenharmony_ci	struct hci_uart *hu = hci_get_drvdata(hdev);
36062306a36Sopenharmony_ci	struct ll_struct *ll = hu->priv;
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci	switch (hci_skb_pkt_type(skb)) {
36362306a36Sopenharmony_ci	case HCILL_GO_TO_SLEEP_IND:
36462306a36Sopenharmony_ci		BT_DBG("HCILL_GO_TO_SLEEP_IND packet");
36562306a36Sopenharmony_ci		ll_device_want_to_sleep(hu);
36662306a36Sopenharmony_ci		break;
36762306a36Sopenharmony_ci	case HCILL_GO_TO_SLEEP_ACK:
36862306a36Sopenharmony_ci		/* shouldn't happen */
36962306a36Sopenharmony_ci		bt_dev_err(hdev, "received HCILL_GO_TO_SLEEP_ACK in state %ld",
37062306a36Sopenharmony_ci			   ll->hcill_state);
37162306a36Sopenharmony_ci		break;
37262306a36Sopenharmony_ci	case HCILL_WAKE_UP_IND:
37362306a36Sopenharmony_ci		BT_DBG("HCILL_WAKE_UP_IND packet");
37462306a36Sopenharmony_ci		ll_device_want_to_wakeup(hu);
37562306a36Sopenharmony_ci		break;
37662306a36Sopenharmony_ci	case HCILL_WAKE_UP_ACK:
37762306a36Sopenharmony_ci		BT_DBG("HCILL_WAKE_UP_ACK packet");
37862306a36Sopenharmony_ci		ll_device_woke_up(hu);
37962306a36Sopenharmony_ci		break;
38062306a36Sopenharmony_ci	}
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci	kfree_skb(skb);
38362306a36Sopenharmony_ci	return 0;
38462306a36Sopenharmony_ci}
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci#define LL_RECV_SLEEP_IND \
38762306a36Sopenharmony_ci	.type = HCILL_GO_TO_SLEEP_IND, \
38862306a36Sopenharmony_ci	.hlen = 0, \
38962306a36Sopenharmony_ci	.loff = 0, \
39062306a36Sopenharmony_ci	.lsize = 0, \
39162306a36Sopenharmony_ci	.maxlen = 0
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci#define LL_RECV_SLEEP_ACK \
39462306a36Sopenharmony_ci	.type = HCILL_GO_TO_SLEEP_ACK, \
39562306a36Sopenharmony_ci	.hlen = 0, \
39662306a36Sopenharmony_ci	.loff = 0, \
39762306a36Sopenharmony_ci	.lsize = 0, \
39862306a36Sopenharmony_ci	.maxlen = 0
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci#define LL_RECV_WAKE_IND \
40162306a36Sopenharmony_ci	.type = HCILL_WAKE_UP_IND, \
40262306a36Sopenharmony_ci	.hlen = 0, \
40362306a36Sopenharmony_ci	.loff = 0, \
40462306a36Sopenharmony_ci	.lsize = 0, \
40562306a36Sopenharmony_ci	.maxlen = 0
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci#define LL_RECV_WAKE_ACK \
40862306a36Sopenharmony_ci	.type = HCILL_WAKE_UP_ACK, \
40962306a36Sopenharmony_ci	.hlen = 0, \
41062306a36Sopenharmony_ci	.loff = 0, \
41162306a36Sopenharmony_ci	.lsize = 0, \
41262306a36Sopenharmony_ci	.maxlen = 0
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_cistatic const struct h4_recv_pkt ll_recv_pkts[] = {
41562306a36Sopenharmony_ci	{ H4_RECV_ACL,       .recv = hci_recv_frame },
41662306a36Sopenharmony_ci	{ H4_RECV_SCO,       .recv = hci_recv_frame },
41762306a36Sopenharmony_ci	{ H4_RECV_EVENT,     .recv = hci_recv_frame },
41862306a36Sopenharmony_ci	{ LL_RECV_SLEEP_IND, .recv = ll_recv_frame  },
41962306a36Sopenharmony_ci	{ LL_RECV_SLEEP_ACK, .recv = ll_recv_frame  },
42062306a36Sopenharmony_ci	{ LL_RECV_WAKE_IND,  .recv = ll_recv_frame  },
42162306a36Sopenharmony_ci	{ LL_RECV_WAKE_ACK,  .recv = ll_recv_frame  },
42262306a36Sopenharmony_ci};
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci/* Recv data */
42562306a36Sopenharmony_cistatic int ll_recv(struct hci_uart *hu, const void *data, int count)
42662306a36Sopenharmony_ci{
42762306a36Sopenharmony_ci	struct ll_struct *ll = hu->priv;
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_ci	if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
43062306a36Sopenharmony_ci		return -EUNATCH;
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ci	ll->rx_skb = h4_recv_buf(hu->hdev, ll->rx_skb, data, count,
43362306a36Sopenharmony_ci				 ll_recv_pkts, ARRAY_SIZE(ll_recv_pkts));
43462306a36Sopenharmony_ci	if (IS_ERR(ll->rx_skb)) {
43562306a36Sopenharmony_ci		int err = PTR_ERR(ll->rx_skb);
43662306a36Sopenharmony_ci		bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
43762306a36Sopenharmony_ci		ll->rx_skb = NULL;
43862306a36Sopenharmony_ci		return err;
43962306a36Sopenharmony_ci	}
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	return count;
44262306a36Sopenharmony_ci}
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_cistatic struct sk_buff *ll_dequeue(struct hci_uart *hu)
44562306a36Sopenharmony_ci{
44662306a36Sopenharmony_ci	struct ll_struct *ll = hu->priv;
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	return skb_dequeue(&ll->txq);
44962306a36Sopenharmony_ci}
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SERIAL_DEV_BUS)
45262306a36Sopenharmony_cistatic int read_local_version(struct hci_dev *hdev)
45362306a36Sopenharmony_ci{
45462306a36Sopenharmony_ci	int err = 0;
45562306a36Sopenharmony_ci	unsigned short version = 0;
45662306a36Sopenharmony_ci	struct sk_buff *skb;
45762306a36Sopenharmony_ci	struct hci_rp_read_local_version *ver;
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ci	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
46062306a36Sopenharmony_ci			     HCI_INIT_TIMEOUT);
46162306a36Sopenharmony_ci	if (IS_ERR(skb)) {
46262306a36Sopenharmony_ci		bt_dev_err(hdev, "Reading TI version information failed (%ld)",
46362306a36Sopenharmony_ci			   PTR_ERR(skb));
46462306a36Sopenharmony_ci		return PTR_ERR(skb);
46562306a36Sopenharmony_ci	}
46662306a36Sopenharmony_ci	if (skb->len != sizeof(*ver)) {
46762306a36Sopenharmony_ci		err = -EILSEQ;
46862306a36Sopenharmony_ci		goto out;
46962306a36Sopenharmony_ci	}
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_ci	ver = (struct hci_rp_read_local_version *)skb->data;
47262306a36Sopenharmony_ci	if (le16_to_cpu(ver->manufacturer) != 13) {
47362306a36Sopenharmony_ci		err = -ENODEV;
47462306a36Sopenharmony_ci		goto out;
47562306a36Sopenharmony_ci	}
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci	version = le16_to_cpu(ver->lmp_subver);
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ciout:
48062306a36Sopenharmony_ci	if (err)
48162306a36Sopenharmony_ci		bt_dev_err(hdev, "Failed to read TI version info: %d", err);
48262306a36Sopenharmony_ci	kfree_skb(skb);
48362306a36Sopenharmony_ci	return err ? err : version;
48462306a36Sopenharmony_ci}
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_cistatic int send_command_from_firmware(struct ll_device *lldev,
48762306a36Sopenharmony_ci				      struct hci_command *cmd)
48862306a36Sopenharmony_ci{
48962306a36Sopenharmony_ci	struct sk_buff *skb;
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci	if (cmd->opcode == HCI_VS_UPDATE_UART_HCI_BAUDRATE) {
49262306a36Sopenharmony_ci		/* ignore remote change
49362306a36Sopenharmony_ci		 * baud rate HCI VS command
49462306a36Sopenharmony_ci		 */
49562306a36Sopenharmony_ci		bt_dev_warn(lldev->hu.hdev,
49662306a36Sopenharmony_ci			    "change remote baud rate command in firmware");
49762306a36Sopenharmony_ci		return 0;
49862306a36Sopenharmony_ci	}
49962306a36Sopenharmony_ci	if (cmd->prefix != 1)
50062306a36Sopenharmony_ci		bt_dev_dbg(lldev->hu.hdev, "command type %d", cmd->prefix);
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	skb = __hci_cmd_sync(lldev->hu.hdev, cmd->opcode, cmd->plen,
50362306a36Sopenharmony_ci			     &cmd->speed, HCI_INIT_TIMEOUT);
50462306a36Sopenharmony_ci	if (IS_ERR(skb)) {
50562306a36Sopenharmony_ci		bt_dev_err(lldev->hu.hdev, "send command failed");
50662306a36Sopenharmony_ci		return PTR_ERR(skb);
50762306a36Sopenharmony_ci	}
50862306a36Sopenharmony_ci	kfree_skb(skb);
50962306a36Sopenharmony_ci	return 0;
51062306a36Sopenharmony_ci}
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci/*
51362306a36Sopenharmony_ci * download_firmware -
51462306a36Sopenharmony_ci *	internal function which parses through the .bts firmware
51562306a36Sopenharmony_ci *	script file intreprets SEND, DELAY actions only as of now
51662306a36Sopenharmony_ci */
51762306a36Sopenharmony_cistatic int download_firmware(struct ll_device *lldev)
51862306a36Sopenharmony_ci{
51962306a36Sopenharmony_ci	unsigned short chip, min_ver, maj_ver;
52062306a36Sopenharmony_ci	int version, err, len;
52162306a36Sopenharmony_ci	unsigned char *ptr, *action_ptr;
52262306a36Sopenharmony_ci	unsigned char bts_scr_name[40];	/* 40 char long bts scr name? */
52362306a36Sopenharmony_ci	const struct firmware *fw;
52462306a36Sopenharmony_ci	struct hci_command *cmd;
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci	version = read_local_version(lldev->hu.hdev);
52762306a36Sopenharmony_ci	if (version < 0)
52862306a36Sopenharmony_ci		return version;
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	chip = (version & 0x7C00) >> 10;
53162306a36Sopenharmony_ci	min_ver = (version & 0x007F);
53262306a36Sopenharmony_ci	maj_ver = (version & 0x0380) >> 7;
53362306a36Sopenharmony_ci	if (version & 0x8000)
53462306a36Sopenharmony_ci		maj_ver |= 0x0008;
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	snprintf(bts_scr_name, sizeof(bts_scr_name),
53762306a36Sopenharmony_ci		 "ti-connectivity/TIInit_%d.%d.%d.bts",
53862306a36Sopenharmony_ci		 chip, maj_ver, min_ver);
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	err = request_firmware(&fw, bts_scr_name, &lldev->serdev->dev);
54162306a36Sopenharmony_ci	if (err || !fw->data || !fw->size) {
54262306a36Sopenharmony_ci		bt_dev_err(lldev->hu.hdev, "request_firmware failed(errno %d) for %s",
54362306a36Sopenharmony_ci			   err, bts_scr_name);
54462306a36Sopenharmony_ci		return -EINVAL;
54562306a36Sopenharmony_ci	}
54662306a36Sopenharmony_ci	ptr = (void *)fw->data;
54762306a36Sopenharmony_ci	len = fw->size;
54862306a36Sopenharmony_ci	/* bts_header to remove out magic number and
54962306a36Sopenharmony_ci	 * version
55062306a36Sopenharmony_ci	 */
55162306a36Sopenharmony_ci	ptr += sizeof(struct bts_header);
55262306a36Sopenharmony_ci	len -= sizeof(struct bts_header);
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ci	while (len > 0 && ptr) {
55562306a36Sopenharmony_ci		bt_dev_dbg(lldev->hu.hdev, " action size %d, type %d ",
55662306a36Sopenharmony_ci			   ((struct bts_action *)ptr)->size,
55762306a36Sopenharmony_ci			   ((struct bts_action *)ptr)->type);
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci		action_ptr = &(((struct bts_action *)ptr)->data[0]);
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_ci		switch (((struct bts_action *)ptr)->type) {
56262306a36Sopenharmony_ci		case ACTION_SEND_COMMAND:	/* action send */
56362306a36Sopenharmony_ci			bt_dev_dbg(lldev->hu.hdev, "S");
56462306a36Sopenharmony_ci			cmd = (struct hci_command *)action_ptr;
56562306a36Sopenharmony_ci			err = send_command_from_firmware(lldev, cmd);
56662306a36Sopenharmony_ci			if (err)
56762306a36Sopenharmony_ci				goto out_rel_fw;
56862306a36Sopenharmony_ci			break;
56962306a36Sopenharmony_ci		case ACTION_WAIT_EVENT:  /* wait */
57062306a36Sopenharmony_ci			/* no need to wait as command was synchronous */
57162306a36Sopenharmony_ci			bt_dev_dbg(lldev->hu.hdev, "W");
57262306a36Sopenharmony_ci			break;
57362306a36Sopenharmony_ci		case ACTION_DELAY:	/* sleep */
57462306a36Sopenharmony_ci			bt_dev_info(lldev->hu.hdev, "sleep command in scr");
57562306a36Sopenharmony_ci			msleep(((struct bts_action_delay *)action_ptr)->msec);
57662306a36Sopenharmony_ci			break;
57762306a36Sopenharmony_ci		}
57862306a36Sopenharmony_ci		len -= (sizeof(struct bts_action) +
57962306a36Sopenharmony_ci			((struct bts_action *)ptr)->size);
58062306a36Sopenharmony_ci		ptr += sizeof(struct bts_action) +
58162306a36Sopenharmony_ci			((struct bts_action *)ptr)->size;
58262306a36Sopenharmony_ci	}
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ciout_rel_fw:
58562306a36Sopenharmony_ci	/* fw download complete */
58662306a36Sopenharmony_ci	release_firmware(fw);
58762306a36Sopenharmony_ci	return err;
58862306a36Sopenharmony_ci}
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_cistatic int ll_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
59162306a36Sopenharmony_ci{
59262306a36Sopenharmony_ci	bdaddr_t bdaddr_swapped;
59362306a36Sopenharmony_ci	struct sk_buff *skb;
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci	/* HCI_VS_WRITE_BD_ADDR (at least on a CC2560A chip) expects the BD
59662306a36Sopenharmony_ci	 * address to be MSB first, but bdaddr_t has the convention of being
59762306a36Sopenharmony_ci	 * LSB first.
59862306a36Sopenharmony_ci	 */
59962306a36Sopenharmony_ci	baswap(&bdaddr_swapped, bdaddr);
60062306a36Sopenharmony_ci	skb = __hci_cmd_sync(hdev, HCI_VS_WRITE_BD_ADDR, sizeof(bdaddr_t),
60162306a36Sopenharmony_ci			     &bdaddr_swapped, HCI_INIT_TIMEOUT);
60262306a36Sopenharmony_ci	if (!IS_ERR(skb))
60362306a36Sopenharmony_ci		kfree_skb(skb);
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci	return PTR_ERR_OR_ZERO(skb);
60662306a36Sopenharmony_ci}
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_cistatic int ll_setup(struct hci_uart *hu)
60962306a36Sopenharmony_ci{
61062306a36Sopenharmony_ci	int err, retry = 3;
61162306a36Sopenharmony_ci	struct ll_device *lldev;
61262306a36Sopenharmony_ci	struct serdev_device *serdev = hu->serdev;
61362306a36Sopenharmony_ci	u32 speed;
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci	if (!serdev)
61662306a36Sopenharmony_ci		return 0;
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci	lldev = serdev_device_get_drvdata(serdev);
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci	hu->hdev->set_bdaddr = ll_set_bdaddr;
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci	serdev_device_set_flow_control(serdev, true);
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_ci	do {
62562306a36Sopenharmony_ci		/* Reset the Bluetooth device */
62662306a36Sopenharmony_ci		gpiod_set_value_cansleep(lldev->enable_gpio, 0);
62762306a36Sopenharmony_ci		msleep(5);
62862306a36Sopenharmony_ci		gpiod_set_value_cansleep(lldev->enable_gpio, 1);
62962306a36Sopenharmony_ci		mdelay(100);
63062306a36Sopenharmony_ci		err = serdev_device_wait_for_cts(serdev, true, 200);
63162306a36Sopenharmony_ci		if (err) {
63262306a36Sopenharmony_ci			bt_dev_err(hu->hdev, "Failed to get CTS");
63362306a36Sopenharmony_ci			return err;
63462306a36Sopenharmony_ci		}
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci		err = download_firmware(lldev);
63762306a36Sopenharmony_ci		if (!err)
63862306a36Sopenharmony_ci			break;
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci		/* Toggle BT_EN and retry */
64162306a36Sopenharmony_ci		bt_dev_err(hu->hdev, "download firmware failed, retrying...");
64262306a36Sopenharmony_ci	} while (retry--);
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_ci	if (err)
64562306a36Sopenharmony_ci		return err;
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_ci	/* Set BD address if one was specified at probe */
64862306a36Sopenharmony_ci	if (!bacmp(&lldev->bdaddr, BDADDR_NONE)) {
64962306a36Sopenharmony_ci		/* This means that there was an error getting the BD address
65062306a36Sopenharmony_ci		 * during probe, so mark the device as having a bad address.
65162306a36Sopenharmony_ci		 */
65262306a36Sopenharmony_ci		set_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks);
65362306a36Sopenharmony_ci	} else if (bacmp(&lldev->bdaddr, BDADDR_ANY)) {
65462306a36Sopenharmony_ci		err = ll_set_bdaddr(hu->hdev, &lldev->bdaddr);
65562306a36Sopenharmony_ci		if (err)
65662306a36Sopenharmony_ci			set_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks);
65762306a36Sopenharmony_ci	}
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci	/* Operational speed if any */
66062306a36Sopenharmony_ci	if (hu->oper_speed)
66162306a36Sopenharmony_ci		speed = hu->oper_speed;
66262306a36Sopenharmony_ci	else if (hu->proto->oper_speed)
66362306a36Sopenharmony_ci		speed = hu->proto->oper_speed;
66462306a36Sopenharmony_ci	else
66562306a36Sopenharmony_ci		speed = 0;
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci	if (speed) {
66862306a36Sopenharmony_ci		__le32 speed_le = cpu_to_le32(speed);
66962306a36Sopenharmony_ci		struct sk_buff *skb;
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci		skb = __hci_cmd_sync(hu->hdev, HCI_VS_UPDATE_UART_HCI_BAUDRATE,
67262306a36Sopenharmony_ci				     sizeof(speed_le), &speed_le,
67362306a36Sopenharmony_ci				     HCI_INIT_TIMEOUT);
67462306a36Sopenharmony_ci		if (!IS_ERR(skb)) {
67562306a36Sopenharmony_ci			kfree_skb(skb);
67662306a36Sopenharmony_ci			serdev_device_set_baudrate(serdev, speed);
67762306a36Sopenharmony_ci		}
67862306a36Sopenharmony_ci	}
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	return 0;
68162306a36Sopenharmony_ci}
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_cistatic const struct hci_uart_proto llp;
68462306a36Sopenharmony_ci
68562306a36Sopenharmony_cistatic int hci_ti_probe(struct serdev_device *serdev)
68662306a36Sopenharmony_ci{
68762306a36Sopenharmony_ci	struct hci_uart *hu;
68862306a36Sopenharmony_ci	struct ll_device *lldev;
68962306a36Sopenharmony_ci	struct nvmem_cell *bdaddr_cell;
69062306a36Sopenharmony_ci	u32 max_speed = 3000000;
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci	lldev = devm_kzalloc(&serdev->dev, sizeof(struct ll_device), GFP_KERNEL);
69362306a36Sopenharmony_ci	if (!lldev)
69462306a36Sopenharmony_ci		return -ENOMEM;
69562306a36Sopenharmony_ci	hu = &lldev->hu;
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	serdev_device_set_drvdata(serdev, lldev);
69862306a36Sopenharmony_ci	lldev->serdev = hu->serdev = serdev;
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	lldev->enable_gpio = devm_gpiod_get_optional(&serdev->dev,
70162306a36Sopenharmony_ci						     "enable",
70262306a36Sopenharmony_ci						     GPIOD_OUT_LOW);
70362306a36Sopenharmony_ci	if (IS_ERR(lldev->enable_gpio))
70462306a36Sopenharmony_ci		return PTR_ERR(lldev->enable_gpio);
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_ci	lldev->ext_clk = devm_clk_get(&serdev->dev, "ext_clock");
70762306a36Sopenharmony_ci	if (IS_ERR(lldev->ext_clk) && PTR_ERR(lldev->ext_clk) != -ENOENT)
70862306a36Sopenharmony_ci		return PTR_ERR(lldev->ext_clk);
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci	of_property_read_u32(serdev->dev.of_node, "max-speed", &max_speed);
71162306a36Sopenharmony_ci	hci_uart_set_speeds(hu, 115200, max_speed);
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	/* optional BD address from nvram */
71462306a36Sopenharmony_ci	bdaddr_cell = nvmem_cell_get(&serdev->dev, "bd-address");
71562306a36Sopenharmony_ci	if (IS_ERR(bdaddr_cell)) {
71662306a36Sopenharmony_ci		int err = PTR_ERR(bdaddr_cell);
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci		if (err == -EPROBE_DEFER)
71962306a36Sopenharmony_ci			return err;
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ci		/* ENOENT means there is no matching nvmem cell and ENOSYS
72262306a36Sopenharmony_ci		 * means that nvmem is not enabled in the kernel configuration.
72362306a36Sopenharmony_ci		 */
72462306a36Sopenharmony_ci		if (err != -ENOENT && err != -ENOSYS) {
72562306a36Sopenharmony_ci			/* If there was some other error, give userspace a
72662306a36Sopenharmony_ci			 * chance to fix the problem instead of failing to load
72762306a36Sopenharmony_ci			 * the driver. Using BDADDR_NONE as a flag that is
72862306a36Sopenharmony_ci			 * tested later in the setup function.
72962306a36Sopenharmony_ci			 */
73062306a36Sopenharmony_ci			dev_warn(&serdev->dev,
73162306a36Sopenharmony_ci				 "Failed to get \"bd-address\" nvmem cell (%d)\n",
73262306a36Sopenharmony_ci				 err);
73362306a36Sopenharmony_ci			bacpy(&lldev->bdaddr, BDADDR_NONE);
73462306a36Sopenharmony_ci		}
73562306a36Sopenharmony_ci	} else {
73662306a36Sopenharmony_ci		bdaddr_t *bdaddr;
73762306a36Sopenharmony_ci		size_t len;
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci		bdaddr = nvmem_cell_read(bdaddr_cell, &len);
74062306a36Sopenharmony_ci		nvmem_cell_put(bdaddr_cell);
74162306a36Sopenharmony_ci		if (IS_ERR(bdaddr)) {
74262306a36Sopenharmony_ci			dev_err(&serdev->dev, "Failed to read nvmem bd-address\n");
74362306a36Sopenharmony_ci			return PTR_ERR(bdaddr);
74462306a36Sopenharmony_ci		}
74562306a36Sopenharmony_ci		if (len != sizeof(bdaddr_t)) {
74662306a36Sopenharmony_ci			dev_err(&serdev->dev, "Invalid nvmem bd-address length\n");
74762306a36Sopenharmony_ci			kfree(bdaddr);
74862306a36Sopenharmony_ci			return -EINVAL;
74962306a36Sopenharmony_ci		}
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci		/* As per the device tree bindings, the value from nvmem is
75262306a36Sopenharmony_ci		 * expected to be MSB first, but in the kernel it is expected
75362306a36Sopenharmony_ci		 * that bdaddr_t is LSB first.
75462306a36Sopenharmony_ci		 */
75562306a36Sopenharmony_ci		baswap(&lldev->bdaddr, bdaddr);
75662306a36Sopenharmony_ci		kfree(bdaddr);
75762306a36Sopenharmony_ci	}
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	return hci_uart_register_device(hu, &llp);
76062306a36Sopenharmony_ci}
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_cistatic void hci_ti_remove(struct serdev_device *serdev)
76362306a36Sopenharmony_ci{
76462306a36Sopenharmony_ci	struct ll_device *lldev = serdev_device_get_drvdata(serdev);
76562306a36Sopenharmony_ci
76662306a36Sopenharmony_ci	hci_uart_unregister_device(&lldev->hu);
76762306a36Sopenharmony_ci}
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_cistatic const struct of_device_id hci_ti_of_match[] = {
77062306a36Sopenharmony_ci	{ .compatible = "ti,cc2560" },
77162306a36Sopenharmony_ci	{ .compatible = "ti,wl1271-st" },
77262306a36Sopenharmony_ci	{ .compatible = "ti,wl1273-st" },
77362306a36Sopenharmony_ci	{ .compatible = "ti,wl1281-st" },
77462306a36Sopenharmony_ci	{ .compatible = "ti,wl1283-st" },
77562306a36Sopenharmony_ci	{ .compatible = "ti,wl1285-st" },
77662306a36Sopenharmony_ci	{ .compatible = "ti,wl1801-st" },
77762306a36Sopenharmony_ci	{ .compatible = "ti,wl1805-st" },
77862306a36Sopenharmony_ci	{ .compatible = "ti,wl1807-st" },
77962306a36Sopenharmony_ci	{ .compatible = "ti,wl1831-st" },
78062306a36Sopenharmony_ci	{ .compatible = "ti,wl1835-st" },
78162306a36Sopenharmony_ci	{ .compatible = "ti,wl1837-st" },
78262306a36Sopenharmony_ci	{},
78362306a36Sopenharmony_ci};
78462306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, hci_ti_of_match);
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_cistatic struct serdev_device_driver hci_ti_drv = {
78762306a36Sopenharmony_ci	.driver		= {
78862306a36Sopenharmony_ci		.name	= "hci-ti",
78962306a36Sopenharmony_ci		.of_match_table = hci_ti_of_match,
79062306a36Sopenharmony_ci	},
79162306a36Sopenharmony_ci	.probe	= hci_ti_probe,
79262306a36Sopenharmony_ci	.remove	= hci_ti_remove,
79362306a36Sopenharmony_ci};
79462306a36Sopenharmony_ci#else
79562306a36Sopenharmony_ci#define ll_setup NULL
79662306a36Sopenharmony_ci#endif
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_cistatic const struct hci_uart_proto llp = {
79962306a36Sopenharmony_ci	.id		= HCI_UART_LL,
80062306a36Sopenharmony_ci	.name		= "LL",
80162306a36Sopenharmony_ci	.setup		= ll_setup,
80262306a36Sopenharmony_ci	.open		= ll_open,
80362306a36Sopenharmony_ci	.close		= ll_close,
80462306a36Sopenharmony_ci	.recv		= ll_recv,
80562306a36Sopenharmony_ci	.enqueue	= ll_enqueue,
80662306a36Sopenharmony_ci	.dequeue	= ll_dequeue,
80762306a36Sopenharmony_ci	.flush		= ll_flush,
80862306a36Sopenharmony_ci};
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ciint __init ll_init(void)
81162306a36Sopenharmony_ci{
81262306a36Sopenharmony_ci	serdev_device_driver_register(&hci_ti_drv);
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ci	return hci_uart_register_proto(&llp);
81562306a36Sopenharmony_ci}
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_ciint __exit ll_deinit(void)
81862306a36Sopenharmony_ci{
81962306a36Sopenharmony_ci	serdev_device_driver_unregister(&hci_ti_drv);
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_ci	return hci_uart_unregister_proto(&llp);
82262306a36Sopenharmony_ci}
823