• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
tcic_getb(u_char reg)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 
tcic_getw(u_char reg)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 
tcic_setb(u_char reg,u_char data)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 
tcic_setw(u_char reg,u_short data)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 
tcic_setl(u_char reg,u_int data)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 
tcic_aux_setb(u_short reg,u_char data)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 
tcic_aux_getw(u_short reg)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 
tcic_aux_setw(u_short reg,u_short data)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 
to_cycles(int ns)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 
tcic_irq_count(int irq,void * dev)202 static irqreturn_t __init tcic_irq_count(int irq, void *dev)
203 {
204     irq_hits++;
205     return IRQ_HANDLED;
206 }
207 
try_irq(int irq)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 
irq_scan(u_int mask0)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 
is_active(int s)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 
get_tcic_id(void)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 
init_tcic(void)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 
exit_tcic(void)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 
tcic_interrupt(int irq,void * dev)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 
tcic_timer(struct timer_list * unused)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 
tcic_get_status(struct pcmcia_socket * sock,u_int * value)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 
tcic_set_socket(struct pcmcia_socket * sock,socket_state_t * state)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 
tcic_set_io_map(struct pcmcia_socket * sock,struct pccard_io_map * io)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 
tcic_set_mem_map(struct pcmcia_socket * sock,struct pccard_mem_map * mem)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 
tcic_init(struct pcmcia_socket * s)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);
806