/*
 * NES, SNES, N64, MultiSystem, PSX gamepad driver for Linux
 *
 *  Copyright (c) 1999-2004	Vojtech Pavlik <vojtech@suse.cz>
 *  Copyright (c) 2004		Peter Nelson <rufus-kernel@hackish.org>
 *
 *  Based on the work of:
 *	Andree Borrmann		John Dahlstrom
 *	David Kuder		Nathan Hand
 *	Raphael Assenat
 */

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Should you need to contact me, the author, you can do so either by
 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/parport.h>
#include <linux/input.h>
#include <linux/mutex.h>

MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver");
MODULE_LICENSE("GPL");

#define GC_MAX_PORTS		3
#define GC_MAX_DEVICES		5

struct gc_config {
	int args[GC_MAX_DEVICES + 1];
	unsigned int nargs;
};

static struct gc_config gc_cfg[GC_MAX_PORTS] __initdata;

module_param_array_named(map, gc_cfg[0].args, int, &gc_cfg[0].nargs, 0);
MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
module_param_array_named(map2, gc_cfg[1].args, int, &gc_cfg[1].nargs, 0);
MODULE_PARM_DESC(map2, "Describes second set of devices");
module_param_array_named(map3, gc_cfg[2].args, int, &gc_cfg[2].nargs, 0);
MODULE_PARM_DESC(map3, "Describes third set of devices");

/* see also gs_psx_delay parameter in PSX support section */

enum gc_type {
	GC_NONE = 0,
	GC_SNES,
	GC_NES,
	GC_NES4,
	GC_MULTI,
	GC_MULTI2,
	GC_N64,
	GC_PSX,
	GC_DDR,
	GC_SNESMOUSE,
	GC_MAX
};

#define GC_REFRESH_TIME	HZ/100

struct gc_pad {
	struct input_dev *dev;
	enum gc_type type;
	char phys[32];
};

struct gc {
	struct pardevice *pd;
	struct gc_pad pads[GC_MAX_DEVICES];
	struct input_dev *dev[GC_MAX_DEVICES];
	struct timer_list timer;
	int pad_count[GC_MAX];
	int used;
	struct mutex mutex;
};

struct gc_subdev {
	unsigned int idx;
};

static struct gc *gc_base[3];

static const int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 };

static const char *gc_names[] = {
	NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick",
	"Multisystem 2-button joystick", "N64 controller", "PSX controller",
	"PSX DDR controller", "SNES mouse"
};

/*
 * N64 support.
 */

static const unsigned char gc_n64_bytes[] = { 0, 1, 13, 15, 14, 12, 10, 11, 2, 3 };
static const short gc_n64_btn[] = {
	BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z,
	BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START
};

#define GC_N64_LENGTH		32		/* N64 bit length, not including stop bit */
#define GC_N64_STOP_LENGTH	5		/* Length of encoded stop bit */
#define GC_N64_CMD_00		0x11111111UL
#define GC_N64_CMD_01		0xd1111111UL
#define GC_N64_CMD_03		0xdd111111UL
#define GC_N64_CMD_1b		0xdd1dd111UL
#define GC_N64_CMD_c0		0x111111ddUL
#define GC_N64_CMD_80		0x1111111dUL
#define GC_N64_STOP_BIT		0x1d		/* Encoded stop bit */
#define GC_N64_REQUEST_DATA	GC_N64_CMD_01	/* the request data command */
#define GC_N64_DELAY		133		/* delay between transmit request, and response ready (us) */
#define GC_N64_DWS		3		/* delay between write segments (required for sound playback because of ISA DMA) */
						/* GC_N64_DWS > 24 is known to fail */
#define GC_N64_POWER_W		0xe2		/* power during write (transmit request) */
#define GC_N64_POWER_R		0xfd		/* power during read */
#define GC_N64_OUT		0x1d		/* output bits to the 4 pads */
						/* Reading the main axes of any N64 pad is known to fail if the corresponding bit */
						/* in GC_N64_OUT is pulled low on the output port (by any routine) for more */
						/* than 123 us */
#define GC_N64_CLOCK		0x02		/* clock bits for read */

/*
 * Used for rumble code.
 */

/* Send encoded command */
static void gc_n64_send_command(struct gc *gc, unsigned long cmd,
				unsigned char target)
{
	struct parport *port = gc->pd->port;
	int i;

	for (i = 0; i < GC_N64_LENGTH; i++) {
		unsigned char data = (cmd >> i) & 1 ? target : 0;
		parport_write_data(port, GC_N64_POWER_W | data);
		udelay(GC_N64_DWS);
	}
}

/* Send stop bit */
static void gc_n64_send_stop_bit(struct gc *gc, unsigned char target)
{
	struct parport *port = gc->pd->port;
	int i;

	for (i = 0; i < GC_N64_STOP_LENGTH; i++) {
		unsigned char data = (GC_N64_STOP_BIT >> i) & 1 ? target : 0;
		parport_write_data(port, GC_N64_POWER_W | data);
		udelay(GC_N64_DWS);
	}
}

/*
 * gc_n64_read_packet() reads an N64 packet.
 * Each pad uses one bit per byte. So all pads connected to this port
 * are read in parallel.
 */

static void gc_n64_read_packet(struct gc *gc, unsigned char *data)
{
	int i;
	unsigned long flags;

/*
 * Request the pad to transmit data
 */

	local_irq_save(flags);
	gc_n64_send_command(gc, GC_N64_REQUEST_DATA, GC_N64_OUT);
	gc_n64_send_stop_bit(gc, GC_N64_OUT);
	local_irq_restore(flags);

/*
 * Wait for the pad response to be loaded into the 33-bit register
 * of the adapter.
 */

	udelay(GC_N64_DELAY);

/*
 * Grab data (ignoring the last bit, which is a stop bit)
 */

	for (i = 0; i < GC_N64_LENGTH; i++) {
		parport_write_data(gc->pd->port, GC_N64_POWER_R);
		udelay(2);
		data[i] = parport_read_status(gc->pd->port);
		parport_write_data(gc->pd->port, GC_N64_POWER_R | GC_N64_CLOCK);
	 }

/*
 * We must wait 200 ms here for the controller to reinitialize before
 * the next read request. No worries as long as gc_read is polled less
 * frequently than this.
 */

}

static void gc_n64_process_packet(struct gc *gc)
{
	unsigned char data[GC_N64_LENGTH];
	struct input_dev *dev;
	int i, j, s;
	signed char x, y;

	gc_n64_read_packet(gc, data);

	for (i = 0; i < GC_MAX_DEVICES; i++) {

		if (gc->pads[i].type != GC_N64)
			continue;

		dev = gc->pads[i].dev;
		s = gc_status_bit[i];

		if (s & ~(data[8] | data[9])) {

			x = y = 0;

			for (j = 0; j < 8; j++) {
				if (data[23 - j] & s)
					x |= 1 << j;
				if (data[31 - j] & s)
					y |= 1 << j;
			}

			input_report_abs(dev, ABS_X,  x);
			input_report_abs(dev, ABS_Y, -y);

			input_report_abs(dev, ABS_HAT0X,
					 !(s & data[6]) - !(s & data[7]));
			input_report_abs(dev, ABS_HAT0Y,
					 !(s & data[4]) - !(s & data[5]));

			for (j = 0; j < 10; j++)
				input_report_key(dev, gc_n64_btn[j],
						 s & data[gc_n64_bytes[j]]);

			input_sync(dev);
		}
	}
}

static int gc_n64_play_effect(struct input_dev *dev, void *data,
			      struct ff_effect *effect)
{
	int i;
	unsigned long flags;
	struct gc *gc = input_get_drvdata(dev);
	struct gc_subdev *sdev = data;
	unsigned char target = 1 << sdev->idx; /* select desired pin */

	if (effect->type == FF_RUMBLE) {
		struct ff_rumble_effect *rumble = &effect->u.rumble;
		unsigned int cmd =
			rumble->strong_magnitude || rumble->weak_magnitude ?
			GC_N64_CMD_01 : GC_N64_CMD_00;

		local_irq_save(flags);

		/* Init Rumble - 0x03, 0x80, 0x01, (34)0x80 */
		gc_n64_send_command(gc, GC_N64_CMD_03, target);
		gc_n64_send_command(gc, GC_N64_CMD_80, target);
		gc_n64_send_command(gc, GC_N64_CMD_01, target);
		for (i = 0; i < 32; i++)
			gc_n64_send_command(gc, GC_N64_CMD_80, target);
		gc_n64_send_stop_bit(gc, target);

		udelay(GC_N64_DELAY);

		/* Now start or stop it - 0x03, 0xc0, 0zx1b, (32)0x01/0x00 */
		gc_n64_send_command(gc, GC_N64_CMD_03, target);
		gc_n64_send_command(gc, GC_N64_CMD_c0, target);
		gc_n64_send_command(gc, GC_N64_CMD_1b, target);
		for (i = 0; i < 32; i++)
			gc_n64_send_command(gc, cmd, target);
		gc_n64_send_stop_bit(gc, target);

		local_irq_restore(flags);

	}

	return 0;
}

static int __init gc_n64_init_ff(struct input_dev *dev, int i)
{
	struct gc_subdev *sdev;
	int err;

	sdev = kmalloc(sizeof(*sdev), GFP_KERNEL);
	if (!sdev)
		return -ENOMEM;

	sdev->idx = i;

	input_set_capability(dev, EV_FF, FF_RUMBLE);

	err = input_ff_create_memless(dev, sdev, gc_n64_play_effect);
	if (err) {
		kfree(sdev);
		return err;
	}

	return 0;
}

/*
 * NES/SNES support.
 */

#define GC_NES_DELAY		6	/* Delay between bits - 6us */
#define GC_NES_LENGTH		8	/* The NES pads use 8 bits of data */
#define GC_SNES_LENGTH		12	/* The SNES true length is 16, but the
					   last 4 bits are unused */
#define GC_SNESMOUSE_LENGTH	32	/* The SNES mouse uses 32 bits, the first
					   16 bits are equivalent to a gamepad */

#define GC_NES_POWER	0xfc
#define GC_NES_CLOCK	0x01
#define GC_NES_LATCH	0x02

static const unsigned char gc_nes_bytes[] = { 0, 1, 2, 3 };
static const unsigned char gc_snes_bytes[] = { 8, 0, 2, 3, 9, 1, 10, 11 };
static const short gc_snes_btn[] = {
	BTN_A, BTN_B, BTN_SELECT, BTN_START, BTN_X, BTN_Y, BTN_TL, BTN_TR
};

/*
 * gc_nes_read_packet() reads a NES/SNES packet.
 * Each pad uses one bit per byte. So all pads connected to
 * this port are read in parallel.
 */

static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data)
{
	int i;

	parport_write_data(gc->pd->port, GC_NES_POWER | GC_NES_CLOCK | GC_NES_LATCH);
	udelay(GC_NES_DELAY * 2);
	parport_write_data(gc->pd->port, GC_NES_POWER | GC_NES_CLOCK);

	for (i = 0; i < length; i++) {
		udelay(GC_NES_DELAY);
		parport_write_data(gc->pd->port, GC_NES_POWER);
		data[i] = parport_read_status(gc->pd->port) ^ 0x7f;
		udelay(GC_NES_DELAY);
		parport_write_data(gc->pd->port, GC_NES_POWER | GC_NES_CLOCK);
	}
}

static void gc_nes_process_packet(struct gc *gc)
{
	unsigned char data[GC_SNESMOUSE_LENGTH];
	struct gc_pad *pad;
	struct input_dev *dev;
	int i, j, s, len;
	char x_rel, y_rel;

	len = gc->pad_count[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH :
			(gc->pad_count[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH);

	gc_nes_read_packet(gc, len, data);

	for (i = 0; i < GC_MAX_DEVICES; i++) {

		pad = &gc->pads[i];
		dev = gc->dev[i];
		s = gc_status_bit[i];

		switch (pad->type) {

		case GC_NES:

			input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7]));
			input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5]));

			for (j = 0; j < 4; j++)
				input_report_key(dev, gc_snes_btn[j],
						 s & data[gc_nes_bytes[j]]);
			input_sync(dev);
			break;

		case GC_SNES:

			input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7]));
			input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5]));

			for (j = 0; j < 8; j++)
				input_report_key(dev, gc_snes_btn[j],
						 s & data[gc_snes_bytes[j]]);
			input_sync(dev);
			break;

		case GC_SNESMOUSE:
			/*
			 * The 4 unused bits from SNES controllers appear
			 * to be ID bits so use them to make sure we are
			 * dealing with a mouse.
			 * gamepad is connected. This is important since
			 * my SNES gamepad sends 1's for bits 16-31, which
			 * cause the mouse pointer to quickly move to the
			 * upper left corner of the screen.
			 */
			if (!(s & data[12]) && !(s & data[13]) &&
			    !(s & data[14]) && (s & data[15])) {
				input_report_key(dev, BTN_LEFT, s & data[9]);
				input_report_key(dev, BTN_RIGHT, s & data[8]);

				x_rel = y_rel = 0;
				for (j = 0; j < 7; j++) {
					x_rel <<= 1;
					if (data[25 + j] & s)
						x_rel |= 1;

					y_rel <<= 1;
					if (data[17 + j] & s)
						y_rel |= 1;
				}

				if (x_rel) {
					if (data[24] & s)
						x_rel = -x_rel;
					input_report_rel(dev, REL_X, x_rel);
				}

				if (y_rel) {
					if (data[16] & s)
						y_rel = -y_rel;
					input_report_rel(dev, REL_Y, y_rel);
				}

				input_sync(dev);
			}
			break;

		default:
			break;
		}
	}
}

/*
 * Multisystem joystick support
 */

#define GC_MULTI_LENGTH		5	/* Multi system joystick packet length is 5 */
#define GC_MULTI2_LENGTH	6	/* One more bit for one more button */

/*
 * gc_multi_read_packet() reads a Multisystem joystick packet.
 */

static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data)
{
	int i;

	for (i = 0; i < length; i++) {
		parport_write_data(gc->pd->port, ~(1 << i));
		data[i] = parport_read_status(gc->pd->port) ^ 0x7f;
	}
}

static void gc_multi_process_packet(struct gc *gc)
{
	unsigned char data[GC_MULTI2_LENGTH];
	int data_len = gc->pad_count[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH;
	struct gc_pad *pad;
	struct input_dev *dev;
	int i, s;

	gc_multi_read_packet(gc, data_len, data);

	for (i = 0; i < GC_MAX_DEVICES; i++) {
		pad = &gc->pads[i];
		dev = pad->dev;
		s = gc_status_bit[i];

		switch (pad->type) {
		case GC_MULTI2:
			input_report_key(dev, BTN_THUMB, s & data[5]);
			/* fall through */

		case GC_MULTI:
			input_report_abs(dev, ABS_X,
					 !(s & data[2]) - !(s & data[3]));
			input_report_abs(dev, ABS_Y,
					 !(s & data[0]) - !(s & data[1]));
			input_report_key(dev, BTN_TRIGGER, s & data[4]);
			input_sync(dev);
			break;

		default:
			break;
		}
	}
}

/*
 * PSX support
 *
 * See documentation at:
 *	http://www.dim.com/~mackys/psxmemcard/ps-eng2.txt
 *	http://www.gamesx.com/controldata/psxcont/psxcont.htm
 *	ftp://milano.usal.es/pablo/
 *
 */

#define GC_PSX_DELAY	25		/* 25 usec */
#define GC_PSX_LENGTH	8		/* talk to the controller in bits */
#define GC_PSX_BYTES	6		/* the maximum number of bytes to read off the controller */

#define GC_PSX_MOUSE	1		/* Mouse */
#define GC_PSX_NEGCON	2		/* NegCon */
#define GC_PSX_NORMAL	4		/* Digital / Analog or Rumble in Digital mode  */
#define GC_PSX_ANALOG	5		/* Analog in Analog mode / Rumble in Green mode */
#define GC_PSX_RUMBLE	7		/* Rumble in Red mode */

#define GC_PSX_CLOCK	0x04		/* Pin 4 */
#define GC_PSX_COMMAND	0x01		/* Pin 2 */
#define GC_PSX_POWER	0xf8		/* Pins 5-9 */
#define GC_PSX_SELECT	0x02		/* Pin 3 */

#define GC_PSX_ID(x)	((x) >> 4)	/* High nibble is device type */
#define GC_PSX_LEN(x)	(((x) & 0xf) << 1)	/* Low nibble is length in bytes/2 */

static int gc_psx_delay = GC_PSX_DELAY;
module_param_named(psx_delay, gc_psx_delay, uint, 0);
MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)");

static const short gc_psx_abs[] = {
	ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y
};
static const short gc_psx_btn[] = {
	BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y,
	BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR
};
static const short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 };

/*
 * gc_psx_command() writes 8bit command and reads 8bit data from
 * the psx pad.
 */

static void gc_psx_command(struct gc *gc, int b, unsigned char *data)
{
	struct parport *port = gc->pd->port;
	int i, j, cmd, read;

	memset(data, 0, GC_MAX_DEVICES);

	for (i = 0; i < GC_PSX_LENGTH; i++, b >>= 1) {
		cmd = (b & 1) ? GC_PSX_COMMAND : 0;
		parport_write_data(port, cmd | GC_PSX_POWER);
		udelay(gc_psx_delay);

		read = parport_read_status(port) ^ 0x80;

		for (j = 0; j < GC_MAX_DEVICES; j++) {
			struct gc_pad *pad = &gc->pads[i];

			if (pad->type == GC_PSX || pad->type == GC_DDR)
				data[j] |= (read & gc_status_bit[j]) ? (1 << i) : 0;
		}

		parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER);
		udelay(gc_psx_delay);
	}
}

/*
 * gc_psx_read_packet() reads a whole psx packet and returns
 * device identifier code.
 */

static void gc_psx_read_packet(struct gc *gc,
			       unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES],
			       unsigned char id[GC_MAX_DEVICES])
{
	int i, j, max_len = 0;
	unsigned long flags;
	unsigned char data2[GC_MAX_DEVICES];

	/* Select pad */
	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER);
	udelay(gc_psx_delay);
	/* Deselect, begin command */
	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER);
	udelay(gc_psx_delay);

	local_irq_save(flags);

	gc_psx_command(gc, 0x01, data2);	/* Access pad */
	gc_psx_command(gc, 0x42, id);		/* Get device ids */
	gc_psx_command(gc, 0, data2);		/* Dump status */

	/* Find the longest pad */
	for (i = 0; i < GC_MAX_DEVICES; i++) {
		struct gc_pad *pad = &gc->pads[i];

		if ((pad->type == GC_PSX || pad->type == GC_DDR) &&
		    GC_PSX_LEN(id[i]) > max_len &&
		    GC_PSX_LEN(id[i]) <= GC_PSX_BYTES) {
			max_len = GC_PSX_LEN(id[i]);
		}
	}

	/* Read in all the data */
	for (i = 0; i < max_len; i++) {
		gc_psx_command(gc, 0, data2);
		for (j = 0; j < GC_MAX_DEVICES; j++)
			data[j][i] = data2[j];
	}

	local_irq_restore(flags);

	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER);

	/* Set id's to the real value */
	for (i = 0; i < GC_MAX_DEVICES; i++)
		id[i] = GC_PSX_ID(id[i]);
}

static void gc_psx_report_one(struct gc_pad *pad, unsigned char psx_type,
			      unsigned char *data)
{
	struct input_dev *dev = pad->dev;
	int i;

	switch (psx_type) {

	case GC_PSX_RUMBLE:

		input_report_key(dev, BTN_THUMBL, ~data[0] & 0x04);
		input_report_key(dev, BTN_THUMBR, ~data[0] & 0x02);

	case GC_PSX_NEGCON:
	case GC_PSX_ANALOG:

		if (pad->type == GC_DDR) {
			for (i = 0; i < 4; i++)
				input_report_key(dev, gc_psx_ddr_btn[i],
						 ~data[0] & (0x10 << i));
		} else {
			for (i = 0; i < 4; i++)
				input_report_abs(dev, gc_psx_abs[i + 2],
						 data[i + 2]);

			input_report_abs(dev, ABS_X,
				!!(data[0] & 0x80) * 128 + !(data[0] & 0x20) * 127);
			input_report_abs(dev, ABS_Y,
				!!(data[0] & 0x10) * 128 + !(data[0] & 0x40) * 127);
		}

		for (i = 0; i < 8; i++)
			input_report_key(dev, gc_psx_btn[i], ~data[1] & (1 << i));

		input_report_key(dev, BTN_START,  ~data[0] & 0x08);
		input_report_key(dev, BTN_SELECT, ~data[0] & 0x01);

		input_sync(dev);

		break;

	case GC_PSX_NORMAL:

		if (pad->type == GC_DDR) {
			for (i = 0; i < 4; i++)
				input_report_key(dev, gc_psx_ddr_btn[i],
						 ~data[0] & (0x10 << i));
		} else {
			input_report_abs(dev, ABS_X,
				!!(data[0] & 0x80) * 128 + !(data[0] & 0x20) * 127);
			input_report_abs(dev, ABS_Y,
				!!(data[0] & 0x10) * 128 + !(data[0] & 0x40) * 127);

			/*
			 * For some reason if the extra axes are left unset
			 * they drift.
			 * for (i = 0; i < 4; i++)
				input_report_abs(dev, gc_psx_abs[i + 2], 128);
			 * This needs to be debugged properly,
			 * maybe fuzz processing needs to be done
			 * in input_sync()
			 *				 --vojtech
			 */
		}

		for (i = 0; i < 8; i++)
			input_report_key(dev, gc_psx_btn[i], ~data[1] & (1 << i));

		input_report_key(dev, BTN_START,  ~data[0] & 0x08);
		input_report_key(dev, BTN_SELECT, ~data[0] & 0x01);

		input_sync(dev);

		break;

	default: /* not a pad, ignore */
		break;
	}
}

static void gc_psx_process_packet(struct gc *gc)
{
	unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES];
	unsigned char id[GC_MAX_DEVICES];
	struct gc_pad *pad;
	int i;

	gc_psx_read_packet(gc, data, id);

	for (i = 0; i < GC_MAX_DEVICES; i++) {
		pad = &gc->pads[i];
		if (pad->type == GC_PSX || pad->type == GC_DDR)
			gc_psx_report_one(pad, id[i], data[i]);
	}
}

/*
 * gc_timer() initiates reads of console pads data.
 */

static void gc_timer(unsigned long private)
{
	struct gc *gc = (void *) private;

/*
 * N64 pads - must be read first, any read confuses them for 200 us
 */

	if (gc->pad_count[GC_N64])
		gc_n64_process_packet(gc);

/*
 * NES and SNES pads or mouse
 */

	if (gc->pad_count[GC_NES] ||
	    gc->pad_count[GC_SNES] ||
	    gc->pad_count[GC_SNESMOUSE]) {
		gc_nes_process_packet(gc);
	}

/*
 * Multi and Multi2 joysticks
 */

	if (gc->pad_count[GC_MULTI] || gc->pad_count[GC_MULTI2])
		gc_multi_process_packet(gc);

/*
 * PSX controllers
 */

	if (gc->pad_count[GC_PSX] || gc->pad_count[GC_DDR])
		gc_psx_process_packet(gc);

	mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME);
}

static int gc_open(struct input_dev *dev)
{
	struct gc *gc = input_get_drvdata(dev);
	int err;

	err = mutex_lock_interruptible(&gc->mutex);
	if (err)
		return err;

	if (!gc->used++) {
		parport_claim(gc->pd);
		parport_write_control(gc->pd->port, 0x04);
		mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME);
	}

	mutex_unlock(&gc->mutex);
	return 0;
}

static void gc_close(struct input_dev *dev)
{
	struct gc *gc = input_get_drvdata(dev);

	mutex_lock(&gc->mutex);
	if (!--gc->used) {
		del_timer_sync(&gc->timer);
		parport_write_control(gc->pd->port, 0x00);
		parport_release(gc->pd);
	}
	mutex_unlock(&gc->mutex);
}

static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
{
	struct gc_pad *pad = &gc->pads[idx];
	struct input_dev *input_dev;
	int i;
	int err;

	if (pad_type < 1 || pad_type >= GC_MAX) {
		pr_err("Pad type %d unknown\n", pad_type);
		return -EINVAL;
	}

	pad->dev = input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("Not enough memory for input device\n");
		return -ENOMEM;
	}

	pad->type = pad_type;

	snprintf(pad->phys, sizeof(pad->phys),
		 "%s/input%d", gc->pd->port->name, idx);

	input_dev->name = gc_names[pad_type];
	input_dev->phys = pad->phys;
	input_dev->id.bustype = BUS_PARPORT;
	input_dev->id.vendor = 0x0001;
	input_dev->id.product = pad_type;
	input_dev->id.version = 0x0100;

	input_set_drvdata(input_dev, gc);

	input_dev->open = gc_open;
	input_dev->close = gc_close;

	if (pad_type != GC_SNESMOUSE) {
		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);

		for (i = 0; i < 2; i++)
			input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0);
	} else
		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);

	gc->pad_count[pad_type]++;

	switch (pad_type) {

	case GC_N64:
		for (i = 0; i < 10; i++)
			__set_bit(gc_n64_btn[i], input_dev->keybit);

		for (i = 0; i < 2; i++) {
			input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2);
			input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
		}

		err = gc_n64_init_ff(input_dev, idx);
		if (err) {
			pr_warning("Failed to initiate rumble for N64 device %d\n", idx);
			goto err_free_dev;
		}

		break;

	case GC_SNESMOUSE:
		__set_bit(BTN_LEFT, input_dev->keybit);
		__set_bit(BTN_RIGHT, input_dev->keybit);
		__set_bit(REL_X, input_dev->relbit);
		__set_bit(REL_Y, input_dev->relbit);
		break;

	case GC_SNES:
		for (i = 4; i < 8; i++)
			__set_bit(gc_snes_btn[i], input_dev->keybit);
	case GC_NES:
		for (i = 0; i < 4; i++)
			__set_bit(gc_snes_btn[i], input_dev->keybit);
		break;

	case GC_MULTI2:
		__set_bit(BTN_THUMB, input_dev->keybit);
	case GC_MULTI:
		__set_bit(BTN_TRIGGER, input_dev->keybit);
		break;

	case GC_PSX:
		for (i = 0; i < 6; i++)
			input_set_abs_params(input_dev,
					     gc_psx_abs[i], 4, 252, 0, 2);
		for (i = 0; i < 12; i++)
			__set_bit(gc_psx_btn[i], input_dev->keybit);

		break;

	case GC_DDR:
		for (i = 0; i < 4; i++)
			__set_bit(gc_psx_ddr_btn[i], input_dev->keybit);
		for (i = 0; i < 12; i++)
			__set_bit(gc_psx_btn[i], input_dev->keybit);

		break;
	}

	err = input_register_device(pad->dev);
	if (err)
		goto err_free_dev;

	return 0;

err_free_dev:
	input_free_device(pad->dev);
	pad->dev = NULL;
	return err;
}

static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
{
	struct gc *gc;
	struct parport *pp;
	struct pardevice *pd;
	int i;
	int count = 0;
	int err;

	pp = parport_find_number(parport);
	if (!pp) {
		pr_err("no such parport %d\n", parport);
		err = -EINVAL;
		goto err_out;
	}

	pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
	if (!pd) {
		pr_err("parport busy already - lp.o loaded?\n");
		err = -EBUSY;
		goto err_put_pp;
	}

	gc = kzalloc(sizeof(struct gc), GFP_KERNEL);
	if (!gc) {
		pr_err("Not enough memory\n");
		err = -ENOMEM;
		goto err_unreg_pardev;
	}

	mutex_init(&gc->mutex);
	gc->pd = pd;
	setup_timer(&gc->timer, gc_timer, (long) gc);

	for (i = 0; i < n_pads && i < GC_MAX_DEVICES; i++) {
		if (!pads[i])
			continue;

		err = gc_setup_pad(gc, i, pads[i]);
		if (err)
			goto err_unreg_devs;

		count++;
	}

	if (count == 0) {
		pr_err("No valid devices specified\n");
		err = -EINVAL;
		goto err_free_gc;
	}

	parport_put_port(pp);
	return gc;

 err_unreg_devs:
	while (--i >= 0)
		if (gc->pads[i].dev)
			input_unregister_device(gc->pads[i].dev);
 err_free_gc:
	kfree(gc);
 err_unreg_pardev:
	parport_unregister_device(pd);
 err_put_pp:
	parport_put_port(pp);
 err_out:
	return ERR_PTR(err);
}

static void gc_remove(struct gc *gc)
{
	int i;

	for (i = 0; i < GC_MAX_DEVICES; i++)
		if (gc->pads[i].dev)
			input_unregister_device(gc->pads[i].dev);
	parport_unregister_device(gc->pd);
	kfree(gc);
}

static int __init gc_init(void)
{
	int i;
	int have_dev = 0;
	int err = 0;

	for (i = 0; i < GC_MAX_PORTS; i++) {
		if (gc_cfg[i].nargs == 0 || gc_cfg[i].args[0] < 0)
			continue;

		if (gc_cfg[i].nargs < 2) {
			pr_err("at least one device must be specified\n");
			err = -EINVAL;
			break;
		}

		gc_base[i] = gc_probe(gc_cfg[i].args[0],
				      gc_cfg[i].args + 1, gc_cfg[i].nargs - 1);
		if (IS_ERR(gc_base[i])) {
			err = PTR_ERR(gc_base[i]);
			break;
		}

		have_dev = 1;
	}

	if (err) {
		while (--i >= 0)
			if (gc_base[i])
				gc_remove(gc_base[i]);
		return err;
	}

	return have_dev ? 0 : -ENODEV;
}

static void __exit gc_exit(void)
{
	int i;

	for (i = 0; i < GC_MAX_PORTS; i++)
		if (gc_base[i])
			gc_remove(gc_base[i]);
}

module_init(gc_init);
module_exit(gc_exit);
