/*
 * LEDs driver for Dialog Semiconductor DA9030/DA9034
 *
 * Copyright (C) 2008 Compulab, Ltd.
 * 	Mike Rapoport <mike@compulab.co.il>
 *
 * Copyright (C) 2006-2008 Marvell International Ltd.
 * 	Eric Miao <eric.miao@marvell.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/leds.h>
#include <linux/workqueue.h>
#include <linux/mfd/da903x.h>

#define DA9030_LED1_CONTROL	0x20
#define DA9030_LED2_CONTROL	0x21
#define DA9030_LED3_CONTROL	0x22
#define DA9030_LED4_CONTROL	0x23
#define DA9030_LEDPC_CONTROL	0x24
#define DA9030_MISC_CONTROL_A	0x26	/* Vibrator Control */

#define DA9034_LED1_CONTROL	0x35
#define DA9034_LED2_CONTROL	0x36
#define DA9034_VIBRA		0x40

struct da903x_led {
	struct led_classdev	cdev;
	struct work_struct	work;
	struct device		*master;
	enum led_brightness	new_brightness;
	int			id;
	int			flags;
};

#define DA9030_LED_OFFSET(id)	((id) - DA9030_ID_LED_1)
#define DA9034_LED_OFFSET(id)	((id) - DA9034_ID_LED_1)

static void da903x_led_work(struct work_struct *work)
{
	struct da903x_led *led = container_of(work, struct da903x_led, work);
	uint8_t val;
	int offset;

	switch (led->id) {
	case DA9030_ID_LED_1:
	case DA9030_ID_LED_2:
	case DA9030_ID_LED_3:
	case DA9030_ID_LED_4:
	case DA9030_ID_LED_PC:
		offset = DA9030_LED_OFFSET(led->id);
		val = led->flags & ~0x87;
		val |= (led->new_brightness) ? 0x80 : 0; /* EN bit */
		val |= (led->new_brightness >> 5) & 0x7; /* PWM<2:0> */
		da903x_write(led->master, DA9030_LED1_CONTROL + offset, val);
		break;
	case DA9030_ID_VIBRA:
		val = led->flags & ~0x80;
		val |= (led->new_brightness) ? 0x80 : 0; /* EN bit */
		da903x_write(led->master, DA9030_MISC_CONTROL_A, val);
		break;
	case DA9034_ID_LED_1:
	case DA9034_ID_LED_2:
		offset = DA9034_LED_OFFSET(led->id);
		val = (led->new_brightness * 0x5f / LED_FULL) & 0x7f;
		val |= (led->flags & DA9034_LED_RAMP) ? 0x80 : 0;
		da903x_write(led->master, DA9034_LED1_CONTROL + offset, val);
		break;
	case DA9034_ID_VIBRA:
		val = led->new_brightness & 0xfe;
		da903x_write(led->master, DA9034_VIBRA, val);
		break;
	}
}

static void da903x_led_set(struct led_classdev *led_cdev,
			   enum led_brightness value)
{
	struct da903x_led *led;
	
	led = container_of(led_cdev, struct da903x_led, cdev);
	led->new_brightness = value;
	schedule_work(&led->work);
}

static int __devinit da903x_led_probe(struct platform_device *pdev)
{
	struct led_info *pdata = pdev->dev.platform_data;
	struct da903x_led *led;
	int id, ret;

	if (pdata == NULL)
		return 0;

	id = pdev->id;

	if (!((id >= DA9030_ID_LED_1 && id <= DA9030_ID_VIBRA) ||
	      (id >= DA9034_ID_LED_1 && id <= DA9034_ID_VIBRA))) {
		dev_err(&pdev->dev, "invalid LED ID (%d) specified\n", id);
		return -EINVAL;
	}

	led = kzalloc(sizeof(struct da903x_led), GFP_KERNEL);
	if (led == NULL) {
		dev_err(&pdev->dev, "failed to alloc memory for LED%d\n", id);
		return -ENOMEM;
	}

	led->cdev.name = pdata->name;
	led->cdev.default_trigger = pdata->default_trigger;
	led->cdev.brightness_set = da903x_led_set;
	led->cdev.brightness = LED_OFF;

	led->id = id;
	led->flags = pdata->flags;
	led->master = pdev->dev.parent;
	led->new_brightness = LED_OFF;

	INIT_WORK(&led->work, da903x_led_work);

	ret = led_classdev_register(led->master, &led->cdev);
	if (ret) {
		dev_err(&pdev->dev, "failed to register LED %d\n", id);
		goto err;
	}

	platform_set_drvdata(pdev, led);
	return 0;

err:
	kfree(led);
	return ret;
}

static int __devexit da903x_led_remove(struct platform_device *pdev)
{
	struct da903x_led *led = platform_get_drvdata(pdev);

	led_classdev_unregister(&led->cdev);
	kfree(led);
	return 0;
}

static struct platform_driver da903x_led_driver = {
	.driver	= {
		.name	= "da903x-led",
		.owner	= THIS_MODULE,
	},
	.probe		= da903x_led_probe,
	.remove		= __devexit_p(da903x_led_remove),
};

static int __init da903x_led_init(void)
{
	return platform_driver_register(&da903x_led_driver);
}
module_init(da903x_led_init);

static void __exit da903x_led_exit(void)
{
	platform_driver_unregister(&da903x_led_driver);
}
module_exit(da903x_led_exit);

MODULE_DESCRIPTION("LEDs driver for Dialog Semiconductor DA9030/DA9034");
MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
	      "Mike Rapoport <mike@compulab.co.il>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:da903x-led");
