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