/*
 * $$
 *
 * 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);

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

	ff = dev->ff;

	while (*ff >= 0) {
		set_bit(*ff, hidinput->input.ffbit);
		++ff;
	}

	hidinput->input.upload_effect = hid_lgff_upload_effect;
	hidinput->input.flush = hid_lgff_flush;

	set_bit(EV_FF, hidinput->input.evbit);
	hidinput->input.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);
}
