/*
 * Copyright 2008  by Andreas Eversberg <andreas@eversberg.eu>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * 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.
 *
 * Quick API description:
 *
 * A clock source registers using mISDN_register_clock:
 * 	name = text string to name clock source
 *	priority = value to priorize clock sources (0 = default)
 *	ctl = callback function to enable/disable clock source
 *	priv = private pointer of clock source
 * 	return = pointer to clock source structure;
 *
 * Note: Callback 'ctl' can be called before mISDN_register_clock returns!
 *       Also it can be called during mISDN_unregister_clock.
 *
 * A clock source calls mISDN_clock_update with given samples elapsed, if
 * enabled. If function call is delayed, tv must be set with the timestamp
 * of the actual event.
 *
 * A clock source unregisters using mISDN_unregister_clock.
 *
 * To get current clock, call mISDN_clock_get. The signed short value
 * counts the number of samples since. Time since last clock event is added.
 *
 */

#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <linux/mISDNif.h>
#include "core.h"

static u_int *debug;
static LIST_HEAD(iclock_list);
DEFINE_RWLOCK(iclock_lock);
u16	iclock_count;		/* counter of last clock */
struct	timeval iclock_tv;	/* time stamp of last clock */
int	iclock_tv_valid;	/* already received one timestamp */
struct	mISDNclock *iclock_current;

void
mISDN_init_clock(u_int *dp)
{
	debug = dp;
	do_gettimeofday(&iclock_tv);
}

static void
select_iclock(void)
{
	struct mISDNclock *iclock, *bestclock = NULL, *lastclock = NULL;
	int pri = -128;

	list_for_each_entry(iclock, &iclock_list, list) {
		if (iclock->pri > pri) {
			pri = iclock->pri;
			bestclock = iclock;
		}
		if (iclock_current == iclock)
			lastclock = iclock;
	}
	if (lastclock && bestclock != lastclock) {
		/* last used clock source still exists but changes, disable */
		if (*debug & DEBUG_CLOCK)
			printk(KERN_DEBUG "Old clock source '%s' disable.\n",
				lastclock->name);
		lastclock->ctl(lastclock->priv, 0);
	}
	if (bestclock && bestclock != iclock_current) {
		/* new clock source selected, enable */
		if (*debug & DEBUG_CLOCK)
			printk(KERN_DEBUG "New clock source '%s' enable.\n",
				bestclock->name);
		bestclock->ctl(bestclock->priv, 1);
	}
	if (bestclock != iclock_current) {
		/* no clock received yet */
		iclock_tv_valid = 0;
	}
	iclock_current = bestclock;
}

struct mISDNclock
*mISDN_register_clock(char *name, int pri, clockctl_func_t *ctl, void *priv)
{
	u_long			flags;
	struct mISDNclock	*iclock;

	if (*debug & (DEBUG_CORE | DEBUG_CLOCK))
		printk(KERN_DEBUG "%s: %s %d\n", __func__, name, pri);
	iclock = kzalloc(sizeof(struct mISDNclock), GFP_ATOMIC);
	if (!iclock) {
		printk(KERN_ERR "%s: No memory for clock entry.\n", __func__);
		return NULL;
	}
	strncpy(iclock->name, name, sizeof(iclock->name)-1);
	iclock->pri = pri;
	iclock->priv = priv;
	iclock->ctl = ctl;
	write_lock_irqsave(&iclock_lock, flags);
	list_add_tail(&iclock->list, &iclock_list);
	select_iclock();
	write_unlock_irqrestore(&iclock_lock, flags);
	return iclock;
}
EXPORT_SYMBOL(mISDN_register_clock);

void
mISDN_unregister_clock(struct mISDNclock *iclock)
{
	u_long	flags;

	if (*debug & (DEBUG_CORE | DEBUG_CLOCK))
		printk(KERN_DEBUG "%s: %s %d\n", __func__, iclock->name,
			iclock->pri);
	write_lock_irqsave(&iclock_lock, flags);
	if (iclock_current == iclock) {
		if (*debug & DEBUG_CLOCK)
			printk(KERN_DEBUG
				"Current clock source '%s' unregisters.\n",
				iclock->name);
		iclock->ctl(iclock->priv, 0);
	}
	list_del(&iclock->list);
	select_iclock();
	write_unlock_irqrestore(&iclock_lock, flags);
}
EXPORT_SYMBOL(mISDN_unregister_clock);

void
mISDN_clock_update(struct mISDNclock *iclock, int samples, struct timeval *tv)
{
	u_long		flags;
	struct timeval	tv_now;
	time_t		elapsed_sec;
	int		elapsed_8000th;

	write_lock_irqsave(&iclock_lock, flags);
	if (iclock_current != iclock) {
		printk(KERN_ERR "%s: '%s' sends us clock updates, but we do "
			"listen to '%s'. This is a bug!\n", __func__,
			iclock->name,
			iclock_current ? iclock_current->name : "nothing");
		iclock->ctl(iclock->priv, 0);
		write_unlock_irqrestore(&iclock_lock, flags);
		return;
	}
	if (iclock_tv_valid) {
		/* increment sample counter by given samples */
		iclock_count += samples;
		if (tv) { /* tv must be set, if function call is delayed */
			iclock_tv.tv_sec = tv->tv_sec;
			iclock_tv.tv_usec = tv->tv_usec;
		} else
			do_gettimeofday(&iclock_tv);
	} else {
		/* calc elapsed time by system clock */
		if (tv) { /* tv must be set, if function call is delayed */
			tv_now.tv_sec = tv->tv_sec;
			tv_now.tv_usec = tv->tv_usec;
		} else
			do_gettimeofday(&tv_now);
		elapsed_sec = tv_now.tv_sec - iclock_tv.tv_sec;
		elapsed_8000th = (tv_now.tv_usec / 125)
			- (iclock_tv.tv_usec / 125);
		if (elapsed_8000th < 0) {
			elapsed_sec -= 1;
			elapsed_8000th += 8000;
		}
		/* add elapsed time to counter and set new timestamp */
		iclock_count += elapsed_sec * 8000 + elapsed_8000th;
		iclock_tv.tv_sec = tv_now.tv_sec;
		iclock_tv.tv_usec = tv_now.tv_usec;
		iclock_tv_valid = 1;
		if (*debug & DEBUG_CLOCK)
			printk("Received first clock from source '%s'.\n",
			    iclock_current ? iclock_current->name : "nothing");
	}
	write_unlock_irqrestore(&iclock_lock, flags);
}
EXPORT_SYMBOL(mISDN_clock_update);

unsigned short
mISDN_clock_get(void)
{
	u_long		flags;
	struct timeval	tv_now;
	time_t		elapsed_sec;
	int		elapsed_8000th;
	u16		count;

	read_lock_irqsave(&iclock_lock, flags);
	/* calc elapsed time by system clock */
	do_gettimeofday(&tv_now);
	elapsed_sec = tv_now.tv_sec - iclock_tv.tv_sec;
	elapsed_8000th = (tv_now.tv_usec / 125) - (iclock_tv.tv_usec / 125);
	if (elapsed_8000th < 0) {
		elapsed_sec -= 1;
		elapsed_8000th += 8000;
	}
	/* add elapsed time to counter */
	count =	iclock_count + elapsed_sec * 8000 + elapsed_8000th;
	read_unlock_irqrestore(&iclock_lock, flags);
	return count;
}
EXPORT_SYMBOL(mISDN_clock_get);

