1b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala/* 2b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * Atheros Communication Bluetooth HCIATH3K UART protocol 3b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * 4b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * HCIATH3K (HCI Atheros AR300x Protocol) is a Atheros Communication's 5b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * power management protocol extension to H4 to support AR300x Bluetooth Chip. 6b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * 7b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * Copyright (c) 2009-2010 Atheros Communications Inc. 8b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * 9b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * Acknowledgements: 10b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * This file is based on hci_h4.c, which was written 11b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * by Maxim Krasnyansky and Marcel Holtmann. 12b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * 13b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * This program is free software; you can redistribute it and/or modify 14b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * it under the terms of the GNU General Public License as published by 15b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * the Free Software Foundation; either version 2 of the License, or 16b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * (at your option) any later version. 17b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * 18b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * This program is distributed in the hope that it will be useful, 19b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * but WITHOUT ANY WARRANTY; without even the implied warranty of 20b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * GNU General Public License for more details. 22b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * 23b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * You should have received a copy of the GNU General Public License 24b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * along with this program; if not, write to the Free Software 25b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * 27b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala */ 28b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 29b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala#include <linux/module.h> 30b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala#include <linux/kernel.h> 31b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 32b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala#include <linux/init.h> 33b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala#include <linux/slab.h> 34b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala#include <linux/tty.h> 35b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala#include <linux/errno.h> 36b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala#include <linux/ioctl.h> 37b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala#include <linux/skbuff.h> 38b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 39b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala#include <net/bluetooth/bluetooth.h> 40b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala#include <net/bluetooth/hci_core.h> 41b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 42b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala#include "hci_uart.h" 43b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 44b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangalastruct ath_struct { 45b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala struct hci_uart *hu; 46b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala unsigned int cur_sleep; 47b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 48b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala struct sk_buff_head txq; 49b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala struct work_struct ctxtsw; 50b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala}; 51b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 52b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangalastatic int ath_wakeup_ar3k(struct tty_struct *tty) 53b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala{ 54afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox struct ktermios ktermios; 55afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox int status = tty->driver->ops->tiocmget(tty); 56b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 57b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala if (status & TIOCM_CTS) 58b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return status; 59b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 60b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala /* Disable Automatic RTSCTS */ 61afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox memcpy(&ktermios, tty->termios, sizeof(ktermios)); 62afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox ktermios.c_cflag &= ~CRTSCTS; 63afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox tty_set_termios(tty, &ktermios); 64b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 65b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala /* Clear RTS first */ 66afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox status = tty->driver->ops->tiocmget(tty); 67afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox tty->driver->ops->tiocmset(tty, 0x00, TIOCM_RTS); 68b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala mdelay(20); 69b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 70b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala /* Set RTS, wake up board */ 71afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox status = tty->driver->ops->tiocmget(tty); 72afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox tty->driver->ops->tiocmset(tty, TIOCM_RTS, 0x00); 73b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala mdelay(20); 74b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 75afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox status = tty->driver->ops->tiocmget(tty); 76b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 77afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox /* Disable Automatic RTSCTS */ 78afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox ktermios.c_cflag |= CRTSCTS; 79afaae08442d86402f9e0b63475c02a651c6f1387Alan Cox status = tty_set_termios(tty, &ktermios); 80b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 81b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return status; 82b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala} 83b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 84b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangalastatic void ath_hci_uart_work(struct work_struct *work) 85b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala{ 86b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala int status; 87b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala struct ath_struct *ath; 88b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala struct hci_uart *hu; 89b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala struct tty_struct *tty; 90b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 91b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala ath = container_of(work, struct ath_struct, ctxtsw); 92b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 93b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala hu = ath->hu; 94b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala tty = hu->tty; 95b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 96b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala /* verify and wake up controller */ 97b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala if (ath->cur_sleep) { 98b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala status = ath_wakeup_ar3k(tty); 99b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala if (!(status & TIOCM_CTS)) 100b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return; 101b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala } 102b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 103b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala /* Ready to send Data */ 104b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala clear_bit(HCI_UART_SENDING, &hu->tx_state); 105b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala hci_uart_tx_wakeup(hu); 106b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala} 107b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 108b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala/* Initialize protocol */ 109b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangalastatic int ath_open(struct hci_uart *hu) 110b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala{ 111b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala struct ath_struct *ath; 112b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 113b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala BT_DBG("hu %p", hu); 114b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 115f5fd5baee39fe941bd73973c63990d153184e3a1David Herrmann ath = kzalloc(sizeof(*ath), GFP_KERNEL); 116b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala if (!ath) 117b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return -ENOMEM; 118b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 119b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala skb_queue_head_init(&ath->txq); 120b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 121b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala hu->priv = ath; 122b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala ath->hu = hu; 123b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 124b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala INIT_WORK(&ath->ctxtsw, ath_hci_uart_work); 125b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 126b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return 0; 127b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala} 128b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 129b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala/* Flush protocol data */ 130b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangalastatic int ath_flush(struct hci_uart *hu) 131b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala{ 132b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala struct ath_struct *ath = hu->priv; 133b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 134b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala BT_DBG("hu %p", hu); 135b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 136b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala skb_queue_purge(&ath->txq); 137b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 138b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return 0; 139b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala} 140b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 141b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala/* Close protocol */ 142b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangalastatic int ath_close(struct hci_uart *hu) 143b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala{ 144b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala struct ath_struct *ath = hu->priv; 145b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 146b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala BT_DBG("hu %p", hu); 147b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 148b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala skb_queue_purge(&ath->txq); 149b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 150b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala cancel_work_sync(&ath->ctxtsw); 151b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 152b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala hu->priv = NULL; 153b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala kfree(ath); 154b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 155b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return 0; 156b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala} 157b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 158b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala#define HCI_OP_ATH_SLEEP 0xFC04 159b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 160b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala/* Enqueue frame for transmittion */ 161b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangalastatic int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb) 162b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala{ 163b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala struct ath_struct *ath = hu->priv; 164b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 165b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) { 1664ebaa4edf8799cab19d5a0642dc95f04fd284e06Dan Carpenter kfree_skb(skb); 167b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return 0; 168b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala } 169b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 170b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala /* 171b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * Update power management enable flag with parameters of 172b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala * HCI sleep enable vendor specific HCI command. 173b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala */ 174b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { 175b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala struct hci_command_hdr *hdr = (void *)skb->data; 176b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 177b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala if (__le16_to_cpu(hdr->opcode) == HCI_OP_ATH_SLEEP) 178b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala ath->cur_sleep = skb->data[HCI_COMMAND_HDR_SIZE]; 179b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala } 180b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 181b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala BT_DBG("hu %p skb %p", hu, skb); 182b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 183b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala /* Prepend skb with frame type */ 184b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); 185b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 186b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala skb_queue_tail(&ath->txq, skb); 187b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala set_bit(HCI_UART_SENDING, &hu->tx_state); 188b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 189b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala schedule_work(&ath->ctxtsw); 190b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 191b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return 0; 192b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala} 193b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 194b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangalastatic struct sk_buff *ath_dequeue(struct hci_uart *hu) 195b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala{ 196b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala struct ath_struct *ath = hu->priv; 197b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 198b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return skb_dequeue(&ath->txq); 199b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala} 200b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 201b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala/* Recv data */ 202b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangalastatic int ath_recv(struct hci_uart *hu, void *data, int count) 203b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala{ 20478b4a56c28c096a1eb02f1d864eb450eb910e43dJiejing Zhang int ret; 20578b4a56c28c096a1eb02f1d864eb450eb910e43dJiejing Zhang 20678b4a56c28c096a1eb02f1d864eb450eb910e43dJiejing Zhang ret = hci_recv_stream_fragment(hu->hdev, data, count); 20778b4a56c28c096a1eb02f1d864eb450eb910e43dJiejing Zhang if (ret < 0) { 208b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala BT_ERR("Frame Reassembly Failed"); 20978b4a56c28c096a1eb02f1d864eb450eb910e43dJiejing Zhang return ret; 21078b4a56c28c096a1eb02f1d864eb450eb910e43dJiejing Zhang } 211b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 212b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return count; 213b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala} 214b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 215b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangalastatic struct hci_uart_proto athp = { 216b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala .id = HCI_UART_ATH3K, 217b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala .open = ath_open, 218b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala .close = ath_close, 219b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala .recv = ath_recv, 220b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala .enqueue = ath_enqueue, 221b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala .dequeue = ath_dequeue, 222b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala .flush = ath_flush, 223b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala}; 224b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 225f2b94bb9e0b8bd048331a6e9d616e918f4bcbd97Gustavo F. Padovanint __init ath_init(void) 226b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala{ 227b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala int err = hci_uart_register_proto(&athp); 228b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 229b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala if (!err) 230b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala BT_INFO("HCIATH3K protocol initialized"); 231b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala else 232b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala BT_ERR("HCIATH3K protocol registration failed"); 233b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 234b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return err; 235b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala} 236b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala 237f2b94bb9e0b8bd048331a6e9d616e918f4bcbd97Gustavo F. Padovanint __exit ath_deinit(void) 238b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala{ 239b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala return hci_uart_unregister_proto(&athp); 240b3190df628617c7a4f188a9465aeabe1f5761933Suraj Sumangala} 241