// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for LEDs connected to the Intel Cherry Trail Whiskey Cove PMIC
 *
 * Copyright 2019 Yauhen Kharuzhy <jekhor@gmail.com>
 * Copyright 2023 Hans de Goede <hansg@kernel.org>
 *
 * Register info comes from the Lenovo Yoga Book Android opensource code
 * available from Lenovo. File lenovo_yb1_x90f_l_osc_201803.7z path in the 7z:
 * YB1_source_code/kernel/cht/drivers/misc/charger_gp_led.c
 */

#include <linux/kernel.h>
#include <linux/leds.h>
#include <linux/mfd/intel_soc_pmic.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/suspend.h>

#define CHT_WC_LED1_CTRL		0x5e1f
#define CHT_WC_LED1_FSM			0x5e20
#define CHT_WC_LED1_PWM			0x5e21

#define CHT_WC_LED2_CTRL		0x4fdf
#define CHT_WC_LED2_FSM			0x4fe0
#define CHT_WC_LED2_PWM			0x4fe1

#define CHT_WC_LED1_SWCTL		BIT(0)		/* HW or SW control of charging led */
#define CHT_WC_LED1_ON			BIT(1)

#define CHT_WC_LED2_ON			BIT(0)
#define CHT_WC_LED_I_MA2_5		(2 << 2)	/* LED current limit */
#define CHT_WC_LED_I_MASK		GENMASK(3, 2)	/* LED current limit mask */

#define CHT_WC_LED_F_1_4_HZ		(0 << 4)
#define CHT_WC_LED_F_1_2_HZ		(1 << 4)
#define CHT_WC_LED_F_1_HZ		(2 << 4)
#define CHT_WC_LED_F_2_HZ		(3 << 4)
#define CHT_WC_LED_F_MASK		GENMASK(5, 4)

#define CHT_WC_LED_EFF_OFF		(0 << 1)
#define CHT_WC_LED_EFF_ON		(1 << 1)
#define CHT_WC_LED_EFF_BLINKING		(2 << 1)
#define CHT_WC_LED_EFF_BREATHING	(3 << 1)
#define CHT_WC_LED_EFF_MASK		GENMASK(2, 1)

#define CHT_WC_LED_COUNT		2

struct cht_wc_led_regs {
	/* Register addresses */
	u16 ctrl;
	u16 fsm;
	u16 pwm;
	/* Mask + values for turning the LED on/off */
	u8 on_off_mask;
	u8 on_val;
	u8 off_val;
};

struct cht_wc_led_saved_regs {
	unsigned int ctrl;
	unsigned int fsm;
	unsigned int pwm;
};

struct cht_wc_led {
	struct led_classdev cdev;
	const struct cht_wc_led_regs *regs;
	struct regmap *regmap;
	struct mutex mutex;
	struct cht_wc_led_saved_regs saved_regs;
};

struct cht_wc_leds {
	struct cht_wc_led leds[CHT_WC_LED_COUNT];
	/* Saved LED1 initial register values */
	struct cht_wc_led_saved_regs led1_initial_regs;
};

static const struct cht_wc_led_regs cht_wc_led_regs[CHT_WC_LED_COUNT] = {
	{
		.ctrl		= CHT_WC_LED1_CTRL,
		.fsm		= CHT_WC_LED1_FSM,
		.pwm		= CHT_WC_LED1_PWM,
		.on_off_mask	= CHT_WC_LED1_SWCTL | CHT_WC_LED1_ON,
		.on_val		= CHT_WC_LED1_SWCTL | CHT_WC_LED1_ON,
		.off_val	= CHT_WC_LED1_SWCTL,
	},
	{
		.ctrl		= CHT_WC_LED2_CTRL,
		.fsm		= CHT_WC_LED2_FSM,
		.pwm		= CHT_WC_LED2_PWM,
		.on_off_mask	= CHT_WC_LED2_ON,
		.on_val		= CHT_WC_LED2_ON,
		.off_val	= 0,
	},
};

static const char * const cht_wc_leds_names[CHT_WC_LED_COUNT] = {
	"platform::" LED_FUNCTION_CHARGING,
	"platform::" LED_FUNCTION_INDICATOR,
};

static int cht_wc_leds_brightness_set(struct led_classdev *cdev,
				      enum led_brightness value)
{
	struct cht_wc_led *led = container_of(cdev, struct cht_wc_led, cdev);
	int ret;

	mutex_lock(&led->mutex);

	if (!value) {
		ret = regmap_update_bits(led->regmap, led->regs->ctrl,
					 led->regs->on_off_mask, led->regs->off_val);
		if (ret < 0) {
			dev_err(cdev->dev, "Failed to turn off: %d\n", ret);
			goto out;
		}

		/* Disable HW blinking */
		ret = regmap_update_bits(led->regmap, led->regs->fsm,
					 CHT_WC_LED_EFF_MASK, CHT_WC_LED_EFF_ON);
		if (ret < 0)
			dev_err(cdev->dev, "Failed to update LED FSM reg: %d\n", ret);
	} else {
		ret = regmap_write(led->regmap, led->regs->pwm, value);
		if (ret < 0) {
			dev_err(cdev->dev, "Failed to set brightness: %d\n", ret);
			goto out;
		}

		ret = regmap_update_bits(led->regmap, led->regs->ctrl,
					 led->regs->on_off_mask, led->regs->on_val);
		if (ret < 0)
			dev_err(cdev->dev, "Failed to turn on: %d\n", ret);
	}
out:
	mutex_unlock(&led->mutex);
	return ret;
}

static enum led_brightness cht_wc_leds_brightness_get(struct led_classdev *cdev)
{
	struct cht_wc_led *led = container_of(cdev, struct cht_wc_led, cdev);
	unsigned int val;
	int ret;

	mutex_lock(&led->mutex);

	ret = regmap_read(led->regmap, led->regs->ctrl, &val);
	if (ret < 0) {
		dev_err(cdev->dev, "Failed to read LED CTRL reg: %d\n", ret);
		ret = 0;
		goto done;
	}

	val &= led->regs->on_off_mask;
	if (val != led->regs->on_val) {
		ret = 0;
		goto done;
	}

	ret = regmap_read(led->regmap, led->regs->pwm, &val);
	if (ret < 0) {
		dev_err(cdev->dev, "Failed to read LED PWM reg: %d\n", ret);
		ret = 0;
		goto done;
	}

	ret = val;
done:
	mutex_unlock(&led->mutex);

	return ret;
}

/* Return blinking period for given CTRL reg value */
static unsigned long cht_wc_leds_get_period(int ctrl)
{
	ctrl &= CHT_WC_LED_F_MASK;

	switch (ctrl) {
	case CHT_WC_LED_F_1_4_HZ:
		return 1000 * 4;
	case CHT_WC_LED_F_1_2_HZ:
		return 1000 * 2;
	case CHT_WC_LED_F_1_HZ:
		return 1000;
	case CHT_WC_LED_F_2_HZ:
		return 1000 / 2;
	}

	return 0;
}

/*
 * Find suitable hardware blink mode for given period.
 * period < 750 ms - select 2 HZ
 * 750 ms <= period < 1500 ms - select 1 HZ
 * 1500 ms <= period < 3000 ms - select 1/2 HZ
 * 3000 ms <= period < 5000 ms - select 1/4 HZ
 * 5000 ms <= period - return -1
 */
static int cht_wc_leds_find_freq(unsigned long period)
{
	if (period < 750)
		return CHT_WC_LED_F_2_HZ;
	else if (period < 1500)
		return CHT_WC_LED_F_1_HZ;
	else if (period < 3000)
		return CHT_WC_LED_F_1_2_HZ;
	else if (period < 5000)
		return CHT_WC_LED_F_1_4_HZ;
	else
		return -1;
}

static int cht_wc_leds_set_effect(struct led_classdev *cdev,
				  unsigned long *delay_on,
				  unsigned long *delay_off,
				  u8 effect)
{
	struct cht_wc_led *led = container_of(cdev, struct cht_wc_led, cdev);
	int ctrl, ret;

	mutex_lock(&led->mutex);

	/* Blink with 1 Hz as default if nothing specified */
	if (!*delay_on && !*delay_off)
		*delay_on = *delay_off = 500;

	ctrl = cht_wc_leds_find_freq(*delay_on + *delay_off);
	if (ctrl < 0) {
		/* Disable HW blinking */
		ret = regmap_update_bits(led->regmap, led->regs->fsm,
					 CHT_WC_LED_EFF_MASK, CHT_WC_LED_EFF_ON);
		if (ret < 0)
			dev_err(cdev->dev, "Failed to update LED FSM reg: %d\n", ret);

		/* Fallback to software timer */
		*delay_on = *delay_off = 0;
		ret = -EINVAL;
		goto done;
	}

	ret = regmap_update_bits(led->regmap, led->regs->fsm,
				 CHT_WC_LED_EFF_MASK, effect);
	if (ret < 0)
		dev_err(cdev->dev, "Failed to update LED FSM reg: %d\n", ret);

	/* Set the frequency and make sure the LED is on */
	ret = regmap_update_bits(led->regmap, led->regs->ctrl,
				 CHT_WC_LED_F_MASK | led->regs->on_off_mask,
				 ctrl | led->regs->on_val);
	if (ret < 0)
		dev_err(cdev->dev, "Failed to update LED CTRL reg: %d\n", ret);

	*delay_off = *delay_on = cht_wc_leds_get_period(ctrl) / 2;

done:
	mutex_unlock(&led->mutex);

	return ret;
}

static int cht_wc_leds_blink_set(struct led_classdev *cdev,
				 unsigned long *delay_on,
				 unsigned long *delay_off)
{
	u8 effect = CHT_WC_LED_EFF_BLINKING;

	/*
	 * The desired default behavior of LED1 / the charge LED is breathing
	 * while charging and on/solid when full. Since triggers cannot select
	 * breathing, blink_set() gets called when charging. Use slow breathing
	 * when the default "charging-blink-full-solid" trigger is used to
	 * achieve the desired default behavior.
	 */
	if (cdev->flags & LED_INIT_DEFAULT_TRIGGER) {
		*delay_on = *delay_off = 1000;
		effect = CHT_WC_LED_EFF_BREATHING;
	}

	return cht_wc_leds_set_effect(cdev, delay_on, delay_off, effect);
}

static int cht_wc_leds_pattern_set(struct led_classdev *cdev,
				   struct led_pattern *pattern,
				   u32 len, int repeat)
{
	unsigned long delay_off, delay_on;

	if (repeat > 0 || len != 2 ||
	    pattern[0].brightness != 0 || pattern[1].brightness != 1 ||
	    pattern[0].delta_t != pattern[1].delta_t ||
	    (pattern[0].delta_t != 250 && pattern[0].delta_t != 500 &&
	     pattern[0].delta_t != 1000 && pattern[0].delta_t != 2000))
		return -EINVAL;

	delay_off = pattern[0].delta_t;
	delay_on  = pattern[1].delta_t;

	return cht_wc_leds_set_effect(cdev, &delay_on, &delay_off, CHT_WC_LED_EFF_BREATHING);
}

static int cht_wc_leds_pattern_clear(struct led_classdev *cdev)
{
	return cht_wc_leds_brightness_set(cdev, 0);
}

static int cht_wc_led_save_regs(struct cht_wc_led *led,
				struct cht_wc_led_saved_regs *saved_regs)
{
	int ret;

	ret = regmap_read(led->regmap, led->regs->ctrl, &saved_regs->ctrl);
	if (ret < 0)
		return ret;

	ret = regmap_read(led->regmap, led->regs->fsm, &saved_regs->fsm);
	if (ret < 0)
		return ret;

	return regmap_read(led->regmap, led->regs->pwm, &saved_regs->pwm);
}

static void cht_wc_led_restore_regs(struct cht_wc_led *led,
				    const struct cht_wc_led_saved_regs *saved_regs)
{
	regmap_write(led->regmap, led->regs->ctrl, saved_regs->ctrl);
	regmap_write(led->regmap, led->regs->fsm, saved_regs->fsm);
	regmap_write(led->regmap, led->regs->pwm, saved_regs->pwm);
}

static int cht_wc_leds_probe(struct platform_device *pdev)
{
	struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
	struct cht_wc_leds *leds;
	int ret;
	int i;

	/*
	 * On the Lenovo Yoga Tab 3 the LED1 driver output is actually
	 * connected to a haptic feedback motor rather then a LED.
	 * So do not register a LED classdev there (LED2 is unused).
	 */
	if (pmic->cht_wc_model == INTEL_CHT_WC_LENOVO_YT3_X90)
		return -ENODEV;

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

	/*
	 * LED1 might be in hw-controlled mode when this driver gets loaded; and
	 * since the PMIC is always powered by the battery any changes made are
	 * permanent. Save LED1 regs to restore them on remove() or shutdown().
	 */
	leds->leds[0].regs = &cht_wc_led_regs[0];
	leds->leds[0].regmap = pmic->regmap;
	ret = cht_wc_led_save_regs(&leds->leds[0], &leds->led1_initial_regs);
	if (ret < 0)
		return ret;

	/* Set LED1 default trigger based on machine model */
	switch (pmic->cht_wc_model) {
	case INTEL_CHT_WC_GPD_WIN_POCKET:
		leds->leds[0].cdev.default_trigger = "max170xx_battery-charging-blink-full-solid";
		break;
	case INTEL_CHT_WC_XIAOMI_MIPAD2:
		leds->leds[0].cdev.default_trigger = "bq27520-0-charging-blink-full-solid";
		break;
	case INTEL_CHT_WC_LENOVO_YOGABOOK1:
		leds->leds[0].cdev.default_trigger = "bq27542-0-charging-blink-full-solid";
		break;
	default:
		dev_warn(&pdev->dev, "Unknown model, no default charging trigger\n");
		break;
	}

	for (i = 0; i < CHT_WC_LED_COUNT; i++) {
		struct cht_wc_led *led = &leds->leds[i];

		led->regs = &cht_wc_led_regs[i];
		led->regmap = pmic->regmap;
		mutex_init(&led->mutex);
		led->cdev.name = cht_wc_leds_names[i];
		led->cdev.brightness_set_blocking = cht_wc_leds_brightness_set;
		led->cdev.brightness_get = cht_wc_leds_brightness_get;
		led->cdev.blink_set = cht_wc_leds_blink_set;
		led->cdev.pattern_set = cht_wc_leds_pattern_set;
		led->cdev.pattern_clear = cht_wc_leds_pattern_clear;
		led->cdev.max_brightness = 255;

		ret = led_classdev_register(&pdev->dev, &led->cdev);
		if (ret < 0)
			return ret;
	}

	platform_set_drvdata(pdev, leds);
	return 0;
}

static void cht_wc_leds_remove(struct platform_device *pdev)
{
	struct cht_wc_leds *leds = platform_get_drvdata(pdev);
	int i;

	for (i = 0; i < CHT_WC_LED_COUNT; i++)
		led_classdev_unregister(&leds->leds[i].cdev);

	/* Restore LED1 regs if hw-control was active else leave LED1 off */
	if (!(leds->led1_initial_regs.ctrl & CHT_WC_LED1_SWCTL))
		cht_wc_led_restore_regs(&leds->leds[0], &leds->led1_initial_regs);
}

static void cht_wc_leds_disable(struct platform_device *pdev)
{
	struct cht_wc_leds *leds = platform_get_drvdata(pdev);
	int i;

	for (i = 0; i < CHT_WC_LED_COUNT; i++)
		cht_wc_leds_brightness_set(&leds->leds[i].cdev, 0);

	/* Restore LED1 regs if hw-control was active else leave LED1 off */
	if (!(leds->led1_initial_regs.ctrl & CHT_WC_LED1_SWCTL))
		cht_wc_led_restore_regs(&leds->leds[0], &leds->led1_initial_regs);
}

/* On suspend save current settings and turn LEDs off */
static int cht_wc_leds_suspend(struct device *dev)
{
	struct cht_wc_leds *leds = dev_get_drvdata(dev);
	int i, ret;

	for (i = 0; i < CHT_WC_LED_COUNT; i++) {
		ret = cht_wc_led_save_regs(&leds->leds[i], &leds->leds[i].saved_regs);
		if (ret < 0)
			return ret;
	}

	cht_wc_leds_disable(to_platform_device(dev));
	return 0;
}

/* On resume restore the saved settings */
static int cht_wc_leds_resume(struct device *dev)
{
	struct cht_wc_leds *leds = dev_get_drvdata(dev);
	int i;

	for (i = 0; i < CHT_WC_LED_COUNT; i++)
		cht_wc_led_restore_regs(&leds->leds[i], &leds->leds[i].saved_regs);

	return 0;
}

static DEFINE_SIMPLE_DEV_PM_OPS(cht_wc_leds_pm, cht_wc_leds_suspend, cht_wc_leds_resume);

static struct platform_driver cht_wc_leds_driver = {
	.probe = cht_wc_leds_probe,
	.remove_new = cht_wc_leds_remove,
	.shutdown = cht_wc_leds_disable,
	.driver = {
		.name = "cht_wcove_leds",
		.pm = pm_sleep_ptr(&cht_wc_leds_pm),
	},
};
module_platform_driver(cht_wc_leds_driver);

MODULE_ALIAS("platform:cht_wcove_leds");
MODULE_DESCRIPTION("Intel Cherry Trail Whiskey Cove PMIC LEDs driver");
MODULE_AUTHOR("Yauhen Kharuzhy <jekhor@gmail.com>");
MODULE_LICENSE("GPL");
