/*
 * System monitoring driver for DA9055 PMICs.
 *
 * Copyright(c) 2012 Dialog Semiconductor Ltd.
 *
 * Author: David Dajun Chen <dchen@diasemi.com>
 *
 * 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.
 *
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/watchdog.h>
#include <linux/delay.h>

#include <linux/mfd/da9055/core.h>
#include <linux/mfd/da9055/reg.h>

static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout,
		 "Watchdog cannot be stopped once started (default="
		 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");

#define DA9055_DEF_TIMEOUT	4
#define DA9055_TWDMIN		256

struct da9055_wdt_data {
	struct watchdog_device wdt;
	struct da9055 *da9055;
	struct kref kref;
};

static const struct {
	u8 reg_val;
	int user_time;  /* In seconds */
} da9055_wdt_maps[] = {
	{ 0, 0 },
	{ 1, 2 },
	{ 2, 4 },
	{ 3, 8 },
	{ 4, 16 },
	{ 5, 32 },
	{ 5, 33 },  /* Actual time  32.768s so included both 32s and 33s */
	{ 6, 65 },
	{ 6, 66 },  /* Actual time 65.536s so include both, 65s and 66s */
	{ 7, 131 },
};

static int da9055_wdt_set_timeout(struct watchdog_device *wdt_dev,
				  unsigned int timeout)
{
	struct da9055_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev);
	struct da9055 *da9055 = driver_data->da9055;
	int ret, i;

	for (i = 0; i < ARRAY_SIZE(da9055_wdt_maps); i++)
		if (da9055_wdt_maps[i].user_time == timeout)
			break;

	if (i == ARRAY_SIZE(da9055_wdt_maps))
		ret = -EINVAL;
	else
		ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B,
					DA9055_TWDSCALE_MASK,
					da9055_wdt_maps[i].reg_val <<
					DA9055_TWDSCALE_SHIFT);
	if (ret < 0)
		dev_err(da9055->dev,
			"Failed to update timescale bit, %d\n", ret);

	wdt_dev->timeout = timeout;

	return ret;
}

static int da9055_wdt_ping(struct watchdog_device *wdt_dev)
{
	struct da9055_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev);
	struct da9055 *da9055 = driver_data->da9055;
	int ret;

	/*
	 * We have a minimum time for watchdog window called TWDMIN. A write
	 * to the watchdog before this elapsed time will cause an error.
	 */
	mdelay(DA9055_TWDMIN);

	/* Reset the watchdog timer */
	ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_E,
				DA9055_WATCHDOG_MASK, 1);

	return ret;
}

static void da9055_wdt_release_resources(struct kref *r)
{
	struct da9055_wdt_data *driver_data =
		container_of(r, struct da9055_wdt_data, kref);

	kfree(driver_data);
}

static void da9055_wdt_ref(struct watchdog_device *wdt_dev)
{
	struct da9055_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev);

	kref_get(&driver_data->kref);
}

static void da9055_wdt_unref(struct watchdog_device *wdt_dev)
{
	struct da9055_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev);

	kref_put(&driver_data->kref, da9055_wdt_release_resources);
}

static int da9055_wdt_start(struct watchdog_device *wdt_dev)
{
	return da9055_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
}

static int da9055_wdt_stop(struct watchdog_device *wdt_dev)
{
	return da9055_wdt_set_timeout(wdt_dev, 0);
}

static struct watchdog_info da9055_wdt_info = {
	.options	= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
	.identity	= "DA9055 Watchdog",
};

static const struct watchdog_ops da9055_wdt_ops = {
	.owner = THIS_MODULE,
	.start = da9055_wdt_start,
	.stop = da9055_wdt_stop,
	.ping = da9055_wdt_ping,
	.set_timeout = da9055_wdt_set_timeout,
	.ref = da9055_wdt_ref,
	.unref = da9055_wdt_unref,
};

static int da9055_wdt_probe(struct platform_device *pdev)
{
	struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent);
	struct da9055_wdt_data *driver_data;
	struct watchdog_device *da9055_wdt;
	int ret;

	driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data),
				   GFP_KERNEL);
	if (!driver_data) {
		dev_err(da9055->dev, "Failed to allocate watchdog device\n");
		return -ENOMEM;
	}

	driver_data->da9055 = da9055;

	da9055_wdt = &driver_data->wdt;

	da9055_wdt->timeout = DA9055_DEF_TIMEOUT;
	da9055_wdt->info = &da9055_wdt_info;
	da9055_wdt->ops = &da9055_wdt_ops;
	watchdog_set_nowayout(da9055_wdt, nowayout);
	watchdog_set_drvdata(da9055_wdt, driver_data);

	kref_init(&driver_data->kref);

	ret = da9055_wdt_stop(da9055_wdt);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to stop watchdog, %d\n", ret);
		goto err;
	}

	dev_set_drvdata(&pdev->dev, driver_data);

	ret = watchdog_register_device(&driver_data->wdt);
	if (ret != 0)
		dev_err(da9055->dev, "watchdog_register_device() failed: %d\n",
			ret);

err:
	return ret;
}

static int da9055_wdt_remove(struct platform_device *pdev)
{
	struct da9055_wdt_data *driver_data = dev_get_drvdata(&pdev->dev);

	watchdog_unregister_device(&driver_data->wdt);
	kref_put(&driver_data->kref, da9055_wdt_release_resources);

	return 0;
}

static struct platform_driver da9055_wdt_driver = {
	.probe = da9055_wdt_probe,
	.remove = da9055_wdt_remove,
	.driver = {
		.name	= "da9055-watchdog",
	},
};

module_platform_driver(da9055_wdt_driver);

MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
MODULE_DESCRIPTION("DA9055 watchdog");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:da9055-watchdog");
