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