/*
 * Backlight Driver for Dialog DA9052 PMICs
 *
 * Copyright(c) 2012 Dialog Semiconductor Ltd.
 *
 * Author: David Dajun Chen <dchen@diasemi.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; either version 2 of the License, or
 * (at your option) any later version.
 *
 */

#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#include <linux/mfd/da9052/da9052.h>
#include <linux/mfd/da9052/reg.h>

#define DA9052_MAX_BRIGHTNESS		0xFF

enum {
	DA9052_WLEDS_OFF,
	DA9052_WLEDS_ON,
};

enum {
	DA9052_TYPE_WLED1,
	DA9052_TYPE_WLED2,
	DA9052_TYPE_WLED3,
};

static unsigned char wled_bank[] = {
	DA9052_LED1_CONF_REG,
	DA9052_LED2_CONF_REG,
	DA9052_LED3_CONF_REG,
};

struct da9052_bl {
	struct da9052 *da9052;
	uint brightness;
	uint state;
	uint led_reg;
};

static int da9052_adjust_wled_brightness(struct da9052_bl *wleds)
{
	unsigned char boost_en;
	unsigned char i_sink;
	int ret;

	boost_en = 0x3F;
	i_sink = 0xFF;
	if (wleds->state == DA9052_WLEDS_OFF) {
		boost_en = 0x00;
		i_sink = 0x00;
	}

	ret = da9052_reg_write(wleds->da9052, DA9052_BOOST_REG, boost_en);
	if (ret < 0)
		return ret;

	ret = da9052_reg_write(wleds->da9052, DA9052_LED_CONT_REG, i_sink);
	if (ret < 0)
		return ret;

	ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg], 0x0);
	if (ret < 0)
		return ret;

	msleep(10);

	if (wleds->brightness) {
		ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg],
				       wleds->brightness);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int da9052_backlight_update_status(struct backlight_device *bl)
{
	int brightness = bl->props.brightness;
	struct da9052_bl *wleds = bl_get_data(bl);

	wleds->brightness = brightness;
	wleds->state = DA9052_WLEDS_ON;

	return da9052_adjust_wled_brightness(wleds);
}

static int da9052_backlight_get_brightness(struct backlight_device *bl)
{
	struct da9052_bl *wleds = bl_get_data(bl);

	return wleds->brightness;
}

static const struct backlight_ops da9052_backlight_ops = {
	.update_status = da9052_backlight_update_status,
	.get_brightness = da9052_backlight_get_brightness,
};

static int da9052_backlight_probe(struct platform_device *pdev)
{
	struct backlight_device *bl;
	struct backlight_properties props;
	struct da9052_bl *wleds;

	wleds = devm_kzalloc(&pdev->dev, sizeof(struct da9052_bl), GFP_KERNEL);
	if (!wleds)
		return -ENOMEM;

	wleds->da9052 = dev_get_drvdata(pdev->dev.parent);
	wleds->brightness = 0;
	wleds->led_reg = platform_get_device_id(pdev)->driver_data;
	wleds->state = DA9052_WLEDS_OFF;

	props.type = BACKLIGHT_RAW;
	props.max_brightness = DA9052_MAX_BRIGHTNESS;

	bl = backlight_device_register(pdev->name, wleds->da9052->dev, wleds,
				       &da9052_backlight_ops, &props);
	if (IS_ERR(bl)) {
		dev_err(&pdev->dev, "Failed to register backlight\n");
		devm_kfree(&pdev->dev, wleds);
		return PTR_ERR(bl);
	}

	bl->props.max_brightness = DA9052_MAX_BRIGHTNESS;
	bl->props.brightness = 0;
	platform_set_drvdata(pdev, bl);

	return da9052_adjust_wled_brightness(wleds);
}

static int da9052_backlight_remove(struct platform_device *pdev)
{
	struct backlight_device *bl = platform_get_drvdata(pdev);
	struct da9052_bl *wleds = bl_get_data(bl);

	wleds->brightness = 0;
	wleds->state = DA9052_WLEDS_OFF;
	da9052_adjust_wled_brightness(wleds);
	backlight_device_unregister(bl);
	devm_kfree(&pdev->dev, wleds);

	return 0;
}

static struct platform_device_id da9052_wled_ids[] = {
	{
		.name		= "da9052-wled1",
		.driver_data	= DA9052_TYPE_WLED1,
	},
	{
		.name		= "da9052-wled2",
		.driver_data	= DA9052_TYPE_WLED2,
	},
	{
		.name		= "da9052-wled3",
		.driver_data	= DA9052_TYPE_WLED3,
	},
};

static struct platform_driver da9052_wled_driver = {
	.probe		= da9052_backlight_probe,
	.remove		= da9052_backlight_remove,
	.id_table	= da9052_wled_ids,
	.driver	= {
		.name	= "da9052-wled",
		.owner	= THIS_MODULE,
	},
};

module_platform_driver(da9052_wled_driver);

MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
MODULE_DESCRIPTION("Backlight driver for DA9052 PMIC");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:da9052-backlight");
