• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/pcmcia/
1/*======================================================================
2
3    Device driver for Databook TCIC-2 PCMCIA controller
4
5    tcic.c 1.111 2000/02/15 04:13:12
6
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/
11
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.
16
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.
20
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.
31
32======================================================================*/
33
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>
48
49#include <asm/io.h>
50#include <asm/system.h>
51
52#include <pcmcia/cs.h>
53#include <pcmcia/ss.h>
54#include "tcic.h"
55
56MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
57MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
58MODULE_LICENSE("Dual MPL/GPL");
59
60/*====================================================================*/
61
62/* Parameters that can be set with 'insmod' */
63
64/* The base port address of the TCIC-2 chip */
65static unsigned long tcic_base = TCIC_BASE;
66
67/* Specify a socket number to ignore */
68static int ignore = -1;
69
70/* Probe for safe interrupts? */
71static int do_scan = 1;
72
73/* Bit map of interrupts to choose from */
74static u_int irq_mask = 0xffff;
75static int irq_list[16];
76static unsigned int irq_list_count;
77
78/* The card status change interrupt -- 0 means autoselect */
79static int cs_irq;
80
81/* Poll status interval -- 0 means default to interrupt */
82static int poll_interval;
83
84/* Delay for card status double-checking */
85static int poll_quick = HZ/20;
86
87/* CCLK external clock time, in nanoseconds.  70 ns = 14.31818 MHz */
88static int cycle_time = 70;
89
90module_param(tcic_base, ulong, 0444);
91module_param(ignore, int, 0444);
92module_param(do_scan, int, 0444);
93module_param(irq_mask, int, 0444);
94module_param_array(irq_list, int, &irq_list_count, 0444);
95module_param(cs_irq, int, 0444);
96module_param(poll_interval, int, 0444);
97module_param(poll_quick, int, 0444);
98module_param(cycle_time, int, 0444);
99
100/*====================================================================*/
101
102static irqreturn_t tcic_interrupt(int irq, void *dev);
103static void tcic_timer(u_long data);
104static struct pccard_operations tcic_operations;
105
106struct tcic_socket {
107    u_short	psock;
108    u_char	last_sstat;
109    u_char	id;
110    struct pcmcia_socket	socket;
111};
112
113static struct timer_list poll_timer;
114static int tcic_timer_pending;
115
116static int sockets;
117static struct tcic_socket socket_table[2];
118
119/*====================================================================*/
120
121/* Trick when selecting interrupts: the TCIC sktirq pin is supposed
122   to map to irq 11, but is coded as 0 or 1 in the irq registers. */
123#define TCIC_IRQ(x) ((x) ? (((x) == 11) ? 1 : (x)) : 15)
124
125#ifdef DEBUG_X
126static u_char tcic_getb(u_char reg)
127{
128    u_char val = inb(tcic_base+reg);
129    printk(KERN_DEBUG "tcic_getb(%#lx) = %#x\n", tcic_base+reg, val);
130    return val;
131}
132
133static u_short tcic_getw(u_char reg)
134{
135    u_short val = inw(tcic_base+reg);
136    printk(KERN_DEBUG "tcic_getw(%#lx) = %#x\n", tcic_base+reg, val);
137    return val;
138}
139
140static void tcic_setb(u_char reg, u_char data)
141{
142    printk(KERN_DEBUG "tcic_setb(%#lx, %#x)\n", tcic_base+reg, data);
143    outb(data, tcic_base+reg);
144}
145
146static void tcic_setw(u_char reg, u_short data)
147{
148    printk(KERN_DEBUG "tcic_setw(%#lx, %#x)\n", tcic_base+reg, data);
149    outw(data, tcic_base+reg);
150}
151#else
152#define tcic_getb(reg) inb(tcic_base+reg)
153#define tcic_getw(reg) inw(tcic_base+reg)
154#define tcic_setb(reg, data) outb(data, tcic_base+reg)
155#define tcic_setw(reg, data) outw(data, tcic_base+reg)
156#endif
157
158static void tcic_setl(u_char reg, u_int data)
159{
160#ifdef DEBUG_X
161    printk(KERN_DEBUG "tcic_setl(%#x, %#lx)\n", tcic_base+reg, data);
162#endif
163    outw(data & 0xffff, tcic_base+reg);
164    outw(data >> 16, tcic_base+reg+2);
165}
166
167static void tcic_aux_setb(u_short reg, u_char data)
168{
169    u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
170    tcic_setb(TCIC_MODE, mode);
171    tcic_setb(TCIC_AUX, data);
172}
173
174static u_short tcic_aux_getw(u_short reg)
175{
176    u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
177    tcic_setb(TCIC_MODE, mode);
178    return tcic_getw(TCIC_AUX);
179}
180
181static void tcic_aux_setw(u_short reg, u_short data)
182{
183    u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
184    tcic_setb(TCIC_MODE, mode);
185    tcic_setw(TCIC_AUX, data);
186}
187
188/*====================================================================*/
189
190/* Time conversion functions */
191
192static int to_cycles(int ns)
193{
194    if (ns < 14)
195	return 0;
196    else
197	return 2*(ns-14)/cycle_time;
198}
199
200/*====================================================================*/
201
202static volatile u_int irq_hits;
203
204static irqreturn_t __init tcic_irq_count(int irq, void *dev)
205{
206    irq_hits++;
207    return IRQ_HANDLED;
208}
209
210static u_int __init try_irq(int irq)
211{
212    u_short cfg;
213
214    irq_hits = 0;
215    if (request_irq(irq, tcic_irq_count, 0, "irq scan", tcic_irq_count) != 0)
216	return -1;
217    mdelay(10);
218    if (irq_hits) {
219	free_irq(irq, tcic_irq_count);
220	return -1;
221    }
222
223    /* Generate one interrupt */
224    cfg = TCIC_SYSCFG_AUTOBUSY | 0x0a00;
225    tcic_aux_setw(TCIC_AUX_SYSCFG, cfg | TCIC_IRQ(irq));
226    tcic_setb(TCIC_IENA, TCIC_IENA_ERR | TCIC_IENA_CFG_HIGH);
227    tcic_setb(TCIC_ICSR, TCIC_ICSR_ERR | TCIC_ICSR_JAM);
228
229    udelay(1000);
230    free_irq(irq, tcic_irq_count);
231
232    /* Turn off interrupts */
233    tcic_setb(TCIC_IENA, TCIC_IENA_CFG_OFF);
234    while (tcic_getb(TCIC_ICSR))
235	tcic_setb(TCIC_ICSR, TCIC_ICSR_JAM);
236    tcic_aux_setw(TCIC_AUX_SYSCFG, cfg);
237
238    return (irq_hits != 1);
239}
240
241static u_int __init irq_scan(u_int mask0)
242{
243    u_int mask1;
244    int i;
245
246#ifdef __alpha__
247#define PIC 0x4d0
248    /* Don't probe level-triggered interrupts -- reserved for PCI */
249    int level_mask = inb_p(PIC) | (inb_p(PIC+1) << 8);
250    if (level_mask)
251	mask0 &= ~level_mask;
252#endif
253
254    mask1 = 0;
255    if (do_scan) {
256	for (i = 0; i < 16; i++)
257	    if ((mask0 & (1 << i)) && (try_irq(i) == 0))
258		mask1 |= (1 << i);
259	for (i = 0; i < 16; i++)
260	    if ((mask1 & (1 << i)) && (try_irq(i) != 0)) {
261		mask1 ^= (1 << i);
262	    }
263    }
264
265    if (mask1) {
266	printk("scanned");
267    } else {
268	/* Fallback: just find interrupts that aren't in use */
269	for (i = 0; i < 16; i++)
270	    if ((mask0 & (1 << i)) &&
271		(request_irq(i, tcic_irq_count, 0, "x", tcic_irq_count) == 0)) {
272		mask1 |= (1 << i);
273		free_irq(i, tcic_irq_count);
274	    }
275	printk("default");
276    }
277
278    printk(") = ");
279    for (i = 0; i < 16; i++)
280	if (mask1 & (1<<i))
281	    printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
282    printk(" ");
283
284    return mask1;
285}
286
287/*======================================================================
288
289    See if a card is present, powered up, in IO mode, and already
290    bound to a (non-PCMCIA) Linux driver.
291
292    We make an exception for cards that look like serial devices.
293
294======================================================================*/
295
296static int __init is_active(int s)
297{
298    u_short scf1, ioctl, base, num;
299    u_char pwr, sstat;
300    u_int addr;
301
302    tcic_setl(TCIC_ADDR, (s << TCIC_ADDR_SS_SHFT)
303	      | TCIC_ADDR_INDREG | TCIC_SCF1(s));
304    scf1 = tcic_getw(TCIC_DATA);
305    pwr = tcic_getb(TCIC_PWR);
306    sstat = tcic_getb(TCIC_SSTAT);
307    addr = TCIC_IWIN(s, 0);
308    tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
309    base = tcic_getw(TCIC_DATA);
310    tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
311    ioctl = tcic_getw(TCIC_DATA);
312
313    if (ioctl & TCIC_ICTL_TINY)
314	num = 1;
315    else {
316	num = (base ^ (base-1));
317	base = base & (base-1);
318    }
319
320    if ((sstat & TCIC_SSTAT_CD) && (pwr & TCIC_PWR_VCC(s)) &&
321	(scf1 & TCIC_SCF1_IOSTS) && (ioctl & TCIC_ICTL_ENA) &&
322	((base & 0xfeef) != 0x02e8)) {
323	struct resource *res = request_region(base, num, "tcic-2");
324	if (!res) /* region is busy */
325	    return 1;
326	release_region(base, num);
327    }
328
329    return 0;
330}
331
332/*======================================================================
333
334    This returns the revision code for the specified socket.
335
336======================================================================*/
337
338static int __init get_tcic_id(void)
339{
340    u_short id;
341
342    tcic_aux_setw(TCIC_AUX_TEST, TCIC_TEST_DIAG);
343    id = tcic_aux_getw(TCIC_AUX_ILOCK);
344    id = (id & TCIC_ILOCKTEST_ID_MASK) >> TCIC_ILOCKTEST_ID_SH;
345    tcic_aux_setw(TCIC_AUX_TEST, 0);
346    return id;
347}
348
349/*====================================================================*/
350
351static struct platform_driver tcic_driver = {
352	.driver = {
353		.name = "tcic-pcmcia",
354		.owner		= THIS_MODULE,
355	},
356};
357
358static struct platform_device tcic_device = {
359	.name = "tcic-pcmcia",
360	.id = 0,
361};
362
363
364static int __init init_tcic(void)
365{
366    int i, sock, ret = 0;
367    u_int mask, scan;
368
369    if (platform_driver_register(&tcic_driver))
370	return -1;
371
372    printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
373    sock = 0;
374
375    if (!request_region(tcic_base, 16, "tcic-2")) {
376	printk("could not allocate ports,\n ");
377	platform_driver_unregister(&tcic_driver);
378	return -ENODEV;
379    }
380    else {
381	tcic_setw(TCIC_ADDR, 0);
382	if (tcic_getw(TCIC_ADDR) == 0) {
383	    tcic_setw(TCIC_ADDR, 0xc3a5);
384	    if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
385	}
386	if (sock == 0) {
387	    /* See if resetting the controller does any good */
388	    tcic_setb(TCIC_SCTRL, TCIC_SCTRL_RESET);
389	    tcic_setb(TCIC_SCTRL, 0);
390	    tcic_setw(TCIC_ADDR, 0);
391	    if (tcic_getw(TCIC_ADDR) == 0) {
392		tcic_setw(TCIC_ADDR, 0xc3a5);
393		if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
394	    }
395	}
396    }
397    if (sock == 0) {
398	printk("not found.\n");
399	release_region(tcic_base, 16);
400	platform_driver_unregister(&tcic_driver);
401	return -ENODEV;
402    }
403
404    sockets = 0;
405    for (i = 0; i < sock; i++) {
406	if ((i == ignore) || is_active(i)) continue;
407	socket_table[sockets].psock = i;
408	socket_table[sockets].id = get_tcic_id();
409
410	socket_table[sockets].socket.owner = THIS_MODULE;
411	/* only 16-bit cards, memory windows must be size-aligned */
412	/* No PCI or CardBus support */
413	socket_table[sockets].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN;
414	/* irq 14, 11, 10, 7, 6, 5, 4, 3 */
415	socket_table[sockets].socket.irq_mask = 0x4cf8;
416	/* 4K minimum window size */
417	socket_table[sockets].socket.map_size = 0x1000;
418	sockets++;
419    }
420
421    switch (socket_table[0].id) {
422    case TCIC_ID_DB86082:
423	printk("DB86082"); break;
424    case TCIC_ID_DB86082A:
425	printk("DB86082A"); break;
426    case TCIC_ID_DB86084:
427	printk("DB86084"); break;
428    case TCIC_ID_DB86084A:
429	printk("DB86084A"); break;
430    case TCIC_ID_DB86072:
431	printk("DB86072"); break;
432    case TCIC_ID_DB86184:
433	printk("DB86184"); break;
434    case TCIC_ID_DB86082B:
435	printk("DB86082B"); break;
436    default:
437	printk("Unknown ID 0x%02x", socket_table[0].id);
438    }
439
440    /* Set up polling */
441    poll_timer.function = &tcic_timer;
442    poll_timer.data = 0;
443    init_timer(&poll_timer);
444
445    /* Build interrupt mask */
446    printk(KERN_CONT ", %d sockets\n", sockets);
447    printk(KERN_INFO "  irq list (");
448    if (irq_list_count == 0)
449	mask = irq_mask;
450    else
451	for (i = mask = 0; i < irq_list_count; i++)
452	    mask |= (1<<irq_list[i]);
453
454    /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
455    mask &= 0x4cf8;
456    /* Scan interrupts */
457    mask = irq_scan(mask);
458    for (i=0;i<sockets;i++)
459	    socket_table[i].socket.irq_mask = mask;
460
461    /* Check for only two interrupts available */
462    scan = (mask & (mask-1));
463    if (((scan & (scan-1)) == 0) && (poll_interval == 0))
464	poll_interval = HZ;
465
466    if (poll_interval == 0) {
467	/* Avoid irq 12 unless it is explicitly requested */
468	u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
469	for (i = 15; i > 0; i--)
470	    if ((cs_mask & (1 << i)) &&
471		(request_irq(i, tcic_interrupt, 0, "tcic",
472			     tcic_interrupt) == 0))
473		break;
474	cs_irq = i;
475	if (cs_irq == 0) poll_interval = HZ;
476    }
477
478    if (socket_table[0].socket.irq_mask & (1 << 11))
479	printk("sktirq is irq 11, ");
480    if (cs_irq != 0)
481	printk("status change on irq %d\n", cs_irq);
482    else
483	printk("polled status, interval = %d ms\n",
484	       poll_interval * 1000 / HZ);
485
486    for (i = 0; i < sockets; i++) {
487	tcic_setw(TCIC_ADDR+2, socket_table[i].psock << TCIC_SS_SHFT);
488	socket_table[i].last_sstat = tcic_getb(TCIC_SSTAT);
489    }
490
491    /* jump start interrupt handler, if needed */
492    tcic_interrupt(0, NULL);
493
494    platform_device_register(&tcic_device);
495
496    for (i = 0; i < sockets; i++) {
497	    socket_table[i].socket.ops = &tcic_operations;
498	    socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
499	    socket_table[i].socket.dev.parent = &tcic_device.dev;
500	    ret = pcmcia_register_socket(&socket_table[i].socket);
501	    if (ret && i)
502		    pcmcia_unregister_socket(&socket_table[0].socket);
503    }
504
505    return ret;
506
507    return 0;
508
509} /* init_tcic */
510
511/*====================================================================*/
512
513static void __exit exit_tcic(void)
514{
515    int i;
516
517    del_timer_sync(&poll_timer);
518    if (cs_irq != 0) {
519	tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
520	free_irq(cs_irq, tcic_interrupt);
521    }
522    release_region(tcic_base, 16);
523
524    for (i = 0; i < sockets; i++) {
525	    pcmcia_unregister_socket(&socket_table[i].socket);
526    }
527
528    platform_device_unregister(&tcic_device);
529    platform_driver_unregister(&tcic_driver);
530} /* exit_tcic */
531
532/*====================================================================*/
533
534static irqreturn_t tcic_interrupt(int irq, void *dev)
535{
536    int i, quick = 0;
537    u_char latch, sstat;
538    u_short psock;
539    u_int events;
540    static volatile int active = 0;
541
542    if (active) {
543	printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
544	return IRQ_NONE;
545    } else
546	active = 1;
547
548    pr_debug("tcic_interrupt()\n");
549
550    for (i = 0; i < sockets; i++) {
551	psock = socket_table[i].psock;
552	tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
553		  | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
554	sstat = tcic_getb(TCIC_SSTAT);
555	latch = sstat ^ socket_table[psock].last_sstat;
556	socket_table[i].last_sstat = sstat;
557	if (tcic_getb(TCIC_ICSR) & TCIC_ICSR_CDCHG) {
558	    tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
559	    quick = 1;
560	}
561	if (latch == 0)
562	    continue;
563	events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
564	events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
565	if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
566	    events |= (latch & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
567	} else {
568	    events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
569	    events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
570	    events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
571	}
572	if (events) {
573		pcmcia_parse_events(&socket_table[i].socket, events);
574	}
575    }
576
577    /* Schedule next poll, if needed */
578    if (((cs_irq == 0) || quick) && (!tcic_timer_pending)) {
579	poll_timer.expires = jiffies + (quick ? poll_quick : poll_interval);
580	add_timer(&poll_timer);
581	tcic_timer_pending = 1;
582    }
583    active = 0;
584
585    pr_debug("interrupt done\n");
586    return IRQ_HANDLED;
587} /* tcic_interrupt */
588
589static void tcic_timer(u_long data)
590{
591    pr_debug("tcic_timer()\n");
592    tcic_timer_pending = 0;
593    tcic_interrupt(0, NULL);
594} /* tcic_timer */
595
596/*====================================================================*/
597
598static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
599{
600    u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
601    u_char reg;
602
603    tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
604	      | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
605    reg = tcic_getb(TCIC_SSTAT);
606    *value  = (reg & TCIC_SSTAT_CD) ? SS_DETECT : 0;
607    *value |= (reg & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
608    if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
609	*value |= (reg & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
610    } else {
611	*value |= (reg & TCIC_SSTAT_RDY) ? SS_READY : 0;
612	*value |= (reg & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
613	*value |= (reg & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
614    }
615    reg = tcic_getb(TCIC_PWR);
616    if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
617	*value |= SS_POWERON;
618    dev_dbg(&sock->dev, "GetStatus(%d) = %#2.2x\n", psock, *value);
619    return 0;
620} /* tcic_get_status */
621
622/*====================================================================*/
623
624static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
625{
626    u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
627    u_char reg;
628    u_short scf1, scf2;
629
630    dev_dbg(&sock->dev, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
631	  "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
632	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
633    tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
634
635    reg = tcic_getb(TCIC_PWR);
636    reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
637
638    if (state->Vcc == 50) {
639	switch (state->Vpp) {
640	case 0:   reg |= TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock); break;
641	case 50:  reg |= TCIC_PWR_VCC(psock); break;
642	case 120: reg |= TCIC_PWR_VPP(psock); break;
643	default:  return -EINVAL;
644	}
645    } else if (state->Vcc != 0)
646	return -EINVAL;
647
648    if (reg != tcic_getb(TCIC_PWR))
649	tcic_setb(TCIC_PWR, reg);
650
651    reg = TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT;
652    if (state->flags & SS_OUTPUT_ENA) {
653	tcic_setb(TCIC_SCTRL, TCIC_SCTRL_ENA);
654	reg |= TCIC_ILOCK_CRESENA;
655    } else
656	tcic_setb(TCIC_SCTRL, 0);
657    if (state->flags & SS_RESET)
658	reg |= TCIC_ILOCK_CRESET;
659    tcic_aux_setb(TCIC_AUX_ILOCK, reg);
660
661    tcic_setw(TCIC_ADDR, TCIC_SCF1(psock));
662    scf1 = TCIC_SCF1_FINPACK;
663    scf1 |= TCIC_IRQ(state->io_irq);
664    if (state->flags & SS_IOCARD) {
665	scf1 |= TCIC_SCF1_IOSTS;
666	if (state->flags & SS_SPKR_ENA)
667	    scf1 |= TCIC_SCF1_SPKR;
668	if (state->flags & SS_DMA_MODE)
669	    scf1 |= TCIC_SCF1_DREQ2 << TCIC_SCF1_DMA_SHIFT;
670    }
671    tcic_setw(TCIC_DATA, scf1);
672
673    /* Some general setup stuff, and configure status interrupt */
674    reg = TCIC_WAIT_ASYNC | TCIC_WAIT_SENSE | to_cycles(250);
675    tcic_aux_setb(TCIC_AUX_WCTL, reg);
676    tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00|
677		  TCIC_IRQ(cs_irq));
678
679    /* Card status change interrupt mask */
680    tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
681    scf2 = TCIC_SCF2_MALL;
682    if (state->csc_mask & SS_DETECT) scf2 &= ~TCIC_SCF2_MCD;
683    if (state->flags & SS_IOCARD) {
684	if (state->csc_mask & SS_STSCHG) reg &= ~TCIC_SCF2_MLBAT1;
685    } else {
686	if (state->csc_mask & SS_BATDEAD) reg &= ~TCIC_SCF2_MLBAT1;
687	if (state->csc_mask & SS_BATWARN) reg &= ~TCIC_SCF2_MLBAT2;
688	if (state->csc_mask & SS_READY) reg &= ~TCIC_SCF2_MRDY;
689    }
690    tcic_setw(TCIC_DATA, scf2);
691    /* For the ISA bus, the irq should be active-high totem-pole */
692    tcic_setb(TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
693
694    return 0;
695} /* tcic_set_socket */
696
697/*====================================================================*/
698
699static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
700{
701    u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
702    u_int addr;
703    u_short base, len, ioctl;
704
705    dev_dbg(&sock->dev, "SetIOMap(%d, %d, %#2.2x, %d ns, "
706	  "%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
707	  (unsigned long long)io->start, (unsigned long long)io->stop);
708    if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
709	(io->stop < io->start)) return -EINVAL;
710    tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
711    addr = TCIC_IWIN(psock, io->map);
712
713    base = io->start; len = io->stop - io->start;
714    /* Check to see that len+1 is power of two, etc */
715    if ((len & (len+1)) || (base & len)) return -EINVAL;
716    base |= (len+1)>>1;
717    tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
718    tcic_setw(TCIC_DATA, base);
719
720    ioctl  = (psock << TCIC_ICTL_SS_SHFT);
721    ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
722    ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
723    ioctl |= to_cycles(io->speed) & TCIC_ICTL_WSCNT_MASK;
724    if (!(io->flags & MAP_AUTOSZ)) {
725	ioctl |= TCIC_ICTL_QUIET;
726	ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
727    }
728    tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
729    tcic_setw(TCIC_DATA, ioctl);
730
731    return 0;
732} /* tcic_set_io_map */
733
734/*====================================================================*/
735
736static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
737{
738    u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
739    u_short addr, ctl;
740    u_long base, len, mmap;
741
742    dev_dbg(&sock->dev, "SetMemMap(%d, %d, %#2.2x, %d ns, "
743	  "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
744	  mem->speed, (unsigned long long)mem->res->start,
745	  (unsigned long long)mem->res->end, mem->card_start);
746    if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
747	(mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) ||
748	(mem->res->start > mem->res->end) || (mem->speed > 1000))
749	return -EINVAL;
750    tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
751    addr = TCIC_MWIN(psock, mem->map);
752
753    base = mem->res->start; len = mem->res->end - mem->res->start;
754    if ((len & (len+1)) || (base & len)) return -EINVAL;
755    if (len == 0x0fff)
756	base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
757    else
758	base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
759    tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
760    tcic_setw(TCIC_DATA, base);
761
762    mmap = mem->card_start - mem->res->start;
763    mmap = (mmap >> TCIC_MMAP_CA_SHFT) & TCIC_MMAP_CA_MASK;
764    if (mem->flags & MAP_ATTRIB) mmap |= TCIC_MMAP_REG;
765    tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
766    tcic_setw(TCIC_DATA, mmap);
767
768    ctl  = TCIC_MCTL_QUIET | (psock << TCIC_MCTL_SS_SHFT);
769    ctl |= to_cycles(mem->speed) & TCIC_MCTL_WSCNT_MASK;
770    ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
771    ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
772    ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
773    tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
774    tcic_setw(TCIC_DATA, ctl);
775
776    return 0;
777} /* tcic_set_mem_map */
778
779/*====================================================================*/
780
781static int tcic_init(struct pcmcia_socket *s)
782{
783	int i;
784	struct resource res = { .start = 0, .end = 0x1000 };
785	pccard_io_map io = { 0, 0, 0, 0, 1 };
786	pccard_mem_map mem = { .res = &res, };
787
788	for (i = 0; i < 2; i++) {
789		io.map = i;
790		tcic_set_io_map(s, &io);
791	}
792	for (i = 0; i < 5; i++) {
793		mem.map = i;
794		tcic_set_mem_map(s, &mem);
795	}
796	return 0;
797}
798
799static struct pccard_operations tcic_operations = {
800	.init		   = tcic_init,
801	.get_status	   = tcic_get_status,
802	.set_socket	   = tcic_set_socket,
803	.set_io_map	   = tcic_set_io_map,
804	.set_mem_map	   = tcic_set_mem_map,
805};
806
807/*====================================================================*/
808
809module_init(init_tcic);
810module_exit(exit_tcic);
811