/*
 *  RTC based high-frequency timer
 *
 *  Copyright (C) 2000 Takashi Iwai
 *	based on rtctimer.c by Steve Ratcliffe
 *
 *   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/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/log2.h>
#include <sound/core.h>
#include <sound/timer.h>

#if IS_ENABLED(CONFIG_RTC)

#include <linux/mc146818rtc.h>

#define RTC_FREQ	1024		/* default frequency */
#define NANO_SEC	1000000000L	/* 10^9 in sec */

/*
 * prototypes
 */
static int rtctimer_open(struct snd_timer *t);
static int rtctimer_close(struct snd_timer *t);
static int rtctimer_start(struct snd_timer *t);
static int rtctimer_stop(struct snd_timer *t);


/*
 * The hardware dependent description for this timer.
 */
static struct snd_timer_hardware rtc_hw = {
	.flags =	SNDRV_TIMER_HW_AUTO |
			SNDRV_TIMER_HW_FIRST |
			SNDRV_TIMER_HW_TASKLET,
	.ticks =	100000000L,		/* FIXME: XXX */
	.open =		rtctimer_open,
	.close =	rtctimer_close,
	.start =	rtctimer_start,
	.stop =		rtctimer_stop,
};

static int rtctimer_freq = RTC_FREQ;		/* frequency */
static struct snd_timer *rtctimer;
static struct tasklet_struct rtc_tasklet;
static rtc_task_t rtc_task;


static int
rtctimer_open(struct snd_timer *t)
{
	int err;

	err = rtc_register(&rtc_task);
	if (err < 0)
		return err;
	t->private_data = &rtc_task;
	return 0;
}

static int
rtctimer_close(struct snd_timer *t)
{
	rtc_task_t *rtc = t->private_data;
	if (rtc) {
		rtc_unregister(rtc);
		tasklet_kill(&rtc_tasklet);
		t->private_data = NULL;
	}
	return 0;
}

static int
rtctimer_start(struct snd_timer *timer)
{
	rtc_task_t *rtc = timer->private_data;
	if (snd_BUG_ON(!rtc))
		return -EINVAL;
	rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq);
	rtc_control(rtc, RTC_PIE_ON, 0);
	return 0;
}

static int
rtctimer_stop(struct snd_timer *timer)
{
	rtc_task_t *rtc = timer->private_data;
	if (snd_BUG_ON(!rtc))
		return -EINVAL;
	rtc_control(rtc, RTC_PIE_OFF, 0);
	return 0;
}

static void rtctimer_tasklet(unsigned long data)
{
	snd_timer_interrupt((struct snd_timer *)data, 1);
}

/*
 * interrupt
 */
static void rtctimer_interrupt(void *private_data)
{
	tasklet_schedule(private_data);
}


/*
 *  ENTRY functions
 */
static int __init rtctimer_init(void)
{
	int err;
	struct snd_timer *timer;

	if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
	    !is_power_of_2(rtctimer_freq)) {
		pr_err("ALSA: rtctimer: invalid frequency %d\n", rtctimer_freq);
		return -EINVAL;
	}

	/* Create a new timer and set up the fields */
	err = snd_timer_global_new("rtc", SNDRV_TIMER_GLOBAL_RTC, &timer);
	if (err < 0)
		return err;

	timer->module = THIS_MODULE;
	strcpy(timer->name, "RTC timer");
	timer->hw = rtc_hw;
	timer->hw.resolution = NANO_SEC / rtctimer_freq;

	tasklet_init(&rtc_tasklet, rtctimer_tasklet, (unsigned long)timer);

	/* set up RTC callback */
	rtc_task.func = rtctimer_interrupt;
	rtc_task.private_data = &rtc_tasklet;

	err = snd_timer_global_register(timer);
	if (err < 0) {
		snd_timer_global_free(timer);
		return err;
	}
	rtctimer = timer; /* remember this */

	return 0;
}

static void __exit rtctimer_exit(void)
{
	if (rtctimer) {
		snd_timer_global_free(rtctimer);
		rtctimer = NULL;
	}
}


/*
 * exported stuff
 */
module_init(rtctimer_init)
module_exit(rtctimer_exit)

module_param(rtctimer_freq, int, 0444);
MODULE_PARM_DESC(rtctimer_freq, "timer frequency in Hz");

MODULE_LICENSE("GPL");

MODULE_ALIAS("snd-timer-" __stringify(SNDRV_TIMER_GLOBAL_RTC));

#endif /* IS_ENABLED(CONFIG_RTC) */
