/*
 *	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/acpi.h>
#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)
		strncpy(dest, str, LP3952_LABEL_MAX_LEN);

	return ret;
}

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},
	{}
};

#ifdef CONFIG_ACPI
static const struct acpi_device_id lp3952_acpi_match[] = {
	{"TXNW3952", 0},
	{}
};

MODULE_DEVICE_TABLE(acpi, lp3952_acpi_match);
#endif

static struct i2c_driver lp3952_i2c_driver = {
	.driver = {
			.name = LP3952_NAME,
			.acpi_match_table = ACPI_PTR(lp3952_acpi_match),
	},
	.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");
