/*
 * OSS compatible sequencer driver
 *
 * Timer control routines
 *
 * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
 *
 * 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 "seq_oss_timer.h"
#include "seq_oss_event.h"
#include <sound/seq_oss_legacy.h>
#include <linux/slab.h>

/*
 */
#define MIN_OSS_TEMPO		8
#define MAX_OSS_TEMPO		360
#define MIN_OSS_TIMEBASE	1
#define MAX_OSS_TIMEBASE	1000

/*
 */
static void calc_alsa_tempo(struct seq_oss_timer *timer);
static int send_timer_event(struct seq_oss_devinfo *dp, int type, int value);


/*
 * create and register a new timer.
 * if queue is not started yet, start it.
 */
struct seq_oss_timer *
snd_seq_oss_timer_new(struct seq_oss_devinfo *dp)
{
	struct seq_oss_timer *rec;

	rec = kzalloc(sizeof(*rec), GFP_KERNEL);
	if (rec == NULL)
		return NULL;

	rec->dp = dp;
	rec->cur_tick = 0;
	rec->realtime = 0;
	rec->running = 0;
	rec->oss_tempo = 60;
	rec->oss_timebase = 100;
	calc_alsa_tempo(rec);

	return rec;
}


/*
 * delete timer.
 * if no more timer exists, stop the queue.
 */
void
snd_seq_oss_timer_delete(struct seq_oss_timer *rec)
{
	if (rec) {
		snd_seq_oss_timer_stop(rec);
		kfree(rec);
	}
}


/*
 * process one timing event
 * return 1 : event proceseed -- skip this event
 *        0 : not a timer event -- enqueue this event
 */
int
snd_seq_oss_process_timer_event(struct seq_oss_timer *rec, union evrec *ev)
{
	abstime_t parm = ev->t.time;

	if (ev->t.code == EV_TIMING) {
		switch (ev->t.cmd) {
		case TMR_WAIT_REL:
			parm += rec->cur_tick;
			rec->realtime = 0;
			/* fall through and continue to next */
		case TMR_WAIT_ABS:
			if (parm == 0) {
				rec->realtime = 1;
			} else if (parm >= rec->cur_tick) {
				rec->realtime = 0;
				rec->cur_tick = parm;
			}
			return 1;	/* skip this event */
			
		case TMR_START:
			snd_seq_oss_timer_start(rec);
			return 1;

		}
	} else if (ev->s.code == SEQ_WAIT) {
		/* time = from 1 to 3 bytes */
		parm = (ev->echo >> 8) & 0xffffff;
		if (parm > rec->cur_tick) {
			/* set next event time */
			rec->cur_tick = parm;
			rec->realtime = 0;
		}
		return 1;
	}

	return 0;
}


/*
 * convert tempo units
 */
static void
calc_alsa_tempo(struct seq_oss_timer *timer)
{
	timer->tempo = (60 * 1000000) / timer->oss_tempo;
	timer->ppq = timer->oss_timebase;
}


/*
 * dispatch a timer event
 */
static int
send_timer_event(struct seq_oss_devinfo *dp, int type, int value)
{
	struct snd_seq_event ev;

	memset(&ev, 0, sizeof(ev));
	ev.type = type;
	ev.source.client = dp->cseq;
	ev.source.port = 0;
	ev.dest.client = SNDRV_SEQ_CLIENT_SYSTEM;
	ev.dest.port = SNDRV_SEQ_PORT_SYSTEM_TIMER;
	ev.queue = dp->queue;
	ev.data.queue.queue = dp->queue;
	ev.data.queue.param.value = value;
	return snd_seq_kernel_client_dispatch(dp->cseq, &ev, 1, 0);
}

/*
 * set queue tempo and start queue
 */
int
snd_seq_oss_timer_start(struct seq_oss_timer *timer)
{
	struct seq_oss_devinfo *dp = timer->dp;
	struct snd_seq_queue_tempo tmprec;

	if (timer->running)
		snd_seq_oss_timer_stop(timer);

	memset(&tmprec, 0, sizeof(tmprec));
	tmprec.queue = dp->queue;
	tmprec.ppq = timer->ppq;
	tmprec.tempo = timer->tempo;
	snd_seq_set_queue_tempo(dp->cseq, &tmprec);

	send_timer_event(dp, SNDRV_SEQ_EVENT_START, 0);
	timer->running = 1;
	timer->cur_tick = 0;
	return 0;
}


/*
 * stop queue
 */
int
snd_seq_oss_timer_stop(struct seq_oss_timer *timer)
{
	if (! timer->running)
		return 0;
	send_timer_event(timer->dp, SNDRV_SEQ_EVENT_STOP, 0);
	timer->running = 0;
	return 0;
}


/*
 * continue queue
 */
int
snd_seq_oss_timer_continue(struct seq_oss_timer *timer)
{
	if (timer->running)
		return 0;
	send_timer_event(timer->dp, SNDRV_SEQ_EVENT_CONTINUE, 0);
	timer->running = 1;
	return 0;
}


/*
 * change queue tempo
 */
int
snd_seq_oss_timer_tempo(struct seq_oss_timer *timer, int value)
{
	if (value < MIN_OSS_TEMPO)
		value = MIN_OSS_TEMPO;
	else if (value > MAX_OSS_TEMPO)
		value = MAX_OSS_TEMPO;
	timer->oss_tempo = value;
	calc_alsa_tempo(timer);
	if (timer->running)
		send_timer_event(timer->dp, SNDRV_SEQ_EVENT_TEMPO, timer->tempo);
	return 0;
}


/*
 * ioctls
 */
int
snd_seq_oss_timer_ioctl(struct seq_oss_timer *timer, unsigned int cmd, int __user *arg)
{
	int value;

	if (cmd == SNDCTL_SEQ_CTRLRATE) {
		/* if *arg == 0, just return the current rate */
		if (get_user(value, arg))
			return -EFAULT;
		if (value)
			return -EINVAL;
		value = ((timer->oss_tempo * timer->oss_timebase) + 30) / 60;
		return put_user(value, arg) ? -EFAULT : 0;
	}

	if (timer->dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH)
		return 0;

	switch (cmd) {
	case SNDCTL_TMR_START:
		return snd_seq_oss_timer_start(timer);
	case SNDCTL_TMR_STOP:
		return snd_seq_oss_timer_stop(timer);
	case SNDCTL_TMR_CONTINUE:
		return snd_seq_oss_timer_continue(timer);
	case SNDCTL_TMR_TEMPO:
		if (get_user(value, arg))
			return -EFAULT;
		return snd_seq_oss_timer_tempo(timer, value);
	case SNDCTL_TMR_TIMEBASE:
		if (get_user(value, arg))
			return -EFAULT;
		if (value < MIN_OSS_TIMEBASE)
			value = MIN_OSS_TIMEBASE;
		else if (value > MAX_OSS_TIMEBASE)
			value = MAX_OSS_TIMEBASE;
		timer->oss_timebase = value;
		calc_alsa_tempo(timer);
		return 0;

	case SNDCTL_TMR_METRONOME:
	case SNDCTL_TMR_SELECT:
	case SNDCTL_TMR_SOURCE:
		/* not supported */
		return 0;
	}
	return 0;
}
