/*
 *	LED driver for TI lp3952 controller
 *
 *	Copyright (C) 2016, DAQRI, LLC.
 *	Author: Tony Makkiel <tony.makkiel@daqri.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/leds.h>
#include <linux/leds-lp3952.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/reboot.h>
#include <linux/regmap.h>

static int lp3952_register_write(struct i2c_client *client, u8 reg, u8 val)
{
	int ret;
	struct lp3952_led_array *priv = i2c_get_clientdata(client);

	ret = regmap_write(priv->regmap, reg, val);

	if (ret)
		dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n",
			__func__, reg, val, ret);
	return ret;
}

static void lp3952_on_off(struct lp3952_led_array *priv,
			  enum lp3952_leds led_id, bool on)
{
	int ret, val;

	dev_dbg(&priv->client->dev, "%s LED %d to %d\n", __func__, led_id, on);

	val = 1 << led_id;
	if (led_id == LP3952_LED_ALL)
		val = LP3952_LED_MASK_ALL;

	ret = regmap_update_bits(priv->regmap, LP3952_REG_LED_CTRL, val,
				 on ? val : 0);
	if (ret)
		dev_err(&priv->client->dev, "%s, Error %d\n", __func__, ret);
}

/*
 * Using Imax to control brightness. There are 4 possible
 * setting 25, 50, 75 and 100 % of Imax. Possible values are
 * values 0-4. 0 meaning turn off.
 */
static int lp3952_set_brightness(struct led_classdev *cdev,
				 enum led_brightness value)
{
	unsigned int reg, shift_val;
	struct lp3952_ctrl_hdl *led = container_of(cdev,
						   struct lp3952_ctrl_hdl,
						   cdev);
	struct lp3952_led_array *priv = (struct lp3952_led_array *)led->priv;

	dev_dbg(cdev->dev, "Brightness request: %d on %d\n", value,
		led->channel);

	if (value == LED_OFF) {
		lp3952_on_off(priv, led->channel, false);
		return 0;
	}

	if (led->channel > LP3952_RED_1) {
		dev_err(cdev->dev, " %s Invalid LED requested", __func__);
		return -EINVAL;
	}

	if (led->channel >= LP3952_BLUE_1) {
		reg = LP3952_REG_RGB1_MAX_I_CTRL;
		shift_val = (led->channel - LP3952_BLUE_1) * 2;
	} else {
		reg = LP3952_REG_RGB2_MAX_I_CTRL;
		shift_val = led->channel * 2;
	}

	/* Enable the LED in case it is not enabled already */
	lp3952_on_off(priv, led->channel, true);

	return regmap_update_bits(priv->regmap, reg, 3 << shift_val,
				  --value << shift_val);
}

static int lp3952_get_label(struct device *dev, const char *label, char *dest)
{
	int ret;
	const char *str;

	ret = device_property_read_string(dev, label, &str);
	if (ret)
		return ret;

	strncpy(dest, str, LP3952_LABEL_MAX_LEN);
	return 0;
}

static int lp3952_register_led_classdev(struct lp3952_led_array *priv)
{
	int i, acpi_ret, ret = -ENODEV;
	static const char *led_name_hdl[LP3952_LED_ALL] = {
		"blue2",
		"green2",
		"red2",
		"blue1",
		"green1",
		"red1"
	};

	for (i = 0; i < LP3952_LED_ALL; i++) {
		acpi_ret = lp3952_get_label(&priv->client->dev, led_name_hdl[i],
					    priv->leds[i].name);
		if (acpi_ret)
			continue;

		priv->leds[i].cdev.name = priv->leds[i].name;
		priv->leds[i].cdev.brightness = LED_OFF;
		priv->leds[i].cdev.max_brightness = LP3952_BRIGHT_MAX;
		priv->leds[i].cdev.brightness_set_blocking =
				lp3952_set_brightness;
		priv->leds[i].channel = i;
		priv->leds[i].priv = priv;

		ret = devm_led_classdev_register(&priv->client->dev,
						 &priv->leds[i].cdev);
		if (ret < 0) {
			dev_err(&priv->client->dev,
				"couldn't register LED %s\n",
				priv->leds[i].cdev.name);
			break;
		}
	}
	return ret;
}

static int lp3952_set_pattern_gen_cmd(struct lp3952_led_array *priv,
				      u8 cmd_index, u8 r, u8 g, u8 b,
				      enum lp3952_tt tt, enum lp3952_cet cet)
{
	int ret;
	struct ptrn_gen_cmd line = {
		{
			{
				.r = r,
				.g = g,
				.b = b,
				.cet = cet,
				.tt = tt
			}
		}
	};

	if (cmd_index >= LP3952_CMD_REG_COUNT)
		return -EINVAL;

	ret = lp3952_register_write(priv->client,
				    LP3952_REG_CMD_0 + cmd_index * 2,
				    line.bytes.msb);
	if (ret)
		return ret;

	return lp3952_register_write(priv->client,
				      LP3952_REG_CMD_0 + cmd_index * 2 + 1,
				      line.bytes.lsb);
}

static int lp3952_configure(struct lp3952_led_array *priv)
{
	int ret;

	/* Disable any LEDs on from any previous conf. */
	ret = lp3952_register_write(priv->client, LP3952_REG_LED_CTRL, 0);
	if (ret)
		return ret;

	/* enable rgb patter, loop */
	ret = lp3952_register_write(priv->client, LP3952_REG_PAT_GEN_CTRL,
				    LP3952_PATRN_LOOP | LP3952_PATRN_GEN_EN);
	if (ret)
		return ret;

	/* Update Bit 6 (Active mode), Select both Led sets, Bit [1:0] */
	ret = lp3952_register_write(priv->client, LP3952_REG_ENABLES,
				    LP3952_ACTIVE_MODE | LP3952_INT_B00ST_LDR);
	if (ret)
		return ret;

	/* Set Cmd1 for RGB intensity,cmd and transition time */
	return lp3952_set_pattern_gen_cmd(priv, 0, I46, I71, I100, TT0,
					   CET197);
}

static const struct regmap_config lp3952_regmap = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = REG_MAX,
	.cache_type = REGCACHE_RBTREE,
};

static int lp3952_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int status;
	struct lp3952_led_array *priv;

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

	priv->client = client;

	priv->enable_gpio = devm_gpiod_get(&client->dev, "nrst",
					   GPIOD_OUT_HIGH);
	if (IS_ERR(priv->enable_gpio)) {
		status = PTR_ERR(priv->enable_gpio);
		dev_err(&client->dev, "Failed to enable gpio: %d\n", status);
		return status;
	}

	priv->regmap = devm_regmap_init_i2c(client, &lp3952_regmap);
	if (IS_ERR(priv->regmap)) {
		int err = PTR_ERR(priv->regmap);

		dev_err(&client->dev, "Failed to allocate register map: %d\n",
			err);
		return err;
	}

	i2c_set_clientdata(client, priv);

	status = lp3952_configure(priv);
	if (status) {
		dev_err(&client->dev, "Probe failed. Device not found (%d)\n",
			status);
		return status;
	}

	status = lp3952_register_led_classdev(priv);
	if (status) {
		dev_err(&client->dev, "Unable to register led_classdev: %d\n",
			status);
		return status;
	}

	return 0;
}

static int lp3952_remove(struct i2c_client *client)
{
	struct lp3952_led_array *priv;

	priv = i2c_get_clientdata(client);
	lp3952_on_off(priv, LP3952_LED_ALL, false);
	gpiod_set_value(priv->enable_gpio, 0);

	return 0;
}

static const struct i2c_device_id lp3952_id[] = {
	{LP3952_NAME, 0},
	{}
};
MODULE_DEVICE_TABLE(i2c, lp3952_id);

static struct i2c_driver lp3952_i2c_driver = {
	.driver = {
			.name = LP3952_NAME,
	},
	.probe = lp3952_probe,
	.remove = lp3952_remove,
	.id_table = lp3952_id,
};

module_i2c_driver(lp3952_i2c_driver);

MODULE_AUTHOR("Tony Makkiel <tony.makkiel@daqri.com>");
MODULE_DESCRIPTION("lp3952 I2C LED controller driver");
MODULE_LICENSE("GPL v2");
