pcmcia: move Vpp setup to struct pcmcia_device
[linux-2.6.git] / drivers / bluetooth / bt3c_cs.c
1 /*
2  *
3  *  Driver for the 3Com Bluetooth PCMCIA card
4  *
5  *  Copyright (C) 2001-2002  Marcel Holtmann <marcel@holtmann.org>
6  *                           Jose Orlando Pereira <jop@di.uminho.pt>
7  *
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License version 2 as
11  *  published by the Free Software Foundation;
12  *
13  *  Software distributed under the License is distributed on an "AS
14  *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
15  *  implied. See the License for the specific language governing
16  *  rights and limitations under the License.
17  *
18  *  The initial developer of the original code is David A. Hinds
19  *  <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
20  *  are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
21  *
22  */
23
24 #include <linux/module.h>
25
26 #include <linux/kernel.h>
27 #include <linux/init.h>
28 #include <linux/slab.h>
29 #include <linux/types.h>
30 #include <linux/delay.h>
31 #include <linux/errno.h>
32 #include <linux/ptrace.h>
33 #include <linux/ioport.h>
34 #include <linux/spinlock.h>
35 #include <linux/moduleparam.h>
36
37 #include <linux/skbuff.h>
38 #include <linux/string.h>
39 #include <linux/serial.h>
40 #include <linux/serial_reg.h>
41 #include <linux/bitops.h>
42 #include <asm/system.h>
43 #include <asm/io.h>
44
45 #include <linux/device.h>
46 #include <linux/firmware.h>
47
48 #include <pcmcia/cs.h>
49 #include <pcmcia/cistpl.h>
50 #include <pcmcia/ciscode.h>
51 #include <pcmcia/ds.h>
52 #include <pcmcia/cisreg.h>
53
54 #include <net/bluetooth/bluetooth.h>
55 #include <net/bluetooth/hci_core.h>
56
57
58
59 /* ======================== Module parameters ======================== */
60
61
62 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
63 MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");
64 MODULE_LICENSE("GPL");
65 MODULE_FIRMWARE("BT3CPCC.bin");
66
67
68
69 /* ======================== Local structures ======================== */
70
71
72 typedef struct bt3c_info_t {
73         struct pcmcia_device *p_dev;
74
75         struct hci_dev *hdev;
76
77         spinlock_t lock;                /* For serializing operations */
78
79         struct sk_buff_head txq;
80         unsigned long tx_state;
81
82         unsigned long rx_state;
83         unsigned long rx_count;
84         struct sk_buff *rx_skb;
85 } bt3c_info_t;
86
87
88 static int bt3c_config(struct pcmcia_device *link);
89 static void bt3c_release(struct pcmcia_device *link);
90
91 static void bt3c_detach(struct pcmcia_device *p_dev);
92
93
94 /* Transmit states  */
95 #define XMIT_SENDING  1
96 #define XMIT_WAKEUP   2
97 #define XMIT_WAITING  8
98
99 /* Receiver states */
100 #define RECV_WAIT_PACKET_TYPE   0
101 #define RECV_WAIT_EVENT_HEADER  1
102 #define RECV_WAIT_ACL_HEADER    2
103 #define RECV_WAIT_SCO_HEADER    3
104 #define RECV_WAIT_DATA          4
105
106
107
108 /* ======================== Special I/O functions ======================== */
109
110
111 #define DATA_L   0
112 #define DATA_H   1
113 #define ADDR_L   2
114 #define ADDR_H   3
115 #define CONTROL  4
116
117
118 static inline void bt3c_address(unsigned int iobase, unsigned short addr)
119 {
120         outb(addr & 0xff, iobase + ADDR_L);
121         outb((addr >> 8) & 0xff, iobase + ADDR_H);
122 }
123
124
125 static inline void bt3c_put(unsigned int iobase, unsigned short value)
126 {
127         outb(value & 0xff, iobase + DATA_L);
128         outb((value >> 8) & 0xff, iobase + DATA_H);
129 }
130
131
132 static inline void bt3c_io_write(unsigned int iobase, unsigned short addr, unsigned short value)
133 {
134         bt3c_address(iobase, addr);
135         bt3c_put(iobase, value);
136 }
137
138
139 static inline unsigned short bt3c_get(unsigned int iobase)
140 {
141         unsigned short value = inb(iobase + DATA_L);
142
143         value |= inb(iobase + DATA_H) << 8;
144
145         return value;
146 }
147
148
149 static inline unsigned short bt3c_read(unsigned int iobase, unsigned short addr)
150 {
151         bt3c_address(iobase, addr);
152
153         return bt3c_get(iobase);
154 }
155
156
157
158 /* ======================== Interrupt handling ======================== */
159
160
161 static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
162 {
163         int actual = 0;
164
165         bt3c_address(iobase, 0x7080);
166
167         /* Fill FIFO with current frame */
168         while (actual < len) {
169                 /* Transmit next byte */
170                 bt3c_put(iobase, buf[actual]);
171                 actual++;
172         }
173
174         bt3c_io_write(iobase, 0x7005, actual);
175
176         return actual;
177 }
178
179
180 static void bt3c_write_wakeup(bt3c_info_t *info)
181 {
182         if (!info) {
183                 BT_ERR("Unknown device");
184                 return;
185         }
186
187         if (test_and_set_bit(XMIT_SENDING, &(info->tx_state)))
188                 return;
189
190         do {
191                 register unsigned int iobase = info->p_dev->resource[0]->start;
192                 register struct sk_buff *skb;
193                 register int len;
194
195                 if (!pcmcia_dev_present(info->p_dev))
196                         break;
197
198
199                 if (!(skb = skb_dequeue(&(info->txq)))) {
200                         clear_bit(XMIT_SENDING, &(info->tx_state));
201                         break;
202                 }
203
204                 /* Send frame */
205                 len = bt3c_write(iobase, 256, skb->data, skb->len);
206
207                 if (len != skb->len) {
208                         BT_ERR("Very strange");
209                 }
210
211                 kfree_skb(skb);
212
213                 info->hdev->stat.byte_tx += len;
214
215         } while (0);
216 }
217
218
219 static void bt3c_receive(bt3c_info_t *info)
220 {
221         unsigned int iobase;
222         int size = 0, avail;
223
224         if (!info) {
225                 BT_ERR("Unknown device");
226                 return;
227         }
228
229         iobase = info->p_dev->resource[0]->start;
230
231         avail = bt3c_read(iobase, 0x7006);
232         //printk("bt3c_cs: receiving %d bytes\n", avail);
233
234         bt3c_address(iobase, 0x7480);
235         while (size < avail) {
236                 size++;
237                 info->hdev->stat.byte_rx++;
238
239                 /* Allocate packet */
240                 if (info->rx_skb == NULL) {
241                         info->rx_state = RECV_WAIT_PACKET_TYPE;
242                         info->rx_count = 0;
243                         if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
244                                 BT_ERR("Can't allocate mem for new packet");
245                                 return;
246                         }
247                 }
248
249
250                 if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
251
252                         info->rx_skb->dev = (void *) info->hdev;
253                         bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L);
254                         inb(iobase + DATA_H);
255                         //printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type);
256
257                         switch (bt_cb(info->rx_skb)->pkt_type) {
258
259                         case HCI_EVENT_PKT:
260                                 info->rx_state = RECV_WAIT_EVENT_HEADER;
261                                 info->rx_count = HCI_EVENT_HDR_SIZE;
262                                 break;
263
264                         case HCI_ACLDATA_PKT:
265                                 info->rx_state = RECV_WAIT_ACL_HEADER;
266                                 info->rx_count = HCI_ACL_HDR_SIZE;
267                                 break;
268
269                         case HCI_SCODATA_PKT:
270                                 info->rx_state = RECV_WAIT_SCO_HEADER;
271                                 info->rx_count = HCI_SCO_HDR_SIZE;
272                                 break;
273
274                         default:
275                                 /* Unknown packet */
276                                 BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
277                                 info->hdev->stat.err_rx++;
278                                 clear_bit(HCI_RUNNING, &(info->hdev->flags));
279
280                                 kfree_skb(info->rx_skb);
281                                 info->rx_skb = NULL;
282                                 break;
283
284                         }
285
286                 } else {
287
288                         __u8 x = inb(iobase + DATA_L);
289
290                         *skb_put(info->rx_skb, 1) = x;
291                         inb(iobase + DATA_H);
292                         info->rx_count--;
293
294                         if (info->rx_count == 0) {
295
296                                 int dlen;
297                                 struct hci_event_hdr *eh;
298                                 struct hci_acl_hdr *ah;
299                                 struct hci_sco_hdr *sh;
300
301                                 switch (info->rx_state) {
302
303                                 case RECV_WAIT_EVENT_HEADER:
304                                         eh = hci_event_hdr(info->rx_skb);
305                                         info->rx_state = RECV_WAIT_DATA;
306                                         info->rx_count = eh->plen;
307                                         break;
308
309                                 case RECV_WAIT_ACL_HEADER:
310                                         ah = hci_acl_hdr(info->rx_skb);
311                                         dlen = __le16_to_cpu(ah->dlen);
312                                         info->rx_state = RECV_WAIT_DATA;
313                                         info->rx_count = dlen;
314                                         break;
315
316                                 case RECV_WAIT_SCO_HEADER:
317                                         sh = hci_sco_hdr(info->rx_skb);
318                                         info->rx_state = RECV_WAIT_DATA;
319                                         info->rx_count = sh->dlen;
320                                         break;
321
322                                 case RECV_WAIT_DATA:
323                                         hci_recv_frame(info->rx_skb);
324                                         info->rx_skb = NULL;
325                                         break;
326
327                                 }
328
329                         }
330
331                 }
332
333         }
334
335         bt3c_io_write(iobase, 0x7006, 0x0000);
336 }
337
338
339 static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
340 {
341         bt3c_info_t *info = dev_inst;
342         unsigned int iobase;
343         int iir;
344         irqreturn_t r = IRQ_NONE;
345
346         if (!info || !info->hdev)
347                 /* our irq handler is shared */
348                 return IRQ_NONE;
349
350         iobase = info->p_dev->resource[0]->start;
351
352         spin_lock(&(info->lock));
353
354         iir = inb(iobase + CONTROL);
355         if (iir & 0x80) {
356                 int stat = bt3c_read(iobase, 0x7001);
357
358                 if ((stat & 0xff) == 0x7f) {
359                         BT_ERR("Very strange (stat=0x%04x)", stat);
360                 } else if ((stat & 0xff) != 0xff) {
361                         if (stat & 0x0020) {
362                                 int status = bt3c_read(iobase, 0x7002) & 0x10;
363                                 BT_INFO("%s: Antenna %s", info->hdev->name,
364                                                         status ? "out" : "in");
365                         }
366                         if (stat & 0x0001)
367                                 bt3c_receive(info);
368                         if (stat & 0x0002) {
369                                 //BT_ERR("Ack (stat=0x%04x)", stat);
370                                 clear_bit(XMIT_SENDING, &(info->tx_state));
371                                 bt3c_write_wakeup(info);
372                         }
373
374                         bt3c_io_write(iobase, 0x7001, 0x0000);
375
376                         outb(iir, iobase + CONTROL);
377                 }
378                 r = IRQ_HANDLED;
379         }
380
381         spin_unlock(&(info->lock));
382
383         return r;
384 }
385
386
387
388 /* ======================== HCI interface ======================== */
389
390
391 static int bt3c_hci_flush(struct hci_dev *hdev)
392 {
393         bt3c_info_t *info = (bt3c_info_t *)(hdev->driver_data);
394
395         /* Drop TX queue */
396         skb_queue_purge(&(info->txq));
397
398         return 0;
399 }
400
401
402 static int bt3c_hci_open(struct hci_dev *hdev)
403 {
404         set_bit(HCI_RUNNING, &(hdev->flags));
405
406         return 0;
407 }
408
409
410 static int bt3c_hci_close(struct hci_dev *hdev)
411 {
412         if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
413                 return 0;
414
415         bt3c_hci_flush(hdev);
416
417         return 0;
418 }
419
420
421 static int bt3c_hci_send_frame(struct sk_buff *skb)
422 {
423         bt3c_info_t *info;
424         struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
425         unsigned long flags;
426
427         if (!hdev) {
428                 BT_ERR("Frame for unknown HCI device (hdev=NULL)");
429                 return -ENODEV;
430         }
431
432         info = (bt3c_info_t *) (hdev->driver_data);
433
434         switch (bt_cb(skb)->pkt_type) {
435         case HCI_COMMAND_PKT:
436                 hdev->stat.cmd_tx++;
437                 break;
438         case HCI_ACLDATA_PKT:
439                 hdev->stat.acl_tx++;
440                 break;
441         case HCI_SCODATA_PKT:
442                 hdev->stat.sco_tx++;
443                 break;
444         };
445
446         /* Prepend skb with frame type */
447         memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
448         skb_queue_tail(&(info->txq), skb);
449
450         spin_lock_irqsave(&(info->lock), flags);
451
452         bt3c_write_wakeup(info);
453
454         spin_unlock_irqrestore(&(info->lock), flags);
455
456         return 0;
457 }
458
459
460 static void bt3c_hci_destruct(struct hci_dev *hdev)
461 {
462 }
463
464
465 static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
466 {
467         return -ENOIOCTLCMD;
468 }
469
470
471
472 /* ======================== Card services HCI interaction ======================== */
473
474
475 static int bt3c_load_firmware(bt3c_info_t *info, const unsigned char *firmware,
476                               int count)
477 {
478         char *ptr = (char *) firmware;
479         char b[9];
480         unsigned int iobase, size, addr, fcs, tmp;
481         int i, err = 0;
482
483         iobase = info->p_dev->resource[0]->start;
484
485         /* Reset */
486         bt3c_io_write(iobase, 0x8040, 0x0404);
487         bt3c_io_write(iobase, 0x8040, 0x0400);
488
489         udelay(1);
490
491         bt3c_io_write(iobase, 0x8040, 0x0404);
492
493         udelay(17);
494
495         /* Load */
496         while (count) {
497                 if (ptr[0] != 'S') {
498                         BT_ERR("Bad address in firmware");
499                         err = -EFAULT;
500                         goto error;
501                 }
502
503                 memset(b, 0, sizeof(b));
504                 memcpy(b, ptr + 2, 2);
505                 size = simple_strtoul(b, NULL, 16);
506
507                 memset(b, 0, sizeof(b));
508                 memcpy(b, ptr + 4, 8);
509                 addr = simple_strtoul(b, NULL, 16);
510
511                 memset(b, 0, sizeof(b));
512                 memcpy(b, ptr + (size * 2) + 2, 2);
513                 fcs = simple_strtoul(b, NULL, 16);
514
515                 memset(b, 0, sizeof(b));
516                 for (tmp = 0, i = 0; i < size; i++) {
517                         memcpy(b, ptr + (i * 2) + 2, 2);
518                         tmp += simple_strtol(b, NULL, 16);
519                 }
520
521                 if (((tmp + fcs) & 0xff) != 0xff) {
522                         BT_ERR("Checksum error in firmware");
523                         err = -EILSEQ;
524                         goto error;
525                 }
526
527                 if (ptr[1] == '3') {
528                         bt3c_address(iobase, addr);
529
530                         memset(b, 0, sizeof(b));
531                         for (i = 0; i < (size - 4) / 2; i++) {
532                                 memcpy(b, ptr + (i * 4) + 12, 4);
533                                 tmp = simple_strtoul(b, NULL, 16);
534                                 bt3c_put(iobase, tmp);
535                         }
536                 }
537
538                 ptr   += (size * 2) + 6;
539                 count -= (size * 2) + 6;
540         }
541
542         udelay(17);
543
544         /* Boot */
545         bt3c_address(iobase, 0x3000);
546         outb(inb(iobase + CONTROL) | 0x40, iobase + CONTROL);
547
548 error:
549         udelay(17);
550
551         /* Clear */
552         bt3c_io_write(iobase, 0x7006, 0x0000);
553         bt3c_io_write(iobase, 0x7005, 0x0000);
554         bt3c_io_write(iobase, 0x7001, 0x0000);
555
556         return err;
557 }
558
559
560 static int bt3c_open(bt3c_info_t *info)
561 {
562         const struct firmware *firmware;
563         struct hci_dev *hdev;
564         int err;
565
566         spin_lock_init(&(info->lock));
567
568         skb_queue_head_init(&(info->txq));
569
570         info->rx_state = RECV_WAIT_PACKET_TYPE;
571         info->rx_count = 0;
572         info->rx_skb = NULL;
573
574         /* Initialize HCI device */
575         hdev = hci_alloc_dev();
576         if (!hdev) {
577                 BT_ERR("Can't allocate HCI device");
578                 return -ENOMEM;
579         }
580
581         info->hdev = hdev;
582
583         hdev->bus = HCI_PCCARD;
584         hdev->driver_data = info;
585         SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
586
587         hdev->open     = bt3c_hci_open;
588         hdev->close    = bt3c_hci_close;
589         hdev->flush    = bt3c_hci_flush;
590         hdev->send     = bt3c_hci_send_frame;
591         hdev->destruct = bt3c_hci_destruct;
592         hdev->ioctl    = bt3c_hci_ioctl;
593
594         hdev->owner = THIS_MODULE;
595
596         /* Load firmware */
597         err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);
598         if (err < 0) {
599                 BT_ERR("Firmware request failed");
600                 goto error;
601         }
602
603         err = bt3c_load_firmware(info, firmware->data, firmware->size);
604
605         release_firmware(firmware);
606
607         if (err < 0) {
608                 BT_ERR("Firmware loading failed");
609                 goto error;
610         }
611
612         /* Timeout before it is safe to send the first HCI packet */
613         msleep(1000);
614
615         /* Register HCI device */
616         err = hci_register_dev(hdev);
617         if (err < 0) {
618                 BT_ERR("Can't register HCI device");
619                 goto error;
620         }
621
622         return 0;
623
624 error:
625         info->hdev = NULL;
626         hci_free_dev(hdev);
627         return err;
628 }
629
630
631 static int bt3c_close(bt3c_info_t *info)
632 {
633         struct hci_dev *hdev = info->hdev;
634
635         if (!hdev)
636                 return -ENODEV;
637
638         bt3c_hci_close(hdev);
639
640         if (hci_unregister_dev(hdev) < 0)
641                 BT_ERR("Can't unregister HCI device %s", hdev->name);
642
643         hci_free_dev(hdev);
644
645         return 0;
646 }
647
648 static int bt3c_probe(struct pcmcia_device *link)
649 {
650         bt3c_info_t *info;
651
652         /* Create new info device */
653         info = kzalloc(sizeof(*info), GFP_KERNEL);
654         if (!info)
655                 return -ENOMEM;
656
657         info->p_dev = link;
658         link->priv = info;
659
660         link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
661         link->resource[0]->end = 8;
662
663         link->conf.Attributes = CONF_ENABLE_IRQ;
664         link->conf.IntType = INT_MEMORY_AND_IO;
665
666         return bt3c_config(link);
667 }
668
669
670 static void bt3c_detach(struct pcmcia_device *link)
671 {
672         bt3c_info_t *info = link->priv;
673
674         bt3c_release(link);
675         kfree(info);
676 }
677
678 static int bt3c_check_config(struct pcmcia_device *p_dev,
679                              cistpl_cftable_entry_t *cf,
680                              cistpl_cftable_entry_t *dflt,
681                              unsigned int vcc,
682                              void *priv_data)
683 {
684         unsigned long try = (unsigned long) priv_data;
685
686         p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
687
688         if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
689                 p_dev->vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
690         if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
691             (cf->io.win[0].base != 0)) {
692                 p_dev->resource[0]->start = cf->io.win[0].base;
693                 if (!pcmcia_request_io(p_dev))
694                         return 0;
695         }
696         return -ENODEV;
697 }
698
699 static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
700                                       cistpl_cftable_entry_t *cf,
701                                       cistpl_cftable_entry_t *dflt,
702                                       unsigned int vcc,
703                                       void *priv_data)
704 {
705         static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
706         int j;
707
708         if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
709                 for (j = 0; j < 5; j++) {
710                         p_dev->resource[0]->start = base[j];
711                         p_dev->io_lines = base[j] ? 16 : 3;
712                         if (!pcmcia_request_io(p_dev))
713                                 return 0;
714                 }
715         }
716         return -ENODEV;
717 }
718
719 static int bt3c_config(struct pcmcia_device *link)
720 {
721         bt3c_info_t *info = link->priv;
722         int i;
723         unsigned long try;
724
725         /* First pass: look for a config entry that looks normal.
726            Two tries: without IO aliases, then with aliases */
727         for (try = 0; try < 2; try++)
728                 if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
729                         goto found_port;
730
731         /* Second pass: try to find an entry that isn't picky about
732            its base address, then try to grab any standard serial port
733            address, and finally try to get any free port. */
734         if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
735                 goto found_port;
736
737         BT_ERR("No usable port range found");
738         goto failed;
739
740 found_port:
741         i = pcmcia_request_irq(link, &bt3c_interrupt);
742         if (i != 0)
743                 goto failed;
744
745         i = pcmcia_request_configuration(link, &link->conf);
746         if (i != 0)
747                 goto failed;
748
749         if (bt3c_open(info) != 0)
750                 goto failed;
751
752         return 0;
753
754 failed:
755         bt3c_release(link);
756         return -ENODEV;
757 }
758
759
760 static void bt3c_release(struct pcmcia_device *link)
761 {
762         bt3c_info_t *info = link->priv;
763
764         bt3c_close(info);
765
766         pcmcia_disable_device(link);
767 }
768
769
770 static struct pcmcia_device_id bt3c_ids[] = {
771         PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),
772         PCMCIA_DEVICE_NULL
773 };
774 MODULE_DEVICE_TABLE(pcmcia, bt3c_ids);
775
776 static struct pcmcia_driver bt3c_driver = {
777         .owner          = THIS_MODULE,
778         .drv            = {
779                 .name   = "bt3c_cs",
780         },
781         .probe          = bt3c_probe,
782         .remove         = bt3c_detach,
783         .id_table       = bt3c_ids,
784 };
785
786 static int __init init_bt3c_cs(void)
787 {
788         return pcmcia_register_driver(&bt3c_driver);
789 }
790
791
792 static void __exit exit_bt3c_cs(void)
793 {
794         pcmcia_unregister_driver(&bt3c_driver);
795 }
796
797 module_init(init_bt3c_cs);
798 module_exit(exit_bt3c_cs);