/*
 * LED Class Core
 *
 * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu>
 * Copyright (C) 2005-2006 Richard Purdie <rpurdie@openedhand.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/list.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <linux/timer.h>
#include <linux/err.h>
#include <linux/ctype.h>
#include <linux/leds.h>
#include "leds.h"

static struct class *leds_class;

static ssize_t led_brightness_show(struct class_device *dev, char *buf)
{
	struct led_classdev *led_cdev = class_get_devdata(dev);
	ssize_t ret = 0;

	/* no lock needed for this */
	sprintf(buf, "%u\n", led_cdev->brightness);
	ret = strlen(buf) + 1;

	return ret;
}

static ssize_t led_brightness_store(struct class_device *dev,
				const char *buf, size_t size)
{
	struct led_classdev *led_cdev = class_get_devdata(dev);
	ssize_t ret = -EINVAL;
	char *after;
	unsigned long state = simple_strtoul(buf, &after, 10);
	size_t count = after - buf;

	if (*after && isspace(*after))
		count++;

	if (count == size) {
		ret = count;
		led_set_brightness(led_cdev, state);
	}

	return ret;
}

static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show,
			led_brightness_store);
#ifdef CONFIG_LEDS_TRIGGERS
static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
#endif

/**
 * led_classdev_suspend - suspend an led_classdev.
 * @led_cdev: the led_classdev to suspend.
 */
void led_classdev_suspend(struct led_classdev *led_cdev)
{
	led_cdev->flags |= LED_SUSPENDED;
	led_cdev->brightness_set(led_cdev, 0);
}
EXPORT_SYMBOL_GPL(led_classdev_suspend);

/**
 * led_classdev_resume - resume an led_classdev.
 * @led_cdev: the led_classdev to resume.
 */
void led_classdev_resume(struct led_classdev *led_cdev)
{
	led_cdev->brightness_set(led_cdev, led_cdev->brightness);
	led_cdev->flags &= ~LED_SUSPENDED;
}
EXPORT_SYMBOL_GPL(led_classdev_resume);

/**
 * led_classdev_register - register a new object of led_classdev class.
 * @dev: The device to register.
 * @led_cdev: the led_classdev structure for this device.
 */
int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
{
	led_cdev->class_dev = class_device_create(leds_class, NULL, 0,
						parent, "%s", led_cdev->name);
	if (unlikely(IS_ERR(led_cdev->class_dev)))
		return PTR_ERR(led_cdev->class_dev);

	class_set_devdata(led_cdev->class_dev, led_cdev);

	/* register the attributes */
	class_device_create_file(led_cdev->class_dev,
				&class_device_attr_brightness);

	/* add to the list of leds */
	write_lock(&leds_list_lock);
	list_add_tail(&led_cdev->node, &leds_list);
	write_unlock(&leds_list_lock);

#ifdef CONFIG_LEDS_TRIGGERS
	rwlock_init(&led_cdev->trigger_lock);

	led_trigger_set_default(led_cdev);

	class_device_create_file(led_cdev->class_dev,
				&class_device_attr_trigger);
#endif

	printk(KERN_INFO "Registered led device: %s\n",
			led_cdev->class_dev->class_id);

	return 0;
}
EXPORT_SYMBOL_GPL(led_classdev_register);

/**
 * led_classdev_unregister - unregisters a object of led_properties class.
 * @led_cdev: the led device to unregister
 *
 * Unregisters a previously registered via led_classdev_register object.
 */
void led_classdev_unregister(struct led_classdev *led_cdev)
{
	class_device_remove_file(led_cdev->class_dev,
				&class_device_attr_brightness);
#ifdef CONFIG_LEDS_TRIGGERS
	class_device_remove_file(led_cdev->class_dev,
				&class_device_attr_trigger);
	write_lock(&led_cdev->trigger_lock);
	if (led_cdev->trigger)
		led_trigger_set(led_cdev, NULL);
	write_unlock(&led_cdev->trigger_lock);
#endif

	class_device_unregister(led_cdev->class_dev);

	write_lock(&leds_list_lock);
	list_del(&led_cdev->node);
	write_unlock(&leds_list_lock);
}
EXPORT_SYMBOL_GPL(led_classdev_unregister);

static int __init leds_init(void)
{
	leds_class = class_create(THIS_MODULE, "leds");
	if (IS_ERR(leds_class))
		return PTR_ERR(leds_class);
	return 0;
}

static void __exit leds_exit(void)
{
	class_destroy(leds_class);
}

subsys_initcall(leds_init);
module_exit(leds_exit);

MODULE_AUTHOR("John Lenz, Richard Purdie");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LED Class Interface");
