/*
 * $Id: grip_mp.c,v 1.9 2002/07/20 19:28:45 bonnland Exp $
 *
 *  Driver for the Gravis Grip Multiport, a gamepad "hub" that
 *  connects up to four 9-pin digital gamepads/joysticks.
 *  Driver tested on SMP and UP kernel versions 2.4.18-4 and 2.4.18-5.
 *
 *  Thanks to Chris Gassib for helpful advice.
 *
 *  Copyright (c)      2002 Brian Bonnlander, Bill Soudan
 *  Copyright (c) 1998-2000 Vojtech Pavlik
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/gameport.h>
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>

#define DRIVER_DESC	"Gravis Grip Multiport driver"

MODULE_AUTHOR("Brian Bonnlander");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

#ifdef GRIP_DEBUG
#define dbg(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" , ## arg)
#else
#define dbg(format, arg...) do {} while (0)
#endif

/*
 * Grip multiport state
 */

struct grip_mp {
	struct gameport *gameport;
	struct input_dev dev[4];
	int mode[4];
	int registered[4];
	int reads;
	int bads;

	/* individual gamepad states */
	int buttons[4];
	int xaxes[4];
	int yaxes[4];
	int dirty[4];     /* has the state been updated? */
};

/*
 * Multiport packet interpretation
 */

#define PACKET_FULL          0x80000000       /* packet is full                        */
#define PACKET_IO_FAST       0x40000000       /* 3 bits per gameport read              */
#define PACKET_IO_SLOW       0x20000000       /* 1 bit per gameport read               */
#define PACKET_MP_MORE       0x04000000       /* multiport wants to send more          */
#define PACKET_MP_DONE       0x02000000       /* multiport done sending                */

/*
 * Packet status code interpretation
 */

#define IO_GOT_PACKET        0x0100           /* Got a packet                           */
#define IO_MODE_FAST         0x0200           /* Used 3 data bits per gameport read     */
#define IO_SLOT_CHANGE       0x0800           /* Multiport physical slot status changed */
#define IO_DONE              0x1000           /* Multiport is done sending packets      */
#define IO_RETRY             0x4000           /* Try again later to get packet          */
#define IO_RESET             0x8000           /* Force multiport to resend all packets  */

/*
 * Gamepad configuration data.  Other 9-pin digital joystick devices
 * may work with the multiport, so this may not be an exhaustive list!
 * Commodore 64 joystick remains untested.
 */

#define GRIP_INIT_DELAY         2000          /*  2 ms */

#define GRIP_MODE_NONE		0
#define GRIP_MODE_RESET         1
#define GRIP_MODE_GP		2
#define GRIP_MODE_C64		3

static int grip_btn_gp[]  = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 };
static int grip_btn_c64[] = { BTN_JOYSTICK, -1 };

static int grip_abs_gp[]  = { ABS_X, ABS_Y, -1 };
static int grip_abs_c64[] = { ABS_X, ABS_Y, -1 };

static int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 };
static int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 };

static char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" };

static const int init_seq[] = {
	1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
	1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1,
	1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
	0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1 };

/* Maps multiport directional values to X,Y axis values (each axis encoded in 3 bits) */

static int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 };

static void register_slot(int i, struct grip_mp *grip);

/*
 * Returns whether an odd or even number of bits are on in pkt.
 */

static int bit_parity(u32 pkt)
{
	int x = pkt ^ (pkt >> 16);
	x ^= x >> 8;
	x ^= x >> 4;
	x ^= x >> 2;
	x ^= x >> 1;
	return x & 1;
}

/*
 * Poll gameport; return true if all bits set in 'onbits' are on and
 * all bits set in 'offbits' are off.
 */

static inline int poll_until(u8 onbits, u8 offbits, int u_sec, struct gameport* gp, u8 *data)
{
	int i, nloops;

	nloops = gameport_time(gp, u_sec);
	for (i = 0; i < nloops; i++) {
		*data = gameport_read(gp);
		if ((*data & onbits) == onbits &&
		    (~(*data) & offbits) == offbits)
			return 1;
	}
	dbg("gameport timed out after %d microseconds.\n", u_sec);
	return 0;
}

/*
 * Gets a 28-bit packet from the multiport.
 *
 * After getting a packet successfully, commands encoded by sendcode may
 * be sent to the multiport.
 *
 * The multiport clock value is reflected in gameport bit B4.
 *
 * Returns a packet status code indicating whether packet is valid, the transfer
 * mode, and any error conditions.
 *
 * sendflags:      current I/O status
 * sendcode:   data to send to the multiport if sendflags is nonzero
 */

static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *packet)
{
	u8  raw_data;            /* raw data from gameport */
	u8  data_mask;           /* packet data bits from raw_data */
	u32 pkt;                 /* packet temporary storage */
	int bits_per_read;       /* num packet bits per gameport read */
	int portvals = 0;        /* used for port value sanity check */
	int i;

	/* Gameport bits B0, B4, B5 should first be off, then B4 should come on. */

	*packet = 0;
	raw_data = gameport_read(gameport);
	if (raw_data & 1)
 		return IO_RETRY;

	for (i = 0; i < 64; i++) {
		raw_data = gameport_read(gameport);
		portvals |= 1 << ((raw_data >> 4) & 3); /* Demux B4, B5 */
	}

	if (portvals == 1) {                            /* B4, B5 off */
		raw_data = gameport_read(gameport);
		portvals = raw_data & 0xf0;

		if (raw_data & 0x31)
			return IO_RESET;
		gameport_trigger(gameport);

		if (!poll_until(0x10, 0, 308, gameport, &raw_data))
			return IO_RESET;
	} else
		return IO_RETRY;

	/* Determine packet transfer mode and prepare for packet construction. */

	if (raw_data & 0x20) {                 /* 3 data bits/read */
		portvals |= raw_data >> 4;     /* Compare B4-B7 before & after trigger */

		if (portvals != 0xb)
			return 0;
		data_mask = 7;
		bits_per_read = 3;
		pkt = (PACKET_FULL | PACKET_IO_FAST) >> 28;
	} else {                                 /* 1 data bit/read */
		data_mask = 1;
		bits_per_read = 1;
		pkt = (PACKET_FULL | PACKET_IO_SLOW) >> 28;
	}

	/* Construct a packet.  Final data bits must be zero. */

	while (1) {
		if (!poll_until(0, 0x10, 77, gameport, &raw_data))
			return IO_RESET;
		raw_data = (raw_data >> 5) & data_mask;

		if (pkt & PACKET_FULL)
			break;
		pkt = (pkt << bits_per_read) | raw_data;

		if (!poll_until(0x10, 0, 77, gameport, &raw_data))
			return IO_RESET;
	}

	if (raw_data)
		return IO_RESET;

	/* If 3 bits/read used, drop from 30 bits to 28. */

	if (bits_per_read == 3) {
		pkt = (pkt & 0xffff0000) | ((pkt << 1) & 0xffff);
		pkt = (pkt >> 2) | 0xf0000000;
	}

	if (bit_parity(pkt) == 1)
		return IO_RESET;

	/* Acknowledge packet receipt */

	if (!poll_until(0x30, 0, 77, gameport, &raw_data))
		return IO_RESET;

	raw_data = gameport_read(gameport);

	if (raw_data & 1)
		return IO_RESET;

	gameport_trigger(gameport);

	if (!poll_until(0, 0x20, 77, gameport, &raw_data))
		return IO_RESET;

        /* Return if we just wanted the packet or multiport wants to send more */

	*packet = pkt;
	if ((sendflags == 0) || ((sendflags & IO_RETRY) && !(pkt & PACKET_MP_DONE)))
		return IO_GOT_PACKET;

	if (pkt & PACKET_MP_MORE)
		return IO_GOT_PACKET | IO_RETRY;

	/* Multiport is done sending packets and is ready to receive data */

	if (!poll_until(0x20, 0, 77, gameport, &raw_data))
		return IO_GOT_PACKET | IO_RESET;

	raw_data = gameport_read(gameport);
	if (raw_data & 1)
		return IO_GOT_PACKET | IO_RESET;

	/* Trigger gameport based on bits in sendcode */

	gameport_trigger(gameport);
	do {
		if (!poll_until(0x20, 0x10, 116, gameport, &raw_data))
			return IO_GOT_PACKET | IO_RESET;

		if (!poll_until(0x30, 0, 193, gameport, &raw_data))
			return IO_GOT_PACKET | IO_RESET;

		if (raw_data & 1)
			return IO_GOT_PACKET | IO_RESET;

		if (sendcode & 1)
			gameport_trigger(gameport);

		sendcode >>= 1;
	} while (sendcode);

	return IO_GOT_PACKET | IO_MODE_FAST;
}

/*
 * Disables and restores interrupts for mp_io(), which does the actual I/O.
 */

static int multiport_io(struct gameport* gameport, int sendflags, int sendcode, u32 *packet)
{
	int status;
	unsigned long flags;

	local_irq_save(flags);
	status = mp_io(gameport, sendflags, sendcode, packet);
	local_irq_restore(flags);

	return status;
}

/*
 * Puts multiport into digital mode.  Multiport LED turns green.
 *
 * Returns true if a valid digital packet was received, false otherwise.
 */

static int dig_mode_start(struct gameport *gameport, u32 *packet)
{
	int i, seq_len = sizeof(init_seq)/sizeof(int);
	int flags, tries = 0, bads = 0;

	for (i = 0; i < seq_len; i++) {     /* Send magic sequence */
		if (init_seq[i])
			gameport_trigger(gameport);
		udelay(GRIP_INIT_DELAY);
	}

	for (i = 0; i < 16; i++)            /* Wait for multiport to settle */
		udelay(GRIP_INIT_DELAY);

	while (tries < 64 && bads < 8) {    /* Reset multiport and try getting a packet */

		flags = multiport_io(gameport, IO_RESET, 0x27, packet);

		if (flags & IO_MODE_FAST)
			return 1;

		if (flags & IO_RETRY)
			tries++;
		else
			bads++;
	}
	return 0;
}

/*
 * Packet structure: B0-B15   => gamepad state
 *                   B16-B20  => gamepad device type
 *                   B21-B24  => multiport slot index (1-4)
 *
 * Known device types: 0x1f (grip pad), 0x0 (no device).  Others may exist.
 *
 * Returns the packet status.
 */

static int get_and_decode_packet(struct grip_mp *grip, int flags)
{
	u32 packet;
	int joytype = 0;
	int slot = 0;

	/* Get a packet and check for validity */

	flags &= IO_RESET | IO_RETRY;
	flags = multiport_io(grip->gameport, flags, 0, &packet);
	grip->reads++;

	if (packet & PACKET_MP_DONE)
		flags |= IO_DONE;

	if (flags && !(flags & IO_GOT_PACKET)) {
		grip->bads++;
		return flags;
	}

	/* Ignore non-gamepad packets, e.g. multiport hardware version */

	slot = ((packet >> 21) & 0xf) - 1;
	if ((slot < 0) || (slot > 3))
		return flags;

	/*
	 * Handle "reset" packets, which occur at startup, and when gamepads
	 * are removed or plugged in.  May contain configuration of a new gamepad.
	 */

	joytype = (packet >> 16) & 0x1f;
	if (!joytype) {

		if (grip->registered[slot]) {
			printk(KERN_INFO "grip_mp: removing %s, slot %d\n",
			       grip_name[grip->mode[slot]], slot);
			input_unregister_device(grip->dev + slot);
			grip->registered[slot] = 0;
		}
		dbg("Reset: grip multiport slot %d\n", slot);
		grip->mode[slot] = GRIP_MODE_RESET;
		flags |= IO_SLOT_CHANGE;
		return flags;
	}

	/* Interpret a grip pad packet */

	if (joytype == 0x1f) {

		int dir = (packet >> 8) & 0xf;          /* eight way directional value */
		grip->buttons[slot] = (~packet) & 0xff;
		grip->yaxes[slot] = ((axis_map[dir] >> 2) & 3) - 1;
		grip->xaxes[slot] = (axis_map[dir] & 3) - 1;
		grip->dirty[slot] = 1;

		if (grip->mode[slot] == GRIP_MODE_RESET)
			flags |= IO_SLOT_CHANGE;

		grip->mode[slot] = GRIP_MODE_GP;

		if (!grip->registered[slot]) {
			dbg("New Grip pad in multiport slot %d.\n", slot);
			register_slot(slot, grip);
		}
		return flags;
	}

	/* Handle non-grip device codes.  For now, just print diagnostics. */

	{
		static int strange_code = 0;
		if (strange_code != joytype) {
			printk(KERN_INFO "Possible non-grip pad/joystick detected.\n");
			printk(KERN_INFO "Got joy type 0x%x and packet 0x%x.\n", joytype, packet);
			strange_code = joytype;
		}
	}
	return flags;
}

/*
 * Returns true if all multiport slot states appear valid.
 */

static int slots_valid(struct grip_mp *grip)
{
	int flags, slot, invalid = 0, active = 0;

	flags = get_and_decode_packet(grip, 0);
	if (!(flags & IO_GOT_PACKET))
		return 0;

	for (slot = 0; slot < 4; slot++) {
		if (grip->mode[slot] == GRIP_MODE_RESET)
			invalid = 1;
		if (grip->mode[slot] != GRIP_MODE_NONE)
			active = 1;
	}

	/* Return true if no active slot but multiport sent all its data */
	if (!active)
		return (flags & IO_DONE) ? 1 : 0;

	/* Return false if invalid device code received */
	return invalid ? 0 : 1;
}

/*
 * Returns whether the multiport was placed into digital mode and
 * able to communicate its state successfully.
 */

static int multiport_init(struct grip_mp *grip)
{
	int dig_mode, initialized = 0, tries = 0;
	u32 packet;

	dig_mode = dig_mode_start(grip->gameport, &packet);
	while (!dig_mode && tries < 4) {
		dig_mode = dig_mode_start(grip->gameport, &packet);
		tries++;
	}

	if (dig_mode)
		dbg("multiport_init(): digital mode activated.\n");
	else {
		dbg("multiport_init(): unable to activate digital mode.\n");
		return 0;
	}

	/* Get packets, store multiport state, and check state's validity */
	for (tries = 0; tries < 4096; tries++) {
		if ( slots_valid(grip) ) {
			initialized = 1;
			break;
		}
	}
	dbg("multiport_init(): initialized == %d\n", initialized);
	return initialized;
}

/*
 * Reports joystick state to the linux input layer.
 */

static void report_slot(struct grip_mp *grip, int slot)
{
	struct input_dev *dev = &(grip->dev[slot]);
	int i, buttons = grip->buttons[slot];

	/* Store button states with linux input driver */

	for (i = 0; i < 8; i++)
		input_report_key(dev, grip_btn_gp[i], (buttons >> i) & 1);

	/* Store axis states with linux driver */

	input_report_abs(dev, ABS_X, grip->xaxes[slot]);
	input_report_abs(dev, ABS_Y, grip->yaxes[slot]);

	/* Tell the receiver of the events to process them */

	input_sync(dev);

	grip->dirty[slot] = 0;
}

/*
 * Get the multiport state.
 */

static void grip_poll(struct gameport *gameport)
{
	struct grip_mp *grip = gameport_get_drvdata(gameport);
	int i, npkts, flags;

	for (npkts = 0; npkts < 4; npkts++) {
		flags = IO_RETRY;
		for (i = 0; i < 32; i++) {
			flags = get_and_decode_packet(grip, flags);
			if ((flags & IO_GOT_PACKET) || !(flags & IO_RETRY))
				break;
		}
		if (flags & IO_DONE)
			break;
	}

	for (i = 0; i < 4; i++)
		if (grip->dirty[i])
			report_slot(grip, i);
}

/*
 * Called when a joystick device file is opened
 */

static int grip_open(struct input_dev *dev)
{
	struct grip_mp *grip = dev->private;

	gameport_start_polling(grip->gameport);
	return 0;
}

/*
 * Called when a joystick device file is closed
 */

static void grip_close(struct input_dev *dev)
{
	struct grip_mp *grip = dev->private;

	gameport_start_polling(grip->gameport);
}

/*
 * Tell the linux input layer about a newly plugged-in gamepad.
 */

static void register_slot(int slot, struct grip_mp *grip)
{
	int j, t;

	grip->dev[slot].private = grip;
	grip->dev[slot].open = grip_open;
	grip->dev[slot].close = grip_close;
	grip->dev[slot].name = grip_name[grip->mode[slot]];
	grip->dev[slot].id.bustype = BUS_GAMEPORT;
	grip->dev[slot].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
	grip->dev[slot].id.product = 0x0100 + grip->mode[slot];
	grip->dev[slot].id.version = 0x0100;
	grip->dev[slot].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);

	for (j = 0; (t = grip_abs[grip->mode[slot]][j]) >= 0; j++)
		input_set_abs_params(&grip->dev[slot], t, -1, 1, 0, 0);

	for (j = 0; (t = grip_btn[grip->mode[slot]][j]) >= 0; j++)
		if (t > 0)
			set_bit(t, grip->dev[slot].keybit);

	input_register_device(grip->dev + slot);
	grip->registered[slot] = 1;

	if (grip->dirty[slot])	            /* report initial state, if any */
		report_slot(grip, slot);

	printk(KERN_INFO "grip_mp: added %s, slot %d\n",
	       grip_name[grip->mode[slot]], slot);
}

static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
{
	struct grip_mp *grip;
	int err;

	if (!(grip = kcalloc(1, sizeof(struct grip_mp), GFP_KERNEL)))
		return -ENOMEM;

	grip->gameport = gameport;

	gameport_set_drvdata(gameport, grip);

	err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW);
	if (err)
		goto fail1;

	gameport_set_poll_handler(gameport, grip_poll);
	gameport_set_poll_interval(gameport, 20);

	if (!multiport_init(grip)) {
		err = -ENODEV;
		goto fail2;
	}

	if (!grip->mode[0] && !grip->mode[1] && !grip->mode[2] && !grip->mode[3]) {
		/* nothing plugged in */
		err = -ENODEV;
		goto fail2;
	}

	return 0;

fail2:	gameport_close(gameport);
fail1:	gameport_set_drvdata(gameport, NULL);
	kfree(grip);
	return err;
}

static void grip_disconnect(struct gameport *gameport)
{
	struct grip_mp *grip = gameport_get_drvdata(gameport);
	int i;

	for (i = 0; i < 4; i++)
		if (grip->registered[i])
			input_unregister_device(grip->dev + i);
	gameport_close(gameport);
	gameport_set_drvdata(gameport, NULL);
	kfree(grip);
}

static struct gameport_driver grip_drv = {
	.driver		= {
		.name	= "grip_mp",
	},
	.description	= DRIVER_DESC,
	.connect	= grip_connect,
	.disconnect	= grip_disconnect,
};

static int __init grip_init(void)
{
	gameport_register_driver(&grip_drv);
	return 0;
}

static void __exit grip_exit(void)
{
	gameport_unregister_driver(&grip_drv);
}

module_init(grip_init);
module_exit(grip_exit);
