/*
 * RTC subsystem, proc interface
 *
 * Copyright (C) 2005-06 Tower Technologies
 * Author: Alessandro Zummo <a.zummo@towertech.it>
 *
 * based on arch/arm/common/rtctime.c
 *
 * 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.
*/

#include <linux/module.h>
#include <linux/rtc.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

static struct class_device *rtc_dev = NULL;
static DEFINE_MUTEX(rtc_lock);

static int rtc_proc_show(struct seq_file *seq, void *offset)
{
	int err;
	struct class_device *class_dev = seq->private;
	struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops;
	struct rtc_wkalrm alrm;
	struct rtc_time tm;

	err = rtc_read_time(class_dev, &tm);
	if (err == 0) {
		seq_printf(seq,
			"rtc_time\t: %02d:%02d:%02d\n"
			"rtc_date\t: %04d-%02d-%02d\n",
			tm.tm_hour, tm.tm_min, tm.tm_sec,
			tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
	}

	err = rtc_read_alarm(class_dev, &alrm);
	if (err == 0) {
		seq_printf(seq, "alrm_time\t: ");
		if ((unsigned int)alrm.time.tm_hour <= 24)
			seq_printf(seq, "%02d:", alrm.time.tm_hour);
		else
			seq_printf(seq, "**:");
		if ((unsigned int)alrm.time.tm_min <= 59)
			seq_printf(seq, "%02d:", alrm.time.tm_min);
		else
			seq_printf(seq, "**:");
		if ((unsigned int)alrm.time.tm_sec <= 59)
			seq_printf(seq, "%02d\n", alrm.time.tm_sec);
		else
			seq_printf(seq, "**\n");

		seq_printf(seq, "alrm_date\t: ");
		if ((unsigned int)alrm.time.tm_year <= 200)
			seq_printf(seq, "%04d-", alrm.time.tm_year + 1900);
		else
			seq_printf(seq, "****-");
		if ((unsigned int)alrm.time.tm_mon <= 11)
			seq_printf(seq, "%02d-", alrm.time.tm_mon + 1);
		else
			seq_printf(seq, "**-");
		if ((unsigned int)alrm.time.tm_mday <= 31)
			seq_printf(seq, "%02d\n", alrm.time.tm_mday);
		else
			seq_printf(seq, "**\n");
		seq_printf(seq, "alrm_wakeup\t: %s\n",
				alrm.enabled ? "yes" : "no");
		seq_printf(seq, "alrm_pending\t: %s\n",
				alrm.pending ? "yes" : "no");
	}

	if (ops->proc)
		ops->proc(class_dev->dev, seq);

	return 0;
}

static int rtc_proc_open(struct inode *inode, struct file *file)
{
	struct class_device *class_dev = PDE(inode)->data;

	if (!try_module_get(THIS_MODULE))
		return -ENODEV;

	return single_open(file, rtc_proc_show, class_dev);
}

static int rtc_proc_release(struct inode *inode, struct file *file)
{
	int res = single_release(inode, file);
	module_put(THIS_MODULE);
	return res;
}

static struct file_operations rtc_proc_fops = {
	.open		= rtc_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= rtc_proc_release,
};

static int rtc_proc_add_device(struct class_device *class_dev,
					struct class_interface *class_intf)
{
	mutex_lock(&rtc_lock);
	if (rtc_dev == NULL) {
		struct proc_dir_entry *ent;

		rtc_dev = class_dev;

		ent = create_proc_entry("driver/rtc", 0, NULL);
		if (ent) {
			struct rtc_device *rtc = to_rtc_device(class_dev);

			ent->proc_fops = &rtc_proc_fops;
			ent->owner = rtc->owner;
			ent->data = class_dev;

			dev_info(class_dev->dev, "rtc intf: proc\n");
		}
		else
			rtc_dev = NULL;
	}
	mutex_unlock(&rtc_lock);

	return 0;
}

static void rtc_proc_remove_device(struct class_device *class_dev,
					struct class_interface *class_intf)
{
	mutex_lock(&rtc_lock);
	if (rtc_dev == class_dev) {
		remove_proc_entry("driver/rtc", NULL);
		rtc_dev = NULL;
	}
	mutex_unlock(&rtc_lock);
}

static struct class_interface rtc_proc_interface = {
	.add = &rtc_proc_add_device,
	.remove = &rtc_proc_remove_device,
};

static int __init rtc_proc_init(void)
{
	return rtc_interface_register(&rtc_proc_interface);
}

static void __exit rtc_proc_exit(void)
{
	class_interface_unregister(&rtc_proc_interface);
}

module_init(rtc_proc_init);
module_exit(rtc_proc_exit);

MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
MODULE_DESCRIPTION("RTC class proc interface");
MODULE_LICENSE("GPL");
