/*
 * Copyright (C) 2013-2014 Dropcam
 * All rights reserved.
 *
 * 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/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/workqueue.h>

#include <asm/uaccess.h>
#include <asm/io.h>

#include <mach/init-dropcam.h>

#define	 DC_WDT_ENABLE_GPIO	 12
#define	 DC_WDT_RESET_GPIO	 54

#define	 DC_WDT_HALF_CYCLE_TIME	     ((HZ * 550)/1000)
#define	 KERNEL_HEARTBEAT_EXPIRE_TIMEOUT	     (HZ * 10)	/* 10 seconds */

static struct workqueue_struct *tps3813k33_kernel_heartbeat;

struct dropcam_tps3813k33_info {
	int last_toggle_value;
	struct timer_list * ptimer;
	unsigned long last_kernel_heartbeat;
	struct work_struct tps3813k33_work;
};

static struct timer_list dropcam_tps3813k33_timer;

static void dropcam_tps3813k33_heartbeat_worker(struct work_struct *work) {
	struct dropcam_tps3813k33_info *wdt_info = container_of(work, struct dropcam_tps3813k33_info, tps3813k33_work);
	wdt_info->last_kernel_heartbeat = jiffies;
}

static void dropcam_tps3813k33_toggle_timer_handler(unsigned long data)
{
	struct dropcam_tps3813k33_info *wdt_info =
		(struct dropcam_tps3813k33_info *)data;

	queue_work(tps3813k33_kernel_heartbeat, &wdt_info->tps3813k33_work);

	/* this timer interrupt handler might still fire after kernel panic
	 * kick the watchdog only if the kernel is alive */
	if (jiffies - wdt_info->last_kernel_heartbeat < KERNEL_HEARTBEAT_EXPIRE_TIMEOUT) {
		wdt_info->last_toggle_value = !wdt_info->last_toggle_value;

		ambarella_gpio_set(DC_WDT_RESET_GPIO, wdt_info->last_toggle_value);

		ambarella_gpio_set(DC_WDT_ENABLE_GPIO, 1);

		mod_timer(wdt_info->ptimer, jiffies + DC_WDT_HALF_CYCLE_TIME);
	}
}

static const struct file_operations dropcam_tps3813k33_fops = {
	.owner		= THIS_MODULE,
};

static int __devinit dropcam_tps3813k33_probe(struct platform_device *pdev)
{
	int					errorCode = 0;
	struct dropcam_tps3813k33_info		*pinfo;

        if (!((AMBARELLA_BOARD_TYPE(system_rev) == AMBARELLA_BOARD_TYPE_VENDOR) &&
              ((AMBARELLA_BOARD_REV(system_rev) == DROPCAM_BOARD_REV_CROWN_ROYAL) ||
              (AMBARELLA_BOARD_REV(system_rev) == DROPCAM_BOARD_REV_QUARTZ)))) {
		printk(KERN_WARNING "dropcam_tps3813k33_probe: Wrong system type, not loading\n");
		errorCode = -ENXIO;
		goto dropcam_tps3813k33_no_dev;
	}

	pinfo = kzalloc(sizeof(struct dropcam_tps3813k33_info), GFP_KERNEL);
	if (pinfo == NULL) {
		printk(KERN_ERR "dropcam_tps3813k33_probe: out of memory\n");
		errorCode = -ENOMEM;
		goto dropcam_tps3813k33_no_pinfo;
	}

	pinfo->last_toggle_value = 0;

	pinfo->ptimer = &dropcam_tps3813k33_timer;
	init_timer(pinfo->ptimer);

	pinfo->ptimer->function = dropcam_tps3813k33_toggle_timer_handler;
	pinfo->ptimer->data = (unsigned long)pinfo;

	pinfo->ptimer->expires = jiffies + DC_WDT_HALF_CYCLE_TIME;

	tps3813k33_kernel_heartbeat = create_workqueue("tps3813k33_kernel_heartbeat");
	INIT_WORK(&pinfo->tps3813k33_work, dropcam_tps3813k33_heartbeat_worker);

	printk(KERN_INFO "Enabling TPS3813 HW WDT\n");
	ambarella_gpio_config(DC_WDT_ENABLE_GPIO, GPIO_FUNC_SW_OUTPUT);

	ambarella_gpio_config(DC_WDT_RESET_GPIO, GPIO_FUNC_SW_OUTPUT);
	ambarella_gpio_set(DC_WDT_RESET_GPIO, pinfo->last_toggle_value);

	add_timer(pinfo->ptimer);

	pinfo->last_kernel_heartbeat = jiffies;

	goto dropcam_tps3813k33_ok;

dropcam_tps3813k33_no_pinfo:
dropcam_tps3813k33_no_dev:
dropcam_tps3813k33_ok:
	return errorCode;
}


static int __devexit dropcam_tps3813k33_remove(struct platform_device *pdev)
{
	struct dropcam_tps3813k33_info		*pinfo;
	int					errorCode = 0;

	pinfo = platform_get_drvdata(pdev);

	printk(KERN_INFO "Disabling TPS3813 HW WDT\n");

	ambarella_gpio_set(DC_WDT_ENABLE_GPIO, 0);

	del_timer(&dropcam_tps3813k33_timer);

	if (pinfo)
	{
		kfree(pinfo);
	}

	return errorCode;
}

static int __devexit dropcam_tps3813k33_shutdown(struct platform_device *pdev)
{
	struct dropcam_tps3813k33_info		*pinfo;

	pinfo = platform_get_drvdata(pdev);

	printk(KERN_INFO "Kicking TPS3813 HW WDT before reboot\n");

	ambarella_gpio_set(DC_WDT_RESET_GPIO, 1);
	ambarella_gpio_set(DC_WDT_RESET_GPIO, 0);

	del_timer(&dropcam_tps3813k33_timer);

	if (pinfo)
	{
		kfree(pinfo);
	}

	return 0;
}


static int dropcam_tps3813k33_release(struct platform_device *pdev)
{
	return 0;
}

static struct platform_driver dropcam_tps3813k33_driver = {
	.probe		= dropcam_tps3813k33_probe,
	.remove		= __devexit_p(dropcam_tps3813k33_remove),
	.shutdown	= __devexit_p(dropcam_tps3813k33_shutdown),
	.driver		= {
		.owner	= THIS_MODULE,
		.name	= "dropcam-tps3813k33",
	},
};

static struct platform_device dropcam_tps3813k33_device = {
	.name		= "dropcam-tps3813k33",
	.id = 0,
	.dev = {
    .release = dropcam_tps3813k33_release,
  },
};

static int __init dropcam_tps3813k33_init(void)
{
	platform_device_register(&dropcam_tps3813k33_device);
	return platform_driver_register(&dropcam_tps3813k33_driver);
}

static void __exit dropcam_tps3813k33_exit(void)
{
	platform_device_unregister(&dropcam_tps3813k33_device);
	platform_driver_unregister(&dropcam_tps3813k33_driver);
}

core_initcall(dropcam_tps3813k33_init);
module_exit(dropcam_tps3813k33_exit);

MODULE_DESCRIPTION("Dropcam TPS3813K33 Watch Dog Timer");
MODULE_AUTHOR("Dan Girellini, <dan@dropcam.com>");
MODULE_LICENSE("GPL");
