1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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/kernel.h>
41#include <linux/errno.h>
42#include <linux/timer.h>
43#include <linux/ioport.h>
44#include <linux/delay.h>
45#include <linux/workqueue.h>
46#include <linux/interrupt.h>
47#include <linux/platform_device.h>
48#include <linux/bitops.h>
49#include <asm/irq.h>
50#include <asm/io.h>
51#include <asm/system.h>
52
53#include <pcmcia/ss.h>
54
55#include <linux/isapnp.h>
56
57
58#include "i82365.h"
59#include "cirrus.h"
60#include "vg468.h"
61#include "ricoh.h"
62
63
64static irqreturn_t i365_count_irq(int, void *);
65static inline int _check_irq(int irq, int flags)
66{
67 if (request_irq(irq, i365_count_irq, flags, "x", i365_count_irq) != 0)
68 return -1;
69 free_irq(irq, i365_count_irq);
70 return 0;
71}
72
73
74
75
76
77
78static unsigned long i365_base = 0x3e0;
79
80static int extra_sockets = 0;
81
82static int ignore = -1;
83
84static u_int irq_mask = 0xffff;
85static int irq_list[16];
86static unsigned int irq_list_count;
87
88static int cs_irq = 0;
89
90
91static int do_scan = 1;
92
93static int poll_interval = 0;
94
95static int cycle_time = 120;
96
97
98static int has_dma = -1;
99static int has_led = -1;
100static int has_ring = -1;
101static int dynamic_mode = 0;
102static int freq_bypass = -1;
103static int setup_time = -1;
104static int cmd_time = -1;
105static int recov_time = -1;
106
107
108static int async_clock = -1;
109static int cable_mode = -1;
110static int wakeup = 0;
111
112module_param(i365_base, ulong, 0444);
113module_param(ignore, int, 0444);
114module_param(extra_sockets, int, 0444);
115module_param(irq_mask, int, 0444);
116module_param_array(irq_list, int, &irq_list_count, 0444);
117module_param(cs_irq, int, 0444);
118module_param(async_clock, int, 0444);
119module_param(cable_mode, int, 0444);
120module_param(wakeup, int, 0444);
121
122module_param(do_scan, int, 0444);
123module_param(poll_interval, int, 0444);
124module_param(cycle_time, int, 0444);
125module_param(has_dma, int, 0444);
126module_param(has_led, int, 0444);
127module_param(has_ring, int, 0444);
128module_param(dynamic_mode, int, 0444);
129module_param(freq_bypass, int, 0444);
130module_param(setup_time, int, 0444);
131module_param(cmd_time, int, 0444);
132module_param(recov_time, int, 0444);
133
134
135
136typedef struct cirrus_state_t {
137 u_char misc1, misc2;
138 u_char timer[6];
139} cirrus_state_t;
140
141typedef struct vg46x_state_t {
142 u_char ctl, ema;
143} vg46x_state_t;
144
145struct i82365_socket {
146 u_short type, flags;
147 struct pcmcia_socket socket;
148 unsigned int number;
149 unsigned int ioaddr;
150 u_short psock;
151 u_char cs_irq, intr;
152 union {
153 cirrus_state_t cirrus;
154 vg46x_state_t vg46x;
155 } state;
156};
157
158
159static int sockets = 0;
160static struct i82365_socket socket[8] = {
161 { 0, },
162};
163
164
165#define I365_MASK 0xdeb8
166
167static int grab_irq;
168static DEFINE_SPINLOCK(isa_lock);
169#define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f)
170#define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f)
171
172static struct timer_list poll_timer;
173
174
175
176
177typedef enum pcic_id {
178 IS_I82365A, IS_I82365B, IS_I82365DF,
179 IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469,
180 IS_PD6710, IS_PD672X, IS_VT83C469,
181} pcic_id;
182
183
184#define IS_VADEM 0x0001
185#define IS_CIRRUS 0x0002
186#define IS_VIA 0x0010
187#define IS_UNKNOWN 0x0400
188#define IS_VG_PWR 0x0800
189#define IS_DF_PWR 0x1000
190#define IS_REGISTERED 0x2000
191#define IS_ALIVE 0x8000
192
193typedef struct pcic_t {
194 char *name;
195 u_short flags;
196} pcic_t;
197
198static pcic_t pcic[] = {
199 { "Intel i82365sl A step", 0 },
200 { "Intel i82365sl B step", 0 },
201 { "Intel i82365sl DF", IS_DF_PWR },
202 { "IBM Clone", 0 },
203 { "Ricoh RF5C296/396", 0 },
204 { "VLSI 82C146", 0 },
205 { "Vadem VG-468", IS_VADEM },
206 { "Vadem VG-469", IS_VADEM|IS_VG_PWR },
207 { "Cirrus PD6710", IS_CIRRUS },
208 { "Cirrus PD672x", IS_CIRRUS },
209 { "VIA VT83C469", IS_CIRRUS|IS_VIA },
210};
211
212#define PCIC_COUNT (sizeof(pcic)/sizeof(pcic_t))
213
214
215
216static DEFINE_SPINLOCK(bus_lock);
217
218static u_char i365_get(u_short sock, u_short reg)
219{
220 unsigned long flags;
221 spin_lock_irqsave(&bus_lock,flags);
222 {
223 unsigned int port = socket[sock].ioaddr;
224 u_char val;
225 reg = I365_REG(socket[sock].psock, reg);
226 outb(reg, port); val = inb(port+1);
227 spin_unlock_irqrestore(&bus_lock,flags);
228 return val;
229 }
230}
231
232static void i365_set(u_short sock, u_short reg, u_char data)
233{
234 unsigned long flags;
235 spin_lock_irqsave(&bus_lock,flags);
236 {
237 unsigned int port = socket[sock].ioaddr;
238 u_char val = I365_REG(socket[sock].psock, reg);
239 outb(val, port); outb(data, port+1);
240 spin_unlock_irqrestore(&bus_lock,flags);
241 }
242}
243
244static void i365_bset(u_short sock, u_short reg, u_char mask)
245{
246 u_char d = i365_get(sock, reg);
247 d |= mask;
248 i365_set(sock, reg, d);
249}
250
251static void i365_bclr(u_short sock, u_short reg, u_char mask)
252{
253 u_char d = i365_get(sock, reg);
254 d &= ~mask;
255 i365_set(sock, reg, d);
256}
257
258static void i365_bflip(u_short sock, u_short reg, u_char mask, int b)
259{
260 u_char d = i365_get(sock, reg);
261 if (b)
262 d |= mask;
263 else
264 d &= ~mask;
265 i365_set(sock, reg, d);
266}
267
268static u_short i365_get_pair(u_short sock, u_short reg)
269{
270 u_short a, b;
271 a = i365_get(sock, reg);
272 b = i365_get(sock, reg+1);
273 return (a + (b<<8));
274}
275
276static void i365_set_pair(u_short sock, u_short reg, u_short data)
277{
278 i365_set(sock, reg, data & 0xff);
279 i365_set(sock, reg+1, data >> 8);
280}
281
282
283
284
285
286
287
288
289
290
291
292
293#define flip(v,b,f) (v = ((f)<0) ? v : ((f) ? ((v)|(b)) : ((v)&(~b))))
294
295static void cirrus_get_state(u_short s)
296{
297 int i;
298 cirrus_state_t *p = &socket[s].state.cirrus;
299 p->misc1 = i365_get(s, PD67_MISC_CTL_1);
300 p->misc1 &= (PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
301 p->misc2 = i365_get(s, PD67_MISC_CTL_2);
302 for (i = 0; i < 6; i++)
303 p->timer[i] = i365_get(s, PD67_TIME_SETUP(0)+i);
304}
305
306static void cirrus_set_state(u_short s)
307{
308 int i;
309 u_char misc;
310 cirrus_state_t *p = &socket[s].state.cirrus;
311
312 misc = i365_get(s, PD67_MISC_CTL_2);
313 i365_set(s, PD67_MISC_CTL_2, p->misc2);
314 if (misc & PD67_MC2_SUSPEND) mdelay(50);
315 misc = i365_get(s, PD67_MISC_CTL_1);
316 misc &= ~(PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
317 i365_set(s, PD67_MISC_CTL_1, misc | p->misc1);
318 for (i = 0; i < 6; i++)
319 i365_set(s, PD67_TIME_SETUP(0)+i, p->timer[i]);
320}
321
322static u_int __init cirrus_set_opts(u_short s, char *buf)
323{
324 struct i82365_socket *t = &socket[s];
325 cirrus_state_t *p = &socket[s].state.cirrus;
326 u_int mask = 0xffff;
327
328 if (has_ring == -1) has_ring = 1;
329 flip(p->misc2, PD67_MC2_IRQ15_RI, has_ring);
330 flip(p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode);
331 flip(p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
332 if (p->misc2 & PD67_MC2_IRQ15_RI)
333 strcat(buf, " [ring]");
334 if (p->misc2 & PD67_MC2_DYNAMIC_MODE)
335 strcat(buf, " [dyn mode]");
336 if (p->misc2 & PD67_MC2_FREQ_BYPASS)
337 strcat(buf, " [freq bypass]");
338 if (p->misc1 & PD67_MC1_INPACK_ENA)
339 strcat(buf, " [inpack]");
340 if (p->misc2 & PD67_MC2_IRQ15_RI)
341 mask &= ~0x8000;
342 if (has_led > 0) {
343 strcat(buf, " [led]");
344 mask &= ~0x1000;
345 }
346 if (has_dma > 0) {
347 strcat(buf, " [dma]");
348 mask &= ~0x0600;
349 }
350 if (!(t->flags & IS_VIA)) {
351 if (setup_time >= 0)
352 p->timer[0] = p->timer[3] = setup_time;
353 if (cmd_time > 0) {
354 p->timer[1] = cmd_time;
355 p->timer[4] = cmd_time*2+4;
356 }
357 if (p->timer[1] == 0) {
358 p->timer[1] = 6; p->timer[4] = 16;
359 if (p->timer[0] == 0)
360 p->timer[0] = p->timer[3] = 1;
361 }
362 if (recov_time >= 0)
363 p->timer[2] = p->timer[5] = recov_time;
364 buf += strlen(buf);
365 sprintf(buf, " [%d/%d/%d] [%d/%d/%d]", p->timer[0], p->timer[1],
366 p->timer[2], p->timer[3], p->timer[4], p->timer[5]);
367 }
368 return mask;
369}
370
371
372
373
374
375
376
377
378
379static void vg46x_get_state(u_short s)
380{
381 vg46x_state_t *p = &socket[s].state.vg46x;
382 p->ctl = i365_get(s, VG468_CTL);
383 if (socket[s].type == IS_VG469)
384 p->ema = i365_get(s, VG469_EXT_MODE);
385}
386
387static void vg46x_set_state(u_short s)
388{
389 vg46x_state_t *p = &socket[s].state.vg46x;
390 i365_set(s, VG468_CTL, p->ctl);
391 if (socket[s].type == IS_VG469)
392 i365_set(s, VG469_EXT_MODE, p->ema);
393}
394
395static u_int __init vg46x_set_opts(u_short s, char *buf)
396{
397 vg46x_state_t *p = &socket[s].state.vg46x;
398
399 flip(p->ctl, VG468_CTL_ASYNC, async_clock);
400 flip(p->ema, VG469_MODE_CABLE, cable_mode);
401 if (p->ctl & VG468_CTL_ASYNC)
402 strcat(buf, " [async]");
403 if (p->ctl & VG468_CTL_INPACK)
404 strcat(buf, " [inpack]");
405 if (socket[s].type == IS_VG469) {
406 u_char vsel = i365_get(s, VG469_VSELECT);
407 if (vsel & VG469_VSEL_EXT_STAT) {
408 strcat(buf, " [ext mode]");
409 if (vsel & VG469_VSEL_EXT_BUS)
410 strcat(buf, " [isa buf]");
411 }
412 if (p->ema & VG469_MODE_CABLE)
413 strcat(buf, " [cable]");
414 if (p->ema & VG469_MODE_COMPAT)
415 strcat(buf, " [c step]");
416 }
417 return 0xffff;
418}
419
420
421
422
423
424
425
426static void get_bridge_state(u_short s)
427{
428 struct i82365_socket *t = &socket[s];
429 if (t->flags & IS_CIRRUS)
430 cirrus_get_state(s);
431 else if (t->flags & IS_VADEM)
432 vg46x_get_state(s);
433}
434
435static void set_bridge_state(u_short s)
436{
437 struct i82365_socket *t = &socket[s];
438 if (t->flags & IS_CIRRUS)
439 cirrus_set_state(s);
440 else {
441 i365_set(s, I365_GBLCTL, 0x00);
442 i365_set(s, I365_GENCTL, 0x00);
443 }
444 i365_bflip(s, I365_INTCTL, I365_INTR_ENA, t->intr);
445 if (t->flags & IS_VADEM)
446 vg46x_set_state(s);
447}
448
449static u_int __init set_bridge_opts(u_short s, u_short ns)
450{
451 u_short i;
452 u_int m = 0xffff;
453 char buf[128];
454
455 for (i = s; i < s+ns; i++) {
456 if (socket[i].flags & IS_ALIVE) {
457 printk(KERN_INFO " host opts [%d]: already alive!\n", i);
458 continue;
459 }
460 buf[0] = '\0';
461 get_bridge_state(i);
462 if (socket[i].flags & IS_CIRRUS)
463 m = cirrus_set_opts(i, buf);
464 else if (socket[i].flags & IS_VADEM)
465 m = vg46x_set_opts(i, buf);
466 set_bridge_state(i);
467 printk(KERN_INFO " host opts [%d]:%s\n", i,
468 (*buf) ? buf : " none");
469 }
470 return m;
471}
472
473
474
475
476
477
478
479static volatile u_int irq_hits;
480static u_short irq_sock;
481
482static irqreturn_t i365_count_irq(int irq, void *dev)
483{
484 i365_get(irq_sock, I365_CSC);
485 irq_hits++;
486 pr_debug("i82365: -> hit on irq %d\n", irq);
487 return IRQ_HANDLED;
488}
489
490static u_int __init test_irq(u_short sock, int irq)
491{
492 pr_debug("i82365: testing ISA irq %d\n", irq);
493 if (request_irq(irq, i365_count_irq, IRQF_PROBE_SHARED, "scan",
494 i365_count_irq) != 0)
495 return 1;
496 irq_hits = 0; irq_sock = sock;
497 msleep(10);
498 if (irq_hits) {
499 free_irq(irq, i365_count_irq);
500 pr_debug("i82365: spurious hit!\n");
501 return 1;
502 }
503
504
505 i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (irq << 4));
506 i365_bset(sock, I365_GENCTL, I365_CTL_SW_IRQ);
507 udelay(1000);
508
509 free_irq(irq, i365_count_irq);
510
511
512 i365_set(sock, I365_CSCINT, 0);
513 pr_debug("i82365: hits = %d\n", irq_hits);
514
515 return (irq_hits != 1);
516}
517
518static u_int __init isa_scan(u_short sock, u_int mask0)
519{
520 u_int mask1 = 0;
521 int i;
522
523#ifdef __alpha__
524#define PIC 0x4d0
525
526 mask0 &= ~(inb(PIC) | (inb(PIC+1) << 8));
527#endif
528
529 if (do_scan) {
530 set_bridge_state(sock);
531 i365_set(sock, I365_CSCINT, 0);
532 for (i = 0; i < 16; i++)
533 if ((mask0 & (1 << i)) && (test_irq(sock, i) == 0))
534 mask1 |= (1 << i);
535 for (i = 0; i < 16; i++)
536 if ((mask1 & (1 << i)) && (test_irq(sock, i) != 0))
537 mask1 ^= (1 << i);
538 }
539
540 printk(KERN_INFO " ISA irqs (");
541 if (mask1) {
542 printk("scanned");
543 } else {
544
545 for (i = 0; i < 16; i++)
546 if ((mask0 & (1 << i)) && (_check_irq(i, IRQF_PROBE_SHARED) == 0))
547 mask1 |= (1 << i);
548 printk("default");
549
550 if (!cs_irq && (poll_interval == 0)) poll_interval = HZ;
551 }
552 printk(") = ");
553
554 for (i = 0; i < 16; i++)
555 if (mask1 & (1<<i))
556 printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
557 if (mask1 == 0) printk("none!");
558
559 return mask1;
560}
561
562
563
564
565
566static int to_cycles(int ns)
567{
568 return ns/cycle_time;
569}
570
571
572
573static int __init identify(unsigned int port, u_short sock)
574{
575 u_char val;
576 int type = -1;
577
578
579 socket[sockets].ioaddr = port;
580 socket[sockets].psock = sock;
581
582
583 if (wakeup) {
584 i365_bclr(sockets, PD67_MISC_CTL_2, PD67_MC2_SUSPEND);
585
586 mdelay(50);
587 }
588
589 if ((val = i365_get(sockets, I365_IDENT)) & 0x70)
590 return -1;
591 switch (val) {
592 case 0x82:
593 type = IS_I82365A; break;
594 case 0x83:
595 type = IS_I82365B; break;
596 case 0x84:
597 type = IS_I82365DF; break;
598 case 0x88: case 0x89: case 0x8a:
599 type = IS_IBM; break;
600 }
601
602
603 outb(0x0e, port);
604 outb(0x37, port);
605 i365_bset(sockets, VG468_MISC, VG468_MISC_VADEMREV);
606 val = i365_get(sockets, I365_IDENT);
607 if (val & I365_IDENT_VADEM) {
608 i365_bclr(sockets, VG468_MISC, VG468_MISC_VADEMREV);
609 type = ((val & 7) >= 4) ? IS_VG469 : IS_VG468;
610 }
611
612
613 val = i365_get(sockets, RF5C_CHIP_ID);
614 if ((val == RF5C_CHIP_RF5C296) || (val == RF5C_CHIP_RF5C396))
615 type = IS_RF5Cx96;
616
617
618 i365_set(sockets, PD67_CHIP_INFO, 0);
619 val = i365_get(sockets, PD67_CHIP_INFO);
620 if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) {
621 val = i365_get(sockets, PD67_CHIP_INFO);
622 if ((val & PD67_INFO_CHIP_ID) == 0) {
623 type = (val & PD67_INFO_SLOTS) ? IS_PD672X : IS_PD6710;
624 i365_set(sockets, PD67_EXT_INDEX, 0xe5);
625 if (i365_get(sockets, PD67_EXT_INDEX) != 0xe5)
626 type = IS_VT83C469;
627 }
628 }
629 return type;
630}
631
632
633
634
635
636
637
638
639
640
641static int __init is_alive(u_short sock)
642{
643 u_char stat;
644 unsigned int start, stop;
645
646 stat = i365_get(sock, I365_STATUS);
647 start = i365_get_pair(sock, I365_IO(0)+I365_W_START);
648 stop = i365_get_pair(sock, I365_IO(0)+I365_W_STOP);
649 if ((stat & I365_CS_DETECT) && (stat & I365_CS_POWERON) &&
650 (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD) &&
651 (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(0)) &&
652 ((start & 0xfeef) != 0x02e8)) {
653 if (!request_region(start, stop-start+1, "i82365"))
654 return 1;
655 release_region(start, stop-start+1);
656 }
657
658 return 0;
659}
660
661
662
663static void __init add_socket(unsigned int port, int psock, int type)
664{
665 socket[sockets].ioaddr = port;
666 socket[sockets].psock = psock;
667 socket[sockets].type = type;
668 socket[sockets].flags = pcic[type].flags;
669 if (is_alive(sockets))
670 socket[sockets].flags |= IS_ALIVE;
671 sockets++;
672}
673
674static void __init add_pcic(int ns, int type)
675{
676 u_int mask = 0, i, base;
677 int isa_irq = 0;
678 struct i82365_socket *t = &socket[sockets-ns];
679
680 base = sockets-ns;
681 if (base == 0) printk("\n");
682 printk(KERN_INFO " %s", pcic[type].name);
683 printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x",
684 t->ioaddr, t->psock*0x40);
685 printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : ""));
686
687
688 if (irq_list_count == 0)
689 mask = irq_mask;
690 else
691 for (i = mask = 0; i < irq_list_count; i++)
692 mask |= (1<<irq_list[i]);
693 mask &= I365_MASK & set_bridge_opts(base, ns);
694
695 mask = isa_scan(base, mask);
696
697
698 if (!poll_interval) {
699 u_int tmp = (mask & 0xff20);
700 tmp = tmp & (tmp-1);
701 if ((tmp & (tmp-1)) == 0)
702 poll_interval = HZ;
703 }
704
705 if (!grab_irq && (cs_irq || !poll_interval)) {
706
707 u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
708 for (cs_irq = 15; cs_irq > 0; cs_irq--)
709 if ((cs_mask & (1 << cs_irq)) &&
710 (_check_irq(cs_irq, IRQF_PROBE_SHARED) == 0))
711 break;
712 if (cs_irq) {
713 grab_irq = 1;
714 isa_irq = cs_irq;
715 printk(" status change on irq %d\n", cs_irq);
716 }
717 }
718
719 if (!isa_irq) {
720 if (poll_interval == 0)
721 poll_interval = HZ;
722 printk(" polling interval = %d ms\n",
723 poll_interval * 1000 / HZ);
724
725 }
726
727
728 for (i = 0; i < ns; i++) {
729 t[i].socket.features |= SS_CAP_PCCARD;
730 t[i].socket.map_size = 0x1000;
731 t[i].socket.irq_mask = mask;
732 t[i].cs_irq = isa_irq;
733 }
734
735}
736
737
738
739#ifdef CONFIG_PNP
740static struct isapnp_device_id id_table[] __initdata = {
741 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
742 ISAPNP_FUNCTION(0x0e00), (unsigned long) "Intel 82365-Compatible" },
743 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
744 ISAPNP_FUNCTION(0x0e01), (unsigned long) "Cirrus Logic CL-PD6720" },
745 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
746 ISAPNP_FUNCTION(0x0e02), (unsigned long) "VLSI VL82C146" },
747 { 0 }
748};
749MODULE_DEVICE_TABLE(isapnp, id_table);
750
751static struct pnp_dev *i82365_pnpdev;
752#endif
753
754static void __init isa_probe(void)
755{
756 int i, j, sock, k, ns, id;
757 unsigned int port;
758#ifdef CONFIG_PNP
759 struct isapnp_device_id *devid;
760 struct pnp_dev *dev;
761
762 for (devid = id_table; devid->vendor; devid++) {
763 if ((dev = pnp_find_dev(NULL, devid->vendor, devid->function, NULL))) {
764
765 if (pnp_device_attach(dev) < 0)
766 continue;
767
768 if (pnp_activate_dev(dev) < 0) {
769 printk("activate failed\n");
770 pnp_device_detach(dev);
771 break;
772 }
773
774 if (!pnp_port_valid(dev, 0)) {
775 printk("invalid resources ?\n");
776 pnp_device_detach(dev);
777 break;
778 }
779 i365_base = pnp_port_start(dev, 0);
780 i82365_pnpdev = dev;
781 break;
782 }
783 }
784#endif
785
786 if (!request_region(i365_base, 2, "i82365")) {
787 if (sockets == 0)
788 printk("port conflict at %#lx\n", i365_base);
789 return;
790 }
791
792 id = identify(i365_base, 0);
793 if ((id == IS_I82365DF) && (identify(i365_base, 1) != id)) {
794 for (i = 0; i < 4; i++) {
795 if (i == ignore) continue;
796 port = i365_base + ((i & 1) << 2) + ((i & 2) << 1);
797 sock = (i & 1) << 1;
798 if (identify(port, sock) == IS_I82365DF) {
799 add_socket(port, sock, IS_VLSI);
800 add_pcic(1, IS_VLSI);
801 }
802 }
803 } else {
804 for (i = 0; i < 8; i += 2) {
805 if (sockets && !extra_sockets && (i == 4))
806 break;
807 port = i365_base + 2*(i>>2);
808 sock = (i & 3);
809 id = identify(port, sock);
810 if (id < 0) continue;
811
812 for (j = ns = 0; j < 2; j++) {
813
814 if ((ignore == i+j) || (identify(port, sock+j) < 0))
815 continue;
816
817 for (k = 0; k <= sockets; k++)
818 i365_set(k, I365_MEM(0)+I365_W_OFF, k);
819 for (k = 0; k <= sockets; k++)
820 if (i365_get(k, I365_MEM(0)+I365_W_OFF) != k)
821 break;
822 if (k <= sockets) break;
823 add_socket(port, sock+j, id); ns++;
824 }
825 if (ns != 0) add_pcic(ns, id);
826 }
827 }
828}
829
830
831
832static irqreturn_t pcic_interrupt(int irq, void *dev)
833{
834 int i, j, csc;
835 u_int events, active;
836 u_long flags = 0;
837 int handled = 0;
838
839 pr_debug("pcic_interrupt(%d)\n", irq);
840
841 for (j = 0; j < 20; j++) {
842 active = 0;
843 for (i = 0; i < sockets; i++) {
844 if (socket[i].cs_irq != irq)
845 continue;
846 handled = 1;
847 ISA_LOCK(i, flags);
848 csc = i365_get(i, I365_CSC);
849 if ((csc == 0) || (i365_get(i, I365_IDENT) & 0x70)) {
850 ISA_UNLOCK(i, flags);
851 continue;
852 }
853 events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
854
855 if (i365_get(i, I365_INTCTL) & I365_PC_IOCARD)
856 events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
857 else {
858 events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
859 events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
860 events |= (csc & I365_CSC_READY) ? SS_READY : 0;
861 }
862 ISA_UNLOCK(i, flags);
863 pr_debug("socket %d event 0x%02x\n", i, events);
864
865 if (events)
866 pcmcia_parse_events(&socket[i].socket, events);
867
868 active |= events;
869 }
870 if (!active) break;
871 }
872 if (j == 20)
873 printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n");
874
875 pr_debug("pcic_interrupt done\n");
876 return IRQ_RETVAL(handled);
877}
878
879static void pcic_interrupt_wrapper(u_long data)
880{
881 pcic_interrupt(0, NULL);
882 poll_timer.expires = jiffies + poll_interval;
883 add_timer(&poll_timer);
884}
885
886
887
888static int i365_get_status(u_short sock, u_int *value)
889{
890 u_int status;
891
892 status = i365_get(sock, I365_STATUS);
893 *value = ((status & I365_CS_DETECT) == I365_CS_DETECT)
894 ? SS_DETECT : 0;
895
896 if (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD)
897 *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
898 else {
899 *value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
900 *value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
901 }
902 *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
903 *value |= (status & I365_CS_READY) ? SS_READY : 0;
904 *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
905
906 if (socket[sock].type == IS_VG469) {
907 status = i365_get(sock, VG469_VSENSE);
908 if (socket[sock].psock & 1) {
909 *value |= (status & VG469_VSENSE_B_VS1) ? 0 : SS_3VCARD;
910 *value |= (status & VG469_VSENSE_B_VS2) ? 0 : SS_XVCARD;
911 } else {
912 *value |= (status & VG469_VSENSE_A_VS1) ? 0 : SS_3VCARD;
913 *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD;
914 }
915 }
916
917 pr_debug("GetStatus(%d) = %#4.4x\n", sock, *value);
918 return 0;
919}
920
921
922
923static int i365_set_socket(u_short sock, socket_state_t *state)
924{
925 struct i82365_socket *t = &socket[sock];
926 u_char reg;
927
928 pr_debug("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
929 "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
930 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
931
932
933 set_bridge_state(sock);
934
935
936 reg = t->intr;
937 reg |= state->io_irq;
938 reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
939 reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
940 i365_set(sock, I365_INTCTL, reg);
941
942 reg = I365_PWR_NORESET;
943 if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
944 if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
945
946 if (t->flags & IS_CIRRUS) {
947 if (state->Vpp != 0) {
948 if (state->Vpp == 120)
949 reg |= I365_VPP1_12V;
950 else if (state->Vpp == state->Vcc)
951 reg |= I365_VPP1_5V;
952 else return -EINVAL;
953 }
954 if (state->Vcc != 0) {
955 reg |= I365_VCC_5V;
956 if (state->Vcc == 33)
957 i365_bset(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
958 else if (state->Vcc == 50)
959 i365_bclr(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
960 else return -EINVAL;
961 }
962 } else if (t->flags & IS_VG_PWR) {
963 if (state->Vpp != 0) {
964 if (state->Vpp == 120)
965 reg |= I365_VPP1_12V;
966 else if (state->Vpp == state->Vcc)
967 reg |= I365_VPP1_5V;
968 else return -EINVAL;
969 }
970 if (state->Vcc != 0) {
971 reg |= I365_VCC_5V;
972 if (state->Vcc == 33)
973 i365_bset(sock, VG469_VSELECT, VG469_VSEL_VCC);
974 else if (state->Vcc == 50)
975 i365_bclr(sock, VG469_VSELECT, VG469_VSEL_VCC);
976 else return -EINVAL;
977 }
978 } else if (t->flags & IS_DF_PWR) {
979 switch (state->Vcc) {
980 case 0: break;
981 case 33: reg |= I365_VCC_3V; break;
982 case 50: reg |= I365_VCC_5V; break;
983 default: return -EINVAL;
984 }
985 switch (state->Vpp) {
986 case 0: break;
987 case 50: reg |= I365_VPP1_5V; break;
988 case 120: reg |= I365_VPP1_12V; break;
989 default: return -EINVAL;
990 }
991 } else {
992 switch (state->Vcc) {
993 case 0: break;
994 case 50: reg |= I365_VCC_5V; break;
995 default: return -EINVAL;
996 }
997 switch (state->Vpp) {
998 case 0: break;
999 case 50: reg |= I365_VPP1_5V | I365_VPP2_5V; break;
1000 case 120: reg |= I365_VPP1_12V | I365_VPP2_12V; break;
1001 default: return -EINVAL;
1002 }
1003 }
1004
1005 if (reg != i365_get(sock, I365_POWER))
1006 i365_set(sock, I365_POWER, reg);
1007
1008
1009 if (t->flags & IS_CIRRUS) {
1010
1011 i365_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA,
1012 state->flags & SS_SPKR_ENA);
1013 }
1014
1015
1016 reg = t->cs_irq << 4;
1017 if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
1018 if (state->flags & SS_IOCARD) {
1019 if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
1020 } else {
1021 if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;
1022 if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
1023 if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
1024 }
1025 i365_set(sock, I365_CSCINT, reg);
1026 i365_get(sock, I365_CSC);
1027
1028 return 0;
1029}
1030
1031
1032
1033static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
1034{
1035 u_char map, ioctl;
1036
1037 pr_debug("SetIOMap(%d, %d, %#2.2x, %d ns, "
1038 "%#llx-%#llx)\n", sock, io->map, io->flags, io->speed,
1039 (unsigned long long)io->start, (unsigned long long)io->stop);
1040 map = io->map;
1041 if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
1042 (io->stop < io->start)) return -EINVAL;
1043
1044 if (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(map))
1045 i365_bclr(sock, I365_ADDRWIN, I365_ENA_IO(map));
1046 i365_set_pair(sock, I365_IO(map)+I365_W_START, io->start);
1047 i365_set_pair(sock, I365_IO(map)+I365_W_STOP, io->stop);
1048 ioctl = i365_get(sock, I365_IOCTL) & ~I365_IOCTL_MASK(map);
1049 if (io->speed) ioctl |= I365_IOCTL_WAIT(map);
1050 if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
1051 if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
1052 if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
1053 i365_set(sock, I365_IOCTL, ioctl);
1054
1055 if (io->flags & MAP_ACTIVE)
1056 i365_bset(sock, I365_ADDRWIN, I365_ENA_IO(map));
1057 return 0;
1058}
1059
1060
1061
1062static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
1063{
1064 u_short base, i;
1065 u_char map;
1066
1067 pr_debug("SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, "
1068 "%#x)\n", sock, mem->map, mem->flags, mem->speed,
1069 (unsigned long long)mem->res->start,
1070 (unsigned long long)mem->res->end, mem->card_start);
1071
1072 map = mem->map;
1073 if ((map > 4) || (mem->card_start > 0x3ffffff) ||
1074 (mem->res->start > mem->res->end) || (mem->speed > 1000))
1075 return -EINVAL;
1076 if ((mem->res->start > 0xffffff) || (mem->res->end > 0xffffff))
1077 return -EINVAL;
1078
1079
1080 if (i365_get(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
1081 i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map));
1082
1083 base = I365_MEM(map);
1084 i = (mem->res->start >> 12) & 0x0fff;
1085 if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT;
1086 if (mem->flags & MAP_0WS) i |= I365_MEM_0WS;
1087 i365_set_pair(sock, base+I365_W_START, i);
1088
1089 i = (mem->res->end >> 12) & 0x0fff;
1090 switch (to_cycles(mem->speed)) {
1091 case 0: break;
1092 case 1: i |= I365_MEM_WS0; break;
1093 case 2: i |= I365_MEM_WS1; break;
1094 default: i |= I365_MEM_WS1 | I365_MEM_WS0; break;
1095 }
1096 i365_set_pair(sock, base+I365_W_STOP, i);
1097
1098 i = ((mem->card_start - mem->res->start) >> 12) & 0x3fff;
1099 if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT;
1100 if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG;
1101 i365_set_pair(sock, base+I365_W_OFF, i);
1102
1103
1104 if (mem->flags & MAP_ACTIVE)
1105 i365_bset(sock, I365_ADDRWIN, I365_ENA_MEM(map));
1106 return 0;
1107}
1108
1109#if 0
1110
1111
1112
1113
1114
1115
1116
1117static ssize_t show_info(struct class_device *class_dev, char *buf)
1118{
1119 struct i82365_socket *s = container_of(class_dev, struct i82365_socket, socket.dev);
1120 return sprintf(buf, "type: %s\npsock: %d\n",
1121 pcic[s->type].name, s->psock);
1122}
1123
1124static ssize_t show_exca(struct class_device *class_dev, char *buf)
1125{
1126 struct i82365_socket *s = container_of(class_dev, struct i82365_socket, socket.dev);
1127 unsigned short sock;
1128 int i;
1129 ssize_t ret = 0;
1130 unsigned long flags = 0;
1131
1132 sock = s->number;
1133
1134 ISA_LOCK(sock, flags);
1135 for (i = 0; i < 0x40; i += 4) {
1136 ret += sprintf(buf, "%02x %02x %02x %02x%s",
1137 i365_get(sock,i), i365_get(sock,i+1),
1138 i365_get(sock,i+2), i365_get(sock,i+3),
1139 ((i % 16) == 12) ? "\n" : " ");
1140 buf += ret;
1141 }
1142 ISA_UNLOCK(sock, flags);
1143
1144 return ret;
1145}
1146
1147static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);
1148static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
1149#endif
1150
1151
1152
1153
1154
1155#define LOCKED(x) do { \
1156 int retval; \
1157 unsigned long flags; \
1158 spin_lock_irqsave(&isa_lock, flags); \
1159 retval = x; \
1160 spin_unlock_irqrestore(&isa_lock, flags); \
1161 return retval; \
1162} while (0)
1163
1164
1165static int pcic_get_status(struct pcmcia_socket *s, u_int *value)
1166{
1167 unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1168
1169 if (socket[sock].flags & IS_ALIVE) {
1170 *value = 0;
1171 return -EINVAL;
1172 }
1173
1174 LOCKED(i365_get_status(sock, value));
1175}
1176
1177static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state)
1178{
1179 unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1180
1181 if (socket[sock].flags & IS_ALIVE)
1182 return -EINVAL;
1183
1184 LOCKED(i365_set_socket(sock, state));
1185}
1186
1187static int pcic_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
1188{
1189 unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1190 if (socket[sock].flags & IS_ALIVE)
1191 return -EINVAL;
1192
1193 LOCKED(i365_set_io_map(sock, io));
1194}
1195
1196static int pcic_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
1197{
1198 unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1199 if (socket[sock].flags & IS_ALIVE)
1200 return -EINVAL;
1201
1202 LOCKED(i365_set_mem_map(sock, mem));
1203}
1204
1205static int pcic_init(struct pcmcia_socket *s)
1206{
1207 int i;
1208 struct resource res = { .start = 0, .end = 0x1000 };
1209 pccard_io_map io = { 0, 0, 0, 0, 1 };
1210 pccard_mem_map mem = { .res = &res, };
1211
1212 for (i = 0; i < 2; i++) {
1213 io.map = i;
1214 pcic_set_io_map(s, &io);
1215 }
1216 for (i = 0; i < 5; i++) {
1217 mem.map = i;
1218 pcic_set_mem_map(s, &mem);
1219 }
1220 return 0;
1221}
1222
1223
1224static struct pccard_operations pcic_operations = {
1225 .init = pcic_init,
1226 .get_status = pcic_get_status,
1227 .set_socket = pcic_set_socket,
1228 .set_io_map = pcic_set_io_map,
1229 .set_mem_map = pcic_set_mem_map,
1230};
1231
1232
1233
1234static struct platform_driver i82365_driver = {
1235 .driver = {
1236 .name = "i82365",
1237 .owner = THIS_MODULE,
1238 },
1239};
1240
1241static struct platform_device *i82365_device;
1242
1243static int __init init_i82365(void)
1244{
1245 int i, ret;
1246
1247 ret = platform_driver_register(&i82365_driver);
1248 if (ret)
1249 goto err_out;
1250
1251 i82365_device = platform_device_alloc("i82365", 0);
1252 if (i82365_device) {
1253 ret = platform_device_add(i82365_device);
1254 if (ret)
1255 platform_device_put(i82365_device);
1256 } else
1257 ret = -ENOMEM;
1258
1259 if (ret)
1260 goto err_driver_unregister;
1261
1262 printk(KERN_INFO "Intel ISA PCIC probe: ");
1263 sockets = 0;
1264
1265 isa_probe();
1266
1267 if (sockets == 0) {
1268 printk("not found.\n");
1269 ret = -ENODEV;
1270 goto err_dev_unregister;
1271 }
1272
1273
1274 if (grab_irq != 0)
1275 ret = request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
1276
1277 if (ret)
1278 goto err_socket_release;
1279
1280
1281 for (i = 0; i < sockets; i++) {
1282 socket[i].socket.dev.parent = &i82365_device->dev;
1283 socket[i].socket.ops = &pcic_operations;
1284 socket[i].socket.resource_ops = &pccard_nonstatic_ops;
1285 socket[i].socket.owner = THIS_MODULE;
1286 socket[i].number = i;
1287 ret = pcmcia_register_socket(&socket[i].socket);
1288 if (!ret)
1289 socket[i].flags |= IS_REGISTERED;
1290
1291#if 0
1292 class_device_create_file(&socket[i].socket.dev,
1293 &class_device_attr_info);
1294 class_device_create_file(&socket[i].socket.dev,
1295 &class_device_attr_exca);
1296#endif
1297 }
1298
1299
1300 if (poll_interval != 0) {
1301 poll_timer.function = pcic_interrupt_wrapper;
1302 poll_timer.data = 0;
1303 init_timer(&poll_timer);
1304 poll_timer.expires = jiffies + poll_interval;
1305 add_timer(&poll_timer);
1306 }
1307
1308 return 0;
1309err_socket_release:
1310 for (i = 0; i < sockets; i++) {
1311
1312 i365_set(i, I365_CSCINT, 0);
1313 release_region(socket[i].ioaddr, 2);
1314 }
1315err_dev_unregister:
1316 platform_device_unregister(i82365_device);
1317 release_region(i365_base, 2);
1318#ifdef CONFIG_PNP
1319 if (i82365_pnpdev)
1320 pnp_disable_dev(i82365_pnpdev);
1321#endif
1322err_driver_unregister:
1323 platform_driver_unregister(&i82365_driver);
1324err_out:
1325 return ret;
1326}
1327
1328static void __exit exit_i82365(void)
1329{
1330 int i;
1331
1332 for (i = 0; i < sockets; i++) {
1333 if (socket[i].flags & IS_REGISTERED)
1334 pcmcia_unregister_socket(&socket[i].socket);
1335 }
1336 platform_device_unregister(i82365_device);
1337 if (poll_interval != 0)
1338 del_timer_sync(&poll_timer);
1339 if (grab_irq != 0)
1340 free_irq(cs_irq, pcic_interrupt);
1341 for (i = 0; i < sockets; i++) {
1342
1343 i365_set(i, I365_CSCINT, 0);
1344 release_region(socket[i].ioaddr, 2);
1345 }
1346 release_region(i365_base, 2);
1347#ifdef CONFIG_PNP
1348 if (i82365_pnpdev)
1349 pnp_disable_dev(i82365_pnpdev);
1350#endif
1351 platform_driver_unregister(&i82365_driver);
1352}
1353
1354module_init(init_i82365);
1355module_exit(exit_i82365);
1356MODULE_LICENSE("Dual MPL/GPL");
1357
1358