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#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/types.h>
32#include <linux/fcntl.h>
33#include <linux/string.h>
34
35#include <asm/io.h>
36#include <asm/bitops.h>
37#include <asm/segment.h>
38#include <asm/system.h>
39
40#include <linux/kernel.h>
41#include <linux/errno.h>
42#include <linux/sched.h>
43#include <linux/slab.h>
44#include <linux/timer.h>
45#include <linux/ioport.h>
46#include <linux/delay.h>
47
48#include <asm/mpc8xx.h>
49#include <asm/8xx_immap.h>
50#include <asm/irq.h>
51
52#include <pcmcia/version.h>
53#include <pcmcia/cs_types.h>
54#include <pcmcia/cs.h>
55#include <pcmcia/ss.h>
56
57#ifdef PCMCIA_DEBUG
58static int pc_debug = PCMCIA_DEBUG;
59MODULE_PARM(pc_debug, "i");
60#define DEBUG(n, args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
61#else
62#define DEBUG(n, args...)
63#endif
64
65#define PCMCIA_INFO(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
66#define PCMCIA_ERROR(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
67
68static const char *version = "Version 0.05, 14-Apr-2002";
69MODULE_LICENSE("Dual MPL/GPL");
70
71
72
73#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
74#define CONFIG_PCMCIA_SLOT_B
75#endif
76
77
78
79#ifdef CONFIG_MBX
80#define CONFIG_PCMCIA_SLOT_A
81#endif
82
83
84
85#ifdef CONFIG_FADS
86#define CONFIG_PCMCIA_SLOT_A
87#endif
88
89
90
91#define PCMCIA_MEM_WIN_BASE 0xe0000000
92#define PCMCIA_MEM_WIN_SIZE 0x04000000
93#define PCMCIA_IO_WIN_BASE _IO_BASE
94
95#define PCMCIA_SCHLVL PCMCIA_INTERRUPT
96
97
98
99#define PCMCIA_SOCKETS_NO 1
100
101#define PCMCIA_MEM_WIN_NO 5
102#define PCMCIA_IO_WIN_NO 2
103
104
105
106#ifdef CONFIG_PCMCIA_SLOT_A
107#define _slot_ 0
108#define PCMCIA_SLOT_MSG "SLOT_A"
109#else
110#define _slot_ 1
111#define PCMCIA_SLOT_MSG "SLOT_B"
112#endif
113
114#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq))
115
116static int pcmcia_schlvl = PCMCIA_SCHLVL;
117
118
119
120#define PCMCIA_SOCKET_KEY_5V 1
121#define PCMCIA_SOCKET_KEY_LV 2
122
123
124
125
126static u_int *m8xx_pgcrx[2] = {
127 &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra,
128 &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb
129};
130
131
132
133
134
135
136
137
138typedef struct {
139 uint br;
140 uint or;
141} pcmcia_win_t;
142
143
144
145
146
147
148
149
150
151
152
153
154#define M8XX_PCMCIA_VS1(slot) (0x80000000 >> (slot << 4))
155#define M8XX_PCMCIA_VS2(slot) (0x40000000 >> (slot << 4))
156#define M8XX_PCMCIA_VS_MASK(slot) (0xc0000000 >> (slot << 4))
157#define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4))
158
159#define M8XX_PCMCIA_WP(slot) (0x20000000 >> (slot << 4))
160#define M8XX_PCMCIA_CD2(slot) (0x10000000 >> (slot << 4))
161#define M8XX_PCMCIA_CD1(slot) (0x08000000 >> (slot << 4))
162#define M8XX_PCMCIA_BVD2(slot) (0x04000000 >> (slot << 4))
163#define M8XX_PCMCIA_BVD1(slot) (0x02000000 >> (slot << 4))
164#define M8XX_PCMCIA_RDY(slot) (0x01000000 >> (slot << 4))
165#define M8XX_PCMCIA_RDY_L(slot) (0x00800000 >> (slot << 4))
166#define M8XX_PCMCIA_RDY_H(slot) (0x00400000 >> (slot << 4))
167#define M8XX_PCMCIA_RDY_R(slot) (0x00200000 >> (slot << 4))
168#define M8XX_PCMCIA_RDY_F(slot) (0x00100000 >> (slot << 4))
169#define M8XX_PCMCIA_MASK(slot) (0xFFFF0000 >> (slot << 4))
170
171#define M8XX_PGCRX(slot) (*m8xx_pgcrx[slot])
172
173#define M8XX_PGCRX_CXOE 0x00000080
174#define M8XX_PGCRX_CXRESET 0x00000040
175
176
177
178#define PCMCIA_EVENTS_MAX 5
179
180typedef struct {
181 u_int regbit;
182 u_int eventbit;
183} event_table_t;
184
185typedef struct socket_info_t {
186 void (*handler)(void *info, u_int events);
187 void *info;
188
189 u_int slot;
190
191 socket_state_t state;
192 struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
193 struct pccard_io_map io_win[PCMCIA_IO_WIN_NO];
194 event_table_t events[PCMCIA_EVENTS_MAX];
195} socket_info_t;
196
197static socket_info_t socket[PCMCIA_SOCKETS_NO];
198
199static socket_cap_t capabilities = {
200 SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP,
201
202
203
204 0x000,
205 0x1000,
206 0,
207 9,
208 0
209};
210
211
212
213
214
215
216#define M8XX_SIZES_NO 32
217
218static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
219{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
220 0x00000080, 0x00000040, 0x00000010, 0x00000020,
221 0x00008000, 0x00004000, 0x00001000, 0x00002000,
222 0x00000100, 0x00000200, 0x00000800, 0x00000400,
223
224 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
225 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
226 0x00010000, 0x00020000, 0x00080000, 0x00040000,
227 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
228
229
230
231
232static void m8xx_interrupt(int irq, void *dev, struct pt_regs *regs);
233
234#define PCMCIA_BMT_LIMIT (15*4)
235
236
237
238
239
240
241
242#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
243
244
245
246
247
248
249#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
250
251#undef PCMCIA_BMT_LIMIT
252#define PCMCIA_BMT_LIMIT (6*8)
253
254static int voltage_set(int slot, int vcc, int vpp)
255{
256 u_int reg = 0;
257
258 switch(vcc) {
259 case 0: break;
260 case 33: reg |= BCSR1_PCVCTL4; break;
261 case 50: reg |= BCSR1_PCVCTL5; break;
262 default: return 1;
263 }
264
265 switch(vpp) {
266 case 0: break;
267 case 33:
268 case 50:
269 if(vcc == vpp)
270 reg |= BCSR1_PCVCTL6;
271 else
272 return 1;
273 break;
274 case 120:
275 reg |= BCSR1_PCVCTL7;
276 default: return 1;
277 }
278
279 if(!((vcc == 50) || (vcc == 0)))
280 return 1;
281
282
283
284 *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
285 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
286
287
288
289 *((uint *)RPX_CSR_ADDR) |= reg;
290
291 return 0;
292}
293
294#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
295#define hardware_enable(_slot_)
296#define hardware_disable(_slot_)
297
298#endif
299
300
301
302
303#if defined(CONFIG_FADS)
304
305#define PCMCIA_BOARD_MSG "FADS"
306
307static int voltage_set(int slot, int vcc, int vpp)
308{
309 uint reg = 0;
310
311 switch(vcc) {
312 case 0: break;
313 case 33: reg |= BCSR1_PCCVCC0; break;
314 case 50: reg |= BCSR1_PCCVCC1; break;
315 default: return 1;
316 }
317
318 switch(vpp) {
319 case 0: break;
320 case 33:
321 case 50:
322 if(vcc == vpp)
323 reg |= BCSR1_PCCVPP1;
324 else
325 return 1;
326 break;
327 case 120:
328 if ((vcc == 33) || (vcc == 50))
329 reg |= BCSR1_PCCVPP0;
330 else
331 return 1;
332 default: return 1;
333 }
334
335
336 *((uint *)BCSR1) &= ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK);
337
338
339 *((uint *)BCSR1) |= reg;
340
341 return 0;
342}
343
344#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
345
346static void hardware_enable(int slot)
347{
348 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
349}
350
351static void hardware_disable(int slot)
352{
353 *((uint *)BCSR1) |= BCSR1_PCCEN;
354}
355
356#endif
357
358
359
360
361#if defined(CONFIG_MBX)
362
363#define PCMCIA_BOARD_MSG "MBX"
364
365static int voltage_set(int slot, int vcc, int vpp)
366{
367 unsigned char reg = 0;
368
369 switch(vcc) {
370 case 0: break;
371 case 33: reg |= CSR2_VCC_33; break;
372 case 50: reg |= CSR2_VCC_50; break;
373 default: return 1;
374 }
375
376 switch(vpp) {
377 case 0: break;
378 case 33:
379 case 50:
380 if(vcc == vpp)
381 reg |= CSR2_VPP_VCC;
382 else
383 return 1;
384 break;
385 case 120:
386 if ((vcc == 33) || (vcc == 50))
387 reg |= CSR2_VPP_12;
388 else
389 return 1;
390 default: return 1;
391 }
392
393
394 *((unsigned char *)MBX_CSR2_ADDR) &= ~(CSR2_VCC_MASK | CSR2_VPP_MASK);
395
396
397 *((unsigned char *)MBX_CSR2_ADDR) |= reg;
398
399 return 0;
400}
401
402#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
403#define hardware_enable(_slot_)
404#define hardware_disable(_slot_)
405
406#endif
407
408
409
410static void m8xx_shutdown(void)
411{
412 u_int m;
413 pcmcia_win_t *w;
414
415
416 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
417
418
419 ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr =
420 M8XX_PCMCIA_MASK(_slot_);
421 ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per
422 &= ~M8XX_PCMCIA_MASK(_slot_);
423
424
425
426 M8XX_PGCRX(_slot_) = M8XX_PGCRX_CXOE;
427
428
429
430 for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
431 w->or = 0;
432 w++;
433 }
434
435
436
437 voltage_set(_slot_, 0, 0);
438
439
440
441 hardware_disable(_slot_);
442
443 free_irq(pcmcia_schlvl, NULL);
444
445}
446
447
448
449
450
451static u_int pending_events[PCMCIA_SOCKETS_NO];
452static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
453
454static void m8xx_pcmcia_bh(void *dummy)
455{
456 u_int events;
457 int i;
458
459 for (i=0; i < PCMCIA_SOCKETS_NO; i++) {
460 spin_lock_irq(&pending_event_lock);
461 events = pending_events[i];
462 pending_events[i] = 0;
463 spin_unlock_irq(&pending_event_lock);
464
465
466
467
468
469 if (events & SS_DETECT)
470 mdelay(4);
471 if (socket[i].handler)
472 socket[i].handler(socket[i].info, events);
473 }
474}
475
476static struct tq_struct m8xx_pcmcia_task = {
477 routine: m8xx_pcmcia_bh
478};
479
480
481static void m8xx_interrupt(int irq, void *dev, struct pt_regs *regs)
482{
483 socket_info_t *s;
484 event_table_t *e;
485 u_int events, pscr, pipr;
486
487 DEBUG(3,"Interrupt!\n");
488
489
490
491 pscr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr;
492 pipr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
493
494 s = &socket[0];
495
496 if(s->handler) {
497
498 e = &s->events[0];
499 events = 0;
500
501 while(e->regbit) {
502 if(pscr & e->regbit)
503 events |= e->eventbit;
504
505 e++;
506 }
507
508
509
510
511
512
513
514 if(events & SS_DETECT)
515 if(((pipr & M8XX_PCMCIA_CD2(_slot_)) >> 1)
516 ^ (pipr & M8XX_PCMCIA_CD1(_slot_)))
517 events &= ~SS_DETECT;
518
519#ifdef PCMCIA_GLITCHY_CD
520
521
522
523
524
525
526
527 if((events & SS_DETECT) &&
528 ((pipr &
529 (M8XX_PCMCIA_CD2(_slot_) | M8XX_PCMCIA_CD1(_slot_)))
530 == 0) && (s->state.Vcc | s->state.Vpp)) {
531 events &= ~SS_DETECT;
532 printk( "CD glitch workaround - CD = 0x%08x!\n",
533 (pipr & (M8XX_PCMCIA_CD2(_slot_)
534 | M8XX_PCMCIA_CD1(_slot_))));
535 }
536#endif
537
538
539
540 DEBUG(3,"slot %u: events = 0x%02x, pscr = 0x%08x, "
541 "pipr = 0x%08x\n",
542 _slot_, events, pscr, pipr);
543
544 if(events) {
545 spin_lock(&pending_event_lock);
546 pending_events[0] |= events;
547 spin_unlock(&pending_event_lock);
548 schedule_task(&m8xx_pcmcia_task);
549 }
550
551 }
552
553
554
555
556 ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr;
557
558 DEBUG(3,"Interrupt done.\n");
559
560}
561
562
563
564static u_int m8xx_get_graycode(u_int size)
565{
566 u_int k;
567
568 for(k = 0; k < M8XX_SIZES_NO; k++)
569 if(m8xx_size_to_gray[k] == size)
570 break;
571
572 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
573 k = -1;
574
575 return k;
576}
577
578
579
580static u_int m8xx_get_speed(u_int ns, u_int is_io)
581{
582 u_int reg, clocks, psst, psl, psht;
583
584 if(!ns) {
585
586
587
588
589
590
591
592 if(is_io)
593 ns = 255;
594 else
595 ns = 100;
596 }
597
598
599
600
601
602
603
604
605
606#define ADJ 180
607
608
609 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
610 clocks = (clocks * ADJ) / (100*1000);
611 if(clocks >= PCMCIA_BMT_LIMIT) {
612 printk( "Max access time limit reached\n");
613 clocks = PCMCIA_BMT_LIMIT-1;
614 }
615
616 psst = clocks / 7;
617 psht = clocks / 7;
618 psl = (clocks * 5) / 7;
619
620 psst += clocks - (psst + psht + psl);
621
622 reg = psst << 12;
623 reg |= psl << 7;
624 reg |= psht << 16;
625
626 return reg;
627}
628
629
630
631static int m8xx_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
632{
633 socket[sock].handler = handler;
634 socket[sock].info = info;
635 if (handler == NULL) {
636 MOD_DEC_USE_COUNT;
637 }
638 else {
639 MOD_INC_USE_COUNT;
640 }
641 return 0;
642}
643
644
645
646static int m8xx_get_status(unsigned int lsock, u_int *value)
647{
648 socket_info_t *s = &socket[lsock];
649 u_int pipr, reg;
650
651
652 pipr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
653
654 *value = ((pipr & (M8XX_PCMCIA_CD1(_slot_)
655 | M8XX_PCMCIA_CD2(_slot_))) == 0) ? SS_DETECT : 0;
656 *value |= (pipr & M8XX_PCMCIA_WP(_slot_)) ? SS_WRPROT : 0;
657
658 if (s->state.flags & SS_IOCARD)
659 *value |= (pipr & M8XX_PCMCIA_BVD1(_slot_)) ? SS_STSCHG : 0;
660 else {
661 *value |= (pipr & M8XX_PCMCIA_RDY(_slot_)) ? SS_READY : 0;
662 *value |= (pipr & M8XX_PCMCIA_BVD1(_slot_)) ? SS_BATDEAD : 0;
663 *value |= (pipr & M8XX_PCMCIA_BVD2(_slot_)) ? SS_BATWARN : 0;
664 }
665
666 if (s->state.Vcc | s->state.Vpp)
667 *value |= SS_POWERON;
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738 reg = (pipr & M8XX_PCMCIA_VS_MASK(_slot_))
739 >> M8XX_PCMCIA_VS_SHIFT(_slot_);
740
741 if(socket_get(_slot_) == PCMCIA_SOCKET_KEY_LV) {
742 switch(reg) {
743 case 1: *value |= SS_3VCARD; break;
744 case 2: *value |= SS_XVCARD; break;
745 };
746 }
747
748 DEBUG(3,"GetStatus(%d) = %#2.2x\n", lsock, *value);
749 return 0;
750}
751
752
753
754static int m8xx_inquire_socket(unsigned int lsock, socket_cap_t *cap)
755{
756 *cap = capabilities;
757
758 return 0;
759}
760
761
762
763static int m8xx_get_socket(unsigned int lsock, socket_state_t *state)
764{
765 *state = socket[lsock].state;
766
767 DEBUG(3,"GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
768 "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags,
769 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
770 return 0;
771}
772
773
774
775static int m8xx_set_socket(unsigned int lsock, socket_state_t *state)
776{
777 socket_info_t *s = &socket[lsock];
778 event_table_t *e;
779 u_int reg;
780 u_long flags;
781
782 DEBUG(3, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
783 "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
784 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
785
786
787
788 if(voltage_set(_slot_, state->Vcc, state->Vpp))
789 return -EINVAL;
790
791
792
793
794 if(state->flags & SS_RESET)
795 M8XX_PGCRX(_slot_) |= M8XX_PGCRX_CXRESET;
796 else
797 M8XX_PGCRX(_slot_) &= ~M8XX_PGCRX_CXRESET;
798
799
800
801
802
803
804
805
806
807
808
809 if(state->Vcc || state->Vpp)
810 M8XX_PGCRX(_slot_) &= ~M8XX_PGCRX_CXOE;
811 else
812 M8XX_PGCRX(_slot_) |= M8XX_PGCRX_CXOE;
813
814
815
816
817
818
819 save_flags(flags);
820 cli();
821
822
823
824
825
826
827 e = &s->events[0];
828 reg = 0;
829
830 if(state->csc_mask & SS_DETECT) {
831 e->eventbit = SS_DETECT;
832 reg |= e->regbit = (M8XX_PCMCIA_CD2(_slot_)
833 | M8XX_PCMCIA_CD1(_slot_));
834 e++;
835 }
836
837 if(state->flags & SS_IOCARD) {
838
839
840
841
842
843 if(state->csc_mask & SS_STSCHG) {
844 e->eventbit = SS_STSCHG;
845 reg |= e->regbit = M8XX_PCMCIA_BVD1(_slot_);
846 e++;
847 }
848
849
850
851
852
853
854 if(state->io_irq) {
855 M8XX_PGCRX(_slot_) |=
856 mk_int_int_mask(state->io_irq) << 24;
857
858
859
860
861
862
863
864
865
866
867
868 reg |= M8XX_PCMCIA_RDY_L(_slot_);
869 }
870 else
871 M8XX_PGCRX(_slot_) &= 0x00ffffff;
872
873 }
874 else {
875
876
877
878
879
880 if(state->csc_mask & SS_BATDEAD) {
881 e->eventbit = SS_BATDEAD;
882 reg |= e->regbit = M8XX_PCMCIA_BVD1(_slot_);
883 e++;
884 }
885
886 if(state->csc_mask & SS_BATWARN) {
887 e->eventbit = SS_BATWARN;
888 reg |= e->regbit = M8XX_PCMCIA_BVD2(_slot_);
889 e++;
890 }
891
892
893 if(state->csc_mask & SS_READY) {
894 e->eventbit = SS_READY;
895 reg |= e->regbit = 0;
896 e++;
897 }
898 }
899
900 e->regbit = 0;
901
902
903
904
905
906
907
908 ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = reg;
909
910
911
912
913
914
915
916
917 reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per
918 & M8XX_PCMCIA_MASK(_slot_);
919
920 ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per = reg;
921
922 restore_flags(flags);
923
924
925
926 s->state = *state;
927
928 return 0;
929}
930
931
932
933static int m8xx_get_io_map(unsigned int lsock, struct pccard_io_map *io)
934{
935 if(io->map >= PCMCIA_IO_WIN_NO)
936 return -EINVAL;
937
938 *io = socket[lsock].io_win[io->map];
939
940 DEBUG(3,"GetIOMap(%d, %d) = %#2.2x, %d ns, "
941 "%#4.4x-%#4.4x\n", lsock, io->map, io->flags,
942 io->speed, io->start, io->stop);
943 return 0;
944}
945
946
947
948static int m8xx_set_io_map(unsigned int lsock, struct pccard_io_map *io)
949{
950 socket_info_t *s = &socket[lsock];
951 pcmcia_win_t *w;
952 u_int reg, winnr;
953
954
955#define M8XX_SIZE (io->stop - io->start + 1)
956#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
957
958 DEBUG(3, "SetIOMap(%d, %d, %#2.2x, %d ns, "
959 "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
960 io->speed, io->start, io->stop);
961
962 if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
963 || (io->stop > 0xffff) || (io->stop < io->start))
964 return -EINVAL;
965
966 if((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
967 return -EINVAL;
968
969 if(io->flags & MAP_ACTIVE) {
970
971 winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
972 + (lsock * PCMCIA_IO_WIN_NO) + io->map;
973
974
975
976 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
977 w += winnr;
978
979 w->or = 0;
980 w->br = M8XX_BASE;
981
982 reg <<= 27;
983 reg |= 0x00018 + (_slot_ << 2);
984
985 reg |= m8xx_get_speed(io->speed, 1);
986
987 if(io->flags & MAP_WRPROT)
988 reg |= 0x00000002;
989
990 if(io->flags & (MAP_16BIT | MAP_AUTOSZ))
991 reg |= 0x00000040;
992
993 if(io->flags & MAP_ACTIVE)
994 reg |= 0x00000001;
995
996 w->or = reg;
997
998 DEBUG(3,"Socket %u: Mapped io window %u at %#8.8x, "
999 "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
1000 }
1001
1002
1003
1004
1005 s->io_win[io->map] = *io;
1006 s->io_win[io->map].flags &= (MAP_WRPROT
1007 | MAP_16BIT
1008 | MAP_ACTIVE);
1009 return 0;
1010}
1011
1012
1013
1014static int m8xx_get_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
1015{
1016 if(mem->map >= PCMCIA_MEM_WIN_NO)
1017 return -EINVAL;
1018
1019 *mem = socket[lsock].mem_win[mem->map];
1020
1021 DEBUG(3, "GetMemMap(%d, %d) = %#2.2x, %d ns, "
1022 "%#5.5lx-%#5.5lx, %#5.5x\n", lsock, mem->map, mem->flags,
1023 mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
1024 return 0;
1025}
1026
1027
1028
1029static int m8xx_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
1030{
1031 socket_info_t *s = &socket[lsock];
1032 pcmcia_win_t *w;
1033 struct pccard_mem_map *old;
1034 u_int reg, winnr;
1035
1036 DEBUG(3, "SetMemMap(%d, %d, %#2.2x, %d ns, "
1037 "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
1038 mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
1039
1040 if ((mem->map >= PCMCIA_MEM_WIN_NO) || (mem->sys_start > mem->sys_stop)
1041 || ((mem->sys_stop - mem->sys_start) >= PCMCIA_MEM_WIN_SIZE)
1042 || (mem->card_start >= 0x04000000)
1043 || (mem->sys_start & 0xfff)
1044 || (mem->card_start & 0xfff))
1045 return -EINVAL;
1046
1047 if((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
1048 printk( "Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
1049 return -EINVAL;
1050 }
1051
1052 winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map;
1053
1054
1055
1056 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
1057 w += winnr;
1058
1059 reg <<= 27;
1060 reg |= _slot_ << 2;
1061
1062 reg |= m8xx_get_speed(mem->speed, 0);
1063
1064 if(mem->flags & MAP_ATTRIB)
1065 reg |= 0x00000010;
1066
1067 if(mem->flags & MAP_WRPROT)
1068 reg |= 0x00000002;
1069
1070 if(mem->flags & MAP_16BIT)
1071 reg |= 0x00000040;
1072
1073 if(mem->flags & MAP_ACTIVE)
1074 reg |= 0x00000001;
1075
1076 w->or = reg;
1077
1078 DEBUG(3, "Socket %u: Mapped memory window %u at %#8.8x, "
1079 "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
1080
1081 if(mem->flags & MAP_ACTIVE) {
1082
1083 mem->sys_stop -= mem->sys_start;
1084
1085
1086
1087 mem->sys_start = PCMCIA_MEM_WIN_BASE +
1088 (PCMCIA_MEM_WIN_SIZE * winnr)
1089 + mem->card_start;
1090
1091 mem->sys_stop += mem->sys_start;
1092 }
1093
1094DEBUG(3, "SetMemMap(%d, %d, %#2.2x, %d ns, "
1095 "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
1096 mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
1097
1098
1099
1100 old = &s->mem_win[mem->map];
1101
1102 *old = *mem;
1103 old->flags &= (MAP_ATTRIB
1104 | MAP_WRPROT
1105 | MAP_16BIT
1106 | MAP_ACTIVE);
1107
1108 return 0;
1109}
1110
1111static int m8xx_sock_init(unsigned int s)
1112{
1113 int i;
1114 pccard_io_map io = { 0, 0, 0, 0, 1 };
1115 pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
1116
1117 DEBUG(3, "sock_init(%d)\n", s);
1118
1119 mem.sys_stop = 0x1000;
1120 m8xx_set_socket(s, &dead_socket);
1121 for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
1122 io.map = i;
1123 m8xx_set_io_map(s, &io);
1124 }
1125 for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) {
1126 mem.map = i;
1127 m8xx_set_mem_map(s, &mem);
1128 }
1129
1130 return 0;
1131
1132}
1133
1134static int m8xx_suspend(unsigned int s)
1135{
1136 return(m8xx_set_socket(s, &dead_socket));
1137}
1138static void m8xx_proc_setup(unsigned int sock, struct proc_dir_entry *base)
1139{
1140}
1141
1142
1143static struct pccard_operations m8xx_services = {
1144 &m8xx_sock_init,
1145 &m8xx_suspend,
1146 &m8xx_register_callback,
1147 &m8xx_inquire_socket,
1148 &m8xx_get_status,
1149 &m8xx_get_socket,
1150 &m8xx_set_socket,
1151 &m8xx_get_io_map,
1152 &m8xx_set_io_map,
1153 &m8xx_get_mem_map,
1154 &m8xx_set_mem_map,
1155 &m8xx_proc_setup
1156};
1157
1158static int __init m8xx_init(void)
1159{
1160 servinfo_t serv;
1161 pcmcia_win_t *w;
1162 u_int m;
1163
1164 PCMCIA_INFO("%s\n", version);
1165 CardServices(GetCardServicesInfo, &serv);
1166 if (serv.Revision != CS_RELEASE_CODE) {
1167 PCMCIA_ERROR("Card Services release does not match!\n");
1168 return -1;
1169 }
1170
1171 PCMCIA_INFO(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
1172 " with IRQ %u.\n", pcmcia_schlvl);
1173
1174
1175
1176 if(request_8xxirq(pcmcia_schlvl, m8xx_interrupt, 0,
1177 "m8xx_pcmcia", NULL)) {
1178 PCMCIA_ERROR("Cannot allocate IRQ %u for SCHLVL!\n",
1179 pcmcia_schlvl);
1180 return -1;
1181 }
1182
1183
1184 w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
1185
1186 socket[0].slot = _slot_;
1187
1188 ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr =
1189 M8XX_PCMCIA_MASK(_slot_);
1190 ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per
1191 &= ~M8XX_PCMCIA_MASK(_slot_);
1192
1193
1194
1195 M8XX_PGCRX(_slot_) = M8XX_PGCRX_CXOE |
1196 (mk_int_int_mask(pcmcia_schlvl) << 16);
1197
1198
1199
1200 for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
1201 w->br = PCMCIA_MEM_WIN_BASE +
1202 (PCMCIA_MEM_WIN_SIZE
1203 * (m + 0 * PCMCIA_MEM_WIN_NO));
1204
1205 w->or = 0;
1206
1207 DEBUG(3,"Socket %u: MemWin %u: Base 0x%08x.\n",
1208 0, m, w->br);
1209
1210 w++;
1211 }
1212
1213
1214 voltage_set(_slot_, 0, 0);
1215
1216
1217 hardware_enable(_slot_);
1218
1219 if(register_ss_entry(PCMCIA_SOCKETS_NO, &m8xx_services) != 0) {
1220 PCMCIA_ERROR("register_ss_entry() failed.\n");
1221 m8xx_shutdown();
1222 return -ENODEV;
1223 }
1224
1225 return 0;
1226}
1227
1228static void __exit m8xx_exit(void)
1229{
1230 unregister_ss_entry(&m8xx_services);
1231
1232 m8xx_shutdown();
1233}
1234
1235module_init(m8xx_init);
1236module_exit(m8xx_exit);
1237