1
2
3
4#include <linux/kernel.h>
5
6#include <linux/slab.h>
7#include <linux/mm.h>
8#include <linux/init.h>
9#include <linux/delay.h>
10#include <linux/spinlock.h>
11
12#include <asm/hwrpb.h>
13#include <asm/io.h>
14#include <asm/segment.h>
15
16#if 0
17# define DBG_DEVS(args) printk args
18#else
19# define DBG_DEVS(args)
20#endif
21
22#define KB 1024
23#define MB (1024*KB)
24#define GB (1024*MB)
25
26#define SMC_DEBUG 0
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63#ifndef __SMC37c669_H
64#define __SMC37c669_H
65
66
67
68
69
70
71
72#define SMC37c669_DEVICE_IRQ_MASK 0x80000000
73#define SMC37c669_DEVICE_IRQ( __i ) \
74 ((SMC37c669_DEVICE_IRQ_MASK) | (__i))
75#define SMC37c669_IS_DEVICE_IRQ(__i) \
76 (((__i) & (SMC37c669_DEVICE_IRQ_MASK)) == (SMC37c669_DEVICE_IRQ_MASK))
77#define SMC37c669_RAW_DEVICE_IRQ(__i) \
78 ((__i) & ~(SMC37c669_DEVICE_IRQ_MASK))
79
80
81
82
83
84
85
86#define SMC37c669_DEVICE_DRQ_MASK 0x80000000
87#define SMC37c669_DEVICE_DRQ(__d) \
88 ((SMC37c669_DEVICE_DRQ_MASK) | (__d))
89#define SMC37c669_IS_DEVICE_DRQ(__d) \
90 (((__d) & (SMC37c669_DEVICE_DRQ_MASK)) == (SMC37c669_DEVICE_DRQ_MASK))
91#define SMC37c669_RAW_DEVICE_DRQ(__d) \
92 ((__d) & ~(SMC37c669_DEVICE_DRQ_MASK))
93
94#define SMC37c669_DEVICE_ID 0x3
95
96
97
98
99#define SERIAL_0 0
100#define SERIAL_1 1
101#define PARALLEL_0 2
102#define FLOPPY_0 3
103#define IDE_0 4
104#define NUM_FUNCS 5
105
106
107
108
109#define COM1_BASE 0x3F8
110#define COM1_IRQ 4
111#define COM2_BASE 0x2F8
112#define COM2_IRQ 3
113#define PARP_BASE 0x3BC
114#define PARP_IRQ 7
115#define PARP_DRQ 3
116#define FDC_BASE 0x3F0
117#define FDC_IRQ 6
118#define FDC_DRQ 2
119
120
121
122
123#define SMC37c669_CONFIG_ON_KEY 0x55
124#define SMC37c669_CONFIG_OFF_KEY 0xAA
125
126
127
128
129#define SMC37c669_DEVICE_IRQ_A ( SMC37c669_DEVICE_IRQ( 0x01 ) )
130#define SMC37c669_DEVICE_IRQ_B ( SMC37c669_DEVICE_IRQ( 0x02 ) )
131#define SMC37c669_DEVICE_IRQ_C ( SMC37c669_DEVICE_IRQ( 0x03 ) )
132#define SMC37c669_DEVICE_IRQ_D ( SMC37c669_DEVICE_IRQ( 0x04 ) )
133#define SMC37c669_DEVICE_IRQ_E ( SMC37c669_DEVICE_IRQ( 0x05 ) )
134#define SMC37c669_DEVICE_IRQ_F ( SMC37c669_DEVICE_IRQ( 0x06 ) )
135
136#define SMC37c669_DEVICE_IRQ_H ( SMC37c669_DEVICE_IRQ( 0x08 ) )
137
138
139
140
141#define SMC37c669_DEVICE_DRQ_A ( SMC37c669_DEVICE_DRQ( 0x01 ) )
142#define SMC37c669_DEVICE_DRQ_B ( SMC37c669_DEVICE_DRQ( 0x02 ) )
143#define SMC37c669_DEVICE_DRQ_C ( SMC37c669_DEVICE_DRQ( 0x03 ) )
144
145
146
147
148#define SMC37c669_CR00_INDEX 0x00
149#define SMC37c669_CR01_INDEX 0x01
150#define SMC37c669_CR02_INDEX 0x02
151#define SMC37c669_CR03_INDEX 0x03
152#define SMC37c669_CR04_INDEX 0x04
153#define SMC37c669_CR05_INDEX 0x05
154#define SMC37c669_CR06_INDEX 0x06
155#define SMC37c669_CR07_INDEX 0x07
156#define SMC37c669_CR08_INDEX 0x08
157#define SMC37c669_CR09_INDEX 0x09
158#define SMC37c669_CR0A_INDEX 0x0A
159#define SMC37c669_CR0B_INDEX 0x0B
160#define SMC37c669_CR0C_INDEX 0x0C
161#define SMC37c669_CR0D_INDEX 0x0D
162#define SMC37c669_CR0E_INDEX 0x0E
163#define SMC37c669_CR0F_INDEX 0x0F
164#define SMC37c669_CR10_INDEX 0x10
165#define SMC37c669_CR11_INDEX 0x11
166#define SMC37c669_CR12_INDEX 0x12
167#define SMC37c669_CR13_INDEX 0x13
168#define SMC37c669_CR14_INDEX 0x14
169#define SMC37c669_CR15_INDEX 0x15
170#define SMC37c669_CR16_INDEX 0x16
171#define SMC37c669_CR17_INDEX 0x17
172#define SMC37c669_CR18_INDEX 0x18
173#define SMC37c669_CR19_INDEX 0x19
174#define SMC37c669_CR1A_INDEX 0x1A
175#define SMC37c669_CR1B_INDEX 0x1B
176#define SMC37c669_CR1C_INDEX 0x1C
177#define SMC37c669_CR1D_INDEX 0x1D
178#define SMC37c669_CR1E_INDEX 0x1E
179#define SMC37c669_CR1F_INDEX 0x1F
180#define SMC37c669_CR20_INDEX 0x20
181#define SMC37c669_CR21_INDEX 0x21
182#define SMC37c669_CR22_INDEX 0x22
183#define SMC37c669_CR23_INDEX 0x23
184#define SMC37c669_CR24_INDEX 0x24
185#define SMC37c669_CR25_INDEX 0x25
186#define SMC37c669_CR26_INDEX 0x26
187#define SMC37c669_CR27_INDEX 0x27
188#define SMC37c669_CR28_INDEX 0x28
189#define SMC37c669_CR29_INDEX 0x29
190
191
192
193
194#define SMC37c669_DEVICE_ID_INDEX SMC37c669_CR0D_INDEX
195#define SMC37c669_DEVICE_REVISION_INDEX SMC37c669_CR0E_INDEX
196#define SMC37c669_FDC_BASE_ADDRESS_INDEX SMC37c669_CR20_INDEX
197#define SMC37c669_IDE_BASE_ADDRESS_INDEX SMC37c669_CR21_INDEX
198#define SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX SMC37c669_CR22_INDEX
199#define SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX SMC37c669_CR23_INDEX
200#define SMC37c669_SERIAL0_BASE_ADDRESS_INDEX SMC37c669_CR24_INDEX
201#define SMC37c669_SERIAL1_BASE_ADDRESS_INDEX SMC37c669_CR25_INDEX
202#define SMC37c669_PARALLEL_FDC_DRQ_INDEX SMC37c669_CR26_INDEX
203#define SMC37c669_PARALLEL_FDC_IRQ_INDEX SMC37c669_CR27_INDEX
204#define SMC37c669_SERIAL_IRQ_INDEX SMC37c669_CR28_INDEX
205
206
207
208
209
210
211
212typedef struct _SMC37c669_CONFIG_REGS {
213 unsigned char index_port;
214 unsigned char data_port;
215} SMC37c669_CONFIG_REGS;
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235typedef union _SMC37c669_CR00 {
236 unsigned char as_uchar;
237 struct {
238 unsigned ide_en : 2;
239 unsigned reserved1 : 1;
240 unsigned fdc_pwr : 1;
241 unsigned reserved2 : 3;
242 unsigned valid : 1;
243 } by_field;
244} SMC37c669_CR00;
245
246
247
248
249typedef union _SMC37c669_CR01 {
250 unsigned char as_uchar;
251 struct {
252 unsigned reserved1 : 2;
253 unsigned ppt_pwr : 1;
254 unsigned ppt_mode : 1;
255 unsigned reserved2 : 1;
256 unsigned reserved3 : 2;
257 unsigned lock_crx: 1;
258 } by_field;
259} SMC37c669_CR01;
260
261
262
263
264typedef union _SMC37c669_CR02 {
265 unsigned char as_uchar;
266 struct {
267 unsigned reserved1 : 3;
268 unsigned uart1_pwr : 1;
269 unsigned reserved2 : 3;
270 unsigned uart2_pwr : 1;
271 } by_field;
272} SMC37c669_CR02;
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290typedef union _SMC37c669_CR03 {
291 unsigned char as_uchar;
292 struct {
293 unsigned pwrgd_gamecs : 1;
294 unsigned fdc_mode2 : 1;
295 unsigned pin94_0 : 1;
296 unsigned reserved1 : 1;
297 unsigned drvden : 1;
298 unsigned op_mode : 2;
299 unsigned pin94_1 : 1;
300 } by_field;
301} SMC37c669_CR03;
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346typedef union _SMC37c669_CR04 {
347 unsigned char as_uchar;
348 struct {
349 unsigned ppt_ext_mode : 2;
350 unsigned ppt_fdc : 2;
351 unsigned midi1 : 1;
352 unsigned midi2 : 1;
353 unsigned epp_type : 1;
354 unsigned alt_io : 1;
355 } by_field;
356} SMC37c669_CR04;
357
358
359
360
361
362
363
364
365
366
367
368typedef union _SMC37c669_CR05 {
369 unsigned char as_uchar;
370 struct {
371 unsigned reserved1 : 2;
372 unsigned fdc_dma_mode : 1;
373 unsigned den_sel : 2;
374 unsigned swap_drv : 1;
375 unsigned extx4 : 1;
376 unsigned reserved2 : 1;
377 } by_field;
378} SMC37c669_CR05;
379
380
381
382
383typedef union _SMC37c669_CR06 {
384 unsigned char as_uchar;
385 struct {
386 unsigned floppy_a : 2;
387 unsigned floppy_b : 2;
388 unsigned floppy_c : 2;
389 unsigned floppy_d : 2;
390 } by_field;
391} SMC37c669_CR06;
392
393
394
395
396
397
398
399
400
401
402
403
404typedef union _SMC37c669_CR07 {
405 unsigned char as_uchar;
406 struct {
407 unsigned floppy_boot : 2;
408 unsigned reserved1 : 2;
409 unsigned ppt_en : 1;
410 unsigned uart1_en : 1;
411 unsigned uart2_en : 1;
412 unsigned fdc_en : 1;
413 } by_field;
414} SMC37c669_CR07;
415
416
417
418
419typedef union _SMC37c669_CR08 {
420 unsigned char as_uchar;
421 struct {
422 unsigned zero : 4;
423 unsigned addrx7_4 : 4;
424 } by_field;
425} SMC37c669_CR08;
426
427
428
429
430
431
432
433
434
435
436
437typedef union _SMC37c669_CR09 {
438 unsigned char as_uchar;
439 struct {
440 unsigned adra8 : 3;
441 unsigned reserved1 : 3;
442 unsigned adrx_config : 2;
443 } by_field;
444} SMC37c669_CR09;
445
446
447
448
449typedef union _SMC37c669_CR0A {
450 unsigned char as_uchar;
451 struct {
452 unsigned ecp_fifo_threshold : 4;
453 unsigned reserved1 : 4;
454 } by_field;
455} SMC37c669_CR0A;
456
457
458
459
460typedef union _SMC37c669_CR0B {
461 unsigned char as_uchar;
462 struct {
463 unsigned fdd0_drtx : 2;
464 unsigned fdd1_drtx : 2;
465 unsigned fdd2_drtx : 2;
466 unsigned fdd3_drtx : 2;
467 } by_field;
468} SMC37c669_CR0B;
469
470
471
472
473
474
475
476
477
478
479
480
481typedef union _SMC37c669_CR0C {
482 unsigned char as_uchar;
483 struct {
484 unsigned uart2_rcv_polarity : 1;
485 unsigned uart2_xmit_polarity : 1;
486 unsigned uart2_duplex : 1;
487 unsigned uart2_mode : 3;
488 unsigned uart1_speed : 1;
489 unsigned uart2_speed : 1;
490 } by_field;
491} SMC37c669_CR0C;
492
493
494
495
496
497
498typedef union _SMC37c669_CR0D {
499 unsigned char as_uchar;
500 struct {
501 unsigned device_id : 8;
502 } by_field;
503} SMC37c669_CR0D;
504
505
506
507
508
509
510typedef union _SMC37c669_CR0E {
511 unsigned char as_uchar;
512 struct {
513 unsigned device_rev : 8;
514 } by_field;
515} SMC37c669_CR0E;
516
517
518
519
520typedef union _SMC37c669_CR0F {
521 unsigned char as_uchar;
522 struct {
523 unsigned test0 : 1;
524 unsigned test1 : 1;
525 unsigned test2 : 1;
526 unsigned test3 : 1;
527 unsigned test4 : 1;
528 unsigned test5 : 1;
529 unsigned test6 : 1;
530 unsigned test7 : 1;
531 } by_field;
532} SMC37c669_CR0F;
533
534
535
536
537typedef union _SMC37c669_CR10 {
538 unsigned char as_uchar;
539 struct {
540 unsigned reserved1 : 3;
541 unsigned pll_gain : 1;
542 unsigned pll_stop : 1;
543 unsigned ace_stop : 1;
544 unsigned pll_clock_ctrl : 1;
545 unsigned ir_test : 1;
546 } by_field;
547} SMC37c669_CR10;
548
549
550
551
552typedef union _SMC37c669_CR11 {
553 unsigned char as_uchar;
554 struct {
555 unsigned ir_loopback : 1;
556 unsigned test_10ms : 1;
557 unsigned reserved1 : 6;
558 } by_field;
559} SMC37c669_CR11;
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575typedef union _SMC37c66_CR1E {
576 unsigned char as_uchar;
577 struct {
578 unsigned gamecs_config: 2;
579 unsigned gamecs_addr9_4 : 6;
580 } by_field;
581} SMC37c669_CR1E;
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599typedef union _SMC37c669_CR1F {
600 unsigned char as_uchar;
601 struct {
602 unsigned fdd0_drive_type : 2;
603 unsigned fdd1_drive_type : 2;
604 unsigned fdd2_drive_type : 2;
605 unsigned fdd3_drive_type : 2;
606 } by_field;
607} SMC37c669_CR1F;
608
609
610
611
612
613
614
615
616
617typedef union _SMC37c669_CR20 {
618 unsigned char as_uchar;
619 struct {
620 unsigned zero : 2;
621 unsigned addr9_4 : 6;
622 } by_field;
623} SMC37c669_CR20;
624
625
626
627
628
629
630
631
632
633typedef union _SMC37c669_CR21 {
634 unsigned char as_uchar;
635 struct {
636 unsigned zero : 2;
637 unsigned addr9_4 : 6;
638 } by_field;
639} SMC37c669_CR21;
640
641
642
643
644
645
646
647
648
649typedef union _SMC37c669_CR22 {
650 unsigned char as_uchar;
651 struct {
652 unsigned zero : 2;
653 unsigned addr9_4 : 6;
654 } by_field;
655} SMC37c669_CR22;
656
657
658
659
660
661
662
663
664
665
666
667typedef union _SMC37c669_CR23 {
668 unsigned char as_uchar;
669 struct {
670 unsigned addr9_2 : 8;
671 } by_field;
672} SMC37c669_CR23;
673
674
675
676
677
678
679
680
681
682typedef union _SMC37c669_CR24 {
683 unsigned char as_uchar;
684 struct {
685 unsigned zero : 1;
686 unsigned addr9_3 : 7;
687 } by_field;
688} SMC37c669_CR24;
689
690
691
692
693
694
695
696
697
698typedef union _SMC37c669_CR25 {
699 unsigned char as_uchar;
700 struct {
701 unsigned zero : 1;
702 unsigned addr9_3 : 7;
703 } by_field;
704} SMC37c669_CR25;
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720typedef union _SMC37c669_CR26 {
721 unsigned char as_uchar;
722 struct {
723 unsigned ppt_drq : 4;
724 unsigned fdc_drq : 4;
725 } by_field;
726} SMC37c669_CR26;
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749typedef union _SMC37c669_CR27 {
750 unsigned char as_uchar;
751 struct {
752 unsigned ppt_irq : 4;
753 unsigned fdc_irq : 4;
754 } by_field;
755} SMC37c669_CR27;
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783typedef union _SMC37c669_CR28 {
784 unsigned char as_uchar;
785 struct {
786 unsigned uart2_irq : 4;
787 unsigned uart1_irq : 4;
788 } by_field;
789} SMC37c669_CR28;
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812typedef union _SMC37c669_CR29 {
813 unsigned char as_uchar;
814 struct {
815 unsigned irqin_irq : 4;
816 unsigned reserved1 : 4;
817 } by_field;
818} SMC37c669_CR29;
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835typedef SMC37c669_CR0D SMC37c669_DEVICE_ID_REGISTER;
836typedef SMC37c669_CR0E SMC37c669_DEVICE_REVISION_REGISTER;
837typedef SMC37c669_CR20 SMC37c669_FDC_BASE_ADDRESS_REGISTER;
838typedef SMC37c669_CR21 SMC37c669_IDE_ADDRESS_REGISTER;
839typedef SMC37c669_CR23 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER;
840typedef SMC37c669_CR24 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER;
841typedef SMC37c669_CR26 SMC37c669_PARALLEL_FDC_DRQ_REGISTER;
842typedef SMC37c669_CR27 SMC37c669_PARALLEL_FDC_IRQ_REGISTER;
843typedef SMC37c669_CR28 SMC37c669_SERIAL_IRQ_REGISTER;
844
845
846
847
848typedef struct _SMC37c669_IRQ_TRANSLATION_ENTRY {
849 int device_irq;
850 int isa_irq;
851} SMC37c669_IRQ_TRANSLATION_ENTRY;
852
853
854
855
856typedef struct _SMC37c669_DRQ_TRANSLATION_ENTRY {
857 int device_drq;
858 int isa_drq;
859} SMC37c669_DRQ_TRANSLATION_ENTRY;
860
861
862
863
864
865SMC37c669_CONFIG_REGS *SMC37c669_detect(
866 int
867);
868
869unsigned int SMC37c669_enable_device(
870 unsigned int func
871);
872
873unsigned int SMC37c669_disable_device(
874 unsigned int func
875);
876
877unsigned int SMC37c669_configure_device(
878 unsigned int func,
879 int port,
880 int irq,
881 int drq
882);
883
884void SMC37c669_display_device_info(
885 void
886);
887
888#endif
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937#if 0
938
939#include "cp$inc:platform_io.h"
940
941#include "cp$src:common.h"
942#include "cp$inc:prototypes.h"
943#include "cp$src:kernel_def.h"
944#include "cp$src:msg_def.h"
945#include "cp$src:smcc669_def.h"
946
947#include "cp$src:platform.h"
948#endif
949
950#ifndef TRUE
951#define TRUE 1
952#endif
953#ifndef FALSE
954#define FALSE 0
955#endif
956
957#define wb( _x_, _y_ ) outb( _y_, (unsigned int)((unsigned long)_x_) )
958#define rb( _x_ ) inb( (unsigned int)((unsigned long)_x_) )
959
960
961
962
963
964
965
966
967
968
969
970static struct DEVICE_CONFIG {
971 unsigned int port1;
972 unsigned int port2;
973 int irq;
974 int drq;
975} local_config [NUM_FUNCS];
976
977
978
979
980static unsigned long SMC37c669_Addresses[] __initdata =
981 {
982 0x3F0UL,
983 0x370UL,
984 0UL
985 };
986
987
988
989
990static SMC37c669_CONFIG_REGS *SMC37c669 __initdata = NULL;
991
992
993
994
995
996
997
998
999static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_table __initdata;
1000
1001
1002
1003
1004
1005static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_default_irq_table[]
1006__initdata =
1007 {
1008 { SMC37c669_DEVICE_IRQ_A, -1 },
1009 { SMC37c669_DEVICE_IRQ_B, -1 },
1010 { SMC37c669_DEVICE_IRQ_C, 7 },
1011 { SMC37c669_DEVICE_IRQ_D, 6 },
1012 { SMC37c669_DEVICE_IRQ_E, 4 },
1013 { SMC37c669_DEVICE_IRQ_F, 3 },
1014 { SMC37c669_DEVICE_IRQ_H, -1 },
1015 { -1, -1 }
1016 };
1017
1018
1019
1020
1021
1022static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_monet_irq_table[]
1023__initdata =
1024 {
1025 { SMC37c669_DEVICE_IRQ_A, -1 },
1026 { SMC37c669_DEVICE_IRQ_B, -1 },
1027 { SMC37c669_DEVICE_IRQ_C, 6 },
1028 { SMC37c669_DEVICE_IRQ_D, 7 },
1029 { SMC37c669_DEVICE_IRQ_E, 4 },
1030 { SMC37c669_DEVICE_IRQ_F, 3 },
1031 { SMC37c669_DEVICE_IRQ_H, -1 },
1032 { -1, -1 }
1033 };
1034
1035static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_tables[] __initdata =
1036 {
1037 SMC37c669_default_irq_table,
1038 SMC37c669_monet_irq_table
1039 };
1040
1041
1042
1043
1044
1045
1046
1047
1048static SMC37c669_DRQ_TRANSLATION_ENTRY *SMC37c669_drq_table __initdata;
1049
1050
1051
1052
1053
1054static SMC37c669_DRQ_TRANSLATION_ENTRY SMC37c669_default_drq_table[]
1055__initdata =
1056 {
1057 { SMC37c669_DEVICE_DRQ_A, 2 },
1058 { SMC37c669_DEVICE_DRQ_B, 3 },
1059 { SMC37c669_DEVICE_DRQ_C, -1 },
1060 { -1, -1 }
1061 };
1062
1063
1064
1065
1066
1067static unsigned int SMC37c669_is_device_enabled(
1068 unsigned int func
1069);
1070
1071#if 0
1072static unsigned int SMC37c669_get_device_config(
1073 unsigned int func,
1074 int *port,
1075 int *irq,
1076 int *drq
1077);
1078#endif
1079
1080static void SMC37c669_config_mode(
1081 unsigned int enable
1082);
1083
1084static unsigned char SMC37c669_read_config(
1085 unsigned char index
1086);
1087
1088static void SMC37c669_write_config(
1089 unsigned char index,
1090 unsigned char data
1091);
1092
1093static void SMC37c669_init_local_config( void );
1094
1095static struct DEVICE_CONFIG *SMC37c669_get_config(
1096 unsigned int func
1097);
1098
1099static int SMC37c669_xlate_irq(
1100 int irq
1101);
1102
1103static int SMC37c669_xlate_drq(
1104 int drq
1105);
1106
1107static __cacheline_aligned DEFINE_SPINLOCK(smc_lock);
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131SMC37c669_CONFIG_REGS * __init SMC37c669_detect( int index )
1132{
1133 int i;
1134 SMC37c669_DEVICE_ID_REGISTER id;
1135
1136 for ( i = 0; SMC37c669_Addresses[i] != 0; i++ ) {
1137
1138
1139
1140
1141
1142
1143 SMC37c669 = ( SMC37c669_CONFIG_REGS * )SMC37c669_Addresses[i];
1144
1145
1146
1147 SMC37c669_config_mode( TRUE );
1148
1149
1150
1151 id.as_uchar = SMC37c669_read_config( SMC37c669_DEVICE_ID_INDEX );
1152
1153
1154
1155 SMC37c669_config_mode( FALSE );
1156
1157
1158
1159
1160 if ( id.by_field.device_id == SMC37c669_DEVICE_ID ) {
1161
1162
1163
1164 SMC37c669_irq_table = SMC37c669_irq_tables[ index ];
1165 SMC37c669_drq_table = SMC37c669_default_drq_table;
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179 SMC37c669_config_mode( TRUE );
1180
1181
1182
1183 SMC37c669_init_local_config( );
1184
1185
1186
1187 SMC37c669_config_mode( FALSE );
1188
1189
1190
1191 break;
1192 }
1193 else {
1194
1195
1196
1197
1198 SMC37c669 = NULL;
1199 }
1200 }
1201 return SMC37c669;
1202}
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239unsigned int __init SMC37c669_enable_device ( unsigned int func )
1240{
1241 unsigned int ret_val = FALSE;
1242
1243
1244
1245 SMC37c669_config_mode( TRUE );
1246 switch ( func ) {
1247 case SERIAL_0:
1248 {
1249 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1250 SMC37c669_SERIAL_IRQ_REGISTER irq;
1251
1252
1253
1254 irq.as_uchar =
1255 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1256
1257 irq.by_field.uart1_irq =
1258 SMC37c669_RAW_DEVICE_IRQ(
1259 SMC37c669_xlate_irq( local_config[ func ].irq )
1260 );
1261
1262 SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1263
1264
1265
1266 base_addr.as_uchar = 0;
1267 base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
1268
1269 SMC37c669_write_config(
1270 SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
1271 base_addr.as_uchar
1272 );
1273 ret_val = TRUE;
1274 break;
1275 }
1276 case SERIAL_1:
1277 {
1278 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1279 SMC37c669_SERIAL_IRQ_REGISTER irq;
1280
1281
1282
1283 irq.as_uchar =
1284 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1285
1286 irq.by_field.uart2_irq =
1287 SMC37c669_RAW_DEVICE_IRQ(
1288 SMC37c669_xlate_irq( local_config[ func ].irq )
1289 );
1290
1291 SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1292
1293
1294
1295 base_addr.as_uchar = 0;
1296 base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
1297
1298 SMC37c669_write_config(
1299 SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
1300 base_addr.as_uchar
1301 );
1302 ret_val = TRUE;
1303 break;
1304 }
1305 case PARALLEL_0:
1306 {
1307 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
1308 SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1309 SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1310
1311
1312
1313 drq.as_uchar =
1314 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1315
1316 drq.by_field.ppt_drq =
1317 SMC37c669_RAW_DEVICE_DRQ(
1318 SMC37c669_xlate_drq( local_config[ func ].drq )
1319 );
1320
1321 SMC37c669_write_config(
1322 SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1323 drq.as_uchar
1324 );
1325
1326
1327
1328 irq.as_uchar =
1329 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1330
1331 irq.by_field.ppt_irq =
1332 SMC37c669_RAW_DEVICE_IRQ(
1333 SMC37c669_xlate_irq( local_config[ func ].irq )
1334 );
1335
1336 SMC37c669_write_config(
1337 SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1338 irq.as_uchar
1339 );
1340
1341
1342
1343 base_addr.as_uchar = 0;
1344 base_addr.by_field.addr9_2 = local_config[ func ].port1 >> 2;
1345
1346 SMC37c669_write_config(
1347 SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
1348 base_addr.as_uchar
1349 );
1350 ret_val = TRUE;
1351 break;
1352 }
1353 case FLOPPY_0:
1354 {
1355 SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
1356 SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1357 SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1358
1359
1360
1361 drq.as_uchar =
1362 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1363
1364 drq.by_field.fdc_drq =
1365 SMC37c669_RAW_DEVICE_DRQ(
1366 SMC37c669_xlate_drq( local_config[ func ].drq )
1367 );
1368
1369 SMC37c669_write_config(
1370 SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1371 drq.as_uchar
1372 );
1373
1374
1375
1376 irq.as_uchar =
1377 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1378
1379 irq.by_field.fdc_irq =
1380 SMC37c669_RAW_DEVICE_IRQ(
1381 SMC37c669_xlate_irq( local_config[ func ].irq )
1382 );
1383
1384 SMC37c669_write_config(
1385 SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1386 irq.as_uchar
1387 );
1388
1389
1390
1391 base_addr.as_uchar = 0;
1392 base_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
1393
1394 SMC37c669_write_config(
1395 SMC37c669_FDC_BASE_ADDRESS_INDEX,
1396 base_addr.as_uchar
1397 );
1398 ret_val = TRUE;
1399 break;
1400 }
1401 case IDE_0:
1402 {
1403 SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
1404
1405
1406
1407 ide_addr.as_uchar = 0;
1408 ide_addr.by_field.addr9_4 = local_config[ func ].port2 >> 4;
1409
1410 SMC37c669_write_config(
1411 SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
1412 ide_addr.as_uchar
1413 );
1414
1415
1416
1417 ide_addr.as_uchar = 0;
1418 ide_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
1419
1420 SMC37c669_write_config(
1421 SMC37c669_IDE_BASE_ADDRESS_INDEX,
1422 ide_addr.as_uchar
1423 );
1424 ret_val = TRUE;
1425 break;
1426 }
1427 }
1428
1429
1430
1431 SMC37c669_config_mode( FALSE );
1432
1433 return ret_val;
1434}
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467unsigned int __init SMC37c669_disable_device ( unsigned int func )
1468{
1469 unsigned int ret_val = FALSE;
1470
1471
1472
1473
1474 SMC37c669_config_mode( TRUE );
1475 switch ( func ) {
1476 case SERIAL_0:
1477 {
1478 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1479 SMC37c669_SERIAL_IRQ_REGISTER irq;
1480
1481
1482
1483 irq.as_uchar =
1484 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1485
1486 irq.by_field.uart1_irq = 0;
1487
1488 SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1489
1490
1491
1492 base_addr.as_uchar = 0;
1493 SMC37c669_write_config(
1494 SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
1495 base_addr.as_uchar
1496 );
1497 ret_val = TRUE;
1498 break;
1499 }
1500 case SERIAL_1:
1501 {
1502 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1503 SMC37c669_SERIAL_IRQ_REGISTER irq;
1504
1505
1506
1507 irq.as_uchar =
1508 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1509
1510 irq.by_field.uart2_irq = 0;
1511
1512 SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1513
1514
1515
1516 base_addr.as_uchar = 0;
1517
1518 SMC37c669_write_config(
1519 SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
1520 base_addr.as_uchar
1521 );
1522 ret_val = TRUE;
1523 break;
1524 }
1525 case PARALLEL_0:
1526 {
1527 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
1528 SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1529 SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1530
1531
1532
1533 drq.as_uchar =
1534 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1535
1536 drq.by_field.ppt_drq = 0;
1537
1538 SMC37c669_write_config(
1539 SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1540 drq.as_uchar
1541 );
1542
1543
1544
1545 irq.as_uchar =
1546 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1547
1548 irq.by_field.ppt_irq = 0;
1549
1550 SMC37c669_write_config(
1551 SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1552 irq.as_uchar
1553 );
1554
1555
1556
1557 base_addr.as_uchar = 0;
1558
1559 SMC37c669_write_config(
1560 SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
1561 base_addr.as_uchar
1562 );
1563 ret_val = TRUE;
1564 break;
1565 }
1566 case FLOPPY_0:
1567 {
1568 SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
1569 SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1570 SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1571
1572
1573
1574 drq.as_uchar =
1575 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1576
1577 drq.by_field.fdc_drq = 0;
1578
1579 SMC37c669_write_config(
1580 SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1581 drq.as_uchar
1582 );
1583
1584
1585
1586 irq.as_uchar =
1587 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1588
1589 irq.by_field.fdc_irq = 0;
1590
1591 SMC37c669_write_config(
1592 SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1593 irq.as_uchar
1594 );
1595
1596
1597
1598 base_addr.as_uchar = 0;
1599
1600 SMC37c669_write_config(
1601 SMC37c669_FDC_BASE_ADDRESS_INDEX,
1602 base_addr.as_uchar
1603 );
1604 ret_val = TRUE;
1605 break;
1606 }
1607 case IDE_0:
1608 {
1609 SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
1610
1611
1612
1613 ide_addr.as_uchar = 0;
1614
1615 SMC37c669_write_config(
1616 SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
1617 ide_addr.as_uchar
1618 );
1619
1620
1621
1622 ide_addr.as_uchar = 0;
1623
1624 SMC37c669_write_config(
1625 SMC37c669_IDE_BASE_ADDRESS_INDEX,
1626 ide_addr.as_uchar
1627 );
1628 ret_val = TRUE;
1629 break;
1630 }
1631 }
1632
1633
1634
1635 SMC37c669_config_mode( FALSE );
1636
1637 return ret_val;
1638}
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681unsigned int __init SMC37c669_configure_device (
1682 unsigned int func,
1683 int port,
1684 int irq,
1685 int drq )
1686{
1687 struct DEVICE_CONFIG *cp;
1688
1689
1690
1691
1692 if ( ( cp = SMC37c669_get_config ( func ) ) != NULL ) {
1693
1694
1695
1696 if ( ( drq & ~0xFF ) == 0 ) {
1697 cp->drq = drq;
1698 }
1699 if ( ( irq & ~0xFF ) == 0 ) {
1700 cp->irq = irq;
1701 }
1702 if ( ( port & ~0xFFFF ) == 0 ) {
1703 cp->port1 = port;
1704 }
1705
1706
1707
1708
1709 if ( SMC37c669_is_device_enabled( func ) ) {
1710 SMC37c669_enable_device( func );
1711 }
1712 return TRUE;
1713 }
1714 return FALSE;
1715}
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748static unsigned int __init SMC37c669_is_device_enabled ( unsigned int func )
1749{
1750 unsigned char base_addr = 0;
1751 unsigned int dev_ok = FALSE;
1752 unsigned int ret_val = FALSE;
1753
1754
1755
1756 SMC37c669_config_mode( TRUE );
1757
1758 switch ( func ) {
1759 case SERIAL_0:
1760 base_addr =
1761 SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
1762 dev_ok = TRUE;
1763 break;
1764 case SERIAL_1:
1765 base_addr =
1766 SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
1767 dev_ok = TRUE;
1768 break;
1769 case PARALLEL_0:
1770 base_addr =
1771 SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
1772 dev_ok = TRUE;
1773 break;
1774 case FLOPPY_0:
1775 base_addr =
1776 SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
1777 dev_ok = TRUE;
1778 break;
1779 case IDE_0:
1780 base_addr =
1781 SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
1782 dev_ok = TRUE;
1783 break;
1784 }
1785
1786
1787
1788
1789 if ( ( dev_ok ) && ( ( base_addr & 0xC0 ) != 0 ) ) {
1790
1791
1792
1793
1794 ret_val = TRUE;
1795 }
1796
1797
1798
1799 SMC37c669_config_mode( FALSE );
1800
1801 return ret_val;
1802}
1803
1804
1805#if 0
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847static unsigned int __init SMC37c669_get_device_config (
1848 unsigned int func,
1849 int *port,
1850 int *irq,
1851 int *drq )
1852{
1853 struct DEVICE_CONFIG *cp;
1854 unsigned int ret_val = FALSE;
1855
1856
1857
1858 if ( ( cp = SMC37c669_get_config( func ) ) != NULL ) {
1859 if ( drq != NULL ) {
1860 *drq = cp->drq;
1861 ret_val = TRUE;
1862 }
1863 if ( irq != NULL ) {
1864 *irq = cp->irq;
1865 ret_val = TRUE;
1866 }
1867 if ( port != NULL ) {
1868 *port = cp->port1;
1869 ret_val = TRUE;
1870 }
1871 }
1872 return ret_val;
1873}
1874#endif
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898void __init SMC37c669_display_device_info ( void )
1899{
1900 if ( SMC37c669_is_device_enabled( SERIAL_0 ) ) {
1901 printk( " Serial 0: Enabled [ Port 0x%x, IRQ %d ]\n",
1902 local_config[ SERIAL_0 ].port1,
1903 local_config[ SERIAL_0 ].irq
1904 );
1905 }
1906 else {
1907 printk( " Serial 0: Disabled\n" );
1908 }
1909
1910 if ( SMC37c669_is_device_enabled( SERIAL_1 ) ) {
1911 printk( " Serial 1: Enabled [ Port 0x%x, IRQ %d ]\n",
1912 local_config[ SERIAL_1 ].port1,
1913 local_config[ SERIAL_1 ].irq
1914 );
1915 }
1916 else {
1917 printk( " Serial 1: Disabled\n" );
1918 }
1919
1920 if ( SMC37c669_is_device_enabled( PARALLEL_0 ) ) {
1921 printk( " Parallel: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
1922 local_config[ PARALLEL_0 ].port1,
1923 local_config[ PARALLEL_0 ].irq,
1924 local_config[ PARALLEL_0 ].drq
1925 );
1926 }
1927 else {
1928 printk( " Parallel: Disabled\n" );
1929 }
1930
1931 if ( SMC37c669_is_device_enabled( FLOPPY_0 ) ) {
1932 printk( " Floppy Ctrl: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
1933 local_config[ FLOPPY_0 ].port1,
1934 local_config[ FLOPPY_0 ].irq,
1935 local_config[ FLOPPY_0 ].drq
1936 );
1937 }
1938 else {
1939 printk( " Floppy Ctrl: Disabled\n" );
1940 }
1941
1942 if ( SMC37c669_is_device_enabled( IDE_0 ) ) {
1943 printk( " IDE 0: Enabled [ Port 0x%x, IRQ %d ]\n",
1944 local_config[ IDE_0 ].port1,
1945 local_config[ IDE_0 ].irq
1946 );
1947 }
1948 else {
1949 printk( " IDE 0: Disabled\n" );
1950 }
1951}
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976static void __init SMC37c669_config_mode(
1977 unsigned int enable )
1978{
1979 if ( enable ) {
1980
1981
1982
1983
1984
1985
1986
1987 spin_lock(&smc_lock);
1988 wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
1989 wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
1990 spin_unlock(&smc_lock);
1991 }
1992 else {
1993 wb( &SMC37c669->index_port, SMC37c669_CONFIG_OFF_KEY );
1994 }
1995}
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020static unsigned char __init SMC37c669_read_config(
2021 unsigned char index )
2022{
2023 unsigned char data;
2024
2025 wb( &SMC37c669->index_port, index );
2026 data = rb( &SMC37c669->data_port );
2027 return data;
2028}
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056static void __init SMC37c669_write_config(
2057 unsigned char index,
2058 unsigned char data )
2059{
2060 wb( &SMC37c669->index_port, index );
2061 wb( &SMC37c669->data_port, data );
2062}
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089static void __init SMC37c669_init_local_config ( void )
2090{
2091 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER uart_base;
2092 SMC37c669_SERIAL_IRQ_REGISTER uart_irqs;
2093 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER ppt_base;
2094 SMC37c669_PARALLEL_FDC_IRQ_REGISTER ppt_fdc_irqs;
2095 SMC37c669_PARALLEL_FDC_DRQ_REGISTER ppt_fdc_drqs;
2096 SMC37c669_FDC_BASE_ADDRESS_REGISTER fdc_base;
2097 SMC37c669_IDE_ADDRESS_REGISTER ide_base;
2098 SMC37c669_IDE_ADDRESS_REGISTER ide_alt;
2099
2100
2101
2102
2103 uart_base.as_uchar =
2104 SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
2105
2106
2107
2108 uart_irqs.as_uchar =
2109 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
2110
2111
2112
2113 local_config[SERIAL_0].port1 = uart_base.by_field.addr9_3 << 3;
2114 local_config[SERIAL_0].irq =
2115 SMC37c669_xlate_irq(
2116 SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart1_irq )
2117 );
2118
2119
2120
2121 uart_base.as_uchar =
2122 SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
2123
2124
2125
2126 local_config[SERIAL_1].port1 = uart_base.by_field.addr9_3 << 3;
2127 local_config[SERIAL_1].irq =
2128 SMC37c669_xlate_irq(
2129 SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart2_irq )
2130 );
2131
2132
2133
2134 ppt_base.as_uchar =
2135 SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
2136
2137
2138
2139 ppt_fdc_irqs.as_uchar =
2140 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
2141
2142
2143
2144 ppt_fdc_drqs.as_uchar =
2145 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
2146
2147
2148
2149 local_config[PARALLEL_0].port1 = ppt_base.by_field.addr9_2 << 2;
2150 local_config[PARALLEL_0].irq =
2151 SMC37c669_xlate_irq(
2152 SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.ppt_irq )
2153 );
2154 local_config[PARALLEL_0].drq =
2155 SMC37c669_xlate_drq(
2156 SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.ppt_drq )
2157 );
2158
2159
2160
2161 fdc_base.as_uchar =
2162 SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
2163
2164
2165
2166 local_config[FLOPPY_0].port1 = fdc_base.by_field.addr9_4 << 4;
2167 local_config[FLOPPY_0].irq =
2168 SMC37c669_xlate_irq(
2169 SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.fdc_irq )
2170 );
2171 local_config[FLOPPY_0].drq =
2172 SMC37c669_xlate_drq(
2173 SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.fdc_drq )
2174 );
2175
2176
2177
2178 ide_base.as_uchar =
2179 SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
2180
2181
2182
2183 ide_alt.as_uchar =
2184 SMC37c669_read_config( SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX );
2185
2186
2187
2188 local_config[IDE_0].port1 = ide_base.by_field.addr9_4 << 4;
2189 local_config[IDE_0].port2 = ide_alt.by_field.addr9_4 << 4;
2190 local_config[IDE_0].irq = 14;
2191}
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217static struct DEVICE_CONFIG * __init SMC37c669_get_config( unsigned int func )
2218{
2219 struct DEVICE_CONFIG *cp = NULL;
2220
2221 switch ( func ) {
2222 case SERIAL_0:
2223 cp = &local_config[ SERIAL_0 ];
2224 break;
2225 case SERIAL_1:
2226 cp = &local_config[ SERIAL_1 ];
2227 break;
2228 case PARALLEL_0:
2229 cp = &local_config[ PARALLEL_0 ];
2230 break;
2231 case FLOPPY_0:
2232 cp = &local_config[ FLOPPY_0 ];
2233 break;
2234 case IDE_0:
2235 cp = &local_config[ IDE_0 ];
2236 break;
2237 }
2238 return cp;
2239}
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263static int __init SMC37c669_xlate_irq ( int irq )
2264{
2265 int i, translated_irq = -1;
2266
2267 if ( SMC37c669_IS_DEVICE_IRQ( irq ) ) {
2268
2269
2270
2271 for ( i = 0; ( SMC37c669_irq_table[i].device_irq != -1 ) || ( SMC37c669_irq_table[i].isa_irq != -1 ); i++ ) {
2272 if ( irq == SMC37c669_irq_table[i].device_irq ) {
2273 translated_irq = SMC37c669_irq_table[i].isa_irq;
2274 break;
2275 }
2276 }
2277 }
2278 else {
2279
2280
2281
2282 for ( i = 0; ( SMC37c669_irq_table[i].isa_irq != -1 ) || ( SMC37c669_irq_table[i].device_irq != -1 ); i++ ) {
2283 if ( irq == SMC37c669_irq_table[i].isa_irq ) {
2284 translated_irq = SMC37c669_irq_table[i].device_irq;
2285 break;
2286 }
2287 }
2288 }
2289 return translated_irq;
2290}
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315static int __init SMC37c669_xlate_drq ( int drq )
2316{
2317 int i, translated_drq = -1;
2318
2319 if ( SMC37c669_IS_DEVICE_DRQ( drq ) ) {
2320
2321
2322
2323 for ( i = 0; ( SMC37c669_drq_table[i].device_drq != -1 ) || ( SMC37c669_drq_table[i].isa_drq != -1 ); i++ ) {
2324 if ( drq == SMC37c669_drq_table[i].device_drq ) {
2325 translated_drq = SMC37c669_drq_table[i].isa_drq;
2326 break;
2327 }
2328 }
2329 }
2330 else {
2331
2332
2333
2334 for ( i = 0; ( SMC37c669_drq_table[i].isa_drq != -1 ) || ( SMC37c669_drq_table[i].device_drq != -1 ); i++ ) {
2335 if ( drq == SMC37c669_drq_table[i].isa_drq ) {
2336 translated_drq = SMC37c669_drq_table[i].device_drq;
2337 break;
2338 }
2339 }
2340 }
2341 return translated_drq;
2342}
2343
2344#if 0
2345int __init smcc669_init ( void )
2346{
2347 struct INODE *ip;
2348
2349 allocinode( smc_ddb.name, 1, &ip );
2350 ip->dva = &smc_ddb;
2351 ip->attr = ATTR$M_WRITE | ATTR$M_READ;
2352 ip->len[0] = 0x30;
2353 ip->misc = 0;
2354 INODE_UNLOCK( ip );
2355
2356 return msg_success;
2357}
2358
2359int __init smcc669_open( struct FILE *fp, char *info, char *next, char *mode )
2360{
2361 struct INODE *ip;
2362
2363
2364
2365
2366 ip = fp->ip;
2367 INODE_LOCK( ip );
2368 if ( fp->mode & ATTR$M_WRITE ) {
2369 if ( ip->misc ) {
2370 INODE_UNLOCK( ip );
2371 return msg_failure;
2372 }
2373 ip->misc++;
2374 }
2375
2376
2377
2378 *fp->offset = xtoi( info );
2379 INODE_UNLOCK( ip );
2380
2381 return msg_success;
2382}
2383
2384int __init smcc669_close( struct FILE *fp )
2385{
2386 struct INODE *ip;
2387
2388 ip = fp->ip;
2389 if ( fp->mode & ATTR$M_WRITE ) {
2390 INODE_LOCK( ip );
2391 ip->misc--;
2392 INODE_UNLOCK( ip );
2393 }
2394 return msg_success;
2395}
2396
2397int __init smcc669_read( struct FILE *fp, int size, int number, unsigned char *buf )
2398{
2399 int i;
2400 int length;
2401 int nbytes;
2402 struct INODE *ip;
2403
2404
2405
2406
2407 ip = fp->ip;
2408 length = size * number;
2409 nbytes = 0;
2410
2411 SMC37c669_config_mode( TRUE );
2412 for ( i = 0; i < length; i++ ) {
2413 if ( !inrange( *fp->offset, 0, ip->len[0] ) )
2414 break;
2415 *buf++ = SMC37c669_read_config( *fp->offset );
2416 *fp->offset += 1;
2417 nbytes++;
2418 }
2419 SMC37c669_config_mode( FALSE );
2420 return nbytes;
2421}
2422
2423int __init smcc669_write( struct FILE *fp, int size, int number, unsigned char *buf )
2424{
2425 int i;
2426 int length;
2427 int nbytes;
2428 struct INODE *ip;
2429
2430
2431
2432 ip = fp->ip;
2433 length = size * number;
2434 nbytes = 0;
2435
2436 SMC37c669_config_mode( TRUE );
2437 for ( i = 0; i < length; i++ ) {
2438 if ( !inrange( *fp->offset, 0, ip->len[0] ) )
2439 break;
2440 SMC37c669_write_config( *fp->offset, *buf );
2441 *fp->offset += 1;
2442 buf++;
2443 nbytes++;
2444 }
2445 SMC37c669_config_mode( FALSE );
2446 return nbytes;
2447}
2448#endif
2449
2450void __init
2451SMC37c669_dump_registers(void)
2452{
2453 int i;
2454 for (i = 0; i <= 0x29; i++)
2455 printk("-- CR%02x : %02x\n", i, SMC37c669_read_config(i));
2456}
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484void __init SMC669_Init ( int index )
2485{
2486 SMC37c669_CONFIG_REGS *SMC_base;
2487 unsigned long flags;
2488
2489 local_irq_save(flags);
2490 if ( ( SMC_base = SMC37c669_detect( index ) ) != NULL ) {
2491#if SMC_DEBUG
2492 SMC37c669_config_mode( TRUE );
2493 SMC37c669_dump_registers( );
2494 SMC37c669_config_mode( FALSE );
2495 SMC37c669_display_device_info( );
2496#endif
2497 SMC37c669_disable_device( SERIAL_0 );
2498 SMC37c669_configure_device(
2499 SERIAL_0,
2500 COM1_BASE,
2501 COM1_IRQ,
2502 -1
2503 );
2504 SMC37c669_enable_device( SERIAL_0 );
2505
2506 SMC37c669_disable_device( SERIAL_1 );
2507 SMC37c669_configure_device(
2508 SERIAL_1,
2509 COM2_BASE,
2510 COM2_IRQ,
2511 -1
2512 );
2513 SMC37c669_enable_device( SERIAL_1 );
2514
2515 SMC37c669_disable_device( PARALLEL_0 );
2516 SMC37c669_configure_device(
2517 PARALLEL_0,
2518 PARP_BASE,
2519 PARP_IRQ,
2520 PARP_DRQ
2521 );
2522 SMC37c669_enable_device( PARALLEL_0 );
2523
2524 SMC37c669_disable_device( FLOPPY_0 );
2525 SMC37c669_configure_device(
2526 FLOPPY_0,
2527 FDC_BASE,
2528 FDC_IRQ,
2529 FDC_DRQ
2530 );
2531 SMC37c669_enable_device( FLOPPY_0 );
2532
2533
2534 outb(0xc, 0x3f2);
2535
2536 SMC37c669_disable_device( IDE_0 );
2537
2538#if SMC_DEBUG
2539 SMC37c669_config_mode( TRUE );
2540 SMC37c669_dump_registers( );
2541 SMC37c669_config_mode( FALSE );
2542 SMC37c669_display_device_info( );
2543#endif
2544 local_irq_restore(flags);
2545 printk( "SMC37c669 Super I/O Controller found @ 0x%lx\n",
2546 (unsigned long) SMC_base );
2547 }
2548 else {
2549 local_irq_restore(flags);
2550#if SMC_DEBUG
2551 printk( "No SMC37c669 Super I/O Controller found\n" );
2552#endif
2553 }
2554}
2555