1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun * Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify
9*4882a593Smuzhiyun * it under the terms of the GNU General Public License version 2 as
10*4882a593Smuzhiyun * published by the Free Software Foundation;
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * Software distributed under the License is distributed on an "AS
13*4882a593Smuzhiyun * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14*4882a593Smuzhiyun * implied. See the License for the specific language governing
15*4882a593Smuzhiyun * rights and limitations under the License.
16*4882a593Smuzhiyun *
17*4882a593Smuzhiyun * The initial developer of the original code is David A. Hinds
18*4882a593Smuzhiyun * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
19*4882a593Smuzhiyun * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
20*4882a593Smuzhiyun *
21*4882a593Smuzhiyun */
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #include <linux/module.h>
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #include <linux/kernel.h>
26*4882a593Smuzhiyun #include <linux/init.h>
27*4882a593Smuzhiyun #include <linux/slab.h>
28*4882a593Smuzhiyun #include <linux/types.h>
29*4882a593Smuzhiyun #include <linux/sched.h>
30*4882a593Smuzhiyun #include <linux/delay.h>
31*4882a593Smuzhiyun #include <linux/timer.h>
32*4882a593Smuzhiyun #include <linux/errno.h>
33*4882a593Smuzhiyun #include <linux/ptrace.h>
34*4882a593Smuzhiyun #include <linux/ioport.h>
35*4882a593Smuzhiyun #include <linux/spinlock.h>
36*4882a593Smuzhiyun #include <linux/moduleparam.h>
37*4882a593Smuzhiyun #include <linux/wait.h>
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun #include <linux/skbuff.h>
40*4882a593Smuzhiyun #include <linux/io.h>
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun #include <pcmcia/cistpl.h>
43*4882a593Smuzhiyun #include <pcmcia/ciscode.h>
44*4882a593Smuzhiyun #include <pcmcia/ds.h>
45*4882a593Smuzhiyun #include <pcmcia/cisreg.h>
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun #include <net/bluetooth/bluetooth.h>
48*4882a593Smuzhiyun #include <net/bluetooth/hci_core.h>
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun /* ======================== Module parameters ======================== */
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
56*4882a593Smuzhiyun MODULE_DESCRIPTION("Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)");
57*4882a593Smuzhiyun MODULE_LICENSE("GPL");
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /* ======================== Local structures ======================== */
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun struct bluecard_info {
65*4882a593Smuzhiyun struct pcmcia_device *p_dev;
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun struct hci_dev *hdev;
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun spinlock_t lock; /* For serializing operations */
70*4882a593Smuzhiyun struct timer_list timer; /* For LED control */
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun struct sk_buff_head txq;
73*4882a593Smuzhiyun unsigned long tx_state;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun unsigned long rx_state;
76*4882a593Smuzhiyun unsigned long rx_count;
77*4882a593Smuzhiyun struct sk_buff *rx_skb;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun unsigned char ctrl_reg;
80*4882a593Smuzhiyun unsigned long hw_state; /* Status of the hardware and LED control */
81*4882a593Smuzhiyun };
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun static int bluecard_config(struct pcmcia_device *link);
85*4882a593Smuzhiyun static void bluecard_release(struct pcmcia_device *link);
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun static void bluecard_detach(struct pcmcia_device *p_dev);
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun /* Default baud rate: 57600, 115200, 230400 or 460800 */
91*4882a593Smuzhiyun #define DEFAULT_BAUD_RATE 230400
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun /* Hardware states */
95*4882a593Smuzhiyun #define CARD_READY 1
96*4882a593Smuzhiyun #define CARD_ACTIVITY 2
97*4882a593Smuzhiyun #define CARD_HAS_PCCARD_ID 4
98*4882a593Smuzhiyun #define CARD_HAS_POWER_LED 5
99*4882a593Smuzhiyun #define CARD_HAS_ACTIVITY_LED 6
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun /* Transmit states */
102*4882a593Smuzhiyun #define XMIT_SENDING 1
103*4882a593Smuzhiyun #define XMIT_WAKEUP 2
104*4882a593Smuzhiyun #define XMIT_BUFFER_NUMBER 5 /* unset = buffer one, set = buffer two */
105*4882a593Smuzhiyun #define XMIT_BUF_ONE_READY 6
106*4882a593Smuzhiyun #define XMIT_BUF_TWO_READY 7
107*4882a593Smuzhiyun #define XMIT_SENDING_READY 8
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun /* Receiver states */
110*4882a593Smuzhiyun #define RECV_WAIT_PACKET_TYPE 0
111*4882a593Smuzhiyun #define RECV_WAIT_EVENT_HEADER 1
112*4882a593Smuzhiyun #define RECV_WAIT_ACL_HEADER 2
113*4882a593Smuzhiyun #define RECV_WAIT_SCO_HEADER 3
114*4882a593Smuzhiyun #define RECV_WAIT_DATA 4
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun /* Special packet types */
117*4882a593Smuzhiyun #define PKT_BAUD_RATE_57600 0x80
118*4882a593Smuzhiyun #define PKT_BAUD_RATE_115200 0x81
119*4882a593Smuzhiyun #define PKT_BAUD_RATE_230400 0x82
120*4882a593Smuzhiyun #define PKT_BAUD_RATE_460800 0x83
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun /* These are the register offsets */
124*4882a593Smuzhiyun #define REG_COMMAND 0x20
125*4882a593Smuzhiyun #define REG_INTERRUPT 0x21
126*4882a593Smuzhiyun #define REG_CONTROL 0x22
127*4882a593Smuzhiyun #define REG_RX_CONTROL 0x24
128*4882a593Smuzhiyun #define REG_CARD_RESET 0x30
129*4882a593Smuzhiyun #define REG_LED_CTRL 0x30
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun /* REG_COMMAND */
132*4882a593Smuzhiyun #define REG_COMMAND_TX_BUF_ONE 0x01
133*4882a593Smuzhiyun #define REG_COMMAND_TX_BUF_TWO 0x02
134*4882a593Smuzhiyun #define REG_COMMAND_RX_BUF_ONE 0x04
135*4882a593Smuzhiyun #define REG_COMMAND_RX_BUF_TWO 0x08
136*4882a593Smuzhiyun #define REG_COMMAND_RX_WIN_ONE 0x00
137*4882a593Smuzhiyun #define REG_COMMAND_RX_WIN_TWO 0x10
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun /* REG_CONTROL */
140*4882a593Smuzhiyun #define REG_CONTROL_BAUD_RATE_57600 0x00
141*4882a593Smuzhiyun #define REG_CONTROL_BAUD_RATE_115200 0x01
142*4882a593Smuzhiyun #define REG_CONTROL_BAUD_RATE_230400 0x02
143*4882a593Smuzhiyun #define REG_CONTROL_BAUD_RATE_460800 0x03
144*4882a593Smuzhiyun #define REG_CONTROL_RTS 0x04
145*4882a593Smuzhiyun #define REG_CONTROL_BT_ON 0x08
146*4882a593Smuzhiyun #define REG_CONTROL_BT_RESET 0x10
147*4882a593Smuzhiyun #define REG_CONTROL_BT_RES_PU 0x20
148*4882a593Smuzhiyun #define REG_CONTROL_INTERRUPT 0x40
149*4882a593Smuzhiyun #define REG_CONTROL_CARD_RESET 0x80
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /* REG_RX_CONTROL */
152*4882a593Smuzhiyun #define RTS_LEVEL_SHIFT_BITS 0x02
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun /* ======================== LED handling routines ======================== */
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun
bluecard_activity_led_timeout(struct timer_list * t)159*4882a593Smuzhiyun static void bluecard_activity_led_timeout(struct timer_list *t)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun struct bluecard_info *info = from_timer(info, t, timer);
162*4882a593Smuzhiyun unsigned int iobase = info->p_dev->resource[0]->start;
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun if (test_bit(CARD_ACTIVITY, &(info->hw_state))) {
165*4882a593Smuzhiyun /* leave LED in inactive state for HZ/10 for blink effect */
166*4882a593Smuzhiyun clear_bit(CARD_ACTIVITY, &(info->hw_state));
167*4882a593Smuzhiyun mod_timer(&(info->timer), jiffies + HZ / 10);
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun /* Disable activity LED, enable power LED */
171*4882a593Smuzhiyun outb(0x08 | 0x20, iobase + 0x30);
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun
bluecard_enable_activity_led(struct bluecard_info * info)175*4882a593Smuzhiyun static void bluecard_enable_activity_led(struct bluecard_info *info)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun unsigned int iobase = info->p_dev->resource[0]->start;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun /* don't disturb running blink timer */
180*4882a593Smuzhiyun if (timer_pending(&(info->timer)))
181*4882a593Smuzhiyun return;
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun set_bit(CARD_ACTIVITY, &(info->hw_state));
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
186*4882a593Smuzhiyun /* Enable activity LED, keep power LED enabled */
187*4882a593Smuzhiyun outb(0x18 | 0x60, iobase + 0x30);
188*4882a593Smuzhiyun } else {
189*4882a593Smuzhiyun /* Disable power LED */
190*4882a593Smuzhiyun outb(0x00, iobase + 0x30);
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun /* Stop the LED after HZ/10 */
194*4882a593Smuzhiyun mod_timer(&(info->timer), jiffies + HZ / 10);
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun /* ======================== Interrupt handling ======================== */
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun
bluecard_write(unsigned int iobase,unsigned int offset,__u8 * buf,int len)202*4882a593Smuzhiyun static int bluecard_write(unsigned int iobase, unsigned int offset, __u8 *buf, int len)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun int i, actual;
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun actual = (len > 15) ? 15 : len;
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun outb_p(actual, iobase + offset);
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun for (i = 0; i < actual; i++)
211*4882a593Smuzhiyun outb_p(buf[i], iobase + offset + i + 1);
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun return actual;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun
bluecard_write_wakeup(struct bluecard_info * info)217*4882a593Smuzhiyun static void bluecard_write_wakeup(struct bluecard_info *info)
218*4882a593Smuzhiyun {
219*4882a593Smuzhiyun if (!info) {
220*4882a593Smuzhiyun BT_ERR("Unknown device");
221*4882a593Smuzhiyun return;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun if (!test_bit(XMIT_SENDING_READY, &(info->tx_state)))
225*4882a593Smuzhiyun return;
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
228*4882a593Smuzhiyun set_bit(XMIT_WAKEUP, &(info->tx_state));
229*4882a593Smuzhiyun return;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun do {
233*4882a593Smuzhiyun unsigned int iobase = info->p_dev->resource[0]->start;
234*4882a593Smuzhiyun unsigned int offset;
235*4882a593Smuzhiyun unsigned char command;
236*4882a593Smuzhiyun unsigned long ready_bit;
237*4882a593Smuzhiyun register struct sk_buff *skb;
238*4882a593Smuzhiyun int len;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun clear_bit(XMIT_WAKEUP, &(info->tx_state));
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun if (!pcmcia_dev_present(info->p_dev))
243*4882a593Smuzhiyun return;
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
246*4882a593Smuzhiyun if (!test_bit(XMIT_BUF_TWO_READY, &(info->tx_state)))
247*4882a593Smuzhiyun break;
248*4882a593Smuzhiyun offset = 0x10;
249*4882a593Smuzhiyun command = REG_COMMAND_TX_BUF_TWO;
250*4882a593Smuzhiyun ready_bit = XMIT_BUF_TWO_READY;
251*4882a593Smuzhiyun } else {
252*4882a593Smuzhiyun if (!test_bit(XMIT_BUF_ONE_READY, &(info->tx_state)))
253*4882a593Smuzhiyun break;
254*4882a593Smuzhiyun offset = 0x00;
255*4882a593Smuzhiyun command = REG_COMMAND_TX_BUF_ONE;
256*4882a593Smuzhiyun ready_bit = XMIT_BUF_ONE_READY;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun skb = skb_dequeue(&(info->txq));
260*4882a593Smuzhiyun if (!skb)
261*4882a593Smuzhiyun break;
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun if (hci_skb_pkt_type(skb) & 0x80) {
264*4882a593Smuzhiyun /* Disable RTS */
265*4882a593Smuzhiyun info->ctrl_reg |= REG_CONTROL_RTS;
266*4882a593Smuzhiyun outb(info->ctrl_reg, iobase + REG_CONTROL);
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun /* Activate LED */
270*4882a593Smuzhiyun bluecard_enable_activity_led(info);
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun /* Send frame */
273*4882a593Smuzhiyun len = bluecard_write(iobase, offset, skb->data, skb->len);
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun /* Tell the FPGA to send the data */
276*4882a593Smuzhiyun outb_p(command, iobase + REG_COMMAND);
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun /* Mark the buffer as dirty */
279*4882a593Smuzhiyun clear_bit(ready_bit, &(info->tx_state));
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun if (hci_skb_pkt_type(skb) & 0x80) {
282*4882a593Smuzhiyun DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
283*4882a593Smuzhiyun DEFINE_WAIT(wait);
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun unsigned char baud_reg;
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun switch (hci_skb_pkt_type(skb)) {
288*4882a593Smuzhiyun case PKT_BAUD_RATE_460800:
289*4882a593Smuzhiyun baud_reg = REG_CONTROL_BAUD_RATE_460800;
290*4882a593Smuzhiyun break;
291*4882a593Smuzhiyun case PKT_BAUD_RATE_230400:
292*4882a593Smuzhiyun baud_reg = REG_CONTROL_BAUD_RATE_230400;
293*4882a593Smuzhiyun break;
294*4882a593Smuzhiyun case PKT_BAUD_RATE_115200:
295*4882a593Smuzhiyun baud_reg = REG_CONTROL_BAUD_RATE_115200;
296*4882a593Smuzhiyun break;
297*4882a593Smuzhiyun case PKT_BAUD_RATE_57600:
298*4882a593Smuzhiyun default:
299*4882a593Smuzhiyun baud_reg = REG_CONTROL_BAUD_RATE_57600;
300*4882a593Smuzhiyun break;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun /* Wait until the command reaches the baseband */
304*4882a593Smuzhiyun mdelay(100);
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun /* Set baud on baseband */
307*4882a593Smuzhiyun info->ctrl_reg &= ~0x03;
308*4882a593Smuzhiyun info->ctrl_reg |= baud_reg;
309*4882a593Smuzhiyun outb(info->ctrl_reg, iobase + REG_CONTROL);
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun /* Enable RTS */
312*4882a593Smuzhiyun info->ctrl_reg &= ~REG_CONTROL_RTS;
313*4882a593Smuzhiyun outb(info->ctrl_reg, iobase + REG_CONTROL);
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun /* Wait before the next HCI packet can be send */
316*4882a593Smuzhiyun mdelay(1000);
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun if (len == skb->len) {
320*4882a593Smuzhiyun kfree_skb(skb);
321*4882a593Smuzhiyun } else {
322*4882a593Smuzhiyun skb_pull(skb, len);
323*4882a593Smuzhiyun skb_queue_head(&(info->txq), skb);
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun info->hdev->stat.byte_tx += len;
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun /* Change buffer */
329*4882a593Smuzhiyun change_bit(XMIT_BUFFER_NUMBER, &(info->tx_state));
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun clear_bit(XMIT_SENDING, &(info->tx_state));
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun
bluecard_read(unsigned int iobase,unsigned int offset,__u8 * buf,int size)337*4882a593Smuzhiyun static int bluecard_read(unsigned int iobase, unsigned int offset, __u8 *buf, int size)
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun int i, n, len;
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun outb(REG_COMMAND_RX_WIN_ONE, iobase + REG_COMMAND);
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun len = inb(iobase + offset);
344*4882a593Smuzhiyun n = 0;
345*4882a593Smuzhiyun i = 1;
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun while (n < len) {
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun if (i == 16) {
350*4882a593Smuzhiyun outb(REG_COMMAND_RX_WIN_TWO, iobase + REG_COMMAND);
351*4882a593Smuzhiyun i = 0;
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun buf[n] = inb(iobase + offset + i);
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun n++;
357*4882a593Smuzhiyun i++;
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun return len;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun
bluecard_receive(struct bluecard_info * info,unsigned int offset)365*4882a593Smuzhiyun static void bluecard_receive(struct bluecard_info *info,
366*4882a593Smuzhiyun unsigned int offset)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun unsigned int iobase;
369*4882a593Smuzhiyun unsigned char buf[31];
370*4882a593Smuzhiyun int i, len;
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun if (!info) {
373*4882a593Smuzhiyun BT_ERR("Unknown device");
374*4882a593Smuzhiyun return;
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun iobase = info->p_dev->resource[0]->start;
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
380*4882a593Smuzhiyun bluecard_enable_activity_led(info);
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun len = bluecard_read(iobase, offset, buf, sizeof(buf));
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun for (i = 0; i < len; i++) {
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun /* Allocate packet */
387*4882a593Smuzhiyun if (!info->rx_skb) {
388*4882a593Smuzhiyun info->rx_state = RECV_WAIT_PACKET_TYPE;
389*4882a593Smuzhiyun info->rx_count = 0;
390*4882a593Smuzhiyun info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
391*4882a593Smuzhiyun if (!info->rx_skb) {
392*4882a593Smuzhiyun BT_ERR("Can't allocate mem for new packet");
393*4882a593Smuzhiyun return;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun hci_skb_pkt_type(info->rx_skb) = buf[i];
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun switch (hci_skb_pkt_type(info->rx_skb)) {
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun case 0x00:
404*4882a593Smuzhiyun /* init packet */
405*4882a593Smuzhiyun if (offset != 0x00) {
406*4882a593Smuzhiyun set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
407*4882a593Smuzhiyun set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
408*4882a593Smuzhiyun set_bit(XMIT_SENDING_READY, &(info->tx_state));
409*4882a593Smuzhiyun bluecard_write_wakeup(info);
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun kfree_skb(info->rx_skb);
413*4882a593Smuzhiyun info->rx_skb = NULL;
414*4882a593Smuzhiyun break;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun case HCI_EVENT_PKT:
417*4882a593Smuzhiyun info->rx_state = RECV_WAIT_EVENT_HEADER;
418*4882a593Smuzhiyun info->rx_count = HCI_EVENT_HDR_SIZE;
419*4882a593Smuzhiyun break;
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun case HCI_ACLDATA_PKT:
422*4882a593Smuzhiyun info->rx_state = RECV_WAIT_ACL_HEADER;
423*4882a593Smuzhiyun info->rx_count = HCI_ACL_HDR_SIZE;
424*4882a593Smuzhiyun break;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun case HCI_SCODATA_PKT:
427*4882a593Smuzhiyun info->rx_state = RECV_WAIT_SCO_HEADER;
428*4882a593Smuzhiyun info->rx_count = HCI_SCO_HDR_SIZE;
429*4882a593Smuzhiyun break;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun default:
432*4882a593Smuzhiyun /* unknown packet */
433*4882a593Smuzhiyun BT_ERR("Unknown HCI packet with type 0x%02x received",
434*4882a593Smuzhiyun hci_skb_pkt_type(info->rx_skb));
435*4882a593Smuzhiyun info->hdev->stat.err_rx++;
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun kfree_skb(info->rx_skb);
438*4882a593Smuzhiyun info->rx_skb = NULL;
439*4882a593Smuzhiyun break;
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun } else {
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun skb_put_u8(info->rx_skb, buf[i]);
446*4882a593Smuzhiyun info->rx_count--;
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun if (info->rx_count == 0) {
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun int dlen;
451*4882a593Smuzhiyun struct hci_event_hdr *eh;
452*4882a593Smuzhiyun struct hci_acl_hdr *ah;
453*4882a593Smuzhiyun struct hci_sco_hdr *sh;
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun switch (info->rx_state) {
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun case RECV_WAIT_EVENT_HEADER:
458*4882a593Smuzhiyun eh = hci_event_hdr(info->rx_skb);
459*4882a593Smuzhiyun info->rx_state = RECV_WAIT_DATA;
460*4882a593Smuzhiyun info->rx_count = eh->plen;
461*4882a593Smuzhiyun break;
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun case RECV_WAIT_ACL_HEADER:
464*4882a593Smuzhiyun ah = hci_acl_hdr(info->rx_skb);
465*4882a593Smuzhiyun dlen = __le16_to_cpu(ah->dlen);
466*4882a593Smuzhiyun info->rx_state = RECV_WAIT_DATA;
467*4882a593Smuzhiyun info->rx_count = dlen;
468*4882a593Smuzhiyun break;
469*4882a593Smuzhiyun
470*4882a593Smuzhiyun case RECV_WAIT_SCO_HEADER:
471*4882a593Smuzhiyun sh = hci_sco_hdr(info->rx_skb);
472*4882a593Smuzhiyun info->rx_state = RECV_WAIT_DATA;
473*4882a593Smuzhiyun info->rx_count = sh->dlen;
474*4882a593Smuzhiyun break;
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun case RECV_WAIT_DATA:
477*4882a593Smuzhiyun hci_recv_frame(info->hdev, info->rx_skb);
478*4882a593Smuzhiyun info->rx_skb = NULL;
479*4882a593Smuzhiyun break;
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun }
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun info->hdev->stat.byte_rx += len;
491*4882a593Smuzhiyun }
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun
bluecard_interrupt(int irq,void * dev_inst)494*4882a593Smuzhiyun static irqreturn_t bluecard_interrupt(int irq, void *dev_inst)
495*4882a593Smuzhiyun {
496*4882a593Smuzhiyun struct bluecard_info *info = dev_inst;
497*4882a593Smuzhiyun unsigned int iobase;
498*4882a593Smuzhiyun unsigned char reg;
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun if (!info || !info->hdev)
501*4882a593Smuzhiyun /* our irq handler is shared */
502*4882a593Smuzhiyun return IRQ_NONE;
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun if (!test_bit(CARD_READY, &(info->hw_state)))
505*4882a593Smuzhiyun return IRQ_HANDLED;
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun iobase = info->p_dev->resource[0]->start;
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun spin_lock(&(info->lock));
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun /* Disable interrupt */
512*4882a593Smuzhiyun info->ctrl_reg &= ~REG_CONTROL_INTERRUPT;
513*4882a593Smuzhiyun outb(info->ctrl_reg, iobase + REG_CONTROL);
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun reg = inb(iobase + REG_INTERRUPT);
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun if ((reg != 0x00) && (reg != 0xff)) {
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun if (reg & 0x04) {
520*4882a593Smuzhiyun bluecard_receive(info, 0x00);
521*4882a593Smuzhiyun outb(0x04, iobase + REG_INTERRUPT);
522*4882a593Smuzhiyun outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
523*4882a593Smuzhiyun }
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun if (reg & 0x08) {
526*4882a593Smuzhiyun bluecard_receive(info, 0x10);
527*4882a593Smuzhiyun outb(0x08, iobase + REG_INTERRUPT);
528*4882a593Smuzhiyun outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
529*4882a593Smuzhiyun }
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun if (reg & 0x01) {
532*4882a593Smuzhiyun set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
533*4882a593Smuzhiyun outb(0x01, iobase + REG_INTERRUPT);
534*4882a593Smuzhiyun bluecard_write_wakeup(info);
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun if (reg & 0x02) {
538*4882a593Smuzhiyun set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
539*4882a593Smuzhiyun outb(0x02, iobase + REG_INTERRUPT);
540*4882a593Smuzhiyun bluecard_write_wakeup(info);
541*4882a593Smuzhiyun }
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun /* Enable interrupt */
546*4882a593Smuzhiyun info->ctrl_reg |= REG_CONTROL_INTERRUPT;
547*4882a593Smuzhiyun outb(info->ctrl_reg, iobase + REG_CONTROL);
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun spin_unlock(&(info->lock));
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun return IRQ_HANDLED;
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun /* ======================== Device specific HCI commands ======================== */
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun
bluecard_hci_set_baud_rate(struct hci_dev * hdev,int baud)559*4882a593Smuzhiyun static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
560*4882a593Smuzhiyun {
561*4882a593Smuzhiyun struct bluecard_info *info = hci_get_drvdata(hdev);
562*4882a593Smuzhiyun struct sk_buff *skb;
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun /* Ericsson baud rate command */
565*4882a593Smuzhiyun unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_KERNEL);
568*4882a593Smuzhiyun if (!skb) {
569*4882a593Smuzhiyun BT_ERR("Can't allocate mem for new packet");
570*4882a593Smuzhiyun return -1;
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun switch (baud) {
574*4882a593Smuzhiyun case 460800:
575*4882a593Smuzhiyun cmd[4] = 0x00;
576*4882a593Smuzhiyun hci_skb_pkt_type(skb) = PKT_BAUD_RATE_460800;
577*4882a593Smuzhiyun break;
578*4882a593Smuzhiyun case 230400:
579*4882a593Smuzhiyun cmd[4] = 0x01;
580*4882a593Smuzhiyun hci_skb_pkt_type(skb) = PKT_BAUD_RATE_230400;
581*4882a593Smuzhiyun break;
582*4882a593Smuzhiyun case 115200:
583*4882a593Smuzhiyun cmd[4] = 0x02;
584*4882a593Smuzhiyun hci_skb_pkt_type(skb) = PKT_BAUD_RATE_115200;
585*4882a593Smuzhiyun break;
586*4882a593Smuzhiyun case 57600:
587*4882a593Smuzhiyun default:
588*4882a593Smuzhiyun cmd[4] = 0x03;
589*4882a593Smuzhiyun hci_skb_pkt_type(skb) = PKT_BAUD_RATE_57600;
590*4882a593Smuzhiyun break;
591*4882a593Smuzhiyun }
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun skb_put_data(skb, cmd, sizeof(cmd));
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun skb_queue_tail(&(info->txq), skb);
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun bluecard_write_wakeup(info);
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun return 0;
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun /* ======================== HCI interface ======================== */
605*4882a593Smuzhiyun
606*4882a593Smuzhiyun
bluecard_hci_flush(struct hci_dev * hdev)607*4882a593Smuzhiyun static int bluecard_hci_flush(struct hci_dev *hdev)
608*4882a593Smuzhiyun {
609*4882a593Smuzhiyun struct bluecard_info *info = hci_get_drvdata(hdev);
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun /* Drop TX queue */
612*4882a593Smuzhiyun skb_queue_purge(&(info->txq));
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun return 0;
615*4882a593Smuzhiyun }
616*4882a593Smuzhiyun
617*4882a593Smuzhiyun
bluecard_hci_open(struct hci_dev * hdev)618*4882a593Smuzhiyun static int bluecard_hci_open(struct hci_dev *hdev)
619*4882a593Smuzhiyun {
620*4882a593Smuzhiyun struct bluecard_info *info = hci_get_drvdata(hdev);
621*4882a593Smuzhiyun unsigned int iobase = info->p_dev->resource[0]->start;
622*4882a593Smuzhiyun
623*4882a593Smuzhiyun if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
624*4882a593Smuzhiyun bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun /* Enable power LED */
627*4882a593Smuzhiyun outb(0x08 | 0x20, iobase + 0x30);
628*4882a593Smuzhiyun
629*4882a593Smuzhiyun return 0;
630*4882a593Smuzhiyun }
631*4882a593Smuzhiyun
632*4882a593Smuzhiyun
bluecard_hci_close(struct hci_dev * hdev)633*4882a593Smuzhiyun static int bluecard_hci_close(struct hci_dev *hdev)
634*4882a593Smuzhiyun {
635*4882a593Smuzhiyun struct bluecard_info *info = hci_get_drvdata(hdev);
636*4882a593Smuzhiyun unsigned int iobase = info->p_dev->resource[0]->start;
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun bluecard_hci_flush(hdev);
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun /* Stop LED timer */
641*4882a593Smuzhiyun del_timer_sync(&(info->timer));
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun /* Disable power LED */
644*4882a593Smuzhiyun outb(0x00, iobase + 0x30);
645*4882a593Smuzhiyun
646*4882a593Smuzhiyun return 0;
647*4882a593Smuzhiyun }
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun
bluecard_hci_send_frame(struct hci_dev * hdev,struct sk_buff * skb)650*4882a593Smuzhiyun static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
651*4882a593Smuzhiyun {
652*4882a593Smuzhiyun struct bluecard_info *info = hci_get_drvdata(hdev);
653*4882a593Smuzhiyun
654*4882a593Smuzhiyun switch (hci_skb_pkt_type(skb)) {
655*4882a593Smuzhiyun case HCI_COMMAND_PKT:
656*4882a593Smuzhiyun hdev->stat.cmd_tx++;
657*4882a593Smuzhiyun break;
658*4882a593Smuzhiyun case HCI_ACLDATA_PKT:
659*4882a593Smuzhiyun hdev->stat.acl_tx++;
660*4882a593Smuzhiyun break;
661*4882a593Smuzhiyun case HCI_SCODATA_PKT:
662*4882a593Smuzhiyun hdev->stat.sco_tx++;
663*4882a593Smuzhiyun break;
664*4882a593Smuzhiyun }
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun /* Prepend skb with frame type */
667*4882a593Smuzhiyun memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
668*4882a593Smuzhiyun skb_queue_tail(&(info->txq), skb);
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun bluecard_write_wakeup(info);
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun return 0;
673*4882a593Smuzhiyun }
674*4882a593Smuzhiyun
675*4882a593Smuzhiyun
676*4882a593Smuzhiyun
677*4882a593Smuzhiyun /* ======================== Card services HCI interaction ======================== */
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun
bluecard_open(struct bluecard_info * info)680*4882a593Smuzhiyun static int bluecard_open(struct bluecard_info *info)
681*4882a593Smuzhiyun {
682*4882a593Smuzhiyun unsigned int iobase = info->p_dev->resource[0]->start;
683*4882a593Smuzhiyun struct hci_dev *hdev;
684*4882a593Smuzhiyun unsigned char id;
685*4882a593Smuzhiyun
686*4882a593Smuzhiyun spin_lock_init(&(info->lock));
687*4882a593Smuzhiyun
688*4882a593Smuzhiyun timer_setup(&info->timer, bluecard_activity_led_timeout, 0);
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun skb_queue_head_init(&(info->txq));
691*4882a593Smuzhiyun
692*4882a593Smuzhiyun info->rx_state = RECV_WAIT_PACKET_TYPE;
693*4882a593Smuzhiyun info->rx_count = 0;
694*4882a593Smuzhiyun info->rx_skb = NULL;
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun /* Initialize HCI device */
697*4882a593Smuzhiyun hdev = hci_alloc_dev();
698*4882a593Smuzhiyun if (!hdev) {
699*4882a593Smuzhiyun BT_ERR("Can't allocate HCI device");
700*4882a593Smuzhiyun return -ENOMEM;
701*4882a593Smuzhiyun }
702*4882a593Smuzhiyun
703*4882a593Smuzhiyun info->hdev = hdev;
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun hdev->bus = HCI_PCCARD;
706*4882a593Smuzhiyun hci_set_drvdata(hdev, info);
707*4882a593Smuzhiyun SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun hdev->open = bluecard_hci_open;
710*4882a593Smuzhiyun hdev->close = bluecard_hci_close;
711*4882a593Smuzhiyun hdev->flush = bluecard_hci_flush;
712*4882a593Smuzhiyun hdev->send = bluecard_hci_send_frame;
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun id = inb(iobase + 0x30);
715*4882a593Smuzhiyun
716*4882a593Smuzhiyun if ((id & 0x0f) == 0x02)
717*4882a593Smuzhiyun set_bit(CARD_HAS_PCCARD_ID, &(info->hw_state));
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun if (id & 0x10)
720*4882a593Smuzhiyun set_bit(CARD_HAS_POWER_LED, &(info->hw_state));
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun if (id & 0x20)
723*4882a593Smuzhiyun set_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state));
724*4882a593Smuzhiyun
725*4882a593Smuzhiyun /* Reset card */
726*4882a593Smuzhiyun info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
727*4882a593Smuzhiyun outb(info->ctrl_reg, iobase + REG_CONTROL);
728*4882a593Smuzhiyun
729*4882a593Smuzhiyun /* Turn FPGA off */
730*4882a593Smuzhiyun outb(0x80, iobase + 0x30);
731*4882a593Smuzhiyun
732*4882a593Smuzhiyun /* Wait some time */
733*4882a593Smuzhiyun msleep(10);
734*4882a593Smuzhiyun
735*4882a593Smuzhiyun /* Turn FPGA on */
736*4882a593Smuzhiyun outb(0x00, iobase + 0x30);
737*4882a593Smuzhiyun
738*4882a593Smuzhiyun /* Activate card */
739*4882a593Smuzhiyun info->ctrl_reg = REG_CONTROL_BT_ON | REG_CONTROL_BT_RES_PU;
740*4882a593Smuzhiyun outb(info->ctrl_reg, iobase + REG_CONTROL);
741*4882a593Smuzhiyun
742*4882a593Smuzhiyun /* Enable interrupt */
743*4882a593Smuzhiyun outb(0xff, iobase + REG_INTERRUPT);
744*4882a593Smuzhiyun info->ctrl_reg |= REG_CONTROL_INTERRUPT;
745*4882a593Smuzhiyun outb(info->ctrl_reg, iobase + REG_CONTROL);
746*4882a593Smuzhiyun
747*4882a593Smuzhiyun if ((id & 0x0f) == 0x03) {
748*4882a593Smuzhiyun /* Disable RTS */
749*4882a593Smuzhiyun info->ctrl_reg |= REG_CONTROL_RTS;
750*4882a593Smuzhiyun outb(info->ctrl_reg, iobase + REG_CONTROL);
751*4882a593Smuzhiyun
752*4882a593Smuzhiyun /* Set baud rate */
753*4882a593Smuzhiyun info->ctrl_reg |= 0x03;
754*4882a593Smuzhiyun outb(info->ctrl_reg, iobase + REG_CONTROL);
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun /* Enable RTS */
757*4882a593Smuzhiyun info->ctrl_reg &= ~REG_CONTROL_RTS;
758*4882a593Smuzhiyun outb(info->ctrl_reg, iobase + REG_CONTROL);
759*4882a593Smuzhiyun
760*4882a593Smuzhiyun set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
761*4882a593Smuzhiyun set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
762*4882a593Smuzhiyun set_bit(XMIT_SENDING_READY, &(info->tx_state));
763*4882a593Smuzhiyun }
764*4882a593Smuzhiyun
765*4882a593Smuzhiyun /* Start the RX buffers */
766*4882a593Smuzhiyun outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
767*4882a593Smuzhiyun outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun /* Signal that the hardware is ready */
770*4882a593Smuzhiyun set_bit(CARD_READY, &(info->hw_state));
771*4882a593Smuzhiyun
772*4882a593Smuzhiyun /* Drop TX queue */
773*4882a593Smuzhiyun skb_queue_purge(&(info->txq));
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun /* Control the point at which RTS is enabled */
776*4882a593Smuzhiyun outb((0x0f << RTS_LEVEL_SHIFT_BITS) | 1, iobase + REG_RX_CONTROL);
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun /* Timeout before it is safe to send the first HCI packet */
779*4882a593Smuzhiyun msleep(1250);
780*4882a593Smuzhiyun
781*4882a593Smuzhiyun /* Register HCI device */
782*4882a593Smuzhiyun if (hci_register_dev(hdev) < 0) {
783*4882a593Smuzhiyun BT_ERR("Can't register HCI device");
784*4882a593Smuzhiyun info->hdev = NULL;
785*4882a593Smuzhiyun hci_free_dev(hdev);
786*4882a593Smuzhiyun return -ENODEV;
787*4882a593Smuzhiyun }
788*4882a593Smuzhiyun
789*4882a593Smuzhiyun return 0;
790*4882a593Smuzhiyun }
791*4882a593Smuzhiyun
792*4882a593Smuzhiyun
bluecard_close(struct bluecard_info * info)793*4882a593Smuzhiyun static int bluecard_close(struct bluecard_info *info)
794*4882a593Smuzhiyun {
795*4882a593Smuzhiyun unsigned int iobase = info->p_dev->resource[0]->start;
796*4882a593Smuzhiyun struct hci_dev *hdev = info->hdev;
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun if (!hdev)
799*4882a593Smuzhiyun return -ENODEV;
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun bluecard_hci_close(hdev);
802*4882a593Smuzhiyun
803*4882a593Smuzhiyun clear_bit(CARD_READY, &(info->hw_state));
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun /* Reset card */
806*4882a593Smuzhiyun info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
807*4882a593Smuzhiyun outb(info->ctrl_reg, iobase + REG_CONTROL);
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun /* Turn FPGA off */
810*4882a593Smuzhiyun outb(0x80, iobase + 0x30);
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun hci_unregister_dev(hdev);
813*4882a593Smuzhiyun hci_free_dev(hdev);
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun return 0;
816*4882a593Smuzhiyun }
817*4882a593Smuzhiyun
bluecard_probe(struct pcmcia_device * link)818*4882a593Smuzhiyun static int bluecard_probe(struct pcmcia_device *link)
819*4882a593Smuzhiyun {
820*4882a593Smuzhiyun struct bluecard_info *info;
821*4882a593Smuzhiyun
822*4882a593Smuzhiyun /* Create new info device */
823*4882a593Smuzhiyun info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
824*4882a593Smuzhiyun if (!info)
825*4882a593Smuzhiyun return -ENOMEM;
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun info->p_dev = link;
828*4882a593Smuzhiyun link->priv = info;
829*4882a593Smuzhiyun
830*4882a593Smuzhiyun link->config_flags |= CONF_ENABLE_IRQ;
831*4882a593Smuzhiyun
832*4882a593Smuzhiyun return bluecard_config(link);
833*4882a593Smuzhiyun }
834*4882a593Smuzhiyun
835*4882a593Smuzhiyun
bluecard_detach(struct pcmcia_device * link)836*4882a593Smuzhiyun static void bluecard_detach(struct pcmcia_device *link)
837*4882a593Smuzhiyun {
838*4882a593Smuzhiyun bluecard_release(link);
839*4882a593Smuzhiyun }
840*4882a593Smuzhiyun
841*4882a593Smuzhiyun
bluecard_config(struct pcmcia_device * link)842*4882a593Smuzhiyun static int bluecard_config(struct pcmcia_device *link)
843*4882a593Smuzhiyun {
844*4882a593Smuzhiyun struct bluecard_info *info = link->priv;
845*4882a593Smuzhiyun int i, n;
846*4882a593Smuzhiyun
847*4882a593Smuzhiyun link->config_index = 0x20;
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
850*4882a593Smuzhiyun link->resource[0]->end = 64;
851*4882a593Smuzhiyun link->io_lines = 6;
852*4882a593Smuzhiyun
853*4882a593Smuzhiyun for (n = 0; n < 0x400; n += 0x40) {
854*4882a593Smuzhiyun link->resource[0]->start = n ^ 0x300;
855*4882a593Smuzhiyun i = pcmcia_request_io(link);
856*4882a593Smuzhiyun if (i == 0)
857*4882a593Smuzhiyun break;
858*4882a593Smuzhiyun }
859*4882a593Smuzhiyun
860*4882a593Smuzhiyun if (i != 0)
861*4882a593Smuzhiyun goto failed;
862*4882a593Smuzhiyun
863*4882a593Smuzhiyun i = pcmcia_request_irq(link, bluecard_interrupt);
864*4882a593Smuzhiyun if (i != 0)
865*4882a593Smuzhiyun goto failed;
866*4882a593Smuzhiyun
867*4882a593Smuzhiyun i = pcmcia_enable_device(link);
868*4882a593Smuzhiyun if (i != 0)
869*4882a593Smuzhiyun goto failed;
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun if (bluecard_open(info) != 0)
872*4882a593Smuzhiyun goto failed;
873*4882a593Smuzhiyun
874*4882a593Smuzhiyun return 0;
875*4882a593Smuzhiyun
876*4882a593Smuzhiyun failed:
877*4882a593Smuzhiyun bluecard_release(link);
878*4882a593Smuzhiyun return -ENODEV;
879*4882a593Smuzhiyun }
880*4882a593Smuzhiyun
881*4882a593Smuzhiyun
bluecard_release(struct pcmcia_device * link)882*4882a593Smuzhiyun static void bluecard_release(struct pcmcia_device *link)
883*4882a593Smuzhiyun {
884*4882a593Smuzhiyun struct bluecard_info *info = link->priv;
885*4882a593Smuzhiyun
886*4882a593Smuzhiyun bluecard_close(info);
887*4882a593Smuzhiyun
888*4882a593Smuzhiyun del_timer_sync(&(info->timer));
889*4882a593Smuzhiyun
890*4882a593Smuzhiyun pcmcia_disable_device(link);
891*4882a593Smuzhiyun }
892*4882a593Smuzhiyun
893*4882a593Smuzhiyun static const struct pcmcia_device_id bluecard_ids[] = {
894*4882a593Smuzhiyun PCMCIA_DEVICE_PROD_ID12("BlueCard", "LSE041", 0xbaf16fbf, 0x657cc15e),
895*4882a593Smuzhiyun PCMCIA_DEVICE_PROD_ID12("BTCFCARD", "LSE139", 0xe3987764, 0x2524b59c),
896*4882a593Smuzhiyun PCMCIA_DEVICE_PROD_ID12("WSS", "LSE039", 0x0a0736ec, 0x24e6dfab),
897*4882a593Smuzhiyun PCMCIA_DEVICE_NULL
898*4882a593Smuzhiyun };
899*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pcmcia, bluecard_ids);
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun static struct pcmcia_driver bluecard_driver = {
902*4882a593Smuzhiyun .owner = THIS_MODULE,
903*4882a593Smuzhiyun .name = "bluecard_cs",
904*4882a593Smuzhiyun .probe = bluecard_probe,
905*4882a593Smuzhiyun .remove = bluecard_detach,
906*4882a593Smuzhiyun .id_table = bluecard_ids,
907*4882a593Smuzhiyun };
908*4882a593Smuzhiyun module_pcmcia_driver(bluecard_driver);
909