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#if 0
937
938#include "cp$inc:platform_io.h"
939
940#include "cp$src:common.h"
941#include "cp$inc:prototypes.h"
942#include "cp$src:kernel_def.h"
943#include "cp$src:msg_def.h"
944#include "cp$src:smcc669_def.h"
945
946#include "cp$src:platform.h"
947#endif
948
949#ifndef TRUE
950#define TRUE 1
951#endif
952#ifndef FALSE
953#define FALSE 0
954#endif
955
956#define wb( _x_, _y_ ) outb( _y_, (unsigned int)((unsigned long)_x_) )
957#define rb( _x_ ) inb( (unsigned int)((unsigned long)_x_) )
958
959
960
961
962
963
964
965
966
967
968
969static struct DEVICE_CONFIG {
970 unsigned int port1;
971 unsigned int port2;
972 int irq;
973 int drq;
974} local_config [NUM_FUNCS];
975
976
977
978
979static unsigned long SMC37c669_Addresses[] __initdata =
980 {
981 0x3F0UL,
982 0x370UL,
983 0UL
984 };
985
986
987
988
989static SMC37c669_CONFIG_REGS *SMC37c669 __initdata = NULL;
990
991
992
993
994
995
996
997
998static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_table __initdata;
999
1000
1001
1002
1003
1004static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_default_irq_table[]
1005__initdata =
1006 {
1007 { SMC37c669_DEVICE_IRQ_A, -1 },
1008 { SMC37c669_DEVICE_IRQ_B, -1 },
1009 { SMC37c669_DEVICE_IRQ_C, 7 },
1010 { SMC37c669_DEVICE_IRQ_D, 6 },
1011 { SMC37c669_DEVICE_IRQ_E, 4 },
1012 { SMC37c669_DEVICE_IRQ_F, 3 },
1013 { SMC37c669_DEVICE_IRQ_H, -1 },
1014 { -1, -1 }
1015 };
1016
1017
1018
1019
1020
1021static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_monet_irq_table[]
1022__initdata =
1023 {
1024 { SMC37c669_DEVICE_IRQ_A, -1 },
1025 { SMC37c669_DEVICE_IRQ_B, -1 },
1026 { SMC37c669_DEVICE_IRQ_C, 6 },
1027 { SMC37c669_DEVICE_IRQ_D, 7 },
1028 { SMC37c669_DEVICE_IRQ_E, 4 },
1029 { SMC37c669_DEVICE_IRQ_F, 3 },
1030 { SMC37c669_DEVICE_IRQ_H, -1 },
1031 { -1, -1 }
1032 };
1033
1034static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_tables[] __initdata =
1035 {
1036 SMC37c669_default_irq_table,
1037 SMC37c669_monet_irq_table
1038 };
1039
1040
1041
1042
1043
1044
1045
1046
1047static SMC37c669_DRQ_TRANSLATION_ENTRY *SMC37c669_drq_table __initdata;
1048
1049
1050
1051
1052
1053static SMC37c669_DRQ_TRANSLATION_ENTRY SMC37c669_default_drq_table[]
1054__initdata =
1055 {
1056 { SMC37c669_DEVICE_DRQ_A, 2 },
1057 { SMC37c669_DEVICE_DRQ_B, 3 },
1058 { SMC37c669_DEVICE_DRQ_C, -1 },
1059 { -1, -1 }
1060 };
1061
1062
1063
1064
1065
1066static unsigned int SMC37c669_is_device_enabled(
1067 unsigned int func
1068);
1069
1070#if 0
1071static unsigned int SMC37c669_get_device_config(
1072 unsigned int func,
1073 int *port,
1074 int *irq,
1075 int *drq
1076);
1077#endif
1078
1079static void SMC37c669_config_mode(
1080 unsigned int enable
1081);
1082
1083static unsigned char SMC37c669_read_config(
1084 unsigned char index
1085);
1086
1087static void SMC37c669_write_config(
1088 unsigned char index,
1089 unsigned char data
1090);
1091
1092static void SMC37c669_init_local_config( void );
1093
1094static struct DEVICE_CONFIG *SMC37c669_get_config(
1095 unsigned int func
1096);
1097
1098static int SMC37c669_xlate_irq(
1099 int irq
1100);
1101
1102static int SMC37c669_xlate_drq(
1103 int drq
1104);
1105
1106static __cacheline_aligned DEFINE_SPINLOCK(smc_lock);
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130SMC37c669_CONFIG_REGS * __init SMC37c669_detect( int index )
1131{
1132 int i;
1133 SMC37c669_DEVICE_ID_REGISTER id;
1134
1135 for ( i = 0; SMC37c669_Addresses[i] != 0; i++ ) {
1136
1137
1138
1139
1140
1141
1142 SMC37c669 = ( SMC37c669_CONFIG_REGS * )SMC37c669_Addresses[i];
1143
1144
1145
1146 SMC37c669_config_mode( TRUE );
1147
1148
1149
1150 id.as_uchar = SMC37c669_read_config( SMC37c669_DEVICE_ID_INDEX );
1151
1152
1153
1154 SMC37c669_config_mode( FALSE );
1155
1156
1157
1158
1159 if ( id.by_field.device_id == SMC37c669_DEVICE_ID ) {
1160
1161
1162
1163 SMC37c669_irq_table = SMC37c669_irq_tables[ index ];
1164 SMC37c669_drq_table = SMC37c669_default_drq_table;
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178 SMC37c669_config_mode( TRUE );
1179
1180
1181
1182 SMC37c669_init_local_config( );
1183
1184
1185
1186 SMC37c669_config_mode( FALSE );
1187
1188
1189
1190 break;
1191 }
1192 else {
1193
1194
1195
1196
1197 SMC37c669 = NULL;
1198 }
1199 }
1200 return SMC37c669;
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
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238unsigned int __init SMC37c669_enable_device ( unsigned int func )
1239{
1240 unsigned int ret_val = FALSE;
1241
1242
1243
1244 SMC37c669_config_mode( TRUE );
1245 switch ( func ) {
1246 case SERIAL_0:
1247 {
1248 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1249 SMC37c669_SERIAL_IRQ_REGISTER irq;
1250
1251
1252
1253 irq.as_uchar =
1254 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1255
1256 irq.by_field.uart1_irq =
1257 SMC37c669_RAW_DEVICE_IRQ(
1258 SMC37c669_xlate_irq( local_config[ func ].irq )
1259 );
1260
1261 SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1262
1263
1264
1265 base_addr.as_uchar = 0;
1266 base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
1267
1268 SMC37c669_write_config(
1269 SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
1270 base_addr.as_uchar
1271 );
1272 ret_val = TRUE;
1273 break;
1274 }
1275 case SERIAL_1:
1276 {
1277 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1278 SMC37c669_SERIAL_IRQ_REGISTER irq;
1279
1280
1281
1282 irq.as_uchar =
1283 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1284
1285 irq.by_field.uart2_irq =
1286 SMC37c669_RAW_DEVICE_IRQ(
1287 SMC37c669_xlate_irq( local_config[ func ].irq )
1288 );
1289
1290 SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1291
1292
1293
1294 base_addr.as_uchar = 0;
1295 base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
1296
1297 SMC37c669_write_config(
1298 SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
1299 base_addr.as_uchar
1300 );
1301 ret_val = TRUE;
1302 break;
1303 }
1304 case PARALLEL_0:
1305 {
1306 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
1307 SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1308 SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1309
1310
1311
1312 drq.as_uchar =
1313 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1314
1315 drq.by_field.ppt_drq =
1316 SMC37c669_RAW_DEVICE_DRQ(
1317 SMC37c669_xlate_drq( local_config[ func ].drq )
1318 );
1319
1320 SMC37c669_write_config(
1321 SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1322 drq.as_uchar
1323 );
1324
1325
1326
1327 irq.as_uchar =
1328 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1329
1330 irq.by_field.ppt_irq =
1331 SMC37c669_RAW_DEVICE_IRQ(
1332 SMC37c669_xlate_irq( local_config[ func ].irq )
1333 );
1334
1335 SMC37c669_write_config(
1336 SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1337 irq.as_uchar
1338 );
1339
1340
1341
1342 base_addr.as_uchar = 0;
1343 base_addr.by_field.addr9_2 = local_config[ func ].port1 >> 2;
1344
1345 SMC37c669_write_config(
1346 SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
1347 base_addr.as_uchar
1348 );
1349 ret_val = TRUE;
1350 break;
1351 }
1352 case FLOPPY_0:
1353 {
1354 SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
1355 SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1356 SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1357
1358
1359
1360 drq.as_uchar =
1361 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1362
1363 drq.by_field.fdc_drq =
1364 SMC37c669_RAW_DEVICE_DRQ(
1365 SMC37c669_xlate_drq( local_config[ func ].drq )
1366 );
1367
1368 SMC37c669_write_config(
1369 SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1370 drq.as_uchar
1371 );
1372
1373
1374
1375 irq.as_uchar =
1376 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1377
1378 irq.by_field.fdc_irq =
1379 SMC37c669_RAW_DEVICE_IRQ(
1380 SMC37c669_xlate_irq( local_config[ func ].irq )
1381 );
1382
1383 SMC37c669_write_config(
1384 SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1385 irq.as_uchar
1386 );
1387
1388
1389
1390 base_addr.as_uchar = 0;
1391 base_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
1392
1393 SMC37c669_write_config(
1394 SMC37c669_FDC_BASE_ADDRESS_INDEX,
1395 base_addr.as_uchar
1396 );
1397 ret_val = TRUE;
1398 break;
1399 }
1400 case IDE_0:
1401 {
1402 SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
1403
1404
1405
1406 ide_addr.as_uchar = 0;
1407 ide_addr.by_field.addr9_4 = local_config[ func ].port2 >> 4;
1408
1409 SMC37c669_write_config(
1410 SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
1411 ide_addr.as_uchar
1412 );
1413
1414
1415
1416 ide_addr.as_uchar = 0;
1417 ide_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
1418
1419 SMC37c669_write_config(
1420 SMC37c669_IDE_BASE_ADDRESS_INDEX,
1421 ide_addr.as_uchar
1422 );
1423 ret_val = TRUE;
1424 break;
1425 }
1426 }
1427
1428
1429
1430 SMC37c669_config_mode( FALSE );
1431
1432 return ret_val;
1433}
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
1466unsigned int __init SMC37c669_disable_device ( unsigned int func )
1467{
1468 unsigned int ret_val = FALSE;
1469
1470
1471
1472
1473 SMC37c669_config_mode( TRUE );
1474 switch ( func ) {
1475 case SERIAL_0:
1476 {
1477 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1478 SMC37c669_SERIAL_IRQ_REGISTER irq;
1479
1480
1481
1482 irq.as_uchar =
1483 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1484
1485 irq.by_field.uart1_irq = 0;
1486
1487 SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1488
1489
1490
1491 base_addr.as_uchar = 0;
1492 SMC37c669_write_config(
1493 SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
1494 base_addr.as_uchar
1495 );
1496 ret_val = TRUE;
1497 break;
1498 }
1499 case SERIAL_1:
1500 {
1501 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1502 SMC37c669_SERIAL_IRQ_REGISTER irq;
1503
1504
1505
1506 irq.as_uchar =
1507 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1508
1509 irq.by_field.uart2_irq = 0;
1510
1511 SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1512
1513
1514
1515 base_addr.as_uchar = 0;
1516
1517 SMC37c669_write_config(
1518 SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
1519 base_addr.as_uchar
1520 );
1521 ret_val = TRUE;
1522 break;
1523 }
1524 case PARALLEL_0:
1525 {
1526 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
1527 SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1528 SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1529
1530
1531
1532 drq.as_uchar =
1533 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1534
1535 drq.by_field.ppt_drq = 0;
1536
1537 SMC37c669_write_config(
1538 SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1539 drq.as_uchar
1540 );
1541
1542
1543
1544 irq.as_uchar =
1545 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1546
1547 irq.by_field.ppt_irq = 0;
1548
1549 SMC37c669_write_config(
1550 SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1551 irq.as_uchar
1552 );
1553
1554
1555
1556 base_addr.as_uchar = 0;
1557
1558 SMC37c669_write_config(
1559 SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
1560 base_addr.as_uchar
1561 );
1562 ret_val = TRUE;
1563 break;
1564 }
1565 case FLOPPY_0:
1566 {
1567 SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
1568 SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1569 SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1570
1571
1572
1573 drq.as_uchar =
1574 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1575
1576 drq.by_field.fdc_drq = 0;
1577
1578 SMC37c669_write_config(
1579 SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1580 drq.as_uchar
1581 );
1582
1583
1584
1585 irq.as_uchar =
1586 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1587
1588 irq.by_field.fdc_irq = 0;
1589
1590 SMC37c669_write_config(
1591 SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1592 irq.as_uchar
1593 );
1594
1595
1596
1597 base_addr.as_uchar = 0;
1598
1599 SMC37c669_write_config(
1600 SMC37c669_FDC_BASE_ADDRESS_INDEX,
1601 base_addr.as_uchar
1602 );
1603 ret_val = TRUE;
1604 break;
1605 }
1606 case IDE_0:
1607 {
1608 SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
1609
1610
1611
1612 ide_addr.as_uchar = 0;
1613
1614 SMC37c669_write_config(
1615 SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
1616 ide_addr.as_uchar
1617 );
1618
1619
1620
1621 ide_addr.as_uchar = 0;
1622
1623 SMC37c669_write_config(
1624 SMC37c669_IDE_BASE_ADDRESS_INDEX,
1625 ide_addr.as_uchar
1626 );
1627 ret_val = TRUE;
1628 break;
1629 }
1630 }
1631
1632
1633
1634 SMC37c669_config_mode( FALSE );
1635
1636 return ret_val;
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
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680unsigned int __init SMC37c669_configure_device (
1681 unsigned int func,
1682 int port,
1683 int irq,
1684 int drq )
1685{
1686 struct DEVICE_CONFIG *cp;
1687
1688
1689
1690
1691 if ( ( cp = SMC37c669_get_config ( func ) ) != NULL ) {
1692
1693
1694
1695 if ( ( drq & ~0xFF ) == 0 ) {
1696 cp->drq = drq;
1697 }
1698 if ( ( irq & ~0xFF ) == 0 ) {
1699 cp->irq = irq;
1700 }
1701 if ( ( port & ~0xFFFF ) == 0 ) {
1702 cp->port1 = port;
1703 }
1704
1705
1706
1707
1708 if ( SMC37c669_is_device_enabled( func ) ) {
1709 SMC37c669_enable_device( func );
1710 }
1711 return TRUE;
1712 }
1713 return FALSE;
1714}
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
1747static unsigned int __init SMC37c669_is_device_enabled ( unsigned int func )
1748{
1749 unsigned char base_addr = 0;
1750 unsigned int dev_ok = FALSE;
1751 unsigned int ret_val = FALSE;
1752
1753
1754
1755 SMC37c669_config_mode( TRUE );
1756
1757 switch ( func ) {
1758 case SERIAL_0:
1759 base_addr =
1760 SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
1761 dev_ok = TRUE;
1762 break;
1763 case SERIAL_1:
1764 base_addr =
1765 SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
1766 dev_ok = TRUE;
1767 break;
1768 case PARALLEL_0:
1769 base_addr =
1770 SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
1771 dev_ok = TRUE;
1772 break;
1773 case FLOPPY_0:
1774 base_addr =
1775 SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
1776 dev_ok = TRUE;
1777 break;
1778 case IDE_0:
1779 base_addr =
1780 SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
1781 dev_ok = TRUE;
1782 break;
1783 }
1784
1785
1786
1787
1788 if ( ( dev_ok ) && ( ( base_addr & 0xC0 ) != 0 ) ) {
1789
1790
1791
1792
1793 ret_val = TRUE;
1794 }
1795
1796
1797
1798 SMC37c669_config_mode( FALSE );
1799
1800 return ret_val;
1801}
1802
1803
1804#if 0
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
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846static unsigned int __init SMC37c669_get_device_config (
1847 unsigned int func,
1848 int *port,
1849 int *irq,
1850 int *drq )
1851{
1852 struct DEVICE_CONFIG *cp;
1853 unsigned int ret_val = FALSE;
1854
1855
1856
1857 if ( ( cp = SMC37c669_get_config( func ) ) != NULL ) {
1858 if ( drq != NULL ) {
1859 *drq = cp->drq;
1860 ret_val = TRUE;
1861 }
1862 if ( irq != NULL ) {
1863 *irq = cp->irq;
1864 ret_val = TRUE;
1865 }
1866 if ( port != NULL ) {
1867 *port = cp->port1;
1868 ret_val = TRUE;
1869 }
1870 }
1871 return ret_val;
1872}
1873#endif
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897void __init SMC37c669_display_device_info ( void )
1898{
1899 if ( SMC37c669_is_device_enabled( SERIAL_0 ) ) {
1900 printk( " Serial 0: Enabled [ Port 0x%x, IRQ %d ]\n",
1901 local_config[ SERIAL_0 ].port1,
1902 local_config[ SERIAL_0 ].irq
1903 );
1904 }
1905 else {
1906 printk( " Serial 0: Disabled\n" );
1907 }
1908
1909 if ( SMC37c669_is_device_enabled( SERIAL_1 ) ) {
1910 printk( " Serial 1: Enabled [ Port 0x%x, IRQ %d ]\n",
1911 local_config[ SERIAL_1 ].port1,
1912 local_config[ SERIAL_1 ].irq
1913 );
1914 }
1915 else {
1916 printk( " Serial 1: Disabled\n" );
1917 }
1918
1919 if ( SMC37c669_is_device_enabled( PARALLEL_0 ) ) {
1920 printk( " Parallel: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
1921 local_config[ PARALLEL_0 ].port1,
1922 local_config[ PARALLEL_0 ].irq,
1923 local_config[ PARALLEL_0 ].drq
1924 );
1925 }
1926 else {
1927 printk( " Parallel: Disabled\n" );
1928 }
1929
1930 if ( SMC37c669_is_device_enabled( FLOPPY_0 ) ) {
1931 printk( " Floppy Ctrl: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
1932 local_config[ FLOPPY_0 ].port1,
1933 local_config[ FLOPPY_0 ].irq,
1934 local_config[ FLOPPY_0 ].drq
1935 );
1936 }
1937 else {
1938 printk( " Floppy Ctrl: Disabled\n" );
1939 }
1940
1941 if ( SMC37c669_is_device_enabled( IDE_0 ) ) {
1942 printk( " IDE 0: Enabled [ Port 0x%x, IRQ %d ]\n",
1943 local_config[ IDE_0 ].port1,
1944 local_config[ IDE_0 ].irq
1945 );
1946 }
1947 else {
1948 printk( " IDE 0: Disabled\n" );
1949 }
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
1975static void __init SMC37c669_config_mode(
1976 unsigned int enable )
1977{
1978 if ( enable ) {
1979
1980
1981
1982
1983
1984
1985
1986 spin_lock(&smc_lock);
1987 wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
1988 wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
1989 spin_unlock(&smc_lock);
1990 }
1991 else {
1992 wb( &SMC37c669->index_port, SMC37c669_CONFIG_OFF_KEY );
1993 }
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
2019static unsigned char __init SMC37c669_read_config(
2020 unsigned char index )
2021{
2022 unsigned char data;
2023
2024 wb( &SMC37c669->index_port, index );
2025 data = rb( &SMC37c669->data_port );
2026 return data;
2027}
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
2055static void __init SMC37c669_write_config(
2056 unsigned char index,
2057 unsigned char data )
2058{
2059 wb( &SMC37c669->index_port, index );
2060 wb( &SMC37c669->data_port, data );
2061}
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
2088static void __init SMC37c669_init_local_config ( void )
2089{
2090 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER uart_base;
2091 SMC37c669_SERIAL_IRQ_REGISTER uart_irqs;
2092 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER ppt_base;
2093 SMC37c669_PARALLEL_FDC_IRQ_REGISTER ppt_fdc_irqs;
2094 SMC37c669_PARALLEL_FDC_DRQ_REGISTER ppt_fdc_drqs;
2095 SMC37c669_FDC_BASE_ADDRESS_REGISTER fdc_base;
2096 SMC37c669_IDE_ADDRESS_REGISTER ide_base;
2097 SMC37c669_IDE_ADDRESS_REGISTER ide_alt;
2098
2099
2100
2101
2102 uart_base.as_uchar =
2103 SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
2104
2105
2106
2107 uart_irqs.as_uchar =
2108 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
2109
2110
2111
2112 local_config[SERIAL_0].port1 = uart_base.by_field.addr9_3 << 3;
2113 local_config[SERIAL_0].irq =
2114 SMC37c669_xlate_irq(
2115 SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart1_irq )
2116 );
2117
2118
2119
2120 uart_base.as_uchar =
2121 SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
2122
2123
2124
2125 local_config[SERIAL_1].port1 = uart_base.by_field.addr9_3 << 3;
2126 local_config[SERIAL_1].irq =
2127 SMC37c669_xlate_irq(
2128 SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart2_irq )
2129 );
2130
2131
2132
2133 ppt_base.as_uchar =
2134 SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
2135
2136
2137
2138 ppt_fdc_irqs.as_uchar =
2139 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
2140
2141
2142
2143 ppt_fdc_drqs.as_uchar =
2144 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
2145
2146
2147
2148 local_config[PARALLEL_0].port1 = ppt_base.by_field.addr9_2 << 2;
2149 local_config[PARALLEL_0].irq =
2150 SMC37c669_xlate_irq(
2151 SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.ppt_irq )
2152 );
2153 local_config[PARALLEL_0].drq =
2154 SMC37c669_xlate_drq(
2155 SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.ppt_drq )
2156 );
2157
2158
2159
2160 fdc_base.as_uchar =
2161 SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
2162
2163
2164
2165 local_config[FLOPPY_0].port1 = fdc_base.by_field.addr9_4 << 4;
2166 local_config[FLOPPY_0].irq =
2167 SMC37c669_xlate_irq(
2168 SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.fdc_irq )
2169 );
2170 local_config[FLOPPY_0].drq =
2171 SMC37c669_xlate_drq(
2172 SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.fdc_drq )
2173 );
2174
2175
2176
2177 ide_base.as_uchar =
2178 SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
2179
2180
2181
2182 ide_alt.as_uchar =
2183 SMC37c669_read_config( SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX );
2184
2185
2186
2187 local_config[IDE_0].port1 = ide_base.by_field.addr9_4 << 4;
2188 local_config[IDE_0].port2 = ide_alt.by_field.addr9_4 << 4;
2189 local_config[IDE_0].irq = 14;
2190}
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
2216static struct DEVICE_CONFIG * __init SMC37c669_get_config( unsigned int func )
2217{
2218 struct DEVICE_CONFIG *cp = NULL;
2219
2220 switch ( func ) {
2221 case SERIAL_0:
2222 cp = &local_config[ SERIAL_0 ];
2223 break;
2224 case SERIAL_1:
2225 cp = &local_config[ SERIAL_1 ];
2226 break;
2227 case PARALLEL_0:
2228 cp = &local_config[ PARALLEL_0 ];
2229 break;
2230 case FLOPPY_0:
2231 cp = &local_config[ FLOPPY_0 ];
2232 break;
2233 case IDE_0:
2234 cp = &local_config[ IDE_0 ];
2235 break;
2236 }
2237 return cp;
2238}
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262static int __init SMC37c669_xlate_irq ( int irq )
2263{
2264 int i, translated_irq = -1;
2265
2266 if ( SMC37c669_IS_DEVICE_IRQ( irq ) ) {
2267
2268
2269
2270 for ( i = 0; ( SMC37c669_irq_table[i].device_irq != -1 ) || ( SMC37c669_irq_table[i].isa_irq != -1 ); i++ ) {
2271 if ( irq == SMC37c669_irq_table[i].device_irq ) {
2272 translated_irq = SMC37c669_irq_table[i].isa_irq;
2273 break;
2274 }
2275 }
2276 }
2277 else {
2278
2279
2280
2281 for ( i = 0; ( SMC37c669_irq_table[i].isa_irq != -1 ) || ( SMC37c669_irq_table[i].device_irq != -1 ); i++ ) {
2282 if ( irq == SMC37c669_irq_table[i].isa_irq ) {
2283 translated_irq = SMC37c669_irq_table[i].device_irq;
2284 break;
2285 }
2286 }
2287 }
2288 return translated_irq;
2289}
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314static int __init SMC37c669_xlate_drq ( int drq )
2315{
2316 int i, translated_drq = -1;
2317
2318 if ( SMC37c669_IS_DEVICE_DRQ( drq ) ) {
2319
2320
2321
2322 for ( i = 0; ( SMC37c669_drq_table[i].device_drq != -1 ) || ( SMC37c669_drq_table[i].isa_drq != -1 ); i++ ) {
2323 if ( drq == SMC37c669_drq_table[i].device_drq ) {
2324 translated_drq = SMC37c669_drq_table[i].isa_drq;
2325 break;
2326 }
2327 }
2328 }
2329 else {
2330
2331
2332
2333 for ( i = 0; ( SMC37c669_drq_table[i].isa_drq != -1 ) || ( SMC37c669_drq_table[i].device_drq != -1 ); i++ ) {
2334 if ( drq == SMC37c669_drq_table[i].isa_drq ) {
2335 translated_drq = SMC37c669_drq_table[i].device_drq;
2336 break;
2337 }
2338 }
2339 }
2340 return translated_drq;
2341}
2342
2343#if 0
2344int __init smcc669_init ( void )
2345{
2346 struct INODE *ip;
2347
2348 allocinode( smc_ddb.name, 1, &ip );
2349 ip->dva = &smc_ddb;
2350 ip->attr = ATTR$M_WRITE | ATTR$M_READ;
2351 ip->len[0] = 0x30;
2352 ip->misc = 0;
2353 INODE_UNLOCK( ip );
2354
2355 return msg_success;
2356}
2357
2358int __init smcc669_open( struct FILE *fp, char *info, char *next, char *mode )
2359{
2360 struct INODE *ip;
2361
2362
2363
2364
2365 ip = fp->ip;
2366 INODE_LOCK( ip );
2367 if ( fp->mode & ATTR$M_WRITE ) {
2368 if ( ip->misc ) {
2369 INODE_UNLOCK( ip );
2370 return msg_failure;
2371 }
2372 ip->misc++;
2373 }
2374
2375
2376
2377 *fp->offset = xtoi( info );
2378 INODE_UNLOCK( ip );
2379
2380 return msg_success;
2381}
2382
2383int __init smcc669_close( struct FILE *fp )
2384{
2385 struct INODE *ip;
2386
2387 ip = fp->ip;
2388 if ( fp->mode & ATTR$M_WRITE ) {
2389 INODE_LOCK( ip );
2390 ip->misc--;
2391 INODE_UNLOCK( ip );
2392 }
2393 return msg_success;
2394}
2395
2396int __init smcc669_read( struct FILE *fp, int size, int number, unsigned char *buf )
2397{
2398 int i;
2399 int length;
2400 int nbytes;
2401 struct INODE *ip;
2402
2403
2404
2405
2406 ip = fp->ip;
2407 length = size * number;
2408 nbytes = 0;
2409
2410 SMC37c669_config_mode( TRUE );
2411 for ( i = 0; i < length; i++ ) {
2412 if ( !inrange( *fp->offset, 0, ip->len[0] ) )
2413 break;
2414 *buf++ = SMC37c669_read_config( *fp->offset );
2415 *fp->offset += 1;
2416 nbytes++;
2417 }
2418 SMC37c669_config_mode( FALSE );
2419 return nbytes;
2420}
2421
2422int __init smcc669_write( struct FILE *fp, int size, int number, unsigned char *buf )
2423{
2424 int i;
2425 int length;
2426 int nbytes;
2427 struct INODE *ip;
2428
2429
2430
2431 ip = fp->ip;
2432 length = size * number;
2433 nbytes = 0;
2434
2435 SMC37c669_config_mode( TRUE );
2436 for ( i = 0; i < length; i++ ) {
2437 if ( !inrange( *fp->offset, 0, ip->len[0] ) )
2438 break;
2439 SMC37c669_write_config( *fp->offset, *buf );
2440 *fp->offset += 1;
2441 buf++;
2442 nbytes++;
2443 }
2444 SMC37c669_config_mode( FALSE );
2445 return nbytes;
2446}
2447#endif
2448
2449void __init
2450SMC37c669_dump_registers(void)
2451{
2452 int i;
2453 for (i = 0; i <= 0x29; i++)
2454 printk("-- CR%02x : %02x\n", i, SMC37c669_read_config(i));
2455}
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
2483void __init SMC669_Init ( int index )
2484{
2485 SMC37c669_CONFIG_REGS *SMC_base;
2486 unsigned long flags;
2487
2488 local_irq_save(flags);
2489 if ( ( SMC_base = SMC37c669_detect( index ) ) != NULL ) {
2490#if SMC_DEBUG
2491 SMC37c669_config_mode( TRUE );
2492 SMC37c669_dump_registers( );
2493 SMC37c669_config_mode( FALSE );
2494 SMC37c669_display_device_info( );
2495#endif
2496 SMC37c669_disable_device( SERIAL_0 );
2497 SMC37c669_configure_device(
2498 SERIAL_0,
2499 COM1_BASE,
2500 COM1_IRQ,
2501 -1
2502 );
2503 SMC37c669_enable_device( SERIAL_0 );
2504
2505 SMC37c669_disable_device( SERIAL_1 );
2506 SMC37c669_configure_device(
2507 SERIAL_1,
2508 COM2_BASE,
2509 COM2_IRQ,
2510 -1
2511 );
2512 SMC37c669_enable_device( SERIAL_1 );
2513
2514 SMC37c669_disable_device( PARALLEL_0 );
2515 SMC37c669_configure_device(
2516 PARALLEL_0,
2517 PARP_BASE,
2518 PARP_IRQ,
2519 PARP_DRQ
2520 );
2521 SMC37c669_enable_device( PARALLEL_0 );
2522
2523 SMC37c669_disable_device( FLOPPY_0 );
2524 SMC37c669_configure_device(
2525 FLOPPY_0,
2526 FDC_BASE,
2527 FDC_IRQ,
2528 FDC_DRQ
2529 );
2530 SMC37c669_enable_device( FLOPPY_0 );
2531
2532
2533 outb(0xc, 0x3f2);
2534
2535 SMC37c669_disable_device( IDE_0 );
2536
2537#if SMC_DEBUG
2538 SMC37c669_config_mode( TRUE );
2539 SMC37c669_dump_registers( );
2540 SMC37c669_config_mode( FALSE );
2541 SMC37c669_display_device_info( );
2542#endif
2543 local_irq_restore(flags);
2544 printk( "SMC37c669 Super I/O Controller found @ 0x%p\n",
2545 SMC_base );
2546 }
2547 else {
2548 local_irq_restore(flags);
2549#if SMC_DEBUG
2550 printk( "No SMC37c669 Super I/O Controller found\n" );
2551#endif
2552 }
2553}
2554