// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for MPS MP3309C White LED driver with I2C interface
 *
 * This driver support both analog (by I2C commands) and PWM dimming control
 * modes.
 *
 * Copyright (C) 2023 ASEM Srl
 * Author: Flavio Suligoi <f.suligoi@asem.it>
 *
 * Based on pwm_bl.c
 */

#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/property.h>
#include <linux/pwm.h>
#include <linux/regmap.h>

#define REG_I2C_0	0x00
#define REG_I2C_1	0x01

#define REG_I2C_0_EN	0x80
#define REG_I2C_0_D0	0x40
#define REG_I2C_0_D1	0x20
#define REG_I2C_0_D2	0x10
#define REG_I2C_0_D3	0x08
#define REG_I2C_0_D4	0x04
#define REG_I2C_0_RSRV1	0x02
#define REG_I2C_0_RSRV2	0x01

#define REG_I2C_1_RSRV1	0x80
#define REG_I2C_1_DIMS	0x40
#define REG_I2C_1_SYNC	0x20
#define REG_I2C_1_OVP0	0x10
#define REG_I2C_1_OVP1	0x08
#define REG_I2C_1_VOS	0x04
#define REG_I2C_1_LEDO	0x02
#define REG_I2C_1_OTP	0x01

#define ANALOG_I2C_NUM_LEVELS	32		/* 0..31 */
#define ANALOG_I2C_REG_MASK	0x7c

#define MP3309C_PWM_DEFAULT_NUM_LEVELS	256	/* 0..255 */

enum mp3309c_status_value {
	FIRST_POWER_ON,
	BACKLIGHT_OFF,
	BACKLIGHT_ON,
};

enum mp3309c_dimming_mode_value {
	DIMMING_PWM,
	DIMMING_ANALOG_I2C,
};

struct mp3309c_platform_data {
	unsigned int max_brightness;
	unsigned int default_brightness;
	unsigned int *levels;
	u8  dimming_mode;
	u8  over_voltage_protection;
	bool sync_mode;
	u8 status;
};

struct mp3309c_chip {
	struct device *dev;
	struct mp3309c_platform_data *pdata;
	struct backlight_device *bl;
	struct gpio_desc *enable_gpio;
	struct regmap *regmap;
	struct pwm_device *pwmd;
};

static const struct regmap_config mp3309c_regmap = {
	.name = "mp3309c_regmap",
	.reg_bits = 8,
	.reg_stride = 1,
	.val_bits = 8,
	.max_register = REG_I2C_1,
};

static int mp3309c_enable_device(struct mp3309c_chip *chip)
{
	u8 reg_val;
	int ret;

	/* I2C register #0 - Device enable */
	ret = regmap_update_bits(chip->regmap, REG_I2C_0, REG_I2C_0_EN,
				 REG_I2C_0_EN);
	if (ret)
		return ret;

	/*
	 * I2C register #1 - Set working mode:
	 *  - enable/disable synchronous mode
	 *  - set overvoltage protection (OVP)
	 */
	reg_val = 0x00;
	if (chip->pdata->sync_mode)
		reg_val |= REG_I2C_1_SYNC;
	reg_val |= chip->pdata->over_voltage_protection;
	ret = regmap_write(chip->regmap, REG_I2C_1, reg_val);
	if (ret)
		return ret;

	return 0;
}

static int mp3309c_bl_update_status(struct backlight_device *bl)
{
	struct mp3309c_chip *chip = bl_get_data(bl);
	int brightness = backlight_get_brightness(bl);
	struct pwm_state pwmstate;
	unsigned int analog_val, bits_val;
	int i, ret;

	if (chip->pdata->dimming_mode == DIMMING_PWM) {
		/*
		 * PWM control mode
		 */
		pwm_get_state(chip->pwmd, &pwmstate);
		pwm_set_relative_duty_cycle(&pwmstate,
					    chip->pdata->levels[brightness],
					    chip->pdata->levels[chip->pdata->max_brightness]);
		pwmstate.enabled = true;
		ret = pwm_apply_might_sleep(chip->pwmd, &pwmstate);
		if (ret)
			return ret;

		switch (chip->pdata->status) {
		case FIRST_POWER_ON:
		case BACKLIGHT_OFF:
			/*
			 * After 20ms of low pwm signal level, the chip turns
			 * off automatically. In this case, before enabling the
			 * chip again, we must wait about 10ms for pwm signal to
			 * stabilize.
			 */
			if (brightness > 0) {
				msleep(10);
				mp3309c_enable_device(chip);
				chip->pdata->status = BACKLIGHT_ON;
			} else {
				chip->pdata->status = BACKLIGHT_OFF;
			}
			break;
		case BACKLIGHT_ON:
			if (brightness == 0)
				chip->pdata->status = BACKLIGHT_OFF;
			break;
		}
	} else {
		/*
		 * Analog (by I2C command) control mode
		 *
		 * The first time, before setting brightness, we must enable the
		 * device
		 */
		if (chip->pdata->status == FIRST_POWER_ON)
			mp3309c_enable_device(chip);

		/*
		 * Dimming mode I2C command (fixed dimming range 0..31)
		 *
		 * The 5 bits of the dimming analog value D4..D0 is allocated
		 * in the I2C register #0, in the following way:
		 *
		 *     +--+--+--+--+--+--+--+--+
		 *     |EN|D0|D1|D2|D3|D4|XX|XX|
		 *     +--+--+--+--+--+--+--+--+
		 */
		analog_val = brightness;
		bits_val = 0;
		for (i = 0; i <= 5; i++)
			bits_val += ((analog_val >> i) & 0x01) << (6 - i);
		ret = regmap_update_bits(chip->regmap, REG_I2C_0,
					 ANALOG_I2C_REG_MASK, bits_val);
		if (ret)
			return ret;

		if (brightness > 0)
			chip->pdata->status = BACKLIGHT_ON;
		else
			chip->pdata->status = BACKLIGHT_OFF;
	}

	return 0;
}

static const struct backlight_ops mp3309c_bl_ops = {
	.update_status = mp3309c_bl_update_status,
};

static int mp3309c_parse_fwnode(struct mp3309c_chip *chip,
				struct mp3309c_platform_data *pdata)
{
	int ret, i;
	unsigned int tmp_value;
	struct device *dev = chip->dev;
	int num_levels;

	if (!dev_fwnode(dev))
		return dev_err_probe(dev, -ENODEV, "failed to get firmware node\n");

	/*
	 * Dimming mode: the MP3309C provides two dimming control mode:
	 *
	 * - PWM mode
	 * - Analog by I2C control mode (default)
	 *
	 * I2C control mode is assumed as default but, if the pwms property is
	 * found in the backlight node, the mode switches to PWM mode.
	 */
	pdata->dimming_mode = DIMMING_ANALOG_I2C;
	if (device_property_present(dev, "pwms")) {
		chip->pwmd = devm_pwm_get(dev, NULL);
		if (IS_ERR(chip->pwmd))
			return dev_err_probe(dev, PTR_ERR(chip->pwmd), "error getting pwm data\n");
		pdata->dimming_mode = DIMMING_PWM;
	}

	/*
	 * In I2C control mode the dimming levels (0..31) are fixed by the
	 * hardware, while in PWM control mode they can be chosen by the user,
	 * to allow nonlinear mappings.
	 */
	if  (pdata->dimming_mode == DIMMING_ANALOG_I2C) {
		/*
		 * Analog (by I2C commands) control mode: fixed 0..31 brightness
		 * levels
		 */
		num_levels = ANALOG_I2C_NUM_LEVELS;

		/* Enable GPIO used in I2C dimming mode only */
		chip->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
		if (IS_ERR(chip->enable_gpio))
			return dev_err_probe(dev, PTR_ERR(chip->enable_gpio),
					     "error getting enable gpio\n");
	} else {
		/*
		 * PWM control mode: check for brightness level in DT
		 */
		if (device_property_present(dev, "brightness-levels")) {
			/* Read brightness levels from DT */
			num_levels = device_property_count_u32(dev, "brightness-levels");
			if (num_levels < 2)
				return -EINVAL;
		} else {
			/* Use default brightness levels */
			num_levels = MP3309C_PWM_DEFAULT_NUM_LEVELS;
		}
	}

	/* Fill brightness levels array */
	pdata->levels = devm_kcalloc(dev, num_levels, sizeof(*pdata->levels), GFP_KERNEL);
	if (!pdata->levels)
		return -ENOMEM;
	if (device_property_present(dev, "brightness-levels")) {
		ret = device_property_read_u32_array(dev, "brightness-levels",
						     pdata->levels, num_levels);
		if (ret < 0)
			return ret;
	} else {
		for (i = 0; i < num_levels; i++)
			pdata->levels[i] = i;
	}

	pdata->max_brightness = num_levels - 1;

	ret = device_property_read_u32(dev, "default-brightness", &pdata->default_brightness);
	if (ret)
		pdata->default_brightness = pdata->max_brightness;
	if (pdata->default_brightness > pdata->max_brightness) {
		dev_err_probe(dev, -ERANGE, "default brightness exceeds max brightness\n");
		pdata->default_brightness = pdata->max_brightness;
	}

	/*
	 * Over-voltage protection (OVP)
	 *
	 * This (optional) property values are:
	 *
	 *  - 13.5V
	 *  - 24V
	 *  - 35.5V (hardware default setting)
	 *
	 * If missing, the default value for OVP is 35.5V
	 */
	pdata->over_voltage_protection = REG_I2C_1_OVP1;
	ret = device_property_read_u32(dev, "mps,overvoltage-protection-microvolt", &tmp_value);
	if (!ret) {
		switch (tmp_value) {
		case 13500000:
			pdata->over_voltage_protection = 0x00;
			break;
		case 24000000:
			pdata->over_voltage_protection = REG_I2C_1_OVP0;
			break;
		case 35500000:
			pdata->over_voltage_protection = REG_I2C_1_OVP1;
			break;
		default:
			return -EINVAL;
		}
	}

	/* Synchronous (default) and non-synchronous mode */
	pdata->sync_mode = !device_property_read_bool(dev, "mps,no-sync-mode");

	return 0;
}

static int mp3309c_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct mp3309c_platform_data *pdata = dev_get_platdata(dev);
	struct mp3309c_chip *chip;
	struct backlight_properties props;
	struct pwm_state pwmstate;
	int ret;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
		return dev_err_probe(dev, -EOPNOTSUPP, "failed to check i2c functionality\n");

	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
	if (!chip)
		return -ENOMEM;

	chip->dev = dev;

	chip->regmap = devm_regmap_init_i2c(client, &mp3309c_regmap);
	if (IS_ERR(chip->regmap))
		return dev_err_probe(dev, PTR_ERR(chip->regmap),
				     "failed to allocate register map\n");

	i2c_set_clientdata(client, chip);

	if (!pdata) {
		pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
		if (!pdata)
			return -ENOMEM;

		ret = mp3309c_parse_fwnode(chip, pdata);
		if (ret)
			return ret;
	}
	chip->pdata = pdata;

	/* Backlight properties */
	props = (typeof(props)){
		.brightness = pdata->default_brightness,
		.max_brightness = pdata->max_brightness,
		.scale = BACKLIGHT_SCALE_LINEAR,
		.type = BACKLIGHT_RAW,
		.power = BACKLIGHT_POWER_ON,
	};
	chip->bl = devm_backlight_device_register(dev, "mp3309c", dev, chip,
						  &mp3309c_bl_ops, &props);
	if (IS_ERR(chip->bl))
		return dev_err_probe(dev, PTR_ERR(chip->bl),
				     "error registering backlight device\n");

	/* In PWM dimming mode, enable pwm device */
	if (chip->pdata->dimming_mode == DIMMING_PWM) {
		pwm_init_state(chip->pwmd, &pwmstate);
		pwm_set_relative_duty_cycle(&pwmstate,
					    chip->pdata->default_brightness,
					    chip->pdata->max_brightness);
		pwmstate.enabled = true;
		ret = pwm_apply_might_sleep(chip->pwmd, &pwmstate);
		if (ret)
			return dev_err_probe(dev, ret, "error setting pwm device\n");
	}

	chip->pdata->status = FIRST_POWER_ON;
	backlight_update_status(chip->bl);

	return 0;
}

static void mp3309c_remove(struct i2c_client *client)
{
	struct mp3309c_chip *chip = i2c_get_clientdata(client);
	struct backlight_device *bl = chip->bl;

	bl->props.power = BACKLIGHT_POWER_OFF;
	bl->props.brightness = 0;
	backlight_update_status(chip->bl);
}

static const struct of_device_id mp3309c_match_table[] = {
	{ .compatible = "mps,mp3309c", },
	{ },
};
MODULE_DEVICE_TABLE(of, mp3309c_match_table);

static const struct i2c_device_id mp3309c_id[] = {
	{ "mp3309c" },
	{ }
};
MODULE_DEVICE_TABLE(i2c, mp3309c_id);

static struct i2c_driver mp3309c_i2c_driver = {
	.driver	= {
			.name		= KBUILD_MODNAME,
			.of_match_table	= mp3309c_match_table,
	},
	.probe		= mp3309c_probe,
	.remove		= mp3309c_remove,
	.id_table	= mp3309c_id,
};

module_i2c_driver(mp3309c_i2c_driver);

MODULE_DESCRIPTION("Backlight Driver for MPS MP3309C");
MODULE_AUTHOR("Flavio Suligoi <f.suligoi@asem.it>");
MODULE_LICENSE("GPL");
