/*
 * USB LED driver
 *
 * Copyright (C) 2004 Greg Kroah-Hartman (greg@kroah.com)
 *
 *	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, version 2.
 *
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb.h>


#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com"
#define DRIVER_DESC "USB LED Driver"

enum led_type {
	DELCOM_VISUAL_SIGNAL_INDICATOR,
	DREAM_CHEEKY_WEBMAIL_NOTIFIER,
};

/* table of devices that work with this driver */
static const struct usb_device_id id_table[] = {
	{ USB_DEVICE(0x0fc5, 0x1223),
			.driver_info = DELCOM_VISUAL_SIGNAL_INDICATOR },
	{ USB_DEVICE(0x1d34, 0x0004),
			.driver_info = DREAM_CHEEKY_WEBMAIL_NOTIFIER },
	{ },
};
MODULE_DEVICE_TABLE(usb, id_table);

struct usb_led {
	struct usb_device	*udev;
	unsigned char		blue;
	unsigned char		red;
	unsigned char		green;
	enum led_type		type;
};

static void change_color(struct usb_led *led)
{
	int retval = 0;
	unsigned char *buffer;

	buffer = kmalloc(8, GFP_KERNEL);
	if (!buffer) {
		dev_err(&led->udev->dev, "out of memory\n");
		return;
	}

	switch (led->type) {
	case DELCOM_VISUAL_SIGNAL_INDICATOR: {
		unsigned char color = 0x07;

		if (led->blue)
			color &= ~0x04;
		if (led->red)
			color &= ~0x02;
		if (led->green)
			color &= ~0x01;
		dev_dbg(&led->udev->dev,
			"blue = %d, red = %d, green = %d, color = %.2x\n",
			led->blue, led->red, led->green, color);

		retval = usb_control_msg(led->udev,
					usb_sndctrlpipe(led->udev, 0),
					0x12,
					0xc8,
					(0x02 * 0x100) + 0x0a,
					(0x00 * 0x100) + color,
					buffer,
					8,
					2000);
		break;
	}

	case DREAM_CHEEKY_WEBMAIL_NOTIFIER:
		dev_dbg(&led->udev->dev,
			"red = %d, green = %d, blue = %d\n",
			led->red, led->green, led->blue);

		buffer[0] = led->red;
		buffer[1] = led->green;
		buffer[2] = led->blue;
		buffer[3] = buffer[4] = buffer[5] = 0;
		buffer[6] = 0x1a;
		buffer[7] = 0x05;

		retval = usb_control_msg(led->udev,
					usb_sndctrlpipe(led->udev, 0),
					0x09,
					0x21,
					0x200,
					0,
					buffer,
					8,
					2000);
		break;

	default:
		dev_err(&led->udev->dev, "unknown device type %d\n", led->type);
	}

	if (retval)
		dev_dbg(&led->udev->dev, "retval = %d\n", retval);
	kfree(buffer);
}

#define show_set(value)	\
static ssize_t show_##value(struct device *dev, struct device_attribute *attr,\
			    char *buf)					\
{									\
	struct usb_interface *intf = to_usb_interface(dev);		\
	struct usb_led *led = usb_get_intfdata(intf);			\
									\
	return sprintf(buf, "%d\n", led->value);			\
}									\
static ssize_t set_##value(struct device *dev, struct device_attribute *attr,\
			   const char *buf, size_t count)		\
{									\
	struct usb_interface *intf = to_usb_interface(dev);		\
	struct usb_led *led = usb_get_intfdata(intf);			\
	int temp = simple_strtoul(buf, NULL, 10);			\
									\
	led->value = temp;						\
	change_color(led);						\
	return count;							\
}									\
static DEVICE_ATTR(value, S_IRUGO | S_IWUSR, show_##value, set_##value);
show_set(blue);
show_set(red);
show_set(green);

static int led_probe(struct usb_interface *interface,
		     const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(interface);
	struct usb_led *dev = NULL;
	int retval = -ENOMEM;

	dev = kzalloc(sizeof(struct usb_led), GFP_KERNEL);
	if (dev == NULL) {
		dev_err(&interface->dev, "out of memory\n");
		goto error_mem;
	}

	dev->udev = usb_get_dev(udev);
	dev->type = id->driver_info;

	usb_set_intfdata(interface, dev);

	retval = device_create_file(&interface->dev, &dev_attr_blue);
	if (retval)
		goto error;
	retval = device_create_file(&interface->dev, &dev_attr_red);
	if (retval)
		goto error;
	retval = device_create_file(&interface->dev, &dev_attr_green);
	if (retval)
		goto error;

	if (dev->type == DREAM_CHEEKY_WEBMAIL_NOTIFIER) {
		unsigned char *enable;

		enable = kmemdup("\x1f\x02\0\x5f\0\0\x1a\x03", 8, GFP_KERNEL);
		if (!enable) {
			dev_err(&interface->dev, "out of memory\n");
			retval = -ENOMEM;
			goto error;
		}

		retval = usb_control_msg(udev,
					usb_sndctrlpipe(udev, 0),
					0x09,
					0x21,
					0x200,
					0,
					enable,
					8,
					2000);

		kfree(enable);
		if (retval != 8)
			goto error;
	}

	dev_info(&interface->dev, "USB LED device now attached\n");
	return 0;

error:
	device_remove_file(&interface->dev, &dev_attr_blue);
	device_remove_file(&interface->dev, &dev_attr_red);
	device_remove_file(&interface->dev, &dev_attr_green);
	usb_set_intfdata(interface, NULL);
	usb_put_dev(dev->udev);
	kfree(dev);
error_mem:
	return retval;
}

static void led_disconnect(struct usb_interface *interface)
{
	struct usb_led *dev;

	dev = usb_get_intfdata(interface);

	device_remove_file(&interface->dev, &dev_attr_blue);
	device_remove_file(&interface->dev, &dev_attr_red);
	device_remove_file(&interface->dev, &dev_attr_green);

	/* first remove the files, then set the pointer to NULL */
	usb_set_intfdata(interface, NULL);

	usb_put_dev(dev->udev);

	kfree(dev);

	dev_info(&interface->dev, "USB LED now disconnected\n");
}

static struct usb_driver led_driver = {
	.name =		"usbled",
	.probe =	led_probe,
	.disconnect =	led_disconnect,
	.id_table =	id_table,
};

static int __init usb_led_init(void)
{
	int retval = 0;

	retval = usb_register(&led_driver);
	if (retval)
		err("usb_register failed. Error number %d", retval);
	return retval;
}

static void __exit usb_led_exit(void)
{
	usb_deregister(&led_driver);
}

module_init(usb_led_init);
module_exit(usb_led_exit);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
