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