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