/*
 *  Driver for Samsung Q10 and related laptops: controls the backlight
 *
 *  Copyright (c) 2011 Frederick van der Wyck <fvanderwyck@gmail.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/backlight.h>
#include <linux/dmi.h>
#include <acpi/acpi_drivers.h>

#define SAMSUNGQ10_BL_MAX_INTENSITY 7

static acpi_handle ec_handle;

static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force,
		"Disable the DMI check and force the driver to be loaded");

static int samsungq10_bl_set_intensity(struct backlight_device *bd)
{

	acpi_status status;
	int i;

	for (i = 0; i < SAMSUNGQ10_BL_MAX_INTENSITY; i++) {
		status = acpi_evaluate_object(ec_handle, "_Q63", NULL, NULL);
		if (ACPI_FAILURE(status))
			return -EIO;
	}
	for (i = 0; i < bd->props.brightness; i++) {
		status = acpi_evaluate_object(ec_handle, "_Q64", NULL, NULL);
		if (ACPI_FAILURE(status))
			return -EIO;
	}

	return 0;
}

static int samsungq10_bl_get_intensity(struct backlight_device *bd)
{
	return bd->props.brightness;
}

static const struct backlight_ops samsungq10_bl_ops = {
	.get_brightness = samsungq10_bl_get_intensity,
	.update_status	= samsungq10_bl_set_intensity,
};

static int samsungq10_probe(struct platform_device *pdev)
{

	struct backlight_properties props;
	struct backlight_device *bd;

	memset(&props, 0, sizeof(struct backlight_properties));
	props.type = BACKLIGHT_PLATFORM;
	props.max_brightness = SAMSUNGQ10_BL_MAX_INTENSITY;
	bd = backlight_device_register("samsung", &pdev->dev, NULL,
				       &samsungq10_bl_ops, &props);
	if (IS_ERR(bd))
		return PTR_ERR(bd);

	platform_set_drvdata(pdev, bd);

	return 0;
}

static int samsungq10_remove(struct platform_device *pdev)
{

	struct backlight_device *bd = platform_get_drvdata(pdev);

	backlight_device_unregister(bd);

	return 0;
}

static struct platform_driver samsungq10_driver = {
	.driver		= {
		.name	= KBUILD_MODNAME,
		.owner	= THIS_MODULE,
	},
	.probe		= samsungq10_probe,
	.remove		= samsungq10_remove,
};

static struct platform_device *samsungq10_device;

static int __init dmi_check_callback(const struct dmi_system_id *id)
{
	printk(KERN_INFO KBUILD_MODNAME ": found model '%s'\n", id->ident);
	return 1;
}

static struct dmi_system_id __initdata samsungq10_dmi_table[] = {
	{
		.ident = "Samsung Q10",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Samsung"),
			DMI_MATCH(DMI_PRODUCT_NAME, "SQ10"),
		},
		.callback = dmi_check_callback,
	},
	{
		.ident = "Samsung Q20",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG Electronics"),
			DMI_MATCH(DMI_PRODUCT_NAME, "SENS Q20"),
		},
		.callback = dmi_check_callback,
	},
	{
		.ident = "Samsung Q25",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG Electronics"),
			DMI_MATCH(DMI_PRODUCT_NAME, "NQ25"),
		},
		.callback = dmi_check_callback,
	},
	{
		.ident = "Dell Latitude X200",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
			DMI_MATCH(DMI_PRODUCT_NAME, "X200"),
		},
		.callback = dmi_check_callback,
	},
	{ },
};
MODULE_DEVICE_TABLE(dmi, samsungq10_dmi_table);

static int __init samsungq10_init(void)
{
	if (!force && !dmi_check_system(samsungq10_dmi_table))
		return -ENODEV;

	ec_handle = ec_get_handle();

	if (!ec_handle)
		return -ENODEV;

	samsungq10_device = platform_create_bundle(&samsungq10_driver,
						   samsungq10_probe,
						   NULL, 0, NULL, 0);

	return PTR_ERR_OR_ZERO(samsungq10_device);
}

static void __exit samsungq10_exit(void)
{
	platform_device_unregister(samsungq10_device);
	platform_driver_unregister(&samsungq10_driver);
}

module_init(samsungq10_init);
module_exit(samsungq10_exit);

MODULE_AUTHOR("Frederick van der Wyck <fvanderwyck@gmail.com>");
MODULE_DESCRIPTION("Samsung Q10 Driver");
MODULE_LICENSE("GPL");
