FreeBSD/Linux Kernel Cross Reference
sys/pccard/pcic.c
1 /*
2 * Intel PCIC or compatible Controller driver
3 * May be built to make a loadable module.
4 *-------------------------------------------------------------------------
5 *
6 * Copyright (c) 1995 Andrew McRae. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * $FreeBSD$
31 */
32
33 /*
34 * pcic98 : PC9801 original PCMCIA controller code for NS/A,Ne,NX/C,NR/L.
35 * by Noriyuki Hosobuchi <yj8n-hsbc@asahi-net.or.jp>
36 */
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/module.h>
42 #include <sys/select.h>
43 #include <sys/interrupt.h>
44
45 #include <machine/clock.h>
46
47 #include <i386/isa/icu.h>
48 #include <i386/isa/isa_device.h>
49
50 #include <pccard/i82365.h>
51 #ifdef PC98
52 #include <pccard/pcic98reg.h>
53 #endif
54
55 #include <pccard/cardinfo.h>
56 #include <pccard/driver.h>
57 #include <pccard/slot.h>
58
59 #ifdef APIC_IO
60 #include <machine/smp.h>
61 #endif /* APIC_IO */
62 /*
63 * Prototypes for interrupt handler.
64 */
65 static inthand2_t pcicintr;
66 static int pcic_ioctl __P((struct slot *, int, caddr_t));
67 static int pcic_power __P((struct slot *));
68 static timeout_t pcic_reset;
69 static void pcic_resume(struct slot *);
70 static void pcic_disable __P((struct slot *));
71 static void pcic_mapirq __P((struct slot *, int));
72 static timeout_t pcictimeout;
73 static struct callout_handle pcictimeout_ch
74 = CALLOUT_HANDLE_INITIALIZER(&pcictimeout_ch);
75 static int pcic_modevent __P((module_t, int, void *));
76 static int pcic_unload __P((void));
77 static int pcic_memory(struct slot *, int);
78 static int pcic_io(struct slot *, int);
79 static u_int build_freelist(u_int);
80
81 /*
82 * Per-slot data table.
83 */
84 static struct pcic_slot {
85 int slotnum; /* My slot number */
86 int index; /* Index register */
87 int data; /* Data register */
88 int offset; /* Offset value for index */
89 char controller; /* Device type */
90 char revision; /* Device Revision */
91 struct slot *slt; /* Back ptr to slot */
92 u_char (*getb)(struct pcic_slot *, int);
93 void (*putb)(struct pcic_slot *, int, u_char);
94 u_char *regs; /* Pointer to regs in mem */
95 } pcic_slots[PCIC_MAX_SLOTS];
96
97 static int pcic_irq;
98 static unsigned pcic_imask;
99 static struct slot_ctrl cinfo;
100
101
102 /*
103 * Internal inline functions for accessing the PCIC.
104 */
105 /*
106 * Read a register from the PCIC.
107 */
108 static __inline unsigned char
109 getb1(struct pcic_slot *sp, int reg)
110 {
111 outb(sp->index, sp->offset + reg);
112 return inb(sp->data);
113 }
114
115 static __inline unsigned char
116 getb2(struct pcic_slot *sp, int reg)
117 {
118 return (sp->regs[reg]);
119 }
120
121 /*
122 * Write a register on the PCIC
123 */
124 static __inline void
125 putb1(struct pcic_slot *sp, int reg, unsigned char val)
126 {
127 outb(sp->index, sp->offset + reg);
128 outb(sp->data, val);
129 }
130
131 static __inline void
132 putb2(struct pcic_slot *sp, int reg, unsigned char val)
133 {
134 sp->regs[reg] = val;
135 }
136
137 /*
138 * Clear bit(s) of a register.
139 */
140 static __inline void
141 clrb(struct pcic_slot *sp, int reg, unsigned char mask)
142 {
143 sp->putb(sp, reg, sp->getb(sp, reg) & ~mask);
144 }
145
146 /*
147 * Set bit(s) of a register
148 */
149 static __inline void
150 setb(struct pcic_slot *sp, int reg, unsigned char mask)
151 {
152 sp->putb(sp, reg, sp->getb(sp, reg) | mask);
153 }
154
155 /*
156 * Write a 16 bit value to 2 adjacent PCIC registers
157 */
158 static __inline void
159 putw(struct pcic_slot *sp, int reg, unsigned short word)
160 {
161 sp->putb(sp, reg, word & 0xFF);
162 sp->putb(sp, reg + 1, (word >> 8) & 0xff);
163 }
164
165
166 /*
167 * Loadable kernel module interface.
168 */
169
170 /*
171 * Module handler that processes loads and unloads.
172 * Once the module is loaded, the probe routine
173 * is called to install the slots (if any).
174 */
175 static int
176 pcic_modevent(module_t mod, int what, void *arg)
177 {
178 int err = 0; /* default = success*/
179 static int pcic_started = 0;
180
181 switch (what) {
182 case MOD_LOAD:
183
184 /*
185 * Call the probe routine to find the slots. If
186 * no slots exist, then don't bother loading the module.
187 * XXX but this is not appropriate as a static module.
188 */
189 if (pcic_probe())
190 pcic_started = 1;
191 break;
192
193 case MOD_UNLOAD:
194 /*
195 * Attempt to unload the slot driver.
196 */
197 if (pcic_started) {
198 printf("Unloading PCIC driver\n");
199 err = pcic_unload();
200 pcic_started = 0;
201 }
202 break; /* Success*/
203
204 default: /* we only care about load/unload; ignore shutdown */
205 break;
206 }
207
208 return(err);
209 }
210
211 static moduledata_t pcic_mod = {
212 "pcic",
213 pcic_modevent,
214 0
215 };
216
217 /* After configure() has run.. bring on the new bus system! */
218 DECLARE_MODULE(pcic, pcic_mod, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE);
219
220 /*
221 * pcic_unload - Called when unloading a LKM.
222 * Disables interrupts and resets PCIC.
223 */
224 static int
225 pcic_unload()
226 {
227 int slot;
228 struct pcic_slot *sp = pcic_slots;
229
230 untimeout(pcictimeout, 0, pcictimeout_ch);
231 if (pcic_irq) {
232 for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++) {
233 if (sp->slt)
234 sp->putb(sp, PCIC_STAT_INT, 0);
235 }
236 unregister_intr(pcic_irq, pcicintr);
237 }
238 pccard_remove_controller(&cinfo);
239 return(0);
240 }
241
242
243 #if 0
244 static void
245 pcic_dump_attributes(unsigned char *scratch, int maxlen)
246 {
247 int i,j,k;
248
249 i = 0;
250 while (scratch[i] != 0xff && i < maxlen) {
251 unsigned char link = scratch[i+2];
252
253 /*
254 * Dump attribute memory
255 */
256 if (scratch[i]) {
257 printf("[%02x] ", i);
258 for (j = 0; j < 2 * link + 4 && j < 128; j += 2)
259 printf("%02x ", scratch[j + i]);
260 printf("\n");
261 }
262 i += 4 + 2 * link;
263 }
264 }
265 #endif
266
267 static void
268 nullfunc(void *unused)
269 {
270 /* empty */
271 }
272
273 static u_int
274 build_freelist(u_int pcic_mask)
275 {
276 int irq;
277 u_int mask, freemask;
278
279 /* No free IRQs (yet). */
280 freemask = 0;
281
282 /* Walk through all of the IRQ's and find any that aren't allocated. */
283 for (irq = 1; irq < ICU_LEN; irq++) {
284 /*
285 * If the PCIC controller can't generate it, don't
286 * bother checking to see if it it's free.
287 */
288 mask = 1 << irq;
289 if (!(mask & pcic_mask)) continue;
290
291 #ifdef APIC_IO
292 /* When using the APIC, ISA IRQs get mapped onto APIC IRQs
293 * (see mptable). Check which APIC IRQ the PCIC controller's
294 * IRQ will map to. Only allow interrupts where the APIC IRQ
295 * is the same as the PCIC controller's IRQ.
296 * This avoids the problem of tracking both PCIC IRQs and
297 * interrupt masks and APIC IRQs and interrupt masks.
298 */
299 if (isa_apic_irq(irq) != irq)
300 continue;
301 #endif /* APIC_IO */
302
303 /* See if the IRQ is free. */
304 if (register_intr(irq, 0, 0, nullfunc, NULL, irq) == 0) {
305 /* Give it back, but add it to the mask */
306 INTRMASK(freemask, mask);
307 unregister_intr(irq, nullfunc);
308 }
309 }
310 #ifdef PCIC_DEBUG
311 printf("Freelist of IRQ's <0x%x>\n", freemask);
312 #endif
313 return freemask;
314 }
315
316 /*
317 * entry point from main code to map/unmap memory context.
318 */
319 static int
320 pcic_memory(struct slot *slt, int win)
321 {
322 struct pcic_slot *sp = slt->cdata;
323 struct mem_desc *mp = &slt->mem[win];
324 int reg = mp->window * PCIC_MEMSIZE + PCIC_MEMBASE;
325
326 #ifdef PC98
327 if (sp->controller == PCIC_PC98) {
328 if (mp->flags & MDF_ACTIVE) {
329 /* slot = 0, window = 0, sys_addr = 0xda000, length = 8KB */
330 unsigned char x;
331
332 if ((unsigned long)mp->start != 0xda000) {
333 printf("sys_addr must be 0xda000. requested address = 0x%x\n",
334 mp->start);
335 return(EINVAL);
336 }
337
338 /* omajinai ??? */
339 outb(PCIC98_REG0, 0);
340 x = inb(PCIC98_REG1);
341 x &= 0xfc;
342 x |= 0x02;
343 outb(PCIC98_REG1, x);
344
345 outw(PCIC98_REG_PAGOFS, 0);
346
347 if (mp->flags & MDF_ATTR) {
348 outb(PCIC98_REG6, inb(PCIC98_REG6) | PCIC98_ATTRMEM);
349 }else{
350 outb(PCIC98_REG6, inb(PCIC98_REG6) & (~PCIC98_ATTRMEM));
351 }
352
353 outb(PCIC98_REG_WINSEL, PCIC98_MAPWIN);
354
355 #if 0
356 if ((mp->flags & MDF_16BITS) == 1) { /* 16bit */
357 outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_8BIT));
358 }else{ /* 8bit */
359 outb(PCIC98_REG2, inb(PCIC98_REG2) | PCIC98_8BIT);
360 }
361 #endif
362 }else{
363 outb(PCIC98_REG_WINSEL, PCIC98_UNMAPWIN);
364 }
365 return 0;
366 }
367 #endif /* PC98 */
368
369 if (mp->flags & MDF_ACTIVE) {
370 unsigned long sys_addr = (uintptr_t)(void *)mp->start >> 12;
371 /*
372 * Write the addresses, card offsets and length.
373 * The values are all stored as the upper 12 bits of the
374 * 24 bit address i.e everything is allocated as 4 Kb chunks.
375 */
376 putw(sp, reg, sys_addr & 0xFFF);
377 putw(sp, reg+2, (sys_addr + (mp->size >> 12) - 1) & 0xFFF);
378 putw(sp, reg+4, ((mp->card >> 12) - sys_addr) & 0x3FFF);
379 #if 0
380 printf("card offs = card_adr = 0x%x 0x%x, sys_addr = 0x%x\n",
381 mp->card, ((mp->card >> 12) - sys_addr) & 0x3FFF,
382 sys_addr);
383 #endif
384 /*
385 * Each 16 bit register has some flags in the upper bits.
386 */
387 if (mp->flags & MDF_16BITS)
388 setb(sp, reg+1, PCIC_DATA16);
389 if (mp->flags & MDF_ZEROWS)
390 setb(sp, reg+1, PCIC_ZEROWS);
391 if (mp->flags & MDF_WS0)
392 setb(sp, reg+3, PCIC_MW0);
393 if (mp->flags & MDF_WS1)
394 setb(sp, reg+3, PCIC_MW1);
395 if (mp->flags & MDF_ATTR)
396 setb(sp, reg+5, PCIC_REG);
397 if (mp->flags & MDF_WP)
398 setb(sp, reg+5, PCIC_WP);
399 #if 0
400 printf("Slot number %d, reg 0x%x, offs 0x%x\n",
401 sp->slotnum, reg, sp->offset);
402 printf("Map window to sys addr 0x%x for %d bytes, card 0x%x\n",
403 mp->start, mp->size, mp->card);
404 printf("regs are: 0x%02x%02x 0x%02x%02x 0x%02x%02x flags 0x%x\n",
405 sp->getb(sp, reg), sp->getb(sp, reg+1),
406 sp->getb(sp, reg+2), sp->getb(sp, reg+3),
407 sp->getb(sp, reg+4), sp->getb(sp, reg+5),
408 mp->flags);
409 #endif
410 /*
411 * Enable the memory window. By experiment, we need a delay.
412 */
413 setb(sp, PCIC_ADDRWINE, (1<<win) | PCIC_MEMCS16);
414 DELAY(50);
415 } else {
416 #if 0
417 printf("Unmapping window %d\n", win);
418 #endif
419 clrb(sp, PCIC_ADDRWINE, 1<<win);
420 putw(sp, reg, 0);
421 putw(sp, reg+2, 0);
422 putw(sp, reg+4, 0);
423 }
424 return(0);
425 }
426
427 /*
428 * pcic_io - map or unmap I/O context
429 */
430 static int
431 pcic_io(struct slot *slt, int win)
432 {
433 int mask, reg;
434 struct pcic_slot *sp = slt->cdata;
435 struct io_desc *ip = &slt->io[win];
436 #ifdef PC98
437 if (sp->controller == PCIC_PC98) {
438 unsigned char x;
439
440 #if 0
441 if (win =! 0) {
442 printf("pcic98:Illegal PCIC I/O window request(%d)!", win);
443 return(EINVAL);
444 }
445 #endif
446
447 if (ip->flags & IODF_ACTIVE) {
448 unsigned short base;
449
450 x = inb(PCIC98_REG2) & 0x0f;
451 if (! (ip->flags & IODF_16BIT))
452 x |= PCIC98_8BIT;
453
454 if (ip->size > 16) /* 128bytes mapping */
455 x |= PCIC98_MAP128;
456
457 x |= PCIC98_IOMEMORY;
458 outb(PCIC98_REG2, x);
459
460 base = 0x80d0;
461 outw(PCIC98_REG4, base); /* 98side IO base */
462 outw(PCIC98_REG5, ip->start); /* card side IO base */
463
464 #ifdef PCIC_DEBUG
465 printf("pcic98: IO mapped 0x%04x(98) -> 0x%04x(Card) and width %d bytes\n",
466 base, ip->start, ip->size);
467 #endif
468 ip->start = base;
469
470 }else{
471 outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_IOMEMORY));
472 }
473 return 0;
474 }
475 #endif
476 switch (win) {
477 case 0:
478 mask = PCIC_IO0_EN;
479 reg = PCIC_IO0;
480 break;
481 case 1:
482 mask = PCIC_IO1_EN;
483 reg = PCIC_IO1;
484 break;
485 default:
486 panic("Illegal PCIC I/O window request!");
487 }
488 if (ip->flags & IODF_ACTIVE) {
489 unsigned char x, ioctlv;
490
491 #ifdef PCIC_DEBUG
492 printf("Map I/O 0x%x (size 0x%x) on Window %d\n", ip->start, ip->size, win);
493 #endif /* PCIC_DEBUG */
494 putw(sp, reg, ip->start);
495 putw(sp, reg+2, ip->start+ip->size-1);
496 x = 0;
497 if (ip->flags & IODF_ZEROWS)
498 x |= PCIC_IO_0WS;
499 if (ip->flags & IODF_WS)
500 x |= PCIC_IO_WS;
501 if (ip->flags & IODF_CS16)
502 x |= PCIC_IO_CS16;
503 if (ip->flags & IODF_16BIT)
504 x |= PCIC_IO_16BIT;
505 /*
506 * Extract the current flags and merge with new flags.
507 * Flags for window 0 in lower nybble, and in upper nybble
508 * for window 1.
509 */
510 ioctlv = sp->getb(sp, PCIC_IOCTL);
511 DELAY(100);
512 switch (win) {
513 case 0:
514 sp->putb(sp, PCIC_IOCTL, x | (ioctlv & 0xf0));
515 break;
516 case 1:
517 sp->putb(sp, PCIC_IOCTL, (x << 4) | (ioctlv & 0xf));
518 break;
519 }
520 DELAY(100);
521 setb(sp, PCIC_ADDRWINE, mask);
522 DELAY(100);
523 } else {
524 clrb(sp, PCIC_ADDRWINE, mask);
525 DELAY(100);
526 putw(sp, reg, 0);
527 putw(sp, reg + 2, 0);
528 }
529 return(0);
530 }
531
532 /*
533 * Look for an Intel PCIC (or compatible).
534 * For each available slot, allocate a PC-CARD slot.
535 */
536
537 /*
538 * VLSI 82C146 has incompatibilities about the I/O address
539 * of slot 1. Assume it's the only PCIC whose vendor ID is 0x84,
540 * contact Nate Williams <nate@FreeBSD.org> if incorrect.
541 */
542 int
543 pcic_probe(void)
544 {
545 int slotnum, validslots = 0;
546 u_int free_irqs, desired_irq;
547 struct slot *slt;
548 struct pcic_slot *sp;
549 unsigned char c;
550 static int maybe_vlsi = 0;
551
552 /* Determine the list of free interrupts */
553 free_irqs = build_freelist(PCIC_INT_MASK_ALLOWED);
554
555 /*
556 * Initialise controller information structure.
557 */
558 cinfo.mapmem = pcic_memory;
559 cinfo.mapio = pcic_io;
560 cinfo.ioctl = pcic_ioctl;
561 cinfo.power = pcic_power;
562 cinfo.mapirq = pcic_mapirq;
563 cinfo.reset = pcic_reset;
564 cinfo.disable = pcic_disable;
565 cinfo.resume = pcic_resume;
566 cinfo.maxmem = PCIC_MEM_WIN;
567 cinfo.maxio = PCIC_IO_WIN;
568 cinfo.irqs = free_irqs;
569 cinfo.imask = &pcic_imask;
570
571 sp = pcic_slots;
572 for (slotnum = 0; slotnum < PCIC_MAX_SLOTS; slotnum++, sp++) {
573 /*
574 * Initialise the PCIC slot table.
575 */
576 sp->getb = getb1;
577 sp->putb = putb1;
578 if (slotnum < 4) {
579 sp->index = PCIC_INDEX_0;
580 sp->data = PCIC_DATA_0;
581 sp->offset = slotnum * PCIC_SLOT_SIZE;
582 } else {
583 sp->index = PCIC_INDEX_1;
584 sp->data = PCIC_DATA_1;
585 sp->offset = (slotnum - 4) * PCIC_SLOT_SIZE;
586 }
587 /*
588 * XXX - Screwed up slot 1 on the VLSI chips. According to
589 * the Linux PCMCIA code from David Hinds, working chipsets
590 * return 0x84 from their (correct) ID ports, while the broken
591 * ones would need to be probed at the new offset we set after
592 * we assume it's broken.
593 */
594 if (slotnum == 1 && maybe_vlsi && sp->getb(sp, PCIC_ID_REV) != 0x84) {
595 sp->index += 4;
596 sp->data += 4;
597 sp->offset = PCIC_SLOT_SIZE << 1;
598 }
599 /*
600 * see if there's a PCMCIA controller here
601 * Intel PCMCIA controllers use 0x82 and 0x83
602 * IBM clone chips use 0x88 and 0x89, apparently
603 */
604 c = sp->getb(sp, PCIC_ID_REV);
605 sp->revision = -1;
606 switch(c) {
607 /*
608 * 82365 or clones.
609 */
610 case 0x82:
611 case 0x83:
612 sp->controller = PCIC_I82365;
613 sp->revision = c & 1;
614 /*
615 * Now check for VADEM chips.
616 */
617 outb(sp->index, 0x0E);
618 outb(sp->index, 0x37);
619 setb(sp, 0x3A, 0x40);
620 c = sp->getb(sp, PCIC_ID_REV);
621 if (c & 0x08) {
622 switch (sp->revision = c & 7) {
623 case 1:
624 sp->controller = PCIC_VG365;
625 break;
626 case 2:
627 sp->controller = PCIC_VG465;
628 break;
629 case 3:
630 sp->controller = PCIC_VG468;
631 break;
632 default:
633 sp->controller = PCIC_VG469;
634 break;
635 }
636 clrb(sp, 0x3A, 0x40);
637 }
638
639 /*
640 * Check for RICOH RF5C396 PCMCIA Controller
641 */
642 c = sp->getb(sp, 0x3a);
643 if (c == 0xb2) {
644 sp->controller = PCIC_RF5C396;
645 }
646
647 break;
648 /*
649 * VLSI chips.
650 */
651 case 0x84:
652 sp->controller = PCIC_VLSI;
653 maybe_vlsi = 1;
654 break;
655 case 0x88:
656 case 0x89:
657 sp->controller = PCIC_IBM;
658 sp->revision = c & 1;
659 break;
660 case 0x8a:
661 sp->controller = PCIC_IBM_KING;
662 sp->revision = c & 1;
663 break;
664 default:
665 continue;
666 }
667 /*
668 * Check for Cirrus logic chips.
669 */
670 sp->putb(sp, 0x1F, 0);
671 c = sp->getb(sp, 0x1F);
672 if ((c & 0xC0) == 0xC0) {
673 c = sp->getb(sp, 0x1F);
674 if ((c & 0xC0) == 0) {
675 if (c & 0x20)
676 sp->controller = PCIC_PD672X;
677 else
678 sp->controller = PCIC_PD6710;
679 sp->revision = 8 - ((c & 0x1F) >> 2);
680 }
681 }
682 switch(sp->controller) {
683 case PCIC_I82365:
684 cinfo.name = "Intel 82365";
685 break;
686 case PCIC_IBM:
687 cinfo.name = "IBM PCIC";
688 break;
689 case PCIC_IBM_KING:
690 cinfo.name = "IBM KING PCMCIA Controller";
691 break;
692 case PCIC_PD672X:
693 cinfo.name = "Cirrus Logic PD672X";
694 break;
695 case PCIC_PD6710:
696 cinfo.name = "Cirrus Logic PD6710";
697 break;
698 case PCIC_VG365:
699 cinfo.name = "Vadem 365";
700 break;
701 case PCIC_VG465:
702 cinfo.name = "Vadem 465";
703 break;
704 case PCIC_VG468:
705 cinfo.name = "Vadem 468";
706 break;
707 case PCIC_VG469:
708 cinfo.name = "Vadem 469";
709 break;
710 case PCIC_RF5C396:
711 cinfo.name = "Ricoh RF5C396";
712 break;
713 case PCIC_VLSI:
714 cinfo.name = "VLSI 82C146";
715 break;
716 default:
717 cinfo.name = "Unknown!";
718 break;
719 }
720 /*
721 * OK it seems we have a PCIC or lookalike.
722 * Allocate a slot and initialise the data structures.
723 */
724 validslots++;
725 sp->slotnum = slotnum;
726 slt = pccard_alloc_slot(&cinfo);
727 if (slt == 0)
728 continue;
729 slt->cdata = sp;
730 sp->slt = slt;
731 /*
732 * If we haven't allocated an interrupt for the controller,
733 * then attempt to get one.
734 */
735 if (pcic_irq == 0) {
736
737 pcic_imask = soft_imask;
738
739 /* See if the user has requested a specific IRQ */
740 if (getenv_int("machdep.pccard.pcic_irq", &desired_irq))
741 /* legal IRQ? */
742 if (desired_irq >= 1 &&
743 desired_irq <= ICU_LEN &&
744 (1ul << desired_irq) & free_irqs)
745 free_irqs = 1ul << desired_irq;
746 else
747 /* illeagal, disable use of IRQ */
748 free_irqs = 0;
749
750 pcic_irq = pccard_alloc_intr(free_irqs,
751 pcicintr, 0, &pcic_imask, NULL);
752 if (pcic_irq < 0)
753 printf("pcic: failed to allocate IRQ\n");
754 else
755 printf("pcic: controller irq %d\n", pcic_irq);
756 }
757 /*
758 * Modem cards send the speaker audio (dialing noises)
759 * to the host's speaker. Cirrus Logic PCIC chips must
760 * enable this. There is also a Low Power Dynamic Mode bit
761 * that claims to reduce power consumption by 30%, so
762 * enable it and hope for the best.
763 */
764 if (sp->controller == PCIC_PD672X) {
765 setb(sp, PCIC_MISC1, PCIC_SPKR_EN);
766 setb(sp, PCIC_MISC2, PCIC_LPDM_EN);
767 }
768 /*
769 * Check for a card in this slot.
770 */
771 setb(sp, PCIC_POWER, PCIC_PCPWRE| PCIC_DISRST);
772 if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) != PCIC_CD) {
773 slt->laststate = slt->state = empty;
774 } else {
775 slt->laststate = slt->state = filled;
776 pccard_event(sp->slt, card_inserted);
777 }
778 /*
779 * Assign IRQ for slot changes
780 */
781 if (pcic_irq > 0)
782 sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
783 }
784 #ifdef PC98
785 if (validslots == 0) {
786 sp = pcic_slots;
787 slotnum = 0;
788 if (inb(PCIC98_REG0) != 0xff) {
789 sp->controller = PCIC_PC98;
790 sp->revision = 0;
791 cinfo.name = "PC98 Original";
792 cinfo.maxmem = 1;
793 cinfo.maxio = 1;
794 /* cinfo.irqs = PCIC_INT_MASK_ALLOWED;*/
795 cinfo.irqs = 0x1468;
796 validslots++;
797 sp->slotnum = slotnum;
798
799 slt = pccard_alloc_slot(&cinfo);
800 if (slt == 0) {
801 printf("pcic98: slt == NULL\n");
802 goto pcic98_probe_end;
803 }
804 slt->cdata = sp;
805 sp->slt = slt;
806
807 /* Check for a card in this slot */
808 if (inb(PCIC98_REG1) & PCIC98_CARDEXIST) {
809 /* PCMCIA card exist */
810 slt->laststate = slt->state = filled;
811 pccard_event(sp->slt, card_inserted);
812 } else {
813 slt->laststate = slt->state = empty;
814 }
815 }
816 pcic98_probe_end:
817 }
818 #endif /* PC98 */
819 if (validslots && pcic_irq <= 0)
820 pcictimeout_ch = timeout(pcictimeout, 0, hz/2);
821 return(validslots);
822 }
823
824 /*
825 * ioctl calls - Controller specific ioctls
826 */
827 static int
828 pcic_ioctl(struct slot *slt, int cmd, caddr_t data)
829 {
830 struct pcic_slot *sp = slt->cdata;
831
832 switch(cmd) {
833 default:
834 return(EINVAL);
835 /*
836 * Get/set PCIC registers
837 */
838 case PIOCGREG:
839 ((struct pcic_reg *)data)->value =
840 sp->getb(sp, ((struct pcic_reg *)data)->reg);
841 break;
842 case PIOCSREG:
843 sp->putb(sp, ((struct pcic_reg *)data)->reg,
844 ((struct pcic_reg *)data)->value);
845 break;
846 }
847 return(0);
848 }
849
850 /*
851 * pcic_power - Enable the power of the slot according to
852 * the parameters in the power structure(s).
853 */
854 static int
855 pcic_power(struct slot *slt)
856 {
857 unsigned char reg = PCIC_DISRST|PCIC_PCPWRE;
858 struct pcic_slot *sp = slt->cdata;
859
860 switch(sp->controller) {
861 #ifdef PC98
862 case PCIC_PC98:
863 reg = inb(PCIC98_REG6) & (~PCIC98_VPP12V);
864 switch(slt->pwr.vpp) {
865 default:
866 return(EINVAL);
867 case 50:
868 break;
869 case 120:
870 reg |= PCIC98_VPP12V;
871 break;
872 }
873 outb(PCIC98_REG6, reg);
874 DELAY(100*1000);
875
876 reg = inb(PCIC98_REG2) & (~PCIC98_VCC3P3V);
877 switch(slt->pwr.vcc) {
878 default:
879 return(EINVAL);
880 case 33:
881 reg |= PCIC98_VCC3P3V;
882 break;
883 case 50:
884 break;
885 }
886 outb(PCIC98_REG2, reg);
887 DELAY(100*1000);
888 return (0);
889 #endif
890 case PCIC_PD672X:
891 case PCIC_PD6710:
892 case PCIC_VG365:
893 case PCIC_VG465:
894 case PCIC_VG468:
895 case PCIC_VG469:
896 case PCIC_RF5C396:
897 case PCIC_VLSI:
898 case PCIC_IBM_KING:
899 switch(slt->pwr.vpp) {
900 default:
901 return(EINVAL);
902 case 0:
903 break;
904 case 50:
905 case 33:
906 reg |= PCIC_VPP_5V;
907 break;
908 case 120:
909 reg |= PCIC_VPP_12V;
910 break;
911 }
912 switch(slt->pwr.vcc) {
913 default:
914 return(EINVAL);
915 case 0:
916 break;
917 case 33:
918 if (sp->controller == PCIC_IBM_KING) {
919 reg |= PCIC_VCC_5V_KING;
920 break;
921 }
922 reg |= PCIC_VCC_3V;
923 if ((sp->controller == PCIC_VG468) ||
924 (sp->controller == PCIC_VG469) ||
925 (sp->controller == PCIC_VG465) ||
926 (sp->controller == PCIC_VG365))
927 setb(sp, 0x2f, 0x03) ;
928 else
929 setb(sp, 0x16, 0x02);
930 break;
931 case 50:
932 if (sp->controller == PCIC_IBM_KING) {
933 reg |= PCIC_VCC_5V_KING;
934 break;
935 }
936 reg |= PCIC_VCC_5V;
937 if ((sp->controller == PCIC_VG468) ||
938 (sp->controller == PCIC_VG469) ||
939 (sp->controller == PCIC_VG465) ||
940 (sp->controller == PCIC_VG365))
941 clrb(sp, 0x2f, 0x03) ;
942 else
943 clrb(sp, 0x16, 0x02);
944 break;
945 }
946 break;
947 }
948 sp->putb(sp, PCIC_POWER, reg);
949 DELAY(300*1000);
950 if (slt->pwr.vcc) {
951 reg |= PCIC_OUTENA;
952 sp->putb(sp, PCIC_POWER, reg);
953 DELAY(100*1000);
954 }
955 /* Some chips are smarter than us it seems, so if we weren't
956 * allowed to use 5V, try 3.3 instead
957 */
958 if (!(sp->getb(sp, PCIC_STATUS) & 0x40) && slt->pwr.vcc == 50) {
959 slt->pwr.vcc = 33;
960 slt->pwr.vpp = 0;
961 return (pcic_power(slt));
962 }
963 return(0);
964 }
965
966 /*
967 * tell the PCIC which irq we want to use. only the following are legal:
968 * 3, 4, 5, 7, 9, 10, 11, 12, 14, 15
969 */
970 static void
971 pcic_mapirq(struct slot *slt, int irq)
972 {
973 struct pcic_slot *sp = slt->cdata;
974 #ifdef PC98
975 if (sp->controller == PCIC_PC98) {
976 unsigned char x;
977 switch (irq) {
978 case 3:
979 x = PCIC98_INT0; break;
980 case 5:
981 x = PCIC98_INT1; break;
982 case 6:
983 x = PCIC98_INT2; break;
984 case 10:
985 x = PCIC98_INT4; break;
986 case 12:
987 x = PCIC98_INT5; break;
988 case 0: /* disable */
989 x = PCIC98_INTDISABLE;
990 break;
991 default:
992 printf("pcic98: illegal irq %d\n", irq);
993 return;
994 }
995 #ifdef PCIC_DEBUG
996 printf("pcic98: irq=%d mapped.\n", irq);
997 #endif
998 outb(PCIC98_REG3, x);
999
1000 return;
1001 }
1002 #endif
1003 if (irq == 0)
1004 clrb(sp, PCIC_INT_GEN, 0xF);
1005 else
1006 sp->putb(sp, PCIC_INT_GEN,
1007 (sp->getb(sp, PCIC_INT_GEN) & 0xF0) | irq);
1008 }
1009
1010 /*
1011 * pcic_reset - Reset the card and enable initial power.
1012 */
1013 static void
1014 pcic_reset(void *chan)
1015 {
1016 struct slot *slt = chan;
1017 struct pcic_slot *sp = slt->cdata;
1018
1019 #ifdef PC98
1020 if (sp->controller == PCIC_PC98) {
1021 outb(PCIC98_REG0, 0);
1022 outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_IOMEMORY));
1023 outb(PCIC98_REG3, PCIC98_INTDISABLE);
1024 outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_VCC3P3V));
1025 outb(PCIC98_REG6, inb(PCIC98_REG6) & (~PCIC98_VPP12V));
1026 outb(PCIC98_REG1, 0);
1027
1028 selwakeup(&slt->selp);
1029 return;
1030 }
1031 #endif
1032 switch (slt->insert_seq) {
1033 case 0: /* Something funny happended on the way to the pub... */
1034 return;
1035 case 1: /* Assert reset */
1036 clrb(sp, PCIC_INT_GEN, PCIC_CARDRESET);
1037 slt->insert_seq = 2;
1038 timeout(pcic_reset, (void *)slt, hz/4);
1039 return;
1040 case 2: /* Deassert it again */
1041 setb(sp, PCIC_INT_GEN, PCIC_CARDRESET|PCIC_IOCARD);
1042 slt->insert_seq = 3;
1043 timeout(pcic_reset, (void *)slt, hz/4);
1044 return;
1045 case 3: /* Wait if card needs more time */
1046 if (!sp->getb(sp, PCIC_STATUS) & PCIC_READY) {
1047 timeout(pcic_reset, (void *)slt, hz/10);
1048 return;
1049 }
1050 }
1051 slt->insert_seq = 0;
1052 if (sp->controller == PCIC_PD672X || sp->controller == PCIC_PD6710) {
1053 sp->putb(sp, PCIC_TIME_SETUP0, 0x1);
1054 sp->putb(sp, PCIC_TIME_CMD0, 0x6);
1055 sp->putb(sp, PCIC_TIME_RECOV0, 0x0);
1056 sp->putb(sp, PCIC_TIME_SETUP1, 1);
1057 sp->putb(sp, PCIC_TIME_CMD1, 0xf);
1058 sp->putb(sp, PCIC_TIME_RECOV1, 0);
1059 }
1060 selwakeup(&slt->selp);
1061 }
1062
1063 /*
1064 * pcic_disable - Disable the slot.
1065 */
1066 static void
1067 pcic_disable(struct slot *slt)
1068 {
1069 struct pcic_slot *sp = slt->cdata;
1070
1071 #ifdef PC98
1072 if (sp->controller == PCIC_PC98) {
1073 return;
1074 }
1075 #endif
1076 sp->putb(sp, PCIC_INT_GEN, 0);
1077 sp->putb(sp, PCIC_POWER, 0);
1078 }
1079
1080 /*
1081 * PCIC timer. If the controller doesn't have a free IRQ to use
1082 * or if interrupt steering doesn't work, poll the controller for
1083 * insertion/removal events.
1084 */
1085 static void
1086 pcictimeout(void *chan)
1087 {
1088 pcicintr(NULL);
1089 pcictimeout_ch = timeout(pcictimeout, 0, hz/2);
1090 }
1091
1092 /*
1093 * PCIC Interrupt handler.
1094 * Check each slot in turn, and read the card status change
1095 * register. If this is non-zero, then a change has occurred
1096 * on this card, so send an event to the main code.
1097 */
1098 static void
1099 pcicintr(void *unused)
1100 {
1101 int slot, s;
1102 unsigned char chg;
1103 struct pcic_slot *sp = pcic_slots;
1104
1105 #ifdef PC98
1106 if (sp->controller == PCIC_PC98) {
1107 slot = 0;
1108 s = splhigh();
1109 /* Check for a card in this slot */
1110 if (inb(PCIC98_REG1) & PCIC98_CARDEXIST) {
1111 if (sp->slt->laststate != filled) {
1112 pccard_event(sp->slt, card_inserted);
1113 }
1114 } else {
1115 if (sp->slt->laststate != empty) {
1116 pccard_event(sp->slt, card_removed);
1117 }
1118 }
1119 splx(s);
1120 return;
1121 }
1122 #endif /* PC98 */
1123 s = splhigh();
1124 for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++)
1125 if (sp->slt && (chg = sp->getb(sp, PCIC_STAT_CHG)) != 0)
1126 if (chg & PCIC_CDTCH) {
1127 if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) ==
1128 PCIC_CD) {
1129 pccard_event(sp->slt, card_inserted);
1130 } else {
1131 pccard_event(sp->slt, card_removed);
1132 }
1133 }
1134 splx(s);
1135 }
1136
1137 /*
1138 * pcic_resume - Suspend/resume support for PCIC
1139 */
1140 static void
1141 pcic_resume(struct slot *slt)
1142 {
1143 struct pcic_slot *sp = slt->cdata;
1144 if (pcic_irq > 0)
1145 sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
1146 if (sp->controller == PCIC_PD672X) {
1147 setb(sp, PCIC_MISC1, PCIC_SPKR_EN);
1148 setb(sp, PCIC_MISC2, PCIC_LPDM_EN);
1149 }
1150 }
Cache object: 37732df26b9a25043e7a4965635a67aa
|