/*
 * 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/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)
{
	struct wm831x_on *wm831x_on = container_of(work, struct wm831x_on,
						   work.work);
	struct wm831x *wm831x = wm831x_on->wm831x;
	int poll, ret;

	ret = wm831x_reg_read(wm831x, WM831X_ON_PIN_CONTROL);
	if (ret >= 0) {
		poll = !(ret & WM831X_ON_PIN_STS);

		input_report_key(wm831x_on->dev, KEY_POWER, poll);
		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, 100);
}

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 wm831x_on_probe(struct platform_device *pdev)
{
	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
	struct wm831x_on *wm831x_on;
	int irq = wm831x_irq(wm831x, platform_get_irq(pdev, 0));
	int ret;

	wm831x_on = devm_kzalloc(&pdev->dev, 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 = devm_input_allocate_device(&pdev->dev);
	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->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_ONESHOT,
				   "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:
err:
	return ret;
}

static int wm831x_on_remove(struct platform_device *pdev)
{
	struct wm831x_on *wm831x_on = platform_get_drvdata(pdev);
	int irq = platform_get_irq(pdev, 0);

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

	return 0;
}

static struct platform_driver wm831x_on_driver = {
	.probe		= wm831x_on_probe,
	.remove		= wm831x_on_remove,
	.driver		= {
		.name	= "wm831x-on",
	},
};
module_platform_driver(wm831x_on_driver);

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

