Version:  2.0.40 2.2.26 2.4.37 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us