1 /*======================================================================
3 Device driver for Databook TCIC-2 PCMCIA controller
5 tcic.c 1.111 2000/02/15 04:13:12
7 The contents of this file are subject to the Mozilla Public
8 License Version 1.1 (the "License"); you may not use this file
9 except in compliance with the License. You may obtain a copy of
10 the License at http://www.mozilla.org/MPL/
12 Software distributed under the License is distributed on an "AS
13 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 implied. See the License for the specific language governing
15 rights and limitations under the License.
17 The initial developer of the original code is David A. Hinds
18 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
19 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
21 Alternatively, the contents of this file may be used under the
22 terms of the GNU General Public License version 2 (the "GPL"), in which
23 case the provisions of the GPL are applicable instead of the
24 above. If you wish to allow the use of your version of this file
25 only under the terms of the GPL and not to allow others to use
26 your version of this file under the MPL, indicate your decision
27 by deleting the provisions above and replace them with the notice
28 and other provisions required by the GPL. If you do not delete
29 the provisions above, a recipient may use your version of this
30 file under either the MPL or the GPL.
32 ======================================================================*/
34 #include <linux/module.h>
35 #include <linux/moduleparam.h>
36 #include <linux/init.h>
37 #include <linux/types.h>
38 #include <linux/fcntl.h>
39 #include <linux/string.h>
40 #include <linux/errno.h>
41 #include <linux/interrupt.h>
42 #include <linux/slab.h>
43 #include <linux/timer.h>
44 #include <linux/ioport.h>
45 #include <linux/delay.h>
46 #include <linux/workqueue.h>
47 #include <linux/device.h>
50 #include <asm/bitops.h>
51 #include <asm/system.h>
53 #include <pcmcia/version.h>
54 #include <pcmcia/cs_types.h>
55 #include <pcmcia/cs.h>
56 #include <pcmcia/ss.h>
62 module_param(pc_debug
, int, 0644);
63 static const char version
[] =
64 "tcic.c 1.111 2000/02/15 04:13:12 (David Hinds)";
66 #define debug(lvl, fmt, arg...) do { \
67 if (pc_debug > (lvl)) \
68 printk(KERN_DEBUG "tcic: " fmt , ## arg); \
71 #define debug(lvl, fmt, arg...) do { } while (0)
74 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
75 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
76 MODULE_LICENSE("Dual MPL/GPL");
78 /*====================================================================*/
80 /* Parameters that can be set with 'insmod' */
82 /* The base port address of the TCIC-2 chip */
83 static int tcic_base
= TCIC_BASE
;
85 /* Specify a socket number to ignore */
86 static int ignore
= -1;
88 /* Probe for safe interrupts? */
89 static int do_scan
= 1;
91 /* Bit map of interrupts to choose from */
92 static u_int irq_mask
= 0xffff;
93 static int irq_list
[16];
94 static int irq_list_count
;
96 /* The card status change interrupt -- 0 means autoselect */
99 /* Poll status interval -- 0 means default to interrupt */
100 static int poll_interval
;
102 /* Delay for card status double-checking */
103 static int poll_quick
= HZ
/20;
105 /* CCLK external clock time, in nanoseconds. 70 ns = 14.31818 MHz */
106 static int cycle_time
= 70;
108 module_param(tcic_base
, int, 0444);
109 module_param(ignore
, int, 0444);
110 module_param(do_scan
, int, 0444);
111 module_param(irq_mask
, int, 0444);
112 module_param_array(irq_list
, int, irq_list_count
, 0444);
113 module_param(cs_irq
, int, 0444);
114 module_param(poll_interval
, int, 0444);
115 module_param(poll_quick
, int, 0444);
116 module_param(cycle_time
, int, 0444);
118 /*====================================================================*/
120 static irqreturn_t
tcic_interrupt(int irq
, void *dev
, struct pt_regs
*regs
);
121 static void tcic_timer(u_long data
);
122 static struct pccard_operations tcic_operations
;
128 struct pcmcia_socket socket
;
131 static struct timer_list poll_timer
;
132 static int tcic_timer_pending
;
135 static struct tcic_socket socket_table
[2];
137 /*====================================================================*/
139 /* Trick when selecting interrupts: the TCIC sktirq pin is supposed
140 to map to irq 11, but is coded as 0 or 1 in the irq registers. */
141 #define TCIC_IRQ(x) ((x) ? (((x) == 11) ? 1 : (x)) : 15)
144 static u_char
tcic_getb(u_char reg
)
146 u_char val
= inb(tcic_base
+reg
);
147 printk(KERN_DEBUG
"tcic_getb(%#x) = %#x\n", tcic_base
+reg
, val
);
151 static u_short
tcic_getw(u_char reg
)
153 u_short val
= inw(tcic_base
+reg
);
154 printk(KERN_DEBUG
"tcic_getw(%#x) = %#x\n", tcic_base
+reg
, val
);
158 static void tcic_setb(u_char reg
, u_char data
)
160 printk(KERN_DEBUG
"tcic_setb(%#x, %#x)\n", tcic_base
+reg
, data
);
161 outb(data
, tcic_base
+reg
);
164 static void tcic_setw(u_char reg
, u_short data
)
166 printk(KERN_DEBUG
"tcic_setw(%#x, %#x)\n", tcic_base
+reg
, data
);
167 outw(data
, tcic_base
+reg
);
170 #define tcic_getb(reg) inb(tcic_base+reg)
171 #define tcic_getw(reg) inw(tcic_base+reg)
172 #define tcic_setb(reg, data) outb(data, tcic_base+reg)
173 #define tcic_setw(reg, data) outw(data, tcic_base+reg)
176 static void tcic_setl(u_char reg
, u_int data
)
179 printk(KERN_DEBUG
"tcic_setl(%#x, %#lx)\n", tcic_base
+reg
, data
);
181 outw(data
& 0xffff, tcic_base
+reg
);
182 outw(data
>> 16, tcic_base
+reg
+2);
185 static u_char
tcic_aux_getb(u_short reg
)
187 u_char mode
= (tcic_getb(TCIC_MODE
) & TCIC_MODE_PGMMASK
) | reg
;
188 tcic_setb(TCIC_MODE
, mode
);
189 return tcic_getb(TCIC_AUX
);
192 static void tcic_aux_setb(u_short reg
, u_char data
)
194 u_char mode
= (tcic_getb(TCIC_MODE
) & TCIC_MODE_PGMMASK
) | reg
;
195 tcic_setb(TCIC_MODE
, mode
);
196 tcic_setb(TCIC_AUX
, data
);
199 static u_short
tcic_aux_getw(u_short reg
)
201 u_char mode
= (tcic_getb(TCIC_MODE
) & TCIC_MODE_PGMMASK
) | reg
;
202 tcic_setb(TCIC_MODE
, mode
);
203 return tcic_getw(TCIC_AUX
);
206 static void tcic_aux_setw(u_short reg
, u_short data
)
208 u_char mode
= (tcic_getb(TCIC_MODE
) & TCIC_MODE_PGMMASK
) | reg
;
209 tcic_setb(TCIC_MODE
, mode
);
210 tcic_setw(TCIC_AUX
, data
);
213 /*====================================================================*/
215 /* Time conversion functions */
217 static int to_cycles(int ns
)
222 return 2*(ns
-14)/cycle_time
;
225 /*====================================================================*/
227 static volatile u_int irq_hits
;
229 static irqreturn_t __init
tcic_irq_count(int irq
, void *dev
, struct pt_regs
*regs
)
235 static u_int __init
try_irq(int irq
)
240 if (request_irq(irq
, tcic_irq_count
, 0, "irq scan", tcic_irq_count
) != 0)
244 free_irq(irq
, tcic_irq_count
);
248 /* Generate one interrupt */
249 cfg
= TCIC_SYSCFG_AUTOBUSY
| 0x0a00;
250 tcic_aux_setw(TCIC_AUX_SYSCFG
, cfg
| TCIC_IRQ(irq
));
251 tcic_setb(TCIC_IENA
, TCIC_IENA_ERR
| TCIC_IENA_CFG_HIGH
);
252 tcic_setb(TCIC_ICSR
, TCIC_ICSR_ERR
| TCIC_ICSR_JAM
);
255 free_irq(irq
, tcic_irq_count
);
257 /* Turn off interrupts */
258 tcic_setb(TCIC_IENA
, TCIC_IENA_CFG_OFF
);
259 while (tcic_getb(TCIC_ICSR
))
260 tcic_setb(TCIC_ICSR
, TCIC_ICSR_JAM
);
261 tcic_aux_setw(TCIC_AUX_SYSCFG
, cfg
);
263 return (irq_hits
!= 1);
266 static u_int __init
irq_scan(u_int mask0
)
273 /* Don't probe level-triggered interrupts -- reserved for PCI */
274 int level_mask
= inb_p(PIC
) | (inb_p(PIC
+1) << 8);
276 mask0
&= ~level_mask
;
281 for (i
= 0; i
< 16; i
++)
282 if ((mask0
& (1 << i
)) && (try_irq(i
) == 0))
284 for (i
= 0; i
< 16; i
++)
285 if ((mask1
& (1 << i
)) && (try_irq(i
) != 0)) {
293 /* Fallback: just find interrupts that aren't in use */
294 for (i
= 0; i
< 16; i
++)
295 if ((mask0
& (1 << i
)) &&
296 (request_irq(i
, tcic_irq_count
, 0, "x", tcic_irq_count
) == 0)) {
298 free_irq(i
, tcic_irq_count
);
304 for (i
= 0; i
< 16; i
++)
306 printk("%s%d", ((mask1
& ((1<<i
)-1)) ? "," : ""), i
);
312 /*======================================================================
314 See if a card is present, powered up, in IO mode, and already
315 bound to a (non-PCMCIA) Linux driver.
317 We make an exception for cards that look like serial devices.
319 ======================================================================*/
321 static int __init
is_active(int s
)
323 u_short scf1
, ioctl
, base
, num
;
327 tcic_setl(TCIC_ADDR
, (s
<< TCIC_ADDR_SS_SHFT
)
328 | TCIC_ADDR_INDREG
| TCIC_SCF1(s
));
329 scf1
= tcic_getw(TCIC_DATA
);
330 pwr
= tcic_getb(TCIC_PWR
);
331 sstat
= tcic_getb(TCIC_SSTAT
);
332 addr
= TCIC_IWIN(s
, 0);
333 tcic_setw(TCIC_ADDR
, addr
+ TCIC_IBASE_X
);
334 base
= tcic_getw(TCIC_DATA
);
335 tcic_setw(TCIC_ADDR
, addr
+ TCIC_ICTL_X
);
336 ioctl
= tcic_getw(TCIC_DATA
);
338 if (ioctl
& TCIC_ICTL_TINY
)
341 num
= (base
^ (base
-1));
342 base
= base
& (base
-1);
345 if ((sstat
& TCIC_SSTAT_CD
) && (pwr
& TCIC_PWR_VCC(s
)) &&
346 (scf1
& TCIC_SCF1_IOSTS
) && (ioctl
& TCIC_ICTL_ENA
) &&
347 (check_region(base
, num
) != 0) && ((base
& 0xfeef) != 0x02e8))
353 /*======================================================================
355 This returns the revision code for the specified socket.
357 ======================================================================*/
359 static int __init
get_tcic_id(void)
363 tcic_aux_setw(TCIC_AUX_TEST
, TCIC_TEST_DIAG
);
364 id
= tcic_aux_getw(TCIC_AUX_ILOCK
);
365 id
= (id
& TCIC_ILOCKTEST_ID_MASK
) >> TCIC_ILOCKTEST_ID_SH
;
366 tcic_aux_setw(TCIC_AUX_TEST
, 0);
370 /*====================================================================*/
372 static int tcic_drv_suspend(struct device
*dev
, u32 state
, u32 level
)
375 if (level
== SUSPEND_SAVE_STATE
)
376 ret
= pcmcia_socket_dev_suspend(dev
, state
);
380 static int tcic_drv_resume(struct device
*dev
, u32 level
)
383 if (level
== RESUME_RESTORE_STATE
)
384 ret
= pcmcia_socket_dev_resume(dev
);
388 static struct device_driver tcic_driver
= {
389 .name
= "tcic-pcmcia",
390 .bus
= &platform_bus_type
,
391 .suspend
= tcic_drv_suspend
,
392 .resume
= tcic_drv_resume
,
395 static struct platform_device tcic_device
= {
396 .name
= "tcic-pcmcia",
401 static int __init
init_tcic(void)
403 int i
, sock
, ret
= 0;
406 if (driver_register(&tcic_driver
))
409 printk(KERN_INFO
"Databook TCIC-2 PCMCIA probe: ");
412 if (!request_region(tcic_base
, 16, "tcic-2")) {
413 printk("could not allocate ports,\n ");
414 driver_unregister(&tcic_driver
);
418 tcic_setw(TCIC_ADDR
, 0);
419 if (tcic_getw(TCIC_ADDR
) == 0) {
420 tcic_setw(TCIC_ADDR
, 0xc3a5);
421 if (tcic_getw(TCIC_ADDR
) == 0xc3a5) sock
= 2;
424 /* See if resetting the controller does any good */
425 tcic_setb(TCIC_SCTRL
, TCIC_SCTRL_RESET
);
426 tcic_setb(TCIC_SCTRL
, 0);
427 tcic_setw(TCIC_ADDR
, 0);
428 if (tcic_getw(TCIC_ADDR
) == 0) {
429 tcic_setw(TCIC_ADDR
, 0xc3a5);
430 if (tcic_getw(TCIC_ADDR
) == 0xc3a5) sock
= 2;
435 printk("not found.\n");
436 release_region(tcic_base
, 16);
437 driver_unregister(&tcic_driver
);
442 for (i
= 0; i
< sock
; i
++) {
443 if ((i
== ignore
) || is_active(i
)) continue;
444 socket_table
[sockets
].psock
= i
;
445 socket_table
[sockets
].id
= get_tcic_id();
447 socket_table
[sockets
].socket
.owner
= THIS_MODULE
;
448 /* only 16-bit cards, memory windows must be size-aligned */
449 /* No PCI or CardBus support */
450 socket_table
[sockets
].socket
.features
= SS_CAP_PCCARD
| SS_CAP_MEM_ALIGN
;
451 /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
452 socket_table
[sockets
].socket
.irq_mask
= 0x4cf8;
453 /* 4K minimum window size */
454 socket_table
[sockets
].socket
.map_size
= 0x1000;
458 switch (socket_table
[0].id
) {
459 case TCIC_ID_DB86082
:
460 printk("DB86082"); break;
461 case TCIC_ID_DB86082A
:
462 printk("DB86082A"); break;
463 case TCIC_ID_DB86084
:
464 printk("DB86084"); break;
465 case TCIC_ID_DB86084A
:
466 printk("DB86084A"); break;
467 case TCIC_ID_DB86072
:
468 printk("DB86072"); break;
469 case TCIC_ID_DB86184
:
470 printk("DB86184"); break;
471 case TCIC_ID_DB86082B
:
472 printk("DB86082B"); break;
474 printk("Unknown ID 0x%02x", socket_table
[0].id
);
478 poll_timer
.function
= &tcic_timer
;
480 init_timer(&poll_timer
);
482 /* Build interrupt mask */
483 printk(", %d sockets\n" KERN_INFO
" irq list (", sockets
);
484 if (irq_list_count
== 0)
487 for (i
= mask
= 0; i
< irq_list_count
; i
++)
488 mask
|= (1<<irq_list
[i
]);
490 /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
492 /* Scan interrupts */
493 mask
= irq_scan(mask
);
494 for (i
=0;i
<sockets
;i
++)
495 socket_table
[i
].socket
.irq_mask
= mask
;
497 /* Check for only two interrupts available */
498 scan
= (mask
& (mask
-1));
499 if (((scan
& (scan
-1)) == 0) && (poll_interval
== 0))
502 if (poll_interval
== 0) {
503 /* Avoid irq 12 unless it is explicitly requested */
504 u_int cs_mask
= mask
& ((cs_irq
) ? (1<<cs_irq
) : ~(1<<12));
505 for (i
= 15; i
> 0; i
--)
506 if ((cs_mask
& (1 << i
)) &&
507 (request_irq(i
, tcic_interrupt
, 0, "tcic",
508 tcic_interrupt
) == 0))
511 if (cs_irq
== 0) poll_interval
= HZ
;
514 if (socket_table
[0].socket
.irq_mask
& (1 << 11))
515 printk("sktirq is irq 11, ");
517 printk("status change on irq %d\n", cs_irq
);
519 printk("polled status, interval = %d ms\n",
520 poll_interval
* 1000 / HZ
);
522 for (i
= 0; i
< sockets
; i
++) {
523 tcic_setw(TCIC_ADDR
+2, socket_table
[i
].psock
<< TCIC_SS_SHFT
);
524 socket_table
[i
].last_sstat
= tcic_getb(TCIC_SSTAT
);
527 /* jump start interrupt handler, if needed */
528 tcic_interrupt(0, NULL
, NULL
);
530 platform_device_register(&tcic_device
);
532 for (i
= 0; i
< sockets
; i
++) {
533 socket_table
[i
].socket
.ops
= &tcic_operations
;
534 socket_table
[i
].socket
.dev
.dev
= &tcic_device
.dev
;
535 ret
= pcmcia_register_socket(&socket_table
[i
].socket
);
537 pcmcia_unregister_socket(&socket_table
[0].socket
);
546 /*====================================================================*/
548 static void __exit
exit_tcic(void)
552 del_timer_sync(&poll_timer
);
554 tcic_aux_setw(TCIC_AUX_SYSCFG
, TCIC_SYSCFG_AUTOBUSY
|0x0a00);
555 free_irq(cs_irq
, tcic_interrupt
);
557 release_region(tcic_base
, 16);
559 for (i
= 0; i
< sockets
; i
++) {
560 pcmcia_unregister_socket(&socket_table
[i
].socket
);
563 platform_device_unregister(&tcic_device
);
564 driver_unregister(&tcic_driver
);
567 /*====================================================================*/
569 static irqreturn_t
tcic_interrupt(int irq
, void *dev
, struct pt_regs
*regs
)
575 static volatile int active
= 0;
578 printk(KERN_NOTICE
"tcic: reentered interrupt handler!\n");
583 debug(2, "tcic_interrupt()\n");
585 for (i
= 0; i
< sockets
; i
++) {
586 psock
= socket_table
[i
].psock
;
587 tcic_setl(TCIC_ADDR
, (psock
<< TCIC_ADDR_SS_SHFT
)
588 | TCIC_ADDR_INDREG
| TCIC_SCF1(psock
));
589 sstat
= tcic_getb(TCIC_SSTAT
);
590 latch
= sstat
^ socket_table
[psock
].last_sstat
;
591 socket_table
[i
].last_sstat
= sstat
;
592 if (tcic_getb(TCIC_ICSR
) & TCIC_ICSR_CDCHG
) {
593 tcic_setb(TCIC_ICSR
, TCIC_ICSR_CLEAR
);
598 events
= (latch
& TCIC_SSTAT_CD
) ? SS_DETECT
: 0;
599 events
|= (latch
& TCIC_SSTAT_WP
) ? SS_WRPROT
: 0;
600 if (tcic_getw(TCIC_DATA
) & TCIC_SCF1_IOSTS
) {
601 events
|= (latch
& TCIC_SSTAT_LBAT1
) ? SS_STSCHG
: 0;
603 events
|= (latch
& TCIC_SSTAT_RDY
) ? SS_READY
: 0;
604 events
|= (latch
& TCIC_SSTAT_LBAT1
) ? SS_BATDEAD
: 0;
605 events
|= (latch
& TCIC_SSTAT_LBAT2
) ? SS_BATWARN
: 0;
608 pcmcia_parse_events(&socket_table
[i
].socket
, events
);
612 /* Schedule next poll, if needed */
613 if (((cs_irq
== 0) || quick
) && (!tcic_timer_pending
)) {
614 poll_timer
.expires
= jiffies
+ (quick
? poll_quick
: poll_interval
);
615 add_timer(&poll_timer
);
616 tcic_timer_pending
= 1;
620 debug(2, "interrupt done\n");
622 } /* tcic_interrupt */
624 static void tcic_timer(u_long data
)
626 debug(2, "tcic_timer()\n");
627 tcic_timer_pending
= 0;
628 tcic_interrupt(0, NULL
, NULL
);
631 /*====================================================================*/
633 static int tcic_get_status(struct pcmcia_socket
*sock
, u_int
*value
)
635 u_short psock
= container_of(sock
, struct tcic_socket
, socket
)->psock
;
638 tcic_setl(TCIC_ADDR
, (psock
<< TCIC_ADDR_SS_SHFT
)
639 | TCIC_ADDR_INDREG
| TCIC_SCF1(psock
));
640 reg
= tcic_getb(TCIC_SSTAT
);
641 *value
= (reg
& TCIC_SSTAT_CD
) ? SS_DETECT
: 0;
642 *value
|= (reg
& TCIC_SSTAT_WP
) ? SS_WRPROT
: 0;
643 if (tcic_getw(TCIC_DATA
) & TCIC_SCF1_IOSTS
) {
644 *value
|= (reg
& TCIC_SSTAT_LBAT1
) ? SS_STSCHG
: 0;
646 *value
|= (reg
& TCIC_SSTAT_RDY
) ? SS_READY
: 0;
647 *value
|= (reg
& TCIC_SSTAT_LBAT1
) ? SS_BATDEAD
: 0;
648 *value
|= (reg
& TCIC_SSTAT_LBAT2
) ? SS_BATWARN
: 0;
650 reg
= tcic_getb(TCIC_PWR
);
651 if (reg
& (TCIC_PWR_VCC(psock
)|TCIC_PWR_VPP(psock
)))
652 *value
|= SS_POWERON
;
653 debug(1, "GetStatus(%d) = %#2.2x\n", psock
, *value
);
655 } /* tcic_get_status */
657 /*====================================================================*/
659 static int tcic_get_socket(struct pcmcia_socket
*sock
, socket_state_t
*state
)
661 u_short psock
= container_of(sock
, struct tcic_socket
, socket
)->psock
;
665 tcic_setl(TCIC_ADDR
, (psock
<< TCIC_ADDR_SS_SHFT
)
666 | TCIC_ADDR_INDREG
| TCIC_SCF1(psock
));
667 scf1
= tcic_getw(TCIC_DATA
);
668 state
->flags
= (scf1
& TCIC_SCF1_IOSTS
) ? SS_IOCARD
: 0;
669 state
->flags
|= (scf1
& TCIC_SCF1_DMA_MASK
) ? SS_DMA_MODE
: 0;
670 state
->flags
|= (scf1
& TCIC_SCF1_SPKR
) ? SS_SPKR_ENA
: 0;
671 if (tcic_getb(TCIC_SCTRL
) & TCIC_SCTRL_ENA
)
672 state
->flags
|= SS_OUTPUT_ENA
;
673 state
->io_irq
= scf1
& TCIC_SCF1_IRQ_MASK
;
674 if (state
->io_irq
== 1) state
->io_irq
= 11;
676 reg
= tcic_getb(TCIC_PWR
);
677 state
->Vcc
= state
->Vpp
= 0;
678 if (reg
& TCIC_PWR_VCC(psock
)) {
679 if (reg
& TCIC_PWR_VPP(psock
))
682 state
->Vcc
= state
->Vpp
= 50;
684 if (reg
& TCIC_PWR_VPP(psock
)) {
689 reg
= tcic_aux_getb(TCIC_AUX_ILOCK
);
690 state
->flags
|= (reg
& TCIC_ILOCK_CRESET
) ? SS_RESET
: 0;
692 /* Card status change interrupt mask */
693 tcic_setw(TCIC_ADDR
, TCIC_SCF2(psock
));
694 scf2
= tcic_getw(TCIC_DATA
);
695 state
->csc_mask
= (scf2
& TCIC_SCF2_MCD
) ? 0 : SS_DETECT
;
696 if (state
->flags
& SS_IOCARD
) {
697 state
->csc_mask
|= (scf2
& TCIC_SCF2_MLBAT1
) ? 0 : SS_STSCHG
;
699 state
->csc_mask
|= (scf2
& TCIC_SCF2_MLBAT1
) ? 0 : SS_BATDEAD
;
700 state
->csc_mask
|= (scf2
& TCIC_SCF2_MLBAT2
) ? 0 : SS_BATWARN
;
701 state
->csc_mask
|= (scf2
& TCIC_SCF2_MRDY
) ? 0 : SS_READY
;
704 debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
705 "io_irq %d, csc_mask %#2.2x\n", psock
, state
->flags
,
706 state
->Vcc
, state
->Vpp
, state
->io_irq
, state
->csc_mask
);
708 } /* tcic_get_socket */
710 /*====================================================================*/
712 static int tcic_set_socket(struct pcmcia_socket
*sock
, socket_state_t
*state
)
714 u_short psock
= container_of(sock
, struct tcic_socket
, socket
)->psock
;
718 debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
719 "io_irq %d, csc_mask %#2.2x)\n", psock
, state
->flags
,
720 state
->Vcc
, state
->Vpp
, state
->io_irq
, state
->csc_mask
);
721 tcic_setw(TCIC_ADDR
+2, (psock
<< TCIC_SS_SHFT
) | TCIC_ADR2_INDREG
);
723 reg
= tcic_getb(TCIC_PWR
);
724 reg
&= ~(TCIC_PWR_VCC(psock
) | TCIC_PWR_VPP(psock
));
726 if (state
->Vcc
== 50) {
727 switch (state
->Vpp
) {
728 case 0: reg
|= TCIC_PWR_VCC(psock
) | TCIC_PWR_VPP(psock
); break;
729 case 50: reg
|= TCIC_PWR_VCC(psock
); break;
730 case 120: reg
|= TCIC_PWR_VPP(psock
); break;
731 default: return -EINVAL
;
733 } else if (state
->Vcc
!= 0)
736 if (reg
!= tcic_getb(TCIC_PWR
))
737 tcic_setb(TCIC_PWR
, reg
);
739 reg
= TCIC_ILOCK_HOLD_CCLK
| TCIC_ILOCK_CWAIT
;
740 if (state
->flags
& SS_OUTPUT_ENA
) {
741 tcic_setb(TCIC_SCTRL
, TCIC_SCTRL_ENA
);
742 reg
|= TCIC_ILOCK_CRESENA
;
744 tcic_setb(TCIC_SCTRL
, 0);
745 if (state
->flags
& SS_RESET
)
746 reg
|= TCIC_ILOCK_CRESET
;
747 tcic_aux_setb(TCIC_AUX_ILOCK
, reg
);
749 tcic_setw(TCIC_ADDR
, TCIC_SCF1(psock
));
750 scf1
= TCIC_SCF1_FINPACK
;
751 scf1
|= TCIC_IRQ(state
->io_irq
);
752 if (state
->flags
& SS_IOCARD
) {
753 scf1
|= TCIC_SCF1_IOSTS
;
754 if (state
->flags
& SS_SPKR_ENA
)
755 scf1
|= TCIC_SCF1_SPKR
;
756 if (state
->flags
& SS_DMA_MODE
)
757 scf1
|= TCIC_SCF1_DREQ2
<< TCIC_SCF1_DMA_SHIFT
;
759 tcic_setw(TCIC_DATA
, scf1
);
761 /* Some general setup stuff, and configure status interrupt */
762 reg
= TCIC_WAIT_ASYNC
| TCIC_WAIT_SENSE
| to_cycles(250);
763 tcic_aux_setb(TCIC_AUX_WCTL
, reg
);
764 tcic_aux_setw(TCIC_AUX_SYSCFG
, TCIC_SYSCFG_AUTOBUSY
|0x0a00|
767 /* Card status change interrupt mask */
768 tcic_setw(TCIC_ADDR
, TCIC_SCF2(psock
));
769 scf2
= TCIC_SCF2_MALL
;
770 if (state
->csc_mask
& SS_DETECT
) scf2
&= ~TCIC_SCF2_MCD
;
771 if (state
->flags
& SS_IOCARD
) {
772 if (state
->csc_mask
& SS_STSCHG
) reg
&= ~TCIC_SCF2_MLBAT1
;
774 if (state
->csc_mask
& SS_BATDEAD
) reg
&= ~TCIC_SCF2_MLBAT1
;
775 if (state
->csc_mask
& SS_BATWARN
) reg
&= ~TCIC_SCF2_MLBAT2
;
776 if (state
->csc_mask
& SS_READY
) reg
&= ~TCIC_SCF2_MRDY
;
778 tcic_setw(TCIC_DATA
, scf2
);
779 /* For the ISA bus, the irq should be active-high totem-pole */
780 tcic_setb(TCIC_IENA
, TCIC_IENA_CDCHG
| TCIC_IENA_CFG_HIGH
);
783 } /* tcic_set_socket */
785 /*====================================================================*/
787 static int tcic_set_io_map(struct pcmcia_socket
*sock
, struct pccard_io_map
*io
)
789 u_short psock
= container_of(sock
, struct tcic_socket
, socket
)->psock
;
791 u_short base
, len
, ioctl
;
793 debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
794 "%#4.4x-%#4.4x)\n", psock
, io
->map
, io
->flags
,
795 io
->speed
, io
->start
, io
->stop
);
796 if ((io
->map
> 1) || (io
->start
> 0xffff) || (io
->stop
> 0xffff) ||
797 (io
->stop
< io
->start
)) return -EINVAL
;
798 tcic_setw(TCIC_ADDR
+2, TCIC_ADR2_INDREG
| (psock
<< TCIC_SS_SHFT
));
799 addr
= TCIC_IWIN(psock
, io
->map
);
801 base
= io
->start
; len
= io
->stop
- io
->start
;
802 /* Check to see that len+1 is power of two, etc */
803 if ((len
& (len
+1)) || (base
& len
)) return -EINVAL
;
805 tcic_setw(TCIC_ADDR
, addr
+ TCIC_IBASE_X
);
806 tcic_setw(TCIC_DATA
, base
);
808 ioctl
= (psock
<< TCIC_ICTL_SS_SHFT
);
809 ioctl
|= (len
== 0) ? TCIC_ICTL_TINY
: 0;
810 ioctl
|= (io
->flags
& MAP_ACTIVE
) ? TCIC_ICTL_ENA
: 0;
811 ioctl
|= to_cycles(io
->speed
) & TCIC_ICTL_WSCNT_MASK
;
812 if (!(io
->flags
& MAP_AUTOSZ
)) {
813 ioctl
|= TCIC_ICTL_QUIET
;
814 ioctl
|= (io
->flags
& MAP_16BIT
) ? TCIC_ICTL_BW_16
: TCIC_ICTL_BW_8
;
816 tcic_setw(TCIC_ADDR
, addr
+ TCIC_ICTL_X
);
817 tcic_setw(TCIC_DATA
, ioctl
);
820 } /* tcic_set_io_map */
822 /*====================================================================*/
824 static int tcic_set_mem_map(struct pcmcia_socket
*sock
, struct pccard_mem_map
*mem
)
826 u_short psock
= container_of(sock
, struct tcic_socket
, socket
)->psock
;
828 u_long base
, len
, mmap
;
830 debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, "
831 "%#5.5lx-%#5.5lx, %#5.5x)\n", psock
, mem
->map
, mem
->flags
,
832 mem
->speed
, mem
->res
->start
, mem
->res
->end
, mem
->card_start
);
833 if ((mem
->map
> 3) || (mem
->card_start
> 0x3ffffff) ||
834 (mem
->res
->start
> 0xffffff) || (mem
->res
->end
> 0xffffff) ||
835 (mem
->res
->start
> mem
->res
->end
) || (mem
->speed
> 1000))
837 tcic_setw(TCIC_ADDR
+2, TCIC_ADR2_INDREG
| (psock
<< TCIC_SS_SHFT
));
838 addr
= TCIC_MWIN(psock
, mem
->map
);
840 base
= mem
->res
->start
; len
= mem
->res
->end
- mem
->res
->start
;
841 if ((len
& (len
+1)) || (base
& len
)) return -EINVAL
;
843 base
= (base
>> TCIC_MBASE_HA_SHFT
) | TCIC_MBASE_4K_BIT
;
845 base
= (base
| (len
+1)>>1) >> TCIC_MBASE_HA_SHFT
;
846 tcic_setw(TCIC_ADDR
, addr
+ TCIC_MBASE_X
);
847 tcic_setw(TCIC_DATA
, base
);
849 mmap
= mem
->card_start
- mem
->res
->start
;
850 mmap
= (mmap
>> TCIC_MMAP_CA_SHFT
) & TCIC_MMAP_CA_MASK
;
851 if (mem
->flags
& MAP_ATTRIB
) mmap
|= TCIC_MMAP_REG
;
852 tcic_setw(TCIC_ADDR
, addr
+ TCIC_MMAP_X
);
853 tcic_setw(TCIC_DATA
, mmap
);
855 ctl
= TCIC_MCTL_QUIET
| (psock
<< TCIC_MCTL_SS_SHFT
);
856 ctl
|= to_cycles(mem
->speed
) & TCIC_MCTL_WSCNT_MASK
;
857 ctl
|= (mem
->flags
& MAP_16BIT
) ? 0 : TCIC_MCTL_B8
;
858 ctl
|= (mem
->flags
& MAP_WRPROT
) ? TCIC_MCTL_WP
: 0;
859 ctl
|= (mem
->flags
& MAP_ACTIVE
) ? TCIC_MCTL_ENA
: 0;
860 tcic_setw(TCIC_ADDR
, addr
+ TCIC_MCTL_X
);
861 tcic_setw(TCIC_DATA
, ctl
);
864 } /* tcic_set_mem_map */
866 /*====================================================================*/
868 static int tcic_init(struct pcmcia_socket
*s
)
871 struct resource res
= { .start
= 0, .end
= 0x1000 };
872 pccard_io_map io
= { 0, 0, 0, 0, 1 };
873 pccard_mem_map mem
= { .res
= &res
, };
875 for (i
= 0; i
< 2; i
++) {
877 tcic_set_io_map(s
, &io
);
879 for (i
= 0; i
< 5; i
++) {
881 tcic_set_mem_map(s
, &mem
);
886 static int tcic_suspend(struct pcmcia_socket
*sock
)
888 return tcic_set_socket(sock
, &dead_socket
);
891 static struct pccard_operations tcic_operations
= {
893 .suspend
= tcic_suspend
,
894 .get_status
= tcic_get_status
,
895 .get_socket
= tcic_get_socket
,
896 .set_socket
= tcic_set_socket
,
897 .set_io_map
= tcic_set_io_map
,
898 .set_mem_map
= tcic_set_mem_map
,
901 /*====================================================================*/
903 module_init(init_tcic
);
904 module_exit(exit_tcic
);