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