Merge branch 'for-linus' of git://android.kernel.org/kernel/tegra
[sfrench/cifs-2.6.git] / drivers / pcmcia / tcic.c
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
56 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
57 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
58 MODULE_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 */
65 static unsigned long tcic_base = TCIC_BASE;
66
67 /* Specify a socket number to ignore */
68 static int ignore = -1;
69
70 /* Probe for safe interrupts? */
71 static int do_scan = 1;
72
73 /* Bit map of interrupts to choose from */
74 static u_int irq_mask = 0xffff;
75 static int irq_list[16];
76 static unsigned int irq_list_count;
77
78 /* The card status change interrupt -- 0 means autoselect */
79 static int cs_irq;
80
81 /* Poll status interval -- 0 means default to interrupt */
82 static int poll_interval;
83
84 /* Delay for card status double-checking */
85 static int poll_quick = HZ/20;
86
87 /* CCLK external clock time, in nanoseconds.  70 ns = 14.31818 MHz */
88 static int cycle_time = 70;
89
90 module_param(tcic_base, ulong, 0444);
91 module_param(ignore, int, 0444);
92 module_param(do_scan, int, 0444);
93 module_param(irq_mask, int, 0444);
94 module_param_array(irq_list, int, &irq_list_count, 0444);
95 module_param(cs_irq, int, 0444);
96 module_param(poll_interval, int, 0444);
97 module_param(poll_quick, int, 0444);
98 module_param(cycle_time, int, 0444);
99
100 /*====================================================================*/
101
102 static irqreturn_t tcic_interrupt(int irq, void *dev);
103 static void tcic_timer(u_long data);
104 static struct pccard_operations tcic_operations;
105
106 struct tcic_socket {
107     u_short     psock;
108     u_char      last_sstat;
109     u_char      id;
110     struct pcmcia_socket        socket;
111 };
112
113 static struct timer_list poll_timer;
114 static int tcic_timer_pending;
115
116 static int sockets;
117 static 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
126 static 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
133 static 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
140 static 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
146 static 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
158 static 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
167 static 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
174 static 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
181 static 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
192 static 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
202 static volatile u_int irq_hits;
203
204 static irqreturn_t __init tcic_irq_count(int irq, void *dev)
205 {
206     irq_hits++;
207     return IRQ_HANDLED;
208 }
209
210 static 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
241 static 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
296 static 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
338 static 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
351 static struct platform_driver tcic_driver = {
352         .driver = {
353                 .name = "tcic-pcmcia",
354                 .owner          = THIS_MODULE,
355         },
356 };
357
358 static struct platform_device tcic_device = {
359         .name = "tcic-pcmcia",
360         .id = 0,
361 };
362
363
364 static 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
513 static 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
534 static 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
589 static 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
598 static 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
624 static 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
699 static 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
736 static 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
781 static 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
799 static 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
809 module_init(init_tcic);
810 module_exit(exit_tcic);