diff options
Diffstat (limited to 'drivers/gpio/it8761e_gpio.c')
| -rw-r--r-- | drivers/gpio/it8761e_gpio.c | 234 | 
1 files changed, 0 insertions, 234 deletions
diff --git a/drivers/gpio/it8761e_gpio.c b/drivers/gpio/it8761e_gpio.c deleted file mode 100644 index 48fc43c4bdd..00000000000 --- a/drivers/gpio/it8761e_gpio.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - *  it8761_gpio.c - 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");  | 
