/*
 * AS3711 PMIC backlight driver, using DCDC Step Up Converters
 *
 * Copyright (C) 2012 Renesas Electronics Corporation
 * Author: Guennadi Liakhovetski, <g.liakhovetski@gmx.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the version 2 of the GNU General Public License as
 * published by the Free Software Foundation
 */

#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/fb.h>
#include <linux/kernel.h>
#include <linux/mfd/as3711.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>

enum as3711_bl_type {
	AS3711_BL_SU1,
	AS3711_BL_SU2,
};

struct as3711_bl_data {
	bool powered;
	const char *fb_name;
	struct device *fb_dev;
	enum as3711_bl_type type;
	int brightness;
	struct backlight_device *bl;
};

struct as3711_bl_supply {
	struct as3711_bl_data su1;
	struct as3711_bl_data su2;
	const struct as3711_bl_pdata *pdata;
	struct as3711 *as3711;
};

static struct as3711_bl_supply *to_supply(struct as3711_bl_data *su)
{
	switch (su->type) {
	case AS3711_BL_SU1:
		return container_of(su, struct as3711_bl_supply, su1);
	case AS3711_BL_SU2:
		return container_of(su, struct as3711_bl_supply, su2);
	}
	return NULL;
}

static int as3711_set_brightness_auto_i(struct as3711_bl_data *data,
					unsigned int brightness)
{
	struct as3711_bl_supply *supply = to_supply(data);
	struct as3711 *as3711 = supply->as3711;
	const struct as3711_bl_pdata *pdata = supply->pdata;
	int ret = 0;

	/* Only all equal current values are supported */
	if (pdata->su2_auto_curr1)
		ret = regmap_write(as3711->regmap, AS3711_CURR1_VALUE,
				   brightness);
	if (!ret && pdata->su2_auto_curr2)
		ret = regmap_write(as3711->regmap, AS3711_CURR2_VALUE,
				   brightness);
	if (!ret && pdata->su2_auto_curr3)
		ret = regmap_write(as3711->regmap, AS3711_CURR3_VALUE,
				   brightness);

	return ret;
}

static int as3711_set_brightness_v(struct as3711 *as3711,
				   unsigned int brightness,
				   unsigned int reg)
{
	if (brightness > 31)
		return -EINVAL;

	return regmap_update_bits(as3711->regmap, reg, 0xf0,
				  brightness << 4);
}

static int as3711_bl_su2_reset(struct as3711_bl_supply *supply)
{
	struct as3711 *as3711 = supply->as3711;
	int ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_5,
				     3, supply->pdata->su2_fbprot);
	if (!ret)
		ret = regmap_update_bits(as3711->regmap,
					 AS3711_STEPUP_CONTROL_2, 1, 0);
	if (!ret)
		ret = regmap_update_bits(as3711->regmap,
					 AS3711_STEPUP_CONTROL_2, 1, 1);
	return ret;
}

/*
 * Someone with less fragile or less expensive hardware could try to simplify
 * the brightness adjustment procedure.
 */
static int as3711_bl_update_status(struct backlight_device *bl)
{
	struct as3711_bl_data *data = bl_get_data(bl);
	struct as3711_bl_supply *supply = to_supply(data);
	struct as3711 *as3711 = supply->as3711;
	int brightness = bl->props.brightness;
	int ret = 0;

	dev_dbg(&bl->dev, "%s(): brightness %u, pwr %x, blank %x, state %x\n",
		__func__, bl->props.brightness, bl->props.power,
		bl->props.fb_blank, bl->props.state);

	if (bl->props.power != FB_BLANK_UNBLANK ||
	    bl->props.fb_blank != FB_BLANK_UNBLANK ||
	    bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
		brightness = 0;

	if (data->type == AS3711_BL_SU1) {
		ret = as3711_set_brightness_v(as3711, brightness,
					      AS3711_STEPUP_CONTROL_1);
	} else {
		const struct as3711_bl_pdata *pdata = supply->pdata;

		switch (pdata->su2_feedback) {
		case AS3711_SU2_VOLTAGE:
			ret = as3711_set_brightness_v(as3711, brightness,
						      AS3711_STEPUP_CONTROL_2);
			break;
		case AS3711_SU2_CURR_AUTO:
			ret = as3711_set_brightness_auto_i(data, brightness / 4);
			if (ret < 0)
				return ret;
			if (brightness) {
				ret = as3711_bl_su2_reset(supply);
				if (ret < 0)
					return ret;
				udelay(500);
				ret = as3711_set_brightness_auto_i(data, brightness);
			} else {
				ret = regmap_update_bits(as3711->regmap,
						AS3711_STEPUP_CONTROL_2, 1, 0);
			}
			break;
		/* Manual one current feedback pin below */
		case AS3711_SU2_CURR1:
			ret = regmap_write(as3711->regmap, AS3711_CURR1_VALUE,
					   brightness);
			break;
		case AS3711_SU2_CURR2:
			ret = regmap_write(as3711->regmap, AS3711_CURR2_VALUE,
					   brightness);
			break;
		case AS3711_SU2_CURR3:
			ret = regmap_write(as3711->regmap, AS3711_CURR3_VALUE,
					   brightness);
			break;
		default:
			ret = -EINVAL;
		}
	}
	if (!ret)
		data->brightness = brightness;

	return ret;
}

static int as3711_bl_get_brightness(struct backlight_device *bl)
{
	struct as3711_bl_data *data = bl_get_data(bl);

	return data->brightness;
}

static const struct backlight_ops as3711_bl_ops = {
	.update_status	= as3711_bl_update_status,
	.get_brightness	= as3711_bl_get_brightness,
};

static int as3711_bl_init_su2(struct as3711_bl_supply *supply)
{
	struct as3711 *as3711 = supply->as3711;
	const struct as3711_bl_pdata *pdata = supply->pdata;
	u8 ctl = 0;
	int ret;

	dev_dbg(as3711->dev, "%s(): use %u\n", __func__, pdata->su2_feedback);

	/* Turn SU2 off */
	ret = regmap_write(as3711->regmap, AS3711_STEPUP_CONTROL_2, 0);
	if (ret < 0)
		return ret;

	switch (pdata->su2_feedback) {
	case AS3711_SU2_VOLTAGE:
		ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_4, 3, 0);
		break;
	case AS3711_SU2_CURR1:
		ctl = 1;
		ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_4, 3, 1);
		break;
	case AS3711_SU2_CURR2:
		ctl = 4;
		ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_4, 3, 2);
		break;
	case AS3711_SU2_CURR3:
		ctl = 0x10;
		ret = regmap_update_bits(as3711->regmap, AS3711_STEPUP_CONTROL_4, 3, 3);
		break;
	case AS3711_SU2_CURR_AUTO:
		if (pdata->su2_auto_curr1)
			ctl = 2;
		if (pdata->su2_auto_curr2)
			ctl |= 8;
		if (pdata->su2_auto_curr3)
			ctl |= 0x20;
		ret = 0;
		break;
	default:
		return -EINVAL;
	}

	if (!ret)
		ret = regmap_write(as3711->regmap, AS3711_CURR_CONTROL, ctl);

	return ret;
}

static int as3711_bl_register(struct platform_device *pdev,
			      unsigned int max_brightness, struct as3711_bl_data *su)
{
	struct backlight_properties props = {.type = BACKLIGHT_RAW,};
	struct backlight_device *bl;

	/* max tuning I = 31uA for voltage- and 38250uA for current-feedback */
	props.max_brightness = max_brightness;

	bl = devm_backlight_device_register(&pdev->dev,
				       su->type == AS3711_BL_SU1 ?
				       "as3711-su1" : "as3711-su2",
				       &pdev->dev, su,
				       &as3711_bl_ops, &props);
	if (IS_ERR(bl)) {
		dev_err(&pdev->dev, "failed to register backlight\n");
		return PTR_ERR(bl);
	}

	bl->props.brightness = props.max_brightness;

	backlight_update_status(bl);

	su->bl = bl;

	return 0;
}

static int as3711_backlight_parse_dt(struct device *dev)
{
	struct as3711_bl_pdata *pdata = dev_get_platdata(dev);
	struct device_node *bl =
		of_find_node_by_name(dev->parent->of_node, "backlight"), *fb;
	int ret;

	if (!bl) {
		dev_dbg(dev, "backlight node not found\n");
		return -ENODEV;
	}

	fb = of_parse_phandle(bl, "su1-dev", 0);
	if (fb) {
		pdata->su1_fb = fb->full_name;

		ret = of_property_read_u32(bl, "su1-max-uA", &pdata->su1_max_uA);
		if (pdata->su1_max_uA <= 0)
			ret = -EINVAL;
		if (ret < 0)
			return ret;
	}

	fb = of_parse_phandle(bl, "su2-dev", 0);
	if (fb) {
		int count = 0;

		pdata->su2_fb = fb->full_name;

		ret = of_property_read_u32(bl, "su2-max-uA", &pdata->su2_max_uA);
		if (pdata->su2_max_uA <= 0)
			ret = -EINVAL;
		if (ret < 0)
			return ret;

		if (of_find_property(bl, "su2-feedback-voltage", NULL)) {
			pdata->su2_feedback = AS3711_SU2_VOLTAGE;
			count++;
		}
		if (of_find_property(bl, "su2-feedback-curr1", NULL)) {
			pdata->su2_feedback = AS3711_SU2_CURR1;
			count++;
		}
		if (of_find_property(bl, "su2-feedback-curr2", NULL)) {
			pdata->su2_feedback = AS3711_SU2_CURR2;
			count++;
		}
		if (of_find_property(bl, "su2-feedback-curr3", NULL)) {
			pdata->su2_feedback = AS3711_SU2_CURR3;
			count++;
		}
		if (of_find_property(bl, "su2-feedback-curr-auto", NULL)) {
			pdata->su2_feedback = AS3711_SU2_CURR_AUTO;
			count++;
		}
		if (count != 1)
			return -EINVAL;

		count = 0;
		if (of_find_property(bl, "su2-fbprot-lx-sd4", NULL)) {
			pdata->su2_fbprot = AS3711_SU2_LX_SD4;
			count++;
		}
		if (of_find_property(bl, "su2-fbprot-gpio2", NULL)) {
			pdata->su2_fbprot = AS3711_SU2_GPIO2;
			count++;
		}
		if (of_find_property(bl, "su2-fbprot-gpio3", NULL)) {
			pdata->su2_fbprot = AS3711_SU2_GPIO3;
			count++;
		}
		if (of_find_property(bl, "su2-fbprot-gpio4", NULL)) {
			pdata->su2_fbprot = AS3711_SU2_GPIO4;
			count++;
		}
		if (count != 1)
			return -EINVAL;

		count = 0;
		if (of_find_property(bl, "su2-auto-curr1", NULL)) {
			pdata->su2_auto_curr1 = true;
			count++;
		}
		if (of_find_property(bl, "su2-auto-curr2", NULL)) {
			pdata->su2_auto_curr2 = true;
			count++;
		}
		if (of_find_property(bl, "su2-auto-curr3", NULL)) {
			pdata->su2_auto_curr3 = true;
			count++;
		}

		/*
		 * At least one su2-auto-curr* must be specified iff
		 * AS3711_SU2_CURR_AUTO is used
		 */
		if (!count ^ (pdata->su2_feedback != AS3711_SU2_CURR_AUTO))
			return -EINVAL;
	}

	return 0;
}

static int as3711_backlight_probe(struct platform_device *pdev)
{
	struct as3711_bl_pdata *pdata = dev_get_platdata(&pdev->dev);
	struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent);
	struct as3711_bl_supply *supply;
	struct as3711_bl_data *su;
	unsigned int max_brightness;
	int ret;

	if (!pdata) {
		dev_err(&pdev->dev, "No platform data, exiting...\n");
		return -ENODEV;
	}

	if (pdev->dev.parent->of_node) {
		ret = as3711_backlight_parse_dt(&pdev->dev);
		if (ret < 0) {
			dev_err(&pdev->dev, "DT parsing failed: %d\n", ret);
			return ret;
		}
	}

	if (!pdata->su1_fb && !pdata->su2_fb) {
		dev_err(&pdev->dev, "No framebuffer specified\n");
		return -EINVAL;
	}

	/*
	 * Due to possible hardware damage I chose to block all modes,
	 * unsupported on my hardware. Anyone, wishing to use any of those modes
	 * will have to first review the code, then activate and test it.
	 */
	if (pdata->su1_fb ||
	    pdata->su2_fbprot != AS3711_SU2_GPIO4 ||
	    pdata->su2_feedback != AS3711_SU2_CURR_AUTO) {
		dev_warn(&pdev->dev,
			 "Attention! An untested mode has been chosen!\n"
			 "Please, review the code, enable, test, and report success:-)\n");
		return -EINVAL;
	}

	supply = devm_kzalloc(&pdev->dev, sizeof(*supply), GFP_KERNEL);
	if (!supply)
		return -ENOMEM;

	supply->as3711 = as3711;
	supply->pdata = pdata;

	if (pdata->su1_fb) {
		su = &supply->su1;
		su->fb_name = pdata->su1_fb;
		su->type = AS3711_BL_SU1;

		max_brightness = min(pdata->su1_max_uA, 31);
		ret = as3711_bl_register(pdev, max_brightness, su);
		if (ret < 0)
			return ret;
	}

	if (pdata->su2_fb) {
		su = &supply->su2;
		su->fb_name = pdata->su2_fb;
		su->type = AS3711_BL_SU2;

		switch (pdata->su2_fbprot) {
		case AS3711_SU2_GPIO2:
		case AS3711_SU2_GPIO3:
		case AS3711_SU2_GPIO4:
		case AS3711_SU2_LX_SD4:
			break;
		default:
			return -EINVAL;
		}

		switch (pdata->su2_feedback) {
		case AS3711_SU2_VOLTAGE:
			max_brightness = min(pdata->su2_max_uA, 31);
			break;
		case AS3711_SU2_CURR1:
		case AS3711_SU2_CURR2:
		case AS3711_SU2_CURR3:
		case AS3711_SU2_CURR_AUTO:
			max_brightness = min(pdata->su2_max_uA / 150, 255);
			break;
		default:
			return -EINVAL;
		}

		ret = as3711_bl_init_su2(supply);
		if (ret < 0)
			return ret;

		ret = as3711_bl_register(pdev, max_brightness, su);
		if (ret < 0)
			return ret;
	}

	platform_set_drvdata(pdev, supply);

	return 0;
}

static struct platform_driver as3711_backlight_driver = {
	.driver		= {
		.name	= "as3711-backlight",
	},
	.probe		= as3711_backlight_probe,
};

module_platform_driver(as3711_backlight_driver);

MODULE_DESCRIPTION("Backlight Driver for AS3711 PMICs");
MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:as3711-backlight");
