OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [alpha/] [kernel/] [smc.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1622 jcastillo
/*
2
 * SMC 37C93X and 37C669 initialization code
3
 */
4
#include <linux/config.h>
5
#include <linux/kernel.h>
6
 
7
#if 0
8
# define DBG_DEVS(args)         printk args
9
#else
10
# define DBG_DEVS(args)
11
#endif
12
 
13
#include <linux/bios32.h>
14
#include <linux/pci.h>
15
#include <linux/malloc.h>
16
#include <linux/mm.h>
17
 
18
#include <asm/hwrpb.h>
19
#include <asm/io.h>
20
#include <asm/segment.h>
21
 
22
#define KB              1024
23
#define MB              (1024*KB)
24
#define GB              (1024*MB)
25
 
26
#if defined(CONFIG_ALPHA_PC164) || defined(CONFIG_ALPHA_LX164)
27
 
28
/* device "activate" register contents */
29
#define DEVICE_ON               1
30
#define DEVICE_OFF              0
31
 
32
/* configuration on/off keys */
33
#define CONFIG_ON_KEY           0x55
34
#define CONFIG_OFF_KEY          0xaa
35
 
36
/* configuration space device definitions */
37
#define FDC                     0
38
#define IDE1                    1
39
#define IDE2                    2
40
#define PARP                    3
41
#define SER1                    4
42
#define SER2                    5
43
#define RTCL                    6
44
#define KYBD                    7
45
#define AUXIO                   8
46
 
47
/* Chip register offsets from base */
48
#define CONFIG_CONTROL          0x02
49
#define INDEX_ADDRESS           0x03
50
#define LOGICAL_DEVICE_NUMBER   0x07
51
#define DEVICE_ID               0x20
52
#define DEVICE_REV              0x21
53
#define POWER_CONTROL           0x22
54
#define POWER_MGMT              0x23
55
#define OSC                     0x24
56
 
57
#define ACTIVATE                0x30
58
#define ADDR_HI                 0x60
59
#define ADDR_LO                 0x61
60
#define INTERRUPT_SEL           0x70
61
#define INTERRUPT_SEL_2         0x72 /* KYBD/MOUS only */
62
#define DMA_CHANNEL_SEL         0x74 /* FDC/PARP only */
63
 
64
#define FDD_MODE_REGISTER       0x90
65
#define FDD_OPTION_REGISTER     0x91
66
 
67
/* values that we read back that are expected ... */
68
#define VALID_DEVICE_ID         2
69
 
70
/* default device addresses */
71
#define KYBD_INTERRUPT          1
72
#define MOUS_INTERRUPT          12
73
#define COM2_BASE               0x2f8
74
#define COM2_INTERRUPT          3
75
#define COM1_BASE               0x3f8
76
#define COM1_INTERRUPT          4
77
#define PARP_BASE               0x3bc
78
#define PARP_INTERRUPT          7
79
 
80
#define SMC_DEBUG 0
81
 
82
unsigned long SMCConfigState( unsigned long baseAddr )
83
{
84
    unsigned char devId;
85
    unsigned char devRev;
86
 
87
    unsigned long configPort;
88
    unsigned long indexPort;
89
    unsigned long dataPort;
90
 
91
    configPort = indexPort = baseAddr;
92
    dataPort = ( unsigned long )( ( char * )configPort + 1 );
93
 
94
    outb(CONFIG_ON_KEY, configPort);
95
    outb(CONFIG_ON_KEY, configPort);
96
    outb(DEVICE_ID, indexPort);
97
    devId = inb(dataPort);
98
    if ( devId == VALID_DEVICE_ID ) {
99
        outb(DEVICE_REV, indexPort);
100
        devRev = inb(dataPort);
101
    }
102
    else {
103
        baseAddr = 0;
104
    }
105
    return( baseAddr );
106
}
107
 
108
void SMCRunState( unsigned long baseAddr )
109
{
110
    outb(CONFIG_OFF_KEY, baseAddr);
111
}
112
 
113
unsigned long SMCDetectUltraIO(void)
114
{
115
    unsigned long baseAddr;
116
 
117
    baseAddr = 0x3F0;
118
    if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x3F0 ) {
119
        return( baseAddr );
120
    }
121
    baseAddr = 0x370;
122
    if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x370 ) {
123
        return( baseAddr );
124
    }
125
    return( ( unsigned long )0 );
126
}
127
 
128
void SMCEnableDevice( unsigned long baseAddr,
129
                      unsigned long device,
130
                      unsigned long portaddr,
131
                      unsigned long interrupt)
132
{
133
    unsigned long indexPort;
134
    unsigned long dataPort;
135
 
136
    indexPort = baseAddr;
137
    dataPort = ( unsigned long )( ( char * )baseAddr + 1 );
138
 
139
    outb(LOGICAL_DEVICE_NUMBER, indexPort);
140
    outb(device, dataPort);
141
 
142
    outb(ADDR_LO, indexPort);
143
    outb(( portaddr & 0xFF ), dataPort);
144
 
145
    outb(ADDR_HI, indexPort);
146
    outb(( ( portaddr >> 8 ) & 0xFF ), dataPort);
147
 
148
    outb(INTERRUPT_SEL, indexPort);
149
    outb(interrupt, dataPort);
150
 
151
    outb(ACTIVATE, indexPort);
152
    outb(DEVICE_ON, dataPort);
153
}
154
 
155
void SMCEnableKYBD( unsigned long baseAddr )
156
{
157
    unsigned long indexPort;
158
    unsigned long dataPort;
159
 
160
    indexPort = baseAddr;
161
    dataPort = ( unsigned long )( ( char * )baseAddr + 1 );
162
 
163
    outb(LOGICAL_DEVICE_NUMBER, indexPort);
164
    outb(KYBD, dataPort);
165
 
166
    outb(INTERRUPT_SEL, indexPort); /* Primary interrupt select */
167
    outb(KYBD_INTERRUPT, dataPort);
168
 
169
    outb(INTERRUPT_SEL_2, indexPort);/* Secondary interrupt select */
170
    outb(MOUS_INTERRUPT, dataPort);
171
 
172
    outb(ACTIVATE, indexPort);
173
    outb(DEVICE_ON, dataPort);
174
}
175
 
176
void SMCEnableFDC( unsigned long baseAddr )
177
{
178
    unsigned long indexPort;
179
    unsigned long dataPort;
180
 
181
    unsigned char oldValue;
182
 
183
    indexPort = baseAddr;
184
    dataPort = ( unsigned long )( ( char * )baseAddr + 1 );
185
 
186
    outb(LOGICAL_DEVICE_NUMBER, indexPort);
187
    outb(FDC, dataPort);
188
 
189
    outb(FDD_MODE_REGISTER, indexPort);
190
    oldValue = inb(dataPort);
191
 
192
    oldValue |= 0x0E;                   /* Enable burst mode */
193
    outb(oldValue, dataPort);
194
 
195
    outb(INTERRUPT_SEL, indexPort); /* Primary interrupt select */
196
    outb(0x06, dataPort );
197
 
198
    outb(DMA_CHANNEL_SEL, indexPort);  /* DMA channel select */
199
    outb(0x02, dataPort);
200
 
201
    outb(ACTIVATE, indexPort);
202
    outb(DEVICE_ON, dataPort);
203
}
204
 
205
#if SMC_DEBUG
206
void SMCReportDeviceStatus( unsigned long baseAddr )
207
{
208
    unsigned long indexPort;
209
    unsigned long dataPort;
210
    unsigned char currentControl;
211
 
212
    indexPort = baseAddr;
213
    dataPort = ( unsigned long )( ( char * )baseAddr + 1 );
214
 
215
    outb(POWER_CONTROL, indexPort);
216
    currentControl = inb(dataPort);
217
 
218
    if ( currentControl & ( 1 << FDC ) )
219
        printk( "\t+FDC Enabled\n" );
220
    else
221
        printk( "\t-FDC Disabled\n" );
222
 
223
    if ( currentControl & ( 1 << IDE1 ) )
224
        printk( "\t+IDE1 Enabled\n" );
225
    else
226
        printk( "\t-IDE1 Disabled\n" );
227
 
228
    if ( currentControl & ( 1 << IDE2 ) )
229
        printk( "\t+IDE2 Enabled\n" );
230
    else
231
        printk( "\t-IDE2 Disabled\n" );
232
 
233
    if ( currentControl & ( 1 << PARP ) )
234
        printk( "\t+PARP Enabled\n" );
235
    else
236
        printk( "\t-PARP Disabled\n" );
237
 
238
    if ( currentControl & ( 1 << SER1 ) )
239
        printk( "\t+SER1 Enabled\n" );
240
    else
241
        printk( "\t-SER1 Disabled\n" );
242
 
243
    if ( currentControl & ( 1 << SER2 ) )
244
        printk( "\t+SER2 Enabled\n" );
245
    else
246
        printk( "\t-SER2 Disabled\n" );
247
 
248
    printk( "\n" );
249
}
250
#endif
251
 
252
void SMC93X_Init(void)
253
{
254
    unsigned long SMCUltraBase;
255
 
256
    if ( ( SMCUltraBase = SMCDetectUltraIO( ) ) != ( unsigned long )0 ) {
257
        printk( "SMC FDC37C93X Ultra I/O Controller found @ 0x%lx\n",
258
                SMCUltraBase );
259
#if SMC_DEBUG
260
        SMCReportDeviceStatus( SMCUltraBase );
261
#endif
262
        SMCEnableDevice( SMCUltraBase, SER1, COM1_BASE, COM1_INTERRUPT );
263
        SMCEnableDevice( SMCUltraBase, SER2, COM2_BASE, COM2_INTERRUPT );
264
        SMCEnableDevice( SMCUltraBase, PARP, PARP_BASE, PARP_INTERRUPT );
265
        /* IDE on the SMC is not enabled; CMD646 (PCI) on MB */
266
        SMCEnableKYBD( SMCUltraBase );
267
        SMCEnableFDC( SMCUltraBase );
268
#if SMC_DEBUG
269
        SMCReportDeviceStatus( SMCUltraBase );
270
#endif
271
        SMCRunState( SMCUltraBase );
272
    }
273
    else {
274
#if SMC_DEBUG
275
        printk( "No SMC FDC37C93X Ultra I/O Controller found\n" );
276
#endif
277
    }
278
}
279
 
280
#endif /* PC164 || LX164 */
281
 
282
/* we include MIATA because the GL has the SMC669 on board */
283
#if defined(CONFIG_ALPHA_SX164) || defined(CONFIG_ALPHA_MIATA)
284
 
285
#define SMC_DEBUG   0
286
 
287
/* File:        smcc669_def.h
288
 *
289
 * Copyright (C) 1997 by
290
 * Digital Equipment Corporation, Maynard, Massachusetts.
291
 * All rights reserved.
292
 *
293
 * This software is furnished under a license and may be used and copied
294
 * only  in  accordance  of  the  terms  of  such  license  and with the
295
 * inclusion of the above copyright notice. This software or  any  other
296
 * copies thereof may not be provided or otherwise made available to any
297
 * other person.  No title to and  ownership of the  software is  hereby
298
 * transferred.
299
 *
300
 * The information in this software is  subject to change without notice
301
 * and  should  not  be  construed  as a commitment by Digital Equipment
302
 * Corporation.
303
 *
304
 * Digital assumes no responsibility for the use  or  reliability of its
305
 * software on equipment which is not supplied by Digital.
306
 *
307
 *
308
 * Abstract:
309
 *
310
 *      This file contains header definitions for the SMC37c669
311
 *      Super I/O controller.
312
 *
313
 * Author:
314
 *
315
 *      Eric Rasmussen
316
 *
317
 * Modification History:
318
 *
319
 *      er      28-Jan-1997     Initial Entry
320
 */
321
 
322
#ifndef __SMC37c669_H
323
#define __SMC37c669_H
324
 
325
/*
326
** Macros for handling device IRQs
327
**
328
** The mask acts as a flag used in mapping actual ISA IRQs (0 - 15)
329
** to device IRQs (A - H).
330
*/
331
#define SMC37c669_DEVICE_IRQ_MASK       0x80000000
332
#define SMC37c669_DEVICE_IRQ( __i )     \
333
        ((SMC37c669_DEVICE_IRQ_MASK) | (__i))
334
#define SMC37c669_IS_DEVICE_IRQ(__i)    \
335
        (((__i) & (SMC37c669_DEVICE_IRQ_MASK)) == (SMC37c669_DEVICE_IRQ_MASK))
336
#define SMC37c669_RAW_DEVICE_IRQ(__i)   \
337
        ((__i) & ~(SMC37c669_DEVICE_IRQ_MASK))
338
 
339
/*
340
** Macros for handling device DRQs
341
**
342
** The mask acts as a flag used in mapping actual ISA DMA
343
** channels to device DMA channels (A - C).
344
*/
345
#define SMC37c669_DEVICE_DRQ_MASK       0x80000000
346
#define SMC37c669_DEVICE_DRQ(__d)       \
347
        ((SMC37c669_DEVICE_DRQ_MASK) | (__d))
348
#define SMC37c669_IS_DEVICE_DRQ(__d)    \
349
        (((__d) & (SMC37c669_DEVICE_DRQ_MASK)) == (SMC37c669_DEVICE_DRQ_MASK))
350
#define SMC37c669_RAW_DEVICE_DRQ(__d)   \
351
        ((__d) & ~(SMC37c669_DEVICE_DRQ_MASK))
352
 
353
#define SMC37c669_DEVICE_ID     0x3
354
 
355
/*
356
** SMC37c669 Device Function Definitions
357
*/
358
#define SERIAL_0        0
359
#define SERIAL_1        1
360
#define PARALLEL_0      2
361
#define FLOPPY_0        3
362
#define IDE_0           4
363
#define NUM_FUNCS       5
364
 
365
/*
366
** Default Device Function Mappings
367
*/
368
#define COM1_BASE       0x3F8
369
#define COM1_IRQ        4
370
#define COM2_BASE       0x2F8
371
#define COM2_IRQ        3
372
#define PARP_BASE       0x3BC
373
#define PARP_IRQ        7
374
#define PARP_DRQ        3
375
#define FDC_BASE        0x3F0
376
#define FDC_IRQ         6
377
#define FDC_DRQ         2
378
 
379
/*
380
** Configuration On/Off Key Definitions
381
*/
382
#define SMC37c669_CONFIG_ON_KEY         0x55
383
#define SMC37c669_CONFIG_OFF_KEY        0xAA
384
 
385
/*
386
** SMC 37c669 Device IRQs
387
*/
388
#define SMC37c669_DEVICE_IRQ_A      ( SMC37c669_DEVICE_IRQ( 0x01 ) )
389
#define SMC37c669_DEVICE_IRQ_B      ( SMC37c669_DEVICE_IRQ( 0x02 ) )
390
#define SMC37c669_DEVICE_IRQ_C      ( SMC37c669_DEVICE_IRQ( 0x03 ) )
391
#define SMC37c669_DEVICE_IRQ_D      ( SMC37c669_DEVICE_IRQ( 0x04 ) )
392
#define SMC37c669_DEVICE_IRQ_E      ( SMC37c669_DEVICE_IRQ( 0x05 ) )
393
#define SMC37c669_DEVICE_IRQ_F      ( SMC37c669_DEVICE_IRQ( 0x06 ) )
394
/*      SMC37c669_DEVICE_IRQ_G      *** RESERVED ***/
395
#define SMC37c669_DEVICE_IRQ_H      ( SMC37c669_DEVICE_IRQ( 0x08 ) )
396
 
397
/*
398
** SMC 37c669 Device DMA Channel Definitions
399
*/
400
#define SMC37c669_DEVICE_DRQ_A              ( SMC37c669_DEVICE_DRQ( 0x01 ) )
401
#define SMC37c669_DEVICE_DRQ_B              ( SMC37c669_DEVICE_DRQ( 0x02 ) )
402
#define SMC37c669_DEVICE_DRQ_C              ( SMC37c669_DEVICE_DRQ( 0x03 ) )
403
 
404
/*
405
** Configuration Register Index Definitions
406
*/
407
#define SMC37c669_CR00_INDEX        0x00
408
#define SMC37c669_CR01_INDEX        0x01
409
#define SMC37c669_CR02_INDEX        0x02
410
#define SMC37c669_CR03_INDEX        0x03
411
#define SMC37c669_CR04_INDEX        0x04
412
#define SMC37c669_CR05_INDEX        0x05
413
#define SMC37c669_CR06_INDEX        0x06
414
#define SMC37c669_CR07_INDEX        0x07
415
#define SMC37c669_CR08_INDEX        0x08
416
#define SMC37c669_CR09_INDEX        0x09
417
#define SMC37c669_CR0A_INDEX        0x0A
418
#define SMC37c669_CR0B_INDEX        0x0B
419
#define SMC37c669_CR0C_INDEX        0x0C
420
#define SMC37c669_CR0D_INDEX        0x0D
421
#define SMC37c669_CR0E_INDEX        0x0E
422
#define SMC37c669_CR0F_INDEX        0x0F
423
#define SMC37c669_CR10_INDEX        0x10
424
#define SMC37c669_CR11_INDEX        0x11
425
#define SMC37c669_CR12_INDEX        0x12
426
#define SMC37c669_CR13_INDEX        0x13
427
#define SMC37c669_CR14_INDEX        0x14
428
#define SMC37c669_CR15_INDEX        0x15
429
#define SMC37c669_CR16_INDEX        0x16
430
#define SMC37c669_CR17_INDEX        0x17
431
#define SMC37c669_CR18_INDEX        0x18
432
#define SMC37c669_CR19_INDEX        0x19
433
#define SMC37c669_CR1A_INDEX        0x1A
434
#define SMC37c669_CR1B_INDEX        0x1B
435
#define SMC37c669_CR1C_INDEX        0x1C
436
#define SMC37c669_CR1D_INDEX        0x1D
437
#define SMC37c669_CR1E_INDEX        0x1E
438
#define SMC37c669_CR1F_INDEX        0x1F
439
#define SMC37c669_CR20_INDEX        0x20
440
#define SMC37c669_CR21_INDEX        0x21
441
#define SMC37c669_CR22_INDEX        0x22
442
#define SMC37c669_CR23_INDEX        0x23
443
#define SMC37c669_CR24_INDEX        0x24
444
#define SMC37c669_CR25_INDEX        0x25
445
#define SMC37c669_CR26_INDEX        0x26
446
#define SMC37c669_CR27_INDEX        0x27
447
#define SMC37c669_CR28_INDEX        0x28
448
#define SMC37c669_CR29_INDEX        0x29
449
 
450
/*
451
** Configuration Register Alias Definitions
452
*/
453
#define SMC37c669_DEVICE_ID_INDEX                   SMC37c669_CR0D_INDEX
454
#define SMC37c669_DEVICE_REVISION_INDEX             SMC37c669_CR0E_INDEX
455
#define SMC37c669_FDC_BASE_ADDRESS_INDEX            SMC37c669_CR20_INDEX
456
#define SMC37c669_IDE_BASE_ADDRESS_INDEX            SMC37c669_CR21_INDEX
457
#define SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX       SMC37c669_CR22_INDEX
458
#define SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX      SMC37c669_CR23_INDEX
459
#define SMC37c669_SERIAL0_BASE_ADDRESS_INDEX        SMC37c669_CR24_INDEX
460
#define SMC37c669_SERIAL1_BASE_ADDRESS_INDEX        SMC37c669_CR25_INDEX
461
#define SMC37c669_PARALLEL_FDC_DRQ_INDEX            SMC37c669_CR26_INDEX
462
#define SMC37c669_PARALLEL_FDC_IRQ_INDEX            SMC37c669_CR27_INDEX
463
#define SMC37c669_SERIAL_IRQ_INDEX                  SMC37c669_CR28_INDEX
464
 
465
/*
466
** Configuration Register Definitions
467
**
468
** The INDEX (write only) and DATA (read/write) ports are effective
469
** only when the chip is in the Configuration State.
470
*/
471
typedef struct _SMC37c669_CONFIG_REGS {
472
    unsigned char index_port;
473
    unsigned char data_port;
474
} SMC37c669_CONFIG_REGS;
475
 
476
/*
477
** CR00 - default value 0x28
478
**
479
**  IDE_EN (CR00<1:0>):
480
**      0x - 30ua pull-ups on nIDEEN, nHDCS0, NHDCS1
481
**      11 - IRQ_H available as IRQ output,
482
**           IRRX2, IRTX2 available as alternate IR pins
483
**      10 - nIDEEN, nHDCS0, nHDCS1 used to control IDE
484
**
485
**  VALID (CR00<7>):
486
**      A high level on this software controlled bit can
487
**      be used to indicate that a valid configuration
488
**      cycle has occurred.  The control software must
489
**      take care to set this bit at the appropriate times.
490
**      Set to zero after power up.  This bit has no
491
**      effect on any other hardware in the chip.
492
**
493
*/
494
typedef union _SMC37c669_CR00 {
495
    unsigned char as_uchar;
496
    struct {
497
        unsigned ide_en : 2;        /* See note above           */
498
        unsigned reserved1 : 1;     /* RAZ                      */
499
        unsigned fdc_pwr : 1;       /* 1 = supply power to FDC  */
500
        unsigned reserved2 : 3;     /* Read as 010b             */
501
        unsigned valid : 1;         /* See note above           */
502
    }   by_field;
503
} SMC37c669_CR00;
504
 
505
/*
506
** CR01 - default value 0x9C
507
*/
508
typedef union _SMC37c669_CR01 {
509
    unsigned char as_uchar;
510
    struct {
511
        unsigned reserved1 : 2;     /* RAZ                          */
512
        unsigned ppt_pwr : 1;       /* 1 = supply power to PPT      */
513
        unsigned ppt_mode : 1;      /* 1 = Printer mode, 0 = EPP    */
514
        unsigned reserved2 : 1;     /* Read as 1                    */
515
        unsigned reserved3 : 2;     /* RAZ                          */
516
        unsigned lock_crx: 1;       /* Lock CR00 - CR18             */
517
    }   by_field;
518
} SMC37c669_CR01;
519
 
520
/*
521
** CR02 - default value 0x88
522
*/
523
typedef union _SMC37c669_CR02 {
524
    unsigned char as_uchar;
525
    struct {
526
        unsigned reserved1 : 3;     /* RAZ                          */
527
        unsigned uart1_pwr : 1;     /* 1 = supply power to UART1    */
528
        unsigned reserved2 : 3;     /* RAZ                          */
529
        unsigned uart2_pwr : 1;     /* 1 = supply power to UART2    */
530
    }   by_field;
531
} SMC37c669_CR02;
532
 
533
/*
534
** CR03 - default value 0x78
535
**
536
**  CR03<7>     CR03<2>     Pin 94
537
**  -------     -------     ------
538
**     0           X        DRV2 (input)
539
**     1           0        ADRX
540
**     1           1        IRQ_B
541
**
542
**  CR03<6>     CR03<5>     Op Mode
543
**  -------     -------     -------
544
**     0           0        Model 30
545
**     0           1        PS/2
546
**     1           0        Reserved
547
**     1           1        AT Mode
548
*/
549
typedef union _SMC37c669_CR03 {
550
    unsigned char as_uchar;
551
    struct {
552
        unsigned pwrgd_gamecs : 1;  /* 1 = PWRGD, 0 = GAMECS        */
553
        unsigned fdc_mode2 : 1;     /* 1 = Enhanced Mode 2          */
554
        unsigned pin94_0 : 1;       /* See note above               */
555
        unsigned reserved1 : 1;     /* RAZ                          */
556
        unsigned drvden : 1;        /* 1 = high, 0 - output         */
557
        unsigned op_mode : 2;       /* See note above               */
558
        unsigned pin94_1 : 1;       /* See note above               */
559
    }   by_field;
560
} SMC37c669_CR03;
561
 
562
/*
563
** CR04 - default value 0x00
564
**
565
**  PP_EXT_MODE:
566
**      If CR01<PP_MODE> = 0 and PP_EXT_MODE =
567
**          00 - Standard and Bidirectional
568
**          01 - EPP mode and SPP
569
**          10 - ECP mode
570
**               In this mode, 2 drives can be supported
571
**               directly, 3 or 4 drives must use external
572
**               4 drive support.  SPP can be selected
573
**               through the ECR register of ECP as mode 000.
574
**          11 - ECP mode and EPP mode
575
**               In this mode, 2 drives can be supported
576
**               directly, 3 or 4 drives must use external
577
**               4 drive support.  SPP can be selected
578
**               through the ECR register of ECP as mode 000.
579
**               In this mode, EPP can be selected through
580
**               the ECR register of ECP as mode 100.
581
**
582
**  PP_FDC:
583
**      00 - Normal
584
**      01 - PPFD1
585
**      10 - PPFD2
586
**      11 - Reserved
587
**
588
**  MIDI1:
589
**      Serial Clock Select:
590
**          A low level on this bit disables MIDI support,
591
**          clock = divide by 13.  A high level on this
592
**          bit enables MIDI support, clock = divide by 12.
593
**
594
**      MIDI operates at 31.25 Kbps which can be derived
595
**      from 125 KHz (24 MHz / 12 = 2 MHz, 2 MHz / 16 = 125 KHz)
596
**
597
**  ALT_IO:
598
**      0 - Use pins IRRX, IRTX
599
**      1 - Use pins IRRX2, IRTX2
600
**
601
**      If this bit is set, the IR receive and transmit
602
**      functions will not be available on pins 25 and 26
603
**      unless CR00<IDE_EN> = 11.
604
*/
605
typedef union _SMC37c669_CR04 {
606
    unsigned char as_uchar;
607
    struct {
608
        unsigned ppt_ext_mode : 2;  /* See note above               */
609
        unsigned ppt_fdc : 2;       /* See note above               */
610
        unsigned midi1 : 1;         /* See note above               */
611
        unsigned midi2 : 1;         /* See note above               */
612
        unsigned epp_type : 1;      /* 0 = EPP 1.9, 1 = EPP 1.7     */
613
        unsigned alt_io : 1;        /* See note above               */
614
    }   by_field;
615
} SMC37c669_CR04;
616
 
617
/*
618
** CR05 - default value 0x00
619
**
620
**  DEN_SEL:
621
**      00 - Densel output normal
622
**      01 - Reserved
623
**      10 - Densel output 1
624
**      11 - Densel output 0
625
**
626
*/
627
typedef union _SMC37c669_CR05 {
628
    unsigned char as_uchar;
629
    struct {
630
        unsigned reserved1 : 2;     /* RAZ                                      */
631
        unsigned fdc_dma_mode : 1;  /* 0 = burst, 1 = non-burst                 */
632
        unsigned den_sel : 2;       /* See note above                           */
633
        unsigned swap_drv : 1;      /* Swap the FDC motor selects               */
634
        unsigned extx4 : 1;         /* 0 = 2 drive, 1 = external 4 drive decode */
635
        unsigned reserved2 : 1;     /* RAZ                                      */
636
    }   by_field;
637
} SMC37c669_CR05;
638
 
639
/*
640
** CR06 - default value 0xFF
641
*/
642
typedef union _SMC37c669_CR06 {
643
    unsigned char as_uchar;
644
    struct {
645
        unsigned floppy_a : 2;      /* Type of floppy drive A       */
646
        unsigned floppy_b : 2;      /* Type of floppy drive B       */
647
        unsigned floppy_c : 2;      /* Type of floppy drive C       */
648
        unsigned floppy_d : 2;      /* Type of floppy drive D       */
649
    }   by_field;
650
} SMC37c669_CR06;
651
 
652
/*
653
** CR07 - default value 0x00
654
**
655
**  Auto Power Management CR07<7:4>:
656
**      0 - Auto Powerdown disabled (default)
657
**      1 - Auto Powerdown enabled
658
**
659
**      This bit is reset to the default state by POR or
660
**      a hardware reset.
661
**
662
*/
663
typedef union _SMC37c669_CR07 {
664
    unsigned char as_uchar;
665
    struct {
666
        unsigned floppy_boot : 2;   /* 0 = A:, 1 = B:               */
667
        unsigned reserved1 : 2;     /* RAZ                          */
668
        unsigned ppt_en : 1;        /* See note above               */
669
        unsigned uart1_en : 1;      /* See note above               */
670
        unsigned uart2_en : 1;      /* See note above               */
671
        unsigned fdc_en : 1;        /* See note above               */
672
    }   by_field;
673
} SMC37c669_CR07;
674
 
675
/*
676
** CR08 - default value 0x00
677
*/
678
typedef union _SMC37c669_CR08 {
679
    unsigned char as_uchar;
680
    struct {
681
        unsigned zero : 4;          /* 0                            */
682
        unsigned addrx7_4 : 4;      /* ADR<7:3> for ADRx decode     */
683
    }   by_field;
684
} SMC37c669_CR08;
685
 
686
/*
687
** CR09 - default value 0x00
688
**
689
**  ADRx_CONFIG:
690
**      00 - ADRx disabled
691
**      01 - 1 byte decode A<3:0> = 0000b
692
**      10 - 8 byte block decode A<3:0> = 0XXXb
693
**      11 - 16 byte block decode A<3:0> = XXXXb
694
**
695
*/
696
typedef union _SMC37c669_CR09 {
697
    unsigned char as_uchar;
698
    struct {
699
        unsigned adra8 : 3;         /* ADR<10:8> for ADRx decode    */
700
        unsigned reserved1 : 3;
701
        unsigned adrx_config : 2;   /* See note above               */
702
    }   by_field;
703
} SMC37c669_CR09;
704
 
705
/*
706
** CR0A - default value 0x00
707
*/
708
typedef union _SMC37c669_CR0A {
709
    unsigned char as_uchar;
710
    struct {
711
        unsigned ecp_fifo_threshold : 4;
712
        unsigned reserved1 : 4;
713
    }   by_field;
714
} SMC37c669_CR0A;
715
 
716
/*
717
** CR0B - default value 0x00
718
*/
719
typedef union _SMC37c669_CR0B {
720
    unsigned char as_uchar;
721
    struct {
722
        unsigned fdd0_drtx : 2;     /* FDD0 Data Rate Table         */
723
        unsigned fdd1_drtx : 2;     /* FDD1 Data Rate Table         */
724
        unsigned fdd2_drtx : 2;     /* FDD2 Data Rate Table         */
725
        unsigned fdd3_drtx : 2;     /* FDD3 Data Rate Table         */
726
    }   by_field;
727
} SMC37c669_CR0B;
728
 
729
/*
730
** CR0C - default value 0x00
731
**
732
**  UART2_MODE:
733
**      000 - Standard (default)
734
**      001 - IrDA (HPSIR)
735
**      010 - Amplitude Shift Keyed IR @500 KHz
736
**      011 - Reserved
737
**      1xx - Reserved
738
**
739
*/
740
typedef union _SMC37c669_CR0C {
741
    unsigned char as_uchar;
742
    struct {
743
        unsigned uart2_rcv_polarity : 1;    /* 1 = invert RX            */
744
        unsigned uart2_xmit_polarity : 1;   /* 1 = invert TX            */
745
        unsigned uart2_duplex : 1;          /* 1 = full, 0 = half       */
746
        unsigned uart2_mode : 3;            /* See note above           */
747
        unsigned uart1_speed : 1;           /* 1 = high speed enabled   */
748
        unsigned uart2_speed : 1;           /* 1 = high speed enabled   */
749
    }   by_field;
750
} SMC37c669_CR0C;
751
 
752
/*
753
** CR0D - default value 0x03
754
**
755
**  Device ID Register - read only
756
*/
757
typedef union _SMC37c669_CR0D {
758
    unsigned char as_uchar;
759
    struct {
760
        unsigned device_id : 8;     /* Returns 0x3 in this field    */
761
    }   by_field;
762
} SMC37c669_CR0D;
763
 
764
/*
765
** CR0E - default value 0x02
766
**
767
**  Device Revision Register - read only
768
*/
769
typedef union _SMC37c669_CR0E {
770
    unsigned char as_uchar;
771
    struct {
772
        unsigned device_rev : 8;    /* Returns 0x2 in this field    */
773
    }   by_field;
774
} SMC37c669_CR0E;
775
 
776
/*
777
** CR0F - default value 0x00
778
*/
779
typedef union _SMC37c669_CR0F {
780
    unsigned char as_uchar;
781
    struct {
782
        unsigned test0 : 1;         /* Reserved - set to 0          */
783
        unsigned test1 : 1;         /* Reserved - set to 0          */
784
        unsigned test2 : 1;         /* Reserved - set to 0          */
785
        unsigned test3 : 1;         /* Reserved - set t0 0          */
786
        unsigned test4 : 1;         /* Reserved - set to 0          */
787
        unsigned test5 : 1;         /* Reserved - set t0 0          */
788
        unsigned test6 : 1;         /* Reserved - set t0 0          */
789
        unsigned test7 : 1;         /* Reserved - set to 0          */
790
    }   by_field;
791
} SMC37c669_CR0F;
792
 
793
/*
794
** CR10 - default value 0x00
795
*/
796
typedef union _SMC37c669_CR10 {
797
    unsigned char as_uchar;
798
    struct {
799
        unsigned reserved1 : 3;      /* RAZ                         */
800
        unsigned pll_gain : 1;       /* 1 = 3V, 2 = 5V operation    */
801
        unsigned pll_stop : 1;       /* 1 = stop PLLs               */
802
        unsigned ace_stop : 1;       /* 1 = stop UART clocks        */
803
        unsigned pll_clock_ctrl : 1; /* 0 = 14.318 MHz, 1 = 24 MHz  */
804
        unsigned ir_test : 1;        /* Enable IR test mode         */
805
    }   by_field;
806
} SMC37c669_CR10;
807
 
808
/*
809
** CR11 - default value 0x00
810
*/
811
typedef union _SMC37c669_CR11 {
812
    unsigned char as_uchar;
813
    struct {
814
        unsigned ir_loopback : 1;   /* Internal IR loop back                */
815
        unsigned test_10ms : 1;     /* Test 10ms autopowerdown FDC timeout  */
816
        unsigned reserved1 : 6;     /* RAZ                                  */
817
    }   by_field;
818
} SMC37c669_CR11;
819
 
820
/*
821
** CR12 - CR1D are reserved registers
822
*/
823
 
824
/*
825
** CR1E - default value 0x80
826
**
827
**  GAMECS:
828
**      00 - GAMECS disabled
829
**      01 - 1 byte decode ADR<3:0> = 0001b
830
**      10 - 8 byte block decode ADR<3:0> = 0XXXb
831
**      11 - 16 byte block decode ADR<3:0> = XXXXb
832
**
833
*/
834
typedef union _SMC37c66_CR1E {
835
    unsigned char as_uchar;
836
    struct {
837
        unsigned gamecs_config: 2;   /* See note above              */
838
        unsigned gamecs_addr9_4 : 6; /* GAMECS Addr<9:4>            */
839
    }   by_field;
840
} SMC37c669_CR1E;
841
 
842
/*
843
** CR1F - default value 0x00
844
**
845
**  DT0 DT1 DRVDEN0 DRVDEN1 Drive Type
846
**  --- --- ------- ------- ----------
847
**   0   0  DENSEL  DRATE0  4/2/1 MB 3.5"
848
**                          2/1 MB 5.25"
849
**                          2/1.6/1 MB 3.5" (3-mode)
850
**   0   1  DRATE1  DRATE0
851
**   1   0  nDENSEL DRATE0  PS/2
852
**   1   1  DRATE0  DRATE1
853
**
854
**  Note: DENSEL, DRATE1, and DRATE0 map onto two output
855
**        pins - DRVDEN0 and DRVDEN1.
856
**
857
*/
858
typedef union _SMC37c669_CR1F {
859
    unsigned char as_uchar;
860
    struct {
861
        unsigned fdd0_drive_type : 2;   /* FDD0 drive type          */
862
        unsigned fdd1_drive_type : 2;   /* FDD1 drive type          */
863
        unsigned fdd2_drive_type : 2;   /* FDD2 drive type          */
864
        unsigned fdd3_drive_type : 2;   /* FDD3 drive type          */
865
    }   by_field;
866
} SMC37c669_CR1F;
867
 
868
/*
869
** CR20 - default value 0x3C
870
**
871
**  FDC Base Address Register
872
**      - To disable this decode set Addr<9:8> = 0
873
**      - A<10> = 0, A<3:0> = 0XXXb to access.
874
**
875
*/
876
typedef union _SMC37c669_CR20 {
877
    unsigned char as_uchar;
878
    struct {
879
        unsigned zero : 2;          /* 0                            */
880
        unsigned addr9_4 : 6;       /* FDC Addr<9:4>                */
881
    }   by_field;
882
} SMC37c669_CR20;
883
 
884
/*
885
** CR21 - default value 0x3C
886
**
887
**  IDE Base Address Register
888
**      - To disable this decode set Addr<9:8> = 0
889
**      - A<10> = 0, A<3:0> = 0XXXb to access.
890
**
891
*/
892
typedef union _SMC37c669_CR21 {
893
    unsigned char as_uchar;
894
    struct {
895
        unsigned zero : 2;          /* 0                            */
896
        unsigned addr9_4 : 6;       /* IDE Addr<9:4>                */
897
    }   by_field;
898
} SMC37c669_CR21;
899
 
900
/*
901
** CR22 - default value 0x3D
902
**
903
**  IDE Alternate Status Base Address Register
904
**      - To disable this decode set Addr<9:8> = 0
905
**      - A<10> = 0, A<3:0> = 0110b to access.
906
**
907
*/
908
typedef union _SMC37c669_CR22 {
909
    unsigned char as_uchar;
910
    struct {
911
        unsigned zero : 2;          /* 0                            */
912
        unsigned addr9_4 : 6;       /* IDE Alt Status Addr<9:4>     */
913
    }   by_field;
914
} SMC37c669_CR22;
915
 
916
/*
917
** CR23 - default value 0x00
918
**
919
**  Parallel Port Base Address Register
920
**      - To disable this decode set Addr<9:8> = 0
921
**      - A<10> = 0 to access.
922
**      - If EPP is enabled, A<2:0> = XXXb to access.
923
**        If EPP is NOT enabled, A<1:0> = XXb to access
924
**
925
*/
926
typedef union _SMC37c669_CR23 {
927
    unsigned char as_uchar;
928
    struct {
929
        unsigned addr9_2 : 8;       /* Parallel Port Addr<9:2>      */
930
    }   by_field;
931
} SMC37c669_CR23;
932
 
933
/*
934
** CR24 - default value 0x00
935
**
936
**  UART1 Base Address Register
937
**      - To disable this decode set Addr<9:8> = 0
938
**      - A<10> = 0, A<2:0> = XXXb to access.
939
**
940
*/
941
typedef union _SMC37c669_CR24 {
942
    unsigned char as_uchar;
943
    struct {
944
        unsigned zero : 1;          /* 0                            */
945
        unsigned addr9_3 : 7;       /* UART1 Addr<9:3>              */
946
    }   by_field;
947
} SMC37c669_CR24;
948
 
949
/*
950
** CR25 - default value 0x00
951
**
952
**  UART2 Base Address Register
953
**      - To disable this decode set Addr<9:8> = 0
954
**      - A<10> = 0, A<2:0> = XXXb to access.
955
**
956
*/
957
typedef union _SMC37c669_CR25 {
958
    unsigned char as_uchar;
959
    struct {
960
        unsigned zero : 1;          /* 0                            */
961
        unsigned addr9_3 : 7;       /* UART2 Addr<9:3>              */
962
    }   by_field;
963
} SMC37c669_CR25;
964
 
965
/*
966
** CR26 - default value 0x00
967
**
968
**  Parallel Port / FDC DMA Select Register
969
**
970
**  D3 - D0       DMA
971
**  D7 - D4     Selected
972
**  -------     --------
973
**   0000        None
974
**   0001        DMA_A
975
**   0010        DMA_B
976
**   0011        DMA_C
977
**
978
*/
979
typedef union _SMC37c669_CR26 {
980
    unsigned char as_uchar;
981
    struct {
982
        unsigned ppt_drq : 4;       /* See note above               */
983
        unsigned fdc_drq : 4;       /* See note above               */
984
    }   by_field;
985
} SMC37c669_CR26;
986
 
987
/*
988
** CR27 - default value 0x00
989
**
990
**  Parallel Port / FDC IRQ Select Register
991
**
992
**  D3 - D0       IRQ
993
**  D7 - D4     Selected
994
**  -------     --------
995
**   0000        None
996
**   0001        IRQ_A
997
**   0010        IRQ_B
998
**   0011        IRQ_C
999
**   0100        IRQ_D
1000
**   0101        IRQ_E
1001
**   0110        IRQ_F
1002
**   0111        Reserved
1003
**   1000        IRQ_H
1004
**
1005
**  Any unselected IRQ REQ is in tristate
1006
**
1007
*/
1008
typedef union _SMC37c669_CR27 {
1009
    unsigned char as_uchar;
1010
    struct {
1011
        unsigned ppt_irq : 4;       /* See note above               */
1012
        unsigned fdc_irq : 4;       /* See note above               */
1013
    }   by_field;
1014
} SMC37c669_CR27;
1015
 
1016
/*
1017
** CR28 - default value 0x00
1018
**
1019
**  UART IRQ Select Register
1020
**
1021
**  D3 - D0       IRQ
1022
**  D7 - D4     Selected
1023
**  -------     --------
1024
**   0000        None
1025
**   0001        IRQ_A
1026
**   0010        IRQ_B
1027
**   0011        IRQ_C
1028
**   0100        IRQ_D
1029
**   0101        IRQ_E
1030
**   0110        IRQ_F
1031
**   0111        Reserved
1032
**   1000        IRQ_H
1033
**   1111        share with UART1 (only for UART2)
1034
**
1035
**  Any unselected IRQ REQ is in tristate
1036
**
1037
**  To share an IRQ between UART1 and UART2, set
1038
**  UART1 to use the desired IRQ and set UART2 to
1039
**  0xF to enable sharing mechanism.
1040
**
1041
*/
1042
typedef union _SMC37c669_CR28 {
1043
    unsigned char as_uchar;
1044
    struct {
1045
        unsigned uart2_irq : 4;     /* See note above               */
1046
        unsigned uart1_irq : 4;     /* See note above               */
1047
    }   by_field;
1048
} SMC37c669_CR28;
1049
 
1050
/*
1051
** CR29 - default value 0x00
1052
**
1053
**  IRQIN IRQ Select Register
1054
**
1055
**  D3 - D0       IRQ
1056
**  D7 - D4     Selected
1057
**  -------     --------
1058
**   0000        None
1059
**   0001        IRQ_A
1060
**   0010        IRQ_B
1061
**   0011        IRQ_C
1062
**   0100        IRQ_D
1063
**   0101        IRQ_E
1064
**   0110        IRQ_F
1065
**   0111        Reserved
1066
**   1000        IRQ_H
1067
**
1068
**  Any unselected IRQ REQ is in tristate
1069
**
1070
*/
1071
typedef union _SMC37c669_CR29 {
1072
    unsigned char as_uchar;
1073
    struct {
1074
        unsigned irqin_irq : 4;     /* See note above               */
1075
        unsigned reserved1 : 4;     /* RAZ                          */
1076
    }   by_field;
1077
} SMC37c669_CR29;
1078
 
1079
/*
1080
** Aliases of Configuration Register formats (should match
1081
** the set of index aliases).
1082
**
1083
** Note that CR24 and CR25 have the same format and are the
1084
** base address registers for UART1 and UART2.  Because of
1085
** this we only define 1 alias here - for CR24 - as the serial
1086
** base address register.
1087
**
1088
** Note that CR21 and CR22 have the same format and are the
1089
** base address and alternate status address registers for
1090
** the IDE controller.  Because of this we only define 1 alias
1091
** here - for CR21 - as the IDE address register.
1092
**
1093
*/
1094
typedef SMC37c669_CR0D SMC37c669_DEVICE_ID_REGISTER;
1095
typedef SMC37c669_CR0E SMC37c669_DEVICE_REVISION_REGISTER;
1096
typedef SMC37c669_CR20 SMC37c669_FDC_BASE_ADDRESS_REGISTER;
1097
typedef SMC37c669_CR21 SMC37c669_IDE_ADDRESS_REGISTER;
1098
typedef SMC37c669_CR23 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER;
1099
typedef SMC37c669_CR24 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER;
1100
typedef SMC37c669_CR26 SMC37c669_PARALLEL_FDC_DRQ_REGISTER;
1101
typedef SMC37c669_CR27 SMC37c669_PARALLEL_FDC_IRQ_REGISTER;
1102
typedef SMC37c669_CR28 SMC37c669_SERIAL_IRQ_REGISTER;
1103
 
1104
/*
1105
** ISA/Device IRQ Translation Table Entry Definition
1106
*/
1107
typedef struct _SMC37c669_IRQ_TRANSLATION_ENTRY {
1108
    int device_irq;
1109
    int isa_irq;
1110
} SMC37c669_IRQ_TRANSLATION_ENTRY;
1111
 
1112
/*
1113
** ISA/Device DMA Translation Table Entry Definition
1114
*/
1115
typedef struct _SMC37c669_DRQ_TRANSLATION_ENTRY {
1116
    int device_drq;
1117
    int isa_drq;
1118
} SMC37c669_DRQ_TRANSLATION_ENTRY;
1119
 
1120
/*
1121
** External Interface Function Prototype Declarations
1122
*/
1123
 
1124
SMC37c669_CONFIG_REGS *SMC37c669_detect(
1125
    void
1126
);
1127
 
1128
unsigned int SMC37c669_enable_device(
1129
    unsigned int func
1130
);
1131
 
1132
unsigned int SMC37c669_disable_device(
1133
    unsigned int func
1134
);
1135
 
1136
unsigned int SMC37c669_configure_device(
1137
    unsigned int func,
1138
    int port,
1139
    int irq,
1140
    int drq
1141
);
1142
 
1143
void SMC37c669_display_device_info(
1144
    void
1145
);
1146
 
1147
#endif  /* __SMC37c669_H */
1148
 
1149
/* file:        smcc669.c
1150
 *
1151
 * Copyright (C) 1997 by
1152
 * Digital Equipment Corporation, Maynard, Massachusetts.
1153
 * All rights reserved.
1154
 *
1155
 * This software is furnished under a license and may be used and copied
1156
 * only  in  accordance  of  the  terms  of  such  license  and with the
1157
 * inclusion of the above copyright notice. This software or  any  other
1158
 * copies thereof may not be provided or otherwise made available to any
1159
 * other person.  No title to and  ownership of the  software is  hereby
1160
 * transferred.
1161
 *
1162
 * The information in this software is  subject to change without notice
1163
 * and  should  not  be  construed  as a commitment by digital equipment
1164
 * corporation.
1165
 *
1166
 * Digital assumes no responsibility for the use  or  reliability of its
1167
 * software on equipment which is not supplied by digital.
1168
 */
1169
 
1170
/*
1171
 *++
1172
 *  FACILITY:
1173
 *
1174
 *      Alpha SRM Console Firmware
1175
 *
1176
 *  MODULE DESCRIPTION:
1177
 *
1178
 *      SMC37c669 Super I/O controller configuration routines.
1179
 *
1180
 *  AUTHORS:
1181
 *
1182
 *      Eric Rasmussen
1183
 *
1184
 *  CREATION DATE:
1185
 *
1186
 *      28-Jan-1997
1187
 *
1188
 *  MODIFICATION HISTORY:
1189
 *
1190
 *      er      01-May-1997     Fixed pointer conversion errors in
1191
 *                              SMC37c669_get_device_config().
1192
 *      er      28-Jan-1997     Initial version.
1193
 *
1194
 *--
1195
 */
1196
#if 0
1197
/* $INCLUDE_OPTIONS$ */
1198
#include    "cp$inc:platform_io.h"
1199
/* $INCLUDE_OPTIONS_END$ */
1200
#include    "cp$src:common.h"
1201
#include    "cp$inc:prototypes.h"
1202
#include    "cp$src:kernel_def.h"
1203
#include    "cp$src:msg_def.h"
1204
#include    "cp$src:smcc669_def.h"
1205
/* Platform-specific includes */
1206
#include    "cp$src:platform.h"
1207
#endif
1208
 
1209
#ifndef TRUE
1210
#define TRUE 1
1211
#endif
1212
#ifndef FALSE
1213
#define FALSE 0
1214
#endif
1215
 
1216
#define wb( _x_, _y_ )  outb( _y_, (unsigned int)((unsigned long)_x_) )
1217
#define rb( _x_ )       inb( (unsigned int)((unsigned long)_x_) )
1218
 
1219
/*
1220
** Local storage for device configuration information.
1221
**
1222
** Since the SMC37c669 does not provide an explicit
1223
** mechanism for enabling/disabling individual device
1224
** functions, other than unmapping the device, local
1225
** storage for device configuration information is
1226
** allocated here for use in implementing our own
1227
** function enable/disable scheme.
1228
*/
1229
static struct DEVICE_CONFIG {
1230
    unsigned int port1;
1231
    unsigned int port2;
1232
    unsigned int irq;
1233
    unsigned int drq;
1234
} local_config [NUM_FUNCS];
1235
 
1236
/*
1237
** List of all possible addresses for the Super I/O chip
1238
*/
1239
static unsigned long SMC37c669_Addresses[] =
1240
    {
1241
        0x3F0UL,            /* Primary address      */
1242
        0x370UL,            /* Secondary address    */
1243
        0UL                 /* End of list          */
1244
    };
1245
 
1246
/*
1247
** Global Pointer to the Super I/O device
1248
*/
1249
static SMC37c669_CONFIG_REGS *SMC37c669 = NULL;
1250
 
1251
/*
1252
** IRQ Translation Table
1253
**
1254
** The IRQ translation table is a list of SMC37c669 device
1255
** and standard ISA IRQs.
1256
**
1257
*/
1258
static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_table;
1259
 
1260
/*
1261
** The following definition is for the default IRQ
1262
** translation table.
1263
*/
1264
static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_default_irq_table[ ] =
1265
    {
1266
        { SMC37c669_DEVICE_IRQ_A, -1 },
1267
        { SMC37c669_DEVICE_IRQ_B, -1 },
1268
        { SMC37c669_DEVICE_IRQ_C, 7 },
1269
        { SMC37c669_DEVICE_IRQ_D, 6 },
1270
        { SMC37c669_DEVICE_IRQ_E, 4 },
1271
        { SMC37c669_DEVICE_IRQ_F, 3 },
1272
        { SMC37c669_DEVICE_IRQ_H, -1 },
1273
        { -1, -1 } /* End of table */
1274
    };
1275
 
1276
/*
1277
** DRQ Translation Table
1278
**
1279
** The DRQ translation table is a list of SMC37c669 device and
1280
** ISA DMA channels.
1281
**
1282
*/
1283
static SMC37c669_DRQ_TRANSLATION_ENTRY *SMC37c669_drq_table;
1284
 
1285
/*
1286
** The following definition is the default DRQ
1287
** translation table.
1288
*/
1289
static SMC37c669_DRQ_TRANSLATION_ENTRY SMC37c669_default_drq_table[ ] =
1290
    {
1291
        { SMC37c669_DEVICE_DRQ_A, 2 },
1292
        { SMC37c669_DEVICE_DRQ_B, 3 },
1293
        { SMC37c669_DEVICE_DRQ_C, -1 },
1294
        { -1, -1 } /* End of table */
1295
    };
1296
 
1297
/*
1298
** Local Function Prototype Declarations
1299
*/
1300
 
1301
static unsigned int SMC37c669_is_device_enabled(
1302
    unsigned int func
1303
);
1304
 
1305
#if 0
1306
static unsigned int SMC37c669_get_device_config(
1307
    unsigned int func,
1308
    int *port,
1309
    int *irq,
1310
    int *drq
1311
);
1312
#endif
1313
 
1314
static void SMC37c669_config_mode(
1315
    unsigned int enable
1316
);
1317
 
1318
static unsigned char SMC37c669_read_config(
1319
    unsigned char index
1320
);
1321
 
1322
static void SMC37c669_write_config(
1323
    unsigned char index,
1324
    unsigned char data
1325
);
1326
 
1327
static void SMC37c669_init_local_config( void );
1328
 
1329
static struct DEVICE_CONFIG *SMC37c669_get_config(
1330
    unsigned int func
1331
);
1332
 
1333
static int SMC37c669_xlate_irq(
1334
    unsigned int irq
1335
);
1336
 
1337
static int SMC37c669_xlate_drq(
1338
    unsigned int drq
1339
);
1340
 
1341
#if 0
1342
/*
1343
** External Data Declarations
1344
*/
1345
 
1346
extern struct LOCK spl_atomic;
1347
 
1348
/*
1349
** External Function Prototype Declarations
1350
*/
1351
 
1352
/* From kernel_alpha.mar */
1353
extern spinlock(
1354
    struct LOCK *spl
1355
);
1356
 
1357
extern spinunlock(
1358
    struct LOCK *spl
1359
);
1360
 
1361
/* From filesys.c */
1362
int allocinode(
1363
    char *name,
1364
    int can_create,
1365
    struct INODE **ipp
1366
);
1367
 
1368
extern int null_procedure( void );
1369
 
1370
int smcc669_init( void );
1371
int smcc669_open( struct FILE *fp, char *info, char *next, char *mode );
1372
int smcc669_read( struct FILE *fp, int size, int number, unsigned char *buf );
1373
int smcc669_write( struct FILE *fp, int size, int number, unsigned char *buf );
1374
int smcc669_close( struct FILE *fp );
1375
 
1376
struct DDB smc_ddb = {
1377
        "smc",                  /* how this routine wants to be called  */
1378
        smcc669_read,           /* read routine                         */
1379
        smcc669_write,          /* write routine                        */
1380
        smcc669_open,           /* open routine                         */
1381
        smcc669_close,          /* close routine                        */
1382
        null_procedure,         /* name expansion routine               */
1383
        null_procedure,         /* delete routine                       */
1384
        null_procedure,         /* create routine                       */
1385
        null_procedure,         /* setmode                              */
1386
        null_procedure,         /* validation routine                   */
1387
        0,                       /* class specific use                   */
1388
        1,                      /* allows information                   */
1389
        0,                       /* must be stacked                      */
1390
        0,                       /* is a flash update driver             */
1391
        0,                       /* is a block device                    */
1392
        0,                       /* not seekable                         */
1393
        0,                       /* is an ethernet device                */
1394
        0,                       /* is a filesystem driver               */
1395
};
1396
#endif
1397
 
1398
#define spinlock(x)
1399
#define spinunlock(x)
1400
 
1401
 
1402
/*
1403
**++
1404
**  FUNCTIONAL DESCRIPTION:
1405
**
1406
**      This function detects the presence of an SMC37c669 Super I/O
1407
**      controller.
1408
**
1409
**  FORMAL PARAMETERS:
1410
**
1411
**      None
1412
**
1413
**  RETURN VALUE:
1414
**
1415
**      Returns a pointer to the device if found, otherwise,
1416
**      the NULL pointer is returned.
1417
**
1418
**  SIDE EFFECTS:
1419
**
1420
**      None
1421
**
1422
**--
1423
*/
1424
SMC37c669_CONFIG_REGS *SMC37c669_detect( void )
1425
{
1426
    int i;
1427
    SMC37c669_DEVICE_ID_REGISTER id;
1428
 
1429
    for ( i = 0;  SMC37c669_Addresses[i] != 0;  i++ ) {
1430
/*
1431
** Initialize the device pointer even though we don't yet know if
1432
** the controller is at this address.  The support functions access
1433
** the controller through this device pointer so we need to set it
1434
** even when we are looking ...
1435
*/
1436
        SMC37c669 = ( SMC37c669_CONFIG_REGS * )SMC37c669_Addresses[i];
1437
/*
1438
** Enter configuration mode
1439
*/
1440
        SMC37c669_config_mode( TRUE );
1441
/*
1442
** Read the device id
1443
*/
1444
        id.as_uchar = SMC37c669_read_config( SMC37c669_DEVICE_ID_INDEX );
1445
/*
1446
** Exit configuration mode
1447
*/
1448
        SMC37c669_config_mode( FALSE );
1449
/*
1450
** Does the device id match?  If so, assume we have found an
1451
** SMC37c669 controller at this address.
1452
*/
1453
        if ( id.by_field.device_id == SMC37c669_DEVICE_ID ) {
1454
/*
1455
** Initialize the IRQ and DRQ translation tables.
1456
*/
1457
            SMC37c669_irq_table = SMC37c669_default_irq_table;
1458
            SMC37c669_drq_table = SMC37c669_default_drq_table;
1459
/*
1460
** erfix
1461
**
1462
** If the platform can't use the IRQ and DRQ defaults set up in this
1463
** file, it should call a platform-specific external routine at this
1464
** point to reset the IRQ and DRQ translation table pointers to point
1465
** at the appropriate tables for the platform.  If the defaults are
1466
** acceptable, then the external routine should do nothing.
1467
*/
1468
 
1469
/*
1470
** Put the chip back into configuration mode
1471
*/
1472
            SMC37c669_config_mode( TRUE );
1473
/*
1474
** Initialize local storage for configuration information
1475
*/
1476
            SMC37c669_init_local_config( );
1477
/*
1478
** Exit configuration mode
1479
*/
1480
            SMC37c669_config_mode( FALSE );
1481
/*
1482
** SMC37c669 controller found, break out of search loop
1483
*/
1484
            break;
1485
        }
1486
        else {
1487
/*
1488
** Otherwise, we did not find an SMC37c669 controller at this
1489
** address so set the device pointer to NULL.
1490
*/
1491
            SMC37c669 = NULL;
1492
        }
1493
    }
1494
    return SMC37c669;
1495
}
1496
 
1497
 
1498
/*
1499
**++
1500
**  FUNCTIONAL DESCRIPTION:
1501
**
1502
**      This function enables an SMC37c669 device function.
1503
**
1504
**  FORMAL PARAMETERS:
1505
**
1506
**      func:
1507
**          Which device function to enable
1508
**
1509
**  RETURN VALUE:
1510
**
1511
**      Returns TRUE is the device function was enabled, otherwise, FALSE
1512
**
1513
**  SIDE EFFECTS:
1514
**
1515
**      {@description or none@}
1516
**
1517
**  DESIGN:
1518
**
1519
**      Enabling a device function in the SMC37c669 controller involves
1520
**      setting all of its mappings (port, irq, drq ...).  A local
1521
**      "shadow" copy of the device configuration is kept so we can
1522
**      just set each mapping to what the local copy says.
1523
**
1524
**      This function ALWAYS updates the local shadow configuration of
1525
**      the device function being enabled, even if the device is always
1526
**      enabled.  To avoid replication of code, functions such as
1527
**      configure_device set up the local copy and then call this
1528
**      function to the update the real device.
1529
**
1530
**--
1531
*/
1532
unsigned int SMC37c669_enable_device ( unsigned int func )
1533
{
1534
    unsigned int ret_val = FALSE;
1535
/*
1536
** Put the device into configuration mode
1537
*/
1538
    SMC37c669_config_mode( TRUE );
1539
    switch ( func ) {
1540
        case SERIAL_0:
1541
            {
1542
                SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1543
                SMC37c669_SERIAL_IRQ_REGISTER irq;
1544
/*
1545
** Enable the serial 1 IRQ mapping
1546
*/
1547
                irq.as_uchar =
1548
                    SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1549
 
1550
                irq.by_field.uart1_irq =
1551
                    SMC37c669_RAW_DEVICE_IRQ(
1552
                        SMC37c669_xlate_irq( local_config[ func ].irq )
1553
                    );
1554
 
1555
                SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1556
/*
1557
** Enable the serial 1 port base address mapping
1558
*/
1559
                base_addr.as_uchar = 0;
1560
                base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
1561
 
1562
                SMC37c669_write_config(
1563
                    SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
1564
                    base_addr.as_uchar
1565
                );
1566
                ret_val = TRUE;
1567
                break;
1568
            }
1569
        case SERIAL_1:
1570
            {
1571
                SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1572
                SMC37c669_SERIAL_IRQ_REGISTER irq;
1573
/*
1574
** Enable the serial 2 IRQ mapping
1575
*/
1576
                irq.as_uchar =
1577
                    SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1578
 
1579
                irq.by_field.uart2_irq =
1580
                    SMC37c669_RAW_DEVICE_IRQ(
1581
                        SMC37c669_xlate_irq( local_config[ func ].irq )
1582
                    );
1583
 
1584
                SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1585
/*
1586
** Enable the serial 2 port base address mapping
1587
*/
1588
                base_addr.as_uchar = 0;
1589
                base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
1590
 
1591
                SMC37c669_write_config(
1592
                    SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
1593
                    base_addr.as_uchar
1594
                );
1595
                ret_val = TRUE;
1596
                break;
1597
            }
1598
        case PARALLEL_0:
1599
            {
1600
                SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
1601
                SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1602
                SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1603
/*
1604
** Enable the parallel port DMA channel mapping
1605
*/
1606
                drq.as_uchar =
1607
                    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1608
 
1609
                drq.by_field.ppt_drq =
1610
                    SMC37c669_RAW_DEVICE_DRQ(
1611
                        SMC37c669_xlate_drq( local_config[ func ].drq )
1612
                    );
1613
 
1614
                SMC37c669_write_config(
1615
                    SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1616
                    drq.as_uchar
1617
                );
1618
/*
1619
** Enable the parallel port IRQ mapping
1620
*/
1621
                irq.as_uchar =
1622
                    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1623
 
1624
                irq.by_field.ppt_irq =
1625
                    SMC37c669_RAW_DEVICE_IRQ(
1626
                        SMC37c669_xlate_irq( local_config[ func ].irq )
1627
                    );
1628
 
1629
                SMC37c669_write_config(
1630
                    SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1631
                    irq.as_uchar
1632
                );
1633
/*
1634
** Enable the parallel port base address mapping
1635
*/
1636
                base_addr.as_uchar = 0;
1637
                base_addr.by_field.addr9_2 = local_config[ func ].port1 >> 2;
1638
 
1639
                SMC37c669_write_config(
1640
                    SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
1641
                    base_addr.as_uchar
1642
                );
1643
                ret_val = TRUE;
1644
                break;
1645
            }
1646
        case FLOPPY_0:
1647
            {
1648
                SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
1649
                SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1650
                SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1651
/*
1652
** Enable the floppy controller DMA channel mapping
1653
*/
1654
                drq.as_uchar =
1655
                    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1656
 
1657
                drq.by_field.fdc_drq =
1658
                    SMC37c669_RAW_DEVICE_DRQ(
1659
                        SMC37c669_xlate_drq( local_config[ func ].drq )
1660
                    );
1661
 
1662
                SMC37c669_write_config(
1663
                    SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1664
                    drq.as_uchar
1665
                );
1666
/*
1667
** Enable the floppy controller IRQ mapping
1668
*/
1669
                irq.as_uchar =
1670
                    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1671
 
1672
                irq.by_field.fdc_irq =
1673
                    SMC37c669_RAW_DEVICE_IRQ(
1674
                        SMC37c669_xlate_irq( local_config[ func ].irq )
1675
                    );
1676
 
1677
                SMC37c669_write_config(
1678
                    SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1679
                    irq.as_uchar
1680
                );
1681
/*
1682
** Enable the floppy controller base address mapping
1683
*/
1684
                base_addr.as_uchar = 0;
1685
                base_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
1686
 
1687
                SMC37c669_write_config(
1688
                    SMC37c669_FDC_BASE_ADDRESS_INDEX,
1689
                    base_addr.as_uchar
1690
                );
1691
                ret_val = TRUE;
1692
                break;
1693
            }
1694
        case IDE_0:
1695
            {
1696
                SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
1697
/*
1698
** Enable the IDE alternate status base address mapping
1699
*/
1700
                ide_addr.as_uchar = 0;
1701
                ide_addr.by_field.addr9_4 = local_config[ func ].port2 >> 4;
1702
 
1703
                SMC37c669_write_config(
1704
                    SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
1705
                    ide_addr.as_uchar
1706
                );
1707
/*
1708
** Enable the IDE controller base address mapping
1709
*/
1710
                ide_addr.as_uchar = 0;
1711
                ide_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
1712
 
1713
                SMC37c669_write_config(
1714
                    SMC37c669_IDE_BASE_ADDRESS_INDEX,
1715
                    ide_addr.as_uchar
1716
                );
1717
                ret_val = TRUE;
1718
                break;
1719
            }
1720
    }
1721
/*
1722
** Exit configuration mode and return
1723
*/
1724
    SMC37c669_config_mode( FALSE );
1725
 
1726
    return ret_val;
1727
}
1728
 
1729
 
1730
/*
1731
**++
1732
**  FUNCTIONAL DESCRIPTION:
1733
**
1734
**      This function disables a device function within the
1735
**      SMC37c669 Super I/O controller.
1736
**
1737
**  FORMAL PARAMETERS:
1738
**
1739
**      func:
1740
**          Which function to disable
1741
**
1742
**  RETURN VALUE:
1743
**
1744
**      Return TRUE if the device function was disabled, otherwise, FALSE
1745
**
1746
**  SIDE EFFECTS:
1747
**
1748
**      {@description or none@}
1749
**
1750
**  DESIGN:
1751
**
1752
**      Disabling a function in the SMC37c669 device involves
1753
**      disabling all the function's mappings (port, irq, drq ...).
1754
**      A shadow copy of the device configuration is maintained
1755
**      in local storage so we won't worry aboving saving the
1756
**      current configuration information.
1757
**
1758
**--
1759
*/
1760
unsigned int SMC37c669_disable_device ( unsigned int func )
1761
{
1762
    unsigned int ret_val = FALSE;
1763
 
1764
/*
1765
** Put the device into configuration mode
1766
*/
1767
    SMC37c669_config_mode( TRUE );
1768
    switch ( func ) {
1769
        case SERIAL_0:
1770
            {
1771
                SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1772
                SMC37c669_SERIAL_IRQ_REGISTER irq;
1773
/*
1774
** Disable the serial 1 IRQ mapping
1775
*/
1776
                irq.as_uchar =
1777
                    SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1778
 
1779
                irq.by_field.uart1_irq = 0;
1780
 
1781
                SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1782
/*
1783
** Disable the serial 1 port base address mapping
1784
*/
1785
                base_addr.as_uchar = 0;
1786
                SMC37c669_write_config(
1787
                    SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
1788
                    base_addr.as_uchar
1789
                );
1790
                ret_val = TRUE;
1791
                break;
1792
            }
1793
        case SERIAL_1:
1794
            {
1795
                SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1796
                SMC37c669_SERIAL_IRQ_REGISTER irq;
1797
/*
1798
** Disable the serial 2 IRQ mapping
1799
*/
1800
                irq.as_uchar =
1801
                    SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1802
 
1803
                irq.by_field.uart2_irq = 0;
1804
 
1805
                SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1806
/*
1807
** Disable the serial 2 port base address mapping
1808
*/
1809
                base_addr.as_uchar = 0;
1810
 
1811
                SMC37c669_write_config(
1812
                    SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
1813
                    base_addr.as_uchar
1814
                );
1815
                ret_val = TRUE;
1816
                break;
1817
            }
1818
        case PARALLEL_0:
1819
            {
1820
                SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
1821
                SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1822
                SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1823
/*
1824
** Disable the parallel port DMA channel mapping
1825
*/
1826
                drq.as_uchar =
1827
                    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1828
 
1829
                drq.by_field.ppt_drq = 0;
1830
 
1831
                SMC37c669_write_config(
1832
                    SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1833
                    drq.as_uchar
1834
                );
1835
/*
1836
** Disable the parallel port IRQ mapping
1837
*/
1838
                irq.as_uchar =
1839
                    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1840
 
1841
                irq.by_field.ppt_irq = 0;
1842
 
1843
                SMC37c669_write_config(
1844
                    SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1845
                    irq.as_uchar
1846
                );
1847
/*
1848
** Disable the parallel port base address mapping
1849
*/
1850
                base_addr.as_uchar = 0;
1851
 
1852
                SMC37c669_write_config(
1853
                    SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
1854
                    base_addr.as_uchar
1855
                );
1856
                ret_val = TRUE;
1857
                break;
1858
            }
1859
        case FLOPPY_0:
1860
            {
1861
                SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
1862
                SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1863
                SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1864
/*
1865
** Disable the floppy controller DMA channel mapping
1866
*/
1867
                drq.as_uchar =
1868
                    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1869
 
1870
                drq.by_field.fdc_drq = 0;
1871
 
1872
                SMC37c669_write_config(
1873
                    SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1874
                    drq.as_uchar
1875
                );
1876
/*
1877
** Disable the floppy controller IRQ mapping
1878
*/
1879
                irq.as_uchar =
1880
                    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1881
 
1882
                irq.by_field.fdc_irq = 0;
1883
 
1884
                SMC37c669_write_config(
1885
                    SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1886
                    irq.as_uchar
1887
                );
1888
/*
1889
** Disable the floppy controller base address mapping
1890
*/
1891
                base_addr.as_uchar = 0;
1892
 
1893
                SMC37c669_write_config(
1894
                    SMC37c669_FDC_BASE_ADDRESS_INDEX,
1895
                    base_addr.as_uchar
1896
                );
1897
                ret_val = TRUE;
1898
                break;
1899
            }
1900
        case IDE_0:
1901
            {
1902
                SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
1903
/*
1904
** Disable the IDE alternate status base address mapping
1905
*/
1906
                ide_addr.as_uchar = 0;
1907
 
1908
                SMC37c669_write_config(
1909
                    SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
1910
                    ide_addr.as_uchar
1911
                );
1912
/*
1913
** Disable the IDE controller base address mapping
1914
*/
1915
                ide_addr.as_uchar = 0;
1916
 
1917
                SMC37c669_write_config(
1918
                    SMC37c669_IDE_BASE_ADDRESS_INDEX,
1919
                    ide_addr.as_uchar
1920
                );
1921
                ret_val = TRUE;
1922
                break;
1923
            }
1924
    }
1925
/*
1926
** Exit configuration mode and return
1927
*/
1928
    SMC37c669_config_mode( FALSE );
1929
 
1930
    return ret_val;
1931
}
1932
 
1933
 
1934
/*
1935
**++
1936
**  FUNCTIONAL DESCRIPTION:
1937
**
1938
**      This function configures a device function within the
1939
**      SMC37c669 Super I/O controller.
1940
**
1941
**  FORMAL PARAMETERS:
1942
**
1943
**      func:
1944
**          Which device function
1945
**
1946
**      port:
1947
**          I/O port for the function to use
1948
**
1949
**      irq:
1950
**          IRQ for the device function to use
1951
**
1952
**      drq:
1953
**          DMA channel for the device function to use
1954
**
1955
**  RETURN VALUE:
1956
**
1957
**      Returns TRUE if the device function was configured,
1958
**      otherwise, FALSE.
1959
**
1960
**  SIDE EFFECTS:
1961
**
1962
**      {@description or none@}
1963
**
1964
**  DESIGN:
1965
**
1966
**      If this function returns TRUE, the local shadow copy of
1967
**      the configuration is also updated.  If the device function
1968
**      is currently disabled, only the local shadow copy is
1969
**      updated and the actual device function will be updated
1970
**      if/when it is enabled.
1971
**
1972
**--
1973
*/
1974
unsigned int SMC37c669_configure_device (
1975
    unsigned int func,
1976
    int port,
1977
    int irq,
1978
    int drq )
1979
{
1980
    struct DEVICE_CONFIG *cp;
1981
 
1982
/*
1983
** Check for a valid configuration
1984
*/
1985
    if ( ( cp = SMC37c669_get_config ( func ) ) != NULL ) {
1986
/*
1987
** Configuration is valid, update the local shadow copy
1988
*/
1989
        if ( ( drq & ~0xFF ) == 0 ) {
1990
            cp->drq = drq;
1991
        }
1992
        if ( ( irq & ~0xFF ) == 0 ) {
1993
            cp->irq = irq;
1994
        }
1995
        if ( ( port & ~0xFFFF ) == 0 ) {
1996
            cp->port1 = port;
1997
        }
1998
/*
1999
** If the device function is enabled, update the actual
2000
** device configuration.
2001
*/
2002
        if ( SMC37c669_is_device_enabled( func ) ) {
2003
            SMC37c669_enable_device( func );
2004
        }
2005
        return TRUE;
2006
    }
2007
    return FALSE;
2008
}
2009
 
2010
 
2011
/*
2012
**++
2013
**  FUNCTIONAL DESCRIPTION:
2014
**
2015
**      This function determines whether a device function
2016
**      within the SMC37c669 controller is enabled.
2017
**
2018
**  FORMAL PARAMETERS:
2019
**
2020
**      func:
2021
**          Which device function
2022
**
2023
**  RETURN VALUE:
2024
**
2025
**      Returns TRUE if the device function is enabled, otherwise, FALSE
2026
**
2027
**  SIDE EFFECTS:
2028
**
2029
**      {@description or none@}
2030
**
2031
**  DESIGN:
2032
**
2033
**      To check whether a device is enabled we will only look at
2034
**      the port base address mapping.  According to the SMC37c669
2035
**      specification, all of the port base address mappings are
2036
**      disabled if the addr<9:8> (bits <7:6> of the register) are
2037
**      zero.
2038
**
2039
**--
2040
*/
2041
static unsigned int SMC37c669_is_device_enabled ( unsigned int func )
2042
{
2043
    unsigned char base_addr = 0;
2044
    unsigned int dev_ok = FALSE;
2045
    unsigned int ret_val = FALSE;
2046
/*
2047
** Enter configuration mode
2048
*/
2049
    SMC37c669_config_mode( TRUE );
2050
 
2051
    switch ( func ) {
2052
        case SERIAL_0:
2053
            base_addr =
2054
                SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
2055
            dev_ok = TRUE;
2056
            break;
2057
        case SERIAL_1:
2058
            base_addr =
2059
                SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
2060
            dev_ok = TRUE;
2061
            break;
2062
        case PARALLEL_0:
2063
            base_addr =
2064
                SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
2065
            dev_ok = TRUE;
2066
            break;
2067
        case FLOPPY_0:
2068
            base_addr =
2069
                SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
2070
            dev_ok = TRUE;
2071
            break;
2072
        case IDE_0:
2073
            base_addr =
2074
                SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
2075
            dev_ok = TRUE;
2076
            break;
2077
    }
2078
/*
2079
** If we have a valid device, check base_addr<7:6> to see if the
2080
** device is enabled (mapped).
2081
*/
2082
    if ( ( dev_ok ) && ( ( base_addr & 0xC0 ) != 0 ) ) {
2083
/*
2084
** The mapping is not disabled, so assume that the function is
2085
** enabled.
2086
*/
2087
        ret_val = TRUE;
2088
    }
2089
/*
2090
** Exit configuration mode
2091
*/
2092
    SMC37c669_config_mode( FALSE );
2093
 
2094
    return ret_val;
2095
}
2096
 
2097
 
2098
#if 0
2099
/*
2100
**++
2101
**  FUNCTIONAL DESCRIPTION:
2102
**
2103
**      This function retrieves the configuration information of a
2104
**      device function within the SMC37c699 Super I/O controller.
2105
**
2106
**  FORMAL PARAMETERS:
2107
**
2108
**      func:
2109
**          Which device function
2110
**
2111
**      port:
2112
**          I/O port returned
2113
**
2114
**      irq:
2115
**          IRQ returned
2116
**
2117
**      drq:
2118
**          DMA channel returned
2119
**
2120
**  RETURN VALUE:
2121
**
2122
**      Returns TRUE if the device configuration was successfully
2123
**      retrieved, otherwise, FALSE.
2124
**
2125
**  SIDE EFFECTS:
2126
**
2127
**      The data pointed to by the port, irq, and drq parameters
2128
**      my be modified even if the configuration is not successfully
2129
**      retrieved.
2130
**
2131
**  DESIGN:
2132
**
2133
**      The device configuration is fetched from the local shadow
2134
**      copy.  Any unused parameters will be set to -1.  Any
2135
**      parameter which is not desired can specify the NULL
2136
**      pointer.
2137
**
2138
**--
2139
*/
2140
static unsigned int SMC37c669_get_device_config (
2141
    unsigned int func,
2142
    int *port,
2143
    int *irq,
2144
    int *drq )
2145
{
2146
    struct DEVICE_CONFIG *cp;
2147
    unsigned int ret_val = FALSE;
2148
/*
2149
** Check for a valid device configuration
2150
*/
2151
    if ( ( cp = SMC37c669_get_config( func ) ) != NULL ) {
2152
        if ( drq != NULL ) {
2153
            *drq = cp->drq;
2154
            ret_val = TRUE;
2155
        }
2156
        if ( irq != NULL ) {
2157
            *irq = cp->irq;
2158
            ret_val = TRUE;
2159
        }
2160
        if ( port != NULL ) {
2161
            *port = cp->port1;
2162
            ret_val = TRUE;
2163
        }
2164
    }
2165
    return ret_val;
2166
}
2167
#endif
2168
 
2169
 
2170
/*
2171
**++
2172
**  FUNCTIONAL DESCRIPTION:
2173
**
2174
**      This function displays the current state of the SMC37c699
2175
**      Super I/O controller's device functions.
2176
**
2177
**  FORMAL PARAMETERS:
2178
**
2179
**      None
2180
**
2181
**  RETURN VALUE:
2182
**
2183
**      None
2184
**
2185
**  SIDE EFFECTS:
2186
**
2187
**      None
2188
**
2189
**--
2190
*/
2191
void SMC37c669_display_device_info ( void )
2192
{
2193
    if ( SMC37c669_is_device_enabled( SERIAL_0 ) ) {
2194
        printk( "  Serial 0:    Enabled [ Port 0x%x, IRQ %d ]\n",
2195
                 local_config[ SERIAL_0 ].port1,
2196
                 local_config[ SERIAL_0 ].irq
2197
        );
2198
    }
2199
    else {
2200
        printk( "  Serial 0:    Disabled\n" );
2201
    }
2202
 
2203
    if ( SMC37c669_is_device_enabled( SERIAL_1 ) ) {
2204
        printk( "  Serial 1:    Enabled [ Port 0x%x, IRQ %d ]\n",
2205
                 local_config[ SERIAL_1 ].port1,
2206
                 local_config[ SERIAL_1 ].irq
2207
        );
2208
    }
2209
    else {
2210
        printk( "  Serial 1:    Disabled\n" );
2211
    }
2212
 
2213
    if ( SMC37c669_is_device_enabled( PARALLEL_0 ) ) {
2214
        printk( "  Parallel:    Enabled [ Port 0x%x, IRQ %d/%d ]\n",
2215
                 local_config[ PARALLEL_0 ].port1,
2216
                 local_config[ PARALLEL_0 ].irq,
2217
                 local_config[ PARALLEL_0 ].drq
2218
        );
2219
    }
2220
    else {
2221
        printk( "  Parallel:    Disabled\n" );
2222
    }
2223
 
2224
    if ( SMC37c669_is_device_enabled( FLOPPY_0 ) ) {
2225
        printk( "  Floppy Ctrl: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
2226
                 local_config[ FLOPPY_0 ].port1,
2227
                 local_config[ FLOPPY_0 ].irq,
2228
                 local_config[ FLOPPY_0 ].drq
2229
        );
2230
    }
2231
    else {
2232
        printk( "  Floppy Ctrl: Disabled\n" );
2233
    }
2234
 
2235
    if ( SMC37c669_is_device_enabled( IDE_0 ) ) {
2236
        printk( "  IDE 0:       Enabled [ Port 0x%x, IRQ %d ]\n",
2237
                 local_config[ IDE_0 ].port1,
2238
                 local_config[ IDE_0 ].irq
2239
        );
2240
    }
2241
    else {
2242
        printk( "  IDE 0:       Disabled\n" );
2243
    }
2244
}
2245
 
2246
 
2247
/*
2248
**++
2249
**  FUNCTIONAL DESCRIPTION:
2250
**
2251
**      This function puts the SMC37c669 Super I/O controller into,
2252
**      and takes it out of, configuration mode.
2253
**
2254
**  FORMAL PARAMETERS:
2255
**
2256
**      enable:
2257
**          TRUE to enter configuration mode, FALSE to exit.
2258
**
2259
**  RETURN VALUE:
2260
**
2261
**      None
2262
**
2263
**  SIDE EFFECTS:
2264
**
2265
**      The SMC37c669 controller may be left in configuration mode.
2266
**
2267
**--
2268
*/
2269
static void SMC37c669_config_mode(
2270
    unsigned int enable )
2271
{
2272
    if ( enable ) {
2273
/*
2274
** To enter configuration mode, two writes in succession to the index
2275
** port are required.  If a write to another address or port occurs
2276
** between these two writes, the chip does not enter configuration
2277
** mode.  Therefore, a spinlock is placed around the two writes to
2278
** guarantee that they complete uninterrupted.
2279
*/
2280
        spinlock( &spl_atomic );
2281
        wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
2282
        wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
2283
        spinunlock( &spl_atomic );
2284
    }
2285
    else {
2286
        wb( &SMC37c669->index_port, SMC37c669_CONFIG_OFF_KEY );
2287
    }
2288
}
2289
 
2290
/*
2291
**++
2292
**  FUNCTIONAL DESCRIPTION:
2293
**
2294
**      This function reads an SMC37c669 Super I/O controller
2295
**      configuration register.  This function assumes that the
2296
**      device is already in configuration mode.
2297
**
2298
**  FORMAL PARAMETERS:
2299
**
2300
**      index:
2301
**          Index value of configuration register to read
2302
**
2303
**  RETURN VALUE:
2304
**
2305
**      Data read from configuration register
2306
**
2307
**  SIDE EFFECTS:
2308
**
2309
**      None
2310
**
2311
**--
2312
*/
2313
static unsigned char SMC37c669_read_config(
2314
    unsigned char index )
2315
{
2316
    unsigned char data;
2317
 
2318
    wb( &SMC37c669->index_port, index );
2319
    data = rb( &SMC37c669->data_port );
2320
    return data;
2321
}
2322
 
2323
/*
2324
**++
2325
**  FUNCTIONAL DESCRIPTION:
2326
**
2327
**      This function writes an SMC37c669 Super I/O controller
2328
**      configuration register.  This function assumes that the
2329
**      device is already in configuration mode.
2330
**
2331
**  FORMAL PARAMETERS:
2332
**
2333
**      index:
2334
**          Index of configuration register to write
2335
**
2336
**      data:
2337
**          Data to be written
2338
**
2339
**  RETURN VALUE:
2340
**
2341
**      None
2342
**
2343
**  SIDE EFFECTS:
2344
**
2345
**      None
2346
**
2347
**--
2348
*/
2349
static void SMC37c669_write_config(
2350
    unsigned char index,
2351
    unsigned char data )
2352
{
2353
    wb( &SMC37c669->index_port, index );
2354
    wb( &SMC37c669->data_port, data );
2355
}
2356
 
2357
 
2358
/*
2359
**++
2360
**  FUNCTIONAL DESCRIPTION:
2361
**
2362
**      This function initializes the local device
2363
**      configuration storage.  This function assumes
2364
**      that the device is already in configuration
2365
**      mode.
2366
**
2367
**  FORMAL PARAMETERS:
2368
**
2369
**      None
2370
**
2371
**  RETURN VALUE:
2372
**
2373
**      None
2374
**
2375
**  SIDE EFFECTS:
2376
**
2377
**      Local storage for device configuration information
2378
**      is initialized.
2379
**
2380
**--
2381
*/
2382
static void SMC37c669_init_local_config ( void )
2383
{
2384
    SMC37c669_SERIAL_BASE_ADDRESS_REGISTER uart_base;
2385
    SMC37c669_SERIAL_IRQ_REGISTER uart_irqs;
2386
    SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER ppt_base;
2387
    SMC37c669_PARALLEL_FDC_IRQ_REGISTER ppt_fdc_irqs;
2388
    SMC37c669_PARALLEL_FDC_DRQ_REGISTER ppt_fdc_drqs;
2389
    SMC37c669_FDC_BASE_ADDRESS_REGISTER fdc_base;
2390
    SMC37c669_IDE_ADDRESS_REGISTER ide_base;
2391
    SMC37c669_IDE_ADDRESS_REGISTER ide_alt;
2392
 
2393
/*
2394
** Get serial port 1 base address
2395
*/
2396
    uart_base.as_uchar =
2397
        SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
2398
/*
2399
** Get IRQs for serial ports 1 & 2
2400
*/
2401
    uart_irqs.as_uchar =
2402
        SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
2403
/*
2404
** Store local configuration information for serial port 1
2405
*/
2406
    local_config[SERIAL_0].port1 = uart_base.by_field.addr9_3 << 3;
2407
    local_config[SERIAL_0].irq =
2408
        SMC37c669_xlate_irq(
2409
            SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart1_irq )
2410
        );
2411
/*
2412
** Get serial port 2 base address
2413
*/
2414
    uart_base.as_uchar =
2415
        SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
2416
/*
2417
** Store local configuration information for serial port 2
2418
*/
2419
    local_config[SERIAL_1].port1 = uart_base.by_field.addr9_3 << 3;
2420
    local_config[SERIAL_1].irq =
2421
        SMC37c669_xlate_irq(
2422
            SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart2_irq )
2423
        );
2424
/*
2425
** Get parallel port base address
2426
*/
2427
    ppt_base.as_uchar =
2428
        SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
2429
/*
2430
** Get IRQs for parallel port and floppy controller
2431
*/
2432
    ppt_fdc_irqs.as_uchar =
2433
        SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
2434
/*
2435
** Get DRQs for parallel port and floppy controller
2436
*/
2437
    ppt_fdc_drqs.as_uchar =
2438
        SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
2439
/*
2440
** Store local configuration information for parallel port
2441
*/
2442
    local_config[PARALLEL_0].port1 = ppt_base.by_field.addr9_2 << 2;
2443
    local_config[PARALLEL_0].irq =
2444
        SMC37c669_xlate_irq(
2445
            SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.ppt_irq )
2446
        );
2447
    local_config[PARALLEL_0].drq =
2448
        SMC37c669_xlate_drq(
2449
            SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.ppt_drq )
2450
        );
2451
/*
2452
** Get floppy controller base address
2453
*/
2454
    fdc_base.as_uchar =
2455
        SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
2456
/*
2457
** Store local configuration information for floppy controller
2458
*/
2459
    local_config[FLOPPY_0].port1 = fdc_base.by_field.addr9_4 << 4;
2460
    local_config[FLOPPY_0].irq =
2461
        SMC37c669_xlate_irq(
2462
            SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.fdc_irq )
2463
        );
2464
    local_config[FLOPPY_0].drq =
2465
        SMC37c669_xlate_drq(
2466
            SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.fdc_drq )
2467
        );
2468
/*
2469
** Get IDE controller base address
2470
*/
2471
    ide_base.as_uchar =
2472
        SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
2473
/*
2474
** Get IDE alternate status base address
2475
*/
2476
    ide_alt.as_uchar =
2477
        SMC37c669_read_config( SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX );
2478
/*
2479
** Store local configuration information for IDE controller
2480
*/
2481
    local_config[IDE_0].port1 = ide_base.by_field.addr9_4 << 4;
2482
    local_config[IDE_0].port2 = ide_alt.by_field.addr9_4 << 4;
2483
    local_config[IDE_0].irq = 14;
2484
}
2485
 
2486
 
2487
/*
2488
**++
2489
**  FUNCTIONAL DESCRIPTION:
2490
**
2491
**      This function returns a pointer to the local shadow
2492
**      configuration of the requested device function.
2493
**
2494
**  FORMAL PARAMETERS:
2495
**
2496
**      func:
2497
**          Which device function
2498
**
2499
**  RETURN VALUE:
2500
**
2501
**      Returns a pointer to the DEVICE_CONFIG structure for the
2502
**      requested function, otherwise, NULL.
2503
**
2504
**  SIDE EFFECTS:
2505
**
2506
**      {@description or none@}
2507
**
2508
**--
2509
*/
2510
static struct DEVICE_CONFIG *SMC37c669_get_config( unsigned int func )
2511
{
2512
    struct DEVICE_CONFIG *cp = NULL;
2513
 
2514
    switch ( func ) {
2515
        case SERIAL_0:
2516
            cp = &local_config[ SERIAL_0 ];
2517
            break;
2518
        case SERIAL_1:
2519
            cp = &local_config[ SERIAL_1 ];
2520
            break;
2521
        case PARALLEL_0:
2522
            cp = &local_config[ PARALLEL_0 ];
2523
            break;
2524
        case FLOPPY_0:
2525
            cp = &local_config[ FLOPPY_0 ];
2526
            break;
2527
        case IDE_0:
2528
            cp = &local_config[ IDE_0 ];
2529
            break;
2530
    }
2531
    return cp;
2532
}
2533
 
2534
/*
2535
**++
2536
**  FUNCTIONAL DESCRIPTION:
2537
**
2538
**      This function translates IRQs back and forth between ISA
2539
**      IRQs and SMC37c669 device IRQs.
2540
**
2541
**  FORMAL PARAMETERS:
2542
**
2543
**      irq:
2544
**          The IRQ to translate
2545
**
2546
**  RETURN VALUE:
2547
**
2548
**      Returns the translated IRQ, otherwise, returns -1.
2549
**
2550
**  SIDE EFFECTS:
2551
**
2552
**      {@description or none@}
2553
**
2554
**--
2555
*/
2556
static int SMC37c669_xlate_irq ( unsigned int irq )
2557
{
2558
    int i, translated_irq = -1;
2559
 
2560
    if ( SMC37c669_IS_DEVICE_IRQ( irq ) ) {
2561
/*
2562
** We are translating a device IRQ to an ISA IRQ
2563
*/
2564
        for ( i = 0; ( SMC37c669_irq_table[i].device_irq != -1 ) || ( SMC37c669_irq_table[i].isa_irq != -1 ); i++ ) {
2565
            if ( irq == SMC37c669_irq_table[i].device_irq ) {
2566
                translated_irq = SMC37c669_irq_table[i].isa_irq;
2567
                break;
2568
            }
2569
        }
2570
    }
2571
    else {
2572
/*
2573
** We are translating an ISA IRQ to a device IRQ
2574
*/
2575
        for ( i = 0; ( SMC37c669_irq_table[i].isa_irq != -1 ) || ( SMC37c669_irq_table[i].device_irq != -1 ); i++ ) {
2576
            if ( irq == SMC37c669_irq_table[i].isa_irq ) {
2577
                translated_irq = SMC37c669_irq_table[i].device_irq;
2578
                break;
2579
            }
2580
        }
2581
    }
2582
    return translated_irq;
2583
}
2584
 
2585
 
2586
/*
2587
**++
2588
**  FUNCTIONAL DESCRIPTION:
2589
**
2590
**      This function translates DMA channels back and forth between
2591
**      ISA DMA channels and SMC37c669 device DMA channels.
2592
**
2593
**  FORMAL PARAMETERS:
2594
**
2595
**      drq:
2596
**          The DMA channel to translate
2597
**
2598
**  RETURN VALUE:
2599
**
2600
**      Returns the translated DMA channel, otherwise, returns -1
2601
**
2602
**  SIDE EFFECTS:
2603
**
2604
**      {@description or none@}
2605
**
2606
**--
2607
*/
2608
static int SMC37c669_xlate_drq ( unsigned int drq )
2609
{
2610
    int i, translated_drq = -1;
2611
 
2612
    if ( SMC37c669_IS_DEVICE_DRQ( drq ) ) {
2613
/*
2614
** We are translating a device DMA channel to an ISA DMA channel
2615
*/
2616
        for ( i = 0; ( SMC37c669_drq_table[i].device_drq != -1 ) || ( SMC37c669_drq_table[i].isa_drq != -1 ); i++ ) {
2617
            if ( drq == SMC37c669_drq_table[i].device_drq ) {
2618
                translated_drq = SMC37c669_drq_table[i].isa_drq;
2619
                break;
2620
            }
2621
        }
2622
    }
2623
    else {
2624
/*
2625
** We are translating an ISA DMA channel to a device DMA channel
2626
*/
2627
        for ( i = 0; ( SMC37c669_drq_table[i].isa_drq != -1 ) || ( SMC37c669_drq_table[i].device_drq != -1 ); i++ ) {
2628
            if ( drq == SMC37c669_drq_table[i].isa_drq ) {
2629
                translated_drq = SMC37c669_drq_table[i].device_drq;
2630
                break;
2631
            }
2632
        }
2633
    }
2634
    return translated_drq;
2635
}
2636
 
2637
#if 0
2638
int smcc669_init ( void )
2639
{
2640
    struct INODE *ip;
2641
 
2642
    allocinode( smc_ddb.name, 1, &ip );
2643
    ip->dva = &smc_ddb;
2644
    ip->attr = ATTR$M_WRITE | ATTR$M_READ;
2645
    ip->len[0] = 0x30;
2646
    ip->misc = 0;
2647
    INODE_UNLOCK( ip );
2648
 
2649
    return msg_success;
2650
}
2651
 
2652
int smcc669_open( struct FILE *fp, char *info, char *next, char *mode )
2653
{
2654
    struct INODE *ip;
2655
/*
2656
** Allow multiple readers but only one writer.  ip->misc keeps track
2657
** of the number of writers
2658
*/
2659
    ip = fp->ip;
2660
    INODE_LOCK( ip );
2661
    if ( fp->mode & ATTR$M_WRITE ) {
2662
        if ( ip->misc ) {
2663
            INODE_UNLOCK( ip );
2664
            return msg_failure;     /* too many writers */
2665
        }
2666
        ip->misc++;
2667
    }
2668
/*
2669
** Treat the information field as a byte offset
2670
*/
2671
    *fp->offset = xtoi( info );
2672
    INODE_UNLOCK( ip );
2673
 
2674
    return msg_success;
2675
}
2676
 
2677
int smcc669_close( struct FILE *fp )
2678
{
2679
    struct INODE *ip;
2680
 
2681
    ip = fp->ip;
2682
    if ( fp->mode & ATTR$M_WRITE ) {
2683
        INODE_LOCK( ip );
2684
        ip->misc--;
2685
        INODE_UNLOCK( ip );
2686
    }
2687
    return msg_success;
2688
}
2689
 
2690
int smcc669_read( struct FILE *fp, int size, int number, unsigned char *buf )
2691
{
2692
    int i;
2693
    int length;
2694
    int nbytes;
2695
    struct INODE *ip;
2696
 
2697
/*
2698
** Always access a byte at a time
2699
*/
2700
    ip = fp->ip;
2701
    length = size * number;
2702
    nbytes = 0;
2703
 
2704
    SMC37c669_config_mode( TRUE );
2705
    for ( i = 0; i < length; i++ ) {
2706
        if ( !inrange( *fp->offset, 0, ip->len[0] ) )
2707
            break;
2708
        *buf++ = SMC37c669_read_config( *fp->offset );
2709
        *fp->offset += 1;
2710
        nbytes++;
2711
    }
2712
    SMC37c669_config_mode( FALSE );
2713
    return nbytes;
2714
}
2715
 
2716
int smcc669_write( struct FILE *fp, int size, int number, unsigned char *buf )
2717
{
2718
    int i;
2719
    int length;
2720
    int nbytes;
2721
    struct INODE *ip;
2722
/*
2723
** Always access a byte at a time
2724
*/
2725
    ip = fp->ip;
2726
    length = size * number;
2727
    nbytes = 0;
2728
 
2729
    SMC37c669_config_mode( TRUE );
2730
    for ( i = 0; i < length; i++ ) {
2731
        if ( !inrange( *fp->offset, 0, ip->len[0] ) )
2732
            break;
2733
        SMC37c669_write_config( *fp->offset, *buf );
2734
        *fp->offset += 1;
2735
        buf++;
2736
        nbytes++;
2737
    }
2738
    SMC37c669_config_mode( FALSE );
2739
    return nbytes;
2740
}
2741
#endif
2742
 
2743
void
2744
SMC37c669_dump_registers(void)
2745
{
2746
  int i;
2747
  for (i = 0; i <= 0x29; i++)
2748
    printk("-- CR%02x : %02x\n", i, SMC37c669_read_config(i));
2749
}
2750
/*+
2751
 * ============================================================================
2752
 * = SMC_init - SMC37c669 Super I/O controller initialization                 =
2753
 * ============================================================================
2754
 *
2755
 * OVERVIEW:
2756
 *
2757
 *      This routine configures and enables device functions on the
2758
 *      SMC37c669 Super I/O controller.
2759
 *
2760
 * FORM OF CALL:
2761
 *
2762
 *      SMC_init( );
2763
 *
2764
 * RETURNS:
2765
 *
2766
 *      Nothing
2767
 *
2768
 * ARGUMENTS:
2769
 *
2770
 *      None
2771
 *
2772
 * SIDE EFFECTS:
2773
 *
2774
 *      None
2775
 *
2776
-*/
2777
void SMC669_Init ( void )
2778
{
2779
    SMC37c669_CONFIG_REGS *SMC_base;
2780
 
2781
    if ( ( SMC_base = SMC37c669_detect( ) ) != NULL ) {
2782
        printk( "SMC37c669 Super I/O Controller found @ 0x%lx\n",
2783
                (unsigned long) SMC_base );
2784
#if SMC_DEBUG
2785
        SMC37c669_config_mode( TRUE );
2786
        SMC37c669_dump_registers( );
2787
        SMC37c669_config_mode( FALSE );
2788
        SMC37c669_display_device_info( );
2789
#endif
2790
        SMC37c669_disable_device( SERIAL_0 );
2791
        SMC37c669_configure_device(
2792
            SERIAL_0,
2793
            COM1_BASE,
2794
            COM1_IRQ,
2795
            -1
2796
        );
2797
        SMC37c669_enable_device( SERIAL_0 );
2798
 
2799
        SMC37c669_disable_device( SERIAL_1 );
2800
        SMC37c669_configure_device(
2801
            SERIAL_1,
2802
            COM2_BASE,
2803
            COM2_IRQ,
2804
            -1
2805
        );
2806
        SMC37c669_enable_device( SERIAL_1 );
2807
 
2808
        SMC37c669_disable_device( PARALLEL_0 );
2809
        SMC37c669_configure_device(
2810
            PARALLEL_0,
2811
            PARP_BASE,
2812
            PARP_IRQ,
2813
            PARP_DRQ
2814
        );
2815
        SMC37c669_enable_device( PARALLEL_0 );
2816
 
2817
        SMC37c669_disable_device( FLOPPY_0 );
2818
        SMC37c669_configure_device(
2819
            FLOPPY_0,
2820
            FDC_BASE,
2821
            FDC_IRQ,
2822
            FDC_DRQ
2823
        );
2824
        SMC37c669_enable_device( FLOPPY_0 );
2825
 
2826
        SMC37c669_disable_device( IDE_0 );
2827
 
2828
#if SMC_DEBUG
2829
        SMC37c669_config_mode( TRUE );
2830
        SMC37c669_dump_registers( );
2831
        SMC37c669_config_mode( FALSE );
2832
        SMC37c669_display_device_info( );
2833
#endif
2834
    }
2835
    else {
2836
#if SMC_DEBUG
2837
        printk( "No SMC37c669 Super I/O Controller found\n" );
2838
#endif
2839
    }
2840
}
2841
 
2842
#endif /* SX164 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.