/*
 * $Id: amijoy.c,v 1.13 2002/01/22 20:26:32 vojtech Exp $
 *
 *  Copyright (c) 1998-2001 Vojtech Pavlik
 */

/*
 * Driver for Amiga joysticks for Linux/m68k
 */

/*
 * 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/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>

#include <asm/system.h>
#include <asm/amigahw.h>
#include <asm/amigaints.h>

MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Driver for Amiga joysticks");
MODULE_LICENSE("GPL");

static int amijoy[2] = { 0, 1 };
module_param_array_named(map, amijoy, uint, NULL, 0);
MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is 0,1)");

__obsolete_setup("amijoy=");

static int amijoy_used;
static DECLARE_MUTEX(amijoy_sem);
static struct input_dev amijoy_dev[2];
static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };

static char *amijoy_name = "Amiga joystick";

static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
	int i, data = 0, button = 0;

	for (i = 0; i < 2; i++)
		if (amijoy[i]) {

			switch (i) {
				case 0: data = ~custom.joy0dat; button = (~ciaa.pra >> 6) & 1; break;
				case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
			}

			input_regs(amijoy_dev + i, fp);

			input_report_key(amijoy_dev + i, BTN_TRIGGER, button);

			input_report_abs(amijoy_dev + i, ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
			data = ~(data ^ (data << 1));
			input_report_abs(amijoy_dev + i, ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1));

			input_sync(amijoy_dev + i);
		}
	return IRQ_HANDLED;
}

static int amijoy_open(struct input_dev *dev)
{
	int err;

	err = down_interruptible(&amijoy_sem);
	if (err)
		return err;

	if (!amijoy_used && request_irq(IRQ_AMIGA_VERTB, amijoy_interrupt, 0, "amijoy", amijoy_interrupt)) {
		printk(KERN_ERR "amijoy.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB);
		err = -EBUSY;
		goto out;
	}

	amijoy_used++;
out:
	up(&amijoy_sem);
	return err;
}

static void amijoy_close(struct input_dev *dev)
{
	down(&amijoy_sem);
	if (!--amijoy_used)
		free_irq(IRQ_AMIGA_VERTB, amijoy_interrupt);
	up(&amijoy_sem);
}

static int __init amijoy_init(void)
{
	int i, j;

	for (i = 0; i < 2; i++)
		if (amijoy[i]) {
			if (!request_mem_region(CUSTOM_PHYSADDR+10+i*2, 2,
						"amijoy [Denise]")) {
				if (i == 1 && amijoy[0]) {
					input_unregister_device(amijoy_dev);
					release_mem_region(CUSTOM_PHYSADDR+10, 2);
				}
				return -EBUSY;
			}

			amijoy_dev[i].open = amijoy_open;
			amijoy_dev[i].close = amijoy_close;
			amijoy_dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
			amijoy_dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
			amijoy_dev[i].keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
			for (j = 0; j < 2; j++) {
				amijoy_dev[i].absmin[ABS_X + j] = -1;
				amijoy_dev[i].absmax[ABS_X + j] = 1;
			}

			amijoy_dev[i].name = amijoy_name;
			amijoy_dev[i].phys = amijoy_phys[i];
			amijoy_dev[i].id.bustype = BUS_AMIGA;
			amijoy_dev[i].id.vendor = 0x0001;
			amijoy_dev[i].id.product = 0x0003;
			amijoy_dev[i].id.version = 0x0100;

			input_register_device(amijoy_dev + i);
			printk(KERN_INFO "input: %s at joy%ddat\n", amijoy_name, i);
		}
	return 0;
}

static void __exit amijoy_exit(void)
{
	int i;

	for (i = 0; i < 2; i++)
		if (amijoy[i]) {
			input_unregister_device(amijoy_dev + i);
			release_mem_region(CUSTOM_PHYSADDR+10+i*2, 2);
		}
}

module_init(amijoy_init);
module_exit(amijoy_exit);
