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