OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [pcmcia/] [i82365.c] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*======================================================================
2
 
3
    Device driver for Intel 82365 and compatible PC Card controllers.
4
 
5
    i82365.c 1.265 1999/11/10 18:36:21
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/init.h>
36
#include <linux/config.h>
37
#include <linux/types.h>
38
#include <linux/fcntl.h>
39
#include <linux/string.h>
40
#include <linux/kernel.h>
41
#include <linux/errno.h>
42
#include <linux/timer.h>
43
#include <linux/sched.h>
44
#include <linux/slab.h>
45
#include <linux/ioport.h>
46
#include <linux/delay.h>
47
#include <linux/proc_fs.h>
48
#include <asm/irq.h>
49
#include <asm/io.h>
50
#include <asm/bitops.h>
51
#include <asm/segment.h>
52
#include <asm/system.h>
53
 
54
#include <pcmcia/version.h>
55
#include <pcmcia/cs_types.h>
56
#include <pcmcia/ss.h>
57
#include <pcmcia/cs.h>
58
 
59
#include <linux/isapnp.h>
60
 
61
/* ISA-bus controllers */
62
#include "i82365.h"
63
#include "cirrus.h"
64
#include "vg468.h"
65
#include "ricoh.h"
66
#include "o2micro.h"
67
 
68
#ifdef PCMCIA_DEBUG
69
static int pc_debug = PCMCIA_DEBUG;
70
MODULE_PARM(pc_debug, "i");
71
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
72
static const char *version =
73
"i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)";
74
#else
75
#define DEBUG(n, args...) do { } while (0)
76
#endif
77
 
78
static void irq_count(int, void *, struct pt_regs *);
79
static inline int _check_irq(int irq, int flags)
80
{
81
    if (request_irq(irq, irq_count, flags, "x", irq_count) != 0)
82
        return -1;
83
    free_irq(irq, irq_count);
84
    return 0;
85
}
86
 
87
/*====================================================================*/
88
 
89
/* Parameters that can be set with 'insmod' */
90
 
91
/* Default base address for i82365sl and other ISA chips */
92
static int i365_base = 0x3e0;
93
/* Should we probe at 0x3e2 for an extra ISA controller? */
94
static int extra_sockets = 0;
95
/* Specify a socket number to ignore */
96
static int ignore = -1;
97
/* Bit map or list of interrupts to choose from */
98
static u_int irq_mask = 0xffff;
99
static int irq_list[16] = { -1 };
100
/* The card status change interrupt -- 0 means autoselect */
101
static int cs_irq = 0;
102
 
103
/* Probe for safe interrupts? */
104
static int do_scan = 1;
105
/* Poll status interval -- 0 means default to interrupt */
106
static int poll_interval = 0;
107
/* External clock time, in nanoseconds.  120 ns = 8.33 MHz */
108
static int cycle_time = 120;
109
 
110
/* Cirrus options */
111
static int has_dma = -1;
112
static int has_led = -1;
113
static int has_ring = -1;
114
static int dynamic_mode = 0;
115
static int freq_bypass = -1;
116
static int setup_time = -1;
117
static int cmd_time = -1;
118
static int recov_time = -1;
119
 
120
/* Vadem options */
121
static int async_clock = -1;
122
static int cable_mode = -1;
123
static int wakeup = 0;
124
 
125
MODULE_PARM(i365_base, "i");
126
MODULE_PARM(ignore, "i");
127
MODULE_PARM(extra_sockets, "i");
128
MODULE_PARM(irq_mask, "i");
129
MODULE_PARM(irq_list, "1-16i");
130
MODULE_PARM(cs_irq, "i");
131
MODULE_PARM(async_clock, "i");
132
MODULE_PARM(cable_mode, "i");
133
MODULE_PARM(wakeup, "i");
134
 
135
MODULE_PARM(do_scan, "i");
136
MODULE_PARM(poll_interval, "i");
137
MODULE_PARM(cycle_time, "i");
138
MODULE_PARM(has_dma, "i");
139
MODULE_PARM(has_led, "i");
140
MODULE_PARM(has_ring, "i");
141
MODULE_PARM(dynamic_mode, "i");
142
MODULE_PARM(freq_bypass, "i");
143
MODULE_PARM(setup_time, "i");
144
MODULE_PARM(cmd_time, "i");
145
MODULE_PARM(recov_time, "i");
146
 
147
/*====================================================================*/
148
 
149
typedef struct cirrus_state_t {
150
    u_char              misc1, misc2;
151
    u_char              timer[6];
152
} cirrus_state_t;
153
 
154
typedef struct vg46x_state_t {
155
    u_char              ctl, ema;
156
} vg46x_state_t;
157
 
158
typedef struct socket_info_t {
159
    u_short             type, flags;
160
    socket_cap_t        cap;
161
    ioaddr_t            ioaddr;
162
    u_short             psock;
163
    u_char              cs_irq, intr;
164
    void                (*handler)(void *info, u_int events);
165
    void                *info;
166
#ifdef CONFIG_PROC_FS
167
    struct proc_dir_entry *proc;
168
#endif
169
    union {
170
        cirrus_state_t          cirrus;
171
        vg46x_state_t           vg46x;
172
    } state;
173
} socket_info_t;
174
 
175
/* Where we keep track of our sockets... */
176
static int sockets = 0;
177
static socket_info_t socket[8] = {
178
    { 0, }, /* ... */
179
};
180
 
181
/* Default ISA interrupt mask */
182
#define I365_MASK       0xdeb8  /* irq 15,14,12,11,10,9,7,5,4,3 */
183
 
184
static int grab_irq;
185
static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED;
186
#define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f)
187
#define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f)
188
 
189
static struct timer_list poll_timer;
190
 
191
/*====================================================================*/
192
 
193
/* These definitions must match the pcic table! */
194
typedef enum pcic_id {
195
    IS_I82365A, IS_I82365B, IS_I82365DF,
196
    IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469,
197
    IS_PD6710, IS_PD672X, IS_VT83C469,
198
} pcic_id;
199
 
200
/* Flags for classifying groups of controllers */
201
#define IS_VADEM        0x0001
202
#define IS_CIRRUS       0x0002
203
#define IS_VIA          0x0010
204
#define IS_UNKNOWN      0x0400
205
#define IS_VG_PWR       0x0800
206
#define IS_DF_PWR       0x1000
207
#define IS_ALIVE        0x8000
208
 
209
typedef struct pcic_t {
210
    char                *name;
211
    u_short             flags;
212
} pcic_t;
213
 
214
static pcic_t pcic[] = {
215
    { "Intel i82365sl A step", 0 },
216
    { "Intel i82365sl B step", 0 },
217
    { "Intel i82365sl DF", IS_DF_PWR },
218
    { "IBM Clone", 0 },
219
    { "Ricoh RF5C296/396", 0 },
220
    { "VLSI 82C146", 0 },
221
    { "Vadem VG-468", IS_VADEM },
222
    { "Vadem VG-469", IS_VADEM|IS_VG_PWR },
223
    { "Cirrus PD6710", IS_CIRRUS },
224
    { "Cirrus PD672x", IS_CIRRUS },
225
    { "VIA VT83C469", IS_CIRRUS|IS_VIA },
226
};
227
 
228
#define PCIC_COUNT      (sizeof(pcic)/sizeof(pcic_t))
229
 
230
/*====================================================================*/
231
 
232
static spinlock_t bus_lock = SPIN_LOCK_UNLOCKED;
233
 
234
static u_char i365_get(u_short sock, u_short reg)
235
{
236
    unsigned long flags;
237
    spin_lock_irqsave(&bus_lock,flags);
238
    {
239
        ioaddr_t port = socket[sock].ioaddr;
240
        u_char val;
241
        reg = I365_REG(socket[sock].psock, reg);
242
        outb(reg, port); val = inb(port+1);
243
        spin_unlock_irqrestore(&bus_lock,flags);
244
        return val;
245
    }
246
}
247
 
248
static void i365_set(u_short sock, u_short reg, u_char data)
249
{
250
    unsigned long flags;
251
    spin_lock_irqsave(&bus_lock,flags);
252
    {
253
        ioaddr_t port = socket[sock].ioaddr;
254
        u_char val = I365_REG(socket[sock].psock, reg);
255
        outb(val, port); outb(data, port+1);
256
        spin_unlock_irqrestore(&bus_lock,flags);
257
    }
258
}
259
 
260
static void i365_bset(u_short sock, u_short reg, u_char mask)
261
{
262
    u_char d = i365_get(sock, reg);
263
    d |= mask;
264
    i365_set(sock, reg, d);
265
}
266
 
267
static void i365_bclr(u_short sock, u_short reg, u_char mask)
268
{
269
    u_char d = i365_get(sock, reg);
270
    d &= ~mask;
271
    i365_set(sock, reg, d);
272
}
273
 
274
static void i365_bflip(u_short sock, u_short reg, u_char mask, int b)
275
{
276
    u_char d = i365_get(sock, reg);
277
    if (b)
278
        d |= mask;
279
    else
280
        d &= ~mask;
281
    i365_set(sock, reg, d);
282
}
283
 
284
static u_short i365_get_pair(u_short sock, u_short reg)
285
{
286
    u_short a, b;
287
    a = i365_get(sock, reg);
288
    b = i365_get(sock, reg+1);
289
    return (a + (b<<8));
290
}
291
 
292
static void i365_set_pair(u_short sock, u_short reg, u_short data)
293
{
294
    i365_set(sock, reg, data & 0xff);
295
    i365_set(sock, reg+1, data >> 8);
296
}
297
 
298
/*======================================================================
299
 
300
    Code to save and restore global state information for Cirrus
301
    PD67xx controllers, and to set and report global configuration
302
    options.
303
 
304
    The VIA controllers also use these routines, as they are mostly
305
    Cirrus lookalikes, without the timing registers.
306
 
307
======================================================================*/
308
 
309
#define flip(v,b,f) (v = ((f)<0) ? v : ((f) ? ((v)|(b)) : ((v)&(~b))))
310
 
311
static void cirrus_get_state(u_short s)
312
{
313
    int i;
314
    cirrus_state_t *p = &socket[s].state.cirrus;
315
    p->misc1 = i365_get(s, PD67_MISC_CTL_1);
316
    p->misc1 &= (PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
317
    p->misc2 = i365_get(s, PD67_MISC_CTL_2);
318
    for (i = 0; i < 6; i++)
319
        p->timer[i] = i365_get(s, PD67_TIME_SETUP(0)+i);
320
}
321
 
322
static void cirrus_set_state(u_short s)
323
{
324
    int i;
325
    u_char misc;
326
    cirrus_state_t *p = &socket[s].state.cirrus;
327
 
328
    misc = i365_get(s, PD67_MISC_CTL_2);
329
    i365_set(s, PD67_MISC_CTL_2, p->misc2);
330
    if (misc & PD67_MC2_SUSPEND) mdelay(50);
331
    misc = i365_get(s, PD67_MISC_CTL_1);
332
    misc &= ~(PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
333
    i365_set(s, PD67_MISC_CTL_1, misc | p->misc1);
334
    for (i = 0; i < 6; i++)
335
        i365_set(s, PD67_TIME_SETUP(0)+i, p->timer[i]);
336
}
337
 
338
static u_int __init cirrus_set_opts(u_short s, char *buf)
339
{
340
    socket_info_t *t = &socket[s];
341
    cirrus_state_t *p = &socket[s].state.cirrus;
342
    u_int mask = 0xffff;
343
 
344
    if (has_ring == -1) has_ring = 1;
345
    flip(p->misc2, PD67_MC2_IRQ15_RI, has_ring);
346
    flip(p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode);
347
    flip(p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
348
    if (p->misc2 & PD67_MC2_IRQ15_RI)
349
        strcat(buf, " [ring]");
350
    if (p->misc2 & PD67_MC2_DYNAMIC_MODE)
351
        strcat(buf, " [dyn mode]");
352
    if (p->misc2 & PD67_MC2_FREQ_BYPASS)
353
        strcat(buf, " [freq bypass]");
354
    if (p->misc1 & PD67_MC1_INPACK_ENA)
355
        strcat(buf, " [inpack]");
356
    if (p->misc2 & PD67_MC2_IRQ15_RI)
357
        mask &= ~0x8000;
358
    if (has_led > 0) {
359
        strcat(buf, " [led]");
360
        mask &= ~0x1000;
361
    }
362
    if (has_dma > 0) {
363
        strcat(buf, " [dma]");
364
        mask &= ~0x0600;
365
    }
366
    if (!(t->flags & IS_VIA)) {
367
        if (setup_time >= 0)
368
            p->timer[0] = p->timer[3] = setup_time;
369
        if (cmd_time > 0) {
370
            p->timer[1] = cmd_time;
371
            p->timer[4] = cmd_time*2+4;
372
        }
373
        if (p->timer[1] == 0) {
374
            p->timer[1] = 6; p->timer[4] = 16;
375
            if (p->timer[0] == 0)
376
                p->timer[0] = p->timer[3] = 1;
377
        }
378
        if (recov_time >= 0)
379
            p->timer[2] = p->timer[5] = recov_time;
380
        buf += strlen(buf);
381
        sprintf(buf, " [%d/%d/%d] [%d/%d/%d]", p->timer[0], p->timer[1],
382
                p->timer[2], p->timer[3], p->timer[4], p->timer[5]);
383
    }
384
    return mask;
385
}
386
 
387
/*======================================================================
388
 
389
    Code to save and restore global state information for Vadem VG468
390
    and VG469 controllers, and to set and report global configuration
391
    options.
392
 
393
======================================================================*/
394
 
395
static void vg46x_get_state(u_short s)
396
{
397
    vg46x_state_t *p = &socket[s].state.vg46x;
398
    p->ctl = i365_get(s, VG468_CTL);
399
    if (socket[s].type == IS_VG469)
400
        p->ema = i365_get(s, VG469_EXT_MODE);
401
}
402
 
403
static void vg46x_set_state(u_short s)
404
{
405
    vg46x_state_t *p = &socket[s].state.vg46x;
406
    i365_set(s, VG468_CTL, p->ctl);
407
    if (socket[s].type == IS_VG469)
408
        i365_set(s, VG469_EXT_MODE, p->ema);
409
}
410
 
411
static u_int __init vg46x_set_opts(u_short s, char *buf)
412
{
413
    vg46x_state_t *p = &socket[s].state.vg46x;
414
 
415
    flip(p->ctl, VG468_CTL_ASYNC, async_clock);
416
    flip(p->ema, VG469_MODE_CABLE, cable_mode);
417
    if (p->ctl & VG468_CTL_ASYNC)
418
        strcat(buf, " [async]");
419
    if (p->ctl & VG468_CTL_INPACK)
420
        strcat(buf, " [inpack]");
421
    if (socket[s].type == IS_VG469) {
422
        u_char vsel = i365_get(s, VG469_VSELECT);
423
        if (vsel & VG469_VSEL_EXT_STAT) {
424
            strcat(buf, " [ext mode]");
425
            if (vsel & VG469_VSEL_EXT_BUS)
426
                strcat(buf, " [isa buf]");
427
        }
428
        if (p->ema & VG469_MODE_CABLE)
429
            strcat(buf, " [cable]");
430
        if (p->ema & VG469_MODE_COMPAT)
431
            strcat(buf, " [c step]");
432
    }
433
    return 0xffff;
434
}
435
 
436
/*======================================================================
437
 
438
    Generic routines to get and set controller options
439
 
440
======================================================================*/
441
 
442
static void get_bridge_state(u_short s)
443
{
444
    socket_info_t *t = &socket[s];
445
    if (t->flags & IS_CIRRUS)
446
        cirrus_get_state(s);
447
    else if (t->flags & IS_VADEM)
448
        vg46x_get_state(s);
449
}
450
 
451
static void set_bridge_state(u_short s)
452
{
453
    socket_info_t *t = &socket[s];
454
    if (t->flags & IS_CIRRUS)
455
        cirrus_set_state(s);
456
    else {
457
        i365_set(s, I365_GBLCTL, 0x00);
458
        i365_set(s, I365_GENCTL, 0x00);
459
    }
460
    i365_bflip(s, I365_INTCTL, I365_INTR_ENA, t->intr);
461
    if (t->flags & IS_VADEM)
462
        vg46x_set_state(s);
463
}
464
 
465
static u_int __init set_bridge_opts(u_short s, u_short ns)
466
{
467
    u_short i;
468
    u_int m = 0xffff;
469
    char buf[128];
470
 
471
    for (i = s; i < s+ns; i++) {
472
        if (socket[i].flags & IS_ALIVE) {
473
            printk(KERN_INFO "    host opts [%d]: already alive!\n", i);
474
            continue;
475
        }
476
        buf[0] = '\0';
477
        get_bridge_state(i);
478
        if (socket[i].flags & IS_CIRRUS)
479
            m = cirrus_set_opts(i, buf);
480
        else if (socket[i].flags & IS_VADEM)
481
            m = vg46x_set_opts(i, buf);
482
        set_bridge_state(i);
483
        printk(KERN_INFO "    host opts [%d]:%s\n", i,
484
               (*buf) ? buf : " none");
485
    }
486
    return m;
487
}
488
 
489
/*======================================================================
490
 
491
    Interrupt testing code, for ISA and PCI interrupts
492
 
493
======================================================================*/
494
 
495
static volatile u_int irq_hits;
496
static u_short irq_sock;
497
 
498
static void irq_count(int irq, void *dev, struct pt_regs *regs)
499
{
500
    i365_get(irq_sock, I365_CSC);
501
    irq_hits++;
502
    DEBUG(2, "-> hit on irq %d\n", irq);
503
}
504
 
505
static u_int __init test_irq(u_short sock, int irq)
506
{
507
    DEBUG(2, "  testing ISA irq %d\n", irq);
508
    if (request_irq(irq, irq_count, 0, "scan", irq_count) != 0)
509
        return 1;
510
    irq_hits = 0; irq_sock = sock;
511
    __set_current_state(TASK_UNINTERRUPTIBLE);
512
    schedule_timeout(HZ/100);
513
    if (irq_hits) {
514
        free_irq(irq, irq_count);
515
        DEBUG(2, "    spurious hit!\n");
516
        return 1;
517
    }
518
 
519
    /* Generate one interrupt */
520
    i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (irq << 4));
521
    i365_bset(sock, I365_GENCTL, I365_CTL_SW_IRQ);
522
    udelay(1000);
523
 
524
    free_irq(irq, irq_count);
525
 
526
    /* mask all interrupts */
527
    i365_set(sock, I365_CSCINT, 0);
528
    DEBUG(2, "    hits = %d\n", irq_hits);
529
 
530
    return (irq_hits != 1);
531
}
532
 
533
static u_int __init isa_scan(u_short sock, u_int mask0)
534
{
535
    u_int mask1 = 0;
536
    int i;
537
 
538
#ifdef __alpha__
539
#define PIC 0x4d0
540
    /* Don't probe level-triggered interrupts -- reserved for PCI */
541
    mask0 &= ~(inb(PIC) | (inb(PIC+1) << 8));
542
#endif
543
 
544
    if (do_scan) {
545
        set_bridge_state(sock);
546
        i365_set(sock, I365_CSCINT, 0);
547
        for (i = 0; i < 16; i++)
548
            if ((mask0 & (1 << i)) && (test_irq(sock, i) == 0))
549
                mask1 |= (1 << i);
550
        for (i = 0; i < 16; i++)
551
            if ((mask1 & (1 << i)) && (test_irq(sock, i) != 0))
552
                mask1 ^= (1 << i);
553
    }
554
 
555
    printk(KERN_INFO "    ISA irqs (");
556
    if (mask1) {
557
        printk("scanned");
558
    } else {
559
        /* Fallback: just find interrupts that aren't in use */
560
        for (i = 0; i < 16; i++)
561
            if ((mask0 & (1 << i)) && (_check_irq(i, 0) == 0))
562
                mask1 |= (1 << i);
563
        printk("default");
564
        /* If scan failed, default to polled status */
565
        if (!cs_irq && (poll_interval == 0)) poll_interval = HZ;
566
    }
567
    printk(") = ");
568
 
569
    for (i = 0; i < 16; i++)
570
        if (mask1 & (1<<i))
571
            printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
572
    if (mask1 == 0) printk("none!");
573
 
574
    return mask1;
575
}
576
 
577
/*====================================================================*/
578
 
579
/* Time conversion functions */
580
 
581
static int to_cycles(int ns)
582
{
583
    return ns/cycle_time;
584
}
585
 
586
static int to_ns(int cycles)
587
{
588
    return cycle_time*cycles;
589
}
590
 
591
/*====================================================================*/
592
 
593
static int __init identify(u_short port, u_short sock)
594
{
595
    u_char val;
596
    int type = -1;
597
 
598
    /* Use the next free entry in the socket table */
599
    socket[sockets].ioaddr = port;
600
    socket[sockets].psock = sock;
601
 
602
    /* Wake up a sleepy Cirrus controller */
603
    if (wakeup) {
604
        i365_bclr(sockets, PD67_MISC_CTL_2, PD67_MC2_SUSPEND);
605
        /* Pause at least 50 ms */
606
        mdelay(50);
607
    }
608
 
609
    if ((val = i365_get(sockets, I365_IDENT)) & 0x70)
610
        return -1;
611
    switch (val) {
612
    case 0x82:
613
        type = IS_I82365A; break;
614
    case 0x83:
615
        type = IS_I82365B; break;
616
    case 0x84:
617
        type = IS_I82365DF; break;
618
    case 0x88: case 0x89: case 0x8a:
619
        type = IS_IBM; break;
620
    }
621
 
622
    /* Check for Vadem VG-468 chips */
623
    outb(0x0e, port);
624
    outb(0x37, port);
625
    i365_bset(sockets, VG468_MISC, VG468_MISC_VADEMREV);
626
    val = i365_get(sockets, I365_IDENT);
627
    if (val & I365_IDENT_VADEM) {
628
        i365_bclr(sockets, VG468_MISC, VG468_MISC_VADEMREV);
629
        type = ((val & 7) >= 4) ? IS_VG469 : IS_VG468;
630
    }
631
 
632
    /* Check for Ricoh chips */
633
    val = i365_get(sockets, RF5C_CHIP_ID);
634
    if ((val == RF5C_CHIP_RF5C296) || (val == RF5C_CHIP_RF5C396))
635
        type = IS_RF5Cx96;
636
 
637
    /* Check for Cirrus CL-PD67xx chips */
638
    i365_set(sockets, PD67_CHIP_INFO, 0);
639
    val = i365_get(sockets, PD67_CHIP_INFO);
640
    if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) {
641
        val = i365_get(sockets, PD67_CHIP_INFO);
642
        if ((val & PD67_INFO_CHIP_ID) == 0) {
643
            type = (val & PD67_INFO_SLOTS) ? IS_PD672X : IS_PD6710;
644
            i365_set(sockets, PD67_EXT_INDEX, 0xe5);
645
            if (i365_get(sockets, PD67_EXT_INDEX) != 0xe5)
646
                type = IS_VT83C469;
647
        }
648
    }
649
    return type;
650
} /* identify */
651
 
652
/*======================================================================
653
 
654
    See if a card is present, powered up, in IO mode, and already
655
    bound to a (non PC Card) Linux driver.  We leave these alone.
656
 
657
    We make an exception for cards that seem to be serial devices.
658
 
659
======================================================================*/
660
 
661
static int __init is_alive(u_short sock)
662
{
663
    u_char stat;
664
    u_short start, stop;
665
 
666
    stat = i365_get(sock, I365_STATUS);
667
    start = i365_get_pair(sock, I365_IO(0)+I365_W_START);
668
    stop = i365_get_pair(sock, I365_IO(0)+I365_W_STOP);
669
    if ((stat & I365_CS_DETECT) && (stat & I365_CS_POWERON) &&
670
        (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD) &&
671
        (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(0)) &&
672
        (check_region(start, stop-start+1) != 0) &&
673
        ((start & 0xfeef) != 0x02e8))
674
        return 1;
675
    else
676
        return 0;
677
}
678
 
679
/*====================================================================*/
680
 
681
static void __init add_socket(u_short port, int psock, int type)
682
{
683
    socket[sockets].ioaddr = port;
684
    socket[sockets].psock = psock;
685
    socket[sockets].type = type;
686
    socket[sockets].flags = pcic[type].flags;
687
    if (is_alive(sockets))
688
        socket[sockets].flags |= IS_ALIVE;
689
    sockets++;
690
}
691
 
692
static void __init add_pcic(int ns, int type)
693
{
694
    u_int mask = 0, i, base;
695
    int isa_irq = 0;
696
    socket_info_t *t = &socket[sockets-ns];
697
 
698
    base = sockets-ns;
699
    if (t->ioaddr > 0) request_region(t->ioaddr, 2, "i82365");
700
 
701
    if (base == 0) printk("\n");
702
    printk(KERN_INFO "  %s", pcic[type].name);
703
    printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x",
704
               t->ioaddr, t->psock*0x40);
705
    printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : ""));
706
 
707
    /* Set host options, build basic interrupt mask */
708
    if (irq_list[0] == -1)
709
        mask = irq_mask;
710
    else
711
        for (i = mask = 0; i < 16; i++)
712
            mask |= (1<<irq_list[i]);
713
    mask &= I365_MASK & set_bridge_opts(base, ns);
714
    /* Scan for ISA interrupts */
715
    mask = isa_scan(base, mask);
716
 
717
    /* Poll if only two interrupts available */
718
    if (!poll_interval) {
719
        u_int tmp = (mask & 0xff20);
720
        tmp = tmp & (tmp-1);
721
        if ((tmp & (tmp-1)) == 0)
722
            poll_interval = HZ;
723
    }
724
    /* Only try an ISA cs_irq if this is the first controller */
725
    if (!grab_irq && (cs_irq || !poll_interval)) {
726
        /* Avoid irq 12 unless it is explicitly requested */
727
        u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
728
        for (cs_irq = 15; cs_irq > 0; cs_irq--)
729
            if ((cs_mask & (1 << cs_irq)) &&
730
                (_check_irq(cs_irq, 0) == 0))
731
                break;
732
        if (cs_irq) {
733
            grab_irq = 1;
734
            isa_irq = cs_irq;
735
            printk(" status change on irq %d\n", cs_irq);
736
        }
737
    }
738
 
739
    if (!isa_irq) {
740
        if (poll_interval == 0)
741
            poll_interval = HZ;
742
        printk(" polling interval = %d ms\n",
743
               poll_interval * 1000 / HZ);
744
 
745
    }
746
 
747
    /* Update socket interrupt information, capabilities */
748
    for (i = 0; i < ns; i++) {
749
        t[i].cap.features |= SS_CAP_PCCARD;
750
        t[i].cap.map_size = 0x1000;
751
        t[i].cap.irq_mask = mask;
752
        t[i].cs_irq = isa_irq;
753
    }
754
 
755
} /* add_pcic */
756
 
757
/*====================================================================*/
758
 
759
#if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
760
#define I82365_ISAPNP
761
#endif
762
 
763
#ifdef I82365_ISAPNP
764
static struct isapnp_device_id id_table[] __initdata = {
765
        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
766
                ISAPNP_FUNCTION(0x0e00), (unsigned long) "Intel 82365-Compatible" },
767
        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
768
                ISAPNP_FUNCTION(0x0e01), (unsigned long) "Cirrus Logic CL-PD6720" },
769
        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
770
                ISAPNP_FUNCTION(0x0e02), (unsigned long) "VLSI VL82C146" },
771
        {       0 }
772
};
773
MODULE_DEVICE_TABLE(isapnp, id_table);
774
 
775
static struct pci_dev *i82365_pnpdev;
776
#endif
777
 
778
static void __init isa_probe(void)
779
{
780
    int i, j, sock, k, ns, id;
781
    ioaddr_t port;
782
#ifdef I82365_ISAPNP
783
    struct isapnp_device_id *devid;
784
    struct pci_dev *dev;
785
 
786
    for (devid = id_table; devid->vendor; devid++) {
787
        if ((dev = isapnp_find_dev(NULL, devid->vendor, devid->function, NULL))) {
788
            printk("ISAPNP ");
789
 
790
            if (dev->prepare && dev->prepare(dev) < 0) {
791
                printk("prepare failed\n");
792
                break;
793
            }
794
 
795
            if (dev->activate && dev->activate(dev) < 0) {
796
                printk("activate failed\n");
797
                break;
798
            }
799
 
800
            if ((i365_base = pci_resource_start(dev, 0))) {
801
                printk("no resources ?\n");
802
                break;
803
            }
804
            i82365_pnpdev = dev;
805
            break;
806
        }
807
    }
808
#endif
809
 
810
    if (check_region(i365_base, 2) != 0) {
811
        if (sockets == 0)
812
            printk("port conflict at %#x\n", i365_base);
813
        return;
814
    }
815
 
816
    id = identify(i365_base, 0);
817
    if ((id == IS_I82365DF) && (identify(i365_base, 1) != id)) {
818
        for (i = 0; i < 4; i++) {
819
            if (i == ignore) continue;
820
            port = i365_base + ((i & 1) << 2) + ((i & 2) << 1);
821
            sock = (i & 1) << 1;
822
            if (identify(port, sock) == IS_I82365DF) {
823
                add_socket(port, sock, IS_VLSI);
824
                add_pcic(1, IS_VLSI);
825
            }
826
        }
827
    } else {
828
        for (i = 0; i < 8; i += 2) {
829
            if (sockets && !extra_sockets && (i == 4))
830
                break;
831
            port = i365_base + 2*(i>>2);
832
            sock = (i & 3);
833
            id = identify(port, sock);
834
            if (id < 0) continue;
835
 
836
            for (j = ns = 0; j < 2; j++) {
837
                /* Does the socket exist? */
838
                if ((ignore == i+j) || (identify(port, sock+j) < 0))
839
                    continue;
840
                /* Check for bad socket decode */
841
                for (k = 0; k <= sockets; k++)
842
                    i365_set(k, I365_MEM(0)+I365_W_OFF, k);
843
                for (k = 0; k <= sockets; k++)
844
                    if (i365_get(k, I365_MEM(0)+I365_W_OFF) != k)
845
                        break;
846
                if (k <= sockets) break;
847
                add_socket(port, sock+j, id); ns++;
848
            }
849
            if (ns != 0) add_pcic(ns, id);
850
        }
851
    }
852
}
853
 
854
/*====================================================================*/
855
 
856
static u_int pending_events[8];
857
static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
858
 
859
static void pcic_bh(void *dummy)
860
{
861
        u_int events;
862
        int i;
863
 
864
        for (i=0; i < sockets; i++) {
865
                spin_lock_irq(&pending_event_lock);
866
                events = pending_events[i];
867
                pending_events[i] = 0;
868
                spin_unlock_irq(&pending_event_lock);
869
                /*
870
                SS_DETECT events need a small delay here. The reason for this is that
871
                the "is there a card" electronics need time to see the card after the
872
                "we have a card coming in" electronics have seen it.
873
                */
874
                if (events & SS_DETECT)
875
                        mdelay(4);
876
                if (socket[i].handler)
877
                        socket[i].handler(socket[i].info, events);
878
        }
879
}
880
 
881
static struct tq_struct pcic_task = {
882
        routine:        pcic_bh
883
};
884
 
885
static unsigned long last_detect_jiffies;
886
 
887
static void pcic_interrupt(int irq, void *dev,
888
                                    struct pt_regs *regs)
889
{
890
    int i, j, csc;
891
    u_int events, active;
892
    u_long flags = 0;
893
 
894
    DEBUG(4, "i82365: pcic_interrupt(%d)\n", irq);
895
 
896
    for (j = 0; j < 20; j++) {
897
        active = 0;
898
        for (i = 0; i < sockets; i++) {
899
            if (socket[i].cs_irq != irq)
900
                continue;
901
            ISA_LOCK(i, flags);
902
            csc = i365_get(i, I365_CSC);
903
            if ((csc == 0) || (!socket[i].handler) ||
904
                (i365_get(i, I365_IDENT) & 0x70)) {
905
                ISA_UNLOCK(i, flags);
906
                continue;
907
            }
908
            events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
909
 
910
 
911
            /* Several sockets will send multiple "new card detected"
912
               events in rapid succession. However, the rest of the pcmcia expects
913
               only one such event. We just ignore these events by having a
914
               timeout */
915
 
916
            if (events) {
917
                if ((jiffies - last_detect_jiffies)<(HZ/20))
918
                        events = 0;
919
                last_detect_jiffies = jiffies;
920
 
921
            }
922
 
923
            if (i365_get(i, I365_INTCTL) & I365_PC_IOCARD)
924
                events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
925
            else {
926
                events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
927
                events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
928
                events |= (csc & I365_CSC_READY) ? SS_READY : 0;
929
            }
930
            ISA_UNLOCK(i, flags);
931
            DEBUG(2, "i82365: socket %d event 0x%02x\n", i, events);
932
 
933
            if (events) {
934
                    spin_lock(&pending_event_lock);
935
                    pending_events[i] |= events;
936
                    spin_unlock(&pending_event_lock);
937
                    schedule_task(&pcic_task);
938
            }
939
            active |= events;
940
        }
941
        if (!active) break;
942
    }
943
    if (j == 20)
944
        printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n");
945
 
946
    DEBUG(4, "i82365: interrupt done\n");
947
} /* pcic_interrupt */
948
 
949
static void pcic_interrupt_wrapper(u_long data)
950
{
951
    pcic_interrupt(0, NULL, NULL);
952
    poll_timer.expires = jiffies + poll_interval;
953
    add_timer(&poll_timer);
954
}
955
 
956
/*====================================================================*/
957
 
958
static int pcic_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
959
{
960
    socket[sock].handler = handler;
961
    socket[sock].info = info;
962
    if (handler == NULL) {
963
        MOD_DEC_USE_COUNT;
964
    } else {
965
        MOD_INC_USE_COUNT;
966
    }
967
    return 0;
968
} /* pcic_register_callback */
969
 
970
/*====================================================================*/
971
 
972
static int pcic_inquire_socket(unsigned int sock, socket_cap_t *cap)
973
{
974
    *cap = socket[sock].cap;
975
    return 0;
976
} /* pcic_inquire_socket */
977
 
978
/*====================================================================*/
979
 
980
static int i365_get_status(u_short sock, u_int *value)
981
{
982
    u_int status;
983
 
984
    status = i365_get(sock, I365_STATUS);
985
    *value = ((status & I365_CS_DETECT) == I365_CS_DETECT)
986
        ? SS_DETECT : 0;
987
 
988
    if (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD)
989
        *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
990
    else {
991
        *value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
992
        *value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
993
    }
994
    *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
995
    *value |= (status & I365_CS_READY) ? SS_READY : 0;
996
    *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
997
 
998
    if (socket[sock].type == IS_VG469) {
999
        status = i365_get(sock, VG469_VSENSE);
1000
        if (socket[sock].psock & 1) {
1001
            *value |= (status & VG469_VSENSE_B_VS1) ? 0 : SS_3VCARD;
1002
            *value |= (status & VG469_VSENSE_B_VS2) ? 0 : SS_XVCARD;
1003
        } else {
1004
            *value |= (status & VG469_VSENSE_A_VS1) ? 0 : SS_3VCARD;
1005
            *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD;
1006
        }
1007
    }
1008
 
1009
    DEBUG(1, "i82365: GetStatus(%d) = %#4.4x\n", sock, *value);
1010
    return 0;
1011
} /* i365_get_status */
1012
 
1013
/*====================================================================*/
1014
 
1015
static int i365_get_socket(u_short sock, socket_state_t *state)
1016
{
1017
    socket_info_t *t = &socket[sock];
1018
    u_char reg, vcc, vpp;
1019
 
1020
    reg = i365_get(sock, I365_POWER);
1021
    state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
1022
    state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
1023
    vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK;
1024
    state->Vcc = state->Vpp = 0;
1025
    if (t->flags & IS_CIRRUS) {
1026
        if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) {
1027
            if (reg & I365_VCC_5V) state->Vcc = 33;
1028
            if (vpp == I365_VPP1_5V) state->Vpp = 33;
1029
        } else {
1030
            if (reg & I365_VCC_5V) state->Vcc = 50;
1031
            if (vpp == I365_VPP1_5V) state->Vpp = 50;
1032
        }
1033
        if (vpp == I365_VPP1_12V) state->Vpp = 120;
1034
    } else if (t->flags & IS_VG_PWR) {
1035
        if (i365_get(sock, VG469_VSELECT) & VG469_VSEL_VCC) {
1036
            if (reg & I365_VCC_5V) state->Vcc = 33;
1037
            if (vpp == I365_VPP1_5V) state->Vpp = 33;
1038
        } else {
1039
            if (reg & I365_VCC_5V) state->Vcc = 50;
1040
            if (vpp == I365_VPP1_5V) state->Vpp = 50;
1041
        }
1042
        if (vpp == I365_VPP1_12V) state->Vpp = 120;
1043
    } else if (t->flags & IS_DF_PWR) {
1044
        if (vcc == I365_VCC_3V) state->Vcc = 33;
1045
        if (vcc == I365_VCC_5V) state->Vcc = 50;
1046
        if (vpp == I365_VPP1_5V) state->Vpp = 50;
1047
        if (vpp == I365_VPP1_12V) state->Vpp = 120;
1048
    } else {
1049
        if (reg & I365_VCC_5V) {
1050
            state->Vcc = 50;
1051
            if (vpp == I365_VPP1_5V) state->Vpp = 50;
1052
            if (vpp == I365_VPP1_12V) state->Vpp = 120;
1053
        }
1054
    }
1055
 
1056
    /* IO card, RESET flags, IO interrupt */
1057
    reg = i365_get(sock, I365_INTCTL);
1058
    state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
1059
    if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD;
1060
    state->io_irq = reg & I365_IRQ_MASK;
1061
 
1062
    /* speaker control */
1063
    if (t->flags & IS_CIRRUS) {
1064
        if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA)
1065
            state->flags |= SS_SPKR_ENA;
1066
    }
1067
 
1068
    /* Card status change mask */
1069
    reg = i365_get(sock, I365_CSCINT);
1070
    state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
1071
    if (state->flags & SS_IOCARD)
1072
        state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
1073
    else {
1074
        state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
1075
        state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
1076
        state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
1077
    }
1078
 
1079
    DEBUG(1, "i82365: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
1080
          "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
1081
          state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
1082
    return 0;
1083
} /* i365_get_socket */
1084
 
1085
/*====================================================================*/
1086
 
1087
static int i365_set_socket(u_short sock, socket_state_t *state)
1088
{
1089
    socket_info_t *t = &socket[sock];
1090
    u_char reg;
1091
 
1092
    DEBUG(1, "i82365: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
1093
          "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
1094
          state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
1095
 
1096
    /* First set global controller options */
1097
    set_bridge_state(sock);
1098
 
1099
    /* IO card, RESET flag, IO interrupt */
1100
    reg = t->intr;
1101
    reg |= state->io_irq;
1102
    reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
1103
    reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
1104
    i365_set(sock, I365_INTCTL, reg);
1105
 
1106
    reg = I365_PWR_NORESET;
1107
    if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
1108
    if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
1109
 
1110
    if (t->flags & IS_CIRRUS) {
1111
        if (state->Vpp != 0) {
1112
            if (state->Vpp == 120)
1113
                reg |= I365_VPP1_12V;
1114
            else if (state->Vpp == state->Vcc)
1115
                reg |= I365_VPP1_5V;
1116
            else return -EINVAL;
1117
        }
1118
        if (state->Vcc != 0) {
1119
            reg |= I365_VCC_5V;
1120
            if (state->Vcc == 33)
1121
                i365_bset(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
1122
            else if (state->Vcc == 50)
1123
                i365_bclr(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
1124
            else return -EINVAL;
1125
        }
1126
    } else if (t->flags & IS_VG_PWR) {
1127
        if (state->Vpp != 0) {
1128
            if (state->Vpp == 120)
1129
                reg |= I365_VPP1_12V;
1130
            else if (state->Vpp == state->Vcc)
1131
                reg |= I365_VPP1_5V;
1132
            else return -EINVAL;
1133
        }
1134
        if (state->Vcc != 0) {
1135
            reg |= I365_VCC_5V;
1136
            if (state->Vcc == 33)
1137
                i365_bset(sock, VG469_VSELECT, VG469_VSEL_VCC);
1138
            else if (state->Vcc == 50)
1139
                i365_bclr(sock, VG469_VSELECT, VG469_VSEL_VCC);
1140
            else return -EINVAL;
1141
        }
1142
    } else if (t->flags & IS_DF_PWR) {
1143
        switch (state->Vcc) {
1144
        case 0:          break;
1145
        case 33:        reg |= I365_VCC_3V; break;
1146
        case 50:        reg |= I365_VCC_5V; break;
1147
        default:        return -EINVAL;
1148
        }
1149
        switch (state->Vpp) {
1150
        case 0:          break;
1151
        case 50:        reg |= I365_VPP1_5V; break;
1152
        case 120:       reg |= I365_VPP1_12V; break;
1153
        default:        return -EINVAL;
1154
        }
1155
    } else {
1156
        switch (state->Vcc) {
1157
        case 0:          break;
1158
        case 50:        reg |= I365_VCC_5V; break;
1159
        default:        return -EINVAL;
1160
        }
1161
        switch (state->Vpp) {
1162
        case 0:          break;
1163
        case 50:        reg |= I365_VPP1_5V | I365_VPP2_5V; break;
1164
        case 120:       reg |= I365_VPP1_12V | I365_VPP2_12V; break;
1165
        default:        return -EINVAL;
1166
        }
1167
    }
1168
 
1169
    if (reg != i365_get(sock, I365_POWER))
1170
        i365_set(sock, I365_POWER, reg);
1171
 
1172
    /* Chipset-specific functions */
1173
    if (t->flags & IS_CIRRUS) {
1174
        /* Speaker control */
1175
        i365_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA,
1176
                   state->flags & SS_SPKR_ENA);
1177
    }
1178
 
1179
    /* Card status change interrupt mask */
1180
    reg = t->cs_irq << 4;
1181
    if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
1182
    if (state->flags & SS_IOCARD) {
1183
        if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
1184
    } else {
1185
        if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;
1186
        if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
1187
        if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
1188
    }
1189
    i365_set(sock, I365_CSCINT, reg);
1190
    i365_get(sock, I365_CSC);
1191
 
1192
    return 0;
1193
} /* i365_set_socket */
1194
 
1195
/*====================================================================*/
1196
 
1197
static int i365_get_io_map(u_short sock, struct pccard_io_map *io)
1198
{
1199
    u_char map, ioctl, addr;
1200
 
1201
    map = io->map;
1202
    if (map > 1) return -EINVAL;
1203
    io->start = i365_get_pair(sock, I365_IO(map)+I365_W_START);
1204
    io->stop = i365_get_pair(sock, I365_IO(map)+I365_W_STOP);
1205
    ioctl = i365_get(sock, I365_IOCTL);
1206
    addr = i365_get(sock, I365_ADDRWIN);
1207
    io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0;
1208
    io->flags  = (addr & I365_ENA_IO(map)) ? MAP_ACTIVE : 0;
1209
    io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0;
1210
    io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0;
1211
    io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0;
1212
    DEBUG(1, "i82365: GetIOMap(%d, %d) = %#2.2x, %d ns, "
1213
          "%#4.4x-%#4.4x\n", sock, map, io->flags, io->speed,
1214
          io->start, io->stop);
1215
    return 0;
1216
} /* i365_get_io_map */
1217
 
1218
/*====================================================================*/
1219
 
1220
static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
1221
{
1222
    u_char map, ioctl;
1223
 
1224
    DEBUG(1, "i82365: SetIOMap(%d, %d, %#2.2x, %d ns, "
1225
          "%#4.4x-%#4.4x)\n", sock, io->map, io->flags,
1226
          io->speed, io->start, io->stop);
1227
    map = io->map;
1228
    if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
1229
        (io->stop < io->start)) return -EINVAL;
1230
    /* Turn off the window before changing anything */
1231
    if (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(map))
1232
        i365_bclr(sock, I365_ADDRWIN, I365_ENA_IO(map));
1233
    i365_set_pair(sock, I365_IO(map)+I365_W_START, io->start);
1234
    i365_set_pair(sock, I365_IO(map)+I365_W_STOP, io->stop);
1235
    ioctl = i365_get(sock, I365_IOCTL) & ~I365_IOCTL_MASK(map);
1236
    if (io->speed) ioctl |= I365_IOCTL_WAIT(map);
1237
    if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
1238
    if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
1239
    if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
1240
    i365_set(sock, I365_IOCTL, ioctl);
1241
    /* Turn on the window if necessary */
1242
    if (io->flags & MAP_ACTIVE)
1243
        i365_bset(sock, I365_ADDRWIN, I365_ENA_IO(map));
1244
    return 0;
1245
} /* i365_set_io_map */
1246
 
1247
/*====================================================================*/
1248
 
1249
static int i365_get_mem_map(u_short sock, struct pccard_mem_map *mem)
1250
{
1251
    u_short base, i;
1252
    u_char map, addr;
1253
 
1254
    map = mem->map;
1255
    if (map > 4) return -EINVAL;
1256
    addr = i365_get(sock, I365_ADDRWIN);
1257
    mem->flags = (addr & I365_ENA_MEM(map)) ? MAP_ACTIVE : 0;
1258
    base = I365_MEM(map);
1259
 
1260
    i = i365_get_pair(sock, base+I365_W_START);
1261
    mem->flags |= (i & I365_MEM_16BIT) ? MAP_16BIT : 0;
1262
    mem->flags |= (i & I365_MEM_0WS) ? MAP_0WS : 0;
1263
    mem->sys_start = ((u_long)(i & 0x0fff) << 12);
1264
 
1265
    i = i365_get_pair(sock, base+I365_W_STOP);
1266
    mem->speed  = (i & I365_MEM_WS0) ? 1 : 0;
1267
    mem->speed += (i & I365_MEM_WS1) ? 2 : 0;
1268
    mem->speed = to_ns(mem->speed);
1269
    mem->sys_stop = ((u_long)(i & 0x0fff) << 12) + 0x0fff;
1270
 
1271
    i = i365_get_pair(sock, base+I365_W_OFF);
1272
    mem->flags |= (i & I365_MEM_WRPROT) ? MAP_WRPROT : 0;
1273
    mem->flags |= (i & I365_MEM_REG) ? MAP_ATTRIB : 0;
1274
    mem->card_start = ((u_int)(i & 0x3fff) << 12) + mem->sys_start;
1275
    mem->card_start &= 0x3ffffff;
1276
 
1277
    DEBUG(1, "i82365: GetMemMap(%d, %d) = %#2.2x, %d ns, %#5.5lx-%#5."
1278
          "5lx, %#5.5x\n", sock, mem->map, mem->flags, mem->speed,
1279
          mem->sys_start, mem->sys_stop, mem->card_start);
1280
    return 0;
1281
} /* i365_get_mem_map */
1282
 
1283
/*====================================================================*/
1284
 
1285
static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
1286
{
1287
    u_short base, i;
1288
    u_char map;
1289
 
1290
    DEBUG(1, "i82365: SetMemMap(%d, %d, %#2.2x, %d ns, %#5.5lx-%#5.5"
1291
          "lx, %#5.5x)\n", sock, mem->map, mem->flags, mem->speed,
1292
          mem->sys_start, mem->sys_stop, mem->card_start);
1293
 
1294
    map = mem->map;
1295
    if ((map > 4) || (mem->card_start > 0x3ffffff) ||
1296
        (mem->sys_start > mem->sys_stop) || (mem->speed > 1000))
1297
        return -EINVAL;
1298
    if ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff))
1299
        return -EINVAL;
1300
 
1301
    /* Turn off the window before changing anything */
1302
    if (i365_get(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
1303
        i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map));
1304
 
1305
    base = I365_MEM(map);
1306
    i = (mem->sys_start >> 12) & 0x0fff;
1307
    if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT;
1308
    if (mem->flags & MAP_0WS) i |= I365_MEM_0WS;
1309
    i365_set_pair(sock, base+I365_W_START, i);
1310
 
1311
    i = (mem->sys_stop >> 12) & 0x0fff;
1312
    switch (to_cycles(mem->speed)) {
1313
    case 0:      break;
1314
    case 1:     i |= I365_MEM_WS0; break;
1315
    case 2:     i |= I365_MEM_WS1; break;
1316
    default:    i |= I365_MEM_WS1 | I365_MEM_WS0; break;
1317
    }
1318
    i365_set_pair(sock, base+I365_W_STOP, i);
1319
 
1320
    i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;
1321
    if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT;
1322
    if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG;
1323
    i365_set_pair(sock, base+I365_W_OFF, i);
1324
 
1325
    /* Turn on the window if necessary */
1326
    if (mem->flags & MAP_ACTIVE)
1327
        i365_bset(sock, I365_ADDRWIN, I365_ENA_MEM(map));
1328
    return 0;
1329
} /* i365_set_mem_map */
1330
 
1331
/*======================================================================
1332
 
1333
    Routines for accessing socket information and register dumps via
1334
    /proc/bus/pccard/...
1335
 
1336
======================================================================*/
1337
 
1338
#ifdef CONFIG_PROC_FS
1339
 
1340
static int proc_read_info(char *buf, char **start, off_t pos,
1341
                          int count, int *eof, void *data)
1342
{
1343
    socket_info_t *s = data;
1344
    char *p = buf;
1345
    p += sprintf(p, "type:     %s\npsock:    %d\n",
1346
                 pcic[s->type].name, s->psock);
1347
    return (p - buf);
1348
}
1349
 
1350
static int proc_read_exca(char *buf, char **start, off_t pos,
1351
                          int count, int *eof, void *data)
1352
{
1353
    u_short sock = (socket_info_t *)data - socket;
1354
    char *p = buf;
1355
    int i, top;
1356
 
1357
    u_long flags = 0;
1358
    ISA_LOCK(sock, flags);
1359
    top = 0x40;
1360
    for (i = 0; i < top; i += 4) {
1361
        if (i == 0x50) {
1362
            p += sprintf(p, "\n");
1363
            i = 0x100;
1364
        }
1365
        p += sprintf(p, "%02x %02x %02x %02x%s",
1366
                     i365_get(sock,i), i365_get(sock,i+1),
1367
                     i365_get(sock,i+2), i365_get(sock,i+3),
1368
                     ((i % 16) == 12) ? "\n" : " ");
1369
    }
1370
    ISA_UNLOCK(sock, flags);
1371
    return (p - buf);
1372
}
1373
 
1374
static void pcic_proc_setup(unsigned int sock, struct proc_dir_entry *base)
1375
{
1376
    socket_info_t *s = &socket[sock];
1377
 
1378
    if (s->flags & IS_ALIVE)
1379
        return;
1380
 
1381
    create_proc_read_entry("info", 0, base, proc_read_info, s);
1382
    create_proc_read_entry("exca", 0, base, proc_read_exca, s);
1383
    s->proc = base;
1384
}
1385
 
1386
static void pcic_proc_remove(u_short sock)
1387
{
1388
    struct proc_dir_entry *base = socket[sock].proc;
1389
    if (base == NULL) return;
1390
    remove_proc_entry("info", base);
1391
    remove_proc_entry("exca", base);
1392
}
1393
 
1394
#else
1395
 
1396
#define pcic_proc_setup NULL
1397
 
1398
#endif /* CONFIG_PROC_FS */
1399
 
1400
/*====================================================================*/
1401
 
1402
/* this is horribly ugly... proper locking needs to be done here at
1403
 * some time... */
1404
#define LOCKED(x) do { \
1405
        int retval; \
1406
        unsigned long flags; \
1407
        spin_lock_irqsave(&isa_lock, flags); \
1408
        retval = x; \
1409
        spin_unlock_irqrestore(&isa_lock, flags); \
1410
        return retval; \
1411
} while (0)
1412
 
1413
static int pcic_get_status(unsigned int sock, u_int *value)
1414
{
1415
        if (socket[sock].flags & IS_ALIVE) {
1416
                *value = 0;
1417
                return -EINVAL;
1418
        }
1419
 
1420
        LOCKED(i365_get_status(sock, value));
1421
}
1422
 
1423
static int pcic_get_socket(unsigned int sock, socket_state_t *state)
1424
{
1425
        if (socket[sock].flags & IS_ALIVE)
1426
                return -EINVAL;
1427
 
1428
        LOCKED(i365_get_socket(sock, state));
1429
}
1430
 
1431
static int pcic_set_socket(unsigned int sock, socket_state_t *state)
1432
{
1433
        if (socket[sock].flags & IS_ALIVE)
1434
                return -EINVAL;
1435
 
1436
        LOCKED(i365_set_socket(sock, state));
1437
}
1438
 
1439
static int pcic_get_io_map(unsigned int sock, struct pccard_io_map *io)
1440
{
1441
        if (socket[sock].flags & IS_ALIVE)
1442
                return -EINVAL;
1443
 
1444
        LOCKED(i365_get_io_map(sock, io));
1445
}
1446
 
1447
static int pcic_set_io_map(unsigned int sock, struct pccard_io_map *io)
1448
{
1449
        if (socket[sock].flags & IS_ALIVE)
1450
                return -EINVAL;
1451
 
1452
        LOCKED(i365_set_io_map(sock, io));
1453
}
1454
 
1455
static int pcic_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
1456
{
1457
        if (socket[sock].flags & IS_ALIVE)
1458
                return -EINVAL;
1459
 
1460
        LOCKED(i365_get_mem_map(sock, mem));
1461
}
1462
 
1463
static int pcic_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
1464
{
1465
        if (socket[sock].flags & IS_ALIVE)
1466
                return -EINVAL;
1467
 
1468
        LOCKED(i365_set_mem_map(sock, mem));
1469
}
1470
 
1471
static int pcic_init(unsigned int s)
1472
{
1473
        int i;
1474
        pccard_io_map io = { 0, 0, 0, 0, 1 };
1475
        pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
1476
 
1477
        mem.sys_stop = 0x1000;
1478
        pcic_set_socket(s, &dead_socket);
1479
        for (i = 0; i < 2; i++) {
1480
                io.map = i;
1481
                pcic_set_io_map(s, &io);
1482
        }
1483
        for (i = 0; i < 5; i++) {
1484
                mem.map = i;
1485
                pcic_set_mem_map(s, &mem);
1486
        }
1487
        return 0;
1488
}
1489
 
1490
static int pcic_suspend(unsigned int sock)
1491
{
1492
        return pcic_set_socket(sock, &dead_socket);
1493
}
1494
 
1495
static struct pccard_operations pcic_operations = {
1496
        pcic_init,
1497
        pcic_suspend,
1498
        pcic_register_callback,
1499
        pcic_inquire_socket,
1500
        pcic_get_status,
1501
        pcic_get_socket,
1502
        pcic_set_socket,
1503
        pcic_get_io_map,
1504
        pcic_set_io_map,
1505
        pcic_get_mem_map,
1506
        pcic_set_mem_map,
1507
        pcic_proc_setup
1508
};
1509
 
1510
/*====================================================================*/
1511
 
1512
static int __init init_i82365(void)
1513
{
1514
    servinfo_t serv;
1515
    pcmcia_get_card_services_info(&serv);
1516
    if (serv.Revision != CS_RELEASE_CODE) {
1517
        printk(KERN_NOTICE "i82365: Card Services release "
1518
               "does not match!\n");
1519
        return -1;
1520
    }
1521
    DEBUG(0, "%s\n", version);
1522
    printk(KERN_INFO "Intel ISA PCIC probe: ");
1523
    sockets = 0;
1524
 
1525
    isa_probe();
1526
 
1527
    if (sockets == 0) {
1528
        printk("not found.\n");
1529
        return -ENODEV;
1530
    }
1531
 
1532
    /* Set up interrupt handler(s) */
1533
    if (grab_irq != 0)
1534
        request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
1535
 
1536
    if (register_ss_entry(sockets, &pcic_operations) != 0)
1537
        printk(KERN_NOTICE "i82365: register_ss_entry() failed\n");
1538
 
1539
    /* Finally, schedule a polling interrupt */
1540
    if (poll_interval != 0) {
1541
        poll_timer.function = pcic_interrupt_wrapper;
1542
        poll_timer.data = 0;
1543
        init_timer(&poll_timer);
1544
        poll_timer.expires = jiffies + poll_interval;
1545
        add_timer(&poll_timer);
1546
    }
1547
 
1548
    return 0;
1549
 
1550
} /* init_i82365 */
1551
 
1552
static void __exit exit_i82365(void)
1553
{
1554
    int i;
1555
#ifdef CONFIG_PROC_FS
1556
    for (i = 0; i < sockets; i++) pcic_proc_remove(i);
1557
#endif
1558
    unregister_ss_entry(&pcic_operations);
1559
    if (poll_interval != 0)
1560
        del_timer(&poll_timer);
1561
    if (grab_irq != 0)
1562
        free_irq(cs_irq, pcic_interrupt);
1563
    for (i = 0; i < sockets; i++) {
1564
        /* Turn off all interrupt sources! */
1565
        i365_set(i, I365_CSCINT, 0);
1566
        release_region(socket[i].ioaddr, 2);
1567
    }
1568
#if defined(I82365_ISAPNP)
1569
    if (i82365_pnpdev && i82365_pnpdev->deactivate)
1570
                i82365_pnpdev->deactivate(i82365_pnpdev);
1571
#endif
1572
} /* exit_i82365 */
1573
 
1574
module_init(init_i82365);
1575
module_exit(exit_i82365);
1576
MODULE_LICENSE("Dual MPL/GPL");
1577
/*====================================================================*/

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.