/*
 *  GPIO interface for IT8761E Super I/O chip
 *
 *  Author: Denis Turischev <denis@compulab.co.il>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License 2 as published
 *  by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/ioport.h>

#include <linux/gpio.h>

#define SIO_CHIP_ID		0x8761
#define CHIP_ID_HIGH_BYTE	0x20
#define CHIP_ID_LOW_BYTE	0x21

static u8 ports[2] = { 0x2e, 0x4e };
static u8 port;

static DEFINE_SPINLOCK(sio_lock);

#define GPIO_NAME		"it8761-gpio"
#define GPIO_BA_HIGH_BYTE	0x60
#define GPIO_BA_LOW_BYTE	0x61
#define GPIO_IOSIZE		4
#define GPIO1X_IO		0xf0
#define GPIO2X_IO		0xf1

static u16 gpio_ba;

static u8 read_reg(u8 addr, u8 port)
{
	outb(addr, port);
	return inb(port + 1);
}

static void write_reg(u8 data, u8 addr, u8 port)
{
	outb(addr, port);
	outb(data, port + 1);
}

static void enter_conf_mode(u8 port)
{
	outb(0x87, port);
	outb(0x61, port);
	outb(0x55, port);
	outb((port == 0x2e) ? 0x55 : 0xaa, port);
}

static void exit_conf_mode(u8 port)
{
	outb(0x2, port);
	outb(0x2, port + 1);
}

static void enter_gpio_mode(u8 port)
{
	write_reg(0x2, 0x7, port);
}

static int it8761e_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
{
	u16 reg;
	u8 bit;

	bit = gpio_num % 8;
	reg = (gpio_num >= 8) ? gpio_ba + 1 : gpio_ba;

	return !!(inb(reg) & (1 << bit));
}

static int it8761e_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
{
	u8 curr_dirs;
	u8 io_reg, bit;

	bit = gpio_num % 8;
	io_reg = (gpio_num >= 8) ? GPIO2X_IO : GPIO1X_IO;

	spin_lock(&sio_lock);

	enter_conf_mode(port);
	enter_gpio_mode(port);

	curr_dirs = read_reg(io_reg, port);

	if (curr_dirs & (1 << bit))
		write_reg(curr_dirs & ~(1 << bit), io_reg, port);

	exit_conf_mode(port);

	spin_unlock(&sio_lock);
	return 0;
}

static void it8761e_gpio_set(struct gpio_chip *gc,
				unsigned gpio_num, int val)
{
	u8 curr_vals, bit;
	u16 reg;

	bit = gpio_num % 8;
	reg = (gpio_num >= 8) ? gpio_ba + 1 : gpio_ba;

	spin_lock(&sio_lock);

	curr_vals = inb(reg);
	if (val)
		outb(curr_vals | (1 << bit) , reg);
	else
		outb(curr_vals & ~(1 << bit), reg);

	spin_unlock(&sio_lock);
}

static int it8761e_gpio_direction_out(struct gpio_chip *gc,
					unsigned gpio_num, int val)
{
	u8 curr_dirs, io_reg, bit;

	bit = gpio_num % 8;
	io_reg = (gpio_num >= 8) ? GPIO2X_IO : GPIO1X_IO;

	it8761e_gpio_set(gc, gpio_num, val);

	spin_lock(&sio_lock);

	enter_conf_mode(port);
	enter_gpio_mode(port);

	curr_dirs = read_reg(io_reg, port);

	if (!(curr_dirs & (1 << bit)))
		write_reg(curr_dirs | (1 << bit), io_reg, port);

	exit_conf_mode(port);

	spin_unlock(&sio_lock);
	return 0;
}

static struct gpio_chip it8761e_gpio_chip = {
	.label			= GPIO_NAME,
	.owner			= THIS_MODULE,
	.get			= it8761e_gpio_get,
	.direction_input	= it8761e_gpio_direction_in,
	.set			= it8761e_gpio_set,
	.direction_output	= it8761e_gpio_direction_out,
};

static int __init it8761e_gpio_init(void)
{
	int i, id, err;

	/* chip and port detection */
	for (i = 0; i < ARRAY_SIZE(ports); i++) {
		spin_lock(&sio_lock);
		enter_conf_mode(ports[i]);

		id = (read_reg(CHIP_ID_HIGH_BYTE, ports[i]) << 8) +
				read_reg(CHIP_ID_LOW_BYTE, ports[i]);

		exit_conf_mode(ports[i]);
		spin_unlock(&sio_lock);

		if (id == SIO_CHIP_ID) {
			port = ports[i];
			break;
		}
	}

	if (!port)
		return -ENODEV;

	/* fetch GPIO base address */
	enter_conf_mode(port);
	enter_gpio_mode(port);
	gpio_ba = (read_reg(GPIO_BA_HIGH_BYTE, port) << 8) +
				read_reg(GPIO_BA_LOW_BYTE, port);
	exit_conf_mode(port);

	if (!request_region(gpio_ba, GPIO_IOSIZE, GPIO_NAME))
		return -EBUSY;

	it8761e_gpio_chip.base = -1;
	it8761e_gpio_chip.ngpio = 16;

	err = gpiochip_add(&it8761e_gpio_chip);
	if (err < 0)
		goto gpiochip_add_err;

	return 0;

gpiochip_add_err:
	release_region(gpio_ba, GPIO_IOSIZE);
	gpio_ba = 0;
	return err;
}

static void __exit it8761e_gpio_exit(void)
{
	if (gpio_ba) {
		int ret = gpiochip_remove(&it8761e_gpio_chip);

		WARN(ret, "%s(): gpiochip_remove() failed, ret=%d\n",
				__func__, ret);

		release_region(gpio_ba, GPIO_IOSIZE);
		gpio_ba = 0;
	}
}
module_init(it8761e_gpio_init);
module_exit(it8761e_gpio_exit);

MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
MODULE_DESCRIPTION("GPIO interface for IT8761E Super I/O chip");
MODULE_LICENSE("GPL");
