// SPDX-License-Identifier: GPL-2.0-only
/*
 * Backlight driver for Marvell Semiconductor 88PM8606
 *
 * Copyright (C) 2009 Marvell International Ltd.
 *	Haojian Zhuang <haojian.zhuang@marvell.com>
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/backlight.h>
#include <linux/mfd/88pm860x.h>
#include <linux/module.h>

#define MAX_BRIGHTNESS		(0xFF)
#define MIN_BRIGHTNESS		(0)

#define CURRENT_BITMASK		(0x1F << 1)

struct pm860x_backlight_data {
	struct pm860x_chip *chip;
	struct i2c_client *i2c;
	int	current_brightness;
	int	port;
	int	pwm;
	int	iset;
	int	reg_duty_cycle;
	int	reg_always_on;
	int	reg_current;
};

static int backlight_power_set(struct pm860x_chip *chip, int port,
		int on)
{
	int ret = -EINVAL;

	switch (port) {
	case 0:
		ret = on ? pm8606_osc_enable(chip, WLED1_DUTY) :
			pm8606_osc_disable(chip, WLED1_DUTY);
		break;
	case 1:
		ret = on ? pm8606_osc_enable(chip, WLED2_DUTY) :
			pm8606_osc_disable(chip, WLED2_DUTY);
		break;
	case 2:
		ret = on ? pm8606_osc_enable(chip, WLED3_DUTY) :
			pm8606_osc_disable(chip, WLED3_DUTY);
		break;
	}
	return ret;
}

static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
{
	struct pm860x_backlight_data *data = bl_get_data(bl);
	struct pm860x_chip *chip = data->chip;
	unsigned char value;
	int ret;

	if (brightness > MAX_BRIGHTNESS)
		value = MAX_BRIGHTNESS;
	else
		value = brightness;

	if (brightness)
		backlight_power_set(chip, data->port, 1);

	ret = pm860x_reg_write(data->i2c, data->reg_duty_cycle, value);
	if (ret < 0)
		goto out;

	if ((data->current_brightness == 0) && brightness) {
		if (data->iset) {
			ret = pm860x_set_bits(data->i2c, data->reg_current,
					      CURRENT_BITMASK, data->iset);
			if (ret < 0)
				goto out;
		}
		if (data->pwm) {
			ret = pm860x_set_bits(data->i2c, PM8606_PWM,
					      PM8606_PWM_FREQ_MASK, data->pwm);
			if (ret < 0)
				goto out;
		}
		if (brightness == MAX_BRIGHTNESS) {
			/* set WLED_ON bit as 100% */
			ret = pm860x_set_bits(data->i2c, data->reg_always_on,
					      PM8606_WLED_ON, PM8606_WLED_ON);
		}
	} else {
		if (brightness == MAX_BRIGHTNESS) {
			/* set WLED_ON bit as 100% */
			ret = pm860x_set_bits(data->i2c, data->reg_always_on,
					      PM8606_WLED_ON, PM8606_WLED_ON);
		} else {
			/* clear WLED_ON bit since it's not 100% */
			ret = pm860x_set_bits(data->i2c, data->reg_always_on,
					      PM8606_WLED_ON, 0);
		}
	}
	if (ret < 0)
		goto out;

	if (brightness == 0)
		backlight_power_set(chip, data->port, 0);

	dev_dbg(chip->dev, "set brightness %d\n", value);
	data->current_brightness = value;
	return 0;
out:
	dev_dbg(chip->dev, "set brightness %d failure with return value: %d\n",
		value, ret);
	return ret;
}

static int pm860x_backlight_update_status(struct backlight_device *bl)
{
	return pm860x_backlight_set(bl, backlight_get_brightness(bl));
}

static int pm860x_backlight_get_brightness(struct backlight_device *bl)
{
	struct pm860x_backlight_data *data = bl_get_data(bl);
	struct pm860x_chip *chip = data->chip;
	int ret;

	ret = pm860x_reg_read(data->i2c, data->reg_duty_cycle);
	if (ret < 0)
		goto out;
	data->current_brightness = ret;
	dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness);
	return data->current_brightness;
out:
	return -EINVAL;
}

static const struct backlight_ops pm860x_backlight_ops = {
	.options	= BL_CORE_SUSPENDRESUME,
	.update_status	= pm860x_backlight_update_status,
	.get_brightness	= pm860x_backlight_get_brightness,
};

#ifdef CONFIG_OF
static int pm860x_backlight_dt_init(struct platform_device *pdev,
				    struct pm860x_backlight_data *data,
				    char *name)
{
	struct device_node *nproot;
	int iset = 0;

	nproot = of_get_child_by_name(pdev->dev.parent->of_node, "backlights");
	if (!nproot) {
		dev_err(&pdev->dev, "failed to find backlights node\n");
		return -ENODEV;
	}
	for_each_child_of_node_scoped(nproot, np) {
		if (of_node_name_eq(np, name)) {
			of_property_read_u32(np, "marvell,88pm860x-iset",
					     &iset);
			data->iset = PM8606_WLED_CURRENT(iset);
			of_property_read_u32(np, "marvell,88pm860x-pwm",
					     &data->pwm);
			break;
		}
	}
	of_node_put(nproot);
	return 0;
}
#else
#define pm860x_backlight_dt_init(x, y, z)	(-1)
#endif

static int pm860x_backlight_probe(struct platform_device *pdev)
{
	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
	struct pm860x_backlight_pdata *pdata = dev_get_platdata(&pdev->dev);
	struct pm860x_backlight_data *data;
	struct backlight_device *bl;
	struct resource *res;
	struct backlight_properties props;
	char name[MFD_NAME_SIZE];
	int ret = 0;

	data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data),
			    GFP_KERNEL);
	if (data == NULL)
		return -ENOMEM;
	res = platform_get_resource_byname(pdev, IORESOURCE_REG, "duty cycle");
	if (!res) {
		dev_err(&pdev->dev, "No REG resource for duty cycle\n");
		return -ENXIO;
	}
	data->reg_duty_cycle = res->start;
	res = platform_get_resource_byname(pdev, IORESOURCE_REG, "always on");
	if (!res) {
		dev_err(&pdev->dev, "No REG resource for always on\n");
		return -ENXIO;
	}
	data->reg_always_on = res->start;
	res = platform_get_resource_byname(pdev, IORESOURCE_REG, "current");
	if (!res) {
		dev_err(&pdev->dev, "No REG resource for current\n");
		return -ENXIO;
	}
	data->reg_current = res->start;

	memset(name, 0, MFD_NAME_SIZE);
	sprintf(name, "backlight-%d", pdev->id);
	data->port = pdev->id;
	data->chip = chip;
	data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
	data->current_brightness = MAX_BRIGHTNESS;
	if (pm860x_backlight_dt_init(pdev, data, name)) {
		if (pdata) {
			data->pwm = pdata->pwm;
			data->iset = pdata->iset;
		}
	}

	memset(&props, 0, sizeof(struct backlight_properties));
	props.type = BACKLIGHT_RAW;
	props.max_brightness = MAX_BRIGHTNESS;
	bl = devm_backlight_device_register(&pdev->dev, name, &pdev->dev, data,
					&pm860x_backlight_ops, &props);
	if (IS_ERR(bl)) {
		dev_err(&pdev->dev, "failed to register backlight\n");
		return PTR_ERR(bl);
	}
	bl->props.brightness = MAX_BRIGHTNESS;

	platform_set_drvdata(pdev, bl);

	/* read current backlight */
	ret = pm860x_backlight_get_brightness(bl);
	if (ret < 0)
		return ret;

	backlight_update_status(bl);
	return 0;
}

static struct platform_driver pm860x_backlight_driver = {
	.driver		= {
		.name	= "88pm860x-backlight",
	},
	.probe		= pm860x_backlight_probe,
};

module_platform_driver(pm860x_backlight_driver);

MODULE_DESCRIPTION("Backlight Driver for Marvell Semiconductor 88PM8606");
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:88pm860x-backlight");
