1166d2f6aSOhad Ben-Cohen /* 2166d2f6aSOhad Ben-Cohen * Texas Instruments' Bluetooth HCILL UART protocol 3166d2f6aSOhad Ben-Cohen * 4166d2f6aSOhad Ben-Cohen * HCILL (HCI Low Level) is a Texas Instruments' power management 5166d2f6aSOhad Ben-Cohen * protocol extension to H4. 6166d2f6aSOhad Ben-Cohen * 7166d2f6aSOhad Ben-Cohen * Copyright (C) 2007 Texas Instruments, Inc. 8166d2f6aSOhad Ben-Cohen * 9166d2f6aSOhad Ben-Cohen * Written by Ohad Ben-Cohen <ohad@bencohen.org> 10166d2f6aSOhad Ben-Cohen * 11166d2f6aSOhad Ben-Cohen * Acknowledgements: 12166d2f6aSOhad Ben-Cohen * This file is based on hci_h4.c, which was written 13166d2f6aSOhad Ben-Cohen * by Maxim Krasnyansky and Marcel Holtmann. 14166d2f6aSOhad Ben-Cohen * 15166d2f6aSOhad Ben-Cohen * This program is free software; you can redistribute it and/or modify 16166d2f6aSOhad Ben-Cohen * it under the terms of the GNU General Public License version 2 17166d2f6aSOhad Ben-Cohen * as published by the Free Software Foundation 18166d2f6aSOhad Ben-Cohen * 19166d2f6aSOhad Ben-Cohen * This program is distributed in the hope that it will be useful, 20166d2f6aSOhad Ben-Cohen * but WITHOUT ANY WARRANTY; without even the implied warranty of 21166d2f6aSOhad Ben-Cohen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22166d2f6aSOhad Ben-Cohen * GNU General Public License for more details. 23166d2f6aSOhad Ben-Cohen * 24166d2f6aSOhad Ben-Cohen * You should have received a copy of the GNU General Public License 25166d2f6aSOhad Ben-Cohen * along with this program; if not, write to the Free Software 26166d2f6aSOhad Ben-Cohen * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27166d2f6aSOhad Ben-Cohen * 28166d2f6aSOhad Ben-Cohen */ 29166d2f6aSOhad Ben-Cohen 30166d2f6aSOhad Ben-Cohen #include <linux/module.h> 31166d2f6aSOhad Ben-Cohen #include <linux/kernel.h> 32166d2f6aSOhad Ben-Cohen 33166d2f6aSOhad Ben-Cohen #include <linux/init.h> 34166d2f6aSOhad Ben-Cohen #include <linux/sched.h> 35166d2f6aSOhad Ben-Cohen #include <linux/types.h> 36166d2f6aSOhad Ben-Cohen #include <linux/fcntl.h> 3737180552SRob Herring #include <linux/firmware.h> 38166d2f6aSOhad Ben-Cohen #include <linux/interrupt.h> 39166d2f6aSOhad Ben-Cohen #include <linux/ptrace.h> 40166d2f6aSOhad Ben-Cohen #include <linux/poll.h> 41166d2f6aSOhad Ben-Cohen 42166d2f6aSOhad Ben-Cohen #include <linux/slab.h> 43166d2f6aSOhad Ben-Cohen #include <linux/errno.h> 44166d2f6aSOhad Ben-Cohen #include <linux/string.h> 45166d2f6aSOhad Ben-Cohen #include <linux/signal.h> 46166d2f6aSOhad Ben-Cohen #include <linux/ioctl.h> 4737180552SRob Herring #include <linux/of.h> 4837180552SRob Herring #include <linux/serdev.h> 49166d2f6aSOhad Ben-Cohen #include <linux/skbuff.h> 5037180552SRob Herring #include <linux/ti_wilink_st.h> 51166d2f6aSOhad Ben-Cohen 52166d2f6aSOhad Ben-Cohen #include <net/bluetooth/bluetooth.h> 53166d2f6aSOhad Ben-Cohen #include <net/bluetooth/hci_core.h> 5437180552SRob Herring #include <linux/gpio/consumer.h> 55166d2f6aSOhad Ben-Cohen 56166d2f6aSOhad Ben-Cohen #include "hci_uart.h" 57166d2f6aSOhad Ben-Cohen 58166d2f6aSOhad Ben-Cohen /* HCILL commands */ 59166d2f6aSOhad Ben-Cohen #define HCILL_GO_TO_SLEEP_IND 0x30 60166d2f6aSOhad Ben-Cohen #define HCILL_GO_TO_SLEEP_ACK 0x31 61166d2f6aSOhad Ben-Cohen #define HCILL_WAKE_UP_IND 0x32 62166d2f6aSOhad Ben-Cohen #define HCILL_WAKE_UP_ACK 0x33 63166d2f6aSOhad Ben-Cohen 64166d2f6aSOhad Ben-Cohen /* HCILL receiver States */ 65166d2f6aSOhad Ben-Cohen #define HCILL_W4_PACKET_TYPE 0 66166d2f6aSOhad Ben-Cohen #define HCILL_W4_EVENT_HDR 1 67166d2f6aSOhad Ben-Cohen #define HCILL_W4_ACL_HDR 2 68166d2f6aSOhad Ben-Cohen #define HCILL_W4_SCO_HDR 3 69166d2f6aSOhad Ben-Cohen #define HCILL_W4_DATA 4 70166d2f6aSOhad Ben-Cohen 71166d2f6aSOhad Ben-Cohen /* HCILL states */ 72166d2f6aSOhad Ben-Cohen enum hcill_states_e { 73166d2f6aSOhad Ben-Cohen HCILL_ASLEEP, 74166d2f6aSOhad Ben-Cohen HCILL_ASLEEP_TO_AWAKE, 75166d2f6aSOhad Ben-Cohen HCILL_AWAKE, 76166d2f6aSOhad Ben-Cohen HCILL_AWAKE_TO_ASLEEP 77166d2f6aSOhad Ben-Cohen }; 78166d2f6aSOhad Ben-Cohen 79166d2f6aSOhad Ben-Cohen struct hcill_cmd { 80166d2f6aSOhad Ben-Cohen u8 cmd; 8181ca405aSGustavo F. Padovan } __packed; 82166d2f6aSOhad Ben-Cohen 8337180552SRob Herring struct ll_device { 8437180552SRob Herring struct hci_uart hu; 8537180552SRob Herring struct serdev_device *serdev; 8637180552SRob Herring struct gpio_desc *enable_gpio; 8737180552SRob Herring }; 8837180552SRob Herring 89166d2f6aSOhad Ben-Cohen struct ll_struct { 90166d2f6aSOhad Ben-Cohen unsigned long rx_state; 91166d2f6aSOhad Ben-Cohen unsigned long rx_count; 92166d2f6aSOhad Ben-Cohen struct sk_buff *rx_skb; 93166d2f6aSOhad Ben-Cohen struct sk_buff_head txq; 94166d2f6aSOhad Ben-Cohen spinlock_t hcill_lock; /* HCILL state lock */ 95166d2f6aSOhad Ben-Cohen unsigned long hcill_state; /* HCILL power state */ 96166d2f6aSOhad Ben-Cohen struct sk_buff_head tx_wait_q; /* HCILL wait queue */ 97166d2f6aSOhad Ben-Cohen }; 98166d2f6aSOhad Ben-Cohen 99166d2f6aSOhad Ben-Cohen /* 100166d2f6aSOhad Ben-Cohen * Builds and sends an HCILL command packet. 101166d2f6aSOhad Ben-Cohen * These are very simple packets with only 1 cmd byte 102166d2f6aSOhad Ben-Cohen */ 103166d2f6aSOhad Ben-Cohen static int send_hcill_cmd(u8 cmd, struct hci_uart *hu) 104166d2f6aSOhad Ben-Cohen { 105166d2f6aSOhad Ben-Cohen int err = 0; 106166d2f6aSOhad Ben-Cohen struct sk_buff *skb = NULL; 107166d2f6aSOhad Ben-Cohen struct ll_struct *ll = hu->priv; 108166d2f6aSOhad Ben-Cohen struct hcill_cmd *hcill_packet; 109166d2f6aSOhad Ben-Cohen 110166d2f6aSOhad Ben-Cohen BT_DBG("hu %p cmd 0x%x", hu, cmd); 111166d2f6aSOhad Ben-Cohen 112166d2f6aSOhad Ben-Cohen /* allocate packet */ 113166d2f6aSOhad Ben-Cohen skb = bt_skb_alloc(1, GFP_ATOMIC); 114166d2f6aSOhad Ben-Cohen if (!skb) { 115166d2f6aSOhad Ben-Cohen BT_ERR("cannot allocate memory for HCILL packet"); 116166d2f6aSOhad Ben-Cohen err = -ENOMEM; 117166d2f6aSOhad Ben-Cohen goto out; 118166d2f6aSOhad Ben-Cohen } 119166d2f6aSOhad Ben-Cohen 120166d2f6aSOhad Ben-Cohen /* prepare packet */ 121166d2f6aSOhad Ben-Cohen hcill_packet = (struct hcill_cmd *) skb_put(skb, 1); 122166d2f6aSOhad Ben-Cohen hcill_packet->cmd = cmd; 123166d2f6aSOhad Ben-Cohen 124166d2f6aSOhad Ben-Cohen /* send packet */ 125166d2f6aSOhad Ben-Cohen skb_queue_tail(&ll->txq, skb); 126166d2f6aSOhad Ben-Cohen out: 127166d2f6aSOhad Ben-Cohen return err; 128166d2f6aSOhad Ben-Cohen } 129166d2f6aSOhad Ben-Cohen 130166d2f6aSOhad Ben-Cohen /* Initialize protocol */ 131166d2f6aSOhad Ben-Cohen static int ll_open(struct hci_uart *hu) 132166d2f6aSOhad Ben-Cohen { 133166d2f6aSOhad Ben-Cohen struct ll_struct *ll; 134166d2f6aSOhad Ben-Cohen 135166d2f6aSOhad Ben-Cohen BT_DBG("hu %p", hu); 136166d2f6aSOhad Ben-Cohen 1379eb648c3SDavid Herrmann ll = kzalloc(sizeof(*ll), GFP_KERNEL); 138166d2f6aSOhad Ben-Cohen if (!ll) 139166d2f6aSOhad Ben-Cohen return -ENOMEM; 140166d2f6aSOhad Ben-Cohen 141166d2f6aSOhad Ben-Cohen skb_queue_head_init(&ll->txq); 142166d2f6aSOhad Ben-Cohen skb_queue_head_init(&ll->tx_wait_q); 143166d2f6aSOhad Ben-Cohen spin_lock_init(&ll->hcill_lock); 144166d2f6aSOhad Ben-Cohen 145166d2f6aSOhad Ben-Cohen ll->hcill_state = HCILL_AWAKE; 146166d2f6aSOhad Ben-Cohen 147166d2f6aSOhad Ben-Cohen hu->priv = ll; 148166d2f6aSOhad Ben-Cohen 14937180552SRob Herring if (hu->serdev) 15037180552SRob Herring serdev_device_open(hu->serdev); 15137180552SRob Herring 152166d2f6aSOhad Ben-Cohen return 0; 153166d2f6aSOhad Ben-Cohen } 154166d2f6aSOhad Ben-Cohen 155166d2f6aSOhad Ben-Cohen /* Flush protocol data */ 156166d2f6aSOhad Ben-Cohen static int ll_flush(struct hci_uart *hu) 157166d2f6aSOhad Ben-Cohen { 158166d2f6aSOhad Ben-Cohen struct ll_struct *ll = hu->priv; 159166d2f6aSOhad Ben-Cohen 160166d2f6aSOhad Ben-Cohen BT_DBG("hu %p", hu); 161166d2f6aSOhad Ben-Cohen 162166d2f6aSOhad Ben-Cohen skb_queue_purge(&ll->tx_wait_q); 163166d2f6aSOhad Ben-Cohen skb_queue_purge(&ll->txq); 164166d2f6aSOhad Ben-Cohen 165166d2f6aSOhad Ben-Cohen return 0; 166166d2f6aSOhad Ben-Cohen } 167166d2f6aSOhad Ben-Cohen 168166d2f6aSOhad Ben-Cohen /* Close protocol */ 169166d2f6aSOhad Ben-Cohen static int ll_close(struct hci_uart *hu) 170166d2f6aSOhad Ben-Cohen { 171166d2f6aSOhad Ben-Cohen struct ll_struct *ll = hu->priv; 172166d2f6aSOhad Ben-Cohen 173166d2f6aSOhad Ben-Cohen BT_DBG("hu %p", hu); 174166d2f6aSOhad Ben-Cohen 175166d2f6aSOhad Ben-Cohen skb_queue_purge(&ll->tx_wait_q); 176166d2f6aSOhad Ben-Cohen skb_queue_purge(&ll->txq); 177166d2f6aSOhad Ben-Cohen 178166d2f6aSOhad Ben-Cohen kfree_skb(ll->rx_skb); 179166d2f6aSOhad Ben-Cohen 18037180552SRob Herring if (hu->serdev) { 18137180552SRob Herring struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev); 18237180552SRob Herring gpiod_set_value_cansleep(lldev->enable_gpio, 0); 18337180552SRob Herring 18437180552SRob Herring serdev_device_close(hu->serdev); 18537180552SRob Herring } 18637180552SRob Herring 187166d2f6aSOhad Ben-Cohen hu->priv = NULL; 188166d2f6aSOhad Ben-Cohen 189166d2f6aSOhad Ben-Cohen kfree(ll); 190166d2f6aSOhad Ben-Cohen 191166d2f6aSOhad Ben-Cohen return 0; 192166d2f6aSOhad Ben-Cohen } 193166d2f6aSOhad Ben-Cohen 194166d2f6aSOhad Ben-Cohen /* 195166d2f6aSOhad Ben-Cohen * internal function, which does common work of the device wake up process: 196166d2f6aSOhad Ben-Cohen * 1. places all pending packets (waiting in tx_wait_q list) in txq list. 197166d2f6aSOhad Ben-Cohen * 2. changes internal state to HCILL_AWAKE. 198166d2f6aSOhad Ben-Cohen * Note: assumes that hcill_lock spinlock is taken, 199166d2f6aSOhad Ben-Cohen * shouldn't be called otherwise! 200166d2f6aSOhad Ben-Cohen */ 201166d2f6aSOhad Ben-Cohen static void __ll_do_awake(struct ll_struct *ll) 202166d2f6aSOhad Ben-Cohen { 203166d2f6aSOhad Ben-Cohen struct sk_buff *skb = NULL; 204166d2f6aSOhad Ben-Cohen 205166d2f6aSOhad Ben-Cohen while ((skb = skb_dequeue(&ll->tx_wait_q))) 206166d2f6aSOhad Ben-Cohen skb_queue_tail(&ll->txq, skb); 207166d2f6aSOhad Ben-Cohen 208166d2f6aSOhad Ben-Cohen ll->hcill_state = HCILL_AWAKE; 209166d2f6aSOhad Ben-Cohen } 210166d2f6aSOhad Ben-Cohen 211166d2f6aSOhad Ben-Cohen /* 212166d2f6aSOhad Ben-Cohen * Called upon a wake-up-indication from the device 213166d2f6aSOhad Ben-Cohen */ 214166d2f6aSOhad Ben-Cohen static void ll_device_want_to_wakeup(struct hci_uart *hu) 215166d2f6aSOhad Ben-Cohen { 216166d2f6aSOhad Ben-Cohen unsigned long flags; 217166d2f6aSOhad Ben-Cohen struct ll_struct *ll = hu->priv; 218166d2f6aSOhad Ben-Cohen 219166d2f6aSOhad Ben-Cohen BT_DBG("hu %p", hu); 220166d2f6aSOhad Ben-Cohen 221166d2f6aSOhad Ben-Cohen /* lock hcill state */ 222166d2f6aSOhad Ben-Cohen spin_lock_irqsave(&ll->hcill_lock, flags); 223166d2f6aSOhad Ben-Cohen 224166d2f6aSOhad Ben-Cohen switch (ll->hcill_state) { 2255c548226SOhad Ben-Cohen case HCILL_ASLEEP_TO_AWAKE: 2265c548226SOhad Ben-Cohen /* 2275c548226SOhad Ben-Cohen * This state means that both the host and the BRF chip 2285c548226SOhad Ben-Cohen * have simultaneously sent a wake-up-indication packet. 22925985edcSLucas De Marchi * Traditionally, in this case, receiving a wake-up-indication 2305c548226SOhad Ben-Cohen * was enough and an additional wake-up-ack wasn't needed. 2315c548226SOhad Ben-Cohen * This has changed with the BRF6350, which does require an 2325c548226SOhad Ben-Cohen * explicit wake-up-ack. Other BRF versions, which do not 2335c548226SOhad Ben-Cohen * require an explicit ack here, do accept it, thus it is 2345c548226SOhad Ben-Cohen * perfectly safe to always send one. 2355c548226SOhad Ben-Cohen */ 2365c548226SOhad Ben-Cohen BT_DBG("dual wake-up-indication"); 2375c548226SOhad Ben-Cohen /* deliberate fall-through - do not add break */ 238166d2f6aSOhad Ben-Cohen case HCILL_ASLEEP: 239166d2f6aSOhad Ben-Cohen /* acknowledge device wake up */ 240166d2f6aSOhad Ben-Cohen if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) { 241166d2f6aSOhad Ben-Cohen BT_ERR("cannot acknowledge device wake up"); 242166d2f6aSOhad Ben-Cohen goto out; 243166d2f6aSOhad Ben-Cohen } 244166d2f6aSOhad Ben-Cohen break; 245166d2f6aSOhad Ben-Cohen default: 2465c548226SOhad Ben-Cohen /* any other state is illegal */ 247166d2f6aSOhad Ben-Cohen BT_ERR("received HCILL_WAKE_UP_IND in state %ld", ll->hcill_state); 248166d2f6aSOhad Ben-Cohen break; 249166d2f6aSOhad Ben-Cohen } 250166d2f6aSOhad Ben-Cohen 251166d2f6aSOhad Ben-Cohen /* send pending packets and change state to HCILL_AWAKE */ 252166d2f6aSOhad Ben-Cohen __ll_do_awake(ll); 253166d2f6aSOhad Ben-Cohen 254166d2f6aSOhad Ben-Cohen out: 255166d2f6aSOhad Ben-Cohen spin_unlock_irqrestore(&ll->hcill_lock, flags); 256166d2f6aSOhad Ben-Cohen 257166d2f6aSOhad Ben-Cohen /* actually send the packets */ 258166d2f6aSOhad Ben-Cohen hci_uart_tx_wakeup(hu); 259166d2f6aSOhad Ben-Cohen } 260166d2f6aSOhad Ben-Cohen 261166d2f6aSOhad Ben-Cohen /* 262166d2f6aSOhad Ben-Cohen * Called upon a sleep-indication from the device 263166d2f6aSOhad Ben-Cohen */ 264166d2f6aSOhad Ben-Cohen static void ll_device_want_to_sleep(struct hci_uart *hu) 265166d2f6aSOhad Ben-Cohen { 266166d2f6aSOhad Ben-Cohen unsigned long flags; 267166d2f6aSOhad Ben-Cohen struct ll_struct *ll = hu->priv; 268166d2f6aSOhad Ben-Cohen 269166d2f6aSOhad Ben-Cohen BT_DBG("hu %p", hu); 270166d2f6aSOhad Ben-Cohen 271166d2f6aSOhad Ben-Cohen /* lock hcill state */ 272166d2f6aSOhad Ben-Cohen spin_lock_irqsave(&ll->hcill_lock, flags); 273166d2f6aSOhad Ben-Cohen 274166d2f6aSOhad Ben-Cohen /* sanity check */ 275166d2f6aSOhad Ben-Cohen if (ll->hcill_state != HCILL_AWAKE) 276166d2f6aSOhad Ben-Cohen BT_ERR("ERR: HCILL_GO_TO_SLEEP_IND in state %ld", ll->hcill_state); 277166d2f6aSOhad Ben-Cohen 278166d2f6aSOhad Ben-Cohen /* acknowledge device sleep */ 279166d2f6aSOhad Ben-Cohen if (send_hcill_cmd(HCILL_GO_TO_SLEEP_ACK, hu) < 0) { 280166d2f6aSOhad Ben-Cohen BT_ERR("cannot acknowledge device sleep"); 281166d2f6aSOhad Ben-Cohen goto out; 282166d2f6aSOhad Ben-Cohen } 283166d2f6aSOhad Ben-Cohen 284166d2f6aSOhad Ben-Cohen /* update state */ 285166d2f6aSOhad Ben-Cohen ll->hcill_state = HCILL_ASLEEP; 286166d2f6aSOhad Ben-Cohen 287166d2f6aSOhad Ben-Cohen out: 288166d2f6aSOhad Ben-Cohen spin_unlock_irqrestore(&ll->hcill_lock, flags); 289166d2f6aSOhad Ben-Cohen 290166d2f6aSOhad Ben-Cohen /* actually send the sleep ack packet */ 291166d2f6aSOhad Ben-Cohen hci_uart_tx_wakeup(hu); 292166d2f6aSOhad Ben-Cohen } 293166d2f6aSOhad Ben-Cohen 294166d2f6aSOhad Ben-Cohen /* 295166d2f6aSOhad Ben-Cohen * Called upon wake-up-acknowledgement from the device 296166d2f6aSOhad Ben-Cohen */ 297166d2f6aSOhad Ben-Cohen static void ll_device_woke_up(struct hci_uart *hu) 298166d2f6aSOhad Ben-Cohen { 299166d2f6aSOhad Ben-Cohen unsigned long flags; 300166d2f6aSOhad Ben-Cohen struct ll_struct *ll = hu->priv; 301166d2f6aSOhad Ben-Cohen 302166d2f6aSOhad Ben-Cohen BT_DBG("hu %p", hu); 303166d2f6aSOhad Ben-Cohen 304166d2f6aSOhad Ben-Cohen /* lock hcill state */ 305166d2f6aSOhad Ben-Cohen spin_lock_irqsave(&ll->hcill_lock, flags); 306166d2f6aSOhad Ben-Cohen 307166d2f6aSOhad Ben-Cohen /* sanity check */ 308166d2f6aSOhad Ben-Cohen if (ll->hcill_state != HCILL_ASLEEP_TO_AWAKE) 309166d2f6aSOhad Ben-Cohen BT_ERR("received HCILL_WAKE_UP_ACK in state %ld", ll->hcill_state); 310166d2f6aSOhad Ben-Cohen 311166d2f6aSOhad Ben-Cohen /* send pending packets and change state to HCILL_AWAKE */ 312166d2f6aSOhad Ben-Cohen __ll_do_awake(ll); 313166d2f6aSOhad Ben-Cohen 314166d2f6aSOhad Ben-Cohen spin_unlock_irqrestore(&ll->hcill_lock, flags); 315166d2f6aSOhad Ben-Cohen 316166d2f6aSOhad Ben-Cohen /* actually send the packets */ 317166d2f6aSOhad Ben-Cohen hci_uart_tx_wakeup(hu); 318166d2f6aSOhad Ben-Cohen } 319166d2f6aSOhad Ben-Cohen 320166d2f6aSOhad Ben-Cohen /* Enqueue frame for transmittion (padding, crc, etc) */ 321166d2f6aSOhad Ben-Cohen /* may be called from two simultaneous tasklets */ 322166d2f6aSOhad Ben-Cohen static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb) 323166d2f6aSOhad Ben-Cohen { 324166d2f6aSOhad Ben-Cohen unsigned long flags = 0; 325166d2f6aSOhad Ben-Cohen struct ll_struct *ll = hu->priv; 326166d2f6aSOhad Ben-Cohen 327166d2f6aSOhad Ben-Cohen BT_DBG("hu %p skb %p", hu, skb); 328166d2f6aSOhad Ben-Cohen 329166d2f6aSOhad Ben-Cohen /* Prepend skb with frame type */ 330618e8bc2SMarcel Holtmann memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1); 331166d2f6aSOhad Ben-Cohen 332166d2f6aSOhad Ben-Cohen /* lock hcill state */ 333166d2f6aSOhad Ben-Cohen spin_lock_irqsave(&ll->hcill_lock, flags); 334166d2f6aSOhad Ben-Cohen 335166d2f6aSOhad Ben-Cohen /* act according to current state */ 336166d2f6aSOhad Ben-Cohen switch (ll->hcill_state) { 337166d2f6aSOhad Ben-Cohen case HCILL_AWAKE: 338166d2f6aSOhad Ben-Cohen BT_DBG("device awake, sending normally"); 339166d2f6aSOhad Ben-Cohen skb_queue_tail(&ll->txq, skb); 340166d2f6aSOhad Ben-Cohen break; 341166d2f6aSOhad Ben-Cohen case HCILL_ASLEEP: 342166d2f6aSOhad Ben-Cohen BT_DBG("device asleep, waking up and queueing packet"); 343166d2f6aSOhad Ben-Cohen /* save packet for later */ 344166d2f6aSOhad Ben-Cohen skb_queue_tail(&ll->tx_wait_q, skb); 345166d2f6aSOhad Ben-Cohen /* awake device */ 346166d2f6aSOhad Ben-Cohen if (send_hcill_cmd(HCILL_WAKE_UP_IND, hu) < 0) { 347166d2f6aSOhad Ben-Cohen BT_ERR("cannot wake up device"); 348166d2f6aSOhad Ben-Cohen break; 349166d2f6aSOhad Ben-Cohen } 350166d2f6aSOhad Ben-Cohen ll->hcill_state = HCILL_ASLEEP_TO_AWAKE; 351166d2f6aSOhad Ben-Cohen break; 352166d2f6aSOhad Ben-Cohen case HCILL_ASLEEP_TO_AWAKE: 353166d2f6aSOhad Ben-Cohen BT_DBG("device waking up, queueing packet"); 354166d2f6aSOhad Ben-Cohen /* transient state; just keep packet for later */ 355166d2f6aSOhad Ben-Cohen skb_queue_tail(&ll->tx_wait_q, skb); 356166d2f6aSOhad Ben-Cohen break; 357166d2f6aSOhad Ben-Cohen default: 358166d2f6aSOhad Ben-Cohen BT_ERR("illegal hcill state: %ld (losing packet)", ll->hcill_state); 359166d2f6aSOhad Ben-Cohen kfree_skb(skb); 360166d2f6aSOhad Ben-Cohen break; 361166d2f6aSOhad Ben-Cohen } 362166d2f6aSOhad Ben-Cohen 363166d2f6aSOhad Ben-Cohen spin_unlock_irqrestore(&ll->hcill_lock, flags); 364166d2f6aSOhad Ben-Cohen 365166d2f6aSOhad Ben-Cohen return 0; 366166d2f6aSOhad Ben-Cohen } 367166d2f6aSOhad Ben-Cohen 368e1a26170SMarcel Holtmann static inline int ll_check_data_len(struct hci_dev *hdev, struct ll_struct *ll, int len) 369166d2f6aSOhad Ben-Cohen { 370fc5fef61SGustavo Padovan int room = skb_tailroom(ll->rx_skb); 371166d2f6aSOhad Ben-Cohen 372166d2f6aSOhad Ben-Cohen BT_DBG("len %d room %d", len, room); 373166d2f6aSOhad Ben-Cohen 374166d2f6aSOhad Ben-Cohen if (!len) { 375e1a26170SMarcel Holtmann hci_recv_frame(hdev, ll->rx_skb); 376166d2f6aSOhad Ben-Cohen } else if (len > room) { 377166d2f6aSOhad Ben-Cohen BT_ERR("Data length is too large"); 378166d2f6aSOhad Ben-Cohen kfree_skb(ll->rx_skb); 379166d2f6aSOhad Ben-Cohen } else { 380166d2f6aSOhad Ben-Cohen ll->rx_state = HCILL_W4_DATA; 381166d2f6aSOhad Ben-Cohen ll->rx_count = len; 382166d2f6aSOhad Ben-Cohen return len; 383166d2f6aSOhad Ben-Cohen } 384166d2f6aSOhad Ben-Cohen 385166d2f6aSOhad Ben-Cohen ll->rx_state = HCILL_W4_PACKET_TYPE; 386166d2f6aSOhad Ben-Cohen ll->rx_skb = NULL; 387166d2f6aSOhad Ben-Cohen ll->rx_count = 0; 388166d2f6aSOhad Ben-Cohen 389166d2f6aSOhad Ben-Cohen return 0; 390166d2f6aSOhad Ben-Cohen } 391166d2f6aSOhad Ben-Cohen 392166d2f6aSOhad Ben-Cohen /* Recv data */ 3939d1c40ebSMarcel Holtmann static int ll_recv(struct hci_uart *hu, const void *data, int count) 394166d2f6aSOhad Ben-Cohen { 395166d2f6aSOhad Ben-Cohen struct ll_struct *ll = hu->priv; 3969d1c40ebSMarcel Holtmann const char *ptr; 397166d2f6aSOhad Ben-Cohen struct hci_event_hdr *eh; 398166d2f6aSOhad Ben-Cohen struct hci_acl_hdr *ah; 399166d2f6aSOhad Ben-Cohen struct hci_sco_hdr *sh; 400fc5fef61SGustavo Padovan int len, type, dlen; 401166d2f6aSOhad Ben-Cohen 402166d2f6aSOhad Ben-Cohen BT_DBG("hu %p count %d rx_state %ld rx_count %ld", hu, count, ll->rx_state, ll->rx_count); 403166d2f6aSOhad Ben-Cohen 404166d2f6aSOhad Ben-Cohen ptr = data; 405166d2f6aSOhad Ben-Cohen while (count) { 406166d2f6aSOhad Ben-Cohen if (ll->rx_count) { 407166d2f6aSOhad Ben-Cohen len = min_t(unsigned int, ll->rx_count, count); 408166d2f6aSOhad Ben-Cohen memcpy(skb_put(ll->rx_skb, len), ptr, len); 409166d2f6aSOhad Ben-Cohen ll->rx_count -= len; count -= len; ptr += len; 410166d2f6aSOhad Ben-Cohen 411166d2f6aSOhad Ben-Cohen if (ll->rx_count) 412166d2f6aSOhad Ben-Cohen continue; 413166d2f6aSOhad Ben-Cohen 414166d2f6aSOhad Ben-Cohen switch (ll->rx_state) { 415166d2f6aSOhad Ben-Cohen case HCILL_W4_DATA: 416166d2f6aSOhad Ben-Cohen BT_DBG("Complete data"); 417e1a26170SMarcel Holtmann hci_recv_frame(hu->hdev, ll->rx_skb); 418166d2f6aSOhad Ben-Cohen 419166d2f6aSOhad Ben-Cohen ll->rx_state = HCILL_W4_PACKET_TYPE; 420166d2f6aSOhad Ben-Cohen ll->rx_skb = NULL; 421166d2f6aSOhad Ben-Cohen continue; 422166d2f6aSOhad Ben-Cohen 423166d2f6aSOhad Ben-Cohen case HCILL_W4_EVENT_HDR: 424acce90d6SGustavo F. Padovan eh = hci_event_hdr(ll->rx_skb); 425166d2f6aSOhad Ben-Cohen 426166d2f6aSOhad Ben-Cohen BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen); 427166d2f6aSOhad Ben-Cohen 428e1a26170SMarcel Holtmann ll_check_data_len(hu->hdev, ll, eh->plen); 429166d2f6aSOhad Ben-Cohen continue; 430166d2f6aSOhad Ben-Cohen 431166d2f6aSOhad Ben-Cohen case HCILL_W4_ACL_HDR: 432acce90d6SGustavo F. Padovan ah = hci_acl_hdr(ll->rx_skb); 433166d2f6aSOhad Ben-Cohen dlen = __le16_to_cpu(ah->dlen); 434166d2f6aSOhad Ben-Cohen 435166d2f6aSOhad Ben-Cohen BT_DBG("ACL header: dlen %d", dlen); 436166d2f6aSOhad Ben-Cohen 437e1a26170SMarcel Holtmann ll_check_data_len(hu->hdev, ll, dlen); 438166d2f6aSOhad Ben-Cohen continue; 439166d2f6aSOhad Ben-Cohen 440166d2f6aSOhad Ben-Cohen case HCILL_W4_SCO_HDR: 441acce90d6SGustavo F. Padovan sh = hci_sco_hdr(ll->rx_skb); 442166d2f6aSOhad Ben-Cohen 443166d2f6aSOhad Ben-Cohen BT_DBG("SCO header: dlen %d", sh->dlen); 444166d2f6aSOhad Ben-Cohen 445e1a26170SMarcel Holtmann ll_check_data_len(hu->hdev, ll, sh->dlen); 446166d2f6aSOhad Ben-Cohen continue; 447166d2f6aSOhad Ben-Cohen } 448166d2f6aSOhad Ben-Cohen } 449166d2f6aSOhad Ben-Cohen 450166d2f6aSOhad Ben-Cohen /* HCILL_W4_PACKET_TYPE */ 451166d2f6aSOhad Ben-Cohen switch (*ptr) { 452166d2f6aSOhad Ben-Cohen case HCI_EVENT_PKT: 453166d2f6aSOhad Ben-Cohen BT_DBG("Event packet"); 454166d2f6aSOhad Ben-Cohen ll->rx_state = HCILL_W4_EVENT_HDR; 455166d2f6aSOhad Ben-Cohen ll->rx_count = HCI_EVENT_HDR_SIZE; 456166d2f6aSOhad Ben-Cohen type = HCI_EVENT_PKT; 457166d2f6aSOhad Ben-Cohen break; 458166d2f6aSOhad Ben-Cohen 459166d2f6aSOhad Ben-Cohen case HCI_ACLDATA_PKT: 460166d2f6aSOhad Ben-Cohen BT_DBG("ACL packet"); 461166d2f6aSOhad Ben-Cohen ll->rx_state = HCILL_W4_ACL_HDR; 462166d2f6aSOhad Ben-Cohen ll->rx_count = HCI_ACL_HDR_SIZE; 463166d2f6aSOhad Ben-Cohen type = HCI_ACLDATA_PKT; 464166d2f6aSOhad Ben-Cohen break; 465166d2f6aSOhad Ben-Cohen 466166d2f6aSOhad Ben-Cohen case HCI_SCODATA_PKT: 467166d2f6aSOhad Ben-Cohen BT_DBG("SCO packet"); 468166d2f6aSOhad Ben-Cohen ll->rx_state = HCILL_W4_SCO_HDR; 469166d2f6aSOhad Ben-Cohen ll->rx_count = HCI_SCO_HDR_SIZE; 470166d2f6aSOhad Ben-Cohen type = HCI_SCODATA_PKT; 471166d2f6aSOhad Ben-Cohen break; 472166d2f6aSOhad Ben-Cohen 473166d2f6aSOhad Ben-Cohen /* HCILL signals */ 474166d2f6aSOhad Ben-Cohen case HCILL_GO_TO_SLEEP_IND: 475166d2f6aSOhad Ben-Cohen BT_DBG("HCILL_GO_TO_SLEEP_IND packet"); 476166d2f6aSOhad Ben-Cohen ll_device_want_to_sleep(hu); 477166d2f6aSOhad Ben-Cohen ptr++; count--; 478166d2f6aSOhad Ben-Cohen continue; 479166d2f6aSOhad Ben-Cohen 480166d2f6aSOhad Ben-Cohen case HCILL_GO_TO_SLEEP_ACK: 481166d2f6aSOhad Ben-Cohen /* shouldn't happen */ 482166d2f6aSOhad Ben-Cohen BT_ERR("received HCILL_GO_TO_SLEEP_ACK (in state %ld)", ll->hcill_state); 483166d2f6aSOhad Ben-Cohen ptr++; count--; 484166d2f6aSOhad Ben-Cohen continue; 485166d2f6aSOhad Ben-Cohen 486166d2f6aSOhad Ben-Cohen case HCILL_WAKE_UP_IND: 487166d2f6aSOhad Ben-Cohen BT_DBG("HCILL_WAKE_UP_IND packet"); 488166d2f6aSOhad Ben-Cohen ll_device_want_to_wakeup(hu); 489166d2f6aSOhad Ben-Cohen ptr++; count--; 490166d2f6aSOhad Ben-Cohen continue; 491166d2f6aSOhad Ben-Cohen 492166d2f6aSOhad Ben-Cohen case HCILL_WAKE_UP_ACK: 493166d2f6aSOhad Ben-Cohen BT_DBG("HCILL_WAKE_UP_ACK packet"); 494166d2f6aSOhad Ben-Cohen ll_device_woke_up(hu); 495166d2f6aSOhad Ben-Cohen ptr++; count--; 496166d2f6aSOhad Ben-Cohen continue; 497166d2f6aSOhad Ben-Cohen 498166d2f6aSOhad Ben-Cohen default: 499166d2f6aSOhad Ben-Cohen BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr); 500166d2f6aSOhad Ben-Cohen hu->hdev->stat.err_rx++; 501166d2f6aSOhad Ben-Cohen ptr++; count--; 502166d2f6aSOhad Ben-Cohen continue; 503d650ccaeSPeter Senna Tschudin } 504166d2f6aSOhad Ben-Cohen 505166d2f6aSOhad Ben-Cohen ptr++; count--; 506166d2f6aSOhad Ben-Cohen 507166d2f6aSOhad Ben-Cohen /* Allocate packet */ 508166d2f6aSOhad Ben-Cohen ll->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); 509166d2f6aSOhad Ben-Cohen if (!ll->rx_skb) { 510166d2f6aSOhad Ben-Cohen BT_ERR("Can't allocate mem for new packet"); 511166d2f6aSOhad Ben-Cohen ll->rx_state = HCILL_W4_PACKET_TYPE; 512166d2f6aSOhad Ben-Cohen ll->rx_count = 0; 513fe1aff71SGustavo F. Padovan return -ENOMEM; 514166d2f6aSOhad Ben-Cohen } 515166d2f6aSOhad Ben-Cohen 516618e8bc2SMarcel Holtmann hci_skb_pkt_type(ll->rx_skb) = type; 517166d2f6aSOhad Ben-Cohen } 518166d2f6aSOhad Ben-Cohen 519166d2f6aSOhad Ben-Cohen return count; 520166d2f6aSOhad Ben-Cohen } 521166d2f6aSOhad Ben-Cohen 522166d2f6aSOhad Ben-Cohen static struct sk_buff *ll_dequeue(struct hci_uart *hu) 523166d2f6aSOhad Ben-Cohen { 524166d2f6aSOhad Ben-Cohen struct ll_struct *ll = hu->priv; 525166d2f6aSOhad Ben-Cohen return skb_dequeue(&ll->txq); 526166d2f6aSOhad Ben-Cohen } 527166d2f6aSOhad Ben-Cohen 52837180552SRob Herring #if IS_ENABLED(CONFIG_SERIAL_DEV_BUS) 52937180552SRob Herring static int read_local_version(struct hci_dev *hdev) 53037180552SRob Herring { 53137180552SRob Herring int err = 0; 53237180552SRob Herring unsigned short version = 0; 53337180552SRob Herring struct sk_buff *skb; 53437180552SRob Herring struct hci_rp_read_local_version *ver; 53537180552SRob Herring 53637180552SRob Herring skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL, HCI_INIT_TIMEOUT); 53737180552SRob Herring if (IS_ERR(skb)) { 53837180552SRob Herring bt_dev_err(hdev, "Reading TI version information failed (%ld)", 53937180552SRob Herring PTR_ERR(skb)); 540f2edd9f6SSebastian Reichel return PTR_ERR(skb); 54137180552SRob Herring } 54237180552SRob Herring if (skb->len != sizeof(*ver)) { 54337180552SRob Herring err = -EILSEQ; 54437180552SRob Herring goto out; 54537180552SRob Herring } 54637180552SRob Herring 54737180552SRob Herring ver = (struct hci_rp_read_local_version *)skb->data; 54837180552SRob Herring if (le16_to_cpu(ver->manufacturer) != 13) { 54937180552SRob Herring err = -ENODEV; 55037180552SRob Herring goto out; 55137180552SRob Herring } 55237180552SRob Herring 55337180552SRob Herring version = le16_to_cpu(ver->lmp_subver); 55437180552SRob Herring 55537180552SRob Herring out: 55637180552SRob Herring if (err) bt_dev_err(hdev, "Failed to read TI version info: %d", err); 55737180552SRob Herring kfree_skb(skb); 55837180552SRob Herring return err ? err : version; 55937180552SRob Herring } 56037180552SRob Herring 56137180552SRob Herring /** 56237180552SRob Herring * download_firmware - 56337180552SRob Herring * internal function which parses through the .bts firmware 56437180552SRob Herring * script file intreprets SEND, DELAY actions only as of now 56537180552SRob Herring */ 56637180552SRob Herring static int download_firmware(struct ll_device *lldev) 56737180552SRob Herring { 56837180552SRob Herring unsigned short chip, min_ver, maj_ver; 56937180552SRob Herring int version, err, len; 57037180552SRob Herring unsigned char *ptr, *action_ptr; 57137180552SRob Herring unsigned char bts_scr_name[40]; /* 40 char long bts scr name? */ 57237180552SRob Herring const struct firmware *fw; 57337180552SRob Herring struct sk_buff *skb; 57437180552SRob Herring struct hci_command *cmd; 57537180552SRob Herring 57637180552SRob Herring version = read_local_version(lldev->hu.hdev); 57737180552SRob Herring if (version < 0) 57837180552SRob Herring return version; 57937180552SRob Herring 58037180552SRob Herring chip = (version & 0x7C00) >> 10; 58137180552SRob Herring min_ver = (version & 0x007F); 58237180552SRob Herring maj_ver = (version & 0x0380) >> 7; 58337180552SRob Herring if (version & 0x8000) 58437180552SRob Herring maj_ver |= 0x0008; 58537180552SRob Herring 58637180552SRob Herring snprintf(bts_scr_name, sizeof(bts_scr_name), 58737180552SRob Herring "ti-connectivity/TIInit_%d.%d.%d.bts", 58837180552SRob Herring chip, maj_ver, min_ver); 58937180552SRob Herring 59037180552SRob Herring err = request_firmware(&fw, bts_scr_name, &lldev->serdev->dev); 59137180552SRob Herring if (err || !fw->data || !fw->size) { 59237180552SRob Herring bt_dev_err(lldev->hu.hdev, "request_firmware failed(errno %d) for %s", 59337180552SRob Herring err, bts_scr_name); 59437180552SRob Herring return -EINVAL; 59537180552SRob Herring } 59637180552SRob Herring ptr = (void *)fw->data; 59737180552SRob Herring len = fw->size; 59837180552SRob Herring /* bts_header to remove out magic number and 59937180552SRob Herring * version 60037180552SRob Herring */ 60137180552SRob Herring ptr += sizeof(struct bts_header); 60237180552SRob Herring len -= sizeof(struct bts_header); 60337180552SRob Herring 60437180552SRob Herring while (len > 0 && ptr) { 60537180552SRob Herring bt_dev_dbg(lldev->hu.hdev, " action size %d, type %d ", 60637180552SRob Herring ((struct bts_action *)ptr)->size, 60737180552SRob Herring ((struct bts_action *)ptr)->type); 60837180552SRob Herring 60937180552SRob Herring action_ptr = &(((struct bts_action *)ptr)->data[0]); 61037180552SRob Herring 61137180552SRob Herring switch (((struct bts_action *)ptr)->type) { 61237180552SRob Herring case ACTION_SEND_COMMAND: /* action send */ 61337180552SRob Herring bt_dev_dbg(lldev->hu.hdev, "S"); 61437180552SRob Herring cmd = (struct hci_command *)action_ptr; 61537180552SRob Herring if (cmd->opcode == 0xff36) { 61637180552SRob Herring /* ignore remote change 61737180552SRob Herring * baud rate HCI VS command */ 61837180552SRob Herring bt_dev_warn(lldev->hu.hdev, "change remote baud rate command in firmware"); 61937180552SRob Herring break; 62037180552SRob Herring } 62137180552SRob Herring if (cmd->prefix != 1) 62237180552SRob Herring bt_dev_dbg(lldev->hu.hdev, "command type %d\n", cmd->prefix); 62337180552SRob Herring 62437180552SRob Herring skb = __hci_cmd_sync(lldev->hu.hdev, cmd->opcode, cmd->plen, &cmd->speed, HCI_INIT_TIMEOUT); 62537180552SRob Herring if (IS_ERR(skb)) { 62637180552SRob Herring bt_dev_err(lldev->hu.hdev, "send command failed\n"); 627823b8420SGuodong Xu err = PTR_ERR(skb); 62837180552SRob Herring goto out_rel_fw; 62937180552SRob Herring } 63037180552SRob Herring kfree_skb(skb); 63137180552SRob Herring break; 63237180552SRob Herring case ACTION_WAIT_EVENT: /* wait */ 63337180552SRob Herring /* no need to wait as command was synchronous */ 63437180552SRob Herring bt_dev_dbg(lldev->hu.hdev, "W"); 63537180552SRob Herring break; 63637180552SRob Herring case ACTION_DELAY: /* sleep */ 63737180552SRob Herring bt_dev_info(lldev->hu.hdev, "sleep command in scr"); 63837180552SRob Herring mdelay(((struct bts_action_delay *)action_ptr)->msec); 63937180552SRob Herring break; 64037180552SRob Herring } 64137180552SRob Herring len -= (sizeof(struct bts_action) + 64237180552SRob Herring ((struct bts_action *)ptr)->size); 64337180552SRob Herring ptr += sizeof(struct bts_action) + 64437180552SRob Herring ((struct bts_action *)ptr)->size; 64537180552SRob Herring } 64637180552SRob Herring 64737180552SRob Herring out_rel_fw: 64837180552SRob Herring /* fw download complete */ 64937180552SRob Herring release_firmware(fw); 65037180552SRob Herring return err; 65137180552SRob Herring } 65237180552SRob Herring 65337180552SRob Herring static int ll_setup(struct hci_uart *hu) 65437180552SRob Herring { 65537180552SRob Herring int err, retry = 3; 65637180552SRob Herring struct ll_device *lldev; 65737180552SRob Herring struct serdev_device *serdev = hu->serdev; 65837180552SRob Herring u32 speed; 65937180552SRob Herring 66037180552SRob Herring if (!serdev) 66137180552SRob Herring return 0; 66237180552SRob Herring 66337180552SRob Herring lldev = serdev_device_get_drvdata(serdev); 66437180552SRob Herring 66537180552SRob Herring serdev_device_set_flow_control(serdev, true); 66637180552SRob Herring 66737180552SRob Herring do { 66837180552SRob Herring /* Configure BT_EN to HIGH state */ 66937180552SRob Herring gpiod_set_value_cansleep(lldev->enable_gpio, 0); 67037180552SRob Herring msleep(5); 67137180552SRob Herring gpiod_set_value_cansleep(lldev->enable_gpio, 1); 67237180552SRob Herring msleep(100); 67337180552SRob Herring 67437180552SRob Herring err = download_firmware(lldev); 67537180552SRob Herring if (!err) 67637180552SRob Herring break; 67737180552SRob Herring 67837180552SRob Herring /* Toggle BT_EN and retry */ 67937180552SRob Herring bt_dev_err(hu->hdev, "download firmware failed, retrying..."); 68037180552SRob Herring } while (retry--); 68137180552SRob Herring 68237180552SRob Herring if (err) 68337180552SRob Herring return err; 68437180552SRob Herring 68537180552SRob Herring /* Operational speed if any */ 68637180552SRob Herring if (hu->oper_speed) 68737180552SRob Herring speed = hu->oper_speed; 68837180552SRob Herring else if (hu->proto->oper_speed) 68937180552SRob Herring speed = hu->proto->oper_speed; 69037180552SRob Herring else 69137180552SRob Herring speed = 0; 69237180552SRob Herring 69337180552SRob Herring if (speed) { 69437180552SRob Herring struct sk_buff *skb = __hci_cmd_sync(hu->hdev, 0xff36, sizeof(speed), &speed, HCI_INIT_TIMEOUT); 69537180552SRob Herring if (!IS_ERR(skb)) { 69637180552SRob Herring kfree_skb(skb); 69737180552SRob Herring serdev_device_set_baudrate(serdev, speed); 69837180552SRob Herring } 69937180552SRob Herring } 70037180552SRob Herring 70137180552SRob Herring return 0; 70237180552SRob Herring } 70337180552SRob Herring 70437180552SRob Herring static const struct hci_uart_proto llp; 70537180552SRob Herring 70637180552SRob Herring static int hci_ti_probe(struct serdev_device *serdev) 70737180552SRob Herring { 70837180552SRob Herring struct hci_uart *hu; 70937180552SRob Herring struct ll_device *lldev; 71037180552SRob Herring u32 max_speed = 3000000; 71137180552SRob Herring 71237180552SRob Herring lldev = devm_kzalloc(&serdev->dev, sizeof(struct ll_device), GFP_KERNEL); 71337180552SRob Herring if (!lldev) 71437180552SRob Herring return -ENOMEM; 71537180552SRob Herring hu = &lldev->hu; 71637180552SRob Herring 71737180552SRob Herring serdev_device_set_drvdata(serdev, lldev); 71837180552SRob Herring lldev->serdev = hu->serdev = serdev; 71937180552SRob Herring 72037180552SRob Herring lldev->enable_gpio = devm_gpiod_get_optional(&serdev->dev, "enable", GPIOD_OUT_LOW); 72137180552SRob Herring if (IS_ERR(lldev->enable_gpio)) 72237180552SRob Herring return PTR_ERR(lldev->enable_gpio); 72337180552SRob Herring 72437180552SRob Herring of_property_read_u32(serdev->dev.of_node, "max-speed", &max_speed); 72537180552SRob Herring hci_uart_set_speeds(hu, 115200, max_speed); 72637180552SRob Herring 72737180552SRob Herring return hci_uart_register_device(hu, &llp); 72837180552SRob Herring } 72937180552SRob Herring 73037180552SRob Herring static void hci_ti_remove(struct serdev_device *serdev) 73137180552SRob Herring { 73237180552SRob Herring struct ll_device *lldev = serdev_device_get_drvdata(serdev); 73337180552SRob Herring struct hci_uart *hu = &lldev->hu; 73437180552SRob Herring struct hci_dev *hdev = hu->hdev; 73537180552SRob Herring 73637180552SRob Herring cancel_work_sync(&hu->write_work); 73737180552SRob Herring 73837180552SRob Herring hci_unregister_dev(hdev); 73937180552SRob Herring hci_free_dev(hdev); 74037180552SRob Herring hu->proto->close(hu); 74137180552SRob Herring } 74237180552SRob Herring 74337180552SRob Herring static const struct of_device_id hci_ti_of_match[] = { 744*c127a871SSebastian Reichel { .compatible = "ti,wl1271-st" }, 745*c127a871SSebastian Reichel { .compatible = "ti,wl1273-st" }, 746*c127a871SSebastian Reichel { .compatible = "ti,wl1281-st" }, 747*c127a871SSebastian Reichel { .compatible = "ti,wl1283-st" }, 748*c127a871SSebastian Reichel { .compatible = "ti,wl1285-st" }, 749*c127a871SSebastian Reichel { .compatible = "ti,wl1801-st" }, 750*c127a871SSebastian Reichel { .compatible = "ti,wl1805-st" }, 751*c127a871SSebastian Reichel { .compatible = "ti,wl1807-st" }, 75237180552SRob Herring { .compatible = "ti,wl1831-st" }, 75337180552SRob Herring { .compatible = "ti,wl1835-st" }, 75437180552SRob Herring { .compatible = "ti,wl1837-st" }, 75537180552SRob Herring {}, 75637180552SRob Herring }; 75737180552SRob Herring MODULE_DEVICE_TABLE(of, hci_ti_of_match); 75837180552SRob Herring 75937180552SRob Herring static struct serdev_device_driver hci_ti_drv = { 76037180552SRob Herring .driver = { 76137180552SRob Herring .name = "hci-ti", 76237180552SRob Herring .of_match_table = of_match_ptr(hci_ti_of_match), 76337180552SRob Herring }, 76437180552SRob Herring .probe = hci_ti_probe, 76537180552SRob Herring .remove = hci_ti_remove, 76637180552SRob Herring }; 76737180552SRob Herring #else 76837180552SRob Herring #define ll_setup NULL 76937180552SRob Herring #endif 77037180552SRob Herring 7714ee7ef19SMarcel Holtmann static const struct hci_uart_proto llp = { 772166d2f6aSOhad Ben-Cohen .id = HCI_UART_LL, 7737c40fb8dSMarcel Holtmann .name = "LL", 77437180552SRob Herring .setup = ll_setup, 775166d2f6aSOhad Ben-Cohen .open = ll_open, 776166d2f6aSOhad Ben-Cohen .close = ll_close, 777166d2f6aSOhad Ben-Cohen .recv = ll_recv, 778166d2f6aSOhad Ben-Cohen .enqueue = ll_enqueue, 779166d2f6aSOhad Ben-Cohen .dequeue = ll_dequeue, 780166d2f6aSOhad Ben-Cohen .flush = ll_flush, 781166d2f6aSOhad Ben-Cohen }; 782166d2f6aSOhad Ben-Cohen 783f2b94bb9SGustavo F. Padovan int __init ll_init(void) 784166d2f6aSOhad Ben-Cohen { 78537180552SRob Herring serdev_device_driver_register(&hci_ti_drv); 78637180552SRob Herring 78701009eecSMarcel Holtmann return hci_uart_register_proto(&llp); 788166d2f6aSOhad Ben-Cohen } 789166d2f6aSOhad Ben-Cohen 790f2b94bb9SGustavo F. Padovan int __exit ll_deinit(void) 791166d2f6aSOhad Ben-Cohen { 79237180552SRob Herring serdev_device_driver_unregister(&hci_ti_drv); 79337180552SRob Herring 794166d2f6aSOhad Ben-Cohen return hci_uart_unregister_proto(&llp); 795166d2f6aSOhad Ben-Cohen } 796