1 /*======================================================================
2
3 Device driver for Databook TCIC-2 PCMCIA controller
4
5 tcic.c 1.111 2000/02/15 04:13:12
6
7 The contents of this file are subject to the Mozilla Public
8 License Version 1.1 (the "License"); you may not use this file
9 except in compliance with the License. You may obtain a copy of
10 the License at http://www.mozilla.org/MPL/
11
12 Software distributed under the License is distributed on an "AS
13 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 implied. See the License for the specific language governing
15 rights and limitations under the License.
16
17 The initial developer of the original code is David A. Hinds
18 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
19 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
20
21 Alternatively, the contents of this file may be used under the
22 terms of the GNU General Public License version 2 (the "GPL"), in which
23 case the provisions of the GPL are applicable instead of the
24 above. If you wish to allow the use of your version of this file
25 only under the terms of the GPL and not to allow others to use
26 your version of this file under the MPL, indicate your decision
27 by deleting the provisions above and replace them with the notice
28 and other provisions required by the GPL. If you do not delete
29 the provisions above, a recipient may use your version of this
30 file under either the MPL or the GPL.
31
32 ======================================================================*/
33
34 #include <linux/module.h>
35 #include <linux/moduleparam.h>
36 #include <linux/init.h>
37 #include <linux/types.h>
38 #include <linux/fcntl.h>
39 #include <linux/string.h>
40 #include <linux/errno.h>
41 #include <linux/interrupt.h>
42 #include <linux/timer.h>
43 #include <linux/ioport.h>
44 #include <linux/delay.h>
45 #include <linux/workqueue.h>
46 #include <linux/platform_device.h>
47 #include <linux/bitops.h>
48
49 #include <asm/io.h>
50
51 #include <pcmcia/ss.h>
52 #include "tcic.h"
53
54 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
55 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
56 MODULE_LICENSE("Dual MPL/GPL");
57
58 /*====================================================================*/
59
60 /* Parameters that can be set with 'insmod' */
61
62 /* The base port address of the TCIC-2 chip */
63 static unsigned long tcic_base = TCIC_BASE;
64
65 /* Specify a socket number to ignore */
66 static int ignore = -1;
67
68 /* Probe for safe interrupts? */
69 static int do_scan = 1;
70
71 /* Bit map of interrupts to choose from */
72 static u_int irq_mask = 0xffff;
73 static int irq_list[16];
74 static unsigned int irq_list_count;
75
76 /* The card status change interrupt -- 0 means autoselect */
77 static int cs_irq;
78
79 /* Poll status interval -- 0 means default to interrupt */
80 static int poll_interval;
81
82 /* Delay for card status double-checking */
83 static int poll_quick = HZ/20;
84
85 /* CCLK external clock time, in nanoseconds. 70 ns = 14.31818 MHz */
86 static int cycle_time = 70;
87
88 module_param(tcic_base, ulong, 0444);
89 module_param(ignore, int, 0444);
90 module_param(do_scan, int, 0444);
91 module_param(irq_mask, int, 0444);
92 module_param_array(irq_list, int, &irq_list_count, 0444);
93 module_param(cs_irq, int, 0444);
94 module_param(poll_interval, int, 0444);
95 module_param(poll_quick, int, 0444);
96 module_param(cycle_time, int, 0444);
97
98 /*====================================================================*/
99
100 static irqreturn_t tcic_interrupt(int irq, void *dev);
101 static void tcic_timer(u_long data);
102 static struct pccard_operations tcic_operations;
103
104 struct tcic_socket {
105 u_short psock;
106 u_char last_sstat;
107 u_char id;
108 struct pcmcia_socket socket;
109 };
110
111 static struct timer_list poll_timer;
112 static int tcic_timer_pending;
113
114 static int sockets;
115 static struct tcic_socket socket_table[2];
116
117 /*====================================================================*/
118
119 /* Trick when selecting interrupts: the TCIC sktirq pin is supposed
120 to map to irq 11, but is coded as 0 or 1 in the irq registers. */
121 #define TCIC_IRQ(x) ((x) ? (((x) == 11) ? 1 : (x)) : 15)
122
123 #ifdef DEBUG_X
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 poll_timer.function = &tcic_timer;
439 poll_timer.data = 0;
440 init_timer(&poll_timer);
441
442 /* Build interrupt mask */
443 printk(KERN_CONT ", %d sockets\n", sockets);
444 printk(KERN_INFO " irq list (");
445 if (irq_list_count == 0)
446 mask = irq_mask;
447 else
448 for (i = mask = 0; i < irq_list_count; i++)
449 mask |= (1<<irq_list[i]);
450
451 /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
452 mask &= 0x4cf8;
453 /* Scan interrupts */
454 mask = irq_scan(mask);
455 for (i=0;i<sockets;i++)
456 socket_table[i].socket.irq_mask = mask;
457
458 /* Check for only two interrupts available */
459 scan = (mask & (mask-1));
460 if (((scan & (scan-1)) == 0) && (poll_interval == 0))
461 poll_interval = HZ;
462
463 if (poll_interval == 0) {
464 /* Avoid irq 12 unless it is explicitly requested */
465 u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
466 for (i = 15; i > 0; i--)
467 if ((cs_mask & (1 << i)) &&
468 (request_irq(i, tcic_interrupt, 0, "tcic",
469 tcic_interrupt) == 0))
470 break;
471 cs_irq = i;
472 if (cs_irq == 0) poll_interval = HZ;
473 }
474
475 if (socket_table[0].socket.irq_mask & (1 << 11))
476 printk("sktirq is irq 11, ");
477 if (cs_irq != 0)
478 printk("status change on irq %d\n", cs_irq);
479 else
480 printk("polled status, interval = %d ms\n",
481 poll_interval * 1000 / HZ);
482
483 for (i = 0; i < sockets; i++) {
484 tcic_setw(TCIC_ADDR+2, socket_table[i].psock << TCIC_SS_SHFT);
485 socket_table[i].last_sstat = tcic_getb(TCIC_SSTAT);
486 }
487
488 /* jump start interrupt handler, if needed */
489 tcic_interrupt(0, NULL);
490
491 platform_device_register(&tcic_device);
492
493 for (i = 0; i < sockets; i++) {
494 socket_table[i].socket.ops = &tcic_operations;
495 socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
496 socket_table[i].socket.dev.parent = &tcic_device.dev;
497 ret = pcmcia_register_socket(&socket_table[i].socket);
498 if (ret && i)
499 pcmcia_unregister_socket(&socket_table[0].socket);
500 }
501
502 return ret;
503
504 return 0;
505
506 } /* init_tcic */
507
508 /*====================================================================*/
509
exit_tcic(void)510 static void __exit exit_tcic(void)
511 {
512 int i;
513
514 del_timer_sync(&poll_timer);
515 if (cs_irq != 0) {
516 tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
517 free_irq(cs_irq, tcic_interrupt);
518 }
519 release_region(tcic_base, 16);
520
521 for (i = 0; i < sockets; i++) {
522 pcmcia_unregister_socket(&socket_table[i].socket);
523 }
524
525 platform_device_unregister(&tcic_device);
526 platform_driver_unregister(&tcic_driver);
527 } /* exit_tcic */
528
529 /*====================================================================*/
530
tcic_interrupt(int irq,void * dev)531 static irqreturn_t tcic_interrupt(int irq, void *dev)
532 {
533 int i, quick = 0;
534 u_char latch, sstat;
535 u_short psock;
536 u_int events;
537 static volatile int active = 0;
538
539 if (active) {
540 printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
541 return IRQ_NONE;
542 } else
543 active = 1;
544
545 pr_debug("tcic_interrupt()\n");
546
547 for (i = 0; i < sockets; i++) {
548 psock = socket_table[i].psock;
549 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
550 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
551 sstat = tcic_getb(TCIC_SSTAT);
552 latch = sstat ^ socket_table[psock].last_sstat;
553 socket_table[i].last_sstat = sstat;
554 if (tcic_getb(TCIC_ICSR) & TCIC_ICSR_CDCHG) {
555 tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
556 quick = 1;
557 }
558 if (latch == 0)
559 continue;
560 events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
561 events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
562 if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
563 events |= (latch & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
564 } else {
565 events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
566 events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
567 events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
568 }
569 if (events) {
570 pcmcia_parse_events(&socket_table[i].socket, events);
571 }
572 }
573
574 /* Schedule next poll, if needed */
575 if (((cs_irq == 0) || quick) && (!tcic_timer_pending)) {
576 poll_timer.expires = jiffies + (quick ? poll_quick : poll_interval);
577 add_timer(&poll_timer);
578 tcic_timer_pending = 1;
579 }
580 active = 0;
581
582 pr_debug("interrupt done\n");
583 return IRQ_HANDLED;
584 } /* tcic_interrupt */
585
tcic_timer(u_long data)586 static void tcic_timer(u_long data)
587 {
588 pr_debug("tcic_timer()\n");
589 tcic_timer_pending = 0;
590 tcic_interrupt(0, NULL);
591 } /* tcic_timer */
592
593 /*====================================================================*/
594
tcic_get_status(struct pcmcia_socket * sock,u_int * value)595 static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
596 {
597 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
598 u_char reg;
599
600 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
601 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
602 reg = tcic_getb(TCIC_SSTAT);
603 *value = (reg & TCIC_SSTAT_CD) ? SS_DETECT : 0;
604 *value |= (reg & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
605 if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
606 *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
607 } else {
608 *value |= (reg & TCIC_SSTAT_RDY) ? SS_READY : 0;
609 *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
610 *value |= (reg & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
611 }
612 reg = tcic_getb(TCIC_PWR);
613 if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
614 *value |= SS_POWERON;
615 dev_dbg(&sock->dev, "GetStatus(%d) = %#2.2x\n", psock, *value);
616 return 0;
617 } /* tcic_get_status */
618
619 /*====================================================================*/
620
tcic_set_socket(struct pcmcia_socket * sock,socket_state_t * state)621 static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
622 {
623 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
624 u_char reg;
625 u_short scf1, scf2;
626
627 dev_dbg(&sock->dev, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
628 "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
629 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
630 tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
631
632 reg = tcic_getb(TCIC_PWR);
633 reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
634
635 if (state->Vcc == 50) {
636 switch (state->Vpp) {
637 case 0: reg |= TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock); break;
638 case 50: reg |= TCIC_PWR_VCC(psock); break;
639 case 120: reg |= TCIC_PWR_VPP(psock); break;
640 default: return -EINVAL;
641 }
642 } else if (state->Vcc != 0)
643 return -EINVAL;
644
645 if (reg != tcic_getb(TCIC_PWR))
646 tcic_setb(TCIC_PWR, reg);
647
648 reg = TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT;
649 if (state->flags & SS_OUTPUT_ENA) {
650 tcic_setb(TCIC_SCTRL, TCIC_SCTRL_ENA);
651 reg |= TCIC_ILOCK_CRESENA;
652 } else
653 tcic_setb(TCIC_SCTRL, 0);
654 if (state->flags & SS_RESET)
655 reg |= TCIC_ILOCK_CRESET;
656 tcic_aux_setb(TCIC_AUX_ILOCK, reg);
657
658 tcic_setw(TCIC_ADDR, TCIC_SCF1(psock));
659 scf1 = TCIC_SCF1_FINPACK;
660 scf1 |= TCIC_IRQ(state->io_irq);
661 if (state->flags & SS_IOCARD) {
662 scf1 |= TCIC_SCF1_IOSTS;
663 if (state->flags & SS_SPKR_ENA)
664 scf1 |= TCIC_SCF1_SPKR;
665 if (state->flags & SS_DMA_MODE)
666 scf1 |= TCIC_SCF1_DREQ2 << TCIC_SCF1_DMA_SHIFT;
667 }
668 tcic_setw(TCIC_DATA, scf1);
669
670 /* Some general setup stuff, and configure status interrupt */
671 reg = TCIC_WAIT_ASYNC | TCIC_WAIT_SENSE | to_cycles(250);
672 tcic_aux_setb(TCIC_AUX_WCTL, reg);
673 tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00|
674 TCIC_IRQ(cs_irq));
675
676 /* Card status change interrupt mask */
677 tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
678 scf2 = TCIC_SCF2_MALL;
679 if (state->csc_mask & SS_DETECT) scf2 &= ~TCIC_SCF2_MCD;
680 if (state->flags & SS_IOCARD) {
681 if (state->csc_mask & SS_STSCHG) reg &= ~TCIC_SCF2_MLBAT1;
682 } else {
683 if (state->csc_mask & SS_BATDEAD) reg &= ~TCIC_SCF2_MLBAT1;
684 if (state->csc_mask & SS_BATWARN) reg &= ~TCIC_SCF2_MLBAT2;
685 if (state->csc_mask & SS_READY) reg &= ~TCIC_SCF2_MRDY;
686 }
687 tcic_setw(TCIC_DATA, scf2);
688 /* For the ISA bus, the irq should be active-high totem-pole */
689 tcic_setb(TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
690
691 return 0;
692 } /* tcic_set_socket */
693
694 /*====================================================================*/
695
tcic_set_io_map(struct pcmcia_socket * sock,struct pccard_io_map * io)696 static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
697 {
698 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
699 u_int addr;
700 u_short base, len, ioctl;
701
702 dev_dbg(&sock->dev, "SetIOMap(%d, %d, %#2.2x, %d ns, "
703 "%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
704 (unsigned long long)io->start, (unsigned long long)io->stop);
705 if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
706 (io->stop < io->start)) return -EINVAL;
707 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
708 addr = TCIC_IWIN(psock, io->map);
709
710 base = io->start; len = io->stop - io->start;
711 /* Check to see that len+1 is power of two, etc */
712 if ((len & (len+1)) || (base & len)) return -EINVAL;
713 base |= (len+1)>>1;
714 tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
715 tcic_setw(TCIC_DATA, base);
716
717 ioctl = (psock << TCIC_ICTL_SS_SHFT);
718 ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
719 ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
720 ioctl |= to_cycles(io->speed) & TCIC_ICTL_WSCNT_MASK;
721 if (!(io->flags & MAP_AUTOSZ)) {
722 ioctl |= TCIC_ICTL_QUIET;
723 ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
724 }
725 tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
726 tcic_setw(TCIC_DATA, ioctl);
727
728 return 0;
729 } /* tcic_set_io_map */
730
731 /*====================================================================*/
732
tcic_set_mem_map(struct pcmcia_socket * sock,struct pccard_mem_map * mem)733 static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
734 {
735 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
736 u_short addr, ctl;
737 u_long base, len, mmap;
738
739 dev_dbg(&sock->dev, "SetMemMap(%d, %d, %#2.2x, %d ns, "
740 "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
741 mem->speed, (unsigned long long)mem->res->start,
742 (unsigned long long)mem->res->end, mem->card_start);
743 if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
744 (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) ||
745 (mem->res->start > mem->res->end) || (mem->speed > 1000))
746 return -EINVAL;
747 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
748 addr = TCIC_MWIN(psock, mem->map);
749
750 base = mem->res->start; len = mem->res->end - mem->res->start;
751 if ((len & (len+1)) || (base & len)) return -EINVAL;
752 if (len == 0x0fff)
753 base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
754 else
755 base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
756 tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
757 tcic_setw(TCIC_DATA, base);
758
759 mmap = mem->card_start - mem->res->start;
760 mmap = (mmap >> TCIC_MMAP_CA_SHFT) & TCIC_MMAP_CA_MASK;
761 if (mem->flags & MAP_ATTRIB) mmap |= TCIC_MMAP_REG;
762 tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
763 tcic_setw(TCIC_DATA, mmap);
764
765 ctl = TCIC_MCTL_QUIET | (psock << TCIC_MCTL_SS_SHFT);
766 ctl |= to_cycles(mem->speed) & TCIC_MCTL_WSCNT_MASK;
767 ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
768 ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
769 ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
770 tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
771 tcic_setw(TCIC_DATA, ctl);
772
773 return 0;
774 } /* tcic_set_mem_map */
775
776 /*====================================================================*/
777
tcic_init(struct pcmcia_socket * s)778 static int tcic_init(struct pcmcia_socket *s)
779 {
780 int i;
781 struct resource res = { .start = 0, .end = 0x1000 };
782 pccard_io_map io = { 0, 0, 0, 0, 1 };
783 pccard_mem_map mem = { .res = &res, };
784
785 for (i = 0; i < 2; i++) {
786 io.map = i;
787 tcic_set_io_map(s, &io);
788 }
789 for (i = 0; i < 5; i++) {
790 mem.map = i;
791 tcic_set_mem_map(s, &mem);
792 }
793 return 0;
794 }
795
796 static struct pccard_operations tcic_operations = {
797 .init = tcic_init,
798 .get_status = tcic_get_status,
799 .set_socket = tcic_set_socket,
800 .set_io_map = tcic_set_io_map,
801 .set_mem_map = tcic_set_mem_map,
802 };
803
804 /*====================================================================*/
805
806 module_init(init_tcic);
807 module_exit(exit_tcic);
808