/*
 * Copyright (c) 2017 Sebastian Reichel <sre@kernel.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 or
 * later as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/leds.h>
#include <linux/mfd/motorola-cpcap.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>

#define CPCAP_LED_NO_CURRENT 0x0001

struct cpcap_led_info {
	u16 reg;
	u16 mask;
	u16 limit;
	u16 init_mask;
	u16 init_val;
};

static const struct cpcap_led_info cpcap_led_red = {
	.reg	= CPCAP_REG_REDC,
	.mask	= 0x03FF,
	.limit	= 31,
};

static const struct cpcap_led_info cpcap_led_green = {
	.reg	= CPCAP_REG_GREENC,
	.mask	= 0x03FF,
	.limit	= 31,
};

static const struct cpcap_led_info cpcap_led_blue = {
	.reg	= CPCAP_REG_BLUEC,
	.mask	= 0x03FF,
	.limit	= 31,
};

/* aux display light */
static const struct cpcap_led_info cpcap_led_adl = {
	.reg		= CPCAP_REG_ADLC,
	.mask		= 0x000F,
	.limit		= 1,
	.init_mask	= 0x7FFF,
	.init_val	= 0x5FF0,
};

/* camera privacy led */
static const struct cpcap_led_info cpcap_led_cp = {
	.reg		= CPCAP_REG_CLEDC,
	.mask		= 0x0007,
	.limit		= 1,
	.init_mask	= 0x03FF,
	.init_val	= 0x0008,
};

struct cpcap_led {
	struct led_classdev led;
	const struct cpcap_led_info *info;
	struct device *dev;
	struct regmap *regmap;
	struct mutex update_lock;
	struct regulator *vdd;
	bool powered;

	u32 current_limit;
};

static u16 cpcap_led_val(u8 current_limit, u8 duty_cycle)
{
	current_limit &= 0x1f; /* 5 bit */
	duty_cycle &= 0x0f; /* 4 bit */

	return current_limit << 4 | duty_cycle;
}

static int cpcap_led_set_power(struct cpcap_led *led, bool status)
{
	int err;

	if (status == led->powered)
		return 0;

	if (status)
		err = regulator_enable(led->vdd);
	else
		err = regulator_disable(led->vdd);

	if (err) {
		dev_err(led->dev, "regulator failure: %d", err);
		return err;
	}

	led->powered = status;

	return 0;
}

static int cpcap_led_set(struct led_classdev *ledc, enum led_brightness value)
{
	struct cpcap_led *led = container_of(ledc, struct cpcap_led, led);
	int brightness;
	int err;

	mutex_lock(&led->update_lock);

	if (value > LED_OFF) {
		err = cpcap_led_set_power(led, true);
		if (err)
			goto exit;
	}

	if (value == LED_OFF) {
		/* Avoid HW issue by turning off current before duty cycle */
		err = regmap_update_bits(led->regmap,
			led->info->reg, led->info->mask, CPCAP_LED_NO_CURRENT);
		if (err) {
			dev_err(led->dev, "regmap failed: %d", err);
			goto exit;
		}

		brightness = cpcap_led_val(value, LED_OFF);
	} else {
		brightness = cpcap_led_val(value, LED_ON);
	}

	err = regmap_update_bits(led->regmap, led->info->reg, led->info->mask,
		brightness);
	if (err) {
		dev_err(led->dev, "regmap failed: %d", err);
		goto exit;
	}

	if (value == LED_OFF) {
		err = cpcap_led_set_power(led, false);
		if (err)
			goto exit;
	}

exit:
	mutex_unlock(&led->update_lock);
	return err;
}

static const struct of_device_id cpcap_led_of_match[] = {
	{ .compatible = "motorola,cpcap-led-red", .data = &cpcap_led_red },
	{ .compatible = "motorola,cpcap-led-green", .data = &cpcap_led_green },
	{ .compatible = "motorola,cpcap-led-blue",  .data = &cpcap_led_blue },
	{ .compatible = "motorola,cpcap-led-adl", .data = &cpcap_led_adl },
	{ .compatible = "motorola,cpcap-led-cp", .data = &cpcap_led_cp },
	{},
};
MODULE_DEVICE_TABLE(of, cpcap_led_of_match);

static int cpcap_led_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	struct cpcap_led *led;
	int err;

	match = of_match_device(of_match_ptr(cpcap_led_of_match), &pdev->dev);
	if (!match || !match->data)
		return -EINVAL;

	led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
	if (!led)
		return -ENOMEM;
	platform_set_drvdata(pdev, led);
	led->info = match->data;
	led->dev = &pdev->dev;

	if (led->info->reg == 0x0000) {
		dev_err(led->dev, "Unsupported LED");
		return -ENODEV;
	}

	led->regmap = dev_get_regmap(pdev->dev.parent, NULL);
	if (!led->regmap)
		return -ENODEV;

	led->vdd = devm_regulator_get(&pdev->dev, "vdd");
	if (IS_ERR(led->vdd)) {
		err = PTR_ERR(led->vdd);
		dev_err(led->dev, "Couldn't get regulator: %d", err);
		return err;
	}

	err = device_property_read_string(&pdev->dev, "label", &led->led.name);
	if (err) {
		dev_err(led->dev, "Couldn't read LED label: %d", err);
		return err;
	}

	if (led->info->init_mask) {
		err = regmap_update_bits(led->regmap, led->info->reg,
			led->info->init_mask, led->info->init_val);
		if (err) {
			dev_err(led->dev, "regmap failed: %d", err);
			return err;
		}
	}

	mutex_init(&led->update_lock);

	led->led.max_brightness = led->info->limit;
	led->led.brightness_set_blocking = cpcap_led_set;
	err = devm_led_classdev_register(&pdev->dev, &led->led);
	if (err) {
		dev_err(led->dev, "Couldn't register LED: %d", err);
		return err;
	}

	return 0;
}

static struct platform_driver cpcap_led_driver = {
	.probe = cpcap_led_probe,
	.driver = {
		.name = "cpcap-led",
		.of_match_table = cpcap_led_of_match,
	},
};
module_platform_driver(cpcap_led_driver);

MODULE_DESCRIPTION("CPCAP LED driver");
MODULE_AUTHOR("Sebastian Reichel <sre@kernel.org>");
MODULE_LICENSE("GPL");
