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/timer.h>
43 #include <linux/ioport.h>
44 #include <linux/delay.h>
45 #include <linux/workqueue.h>
46 #include <linux/platform_device.h>
47 #include <linux/bitops.h>
50 #include <asm/system.h>
52 #include <pcmcia/cs_types.h>
53 #include <pcmcia/cs.h>
54 #include <pcmcia/ss.h>
57 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
58 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
59 MODULE_LICENSE("Dual MPL/GPL");
61 /*====================================================================*/
63 /* Parameters that can be set with 'insmod' */
65 /* The base port address of the TCIC-2 chip */
66 static unsigned long tcic_base
= TCIC_BASE
;
68 /* Specify a socket number to ignore */
69 static int ignore
= -1;
71 /* Probe for safe interrupts? */
72 static int do_scan
= 1;
74 /* Bit map of interrupts to choose from */
75 static u_int irq_mask
= 0xffff;
76 static int irq_list
[16];
77 static unsigned int irq_list_count
;
79 /* The card status change interrupt -- 0 means autoselect */
82 /* Poll status interval -- 0 means default to interrupt */
83 static int poll_interval
;
85 /* Delay for card status double-checking */
86 static int poll_quick
= HZ
/20;
88 /* CCLK external clock time, in nanoseconds. 70 ns = 14.31818 MHz */
89 static int cycle_time
= 70;
91 module_param(tcic_base
, ulong
, 0444);
92 module_param(ignore
, int, 0444);
93 module_param(do_scan
, int, 0444);
94 module_param(irq_mask
, int, 0444);
95 module_param_array(irq_list
, int, &irq_list_count
, 0444);
96 module_param(cs_irq
, int, 0444);
97 module_param(poll_interval
, int, 0444);
98 module_param(poll_quick
, int, 0444);
99 module_param(cycle_time
, int, 0444);
101 /*====================================================================*/
103 static irqreturn_t
tcic_interrupt(int irq
, void *dev
);
104 static void tcic_timer(u_long data
);
105 static struct pccard_operations tcic_operations
;
111 struct pcmcia_socket socket
;
114 static struct timer_list poll_timer
;
115 static int tcic_timer_pending
;
118 static struct tcic_socket socket_table
[2];
120 /*====================================================================*/
122 /* Trick when selecting interrupts: the TCIC sktirq pin is supposed
123 to map to irq 11, but is coded as 0 or 1 in the irq registers. */
124 #define TCIC_IRQ(x) ((x) ? (((x) == 11) ? 1 : (x)) : 15)
127 static u_char
tcic_getb(u_char reg
)
129 u_char val
= inb(tcic_base
+reg
);
130 printk(KERN_DEBUG
"tcic_getb(%#lx) = %#x\n", tcic_base
+reg
, val
);
134 static u_short
tcic_getw(u_char reg
)
136 u_short val
= inw(tcic_base
+reg
);
137 printk(KERN_DEBUG
"tcic_getw(%#lx) = %#x\n", tcic_base
+reg
, val
);
141 static void tcic_setb(u_char reg
, u_char data
)
143 printk(KERN_DEBUG
"tcic_setb(%#lx, %#x)\n", tcic_base
+reg
, data
);
144 outb(data
, tcic_base
+reg
);
147 static void tcic_setw(u_char reg
, u_short data
)
149 printk(KERN_DEBUG
"tcic_setw(%#lx, %#x)\n", tcic_base
+reg
, data
);
150 outw(data
, tcic_base
+reg
);
153 #define tcic_getb(reg) inb(tcic_base+reg)
154 #define tcic_getw(reg) inw(tcic_base+reg)
155 #define tcic_setb(reg, data) outb(data, tcic_base+reg)
156 #define tcic_setw(reg, data) outw(data, tcic_base+reg)
159 static void tcic_setl(u_char reg
, u_int data
)
162 printk(KERN_DEBUG
"tcic_setl(%#x, %#lx)\n", tcic_base
+reg
, data
);
164 outw(data
& 0xffff, tcic_base
+reg
);
165 outw(data
>> 16, tcic_base
+reg
+2);
168 static void tcic_aux_setb(u_short reg
, u_char data
)
170 u_char mode
= (tcic_getb(TCIC_MODE
) & TCIC_MODE_PGMMASK
) | reg
;
171 tcic_setb(TCIC_MODE
, mode
);
172 tcic_setb(TCIC_AUX
, data
);
175 static u_short
tcic_aux_getw(u_short reg
)
177 u_char mode
= (tcic_getb(TCIC_MODE
) & TCIC_MODE_PGMMASK
) | reg
;
178 tcic_setb(TCIC_MODE
, mode
);
179 return tcic_getw(TCIC_AUX
);
182 static void tcic_aux_setw(u_short reg
, u_short data
)
184 u_char mode
= (tcic_getb(TCIC_MODE
) & TCIC_MODE_PGMMASK
) | reg
;
185 tcic_setb(TCIC_MODE
, mode
);
186 tcic_setw(TCIC_AUX
, data
);
189 /*====================================================================*/
191 /* Time conversion functions */
193 static int to_cycles(int ns
)
198 return 2*(ns
-14)/cycle_time
;
201 /*====================================================================*/
203 static volatile u_int irq_hits
;
205 static irqreturn_t __init
tcic_irq_count(int irq
, void *dev
)
211 static u_int __init
try_irq(int irq
)
216 if (request_irq(irq
, tcic_irq_count
, 0, "irq scan", tcic_irq_count
) != 0)
220 free_irq(irq
, tcic_irq_count
);
224 /* Generate one interrupt */
225 cfg
= TCIC_SYSCFG_AUTOBUSY
| 0x0a00;
226 tcic_aux_setw(TCIC_AUX_SYSCFG
, cfg
| TCIC_IRQ(irq
));
227 tcic_setb(TCIC_IENA
, TCIC_IENA_ERR
| TCIC_IENA_CFG_HIGH
);
228 tcic_setb(TCIC_ICSR
, TCIC_ICSR_ERR
| TCIC_ICSR_JAM
);
231 free_irq(irq
, tcic_irq_count
);
233 /* Turn off interrupts */
234 tcic_setb(TCIC_IENA
, TCIC_IENA_CFG_OFF
);
235 while (tcic_getb(TCIC_ICSR
))
236 tcic_setb(TCIC_ICSR
, TCIC_ICSR_JAM
);
237 tcic_aux_setw(TCIC_AUX_SYSCFG
, cfg
);
239 return (irq_hits
!= 1);
242 static u_int __init
irq_scan(u_int mask0
)
249 /* Don't probe level-triggered interrupts -- reserved for PCI */
250 int level_mask
= inb_p(PIC
) | (inb_p(PIC
+1) << 8);
252 mask0
&= ~level_mask
;
257 for (i
= 0; i
< 16; i
++)
258 if ((mask0
& (1 << i
)) && (try_irq(i
) == 0))
260 for (i
= 0; i
< 16; i
++)
261 if ((mask1
& (1 << i
)) && (try_irq(i
) != 0)) {
269 /* Fallback: just find interrupts that aren't in use */
270 for (i
= 0; i
< 16; i
++)
271 if ((mask0
& (1 << i
)) &&
272 (request_irq(i
, tcic_irq_count
, 0, "x", tcic_irq_count
) == 0)) {
274 free_irq(i
, tcic_irq_count
);
280 for (i
= 0; i
< 16; i
++)
282 printk("%s%d", ((mask1
& ((1<<i
)-1)) ? "," : ""), i
);
288 /*======================================================================
290 See if a card is present, powered up, in IO mode, and already
291 bound to a (non-PCMCIA) Linux driver.
293 We make an exception for cards that look like serial devices.
295 ======================================================================*/
297 static int __init
is_active(int s
)
299 u_short scf1
, ioctl
, base
, num
;
303 tcic_setl(TCIC_ADDR
, (s
<< TCIC_ADDR_SS_SHFT
)
304 | TCIC_ADDR_INDREG
| TCIC_SCF1(s
));
305 scf1
= tcic_getw(TCIC_DATA
);
306 pwr
= tcic_getb(TCIC_PWR
);
307 sstat
= tcic_getb(TCIC_SSTAT
);
308 addr
= TCIC_IWIN(s
, 0);
309 tcic_setw(TCIC_ADDR
, addr
+ TCIC_IBASE_X
);
310 base
= tcic_getw(TCIC_DATA
);
311 tcic_setw(TCIC_ADDR
, addr
+ TCIC_ICTL_X
);
312 ioctl
= tcic_getw(TCIC_DATA
);
314 if (ioctl
& TCIC_ICTL_TINY
)
317 num
= (base
^ (base
-1));
318 base
= base
& (base
-1);
321 if ((sstat
& TCIC_SSTAT_CD
) && (pwr
& TCIC_PWR_VCC(s
)) &&
322 (scf1
& TCIC_SCF1_IOSTS
) && (ioctl
& TCIC_ICTL_ENA
) &&
323 ((base
& 0xfeef) != 0x02e8)) {
324 struct resource
*res
= request_region(base
, num
, "tcic-2");
325 if (!res
) /* region is busy */
327 release_region(base
, num
);
333 /*======================================================================
335 This returns the revision code for the specified socket.
337 ======================================================================*/
339 static int __init
get_tcic_id(void)
343 tcic_aux_setw(TCIC_AUX_TEST
, TCIC_TEST_DIAG
);
344 id
= tcic_aux_getw(TCIC_AUX_ILOCK
);
345 id
= (id
& TCIC_ILOCKTEST_ID_MASK
) >> TCIC_ILOCKTEST_ID_SH
;
346 tcic_aux_setw(TCIC_AUX_TEST
, 0);
350 /*====================================================================*/
352 static struct platform_driver tcic_driver
= {
354 .name
= "tcic-pcmcia",
355 .owner
= THIS_MODULE
,
359 static struct platform_device tcic_device
= {
360 .name
= "tcic-pcmcia",
365 static int __init
init_tcic(void)
367 int i
, sock
, ret
= 0;
370 if (platform_driver_register(&tcic_driver
))
373 printk(KERN_INFO
"Databook TCIC-2 PCMCIA probe: ");
376 if (!request_region(tcic_base
, 16, "tcic-2")) {
377 printk("could not allocate ports,\n ");
378 platform_driver_unregister(&tcic_driver
);
382 tcic_setw(TCIC_ADDR
, 0);
383 if (tcic_getw(TCIC_ADDR
) == 0) {
384 tcic_setw(TCIC_ADDR
, 0xc3a5);
385 if (tcic_getw(TCIC_ADDR
) == 0xc3a5) sock
= 2;
388 /* See if resetting the controller does any good */
389 tcic_setb(TCIC_SCTRL
, TCIC_SCTRL_RESET
);
390 tcic_setb(TCIC_SCTRL
, 0);
391 tcic_setw(TCIC_ADDR
, 0);
392 if (tcic_getw(TCIC_ADDR
) == 0) {
393 tcic_setw(TCIC_ADDR
, 0xc3a5);
394 if (tcic_getw(TCIC_ADDR
) == 0xc3a5) sock
= 2;
399 printk("not found.\n");
400 release_region(tcic_base
, 16);
401 platform_driver_unregister(&tcic_driver
);
406 for (i
= 0; i
< sock
; i
++) {
407 if ((i
== ignore
) || is_active(i
)) continue;
408 socket_table
[sockets
].psock
= i
;
409 socket_table
[sockets
].id
= get_tcic_id();
411 socket_table
[sockets
].socket
.owner
= THIS_MODULE
;
412 /* only 16-bit cards, memory windows must be size-aligned */
413 /* No PCI or CardBus support */
414 socket_table
[sockets
].socket
.features
= SS_CAP_PCCARD
| SS_CAP_MEM_ALIGN
;
415 /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
416 socket_table
[sockets
].socket
.irq_mask
= 0x4cf8;
417 /* 4K minimum window size */
418 socket_table
[sockets
].socket
.map_size
= 0x1000;
422 switch (socket_table
[0].id
) {
423 case TCIC_ID_DB86082
:
424 printk("DB86082"); break;
425 case TCIC_ID_DB86082A
:
426 printk("DB86082A"); break;
427 case TCIC_ID_DB86084
:
428 printk("DB86084"); break;
429 case TCIC_ID_DB86084A
:
430 printk("DB86084A"); break;
431 case TCIC_ID_DB86072
:
432 printk("DB86072"); break;
433 case TCIC_ID_DB86184
:
434 printk("DB86184"); break;
435 case TCIC_ID_DB86082B
:
436 printk("DB86082B"); break;
438 printk("Unknown ID 0x%02x", socket_table
[0].id
);
442 poll_timer
.function
= &tcic_timer
;
444 init_timer(&poll_timer
);
446 /* Build interrupt mask */
447 printk(KERN_CONT
", %d sockets\n", sockets
);
448 printk(KERN_INFO
" irq list (");
449 if (irq_list_count
== 0)
452 for (i
= mask
= 0; i
< irq_list_count
; i
++)
453 mask
|= (1<<irq_list
[i
]);
455 /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
457 /* Scan interrupts */
458 mask
= irq_scan(mask
);
459 for (i
=0;i
<sockets
;i
++)
460 socket_table
[i
].socket
.irq_mask
= mask
;
462 /* Check for only two interrupts available */
463 scan
= (mask
& (mask
-1));
464 if (((scan
& (scan
-1)) == 0) && (poll_interval
== 0))
467 if (poll_interval
== 0) {
468 /* Avoid irq 12 unless it is explicitly requested */
469 u_int cs_mask
= mask
& ((cs_irq
) ? (1<<cs_irq
) : ~(1<<12));
470 for (i
= 15; i
> 0; i
--)
471 if ((cs_mask
& (1 << i
)) &&
472 (request_irq(i
, tcic_interrupt
, 0, "tcic",
473 tcic_interrupt
) == 0))
476 if (cs_irq
== 0) poll_interval
= HZ
;
479 if (socket_table
[0].socket
.irq_mask
& (1 << 11))
480 printk("sktirq is irq 11, ");
482 printk("status change on irq %d\n", cs_irq
);
484 printk("polled status, interval = %d ms\n",
485 poll_interval
* 1000 / HZ
);
487 for (i
= 0; i
< sockets
; i
++) {
488 tcic_setw(TCIC_ADDR
+2, socket_table
[i
].psock
<< TCIC_SS_SHFT
);
489 socket_table
[i
].last_sstat
= tcic_getb(TCIC_SSTAT
);
492 /* jump start interrupt handler, if needed */
493 tcic_interrupt(0, NULL
);
495 platform_device_register(&tcic_device
);
497 for (i
= 0; i
< sockets
; i
++) {
498 socket_table
[i
].socket
.ops
= &tcic_operations
;
499 socket_table
[i
].socket
.resource_ops
= &pccard_nonstatic_ops
;
500 socket_table
[i
].socket
.dev
.parent
= &tcic_device
.dev
;
501 ret
= pcmcia_register_socket(&socket_table
[i
].socket
);
503 pcmcia_unregister_socket(&socket_table
[0].socket
);
512 /*====================================================================*/
514 static void __exit
exit_tcic(void)
518 del_timer_sync(&poll_timer
);
520 tcic_aux_setw(TCIC_AUX_SYSCFG
, TCIC_SYSCFG_AUTOBUSY
|0x0a00);
521 free_irq(cs_irq
, tcic_interrupt
);
523 release_region(tcic_base
, 16);
525 for (i
= 0; i
< sockets
; i
++) {
526 pcmcia_unregister_socket(&socket_table
[i
].socket
);
529 platform_device_unregister(&tcic_device
);
530 platform_driver_unregister(&tcic_driver
);
533 /*====================================================================*/
535 static irqreturn_t
tcic_interrupt(int irq
, void *dev
)
541 static volatile int active
= 0;
544 printk(KERN_NOTICE
"tcic: reentered interrupt handler!\n");
549 pr_debug("tcic_interrupt()\n");
551 for (i
= 0; i
< sockets
; i
++) {
552 psock
= socket_table
[i
].psock
;
553 tcic_setl(TCIC_ADDR
, (psock
<< TCIC_ADDR_SS_SHFT
)
554 | TCIC_ADDR_INDREG
| TCIC_SCF1(psock
));
555 sstat
= tcic_getb(TCIC_SSTAT
);
556 latch
= sstat
^ socket_table
[psock
].last_sstat
;
557 socket_table
[i
].last_sstat
= sstat
;
558 if (tcic_getb(TCIC_ICSR
) & TCIC_ICSR_CDCHG
) {
559 tcic_setb(TCIC_ICSR
, TCIC_ICSR_CLEAR
);
564 events
= (latch
& TCIC_SSTAT_CD
) ? SS_DETECT
: 0;
565 events
|= (latch
& TCIC_SSTAT_WP
) ? SS_WRPROT
: 0;
566 if (tcic_getw(TCIC_DATA
) & TCIC_SCF1_IOSTS
) {
567 events
|= (latch
& TCIC_SSTAT_LBAT1
) ? SS_STSCHG
: 0;
569 events
|= (latch
& TCIC_SSTAT_RDY
) ? SS_READY
: 0;
570 events
|= (latch
& TCIC_SSTAT_LBAT1
) ? SS_BATDEAD
: 0;
571 events
|= (latch
& TCIC_SSTAT_LBAT2
) ? SS_BATWARN
: 0;
574 pcmcia_parse_events(&socket_table
[i
].socket
, events
);
578 /* Schedule next poll, if needed */
579 if (((cs_irq
== 0) || quick
) && (!tcic_timer_pending
)) {
580 poll_timer
.expires
= jiffies
+ (quick
? poll_quick
: poll_interval
);
581 add_timer(&poll_timer
);
582 tcic_timer_pending
= 1;
586 pr_debug("interrupt done\n");
588 } /* tcic_interrupt */
590 static void tcic_timer(u_long data
)
592 pr_debug("tcic_timer()\n");
593 tcic_timer_pending
= 0;
594 tcic_interrupt(0, NULL
);
597 /*====================================================================*/
599 static int tcic_get_status(struct pcmcia_socket
*sock
, u_int
*value
)
601 u_short psock
= container_of(sock
, struct tcic_socket
, socket
)->psock
;
604 tcic_setl(TCIC_ADDR
, (psock
<< TCIC_ADDR_SS_SHFT
)
605 | TCIC_ADDR_INDREG
| TCIC_SCF1(psock
));
606 reg
= tcic_getb(TCIC_SSTAT
);
607 *value
= (reg
& TCIC_SSTAT_CD
) ? SS_DETECT
: 0;
608 *value
|= (reg
& TCIC_SSTAT_WP
) ? SS_WRPROT
: 0;
609 if (tcic_getw(TCIC_DATA
) & TCIC_SCF1_IOSTS
) {
610 *value
|= (reg
& TCIC_SSTAT_LBAT1
) ? SS_STSCHG
: 0;
612 *value
|= (reg
& TCIC_SSTAT_RDY
) ? SS_READY
: 0;
613 *value
|= (reg
& TCIC_SSTAT_LBAT1
) ? SS_BATDEAD
: 0;
614 *value
|= (reg
& TCIC_SSTAT_LBAT2
) ? SS_BATWARN
: 0;
616 reg
= tcic_getb(TCIC_PWR
);
617 if (reg
& (TCIC_PWR_VCC(psock
)|TCIC_PWR_VPP(psock
)))
618 *value
|= SS_POWERON
;
619 dev_dbg(&sock
->dev
, "GetStatus(%d) = %#2.2x\n", psock
, *value
);
621 } /* tcic_get_status */
623 /*====================================================================*/
625 static int tcic_set_socket(struct pcmcia_socket
*sock
, socket_state_t
*state
)
627 u_short psock
= container_of(sock
, struct tcic_socket
, socket
)->psock
;
631 dev_dbg(&sock
->dev
, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
632 "io_irq %d, csc_mask %#2.2x)\n", psock
, state
->flags
,
633 state
->Vcc
, state
->Vpp
, state
->io_irq
, state
->csc_mask
);
634 tcic_setw(TCIC_ADDR
+2, (psock
<< TCIC_SS_SHFT
) | TCIC_ADR2_INDREG
);
636 reg
= tcic_getb(TCIC_PWR
);
637 reg
&= ~(TCIC_PWR_VCC(psock
) | TCIC_PWR_VPP(psock
));
639 if (state
->Vcc
== 50) {
640 switch (state
->Vpp
) {
641 case 0: reg
|= TCIC_PWR_VCC(psock
) | TCIC_PWR_VPP(psock
); break;
642 case 50: reg
|= TCIC_PWR_VCC(psock
); break;
643 case 120: reg
|= TCIC_PWR_VPP(psock
); break;
644 default: return -EINVAL
;
646 } else if (state
->Vcc
!= 0)
649 if (reg
!= tcic_getb(TCIC_PWR
))
650 tcic_setb(TCIC_PWR
, reg
);
652 reg
= TCIC_ILOCK_HOLD_CCLK
| TCIC_ILOCK_CWAIT
;
653 if (state
->flags
& SS_OUTPUT_ENA
) {
654 tcic_setb(TCIC_SCTRL
, TCIC_SCTRL_ENA
);
655 reg
|= TCIC_ILOCK_CRESENA
;
657 tcic_setb(TCIC_SCTRL
, 0);
658 if (state
->flags
& SS_RESET
)
659 reg
|= TCIC_ILOCK_CRESET
;
660 tcic_aux_setb(TCIC_AUX_ILOCK
, reg
);
662 tcic_setw(TCIC_ADDR
, TCIC_SCF1(psock
));
663 scf1
= TCIC_SCF1_FINPACK
;
664 scf1
|= TCIC_IRQ(state
->io_irq
);
665 if (state
->flags
& SS_IOCARD
) {
666 scf1
|= TCIC_SCF1_IOSTS
;
667 if (state
->flags
& SS_SPKR_ENA
)
668 scf1
|= TCIC_SCF1_SPKR
;
669 if (state
->flags
& SS_DMA_MODE
)
670 scf1
|= TCIC_SCF1_DREQ2
<< TCIC_SCF1_DMA_SHIFT
;
672 tcic_setw(TCIC_DATA
, scf1
);
674 /* Some general setup stuff, and configure status interrupt */
675 reg
= TCIC_WAIT_ASYNC
| TCIC_WAIT_SENSE
| to_cycles(250);
676 tcic_aux_setb(TCIC_AUX_WCTL
, reg
);
677 tcic_aux_setw(TCIC_AUX_SYSCFG
, TCIC_SYSCFG_AUTOBUSY
|0x0a00|
680 /* Card status change interrupt mask */
681 tcic_setw(TCIC_ADDR
, TCIC_SCF2(psock
));
682 scf2
= TCIC_SCF2_MALL
;
683 if (state
->csc_mask
& SS_DETECT
) scf2
&= ~TCIC_SCF2_MCD
;
684 if (state
->flags
& SS_IOCARD
) {
685 if (state
->csc_mask
& SS_STSCHG
) reg
&= ~TCIC_SCF2_MLBAT1
;
687 if (state
->csc_mask
& SS_BATDEAD
) reg
&= ~TCIC_SCF2_MLBAT1
;
688 if (state
->csc_mask
& SS_BATWARN
) reg
&= ~TCIC_SCF2_MLBAT2
;
689 if (state
->csc_mask
& SS_READY
) reg
&= ~TCIC_SCF2_MRDY
;
691 tcic_setw(TCIC_DATA
, scf2
);
692 /* For the ISA bus, the irq should be active-high totem-pole */
693 tcic_setb(TCIC_IENA
, TCIC_IENA_CDCHG
| TCIC_IENA_CFG_HIGH
);
696 } /* tcic_set_socket */
698 /*====================================================================*/
700 static int tcic_set_io_map(struct pcmcia_socket
*sock
, struct pccard_io_map
*io
)
702 u_short psock
= container_of(sock
, struct tcic_socket
, socket
)->psock
;
704 u_short base
, len
, ioctl
;
706 dev_dbg(&sock
->dev
, "SetIOMap(%d, %d, %#2.2x, %d ns, "
707 "%#llx-%#llx)\n", psock
, io
->map
, io
->flags
, io
->speed
,
708 (unsigned long long)io
->start
, (unsigned long long)io
->stop
);
709 if ((io
->map
> 1) || (io
->start
> 0xffff) || (io
->stop
> 0xffff) ||
710 (io
->stop
< io
->start
)) return -EINVAL
;
711 tcic_setw(TCIC_ADDR
+2, TCIC_ADR2_INDREG
| (psock
<< TCIC_SS_SHFT
));
712 addr
= TCIC_IWIN(psock
, io
->map
);
714 base
= io
->start
; len
= io
->stop
- io
->start
;
715 /* Check to see that len+1 is power of two, etc */
716 if ((len
& (len
+1)) || (base
& len
)) return -EINVAL
;
718 tcic_setw(TCIC_ADDR
, addr
+ TCIC_IBASE_X
);
719 tcic_setw(TCIC_DATA
, base
);
721 ioctl
= (psock
<< TCIC_ICTL_SS_SHFT
);
722 ioctl
|= (len
== 0) ? TCIC_ICTL_TINY
: 0;
723 ioctl
|= (io
->flags
& MAP_ACTIVE
) ? TCIC_ICTL_ENA
: 0;
724 ioctl
|= to_cycles(io
->speed
) & TCIC_ICTL_WSCNT_MASK
;
725 if (!(io
->flags
& MAP_AUTOSZ
)) {
726 ioctl
|= TCIC_ICTL_QUIET
;
727 ioctl
|= (io
->flags
& MAP_16BIT
) ? TCIC_ICTL_BW_16
: TCIC_ICTL_BW_8
;
729 tcic_setw(TCIC_ADDR
, addr
+ TCIC_ICTL_X
);
730 tcic_setw(TCIC_DATA
, ioctl
);
733 } /* tcic_set_io_map */
735 /*====================================================================*/
737 static int tcic_set_mem_map(struct pcmcia_socket
*sock
, struct pccard_mem_map
*mem
)
739 u_short psock
= container_of(sock
, struct tcic_socket
, socket
)->psock
;
741 u_long base
, len
, mmap
;
743 dev_dbg(&sock
->dev
, "SetMemMap(%d, %d, %#2.2x, %d ns, "
744 "%#llx-%#llx, %#x)\n", psock
, mem
->map
, mem
->flags
,
745 mem
->speed
, (unsigned long long)mem
->res
->start
,
746 (unsigned long long)mem
->res
->end
, mem
->card_start
);
747 if ((mem
->map
> 3) || (mem
->card_start
> 0x3ffffff) ||
748 (mem
->res
->start
> 0xffffff) || (mem
->res
->end
> 0xffffff) ||
749 (mem
->res
->start
> mem
->res
->end
) || (mem
->speed
> 1000))
751 tcic_setw(TCIC_ADDR
+2, TCIC_ADR2_INDREG
| (psock
<< TCIC_SS_SHFT
));
752 addr
= TCIC_MWIN(psock
, mem
->map
);
754 base
= mem
->res
->start
; len
= mem
->res
->end
- mem
->res
->start
;
755 if ((len
& (len
+1)) || (base
& len
)) return -EINVAL
;
757 base
= (base
>> TCIC_MBASE_HA_SHFT
) | TCIC_MBASE_4K_BIT
;
759 base
= (base
| (len
+1)>>1) >> TCIC_MBASE_HA_SHFT
;
760 tcic_setw(TCIC_ADDR
, addr
+ TCIC_MBASE_X
);
761 tcic_setw(TCIC_DATA
, base
);
763 mmap
= mem
->card_start
- mem
->res
->start
;
764 mmap
= (mmap
>> TCIC_MMAP_CA_SHFT
) & TCIC_MMAP_CA_MASK
;
765 if (mem
->flags
& MAP_ATTRIB
) mmap
|= TCIC_MMAP_REG
;
766 tcic_setw(TCIC_ADDR
, addr
+ TCIC_MMAP_X
);
767 tcic_setw(TCIC_DATA
, mmap
);
769 ctl
= TCIC_MCTL_QUIET
| (psock
<< TCIC_MCTL_SS_SHFT
);
770 ctl
|= to_cycles(mem
->speed
) & TCIC_MCTL_WSCNT_MASK
;
771 ctl
|= (mem
->flags
& MAP_16BIT
) ? 0 : TCIC_MCTL_B8
;
772 ctl
|= (mem
->flags
& MAP_WRPROT
) ? TCIC_MCTL_WP
: 0;
773 ctl
|= (mem
->flags
& MAP_ACTIVE
) ? TCIC_MCTL_ENA
: 0;
774 tcic_setw(TCIC_ADDR
, addr
+ TCIC_MCTL_X
);
775 tcic_setw(TCIC_DATA
, ctl
);
778 } /* tcic_set_mem_map */
780 /*====================================================================*/
782 static int tcic_init(struct pcmcia_socket
*s
)
785 struct resource res
= { .start
= 0, .end
= 0x1000 };
786 pccard_io_map io
= { 0, 0, 0, 0, 1 };
787 pccard_mem_map mem
= { .res
= &res
, };
789 for (i
= 0; i
< 2; i
++) {
791 tcic_set_io_map(s
, &io
);
793 for (i
= 0; i
< 5; i
++) {
795 tcic_set_mem_map(s
, &mem
);
800 static struct pccard_operations tcic_operations
= {
802 .get_status
= tcic_get_status
,
803 .set_socket
= tcic_set_socket
,
804 .set_io_map
= tcic_set_io_map
,
805 .set_mem_map
= tcic_set_mem_map
,
808 /*====================================================================*/
810 module_init(init_tcic
);
811 module_exit(exit_tcic
);