/*
 * $$
 *
 * Force feedback support for hid-compliant for some of the devices from
 * Logitech, namely:
 * - WingMan Cordless RumblePad
 * - WingMan Force 3D
 *
 *  Copyright (c) 2002-2004 Johann Deneux
 */

/*
 * 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 by
 * e-mail - mail your message to <johann.deneux@it.uu.se>
 */

#include <linux/input.h>
#include <linux/sched.h>

//#define DEBUG
#include <linux/usb.h>

#include <linux/circ_buf.h>

#include "hid.h"
#include "fixp-arith.h"


/* Periodicity of the update */
#define PERIOD (HZ/10)

#define RUN_AT(t) (jiffies + (t))

/* Effect status */
#define EFFECT_STARTED 0     /* Effect is going to play after some time
				(ff_replay.delay) */
#define EFFECT_PLAYING 1     /* Effect is being played */
#define EFFECT_USED    2

// For lgff_device::flags
#define DEVICE_CLOSING 0     /* The driver is being unitialised */

/* Check that the current process can access an effect */
#define CHECK_OWNERSHIP(effect) (current->pid == 0 \
        || effect.owner == current->pid)

#define LGFF_CHECK_OWNERSHIP(i, l) \
        (i>=0 && i<LGFF_EFFECTS \
        && test_bit(EFFECT_USED, l->effects[i].flags) \
        && CHECK_OWNERSHIP(l->effects[i]))

#define LGFF_EFFECTS 8

struct device_type {
	u16 idVendor;
	u16 idProduct;
	signed short *ff;
};

struct lgff_effect {
	pid_t owner;

	struct ff_effect effect;

	unsigned long flags[1];
	unsigned int count;          /* Number of times left to play */
	unsigned long started_at;    /* When the effect started to play */
};

struct lgff_device {
	struct hid_device* hid;

	struct hid_report* constant;
	struct hid_report* rumble;
	struct hid_report* condition;

	struct lgff_effect effects[LGFF_EFFECTS];
	spinlock_t lock;             /* device-level lock. Having locks on
					a per-effect basis could be nice, but
					isn't really necessary */

	unsigned long flags[1];      /* Contains various information about the
				        state of the driver for this device */

	struct timer_list timer;
};

/* Callbacks */
static void hid_lgff_exit(struct hid_device* hid);
static int hid_lgff_event(struct hid_device *hid, struct input_dev *input,
			  unsigned int type, unsigned int code, int value);
static int hid_lgff_flush(struct input_dev *input, struct file *file);
static int hid_lgff_upload_effect(struct input_dev *input,
				  struct ff_effect *effect);
static int hid_lgff_erase(struct input_dev *input, int id);

/* Local functions */
static void hid_lgff_input_init(struct hid_device* hid);
static void hid_lgff_timer(unsigned long timer_data);
static struct hid_report* hid_lgff_duplicate_report(struct hid_report*);
static void hid_lgff_delete_report(struct hid_report*);

static signed short ff_rumble[] = {
	FF_RUMBLE,
	-1
};

static signed short ff_joystick[] = {
	FF_CONSTANT,
	-1
};

static struct device_type devices[] = {
	{0x046d, 0xc211, ff_rumble},
	{0x046d, 0xc219, ff_rumble},
	{0x046d, 0xc283, ff_joystick},
	{0x0000, 0x0000, ff_joystick}
};

int hid_lgff_init(struct hid_device* hid)
{
	struct lgff_device *private;
	struct hid_report* report;
	struct hid_field* field;

	/* Find the report to use */
	if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
		err("No output report found");
		return -1;
	}
	/* Check that the report looks ok */
	report = (struct hid_report*)hid->report_enum[HID_OUTPUT_REPORT].report_list.next;
	if (!report) {
		err("NULL output report");
		return -1;
	}
	field = report->field[0];
	if (!field) {
		err("NULL field");
		return -1;
	}

	private = kmalloc(sizeof(struct lgff_device), GFP_KERNEL);
	if (!private)
		return -1;
	memset(private, 0, sizeof(struct lgff_device));
	hid->ff_private = private;

	/* Input init */
	hid_lgff_input_init(hid);


	private->constant = hid_lgff_duplicate_report(report);
	if (!private->constant) {
		kfree(private);
		return -1;
	}
	private->constant->field[0]->value[0] = 0x51;
	private->constant->field[0]->value[1] = 0x08;
	private->constant->field[0]->value[2] = 0x7f;
	private->constant->field[0]->value[3] = 0x7f;

	private->rumble = hid_lgff_duplicate_report(report);
	if (!private->rumble) {
		hid_lgff_delete_report(private->constant);
		kfree(private);
		return -1;
	}
	private->rumble->field[0]->value[0] = 0x42;


	private->condition = hid_lgff_duplicate_report(report);
	if (!private->condition) {
		hid_lgff_delete_report(private->rumble);
		hid_lgff_delete_report(private->constant);
		kfree(private);
		return -1;
	}

	private->hid = hid;

	spin_lock_init(&private->lock);
	init_timer(&private->timer);
	private->timer.data = (unsigned long)private;
	private->timer.function = hid_lgff_timer;

	/* Event and exit callbacks */
	hid->ff_exit = hid_lgff_exit;
	hid->ff_event = hid_lgff_event;

	/* Start the update task */
	private->timer.expires = RUN_AT(PERIOD);
	add_timer(&private->timer);  /*TODO: only run the timer when at least
				       one effect is playing */

	printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n");

	return 0;
}

static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report)
{
	struct hid_report* ret;

	ret = kmalloc(sizeof(struct lgff_device), GFP_KERNEL);
	if (!ret)
		return NULL;
	*ret = *report;

	ret->field[0] = kmalloc(sizeof(struct hid_field), GFP_KERNEL);
	if (!ret->field[0]) {
		kfree(ret);
		return NULL;
	}
	*ret->field[0] = *report->field[0];

	ret->field[0]->value = kmalloc(sizeof(s32[8]), GFP_KERNEL);
	if (!ret->field[0]->value) {
		kfree(ret->field[0]);
		kfree(ret);
		return NULL;
	}
	memset(ret->field[0]->value, 0, sizeof(s32[8]));

	return ret;
}

static void hid_lgff_delete_report(struct hid_report* report)
{
	if (report) {
		kfree(report->field[0]->value);
		kfree(report->field[0]);
		kfree(report);
	}
}

static void hid_lgff_input_init(struct hid_device* hid)
{
	struct device_type* dev = devices;
	signed short* ff;
	u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor);
	u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct);
	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
	struct input_dev *input_dev = hidinput->input;

	while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
		dev++;

	for (ff = dev->ff; *ff >= 0; ff++)
		set_bit(*ff, input_dev->ffbit);

	input_dev->upload_effect = hid_lgff_upload_effect;
	input_dev->flush = hid_lgff_flush;

	set_bit(EV_FF, input_dev->evbit);
	input_dev->ff_effects_max = LGFF_EFFECTS;
}

static void hid_lgff_exit(struct hid_device* hid)
{
	struct lgff_device *lgff = hid->ff_private;

	set_bit(DEVICE_CLOSING, lgff->flags);
	del_timer_sync(&lgff->timer);

	hid_lgff_delete_report(lgff->condition);
	hid_lgff_delete_report(lgff->rumble);
	hid_lgff_delete_report(lgff->constant);

	kfree(lgff);
}

static int hid_lgff_event(struct hid_device *hid, struct input_dev* input,
			  unsigned int type, unsigned int code, int value)
{
	struct lgff_device *lgff = hid->ff_private;
	struct lgff_effect *effect = lgff->effects + code;
	unsigned long flags;

	if (type != EV_FF)                     return -EINVAL;
	if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES;
	if (value < 0)                         return -EINVAL;

	spin_lock_irqsave(&lgff->lock, flags);

	if (value > 0) {
		if (test_bit(EFFECT_STARTED, effect->flags)) {
			spin_unlock_irqrestore(&lgff->lock, flags);
			return -EBUSY;
		}
		if (test_bit(EFFECT_PLAYING, effect->flags)) {
			spin_unlock_irqrestore(&lgff->lock, flags);
			return -EBUSY;
		}

		effect->count = value;

		if (effect->effect.replay.delay) {
			set_bit(EFFECT_STARTED, effect->flags);
		} else {
			set_bit(EFFECT_PLAYING, effect->flags);
		}
		effect->started_at = jiffies;
	}
	else { /* value == 0 */
		clear_bit(EFFECT_STARTED, effect->flags);
		clear_bit(EFFECT_PLAYING, effect->flags);
	}

	spin_unlock_irqrestore(&lgff->lock, flags);

	return 0;

}

/* Erase all effects this process owns */
static int hid_lgff_flush(struct input_dev *dev, struct file *file)
{
	struct hid_device *hid = dev->private;
	struct lgff_device *lgff = hid->ff_private;
	int i;

	for (i=0; i<dev->ff_effects_max; ++i) {

		/*NOTE: no need to lock here. The only times EFFECT_USED is
		  modified is when effects are uploaded or when an effect is
		  erased. But a process cannot close its dev/input/eventX fd
		  and perform ioctls on the same fd all at the same time */
		if ( current->pid == lgff->effects[i].owner
		     && test_bit(EFFECT_USED, lgff->effects[i].flags)) {

			if (hid_lgff_erase(dev, i))
				warn("erase effect %d failed", i);
		}

	}

	return 0;
}

static int hid_lgff_erase(struct input_dev *dev, int id)
{
	struct hid_device *hid = dev->private;
	struct lgff_device *lgff = hid->ff_private;
	unsigned long flags;

	if (!LGFF_CHECK_OWNERSHIP(id, lgff)) return -EACCES;

	spin_lock_irqsave(&lgff->lock, flags);
	lgff->effects[id].flags[0] = 0;
	spin_unlock_irqrestore(&lgff->lock, flags);

	return 0;
}

static int hid_lgff_upload_effect(struct input_dev* input,
				  struct ff_effect* effect)
{
	struct hid_device *hid = input->private;
	struct lgff_device *lgff = hid->ff_private;
	struct lgff_effect new;
	int id;
	unsigned long flags;

	dbg("ioctl rumble");

	if (!test_bit(effect->type, input->ffbit)) return -EINVAL;

	spin_lock_irqsave(&lgff->lock, flags);

	if (effect->id == -1) {
		int i;

		for (i=0; i<LGFF_EFFECTS && test_bit(EFFECT_USED, lgff->effects[i].flags); ++i);
		if (i >= LGFF_EFFECTS) {
			spin_unlock_irqrestore(&lgff->lock, flags);
			return -ENOSPC;
		}

		effect->id = i;
		lgff->effects[i].owner = current->pid;
		lgff->effects[i].flags[0] = 0;
		set_bit(EFFECT_USED, lgff->effects[i].flags);
	}
	else if (!LGFF_CHECK_OWNERSHIP(effect->id, lgff)) {
		spin_unlock_irqrestore(&lgff->lock, flags);
		return -EACCES;
	}

	id = effect->id;
	new = lgff->effects[id];

	new.effect = *effect;

	if (test_bit(EFFECT_STARTED, lgff->effects[id].flags)
	    || test_bit(EFFECT_STARTED, lgff->effects[id].flags)) {

		/* Changing replay parameters is not allowed (for the time
		   being) */
		if (new.effect.replay.delay != lgff->effects[id].effect.replay.delay
		    || new.effect.replay.length != lgff->effects[id].effect.replay.length) {
			spin_unlock_irqrestore(&lgff->lock, flags);
			return -ENOSYS;
		}

		lgff->effects[id] = new;

	} else {
		lgff->effects[id] = new;
	}

	spin_unlock_irqrestore(&lgff->lock, flags);
	return 0;
}

static void hid_lgff_timer(unsigned long timer_data)
{
	struct lgff_device *lgff = (struct lgff_device*)timer_data;
	struct hid_device *hid = lgff->hid;
	unsigned long flags;
	int x = 0x7f, y = 0x7f;   // Coordinates of constant effects
	unsigned int left = 0, right = 0;   // Rumbling
	int i;

	spin_lock_irqsave(&lgff->lock, flags);

	for (i=0; i<LGFF_EFFECTS; ++i) {
		struct lgff_effect* effect = lgff->effects +i;

		if (test_bit(EFFECT_PLAYING, effect->flags)) {

			switch (effect->effect.type) {
			case FF_CONSTANT: {
				//TODO: handle envelopes
				int degrees = effect->effect.direction * 360 >> 16;
				x += fixp_mult(fixp_sin(degrees),
					       fixp_new16(effect->effect.u.constant.level));
				y += fixp_mult(-fixp_cos(degrees),
					       fixp_new16(effect->effect.u.constant.level));
			}       break;
			case FF_RUMBLE:
				right += effect->effect.u.rumble.strong_magnitude;
				left += effect->effect.u.rumble.weak_magnitude;
				break;
			};

			/* One run of the effect is finished playing */
			if (time_after(jiffies,
					effect->started_at
					+ effect->effect.replay.delay*HZ/1000
					+ effect->effect.replay.length*HZ/1000)) {
				dbg("Finished playing once %d", i);
				if (--effect->count <= 0) {
					dbg("Stopped %d", i);
					clear_bit(EFFECT_PLAYING, effect->flags);
				}
				else {
					dbg("Start again %d", i);
					if (effect->effect.replay.length != 0) {
						clear_bit(EFFECT_PLAYING, effect->flags);
						set_bit(EFFECT_STARTED, effect->flags);
					}
					effect->started_at = jiffies;
				}
			}

		} else if (test_bit(EFFECT_STARTED, lgff->effects[i].flags)) {
			/* Check if we should start playing the effect */
			if (time_after(jiffies,
					lgff->effects[i].started_at
					+ lgff->effects[i].effect.replay.delay*HZ/1000)) {
				dbg("Now playing %d", i);
				clear_bit(EFFECT_STARTED, lgff->effects[i].flags);
				set_bit(EFFECT_PLAYING, lgff->effects[i].flags);
			}
		}
	}

#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff

	// Clamp values
	CLAMP(x);
	CLAMP(y);
	CLAMP(left);
	CLAMP(right);

#undef CLAMP

	if (x != lgff->constant->field[0]->value[2]
	    || y != lgff->constant->field[0]->value[3]) {
		lgff->constant->field[0]->value[2] = x;
		lgff->constant->field[0]->value[3] = y;
		dbg("(x,y)=(%04x, %04x)", x, y);
		hid_submit_report(hid, lgff->constant, USB_DIR_OUT);
	}

	if (left != lgff->rumble->field[0]->value[2]
	    || right != lgff->rumble->field[0]->value[3]) {
		lgff->rumble->field[0]->value[2] = left;
		lgff->rumble->field[0]->value[3] = right;
		dbg("(left,right)=(%04x, %04x)", left, right);
		hid_submit_report(hid, lgff->rumble, USB_DIR_OUT);
	}

	if (!test_bit(DEVICE_CLOSING, lgff->flags)) {
		lgff->timer.expires = RUN_AT(PERIOD);
		add_timer(&lgff->timer);
	}

	spin_unlock_irqrestore(&lgff->lock, flags);
}
