root/arch/alpha/kernel/smc37c93x.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. SMCConfigState
  2. SMCRunState
  3. SMCDetectUltraIO
  4. SMCEnableDevice
  5. SMCEnableKYBD
  6. SMCEnableFDC
  7. SMCReportDeviceStatus
  8. SMC93x_Init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * SMC 37C93X initialization code
   4  */
   5 
   6 #include <linux/kernel.h>
   7 
   8 #include <linux/mm.h>
   9 #include <linux/init.h>
  10 #include <linux/delay.h>
  11 
  12 #include <asm/hwrpb.h>
  13 #include <asm/io.h>
  14 
  15 #define SMC_DEBUG 0
  16 
  17 #if SMC_DEBUG
  18 # define DBG_DEVS(args)         printk args
  19 #else
  20 # define DBG_DEVS(args)
  21 #endif
  22 
  23 #define KB              1024
  24 #define MB              (1024*KB)
  25 #define GB              (1024*MB)
  26 
  27 /* device "activate" register contents */
  28 #define DEVICE_ON               1
  29 #define DEVICE_OFF              0
  30 
  31 /* configuration on/off keys */
  32 #define CONFIG_ON_KEY           0x55
  33 #define CONFIG_OFF_KEY          0xaa
  34 
  35 /* configuration space device definitions */
  36 #define FDC                     0
  37 #define IDE1                    1
  38 #define IDE2                    2
  39 #define PARP                    3
  40 #define SER1                    4
  41 #define SER2                    5
  42 #define RTCL                    6
  43 #define KYBD                    7
  44 #define AUXIO                   8
  45 
  46 /* Chip register offsets from base */
  47 #define CONFIG_CONTROL          0x02
  48 #define INDEX_ADDRESS           0x03
  49 #define LOGICAL_DEVICE_NUMBER   0x07
  50 #define DEVICE_ID               0x20
  51 #define DEVICE_REV              0x21
  52 #define POWER_CONTROL           0x22
  53 #define POWER_MGMT              0x23
  54 #define OSC                     0x24
  55 
  56 #define ACTIVATE                0x30
  57 #define ADDR_HI                 0x60
  58 #define ADDR_LO                 0x61
  59 #define INTERRUPT_SEL           0x70
  60 #define INTERRUPT_SEL_2         0x72 /* KYBD/MOUS only */
  61 #define DMA_CHANNEL_SEL         0x74 /* FDC/PARP only */
  62 
  63 #define FDD_MODE_REGISTER       0x90
  64 #define FDD_OPTION_REGISTER     0x91
  65 
  66 /* values that we read back that are expected ... */
  67 #define VALID_DEVICE_ID         2
  68 
  69 /* default device addresses */
  70 #define KYBD_INTERRUPT          1
  71 #define MOUS_INTERRUPT          12
  72 #define COM2_BASE               0x2f8
  73 #define COM2_INTERRUPT          3
  74 #define COM1_BASE               0x3f8
  75 #define COM1_INTERRUPT          4
  76 #define PARP_BASE               0x3bc
  77 #define PARP_INTERRUPT          7
  78 
  79 static unsigned long __init SMCConfigState(unsigned long baseAddr)
  80 {
  81         unsigned char devId;
  82 
  83         unsigned long configPort;
  84         unsigned long indexPort;
  85         unsigned long dataPort;
  86 
  87         int i;
  88 
  89         configPort = indexPort = baseAddr;
  90         dataPort = configPort + 1;
  91 
  92 #define NUM_RETRIES 5
  93 
  94         for (i = 0; i < NUM_RETRIES; i++)
  95         {
  96                 outb(CONFIG_ON_KEY, configPort);
  97                 outb(CONFIG_ON_KEY, configPort);
  98                 outb(DEVICE_ID, indexPort);
  99                 devId = inb(dataPort);
 100                 if (devId == VALID_DEVICE_ID) {
 101                         outb(DEVICE_REV, indexPort);
 102                         /* unsigned char devRev = */ inb(dataPort);
 103                         break;
 104                 }
 105                 else
 106                         udelay(100);
 107         }
 108         return (i != NUM_RETRIES) ? baseAddr : 0L;
 109 }
 110 
 111 static void __init SMCRunState(unsigned long baseAddr)
 112 {
 113         outb(CONFIG_OFF_KEY, baseAddr);
 114 }
 115 
 116 static unsigned long __init SMCDetectUltraIO(void)
 117 {
 118         unsigned long baseAddr;
 119 
 120         baseAddr = 0x3F0;
 121         if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x3F0 ) {
 122                 return( baseAddr );
 123         }
 124         baseAddr = 0x370;
 125         if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x370 ) {
 126                 return( baseAddr );
 127         }
 128         return( ( unsigned long )0 );
 129 }
 130 
 131 static void __init SMCEnableDevice(unsigned long baseAddr,
 132                             unsigned long device,
 133                             unsigned long portaddr,
 134                             unsigned long interrupt)
 135 {
 136         unsigned long indexPort;
 137         unsigned long dataPort;
 138 
 139         indexPort = baseAddr;
 140         dataPort = baseAddr + 1;
 141 
 142         outb(LOGICAL_DEVICE_NUMBER, indexPort);
 143         outb(device, dataPort);
 144 
 145         outb(ADDR_LO, indexPort);
 146         outb(( portaddr & 0xFF ), dataPort);
 147 
 148         outb(ADDR_HI, indexPort);
 149         outb((portaddr >> 8) & 0xFF, dataPort);
 150 
 151         outb(INTERRUPT_SEL, indexPort);
 152         outb(interrupt, dataPort);
 153 
 154         outb(ACTIVATE, indexPort);
 155         outb(DEVICE_ON, dataPort);
 156 }
 157 
 158 static void __init SMCEnableKYBD(unsigned long baseAddr)
 159 {
 160         unsigned long indexPort;
 161         unsigned long dataPort;
 162 
 163         indexPort = baseAddr;
 164         dataPort = baseAddr + 1;
 165 
 166         outb(LOGICAL_DEVICE_NUMBER, indexPort);
 167         outb(KYBD, dataPort);
 168 
 169         outb(INTERRUPT_SEL, indexPort); /* Primary interrupt select */
 170         outb(KYBD_INTERRUPT, dataPort);
 171 
 172         outb(INTERRUPT_SEL_2, indexPort); /* Secondary interrupt select */
 173         outb(MOUS_INTERRUPT, dataPort);
 174 
 175         outb(ACTIVATE, indexPort);
 176         outb(DEVICE_ON, dataPort);
 177 }
 178 
 179 static void __init SMCEnableFDC(unsigned long baseAddr)
 180 {
 181         unsigned long indexPort;
 182         unsigned long dataPort;
 183 
 184         unsigned char oldValue;
 185 
 186         indexPort = baseAddr;
 187         dataPort = baseAddr + 1;
 188 
 189         outb(LOGICAL_DEVICE_NUMBER, indexPort);
 190         outb(FDC, dataPort);
 191 
 192         outb(FDD_MODE_REGISTER, indexPort);
 193         oldValue = inb(dataPort);
 194 
 195         oldValue |= 0x0E;                   /* Enable burst mode */
 196         outb(oldValue, dataPort);
 197 
 198         outb(INTERRUPT_SEL, indexPort);     /* Primary interrupt select */
 199         outb(0x06, dataPort );
 200 
 201         outb(DMA_CHANNEL_SEL, indexPort);   /* DMA channel select */
 202         outb(0x02, dataPort);
 203 
 204         outb(ACTIVATE, indexPort);
 205         outb(DEVICE_ON, dataPort);
 206 }
 207 
 208 #if SMC_DEBUG
 209 static void __init SMCReportDeviceStatus(unsigned long baseAddr)
 210 {
 211         unsigned long indexPort;
 212         unsigned long dataPort;
 213         unsigned char currentControl;
 214 
 215         indexPort = baseAddr;
 216         dataPort = baseAddr + 1;
 217 
 218         outb(POWER_CONTROL, indexPort);
 219         currentControl = inb(dataPort);
 220 
 221         printk(currentControl & (1 << FDC)
 222                ? "\t+FDC Enabled\n" : "\t-FDC Disabled\n");
 223         printk(currentControl & (1 << IDE1)
 224                ? "\t+IDE1 Enabled\n" : "\t-IDE1 Disabled\n");
 225         printk(currentControl & (1 << IDE2)
 226                ? "\t+IDE2 Enabled\n" : "\t-IDE2 Disabled\n");
 227         printk(currentControl & (1 << PARP)
 228                ? "\t+PARP Enabled\n" : "\t-PARP Disabled\n");
 229         printk(currentControl & (1 << SER1)
 230                ? "\t+SER1 Enabled\n" : "\t-SER1 Disabled\n");
 231         printk(currentControl & (1 << SER2)
 232                ? "\t+SER2 Enabled\n" : "\t-SER2 Disabled\n");
 233 
 234         printk( "\n" );
 235 }
 236 #endif
 237 
 238 int __init SMC93x_Init(void)
 239 {
 240         unsigned long SMCUltraBase;
 241         unsigned long flags;
 242 
 243         local_irq_save(flags);
 244         if ((SMCUltraBase = SMCDetectUltraIO()) != 0UL) {
 245 #if SMC_DEBUG
 246                 SMCReportDeviceStatus(SMCUltraBase);
 247 #endif
 248                 SMCEnableDevice(SMCUltraBase, SER1, COM1_BASE, COM1_INTERRUPT);
 249                 DBG_DEVS(("SMC FDC37C93X: SER1 done\n"));
 250                 SMCEnableDevice(SMCUltraBase, SER2, COM2_BASE, COM2_INTERRUPT);
 251                 DBG_DEVS(("SMC FDC37C93X: SER2 done\n"));
 252                 SMCEnableDevice(SMCUltraBase, PARP, PARP_BASE, PARP_INTERRUPT);
 253                 DBG_DEVS(("SMC FDC37C93X: PARP done\n"));
 254                 /* On PC164, IDE on the SMC is not enabled;
 255                    CMD646 (PCI) on MB */
 256                 SMCEnableKYBD(SMCUltraBase);
 257                 DBG_DEVS(("SMC FDC37C93X: KYB done\n"));
 258                 SMCEnableFDC(SMCUltraBase);
 259                 DBG_DEVS(("SMC FDC37C93X: FDC done\n"));
 260 #if SMC_DEBUG
 261                 SMCReportDeviceStatus(SMCUltraBase);
 262 #endif
 263                 SMCRunState(SMCUltraBase);
 264                 local_irq_restore(flags);
 265                 printk("SMC FDC37C93X Ultra I/O Controller found @ 0x%lx\n",
 266                        SMCUltraBase);
 267                 return 1;
 268         }
 269         else {
 270                 local_irq_restore(flags);
 271                 DBG_DEVS(("No SMC FDC37C93X Ultra I/O Controller found\n"));
 272                 return 0;
 273         }
 274 }

/* [<][>][^][v][top][bottom][index][help] */