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