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