Linux Audio

Check our new training course

Loading...
v3.1
  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);
v3.5.6
  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);