/*
 * LEDs driver for PCEngines WRAP
 *
 * Copyright (C) 2006 Kristian Kielhofner <kris@krisk.org>
 *
 * Based on leds-net48xx.c
 *
 * 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/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/err.h>
#include <asm/io.h>
#include <linux/scx200_gpio.h>

#define DRVNAME "wrap-led"
#define WRAP_POWER_LED_GPIO	2
#define WRAP_ERROR_LED_GPIO	3
#define WRAP_EXTRA_LED_GPIO	18

static struct platform_device *pdev;

static void wrap_power_led_set(struct led_classdev *led_cdev,
		enum led_brightness value)
{
	if (value)
		scx200_gpio_set_low(WRAP_POWER_LED_GPIO);
	else
		scx200_gpio_set_high(WRAP_POWER_LED_GPIO);
}

static void wrap_error_led_set(struct led_classdev *led_cdev,
		enum led_brightness value)
{
	if (value)
		scx200_gpio_set_low(WRAP_ERROR_LED_GPIO);
	else
		scx200_gpio_set_high(WRAP_ERROR_LED_GPIO);
}

static void wrap_extra_led_set(struct led_classdev *led_cdev,
		enum led_brightness value)
{
	if (value)
		scx200_gpio_set_low(WRAP_EXTRA_LED_GPIO);
	else
		scx200_gpio_set_high(WRAP_EXTRA_LED_GPIO);
}

static struct led_classdev wrap_power_led = {
	.name			= "wrap::power",
	.brightness_set		= wrap_power_led_set,
	.default_trigger	= "default-on",
	.flags			= LED_CORE_SUSPENDRESUME,
};

static struct led_classdev wrap_error_led = {
	.name		= "wrap::error",
	.brightness_set	= wrap_error_led_set,
	.flags			= LED_CORE_SUSPENDRESUME,
};

static struct led_classdev wrap_extra_led = {
	.name           = "wrap::extra",
	.brightness_set = wrap_extra_led_set,
	.flags			= LED_CORE_SUSPENDRESUME,
};

static int wrap_led_probe(struct platform_device *pdev)
{
	int ret;

	ret = led_classdev_register(&pdev->dev, &wrap_power_led);
	if (ret < 0)
		return ret;

	ret = led_classdev_register(&pdev->dev, &wrap_error_led);
	if (ret < 0)
		goto err1;

	ret = led_classdev_register(&pdev->dev, &wrap_extra_led);
	if (ret < 0)
		goto err2;

	return ret;

err2:
	led_classdev_unregister(&wrap_error_led);
err1:
	led_classdev_unregister(&wrap_power_led);

	return ret;
}

static int wrap_led_remove(struct platform_device *pdev)
{
	led_classdev_unregister(&wrap_power_led);
	led_classdev_unregister(&wrap_error_led);
	led_classdev_unregister(&wrap_extra_led);
	return 0;
}

static struct platform_driver wrap_led_driver = {
	.probe		= wrap_led_probe,
	.remove		= wrap_led_remove,
	.driver		= {
		.name		= DRVNAME,
		.owner		= THIS_MODULE,
	},
};

static int __init wrap_led_init(void)
{
	int ret;

	if (!scx200_gpio_present()) {
		ret = -ENODEV;
		goto out;
	}

	ret = platform_driver_register(&wrap_led_driver);
	if (ret < 0)
		goto out;

	pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
	if (IS_ERR(pdev)) {
		ret = PTR_ERR(pdev);
		platform_driver_unregister(&wrap_led_driver);
		goto out;
	}

out:
	return ret;
}

static void __exit wrap_led_exit(void)
{
	platform_device_unregister(pdev);
	platform_driver_unregister(&wrap_led_driver);
}

module_init(wrap_led_init);
module_exit(wrap_led_exit);

MODULE_AUTHOR("Kristian Kielhofner <kris@krisk.org>");
MODULE_DESCRIPTION("PCEngines WRAP LED driver");
MODULE_LICENSE("GPL");

