Version:  2.0.40 2.2.26 2.4.37 3.1 3.2 3.3 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

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                 .owner          = THIS_MODULE,
353         },
354 };
355 
356 static struct platform_device tcic_device = {
357         .name = "tcic-pcmcia",
358         .id = 0,
359 };
360 
361 
362 static int __init init_tcic(void)
363 {
364     int i, sock, ret = 0;
365     u_int mask, scan;
366 
367     if (platform_driver_register(&tcic_driver))
368         return -1;
369     
370     printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
371     sock = 0;
372 
373     if (!request_region(tcic_base, 16, "tcic-2")) {
374         printk("could not allocate ports,\n ");
375         platform_driver_unregister(&tcic_driver);
376         return -ENODEV;
377     }
378     else {
379         tcic_setw(TCIC_ADDR, 0);
380         if (tcic_getw(TCIC_ADDR) == 0) {
381             tcic_setw(TCIC_ADDR, 0xc3a5);
382             if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
383         }
384         if (sock == 0) {
385             /* See if resetting the controller does any good */
386             tcic_setb(TCIC_SCTRL, TCIC_SCTRL_RESET);
387             tcic_setb(TCIC_SCTRL, 0);
388             tcic_setw(TCIC_ADDR, 0);
389             if (tcic_getw(TCIC_ADDR) == 0) {
390                 tcic_setw(TCIC_ADDR, 0xc3a5);
391                 if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
392             }
393         }
394     }
395     if (sock == 0) {
396         printk("not found.\n");
397         release_region(tcic_base, 16);
398         platform_driver_unregister(&tcic_driver);
399         return -ENODEV;
400     }
401 
402     sockets = 0;
403     for (i = 0; i < sock; i++) {
404         if ((i == ignore) || is_active(i)) continue;
405         socket_table[sockets].psock = i;
406         socket_table[sockets].id = get_tcic_id();
407 
408         socket_table[sockets].socket.owner = THIS_MODULE;
409         /* only 16-bit cards, memory windows must be size-aligned */
410         /* No PCI or CardBus support */
411         socket_table[sockets].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN;
412         /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
413         socket_table[sockets].socket.irq_mask = 0x4cf8;
414         /* 4K minimum window size */
415         socket_table[sockets].socket.map_size = 0x1000;         
416         sockets++;
417     }
418 
419     switch (socket_table[0].id) {
420     case TCIC_ID_DB86082:
421         printk("DB86082"); break;
422     case TCIC_ID_DB86082A:
423         printk("DB86082A"); break;
424     case TCIC_ID_DB86084:
425         printk("DB86084"); break;
426     case TCIC_ID_DB86084A:
427         printk("DB86084A"); break;
428     case TCIC_ID_DB86072:
429         printk("DB86072"); break;
430     case TCIC_ID_DB86184:
431         printk("DB86184"); break;
432     case TCIC_ID_DB86082B:
433         printk("DB86082B"); break;
434     default:
435         printk("Unknown ID 0x%02x", socket_table[0].id);
436     }
437     
438     /* Set up polling */
439     poll_timer.function = &tcic_timer;
440     poll_timer.data = 0;
441     init_timer(&poll_timer);
442 
443     /* Build interrupt mask */
444     printk(KERN_CONT ", %d sockets\n", sockets);
445     printk(KERN_INFO "  irq list (");
446     if (irq_list_count == 0)
447         mask = irq_mask;
448     else
449         for (i = mask = 0; i < irq_list_count; i++)
450             mask |= (1<<irq_list[i]);
451 
452     /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
453     mask &= 0x4cf8;
454     /* Scan interrupts */
455     mask = irq_scan(mask);
456     for (i=0;i<sockets;i++)
457             socket_table[i].socket.irq_mask = mask;
458     
459     /* Check for only two interrupts available */
460     scan = (mask & (mask-1));
461     if (((scan & (scan-1)) == 0) && (poll_interval == 0))
462         poll_interval = HZ;
463     
464     if (poll_interval == 0) {
465         /* Avoid irq 12 unless it is explicitly requested */
466         u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
467         for (i = 15; i > 0; i--)
468             if ((cs_mask & (1 << i)) &&
469                 (request_irq(i, tcic_interrupt, 0, "tcic",
470                              tcic_interrupt) == 0))
471                 break;
472         cs_irq = i;
473         if (cs_irq == 0) poll_interval = HZ;
474     }
475     
476     if (socket_table[0].socket.irq_mask & (1 << 11))
477         printk("sktirq is irq 11, ");
478     if (cs_irq != 0)
479         printk("status change on irq %d\n", cs_irq);
480     else
481         printk("polled status, interval = %d ms\n",
482                poll_interval * 1000 / HZ);
483     
484     for (i = 0; i < sockets; i++) {
485         tcic_setw(TCIC_ADDR+2, socket_table[i].psock << TCIC_SS_SHFT);
486         socket_table[i].last_sstat = tcic_getb(TCIC_SSTAT);
487     }
488     
489     /* jump start interrupt handler, if needed */
490     tcic_interrupt(0, NULL);
491 
492     platform_device_register(&tcic_device);
493 
494     for (i = 0; i < sockets; i++) {
495             socket_table[i].socket.ops = &tcic_operations;
496             socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
497             socket_table[i].socket.dev.parent = &tcic_device.dev;
498             ret = pcmcia_register_socket(&socket_table[i].socket);
499             if (ret && i)
500                     pcmcia_unregister_socket(&socket_table[0].socket);
501     }
502     
503     return ret;
504 
505     return 0;
506     
507 } /* init_tcic */
508 
509 /*====================================================================*/
510 
511 static void __exit exit_tcic(void)
512 {
513     int i;
514 
515     del_timer_sync(&poll_timer);
516     if (cs_irq != 0) {
517         tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
518         free_irq(cs_irq, tcic_interrupt);
519     }
520     release_region(tcic_base, 16);
521 
522     for (i = 0; i < sockets; i++) {
523             pcmcia_unregister_socket(&socket_table[i].socket);      
524     }
525 
526     platform_device_unregister(&tcic_device);
527     platform_driver_unregister(&tcic_driver);
528 } /* exit_tcic */
529 
530 /*====================================================================*/
531 
532 static irqreturn_t tcic_interrupt(int irq, void *dev)
533 {
534     int i, quick = 0;
535     u_char latch, sstat;
536     u_short psock;
537     u_int events;
538     static volatile int active = 0;
539 
540     if (active) {
541         printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
542         return IRQ_NONE;
543     } else
544         active = 1;
545 
546     pr_debug("tcic_interrupt()\n");
547     
548     for (i = 0; i < sockets; i++) {
549         psock = socket_table[i].psock;
550         tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
551                   | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
552         sstat = tcic_getb(TCIC_SSTAT);
553         latch = sstat ^ socket_table[psock].last_sstat;
554         socket_table[i].last_sstat = sstat;
555         if (tcic_getb(TCIC_ICSR) & TCIC_ICSR_CDCHG) {
556             tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
557             quick = 1;
558         }
559         if (latch == 0)
560             continue;
561         events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
562         events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
563         if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
564             events |= (latch & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
565         } else {
566             events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
567             events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
568             events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
569         }
570         if (events) {
571                 pcmcia_parse_events(&socket_table[i].socket, events);
572         }
573     }
574 
575     /* Schedule next poll, if needed */
576     if (((cs_irq == 0) || quick) && (!tcic_timer_pending)) {
577         poll_timer.expires = jiffies + (quick ? poll_quick : poll_interval);
578         add_timer(&poll_timer);
579         tcic_timer_pending = 1;
580     }
581     active = 0;
582     
583     pr_debug("interrupt done\n");
584     return IRQ_HANDLED;
585 } /* tcic_interrupt */
586 
587 static void tcic_timer(u_long data)
588 {
589     pr_debug("tcic_timer()\n");
590     tcic_timer_pending = 0;
591     tcic_interrupt(0, NULL);
592 } /* tcic_timer */
593 
594 /*====================================================================*/
595 
596 static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
597 {
598     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
599     u_char reg;
600 
601     tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
602               | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
603     reg = tcic_getb(TCIC_SSTAT);
604     *value  = (reg & TCIC_SSTAT_CD) ? SS_DETECT : 0;
605     *value |= (reg & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
606     if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
607         *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
608     } else {
609         *value |= (reg & TCIC_SSTAT_RDY) ? SS_READY : 0;
610         *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
611         *value |= (reg & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
612     }
613     reg = tcic_getb(TCIC_PWR);
614     if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
615         *value |= SS_POWERON;
616     dev_dbg(&sock->dev, "GetStatus(%d) = %#2.2x\n", psock, *value);
617     return 0;
618 } /* tcic_get_status */
619 
620 /*====================================================================*/
621 
622 static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
623 {
624     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
625     u_char reg;
626     u_short scf1, scf2;
627 
628     dev_dbg(&sock->dev, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
629           "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
630           state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
631     tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
632 
633     reg = tcic_getb(TCIC_PWR);
634     reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
635 
636     if (state->Vcc == 50) {
637         switch (state->Vpp) {
638         case 0:   reg |= TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock); break;
639         case 50:  reg |= TCIC_PWR_VCC(psock); break;
640         case 120: reg |= TCIC_PWR_VPP(psock); break;
641         default:  return -EINVAL;
642         }
643     } else if (state->Vcc != 0)
644         return -EINVAL;
645 
646     if (reg != tcic_getb(TCIC_PWR))
647         tcic_setb(TCIC_PWR, reg);
648 
649     reg = TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT;
650     if (state->flags & SS_OUTPUT_ENA) {
651         tcic_setb(TCIC_SCTRL, TCIC_SCTRL_ENA);
652         reg |= TCIC_ILOCK_CRESENA;
653     } else
654         tcic_setb(TCIC_SCTRL, 0);
655     if (state->flags & SS_RESET)
656         reg |= TCIC_ILOCK_CRESET;
657     tcic_aux_setb(TCIC_AUX_ILOCK, reg);
658     
659     tcic_setw(TCIC_ADDR, TCIC_SCF1(psock));
660     scf1 = TCIC_SCF1_FINPACK;
661     scf1 |= TCIC_IRQ(state->io_irq);
662     if (state->flags & SS_IOCARD) {
663         scf1 |= TCIC_SCF1_IOSTS;
664         if (state->flags & SS_SPKR_ENA)
665             scf1 |= TCIC_SCF1_SPKR;
666         if (state->flags & SS_DMA_MODE)
667             scf1 |= TCIC_SCF1_DREQ2 << TCIC_SCF1_DMA_SHIFT;
668     }
669     tcic_setw(TCIC_DATA, scf1);
670 
671     /* Some general setup stuff, and configure status interrupt */
672     reg = TCIC_WAIT_ASYNC | TCIC_WAIT_SENSE | to_cycles(250);
673     tcic_aux_setb(TCIC_AUX_WCTL, reg);
674     tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00|
675                   TCIC_IRQ(cs_irq));
676     
677     /* Card status change interrupt mask */
678     tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
679     scf2 = TCIC_SCF2_MALL;
680     if (state->csc_mask & SS_DETECT) scf2 &= ~TCIC_SCF2_MCD;
681     if (state->flags & SS_IOCARD) {
682         if (state->csc_mask & SS_STSCHG) reg &= ~TCIC_SCF2_MLBAT1;
683     } else {
684         if (state->csc_mask & SS_BATDEAD) reg &= ~TCIC_SCF2_MLBAT1;
685         if (state->csc_mask & SS_BATWARN) reg &= ~TCIC_SCF2_MLBAT2;
686         if (state->csc_mask & SS_READY) reg &= ~TCIC_SCF2_MRDY;
687     }
688     tcic_setw(TCIC_DATA, scf2);
689     /* For the ISA bus, the irq should be active-high totem-pole */
690     tcic_setb(TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
691 
692     return 0;
693 } /* tcic_set_socket */
694   
695 /*====================================================================*/
696 
697 static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
698 {
699     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
700     u_int addr;
701     u_short base, len, ioctl;
702     
703     dev_dbg(&sock->dev, "SetIOMap(%d, %d, %#2.2x, %d ns, "
704           "%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
705           (unsigned long long)io->start, (unsigned long long)io->stop);
706     if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
707         (io->stop < io->start)) return -EINVAL;
708     tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
709     addr = TCIC_IWIN(psock, io->map);
710 
711     base = io->start; len = io->stop - io->start;
712     /* Check to see that len+1 is power of two, etc */
713     if ((len & (len+1)) || (base & len)) return -EINVAL;
714     base |= (len+1)>>1;
715     tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
716     tcic_setw(TCIC_DATA, base);
717     
718     ioctl  = (psock << TCIC_ICTL_SS_SHFT);
719     ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
720     ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
721     ioctl |= to_cycles(io->speed) & TCIC_ICTL_WSCNT_MASK;
722     if (!(io->flags & MAP_AUTOSZ)) {
723         ioctl |= TCIC_ICTL_QUIET;
724         ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
725     }
726     tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
727     tcic_setw(TCIC_DATA, ioctl);
728     
729     return 0;
730 } /* tcic_set_io_map */
731 
732 /*====================================================================*/
733 
734 static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
735 {
736     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
737     u_short addr, ctl;
738     u_long base, len, mmap;
739 
740     dev_dbg(&sock->dev, "SetMemMap(%d, %d, %#2.2x, %d ns, "
741           "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
742           mem->speed, (unsigned long long)mem->res->start,
743           (unsigned long long)mem->res->end, mem->card_start);
744     if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
745         (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) ||
746         (mem->res->start > mem->res->end) || (mem->speed > 1000))
747         return -EINVAL;
748     tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
749     addr = TCIC_MWIN(psock, mem->map);
750 
751     base = mem->res->start; len = mem->res->end - mem->res->start;
752     if ((len & (len+1)) || (base & len)) return -EINVAL;
753     if (len == 0x0fff)
754         base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
755     else
756         base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
757     tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
758     tcic_setw(TCIC_DATA, base);
759     
760     mmap = mem->card_start - mem->res->start;
761     mmap = (mmap >> TCIC_MMAP_CA_SHFT) & TCIC_MMAP_CA_MASK;
762     if (mem->flags & MAP_ATTRIB) mmap |= TCIC_MMAP_REG;
763     tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
764     tcic_setw(TCIC_DATA, mmap);
765 
766     ctl  = TCIC_MCTL_QUIET | (psock << TCIC_MCTL_SS_SHFT);
767     ctl |= to_cycles(mem->speed) & TCIC_MCTL_WSCNT_MASK;
768     ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
769     ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
770     ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
771     tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
772     tcic_setw(TCIC_DATA, ctl);
773     
774     return 0;
775 } /* tcic_set_mem_map */
776 
777 /*====================================================================*/
778 
779 static int tcic_init(struct pcmcia_socket *s)
780 {
781         int i;
782         struct resource res = { .start = 0, .end = 0x1000 };
783         pccard_io_map io = { 0, 0, 0, 0, 1 };
784         pccard_mem_map mem = { .res = &res, };
785 
786         for (i = 0; i < 2; i++) {
787                 io.map = i;
788                 tcic_set_io_map(s, &io);
789         }
790         for (i = 0; i < 5; i++) {
791                 mem.map = i;
792                 tcic_set_mem_map(s, &mem);
793         }
794         return 0;
795 }
796 
797 static struct pccard_operations tcic_operations = {
798         .init              = tcic_init,
799         .get_status        = tcic_get_status,
800         .set_socket        = tcic_set_socket,
801         .set_io_map        = tcic_set_io_map,
802         .set_mem_map       = tcic_set_mem_map,
803 };
804 
805 /*====================================================================*/
806 
807 module_init(init_tcic);
808 module_exit(exit_tcic);
809 

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