in tcic.c [361:504]
static int __init init_tcic(void)
{
int i, sock, ret = 0;
u_int mask, scan;
if (platform_driver_register(&tcic_driver))
return -1;
printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
sock = 0;
if (!request_region(tcic_base, 16, "tcic-2")) {
printk("could not allocate ports,\n ");
platform_driver_unregister(&tcic_driver);
return -ENODEV;
}
else {
tcic_setw(TCIC_ADDR, 0);
if (tcic_getw(TCIC_ADDR) == 0) {
tcic_setw(TCIC_ADDR, 0xc3a5);
if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
}
if (sock == 0) {
/* See if resetting the controller does any good */
tcic_setb(TCIC_SCTRL, TCIC_SCTRL_RESET);
tcic_setb(TCIC_SCTRL, 0);
tcic_setw(TCIC_ADDR, 0);
if (tcic_getw(TCIC_ADDR) == 0) {
tcic_setw(TCIC_ADDR, 0xc3a5);
if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
}
}
}
if (sock == 0) {
printk("not found.\n");
release_region(tcic_base, 16);
platform_driver_unregister(&tcic_driver);
return -ENODEV;
}
sockets = 0;
for (i = 0; i < sock; i++) {
if ((i == ignore) || is_active(i)) continue;
socket_table[sockets].psock = i;
socket_table[sockets].id = get_tcic_id();
socket_table[sockets].socket.owner = THIS_MODULE;
/* only 16-bit cards, memory windows must be size-aligned */
/* No PCI or CardBus support */
socket_table[sockets].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN;
/* irq 14, 11, 10, 7, 6, 5, 4, 3 */
socket_table[sockets].socket.irq_mask = 0x4cf8;
/* 4K minimum window size */
socket_table[sockets].socket.map_size = 0x1000;
sockets++;
}
switch (socket_table[0].id) {
case TCIC_ID_DB86082:
printk("DB86082"); break;
case TCIC_ID_DB86082A:
printk("DB86082A"); break;
case TCIC_ID_DB86084:
printk("DB86084"); break;
case TCIC_ID_DB86084A:
printk("DB86084A"); break;
case TCIC_ID_DB86072:
printk("DB86072"); break;
case TCIC_ID_DB86184:
printk("DB86184"); break;
case TCIC_ID_DB86082B:
printk("DB86082B"); break;
default:
printk("Unknown ID 0x%02x", socket_table[0].id);
}
/* Set up polling */
timer_setup(&poll_timer, &tcic_timer, 0);
/* Build interrupt mask */
printk(KERN_CONT ", %d sockets\n", sockets);
printk(KERN_INFO " irq list (");
if (irq_list_count == 0)
mask = irq_mask;
else
for (i = mask = 0; i < irq_list_count; i++)
mask |= (1<<irq_list[i]);
/* irq 14, 11, 10, 7, 6, 5, 4, 3 */
mask &= 0x4cf8;
/* Scan interrupts */
mask = irq_scan(mask);
for (i=0;i<sockets;i++)
socket_table[i].socket.irq_mask = mask;
/* Check for only two interrupts available */
scan = (mask & (mask-1));
if (((scan & (scan-1)) == 0) && (poll_interval == 0))
poll_interval = HZ;
if (poll_interval == 0) {
/* Avoid irq 12 unless it is explicitly requested */
u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
for (i = 15; i > 0; i--)
if ((cs_mask & (1 << i)) &&
(request_irq(i, tcic_interrupt, 0, "tcic",
tcic_interrupt) == 0))
break;
cs_irq = i;
if (cs_irq == 0) poll_interval = HZ;
}
if (socket_table[0].socket.irq_mask & (1 << 11))
printk("sktirq is irq 11, ");
if (cs_irq != 0)
printk("status change on irq %d\n", cs_irq);
else
printk("polled status, interval = %d ms\n",
poll_interval * 1000 / HZ);
for (i = 0; i < sockets; i++) {
tcic_setw(TCIC_ADDR+2, socket_table[i].psock << TCIC_SS_SHFT);
socket_table[i].last_sstat = tcic_getb(TCIC_SSTAT);
}
/* jump start interrupt handler, if needed */
tcic_interrupt(0, NULL);
platform_device_register(&tcic_device);
for (i = 0; i < sockets; i++) {
socket_table[i].socket.ops = &tcic_operations;
socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
socket_table[i].socket.dev.parent = &tcic_device.dev;
ret = pcmcia_register_socket(&socket_table[i].socket);
if (ret && i)
pcmcia_unregister_socket(&socket_table[0].socket);
}
return ret;
return 0;
} /* init_tcic */