pandora: update defconfig
[pandora-kernel.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_types.h>
53 #include <pcmcia/cs.h>
54 #include <pcmcia/ss.h>
55 #include "tcic.h"
56
57 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
58 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
59 MODULE_LICENSE("Dual MPL/GPL");
60
61 /*====================================================================*/
62
63 /* Parameters that can be set with 'insmod' */
64
65 /* The base port address of the TCIC-2 chip */
66 static unsigned long tcic_base = TCIC_BASE;
67
68 /* Specify a socket number to ignore */
69 static int ignore = -1;
70
71 /* Probe for safe interrupts? */
72 static int do_scan = 1;
73
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;
78
79 /* The card status change interrupt -- 0 means autoselect */
80 static int cs_irq;
81
82 /* Poll status interval -- 0 means default to interrupt */
83 static int poll_interval;
84
85 /* Delay for card status double-checking */
86 static int poll_quick = HZ/20;
87
88 /* CCLK external clock time, in nanoseconds.  70 ns = 14.31818 MHz */
89 static int cycle_time = 70;
90
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);
100
101 /*====================================================================*/
102
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;
106
107 struct tcic_socket {
108     u_short     psock;
109     u_char      last_sstat;
110     u_char      id;
111     struct pcmcia_socket        socket;
112 };
113
114 static struct timer_list poll_timer;
115 static int tcic_timer_pending;
116
117 static int sockets;
118 static struct tcic_socket socket_table[2];
119
120 /*====================================================================*/
121
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)
125
126 #ifdef DEBUG_X
127 static u_char tcic_getb(u_char reg)
128 {
129     u_char val = inb(tcic_base+reg);
130     printk(KERN_DEBUG "tcic_getb(%#lx) = %#x\n", tcic_base+reg, val);
131     return val;
132 }
133
134 static u_short tcic_getw(u_char reg)
135 {
136     u_short val = inw(tcic_base+reg);
137     printk(KERN_DEBUG "tcic_getw(%#lx) = %#x\n", tcic_base+reg, val);
138     return val;
139 }
140
141 static void tcic_setb(u_char reg, u_char data)
142 {
143     printk(KERN_DEBUG "tcic_setb(%#lx, %#x)\n", tcic_base+reg, data);
144     outb(data, tcic_base+reg);
145 }
146
147 static void tcic_setw(u_char reg, u_short data)
148 {
149     printk(KERN_DEBUG "tcic_setw(%#lx, %#x)\n", tcic_base+reg, data);
150     outw(data, tcic_base+reg);
151 }
152 #else
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)
157 #endif
158
159 static void tcic_setl(u_char reg, u_int data)
160 {
161 #ifdef DEBUG_X
162     printk(KERN_DEBUG "tcic_setl(%#x, %#lx)\n", tcic_base+reg, data);
163 #endif
164     outw(data & 0xffff, tcic_base+reg);
165     outw(data >> 16, tcic_base+reg+2);
166 }
167
168 static void tcic_aux_setb(u_short reg, u_char data)
169 {
170     u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
171     tcic_setb(TCIC_MODE, mode);
172     tcic_setb(TCIC_AUX, data);
173 }
174
175 static u_short tcic_aux_getw(u_short reg)
176 {
177     u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
178     tcic_setb(TCIC_MODE, mode);
179     return tcic_getw(TCIC_AUX);
180 }
181
182 static void tcic_aux_setw(u_short reg, u_short data)
183 {
184     u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
185     tcic_setb(TCIC_MODE, mode);
186     tcic_setw(TCIC_AUX, data);
187 }
188
189 /*====================================================================*/
190
191 /* Time conversion functions */
192
193 static int to_cycles(int ns)
194 {
195     if (ns < 14)
196         return 0;
197     else
198         return 2*(ns-14)/cycle_time;
199 }
200
201 /*====================================================================*/
202
203 static volatile u_int irq_hits;
204
205 static irqreturn_t __init tcic_irq_count(int irq, void *dev)
206 {
207     irq_hits++;
208     return IRQ_HANDLED;
209 }
210
211 static u_int __init try_irq(int irq)
212 {
213     u_short cfg;
214
215     irq_hits = 0;
216     if (request_irq(irq, tcic_irq_count, 0, "irq scan", tcic_irq_count) != 0)
217         return -1;
218     mdelay(10);
219     if (irq_hits) {
220         free_irq(irq, tcic_irq_count);
221         return -1;
222     }
223
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);
229
230     udelay(1000);
231     free_irq(irq, tcic_irq_count);
232
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);
238     
239     return (irq_hits != 1);
240 }
241
242 static u_int __init irq_scan(u_int mask0)
243 {
244     u_int mask1;
245     int i;
246
247 #ifdef __alpha__
248 #define PIC 0x4d0
249     /* Don't probe level-triggered interrupts -- reserved for PCI */
250     int level_mask = inb_p(PIC) | (inb_p(PIC+1) << 8);
251     if (level_mask)
252         mask0 &= ~level_mask;
253 #endif
254
255     mask1 = 0;
256     if (do_scan) {
257         for (i = 0; i < 16; i++)
258             if ((mask0 & (1 << i)) && (try_irq(i) == 0))
259                 mask1 |= (1 << i);
260         for (i = 0; i < 16; i++)
261             if ((mask1 & (1 << i)) && (try_irq(i) != 0)) {
262                 mask1 ^= (1 << i);
263             }
264     }
265     
266     if (mask1) {
267         printk("scanned");
268     } else {
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)) {
273                 mask1 |= (1 << i);
274                 free_irq(i, tcic_irq_count);
275             }
276         printk("default");
277     }
278     
279     printk(") = ");
280     for (i = 0; i < 16; i++)
281         if (mask1 & (1<<i))
282             printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
283     printk(" ");
284     
285     return mask1;
286 }
287
288 /*======================================================================
289
290     See if a card is present, powered up, in IO mode, and already
291     bound to a (non-PCMCIA) Linux driver.
292
293     We make an exception for cards that look like serial devices.
294     
295 ======================================================================*/
296
297 static int __init is_active(int s)
298 {
299     u_short scf1, ioctl, base, num;
300     u_char pwr, sstat;
301     u_int addr;
302     
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);
313
314     if (ioctl & TCIC_ICTL_TINY)
315         num = 1;
316     else {
317         num = (base ^ (base-1));
318         base = base & (base-1);
319     }
320
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 */
326             return 1;
327         release_region(base, num);
328     }
329
330     return 0;
331 }
332
333 /*======================================================================
334
335     This returns the revision code for the specified socket.
336     
337 ======================================================================*/
338
339 static int __init get_tcic_id(void)
340 {
341     u_short id;
342     
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);
347     return id;
348 }
349
350 /*====================================================================*/
351
352 static struct platform_driver tcic_driver = {
353         .driver = {
354                 .name = "tcic-pcmcia",
355                 .owner          = THIS_MODULE,
356         },
357 };
358
359 static struct platform_device tcic_device = {
360         .name = "tcic-pcmcia",
361         .id = 0,
362 };
363
364
365 static int __init init_tcic(void)
366 {
367     int i, sock, ret = 0;
368     u_int mask, scan;
369
370     if (platform_driver_register(&tcic_driver))
371         return -1;
372     
373     printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
374     sock = 0;
375
376     if (!request_region(tcic_base, 16, "tcic-2")) {
377         printk("could not allocate ports,\n ");
378         platform_driver_unregister(&tcic_driver);
379         return -ENODEV;
380     }
381     else {
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;
386         }
387         if (sock == 0) {
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;
395             }
396         }
397     }
398     if (sock == 0) {
399         printk("not found.\n");
400         release_region(tcic_base, 16);
401         platform_driver_unregister(&tcic_driver);
402         return -ENODEV;
403     }
404
405     sockets = 0;
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();
410
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;         
419         sockets++;
420     }
421
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;
437     default:
438         printk("Unknown ID 0x%02x", socket_table[0].id);
439     }
440     
441     /* Set up polling */
442     poll_timer.function = &tcic_timer;
443     poll_timer.data = 0;
444     init_timer(&poll_timer);
445
446     /* Build interrupt mask */
447     printk(KERN_CONT ", %d sockets\n", sockets);
448     printk(KERN_INFO "  irq list (");
449     if (irq_list_count == 0)
450         mask = irq_mask;
451     else
452         for (i = mask = 0; i < irq_list_count; i++)
453             mask |= (1<<irq_list[i]);
454
455     /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
456     mask &= 0x4cf8;
457     /* Scan interrupts */
458     mask = irq_scan(mask);
459     for (i=0;i<sockets;i++)
460             socket_table[i].socket.irq_mask = mask;
461     
462     /* Check for only two interrupts available */
463     scan = (mask & (mask-1));
464     if (((scan & (scan-1)) == 0) && (poll_interval == 0))
465         poll_interval = HZ;
466     
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))
474                 break;
475         cs_irq = i;
476         if (cs_irq == 0) poll_interval = HZ;
477     }
478     
479     if (socket_table[0].socket.irq_mask & (1 << 11))
480         printk("sktirq is irq 11, ");
481     if (cs_irq != 0)
482         printk("status change on irq %d\n", cs_irq);
483     else
484         printk("polled status, interval = %d ms\n",
485                poll_interval * 1000 / HZ);
486     
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);
490     }
491     
492     /* jump start interrupt handler, if needed */
493     tcic_interrupt(0, NULL);
494
495     platform_device_register(&tcic_device);
496
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);
502             if (ret && i)
503                     pcmcia_unregister_socket(&socket_table[0].socket);
504     }
505     
506     return ret;
507
508     return 0;
509     
510 } /* init_tcic */
511
512 /*====================================================================*/
513
514 static void __exit exit_tcic(void)
515 {
516     int i;
517
518     del_timer_sync(&poll_timer);
519     if (cs_irq != 0) {
520         tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
521         free_irq(cs_irq, tcic_interrupt);
522     }
523     release_region(tcic_base, 16);
524
525     for (i = 0; i < sockets; i++) {
526             pcmcia_unregister_socket(&socket_table[i].socket);      
527     }
528
529     platform_device_unregister(&tcic_device);
530     platform_driver_unregister(&tcic_driver);
531 } /* exit_tcic */
532
533 /*====================================================================*/
534
535 static irqreturn_t tcic_interrupt(int irq, void *dev)
536 {
537     int i, quick = 0;
538     u_char latch, sstat;
539     u_short psock;
540     u_int events;
541     static volatile int active = 0;
542
543     if (active) {
544         printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
545         return IRQ_NONE;
546     } else
547         active = 1;
548
549     pr_debug("tcic_interrupt()\n");
550     
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);
560             quick = 1;
561         }
562         if (latch == 0)
563             continue;
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;
568         } else {
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;
572         }
573         if (events) {
574                 pcmcia_parse_events(&socket_table[i].socket, events);
575         }
576     }
577
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;
583     }
584     active = 0;
585     
586     pr_debug("interrupt done\n");
587     return IRQ_HANDLED;
588 } /* tcic_interrupt */
589
590 static void tcic_timer(u_long data)
591 {
592     pr_debug("tcic_timer()\n");
593     tcic_timer_pending = 0;
594     tcic_interrupt(0, NULL);
595 } /* tcic_timer */
596
597 /*====================================================================*/
598
599 static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
600 {
601     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
602     u_char reg;
603
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;
611     } else {
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;
615     }
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);
620     return 0;
621 } /* tcic_get_status */
622
623 /*====================================================================*/
624
625 static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
626 {
627     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
628     u_char reg;
629     u_short scf1, scf2;
630
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);
635
636     reg = tcic_getb(TCIC_PWR);
637     reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
638
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;
645         }
646     } else if (state->Vcc != 0)
647         return -EINVAL;
648
649     if (reg != tcic_getb(TCIC_PWR))
650         tcic_setb(TCIC_PWR, reg);
651
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;
656     } else
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);
661     
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;
671     }
672     tcic_setw(TCIC_DATA, scf1);
673
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|
678                   TCIC_IRQ(cs_irq));
679     
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;
686     } else {
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;
690     }
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);
694
695     return 0;
696 } /* tcic_set_socket */
697   
698 /*====================================================================*/
699
700 static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
701 {
702     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
703     u_int addr;
704     u_short base, len, ioctl;
705     
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);
713
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;
717     base |= (len+1)>>1;
718     tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
719     tcic_setw(TCIC_DATA, base);
720     
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;
728     }
729     tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
730     tcic_setw(TCIC_DATA, ioctl);
731     
732     return 0;
733 } /* tcic_set_io_map */
734
735 /*====================================================================*/
736
737 static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
738 {
739     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
740     u_short addr, ctl;
741     u_long base, len, mmap;
742
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))
750         return -EINVAL;
751     tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
752     addr = TCIC_MWIN(psock, mem->map);
753
754     base = mem->res->start; len = mem->res->end - mem->res->start;
755     if ((len & (len+1)) || (base & len)) return -EINVAL;
756     if (len == 0x0fff)
757         base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
758     else
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);
762     
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);
768
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);
776     
777     return 0;
778 } /* tcic_set_mem_map */
779
780 /*====================================================================*/
781
782 static int tcic_init(struct pcmcia_socket *s)
783 {
784         int i;
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, };
788
789         for (i = 0; i < 2; i++) {
790                 io.map = i;
791                 tcic_set_io_map(s, &io);
792         }
793         for (i = 0; i < 5; i++) {
794                 mem.map = i;
795                 tcic_set_mem_map(s, &mem);
796         }
797         return 0;
798 }
799
800 static struct pccard_operations tcic_operations = {
801         .init              = tcic_init,
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,
806 };
807
808 /*====================================================================*/
809
810 module_init(init_tcic);
811 module_exit(exit_tcic);