root/drivers/pcmcia/tcic.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tcic_getb
  2. tcic_getw
  3. tcic_setb
  4. tcic_setw
  5. tcic_setl
  6. tcic_aux_setb
  7. tcic_aux_getw
  8. tcic_aux_setw
  9. to_cycles
  10. tcic_irq_count
  11. try_irq
  12. irq_scan
  13. is_active
  14. get_tcic_id
  15. init_tcic
  16. exit_tcic
  17. tcic_interrupt
  18. tcic_timer
  19. tcic_get_status
  20. tcic_set_socket
  21. tcic_set_io_map
  22. tcic_set_mem_map
  23. tcic_init

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

/* [<][>][^][v][top][bottom][index][help] */