/*
 *  Copyright (C) 2011 Paul Parsons <lost.distance@yahoo.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/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/slab.h>

#include <linux/mfd/asic3.h>
#include <linux/mfd/core.h>

/*
 *	The HTC ASIC3 LED GPIOs are inputs, not outputs.
 *	Hence we turn the LEDs on/off via the TimeBase register.
 */

/*
 *	When TimeBase is 4 the clock resolution is about 32Hz.
 *	This driver supports hardware blinking with an on+off
 *	period from 62ms (2 clocks) to 125s (4000 clocks).
 */
#define MS_TO_CLK(ms)	DIV_ROUND_CLOSEST(((ms)*1024), 32000)
#define CLK_TO_MS(clk)	(((clk)*32000)/1024)
#define MAX_CLK		4000            /* Fits into 12-bit Time registers */
#define MAX_MS		CLK_TO_MS(MAX_CLK)

static const unsigned int led_n_base[ASIC3_NUM_LEDS] = {
	[0] = ASIC3_LED_0_Base,
	[1] = ASIC3_LED_1_Base,
	[2] = ASIC3_LED_2_Base,
};

static void brightness_set(struct led_classdev *cdev,
	enum led_brightness value)
{
	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
	u32 timebase;
	unsigned int base;

	timebase = (value == LED_OFF) ? 0 : (LED_EN|0x4);

	base = led_n_base[cell->id];
	asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), 32);
	asic3_write_register(asic, (base + ASIC3_LED_DutyTime), 32);
	asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0);
	asic3_write_register(asic, (base + ASIC3_LED_TimeBase), timebase);
}

static int blink_set(struct led_classdev *cdev,
	unsigned long *delay_on,
	unsigned long *delay_off)
{
	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
	u32 on;
	u32 off;
	unsigned int base;

	if (*delay_on > MAX_MS || *delay_off > MAX_MS)
		return -EINVAL;

	if (*delay_on == 0 && *delay_off == 0) {
		/* If both are zero then a sensible default should be chosen */
		on = MS_TO_CLK(500);
		off = MS_TO_CLK(500);
	} else {
		on = MS_TO_CLK(*delay_on);
		off = MS_TO_CLK(*delay_off);
		if ((on + off) > MAX_CLK)
			return -EINVAL;
	}

	base = led_n_base[cell->id];
	asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), (on + off));
	asic3_write_register(asic, (base + ASIC3_LED_DutyTime), on);
	asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0);
	asic3_write_register(asic, (base + ASIC3_LED_TimeBase), (LED_EN|0x4));

	*delay_on = CLK_TO_MS(on);
	*delay_off = CLK_TO_MS(off);

	return 0;
}

static int __devinit asic3_led_probe(struct platform_device *pdev)
{
	struct asic3_led *led = pdev->dev.platform_data;
	int ret;

	ret = mfd_cell_enable(pdev);
	if (ret < 0)
		goto ret0;

	led->cdev = kzalloc(sizeof(struct led_classdev), GFP_KERNEL);
	if (!led->cdev) {
		ret = -ENOMEM;
		goto ret1;
	}

	led->cdev->name = led->name;
	led->cdev->flags = LED_CORE_SUSPENDRESUME;
	led->cdev->brightness_set = brightness_set;
	led->cdev->blink_set = blink_set;
	led->cdev->default_trigger = led->default_trigger;

	ret = led_classdev_register(&pdev->dev, led->cdev);
	if (ret < 0)
		goto ret2;

	return 0;

ret2:
	kfree(led->cdev);
ret1:
	(void) mfd_cell_disable(pdev);
ret0:
	return ret;
}

static int __devexit asic3_led_remove(struct platform_device *pdev)
{
	struct asic3_led *led = pdev->dev.platform_data;

	led_classdev_unregister(led->cdev);

	kfree(led->cdev);

	return mfd_cell_disable(pdev);
}

static int asic3_led_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	int ret;

	ret = 0;
	if (cell->suspend)
		ret = (*cell->suspend)(pdev);

	return ret;
}

static int asic3_led_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	int ret;

	ret = 0;
	if (cell->resume)
		ret = (*cell->resume)(pdev);

	return ret;
}

static const struct dev_pm_ops asic3_led_pm_ops = {
	.suspend	= asic3_led_suspend,
	.resume		= asic3_led_resume,
};

static struct platform_driver asic3_led_driver = {
	.probe		= asic3_led_probe,
	.remove		= __devexit_p(asic3_led_remove),
	.driver		= {
		.name	= "leds-asic3",
		.owner	= THIS_MODULE,
		.pm	= &asic3_led_pm_ops,
	},
};

MODULE_ALIAS("platform:leds-asic3");

static int __init asic3_led_init(void)
{
	return platform_driver_register(&asic3_led_driver);
}

static void __exit asic3_led_exit(void)
{
	platform_driver_unregister(&asic3_led_driver);
}

module_init(asic3_led_init);
module_exit(asic3_led_exit);

MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>");
MODULE_DESCRIPTION("HTC ASIC3 LED driver");
MODULE_LICENSE("GPL");
