File Index
Files and directories
Sign in
FILE

smc37c93x.c

File preview with syntax highlighting.

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