/*
 * Force feedback support for various HID compliant devices by ThrustMaster:
 *    ThrustMaster FireStorm Dual Power 2
 * and possibly others whose device ids haven't been added.
 *
 *  Modified to support ThrustMaster devices by Zinx Verituse
 *  on 2003-01-25 from the Logitech force feedback driver,
 *  which is by Johann Deneux.
 *
 *  Copyright (c) 2003 Zinx Verituse <zinx@epicsol.org>
 *  Copyright (c) 2002 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
 */

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

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

#include <linux/circ_buf.h>

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

/* Usages for thrustmaster devices I know about */
#define THRUSTMASTER_USAGE_RUMBLE_LR	(HID_UP_GENDESK | 0xbb)
#define DELAY_CALC(t,delay)		((t) + (delay)*HZ/1000)

/* Effect status */
#define EFFECT_STARTED 0	/* Effect is going to play after some time */
#define EFFECT_PLAYING 1	/* Effect is playing */
#define EFFECT_USED    2

/* For tmff_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 TMFF_CHECK_ID(id)	((id) >= 0 && (id) < TMFF_EFFECTS)

#define TMFF_CHECK_OWNERSHIP(i, l) \
        (test_bit(EFFECT_USED, l->effects[i].flags) \
        && CHECK_OWNERSHIP(l->effects[i]))

#define TMFF_EFFECTS 8

struct tmff_effect {
	pid_t owner;

	struct ff_effect effect;

	unsigned long flags[1];
	unsigned int count;             /* Number of times left to play */

	unsigned long play_at;          /* When the effect starts to play */
	unsigned long stop_at;		/* When the effect ends */
};

struct tmff_device {
	struct hid_device *hid;

	struct hid_report *report;

	struct hid_field *rumble;

	unsigned int effects_playing;
	struct tmff_effect effects[TMFF_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_tmff_exit(struct hid_device *hid);
static int hid_tmff_event(struct hid_device *hid, struct input_dev *input,
			  unsigned int type, unsigned int code, int value);
static int hid_tmff_flush(struct input_dev *input, struct file *file);
static int hid_tmff_upload_effect(struct input_dev *input,
				  struct ff_effect *effect);
static int hid_tmff_erase(struct input_dev *input, int id);

/* Local functions */
static void hid_tmff_recalculate_timer(struct tmff_device *tmff);
static void hid_tmff_timer(unsigned long timer_data);

int hid_tmff_init(struct hid_device *hid)
{
	struct tmff_device *private;
	struct list_head *pos;
	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);

	private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL);
	if (!private)
		return -ENOMEM;

	memset(private, 0, sizeof(struct tmff_device));
	hid->ff_private = private;

	/* Find the report to use */
	__list_for_each(pos, &hid->report_enum[HID_OUTPUT_REPORT].report_list) {
		struct hid_report *report = (struct hid_report *)pos;
		int fieldnum;

		for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) {
			struct hid_field *field = report->field[fieldnum];

			if (field->maxusage <= 0)
				continue;

			switch (field->usage[0].hid) {
				case THRUSTMASTER_USAGE_RUMBLE_LR:
					if (field->report_count < 2) {
						warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR with report_count < 2");
						continue;
					}

					if (field->logical_maximum == field->logical_minimum) {
						warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR with logical_maximum == logical_minimum");
						continue;
					}

					if (private->report && private->report != report) {
						warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR in other report");
						continue;
					}

					if (private->rumble && private->rumble != field) {
						warn("ignoring duplicate THRUSTMASTER_USAGE_RUMBLE_LR");
						continue;
					}

					private->report = report;
					private->rumble = field;

					set_bit(FF_RUMBLE, hidinput->input.ffbit);
					break;

				default:
					warn("ignoring unknown output usage %08x", field->usage[0].hid);
					continue;
			}

			/* Fallthrough to here only when a valid usage is found */
			hidinput->input.upload_effect = hid_tmff_upload_effect;
			hidinput->input.flush = hid_tmff_flush;

			set_bit(EV_FF, hidinput->input.evbit);
			hidinput->input.ff_effects_max = TMFF_EFFECTS;
		}
	}

	private->hid = hid;

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

	/* Event and exit callbacks */
	hid->ff_exit = hid_tmff_exit;
	hid->ff_event = hid_tmff_event;

	info("Force feedback for ThrustMaster rumble pad devices by Zinx Verituse <zinx@epicsol.org>");

	return 0;
}

static void hid_tmff_exit(struct hid_device *hid)
{
	struct tmff_device *tmff = hid->ff_private;
	unsigned long flags;

	spin_lock_irqsave(&tmff->lock, flags);

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

	spin_unlock_irqrestore(&tmff->lock, flags);

	kfree(tmff);
}

static int hid_tmff_event(struct hid_device *hid, struct input_dev *input,
			  unsigned int type, unsigned int code, int value)
{
	struct tmff_device *tmff = hid->ff_private;
	struct tmff_effect *effect = &tmff->effects[code];
	unsigned long flags;

	if (type != EV_FF)
		return -EINVAL;
	if (!TMFF_CHECK_ID(code))
		return -EINVAL;
	if (!TMFF_CHECK_OWNERSHIP(code, tmff))
		return -EACCES;
	if (value < 0)
		return -EINVAL;

	spin_lock_irqsave(&tmff->lock, flags);

	if (value > 0) {
		set_bit(EFFECT_STARTED, effect->flags);
		clear_bit(EFFECT_PLAYING, effect->flags);
		effect->count = value;
		effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay);
	} else {
		clear_bit(EFFECT_STARTED, effect->flags);
		clear_bit(EFFECT_PLAYING, effect->flags);
	}

	hid_tmff_recalculate_timer(tmff);

	spin_unlock_irqrestore(&tmff->lock, flags);

	return 0;

}

/* Erase all effects this process owns */

static int hid_tmff_flush(struct input_dev *dev, struct file *file)
{
	struct hid_device *hid = dev->private;
	struct tmff_device *tmff = 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 == tmff->effects[i].owner
		     && test_bit(EFFECT_USED, tmff->effects[i].flags))
			if (hid_tmff_erase(dev, i))
				warn("erase effect %d failed", i);


	return 0;
}

static int hid_tmff_erase(struct input_dev *dev, int id)
{
	struct hid_device *hid = dev->private;
	struct tmff_device *tmff = hid->ff_private;
	unsigned long flags;

	if (!TMFF_CHECK_ID(id))
		return -EINVAL;
	if (!TMFF_CHECK_OWNERSHIP(id, tmff))
		return -EACCES;

	spin_lock_irqsave(&tmff->lock, flags);

	tmff->effects[id].flags[0] = 0;
	hid_tmff_recalculate_timer(tmff);

	spin_unlock_irqrestore(&tmff->lock, flags);

	return 0;
}

static int hid_tmff_upload_effect(struct input_dev *input,
				  struct ff_effect *effect)
{
	struct hid_device *hid = input->private;
	struct tmff_device *tmff = hid->ff_private;
	int id;
	unsigned long flags;

	if (!test_bit(effect->type, input->ffbit))
		return -EINVAL;
	if (effect->id != -1 && !TMFF_CHECK_ID(effect->id))
		return -EINVAL;

	spin_lock_irqsave(&tmff->lock, flags);

	if (effect->id == -1) {
		/* Find a free effect */
		for (id = 0; id < TMFF_EFFECTS && test_bit(EFFECT_USED, tmff->effects[id].flags); ++id);

		if (id >= TMFF_EFFECTS) {
			spin_unlock_irqrestore(&tmff->lock, flags);
			return -ENOSPC;
		}

		effect->id = id;
		tmff->effects[id].owner = current->pid;
		tmff->effects[id].flags[0] = 0;
		set_bit(EFFECT_USED, tmff->effects[id].flags);

	} else {
		/* Re-uploading an owned effect, to change parameters */
		id = effect->id;
		clear_bit(EFFECT_PLAYING, tmff->effects[id].flags);
	}

	tmff->effects[id].effect = *effect;

	hid_tmff_recalculate_timer(tmff);

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

/* Start the timer for the next start/stop/delay */
/* Always call this while tmff->lock is locked */

static void hid_tmff_recalculate_timer(struct tmff_device *tmff)
{
	int i;
	int events = 0;
	unsigned long next_time;

	next_time = 0;	/* Shut up compiler's incorrect warning */

	/* Find the next change in an effect's status */
	for (i = 0; i < TMFF_EFFECTS; ++i) {
		struct tmff_effect *effect = &tmff->effects[i];
		unsigned long play_time;

		if (!test_bit(EFFECT_STARTED, effect->flags))
			continue;

		effect->stop_at = DELAY_CALC(effect->play_at, effect->effect.replay.length);

		if (!test_bit(EFFECT_PLAYING, effect->flags))
			play_time = effect->play_at;
		else
			play_time = effect->stop_at;

		events++;

		if (time_after(jiffies, play_time))
			play_time = jiffies;

		if (events == 1)
			next_time = play_time;
		else {
			if (time_after(next_time, play_time))
				next_time = play_time;
		}
	}

	if (!events && tmff->effects_playing) {
		/* Treat all effects turning off as an event */
		events = 1;
		next_time = jiffies;
	}

	if (!events) {
		/* No events, no time, no need for a timer. */
		del_timer_sync(&tmff->timer);
		return;
	}

	mod_timer(&tmff->timer, next_time);
}

/* Changes values from 0 to 0xffff into values from minimum to maximum */
static inline int hid_tmff_scale(unsigned int in, int minimum, int maximum)
{
	int ret;

	ret = (in * (maximum - minimum) / 0xffff) + minimum;
	if (ret < minimum)
		return minimum;
	if (ret > maximum)
		return maximum;
	return ret;
}

static void hid_tmff_timer(unsigned long timer_data)
{
	struct tmff_device *tmff = (struct tmff_device *) timer_data;
	struct hid_device *hid = tmff->hid;
	unsigned long flags;
	int left = 0, right = 0;	/* Rumbling */
	int i;

	spin_lock_irqsave(&tmff->lock, flags);

	tmff->effects_playing = 0;

	for (i = 0; i < TMFF_EFFECTS; ++i) {
		struct tmff_effect *effect = &tmff->effects[i];

		if (!test_bit(EFFECT_STARTED, effect->flags))
			continue;

		if (!time_after(jiffies, effect->play_at))
			continue;

		if (time_after(jiffies, effect->stop_at)) {

			dbg("Finished playing once %d", i);
			clear_bit(EFFECT_PLAYING, effect->flags);

			if (--effect->count <= 0) {
				dbg("Stopped %d", i);
				clear_bit(EFFECT_STARTED, effect->flags);
				continue;
			} else {
				dbg("Start again %d", i);
				effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay);
				continue;
			}
		}

		++tmff->effects_playing;

		set_bit(EFFECT_PLAYING, effect->flags);

		switch (effect->effect.type) {
			case FF_RUMBLE:
				right += effect->effect.u.rumble.strong_magnitude;
				left += effect->effect.u.rumble.weak_magnitude;
				break;
			default:
				BUG();
				break;
		}
	}

	left = hid_tmff_scale(left, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
	right = hid_tmff_scale(right, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);

	if (left != tmff->rumble->value[0] || right != tmff->rumble->value[1]) {
		tmff->rumble->value[0] = left;
		tmff->rumble->value[1] = right;
		dbg("(left,right)=(%08x, %08x)", left, right);
		hid_submit_report(hid, tmff->report, USB_DIR_OUT);
	}

	if (!test_bit(DEVICE_CLOSING, tmff->flags))
		hid_tmff_recalculate_timer(tmff);

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