// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2000  Frodo Looijaard <frodol@dds.nl>,
 *                      Philip Edelbrock <phil@netroedge.com>,
 *                      Mark D. Studebaker <mdsxyz123@yahoo.com>,
 *                      Dan Eaton <dan.eaton@rocketlogix.com> and
 *                      Stephen Rousset <stephen.rousset@rocketlogix.com>
*/

/*
    This is the driver for the SMB Host controller on
    Acer Labs Inc. (ALI) M1535 South Bridge.

    The M1535 is a South bridge for portable systems.
    It is very similar to the M15x3 South bridges also produced
    by Acer Labs Inc.  Some of the registers within the part
    have moved and some have been redefined slightly. Additionally,
    the sequencing of the SMBus transactions has been modified
    to be more consistent with the sequencing recommended by
    the manufacturer and observed through testing.  These
    changes are reflected in this driver and can be identified
    by comparing this driver to the i2c-ali15x3 driver.
    For an overview of these chips see http://www.acerlabs.com

    The SMB controller is part of the 7101 device, which is an
    ACPI-compliant Power Management Unit (PMU).

    The whole 7101 device has to be enabled for the SMB to work.
    You can't just enable the SMB alone.
    The SMB and the ACPI have separate I/O spaces.
    We make sure that the SMB is enabled. We leave the ACPI alone.

    This driver controls the SMB Host only.

    This driver does not use interrupts.
*/


/* Note: we assume there can only be one ALI1535, with one SMBus interface */

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/i2c.h>
#include <linux/acpi.h>
#include <linux/io.h>


/* ALI1535 SMBus address offsets */
#define SMBHSTSTS	(0 + ali1535_smba)
#define SMBHSTTYP	(1 + ali1535_smba)
#define SMBHSTPORT	(2 + ali1535_smba)
#define SMBHSTCMD	(7 + ali1535_smba)
#define SMBHSTADD	(3 + ali1535_smba)
#define SMBHSTDAT0	(4 + ali1535_smba)
#define SMBHSTDAT1	(5 + ali1535_smba)
#define SMBBLKDAT	(6 + ali1535_smba)

/* PCI Address Constants */
#define SMBCOM		0x004
#define SMBREV		0x008
#define SMBCFG		0x0D1
#define SMBBA		0x0E2
#define SMBHSTCFG	0x0F0
#define SMBCLK		0x0F2

/* Other settings */
#define MAX_TIMEOUT		500	/* times 1/100 sec */
#define ALI1535_SMB_IOSIZE	32

#define ALI1535_SMB_DEFAULTBASE	0x8040

/* ALI1535 address lock bits */
#define ALI1535_LOCK		0x06	/* dwe */

/* ALI1535 command constants */
#define ALI1535_QUICK		0x00
#define ALI1535_BYTE		0x10
#define ALI1535_BYTE_DATA	0x20
#define ALI1535_WORD_DATA	0x30
#define ALI1535_BLOCK_DATA	0x40
#define ALI1535_I2C_READ	0x60

#define	ALI1535_DEV10B_EN	0x80	/* Enable 10-bit addressing in	*/
					/*  I2C read			*/
#define	ALI1535_T_OUT		0x08	/* Time-out Command (write)	*/
#define	ALI1535_A_HIGH_BIT9	0x08	/* Bit 9 of 10-bit address in	*/
					/* Alert-Response-Address	*/
					/* (read)			*/
#define	ALI1535_KILL		0x04	/* Kill Command (write)		*/
#define	ALI1535_A_HIGH_BIT8	0x04	/* Bit 8 of 10-bit address in	*/
					/*  Alert-Response-Address	*/
					/*  (read)			*/

#define	ALI1535_D_HI_MASK	0x03	/* Mask for isolating bits 9-8	*/
					/*  of 10-bit address in I2C	*/
					/*  Read Command		*/

/* ALI1535 status register bits */
#define ALI1535_STS_IDLE	0x04
#define ALI1535_STS_BUSY	0x08	/* host busy */
#define ALI1535_STS_DONE	0x10	/* transaction complete */
#define ALI1535_STS_DEV		0x20	/* device error */
#define ALI1535_STS_BUSERR	0x40	/* bus error    */
#define ALI1535_STS_FAIL	0x80	/* failed bus transaction */
#define ALI1535_STS_ERR		0xE0	/* all the bad error bits */

#define ALI1535_BLOCK_CLR	0x04	/* reset block data index */

/* ALI1535 device address register bits */
#define	ALI1535_RD_ADDR		0x01	/* Read/Write Bit in Device	*/
					/*  Address field		*/
					/*  -> Write = 0		*/
					/*  -> Read  = 1		*/
#define	ALI1535_SMBIO_EN	0x04	/* SMB I/O Space enable		*/

static struct pci_driver ali1535_driver;
static unsigned long ali1535_smba;
static unsigned short ali1535_offset;

/* Detect whether a ALI1535 can be found, and initialize it, where necessary.
   Note the differences between kernels with the old PCI BIOS interface and
   newer kernels with the real PCI interface. In compat.h some things are
   defined to make the transition easier. */
static int ali1535_setup(struct pci_dev *dev)
{
	int retval;
	unsigned char temp;

	/* Check the following things:
		- SMB I/O address is initialized
		- Device is enabled
		- We can use the addresses
	*/

	retval = pci_enable_device(dev);
	if (retval) {
		dev_err(&dev->dev, "ALI1535_smb can't enable device\n");
		goto exit;
	}

	/* Determine the address of the SMBus area */
	pci_read_config_word(dev, SMBBA, &ali1535_offset);
	dev_dbg(&dev->dev, "ALI1535_smb is at offset 0x%04x\n", ali1535_offset);
	ali1535_offset &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1));
	if (ali1535_offset == 0) {
		dev_warn(&dev->dev,
			"ALI1535_smb region uninitialized - upgrade BIOS?\n");
		retval = -ENODEV;
		goto exit;
	}

	if (pci_resource_flags(dev, 0) & IORESOURCE_IO)
		ali1535_smba = pci_resource_start(dev, 0) + ali1535_offset;
	else
		ali1535_smba = ali1535_offset;

	retval = acpi_check_region(ali1535_smba, ALI1535_SMB_IOSIZE,
				   ali1535_driver.name);
	if (retval)
		goto exit;

	if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE,
			    ali1535_driver.name)) {
		dev_err(&dev->dev, "ALI1535_smb region 0x%lx already in use!\n",
			ali1535_smba);
		retval = -EBUSY;
		goto exit;
	}

	/* check if whole device is enabled */
	pci_read_config_byte(dev, SMBCFG, &temp);
	if ((temp & ALI1535_SMBIO_EN) == 0) {
		dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n");
		retval = -ENODEV;
		goto exit_free;
	}

	/* Is SMB Host controller enabled? */
	pci_read_config_byte(dev, SMBHSTCFG, &temp);
	if ((temp & 1) == 0) {
		dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n");
		retval = -ENODEV;
		goto exit_free;
	}

	/* set SMB clock to 74KHz as recommended in data sheet */
	pci_write_config_byte(dev, SMBCLK, 0x20);

	/*
	  The interrupt routing for SMB is set up in register 0x77 in the
	  1533 ISA Bridge device, NOT in the 7101 device.
	  Don't bother with finding the 1533 device and reading the register.
	if ((....... & 0x0F) == 1)
		dev_dbg(&dev->dev, "ALI1535 using Interrupt 9 for SMBus.\n");
	*/
	pci_read_config_byte(dev, SMBREV, &temp);
	dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
	dev_dbg(&dev->dev, "ALI1535_smba = 0x%lx\n", ali1535_smba);

	return 0;

exit_free:
	release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
exit:
	return retval;
}

static int ali1535_transaction(struct i2c_adapter *adap)
{
	int temp;
	int result = 0;
	int timeout = 0;

	dev_dbg(&adap->dev, "Transaction (pre): STS=%02x, TYP=%02x, "
		"CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
		inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
		inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));

	/* get status */
	temp = inb_p(SMBHSTSTS);

	/* Make sure the SMBus host is ready to start transmitting */
	/* Check the busy bit first */
	if (temp & ALI1535_STS_BUSY) {
		/* If the host controller is still busy, it may have timed out
		 * in the previous transaction, resulting in a "SMBus Timeout"
		 * printk.  I've tried the following to reset a stuck busy bit.
		 *   1. Reset the controller with an KILL command. (this
		 *      doesn't seem to clear the controller if an external
		 *      device is hung)
		 *   2. Reset the controller and the other SMBus devices with a
		 *      T_OUT command. (this clears the host busy bit if an
		 *      external device is hung, but it comes back upon a new
		 *      access to a device)
		 *   3. Disable and reenable the controller in SMBHSTCFG. Worst
		 *      case, nothing seems to work except power reset.
		 */

		/* Try resetting entire SMB bus, including other devices - This
		 * may not work either - it clears the BUSY bit but then the
		 * BUSY bit may come back on when you try and use the chip
		 * again.  If that's the case you are stuck.
		 */
		dev_info(&adap->dev,
			"Resetting entire SMB Bus to clear busy condition (%02x)\n",
			temp);
		outb_p(ALI1535_T_OUT, SMBHSTTYP);
		temp = inb_p(SMBHSTSTS);
	}

	/* now check the error bits and the busy bit */
	if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
		/* do a clear-on-write */
		outb_p(0xFF, SMBHSTSTS);
		temp = inb_p(SMBHSTSTS);
		if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
			/* This is probably going to be correctable only by a
			 * power reset as one of the bits now appears to be
			 * stuck */
			/* This may be a bus or device with electrical problems. */
			dev_err(&adap->dev,
				"SMBus reset failed! (0x%02x) - controller or "
				"device on bus is probably hung\n", temp);
			return -EBUSY;
		}
	} else {
		/* check and clear done bit */
		if (temp & ALI1535_STS_DONE)
			outb_p(temp, SMBHSTSTS);
	}

	/* start the transaction by writing anything to the start register */
	outb_p(0xFF, SMBHSTPORT);

	/* We will always wait for a fraction of a second! */
	timeout = 0;
	do {
		usleep_range(1000, 2000);
		temp = inb_p(SMBHSTSTS);
	} while (((temp & ALI1535_STS_BUSY) && !(temp & ALI1535_STS_IDLE))
		 && (timeout++ < MAX_TIMEOUT));

	/* If the SMBus is still busy, we give up */
	if (timeout > MAX_TIMEOUT)
		result = -ETIMEDOUT;

	if (temp & ALI1535_STS_FAIL) {
		result = -EIO;
		dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
	}

	/* Unfortunately the ALI SMB controller maps "no response" and "bus
	 * collision" into a single bit. No response is the usual case so don't
	 * do a printk.  This means that bus collisions go unreported.
	 */
	if (temp & ALI1535_STS_BUSERR) {
		result = -ENXIO;
		dev_dbg(&adap->dev,
			"Error: no response or bus collision ADD=%02x\n",
			inb_p(SMBHSTADD));
	}

	/* haven't ever seen this */
	if (temp & ALI1535_STS_DEV) {
		result = -EIO;
		dev_err(&adap->dev, "Error: device error\n");
	}

	/* check to see if the "command complete" indication is set */
	if (!(temp & ALI1535_STS_DONE))
		result = -ETIMEDOUT;

	dev_dbg(&adap->dev, "Transaction (post): STS=%02x, TYP=%02x, "
		"CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
		inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
		inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));

	/* take consequent actions for error conditions */
	if (!(temp & ALI1535_STS_DONE)) {
		/* issue "kill" to reset host controller */
		outb_p(ALI1535_KILL, SMBHSTTYP);
		outb_p(0xFF, SMBHSTSTS);
	} else if (temp & ALI1535_STS_ERR) {
		/* issue "timeout" to reset all devices on bus */
		outb_p(ALI1535_T_OUT, SMBHSTTYP);
		outb_p(0xFF, SMBHSTSTS);
	}

	return result;
}

/* Return negative errno on error. */
static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
			  unsigned short flags, char read_write, u8 command,
			  int size, union i2c_smbus_data *data)
{
	int i, len;
	int temp;
	int timeout;
	s32 result = 0;

	/* make sure SMBus is idle */
	temp = inb_p(SMBHSTSTS);
	for (timeout = 0;
	     (timeout < MAX_TIMEOUT) && !(temp & ALI1535_STS_IDLE);
	     timeout++) {
		usleep_range(1000, 2000);
		temp = inb_p(SMBHSTSTS);
	}
	if (timeout >= MAX_TIMEOUT)
		dev_warn(&adap->dev, "Idle wait Timeout! STS=0x%02x\n", temp);

	/* clear status register (clear-on-write) */
	outb_p(0xFF, SMBHSTSTS);

	switch (size) {
	case I2C_SMBUS_QUICK:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		size = ALI1535_QUICK;
		outb_p(size, SMBHSTTYP);	/* output command */
		break;
	case I2C_SMBUS_BYTE:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		size = ALI1535_BYTE;
		outb_p(size, SMBHSTTYP);	/* output command */
		if (read_write == I2C_SMBUS_WRITE)
			outb_p(command, SMBHSTCMD);
		break;
	case I2C_SMBUS_BYTE_DATA:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		size = ALI1535_BYTE_DATA;
		outb_p(size, SMBHSTTYP);	/* output command */
		outb_p(command, SMBHSTCMD);
		if (read_write == I2C_SMBUS_WRITE)
			outb_p(data->byte, SMBHSTDAT0);
		break;
	case I2C_SMBUS_WORD_DATA:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		size = ALI1535_WORD_DATA;
		outb_p(size, SMBHSTTYP);	/* output command */
		outb_p(command, SMBHSTCMD);
		if (read_write == I2C_SMBUS_WRITE) {
			outb_p(data->word & 0xff, SMBHSTDAT0);
			outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
		}
		break;
	case I2C_SMBUS_BLOCK_DATA:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		size = ALI1535_BLOCK_DATA;
		outb_p(size, SMBHSTTYP);	/* output command */
		outb_p(command, SMBHSTCMD);
		if (read_write == I2C_SMBUS_WRITE) {
			len = data->block[0];
			if (len < 0) {
				len = 0;
				data->block[0] = len;
			}
			if (len > 32) {
				len = 32;
				data->block[0] = len;
			}
			outb_p(len, SMBHSTDAT0);
			/* Reset SMBBLKDAT */
			outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
			for (i = 1; i <= len; i++)
				outb_p(data->block[i], SMBBLKDAT);
		}
		break;
	default:
		dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
		result = -EOPNOTSUPP;
		goto EXIT;
	}

	result = ali1535_transaction(adap);
	if (result)
		goto EXIT;

	if ((read_write == I2C_SMBUS_WRITE) || (size == ALI1535_QUICK)) {
		result = 0;
		goto EXIT;
	}

	switch (size) {
	case ALI1535_BYTE:	/* Result put in SMBHSTDAT0 */
		data->byte = inb_p(SMBHSTDAT0);
		break;
	case ALI1535_BYTE_DATA:
		data->byte = inb_p(SMBHSTDAT0);
		break;
	case ALI1535_WORD_DATA:
		data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
		break;
	case ALI1535_BLOCK_DATA:
		len = inb_p(SMBHSTDAT0);
		if (len > 32)
			len = 32;
		data->block[0] = len;
		/* Reset SMBBLKDAT */
		outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
		for (i = 1; i <= data->block[0]; i++) {
			data->block[i] = inb_p(SMBBLKDAT);
			dev_dbg(&adap->dev, "Blk: len=%d, i=%d, data=%02x\n",
				len, i, data->block[i]);
		}
		break;
	}
EXIT:
	return result;
}


static u32 ali1535_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
	    I2C_FUNC_SMBUS_BLOCK_DATA;
}

static const struct i2c_algorithm smbus_algorithm = {
	.smbus_xfer	= ali1535_access,
	.functionality	= ali1535_func,
};

static struct i2c_adapter ali1535_adapter = {
	.owner		= THIS_MODULE,
	.class          = I2C_CLASS_HWMON,
	.algo		= &smbus_algorithm,
};

static const struct pci_device_id ali1535_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
	{ }
};
MODULE_DEVICE_TABLE(pci, ali1535_ids);

static int ali1535_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	if (ali1535_setup(dev)) {
		dev_warn(&dev->dev,
			"ALI1535 not detected, module not inserted.\n");
		return -ENODEV;
	}

	/* set up the sysfs linkage to our parent device */
	ali1535_adapter.dev.parent = &dev->dev;

	snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name),
		"SMBus ALI1535 adapter at %04x", ali1535_offset);
	return i2c_add_adapter(&ali1535_adapter);
}

static void ali1535_remove(struct pci_dev *dev)
{
	i2c_del_adapter(&ali1535_adapter);
	release_region(ali1535_smba, ALI1535_SMB_IOSIZE);

	/*
	 * do not call pci_disable_device(dev) since it can cause hard hangs on
	 * some systems during power-off
	 */
}

static struct pci_driver ali1535_driver = {
	.name		= "ali1535_smbus",
	.id_table	= ali1535_ids,
	.probe		= ali1535_probe,
	.remove		= ali1535_remove,
};

module_pci_driver(ali1535_driver);

MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
MODULE_AUTHOR("Philip Edelbrock <phil@netroedge.com>");
MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
MODULE_AUTHOR("Dan Eaton <dan.eaton@rocketlogix.com>");
MODULE_DESCRIPTION("ALI1535 SMBus driver");
MODULE_LICENSE("GPL");
