1
/*======================================================================
3
Device driver for Databook TCIC-2 PCMCIA controller
5
tcic.c 1.111 2000/02/15 04:13:12
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/
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.
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.
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.
32
======================================================================*/
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>
50
#include <asm/system.h>
52
#include <pcmcia/ss.h>
55
MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
56
MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
57
MODULE_LICENSE("Dual MPL/GPL");
59
/*====================================================================*/
61
/* Parameters that can be set with 'insmod' */
63
/* The base port address of the TCIC-2 chip */
64
static unsigned long tcic_base = TCIC_BASE;
66
/* Specify a socket number to ignore */
67
static int ignore = -1;
69
/* Probe for safe interrupts? */
70
static int do_scan = 1;
72
/* Bit map of interrupts to choose from */
73
static u_int irq_mask = 0xffff;
74
static int irq_list[16];
75
static unsigned int irq_list_count;
77
/* The card status change interrupt -- 0 means autoselect */
80
/* Poll status interval -- 0 means default to interrupt */
81
static int poll_interval;
83
/* Delay for card status double-checking */
84
static int poll_quick = HZ/20;
86
/* CCLK external clock time, in nanoseconds. 70 ns = 14.31818 MHz */
87
static int cycle_time = 70;
89
module_param(tcic_base, ulong, 0444);
90
module_param(ignore, int, 0444);
91
module_param(do_scan, int, 0444);
92
module_param(irq_mask, int, 0444);
93
module_param_array(irq_list, int, &irq_list_count, 0444);
94
module_param(cs_irq, int, 0444);
95
module_param(poll_interval, int, 0444);
96
module_param(poll_quick, int, 0444);
97
module_param(cycle_time, int, 0444);
99
/*====================================================================*/
101
static irqreturn_t tcic_interrupt(int irq, void *dev);
102
static void tcic_timer(u_long data);
103
static struct pccard_operations tcic_operations;
109
struct pcmcia_socket socket;
112
static struct timer_list poll_timer;
113
static int tcic_timer_pending;
116
static struct tcic_socket socket_table[2];
118
/*====================================================================*/
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)
125
static u_char tcic_getb(u_char reg)
127
u_char val = inb(tcic_base+reg);
128
printk(KERN_DEBUG "tcic_getb(%#lx) = %#x\n", tcic_base+reg, val);
132
static u_short tcic_getw(u_char reg)
134
u_short val = inw(tcic_base+reg);
135
printk(KERN_DEBUG "tcic_getw(%#lx) = %#x\n", tcic_base+reg, val);
139
static void tcic_setb(u_char reg, u_char data)
141
printk(KERN_DEBUG "tcic_setb(%#lx, %#x)\n", tcic_base+reg, data);
142
outb(data, tcic_base+reg);
145
static void tcic_setw(u_char reg, u_short data)
147
printk(KERN_DEBUG "tcic_setw(%#lx, %#x)\n", tcic_base+reg, data);
148
outw(data, tcic_base+reg);
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)
157
static void tcic_setl(u_char reg, u_int data)
160
printk(KERN_DEBUG "tcic_setl(%#x, %#lx)\n", tcic_base+reg, data);
162
outw(data & 0xffff, tcic_base+reg);
163
outw(data >> 16, tcic_base+reg+2);
166
static void tcic_aux_setb(u_short reg, u_char data)
168
u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
169
tcic_setb(TCIC_MODE, mode);
170
tcic_setb(TCIC_AUX, data);
173
static u_short tcic_aux_getw(u_short reg)
175
u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
176
tcic_setb(TCIC_MODE, mode);
177
return tcic_getw(TCIC_AUX);
180
static void tcic_aux_setw(u_short reg, u_short data)
182
u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
183
tcic_setb(TCIC_MODE, mode);
184
tcic_setw(TCIC_AUX, data);
187
/*====================================================================*/
189
/* Time conversion functions */
191
static int to_cycles(int ns)
196
return 2*(ns-14)/cycle_time;
199
/*====================================================================*/
201
static volatile u_int irq_hits;
203
static irqreturn_t __init tcic_irq_count(int irq, void *dev)
209
static u_int __init try_irq(int irq)
214
if (request_irq(irq, tcic_irq_count, 0, "irq scan", tcic_irq_count) != 0)
218
free_irq(irq, tcic_irq_count);
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);
229
free_irq(irq, tcic_irq_count);
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);
237
return (irq_hits != 1);
240
static u_int __init irq_scan(u_int mask0)
247
/* Don't probe level-triggered interrupts -- reserved for PCI */
248
int level_mask = inb_p(PIC) | (inb_p(PIC+1) << 8);
250
mask0 &= ~level_mask;
255
for (i = 0; i < 16; i++)
256
if ((mask0 & (1 << i)) && (try_irq(i) == 0))
258
for (i = 0; i < 16; i++)
259
if ((mask1 & (1 << i)) && (try_irq(i) != 0)) {
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)) {
272
free_irq(i, tcic_irq_count);
278
for (i = 0; i < 16; i++)
280
printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
286
/*======================================================================
288
See if a card is present, powered up, in IO mode, and already
289
bound to a (non-PCMCIA) Linux driver.
291
We make an exception for cards that look like serial devices.
293
======================================================================*/
295
static int __init is_active(int s)
297
u_short scf1, ioctl, base, num;
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);
312
if (ioctl & TCIC_ICTL_TINY)
315
num = (base ^ (base-1));
316
base = base & (base-1);
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 */
325
release_region(base, num);
331
/*======================================================================
333
This returns the revision code for the specified socket.
335
======================================================================*/
337
static int __init get_tcic_id(void)
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);
348
/*====================================================================*/
350
static struct platform_driver tcic_driver = {
352
.name = "tcic-pcmcia",
353
.owner = THIS_MODULE,
357
static struct platform_device tcic_device = {
358
.name = "tcic-pcmcia",
363
static int __init init_tcic(void)
365
int i, sock, ret = 0;
368
if (platform_driver_register(&tcic_driver))
371
printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
374
if (!request_region(tcic_base, 16, "tcic-2")) {
375
printk("could not allocate ports,\n ");
376
platform_driver_unregister(&tcic_driver);
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;
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;
397
printk("not found.\n");
398
release_region(tcic_base, 16);
399
platform_driver_unregister(&tcic_driver);
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();
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;
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;
436
printk("Unknown ID 0x%02x", socket_table[0].id);
440
poll_timer.function = &tcic_timer;
442
init_timer(&poll_timer);
444
/* Build interrupt mask */
445
printk(KERN_CONT ", %d sockets\n", sockets);
446
printk(KERN_INFO " irq list (");
447
if (irq_list_count == 0)
450
for (i = mask = 0; i < irq_list_count; i++)
451
mask |= (1<<irq_list[i]);
453
/* irq 14, 11, 10, 7, 6, 5, 4, 3 */
455
/* Scan interrupts */
456
mask = irq_scan(mask);
457
for (i=0;i<sockets;i++)
458
socket_table[i].socket.irq_mask = mask;
460
/* Check for only two interrupts available */
461
scan = (mask & (mask-1));
462
if (((scan & (scan-1)) == 0) && (poll_interval == 0))
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))
474
if (cs_irq == 0) poll_interval = HZ;
477
if (socket_table[0].socket.irq_mask & (1 << 11))
478
printk("sktirq is irq 11, ");
480
printk("status change on irq %d\n", cs_irq);
482
printk("polled status, interval = %d ms\n",
483
poll_interval * 1000 / HZ);
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);
490
/* jump start interrupt handler, if needed */
491
tcic_interrupt(0, NULL);
493
platform_device_register(&tcic_device);
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);
501
pcmcia_unregister_socket(&socket_table[0].socket);
510
/*====================================================================*/
512
static void __exit exit_tcic(void)
516
del_timer_sync(&poll_timer);
518
tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
519
free_irq(cs_irq, tcic_interrupt);
521
release_region(tcic_base, 16);
523
for (i = 0; i < sockets; i++) {
524
pcmcia_unregister_socket(&socket_table[i].socket);
527
platform_device_unregister(&tcic_device);
528
platform_driver_unregister(&tcic_driver);
531
/*====================================================================*/
533
static irqreturn_t tcic_interrupt(int irq, void *dev)
539
static volatile int active = 0;
542
printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
547
pr_debug("tcic_interrupt()\n");
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);
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;
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;
572
pcmcia_parse_events(&socket_table[i].socket, events);
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;
584
pr_debug("interrupt done\n");
586
} /* tcic_interrupt */
588
static void tcic_timer(u_long data)
590
pr_debug("tcic_timer()\n");
591
tcic_timer_pending = 0;
592
tcic_interrupt(0, NULL);
595
/*====================================================================*/
597
static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
599
u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
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;
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;
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);
619
} /* tcic_get_status */
621
/*====================================================================*/
623
static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
625
u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
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);
634
reg = tcic_getb(TCIC_PWR);
635
reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
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;
644
} else if (state->Vcc != 0)
647
if (reg != tcic_getb(TCIC_PWR))
648
tcic_setb(TCIC_PWR, reg);
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;
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);
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;
670
tcic_setw(TCIC_DATA, scf1);
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|
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;
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;
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);
694
} /* tcic_set_socket */
696
/*====================================================================*/
698
static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
700
u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
702
u_short base, len, ioctl;
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);
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;
716
tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
717
tcic_setw(TCIC_DATA, base);
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;
727
tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
728
tcic_setw(TCIC_DATA, ioctl);
731
} /* tcic_set_io_map */
733
/*====================================================================*/
735
static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
737
u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
739
u_long base, len, mmap;
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))
749
tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
750
addr = TCIC_MWIN(psock, mem->map);
752
base = mem->res->start; len = mem->res->end - mem->res->start;
753
if ((len & (len+1)) || (base & len)) return -EINVAL;
755
base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
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);
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);
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);
776
} /* tcic_set_mem_map */
778
/*====================================================================*/
780
static int tcic_init(struct pcmcia_socket *s)
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, };
787
for (i = 0; i < 2; i++) {
789
tcic_set_io_map(s, &io);
791
for (i = 0; i < 5; i++) {
793
tcic_set_mem_map(s, &mem);
798
static struct pccard_operations tcic_operations = {
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,
806
/*====================================================================*/
808
module_init(init_tcic);
809
module_exit(exit_tcic);