/*
 *  OLPC XO-1.5 ebook switch driver
 *  (based on generic ACPI button driver)
 *
 *  Copyright (C) 2009 Paul Fox <pgf@laptop.org>
 *  Copyright (C) 2010 One Laptop per Child
 *
 *  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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/input.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>

#define MODULE_NAME "xo15-ebook"

#define XO15_EBOOK_CLASS		MODULE_NAME
#define XO15_EBOOK_TYPE_UNKNOWN	0x00
#define XO15_EBOOK_NOTIFY_STATUS	0x80

#define XO15_EBOOK_SUBCLASS		"ebook"
#define XO15_EBOOK_HID			"XO15EBK"
#define XO15_EBOOK_DEVICE_NAME		"EBook Switch"

ACPI_MODULE_NAME(MODULE_NAME);

MODULE_DESCRIPTION("OLPC XO-1.5 ebook switch driver");
MODULE_LICENSE("GPL");

static const struct acpi_device_id ebook_device_ids[] = {
	{ XO15_EBOOK_HID, 0 },
	{ "", 0 },
};
MODULE_DEVICE_TABLE(acpi, ebook_device_ids);

struct ebook_switch {
	struct input_dev *input;
	char phys[32];			/* for input device */
};

static int ebook_send_state(struct acpi_device *device)
{
	struct ebook_switch *button = acpi_driver_data(device);
	unsigned long long state;
	acpi_status status;

	status = acpi_evaluate_integer(device->handle, "EBK", NULL, &state);
	if (ACPI_FAILURE(status))
		return -EIO;

	/* input layer checks if event is redundant */
	input_report_switch(button->input, SW_TABLET_MODE, !state);
	input_sync(button->input);
	return 0;
}

static void ebook_switch_notify(struct acpi_device *device, u32 event)
{
	switch (event) {
	case ACPI_FIXED_HARDWARE_EVENT:
	case XO15_EBOOK_NOTIFY_STATUS:
		ebook_send_state(device);
		break;
	default:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "Unsupported event [0x%x]\n", event));
		break;
	}
}

#ifdef CONFIG_PM_SLEEP
static int ebook_switch_resume(struct device *dev)
{
	return ebook_send_state(to_acpi_device(dev));
}
#endif

static SIMPLE_DEV_PM_OPS(ebook_switch_pm, NULL, ebook_switch_resume);

static int ebook_switch_add(struct acpi_device *device)
{
	struct ebook_switch *button;
	struct input_dev *input;
	const char *hid = acpi_device_hid(device);
	char *name, *class;
	int error;

	button = kzalloc(sizeof(struct ebook_switch), GFP_KERNEL);
	if (!button)
		return -ENOMEM;

	device->driver_data = button;

	button->input = input = input_allocate_device();
	if (!input) {
		error = -ENOMEM;
		goto err_free_button;
	}

	name = acpi_device_name(device);
	class = acpi_device_class(device);

	if (strcmp(hid, XO15_EBOOK_HID)) {
		pr_err("Unsupported hid [%s]\n", hid);
		error = -ENODEV;
		goto err_free_input;
	}

	strcpy(name, XO15_EBOOK_DEVICE_NAME);
	sprintf(class, "%s/%s", XO15_EBOOK_CLASS, XO15_EBOOK_SUBCLASS);

	snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);

	input->name = name;
	input->phys = button->phys;
	input->id.bustype = BUS_HOST;
	input->dev.parent = &device->dev;

	input->evbit[0] = BIT_MASK(EV_SW);
	set_bit(SW_TABLET_MODE, input->swbit);

	error = input_register_device(input);
	if (error)
		goto err_free_input;

	ebook_send_state(device);

	if (device->wakeup.flags.valid) {
		/* Button's GPE is run-wake GPE */
		acpi_enable_gpe(device->wakeup.gpe_device,
				device->wakeup.gpe_number);
		device_set_wakeup_enable(&device->dev, true);
	}

	return 0;

 err_free_input:
	input_free_device(input);
 err_free_button:
	kfree(button);
	return error;
}

static int ebook_switch_remove(struct acpi_device *device)
{
	struct ebook_switch *button = acpi_driver_data(device);

	input_unregister_device(button->input);
	kfree(button);
	return 0;
}

static struct acpi_driver xo15_ebook_driver = {
	.name = MODULE_NAME,
	.class = XO15_EBOOK_CLASS,
	.ids = ebook_device_ids,
	.ops = {
		.add = ebook_switch_add,
		.remove = ebook_switch_remove,
		.notify = ebook_switch_notify,
	},
	.drv.pm = &ebook_switch_pm,
};
module_acpi_driver(xo15_ebook_driver);
