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