Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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