/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#define pr_fmt(fmt) "%s: " fmt, __func__

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/module.h>

#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>

/* Early-suspend level */
#define LED_SUSPEND_LEVEL 1
#endif

#define PDM_DUTY_MAXVAL BIT(16)
#define PDM_DUTY_REFVAL BIT(15)

struct pdm_led_data {
	struct led_classdev cdev;
	void __iomem *perph_base;
	int pdm_offset;
#ifdef CONFIG_HAS_EARLYSUSPEND
	struct early_suspend early_suspend;
#endif
};

static void msm_led_brightness_set_percent(struct pdm_led_data *led,
						int duty_per)
{
	u16 duty_val;

	duty_val = PDM_DUTY_REFVAL - ((PDM_DUTY_MAXVAL * duty_per) / 100);

	if (!duty_per)
		duty_val--;

	writel_relaxed(duty_val, led->perph_base + led->pdm_offset);
}

static void msm_led_brightness_set(struct led_classdev *led_cdev,
				enum led_brightness value)
{
	struct pdm_led_data *led =
		container_of(led_cdev, struct pdm_led_data, cdev);

	msm_led_brightness_set_percent(led, (value * 100) / LED_FULL);
}

#ifdef CONFIG_PM_SLEEP
static int msm_led_pdm_suspend(struct device *dev)
{
	struct pdm_led_data *led = dev_get_drvdata(dev);

	msm_led_brightness_set_percent(led, 0);

	return 0;
}

#ifdef CONFIG_HAS_EARLYSUSPEND
static void msm_led_pdm_early_suspend(struct early_suspend *h)
{
	struct pdm_led_data *led = container_of(h,
			struct pdm_led_data, early_suspend);

	msm_led_pdm_suspend(led->cdev.dev->parent);
}

#endif

static const struct dev_pm_ops msm_led_pdm_pm_ops = {
#ifndef CONFIG_HAS_EARLYSUSPEND
	.suspend	= msm_led_pdm_suspend,
#endif
};
#endif

static int __devinit msm_pdm_led_probe(struct platform_device *pdev)
{
	const struct led_info *pdata = pdev->dev.platform_data;
	struct pdm_led_data *led;
	struct resource *res, *ioregion;
	u32 tcxo_pdm_ctl;
	int rc;

	if (!pdata) {
		pr_err("platform data is invalid\n");
		return -EINVAL;
	}

	if (pdev->id > 2) {
		pr_err("pdm id is invalid\n");
		return -EINVAL;
	}

	led = kzalloc(sizeof(struct pdm_led_data), GFP_KERNEL);
	if (!led)
		return -ENOMEM;

	/* Enable runtime PM ops, start in ACTIVE mode */
	rc = pm_runtime_set_active(&pdev->dev);
	if (rc < 0)
		dev_dbg(&pdev->dev, "unable to set runtime pm state\n");
	pm_runtime_enable(&pdev->dev);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		pr_err("get resource failed\n");
		rc = -EINVAL;
		goto err_get_res;
	}

	ioregion = request_mem_region(res->start, resource_size(res),
						pdev->name);
	if (!ioregion) {
		pr_err("request for mem region failed\n");
		rc = -ENOMEM;
		goto err_get_res;
	}

	led->perph_base = ioremap(res->start, resource_size(res));
	if (!led->perph_base) {
		pr_err("ioremap failed\n");
		rc = -ENOMEM;
		goto err_ioremap;
	}

	/* Pulse Density Modulation(PDM) ids start with 0 and
	 * every PDM register takes 4 bytes
	 */
	led->pdm_offset = ((pdev->id) + 1) * 4;

	/* program tcxo_pdm_ctl register to enable pdm*/
	tcxo_pdm_ctl = readl_relaxed(led->perph_base);
	tcxo_pdm_ctl |= (1 << pdev->id);
	writel_relaxed(tcxo_pdm_ctl, led->perph_base);

	/* Start with LED in off state */
	msm_led_brightness_set_percent(led, 0);

	led->cdev.brightness_set = msm_led_brightness_set;
	led->cdev.name = pdata->name ? : "leds-msm-pdm";

	rc = led_classdev_register(&pdev->dev, &led->cdev);
	if (rc) {
		pr_err("led class registration failed\n");
		goto err_led_reg;
	}

#ifdef CONFIG_HAS_EARLYSUSPEND
	led->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
						LED_SUSPEND_LEVEL;
	led->early_suspend.suspend = msm_led_pdm_early_suspend;
	register_early_suspend(&led->early_suspend);
#endif

	platform_set_drvdata(pdev, led);
	return 0;

err_led_reg:
	iounmap(led->perph_base);
err_ioremap:
	release_mem_region(res->start, resource_size(res));
err_get_res:
	pm_runtime_set_suspended(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
	kfree(led);
	return rc;
}

static int __devexit msm_pdm_led_remove(struct platform_device *pdev)
{
	struct pdm_led_data *led = platform_get_drvdata(pdev);
	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

#ifdef CONFIG_HAS_EARLYSUSPEND
	unregister_early_suspend(&led->early_suspend);
#endif
	pm_runtime_set_suspended(&pdev->dev);
	pm_runtime_disable(&pdev->dev);

	led_classdev_unregister(&led->cdev);
	msm_led_brightness_set_percent(led, 0);
	iounmap(led->perph_base);
	release_mem_region(res->start, resource_size(res));
	kfree(led);

	return 0;
}

static struct platform_driver msm_pdm_led_driver = {
	.probe		= msm_pdm_led_probe,
	.remove		= __devexit_p(msm_pdm_led_remove),
	.driver		= {
		.name	= "leds-msm-pdm",
		.owner	= THIS_MODULE,
#ifdef CONFIG_PM_SLEEP
		.pm	= &msm_led_pdm_pm_ops,
#endif
	},
};

static int __init msm_pdm_led_init(void)
{
	return platform_driver_register(&msm_pdm_led_driver);
}
module_init(msm_pdm_led_init);

static void __exit msm_pdm_led_exit(void)
{
	platform_driver_unregister(&msm_pdm_led_driver);
}
module_exit(msm_pdm_led_exit);

MODULE_DESCRIPTION("MSM PDM LEDs driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:leds-msm-pdm");
