~ubuntu-branches/ubuntu/natty/linux-backports-modules-2.6.38/natty-updates

« back to all changes in this revision

Viewing changes to updates/cw-3.0.0/drivers/bluetooth/hci_ath.c

  • Committer: Package Import Robot
  • Author(s): Herton Ronaldo Krzesinski, Herton Ronaldo Krzesinski, Tim Gardner
  • Date: 2011-09-27 18:53:53 UTC
  • Revision ID: package-import@ubuntu.com-20110927185353-kv2b0it2l42t74bh
Tags: 2.6.38-12.8
[ Herton Ronaldo Krzesinski ]

* Bump ABI - Natty ABI 12

[ Tim Gardner ]

* Added compat wireless 3.0.0
  - LP: #819484

Show diffs side-by-side

added added

removed removed

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