/**
 * wm831x-on.c - WM831X ON pin driver
 *
 * Copyright (C) 2009 Wolfson Microelectronics plc
 *
 * This file is subject to the terms and conditions of the GNU General
 * Public License. See the file "COPYING" in the main directory of this
 * archive for more details.
 *
 * 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/init.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/mfd/wm831x/core.h>

struct wm831x_on {
	struct input_dev *dev;
	struct delayed_work work;
	struct wm831x *wm831x;
};

/*
 * The chip gives us an interrupt when the ON pin is asserted but we
 * then need to poll to see when the pin is deasserted.
 */
static void wm831x_poll_on(struct work_struct *work)
{
	int					ret;
	struct wm831x_on			*wm831x_on;
	struct wm831x				*wm831x;
	int					key;
	int					poll = 0;

	wm831x_on = container_of(work, struct wm831x_on, work.work);
	wm831x = wm831x_on->wm831x;

	ret = wm831x_reg_read(wm831x, WM831X_ON_PIN_CONTROL);
	if (ret >= 0) {
		key = !(ret & WM831X_ON_PIN_STS);
		input_report_key(wm831x_on->dev, KEY_POWER, key);
		input_sync(wm831x_on->dev);
	} else {
		dev_err(wm831x->dev, "Failed to read ON status: %d\n", ret);
		poll = 1;
	}

	if (poll)
		schedule_delayed_work(&wm831x_on->work, HZ / 10);
}

static irqreturn_t wm831x_on_irq(int irq, void *data)
{
	struct wm831x_on *wm831x_on = data;

	schedule_delayed_work(&wm831x_on->work, 0);

	return IRQ_HANDLED;
}

static int __devinit wm831x_on_probe(struct platform_device *pdev)
{
	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
	struct wm831x_on *wm831x_on;
	int irq = platform_get_irq(pdev, 0);
	int ret;

	wm831x_on = kzalloc(sizeof(struct wm831x_on), GFP_KERNEL);
	if (!wm831x_on) {
		dev_err(&pdev->dev, "Can't allocate data\n");
		return -ENOMEM;
	}

	wm831x_on->wm831x = wm831x;
	INIT_DELAYED_WORK(&wm831x_on->work, wm831x_poll_on);

	wm831x_on->dev = input_allocate_device();
	if (!wm831x_on->dev) {
		dev_err(&pdev->dev, "Can't allocate input dev\n");
		ret = -ENOMEM;
		goto err;
	}

	wm831x_on->dev->evbit[0] = BIT_MASK(EV_KEY);
	wm831x_on->dev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
	wm831x_on->dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
	wm831x_on->dev->keybit[BIT_WORD(KEY_MENU)] = BIT_MASK(KEY_MENU);
	wm831x_on->dev->name = "wm831x_on";
	wm831x_on->dev->phys = "wm831x_on/input0";
	wm831x_on->dev->dev.parent = &pdev->dev;

	ret = request_threaded_irq(irq, NULL, wm831x_on_irq,
		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
		"wm831x_on", wm831x_on);
	if (ret < 0) {
		dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret);
		goto err_input_dev;
	}
	ret = input_register_device(wm831x_on->dev);
	if (ret) {
		dev_dbg(&pdev->dev, "Can't register input device: %d\n", ret);
		goto err_irq;
	}

	platform_set_drvdata(pdev, wm831x_on);

	return 0;

err_irq:
	free_irq(irq, wm831x_on);
err_input_dev:
	input_free_device(wm831x_on->dev);
err:
	kfree(wm831x_on);
	return ret;
}

static int __devexit wm831x_on_remove(struct platform_device *pdev)
{
	struct wm831x_on			*wm831x_on;
	int					irq;

	wm831x_on = platform_get_drvdata(pdev);
	irq = platform_get_irq(pdev, 0);

	free_irq(irq, wm831x_on);
	cancel_delayed_work_sync(&wm831x_on->work);
	input_unregister_device(wm831x_on->dev);
	kfree(wm831x_on);

	return 0;
}

#ifdef CONFIG_PM
static int wm831x_on_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct wm831x_on			*wm831x_on;
	int					irq;

	wm831x_on = platform_get_drvdata(pdev);
	irq = platform_get_irq(pdev, 0);

	disable_irq(irq);
	cancel_delayed_work_sync(&wm831x_on->work);

	return 0;
}

static int wm831x_on_resume(struct platform_device *pdev)
{
	struct wm831x_on			*wm831x_on;
	struct wm831x				*wm831x;
	int					irq;
	int					ret;

	wm831x_on = platform_get_drvdata(pdev);
	irq = platform_get_irq(pdev, 0);

	wm831x = wm831x_on->wm831x;

	//TBD: Check resumed form self-referesh.
	ret = wm831x_reg_read(wm831x, WM831X_ON_SOURCE);

	if (ret & WM831X_ON_SOURCE_ON_PIN) {
		input_report_key(wm831x_on->dev, KEY_POWER, 1);
		input_sync(wm831x_on->dev);
		input_report_key(wm831x_on->dev, KEY_POWER, 0);
		input_sync(wm831x_on->dev);
	}

	if (ret & WM831X_ON_SOURCE_GPIO) {
		input_report_key(wm831x_on->dev, KEY_POWER, 1);
		input_sync(wm831x_on->dev);
		input_report_key(wm831x_on->dev, KEY_POWER, 0);
		input_sync(wm831x_on->dev);
	}
	enable_irq(irq);

	return 0;
}
#endif /* CONFIG_PM */

static struct platform_driver wm831x_on_driver = {
	.probe		= wm831x_on_probe,
	.remove		= __devexit_p(wm831x_on_remove),
#ifdef CONFIG_PM
	.suspend	= wm831x_on_suspend,
	.resume		= wm831x_on_resume,
#endif
	.driver		= {
		.name	= "wm831x-on",
		.owner	= THIS_MODULE,
	},
};

static int __init wm831x_on_init(void)
{
	return platform_driver_register(&wm831x_on_driver);
}
module_init(wm831x_on_init);

static void __exit wm831x_on_exit(void)
{
	platform_driver_unregister(&wm831x_on_driver);
}
module_exit(wm831x_on_exit);

MODULE_ALIAS("platform:wm831x-on");
MODULE_DESCRIPTION("WM831x ON pin");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");

