// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * OSS compatible sequencer driver
 *
 * Timer control routines
 *
 * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
 */

#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 */
		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;
}
