// SPDX-License-Identifier: GPL-2.0
/*
 * SMC 37C93X initialization code
 */

#include <linux/kernel.h>

#include <linux/mm.h>
#include <linux/init.h>
#include <linux/delay.h>

#include <asm/hwrpb.h>
#include <asm/io.h>

#include "proto.h"

#define SMC_DEBUG 0

#if SMC_DEBUG
# define DBG_DEVS(args)         printk args
#else
# define DBG_DEVS(args)
#endif

#define KB              1024
#define MB              (1024*KB)
#define GB              (1024*MB)

/* device "activate" register contents */
#define DEVICE_ON		1
#define DEVICE_OFF		0

/* configuration on/off keys */
#define CONFIG_ON_KEY		0x55
#define CONFIG_OFF_KEY		0xaa

/* configuration space device definitions */
#define FDC			0
#define IDE1			1
#define IDE2			2
#define PARP			3
#define SER1			4
#define SER2			5
#define RTCL			6
#define KYBD			7
#define AUXIO			8

/* Chip register offsets from base */
#define CONFIG_CONTROL		0x02
#define INDEX_ADDRESS		0x03
#define LOGICAL_DEVICE_NUMBER	0x07
#define DEVICE_ID		0x20
#define DEVICE_REV		0x21
#define POWER_CONTROL		0x22
#define POWER_MGMT		0x23
#define OSC			0x24

#define ACTIVATE		0x30
#define ADDR_HI			0x60
#define ADDR_LO			0x61
#define INTERRUPT_SEL		0x70
#define INTERRUPT_SEL_2		0x72 /* KYBD/MOUS only */
#define DMA_CHANNEL_SEL		0x74 /* FDC/PARP only */

#define FDD_MODE_REGISTER	0x90
#define FDD_OPTION_REGISTER	0x91

/* values that we read back that are expected ... */
#define VALID_DEVICE_ID		2

/* default device addresses */
#define KYBD_INTERRUPT		1
#define MOUS_INTERRUPT		12
#define COM2_BASE		0x2f8
#define COM2_INTERRUPT		3
#define COM1_BASE		0x3f8
#define COM1_INTERRUPT		4
#define PARP_BASE		0x3bc
#define PARP_INTERRUPT		7

static unsigned long __init SMCConfigState(unsigned long baseAddr)
{
	unsigned char devId;

	unsigned long configPort;
	unsigned long indexPort;
	unsigned long dataPort;

	int i;

	configPort = indexPort = baseAddr;
	dataPort = configPort + 1;

#define NUM_RETRIES 5

	for (i = 0; i < NUM_RETRIES; i++)
	{
		outb(CONFIG_ON_KEY, configPort);
		outb(CONFIG_ON_KEY, configPort);
		outb(DEVICE_ID, indexPort);
		devId = inb(dataPort);
		if (devId == VALID_DEVICE_ID) {
			outb(DEVICE_REV, indexPort);
			/* unsigned char devRev = */ inb(dataPort);
			break;
		}
		else
			udelay(100);
	}
	return (i != NUM_RETRIES) ? baseAddr : 0L;
}

static void __init SMCRunState(unsigned long baseAddr)
{
	outb(CONFIG_OFF_KEY, baseAddr);
}

static unsigned long __init SMCDetectUltraIO(void)
{
	unsigned long baseAddr;

	baseAddr = 0x3F0;
	if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x3F0 ) {
		return( baseAddr );
	}
	baseAddr = 0x370;
	if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x370 ) {
		return( baseAddr );
	}
	return( ( unsigned long )0 );
}

static void __init SMCEnableDevice(unsigned long baseAddr,
			    unsigned long device,
			    unsigned long portaddr,
			    unsigned long interrupt)
{
	unsigned long indexPort;
	unsigned long dataPort;

	indexPort = baseAddr;
	dataPort = baseAddr + 1;

	outb(LOGICAL_DEVICE_NUMBER, indexPort);
	outb(device, dataPort);

	outb(ADDR_LO, indexPort);
	outb(( portaddr & 0xFF ), dataPort);

	outb(ADDR_HI, indexPort);
	outb((portaddr >> 8) & 0xFF, dataPort);

	outb(INTERRUPT_SEL, indexPort);
	outb(interrupt, dataPort);

	outb(ACTIVATE, indexPort);
	outb(DEVICE_ON, dataPort);
}

static void __init SMCEnableKYBD(unsigned long baseAddr)
{
	unsigned long indexPort;
	unsigned long dataPort;

	indexPort = baseAddr;
	dataPort = baseAddr + 1;

	outb(LOGICAL_DEVICE_NUMBER, indexPort);
	outb(KYBD, dataPort);

	outb(INTERRUPT_SEL, indexPort); /* Primary interrupt select */
	outb(KYBD_INTERRUPT, dataPort);

	outb(INTERRUPT_SEL_2, indexPort); /* Secondary interrupt select */
	outb(MOUS_INTERRUPT, dataPort);

	outb(ACTIVATE, indexPort);
	outb(DEVICE_ON, dataPort);
}

static void __init SMCEnableFDC(unsigned long baseAddr)
{
	unsigned long indexPort;
	unsigned long dataPort;

	unsigned char oldValue;

	indexPort = baseAddr;
	dataPort = baseAddr + 1;

	outb(LOGICAL_DEVICE_NUMBER, indexPort);
	outb(FDC, dataPort);

	outb(FDD_MODE_REGISTER, indexPort);
	oldValue = inb(dataPort);

	oldValue |= 0x0E;                   /* Enable burst mode */
	outb(oldValue, dataPort);

	outb(INTERRUPT_SEL, indexPort);	    /* Primary interrupt select */
	outb(0x06, dataPort );

	outb(DMA_CHANNEL_SEL, indexPort);   /* DMA channel select */
	outb(0x02, dataPort);

	outb(ACTIVATE, indexPort);
	outb(DEVICE_ON, dataPort);
}

#if SMC_DEBUG
static void __init SMCReportDeviceStatus(unsigned long baseAddr)
{
	unsigned long indexPort;
	unsigned long dataPort;
	unsigned char currentControl;

	indexPort = baseAddr;
	dataPort = baseAddr + 1;

	outb(POWER_CONTROL, indexPort);
	currentControl = inb(dataPort);

	printk(currentControl & (1 << FDC)
	       ? "\t+FDC Enabled\n" : "\t-FDC Disabled\n");
	printk(currentControl & (1 << IDE1)
	       ? "\t+IDE1 Enabled\n" : "\t-IDE1 Disabled\n");
	printk(currentControl & (1 << IDE2)
	       ? "\t+IDE2 Enabled\n" : "\t-IDE2 Disabled\n");
	printk(currentControl & (1 << PARP)
	       ? "\t+PARP Enabled\n" : "\t-PARP Disabled\n");
	printk(currentControl & (1 << SER1)
	       ? "\t+SER1 Enabled\n" : "\t-SER1 Disabled\n");
	printk(currentControl & (1 << SER2)
	       ? "\t+SER2 Enabled\n" : "\t-SER2 Disabled\n");

	printk( "\n" );
}
#endif

int __init SMC93x_Init(void)
{
	unsigned long SMCUltraBase;
	unsigned long flags;

	local_irq_save(flags);
	if ((SMCUltraBase = SMCDetectUltraIO()) != 0UL) {
#if SMC_DEBUG
		SMCReportDeviceStatus(SMCUltraBase);
#endif
		SMCEnableDevice(SMCUltraBase, SER1, COM1_BASE, COM1_INTERRUPT);
		DBG_DEVS(("SMC FDC37C93X: SER1 done\n"));
		SMCEnableDevice(SMCUltraBase, SER2, COM2_BASE, COM2_INTERRUPT);
		DBG_DEVS(("SMC FDC37C93X: SER2 done\n"));
		SMCEnableDevice(SMCUltraBase, PARP, PARP_BASE, PARP_INTERRUPT);
		DBG_DEVS(("SMC FDC37C93X: PARP done\n"));
		/* On PC164, IDE on the SMC is not enabled;
		   CMD646 (PCI) on MB */
		SMCEnableKYBD(SMCUltraBase);
		DBG_DEVS(("SMC FDC37C93X: KYB done\n"));
		SMCEnableFDC(SMCUltraBase);
		DBG_DEVS(("SMC FDC37C93X: FDC done\n"));
#if SMC_DEBUG
		SMCReportDeviceStatus(SMCUltraBase);
#endif
		SMCRunState(SMCUltraBase);
		local_irq_restore(flags);
		printk("SMC FDC37C93X Ultra I/O Controller found @ 0x%lx\n",
		       SMCUltraBase);
		return 1;
	}
	else {
		local_irq_restore(flags);
		DBG_DEVS(("No SMC FDC37C93X Ultra I/O Controller found\n"));
		return 0;
	}
}
