/*
 *  Copyright (c) 1999-2001 Vojtech Pavlik
 *
 *  Based on the work of:
 *	Andree Borrmann		Mats Sjövall
 */

/*
 * Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver for Linux
 */

/*
 * 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
 */

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

MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver");
MODULE_LICENSE("GPL");

struct db9_config {
	int args[2];
	unsigned int nargs;
};

#define DB9_MAX_PORTS		3
static struct db9_config db9_cfg[DB9_MAX_PORTS];

module_param_array_named(dev, db9_cfg[0].args, int, &db9_cfg[0].nargs, 0);
MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
module_param_array_named(dev2, db9_cfg[1].args, int, &db9_cfg[1].nargs, 0);
MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
module_param_array_named(dev3, db9_cfg[2].args, int, &db9_cfg[2].nargs, 0);
MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");

#define DB9_ARG_PARPORT		0
#define DB9_ARG_MODE		1

#define DB9_MULTI_STICK		0x01
#define DB9_MULTI2_STICK	0x02
#define DB9_GENESIS_PAD		0x03
#define DB9_GENESIS5_PAD	0x05
#define DB9_GENESIS6_PAD	0x06
#define DB9_SATURN_PAD		0x07
#define DB9_MULTI_0802		0x08
#define DB9_MULTI_0802_2	0x09
#define DB9_CD32_PAD		0x0A
#define DB9_SATURN_DPP		0x0B
#define DB9_SATURN_DPP_2	0x0C
#define DB9_MAX_PAD		0x0D

#define DB9_UP			0x01
#define DB9_DOWN		0x02
#define DB9_LEFT		0x04
#define DB9_RIGHT		0x08
#define DB9_FIRE1		0x10
#define DB9_FIRE2		0x20
#define DB9_FIRE3		0x40
#define DB9_FIRE4		0x80

#define DB9_NORMAL		0x0a
#define DB9_NOSELECT		0x08

#define DB9_GENESIS6_DELAY	14
#define DB9_REFRESH_TIME	HZ/100

#define DB9_MAX_DEVICES		2

struct db9_mode_data {
	const char *name;
	const short *buttons;
	int n_buttons;
	int n_pads;
	int n_axis;
	int bidirectional;
	int reverse;
};

struct db9 {
	struct input_dev *dev[DB9_MAX_DEVICES];
	struct timer_list timer;
	struct pardevice *pd;
	int mode;
	int used;
	int parportno;
	struct mutex mutex;
	char phys[DB9_MAX_DEVICES][32];
};

static struct db9 *db9_base[3];

static const short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB };
static const short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
static const short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
static const short db9_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_RZ, ABS_Z, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };

static const struct db9_mode_data db9_modes[] = {
	{ NULL,					 NULL,		  0,  0,  0,  0,  0 },
	{ "Multisystem joystick",		 db9_multi_btn,	  1,  1,  2,  1,  1 },
	{ "Multisystem joystick (2 fire)",	 db9_multi_btn,	  2,  1,  2,  1,  1 },
	{ "Genesis pad",			 db9_genesis_btn, 4,  1,  2,  1,  1 },
	{ NULL,					 NULL,		  0,  0,  0,  0,  0 },
	{ "Genesis 5 pad",			 db9_genesis_btn, 6,  1,  2,  1,  1 },
	{ "Genesis 6 pad",			 db9_genesis_btn, 8,  1,  2,  1,  1 },
	{ "Saturn pad",				 db9_cd32_btn,	  9,  6,  7,  0,  1 },
	{ "Multisystem (0.8.0.2) joystick",	 db9_multi_btn,	  1,  1,  2,  1,  1 },
	{ "Multisystem (0.8.0.2-dual) joystick", db9_multi_btn,	  1,  2,  2,  1,  1 },
	{ "Amiga CD-32 pad",			 db9_cd32_btn,	  7,  1,  2,  1,  1 },
	{ "Saturn dpp",				 db9_cd32_btn,	  9,  6,  7,  0,  0 },
	{ "Saturn dpp dual",			 db9_cd32_btn,	  9,  12, 7,  0,  0 },
};

/*
 * Saturn controllers
 */
#define DB9_SATURN_DELAY 300
static const int db9_saturn_byte[] = { 1, 1, 1, 2, 2, 2, 2, 2, 1 };
static const unsigned char db9_saturn_mask[] = { 0x04, 0x01, 0x02, 0x40, 0x20, 0x10, 0x08, 0x80, 0x08 };

/*
 * db9_saturn_write_sub() writes 2 bit data.
 */
static void db9_saturn_write_sub(struct parport *port, int type, unsigned char data, int powered, int pwr_sub)
{
	unsigned char c;

	switch (type) {
	case 1: /* DPP1 */
		c = 0x80 | 0x30 | (powered ? 0x08 : 0) | (pwr_sub ? 0x04 : 0) | data;
		parport_write_data(port, c);
		break;
	case 2: /* DPP2 */
		c = 0x40 | data << 4 | (powered ? 0x08 : 0) | (pwr_sub ? 0x04 : 0) | 0x03;
		parport_write_data(port, c);
		break;
	case 0:	/* DB9 */
		c = ((((data & 2) ? 2 : 0) | ((data & 1) ? 4 : 0)) ^ 0x02) | !powered;
		parport_write_control(port, c);
		break;
	}
}

/*
 * gc_saturn_read_sub() reads 4 bit data.
 */
static unsigned char db9_saturn_read_sub(struct parport *port, int type)
{
	unsigned char data;

	if (type) {
		/* DPP */
		data = parport_read_status(port) ^ 0x80;
		return (data & 0x80 ? 1 : 0) | (data & 0x40 ? 2 : 0)
		     | (data & 0x20 ? 4 : 0) | (data & 0x10 ? 8 : 0);
	} else {
		/* DB9 */
		data = parport_read_data(port) & 0x0f;
		return (data & 0x8 ? 1 : 0) | (data & 0x4 ? 2 : 0)
		     | (data & 0x2 ? 4 : 0) | (data & 0x1 ? 8 : 0);
	}
}

/*
 * db9_saturn_read_analog() sends clock and reads 8 bit data.
 */
static unsigned char db9_saturn_read_analog(struct parport *port, int type, int powered)
{
	unsigned char data;

	db9_saturn_write_sub(port, type, 0, powered, 0);
	udelay(DB9_SATURN_DELAY);
	data = db9_saturn_read_sub(port, type) << 4;
	db9_saturn_write_sub(port, type, 2, powered, 0);
	udelay(DB9_SATURN_DELAY);
	data |= db9_saturn_read_sub(port, type);
	return data;
}

/*
 * db9_saturn_read_packet() reads whole saturn packet at connector
 * and returns device identifier code.
 */
static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char *data, int type, int powered)
{
	int i, j;
	unsigned char tmp;

	db9_saturn_write_sub(port, type, 3, powered, 0);
	data[0] = db9_saturn_read_sub(port, type);
	switch (data[0] & 0x0f) {
	case 0xf:
		/* 1111  no pad */
		return data[0] = 0xff;
	case 0x4: case 0x4 | 0x8:
		/* ?100 : digital controller */
		db9_saturn_write_sub(port, type, 0, powered, 1);
		data[2] = db9_saturn_read_sub(port, type) << 4;
		db9_saturn_write_sub(port, type, 2, powered, 1);
		data[1] = db9_saturn_read_sub(port, type) << 4;
		db9_saturn_write_sub(port, type, 1, powered, 1);
		data[1] |= db9_saturn_read_sub(port, type);
		db9_saturn_write_sub(port, type, 3, powered, 1);
		/* data[2] |= db9_saturn_read_sub(port, type); */
		data[2] |= data[0];
		return data[0] = 0x02;
	case 0x1:
		/* 0001 : analog controller or multitap */
		db9_saturn_write_sub(port, type, 2, powered, 0);
		udelay(DB9_SATURN_DELAY);
		data[0] = db9_saturn_read_analog(port, type, powered);
		if (data[0] != 0x41) {
			/* read analog controller */
			for (i = 0; i < (data[0] & 0x0f); i++)
				data[i + 1] = db9_saturn_read_analog(port, type, powered);
			db9_saturn_write_sub(port, type, 3, powered, 0);
			return data[0];
		} else {
			/* read multitap */
			if (db9_saturn_read_analog(port, type, powered) != 0x60)
				return data[0] = 0xff;
			for (i = 0; i < 60; i += 10) {
				data[i] = db9_saturn_read_analog(port, type, powered);
				if (data[i] != 0xff)
					/* read each pad */
					for (j = 0; j < (data[i] & 0x0f); j++)
						data[i + j + 1] = db9_saturn_read_analog(port, type, powered);
			}
			db9_saturn_write_sub(port, type, 3, powered, 0);
			return 0x41;
		}
	case 0x0:
		/* 0000 : mouse */
		db9_saturn_write_sub(port, type, 2, powered, 0);
		udelay(DB9_SATURN_DELAY);
		tmp = db9_saturn_read_analog(port, type, powered);
		if (tmp == 0xff) {
			for (i = 0; i < 3; i++)
				data[i + 1] = db9_saturn_read_analog(port, type, powered);
			db9_saturn_write_sub(port, type, 3, powered, 0);
			return data[0] = 0xe3;
		}
	default:
		return data[0];
	}
}

/*
 * db9_saturn_report() analyzes packet and reports.
 */
static int db9_saturn_report(unsigned char id, unsigned char data[60], struct input_dev *devs[], int n, int max_pads)
{
	struct input_dev *dev;
	int tmp, i, j;

	tmp = (id == 0x41) ? 60 : 10;
	for (j = 0; j < tmp && n < max_pads; j += 10, n++) {
		dev = devs[n];
		switch (data[j]) {
		case 0x16: /* multi controller (analog 4 axis) */
			input_report_abs(dev, db9_abs[5], data[j + 6]);
		case 0x15: /* mission stick (analog 3 axis) */
			input_report_abs(dev, db9_abs[3], data[j + 4]);
			input_report_abs(dev, db9_abs[4], data[j + 5]);
		case 0x13: /* racing controller (analog 1 axis) */
			input_report_abs(dev, db9_abs[2], data[j + 3]);
		case 0x34: /* saturn keyboard (udlr ZXC ASD QE Esc) */
		case 0x02: /* digital pad (digital 2 axis + buttons) */
			input_report_abs(dev, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
			input_report_abs(dev, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
			for (i = 0; i < 9; i++)
				input_report_key(dev, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
			break;
		case 0x19: /* mission stick x2 (analog 6 axis + buttons) */
			input_report_abs(dev, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
			input_report_abs(dev, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
			for (i = 0; i < 9; i++)
				input_report_key(dev, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
			input_report_abs(dev, db9_abs[2], data[j + 3]);
			input_report_abs(dev, db9_abs[3], data[j + 4]);
			input_report_abs(dev, db9_abs[4], data[j + 5]);
			/*
			input_report_abs(dev, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1));
			input_report_abs(dev, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1));
			*/
			input_report_abs(dev, db9_abs[6], data[j + 7]);
			input_report_abs(dev, db9_abs[7], data[j + 8]);
			input_report_abs(dev, db9_abs[5], data[j + 9]);
			break;
		case 0xd3: /* sankyo ff (analog 1 axis + stop btn) */
			input_report_key(dev, BTN_A, data[j + 3] & 0x80);
			input_report_abs(dev, db9_abs[2], data[j + 3] & 0x7f);
			break;
		case 0xe3: /* shuttle mouse (analog 2 axis + buttons. signed value) */
			input_report_key(dev, BTN_START, data[j + 1] & 0x08);
			input_report_key(dev, BTN_A, data[j + 1] & 0x04);
			input_report_key(dev, BTN_C, data[j + 1] & 0x02);
			input_report_key(dev, BTN_B, data[j + 1] & 0x01);
			input_report_abs(dev, db9_abs[2], data[j + 2] ^ 0x80);
			input_report_abs(dev, db9_abs[3], (0xff-(data[j + 3] ^ 0x80))+1); /* */
			break;
		case 0xff:
		default: /* no pad */
			input_report_abs(dev, db9_abs[0], 0);
			input_report_abs(dev, db9_abs[1], 0);
			for (i = 0; i < 9; i++)
				input_report_key(dev, db9_cd32_btn[i], 0);
			break;
		}
	}
	return n;
}

static int db9_saturn(int mode, struct parport *port, struct input_dev *devs[])
{
	unsigned char id, data[60];
	int type, n, max_pads;
	int tmp, i;

	switch (mode) {
	case DB9_SATURN_PAD:
		type = 0;
		n = 1;
		break;
	case DB9_SATURN_DPP:
		type = 1;
		n = 1;
		break;
	case DB9_SATURN_DPP_2:
		type = 1;
		n = 2;
		break;
	default:
		return -1;
	}
	max_pads = min(db9_modes[mode].n_pads, DB9_MAX_DEVICES);
	for (tmp = 0, i = 0; i < n; i++) {
		id = db9_saturn_read_packet(port, data, type + i, 1);
		tmp = db9_saturn_report(id, data, devs, tmp, max_pads);
	}
	return 0;
}

static void db9_timer(unsigned long private)
{
	struct db9 *db9 = (void *) private;
	struct parport *port = db9->pd->port;
	struct input_dev *dev = db9->dev[0];
	struct input_dev *dev2 = db9->dev[1];
	int data, i;

	switch (db9->mode) {
		case DB9_MULTI_0802_2:

			data = parport_read_data(port) >> 3;

			input_report_abs(dev2, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
			input_report_abs(dev2, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
			input_report_key(dev2, BTN_TRIGGER, ~data & DB9_FIRE1);

		case DB9_MULTI_0802:

			data = parport_read_status(port) >> 3;

			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
			input_report_key(dev, BTN_TRIGGER, data & DB9_FIRE1);
			break;

		case DB9_MULTI_STICK:

			data = parport_read_data(port);

			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
			input_report_key(dev, BTN_TRIGGER, ~data & DB9_FIRE1);
			break;

		case DB9_MULTI2_STICK:

			data = parport_read_data(port);

			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
			input_report_key(dev, BTN_TRIGGER, ~data & DB9_FIRE1);
			input_report_key(dev, BTN_THUMB,   ~data & DB9_FIRE2);
			break;

		case DB9_GENESIS_PAD:

			parport_write_control(port, DB9_NOSELECT);
			data = parport_read_data(port);

			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
			input_report_key(dev, BTN_B, ~data & DB9_FIRE1);
			input_report_key(dev, BTN_C, ~data & DB9_FIRE2);

			parport_write_control(port, DB9_NORMAL);
			data = parport_read_data(port);

			input_report_key(dev, BTN_A,     ~data & DB9_FIRE1);
			input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
			break;

		case DB9_GENESIS5_PAD:

			parport_write_control(port, DB9_NOSELECT);
			data = parport_read_data(port);

			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
			input_report_key(dev, BTN_B, ~data & DB9_FIRE1);
			input_report_key(dev, BTN_C, ~data & DB9_FIRE2);

			parport_write_control(port, DB9_NORMAL);
			data = parport_read_data(port);

			input_report_key(dev, BTN_A,     ~data & DB9_FIRE1);
			input_report_key(dev, BTN_X,     ~data & DB9_FIRE2);
			input_report_key(dev, BTN_Y,     ~data & DB9_LEFT);
			input_report_key(dev, BTN_START, ~data & DB9_RIGHT);
			break;

		case DB9_GENESIS6_PAD:

			parport_write_control(port, DB9_NOSELECT); /* 1 */
			udelay(DB9_GENESIS6_DELAY);
			data = parport_read_data(port);

			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
			input_report_key(dev, BTN_B, ~data & DB9_FIRE1);
			input_report_key(dev, BTN_C, ~data & DB9_FIRE2);

			parport_write_control(port, DB9_NORMAL);
			udelay(DB9_GENESIS6_DELAY);
			data = parport_read_data(port);

			input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
			input_report_key(dev, BTN_START, ~data & DB9_FIRE2);

			parport_write_control(port, DB9_NOSELECT); /* 2 */
			udelay(DB9_GENESIS6_DELAY);
			parport_write_control(port, DB9_NORMAL);
			udelay(DB9_GENESIS6_DELAY);
			parport_write_control(port, DB9_NOSELECT); /* 3 */
			udelay(DB9_GENESIS6_DELAY);
			data=parport_read_data(port);

			input_report_key(dev, BTN_X,    ~data & DB9_LEFT);
			input_report_key(dev, BTN_Y,    ~data & DB9_DOWN);
			input_report_key(dev, BTN_Z,    ~data & DB9_UP);
			input_report_key(dev, BTN_MODE, ~data & DB9_RIGHT);

			parport_write_control(port, DB9_NORMAL);
			udelay(DB9_GENESIS6_DELAY);
			parport_write_control(port, DB9_NOSELECT); /* 4 */
			udelay(DB9_GENESIS6_DELAY);
			parport_write_control(port, DB9_NORMAL);
			break;

		case DB9_SATURN_PAD:
		case DB9_SATURN_DPP:
		case DB9_SATURN_DPP_2:

			db9_saturn(db9->mode, port, db9->dev);
			break;

		case DB9_CD32_PAD:

			data = parport_read_data(port);

			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));

			parport_write_control(port, 0x0a);

			for (i = 0; i < 7; i++) {
				data = parport_read_data(port);
				parport_write_control(port, 0x02);
				parport_write_control(port, 0x0a);
				input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2);
			}

			parport_write_control(port, 0x00);
			break;
		}

	input_sync(dev);

	mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME);
}

static int db9_open(struct input_dev *dev)
{
	struct db9 *db9 = input_get_drvdata(dev);
	struct parport *port = db9->pd->port;
	int err;

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

	if (!db9->used++) {
		parport_claim(db9->pd);
		parport_write_data(port, 0xff);
		if (db9_modes[db9->mode].reverse) {
			parport_data_reverse(port);
			parport_write_control(port, DB9_NORMAL);
		}
		mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME);
	}

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

static void db9_close(struct input_dev *dev)
{
	struct db9 *db9 = input_get_drvdata(dev);
	struct parport *port = db9->pd->port;

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

static void db9_attach(struct parport *pp)
{
	struct db9 *db9;
	const struct db9_mode_data *db9_mode;
	struct pardevice *pd;
	struct input_dev *input_dev;
	int i, j, port_idx;
	int mode;
	struct pardev_cb db9_parport_cb;

	for (port_idx = 0; port_idx < DB9_MAX_PORTS; port_idx++) {
		if (db9_cfg[port_idx].nargs == 0 ||
		    db9_cfg[port_idx].args[DB9_ARG_PARPORT] < 0)
			continue;

		if (db9_cfg[port_idx].args[DB9_ARG_PARPORT] == pp->number)
			break;
	}

	if (port_idx == DB9_MAX_PORTS) {
		pr_debug("Not using parport%d.\n", pp->number);
		return;
	}

	mode = db9_cfg[port_idx].args[DB9_ARG_MODE];

	if (mode < 1 || mode >= DB9_MAX_PAD || !db9_modes[mode].n_buttons) {
		printk(KERN_ERR "db9.c: Bad device type %d\n", mode);
		return;
	}

	db9_mode = &db9_modes[mode];

	if (db9_mode->bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) {
		printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
		return;
	}

	memset(&db9_parport_cb, 0, sizeof(db9_parport_cb));
	db9_parport_cb.flags = PARPORT_FLAG_EXCL;

	pd = parport_register_dev_model(pp, "db9", &db9_parport_cb, port_idx);
	if (!pd) {
		printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
		return;
	}

	db9 = kzalloc(sizeof(struct db9), GFP_KERNEL);
	if (!db9)
		goto err_unreg_pardev;

	mutex_init(&db9->mutex);
	db9->pd = pd;
	db9->mode = mode;
	db9->parportno = pp->number;
	setup_timer(&db9->timer, db9_timer, (long)db9);

	for (i = 0; i < (min(db9_mode->n_pads, DB9_MAX_DEVICES)); i++) {

		db9->dev[i] = input_dev = input_allocate_device();
		if (!input_dev) {
			printk(KERN_ERR "db9.c: Not enough memory for input device\n");
			goto err_unreg_devs;
		}

		snprintf(db9->phys[i], sizeof(db9->phys[i]),
			 "%s/input%d", db9->pd->port->name, i);

		input_dev->name = db9_mode->name;
		input_dev->phys = db9->phys[i];
		input_dev->id.bustype = BUS_PARPORT;
		input_dev->id.vendor = 0x0002;
		input_dev->id.product = mode;
		input_dev->id.version = 0x0100;

		input_set_drvdata(input_dev, db9);

		input_dev->open = db9_open;
		input_dev->close = db9_close;

		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
		for (j = 0; j < db9_mode->n_buttons; j++)
			set_bit(db9_mode->buttons[j], input_dev->keybit);
		for (j = 0; j < db9_mode->n_axis; j++) {
			if (j < 2)
				input_set_abs_params(input_dev, db9_abs[j], -1, 1, 0, 0);
			else
				input_set_abs_params(input_dev, db9_abs[j], 1, 255, 0, 0);
		}

		if (input_register_device(input_dev))
			goto err_free_dev;
	}

	db9_base[port_idx] = db9;
	return;

 err_free_dev:
	input_free_device(db9->dev[i]);
 err_unreg_devs:
	while (--i >= 0)
		input_unregister_device(db9->dev[i]);
	kfree(db9);
 err_unreg_pardev:
	parport_unregister_device(pd);
}

static void db9_detach(struct parport *port)
{
	int i;
	struct db9 *db9;

	for (i = 0; i < DB9_MAX_PORTS; i++) {
		if (db9_base[i] && db9_base[i]->parportno == port->number)
			break;
	}

	if (i == DB9_MAX_PORTS)
		return;

	db9 = db9_base[i];
	db9_base[i] = NULL;

	for (i = 0; i < min(db9_modes[db9->mode].n_pads, DB9_MAX_DEVICES); i++)
		input_unregister_device(db9->dev[i]);
	parport_unregister_device(db9->pd);
	kfree(db9);
}

static struct parport_driver db9_parport_driver = {
	.name = "db9",
	.match_port = db9_attach,
	.detach = db9_detach,
	.devmodel = true,
};

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

	for (i = 0; i < DB9_MAX_PORTS; i++) {
		if (db9_cfg[i].nargs == 0 || db9_cfg[i].args[DB9_ARG_PARPORT] < 0)
			continue;

		if (db9_cfg[i].nargs < 2) {
			printk(KERN_ERR "db9.c: Device type must be specified.\n");
			return -EINVAL;
		}

		have_dev = 1;
	}

	if (!have_dev)
		return -ENODEV;

	return parport_register_driver(&db9_parport_driver);
}

static void __exit db9_exit(void)
{
	parport_unregister_driver(&db9_parport_driver);
}

module_init(db9_init);
module_exit(db9_exit);
