/*
* Simple driver for Texas Instruments LM355x LED Flash driver chip
* Copyright (C) 2012 Texas Instruments
*
* 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/module.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/regmap.h>
#include <linux/workqueue.h>
#include <linux/platform_data/leds-lm355x.h>

enum lm355x_type {
	CHIP_LM3554 = 0,
	CHIP_LM3556,
};

enum lm355x_regs {
	REG_FLAG = 0,
	REG_TORCH_CFG,
	REG_TORCH_CTRL,
	REG_STROBE_CFG,
	REG_FLASH_CTRL,
	REG_INDI_CFG,
	REG_INDI_CTRL,
	REG_OPMODE,
	REG_MAX,
};

/* operation mode */
enum lm355x_mode {
	MODE_SHDN = 0,
	MODE_INDIC,
	MODE_TORCH,
	MODE_FLASH
};

/* register map info. */
struct lm355x_reg_data {
	u8 regno;
	u8 mask;
	u8 shift;
};

struct lm355x_chip_data {
	struct device *dev;
	enum lm355x_type type;

	struct led_classdev cdev_flash;
	struct led_classdev cdev_torch;
	struct led_classdev cdev_indicator;

	struct work_struct work_flash;
	struct work_struct work_torch;
	struct work_struct work_indicator;

	u8 br_flash;
	u8 br_torch;
	u8 br_indicator;

	struct lm355x_platform_data *pdata;
	struct regmap *regmap;
	struct mutex lock;

	unsigned int last_flag;
	struct lm355x_reg_data *regs;
};

/* specific indicator function for lm3556 */
enum lm3556_indic_pulse_time {
	PULSE_TIME_0_MS = 0,
	PULSE_TIME_32_MS,
	PULSE_TIME_64_MS,
	PULSE_TIME_92_MS,
	PULSE_TIME_128_MS,
	PULSE_TIME_160_MS,
	PULSE_TIME_196_MS,
	PULSE_TIME_224_MS,
	PULSE_TIME_256_MS,
	PULSE_TIME_288_MS,
	PULSE_TIME_320_MS,
	PULSE_TIME_352_MS,
	PULSE_TIME_384_MS,
	PULSE_TIME_416_MS,
	PULSE_TIME_448_MS,
	PULSE_TIME_480_MS,
};

enum lm3556_indic_n_blank {
	INDIC_N_BLANK_0 = 0,
	INDIC_N_BLANK_1,
	INDIC_N_BLANK_2,
	INDIC_N_BLANK_3,
	INDIC_N_BLANK_4,
	INDIC_N_BLANK_5,
	INDIC_N_BLANK_6,
	INDIC_N_BLANK_7,
	INDIC_N_BLANK_8,
	INDIC_N_BLANK_9,
	INDIC_N_BLANK_10,
	INDIC_N_BLANK_11,
	INDIC_N_BLANK_12,
	INDIC_N_BLANK_13,
	INDIC_N_BLANK_14,
	INDIC_N_BLANK_15,
};

enum lm3556_indic_period {
	INDIC_PERIOD_0 = 0,
	INDIC_PERIOD_1,
	INDIC_PERIOD_2,
	INDIC_PERIOD_3,
	INDIC_PERIOD_4,
	INDIC_PERIOD_5,
	INDIC_PERIOD_6,
	INDIC_PERIOD_7,
};

#define INDIC_PATTERN_SIZE 4

struct indicator {
	u8 blinking;
	u8 period_cnt;
};

/* indicator pattern data only for lm3556 */
static struct indicator indicator_pattern[INDIC_PATTERN_SIZE] = {
	[0] = {(INDIC_N_BLANK_1 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_1},
	[1] = {(INDIC_N_BLANK_15 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_2},
	[2] = {(INDIC_N_BLANK_10 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_4},
	[3] = {(INDIC_N_BLANK_5 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_7},
};

static struct lm355x_reg_data lm3554_regs[REG_MAX] = {
	[REG_FLAG] = {0xD0, 0xBF, 0},
	[REG_TORCH_CFG] = {0xE0, 0x80, 7},
	[REG_TORCH_CTRL] = {0xA0, 0x38, 3},
	[REG_STROBE_CFG] = {0xE0, 0x04, 2},
	[REG_FLASH_CTRL] = {0xB0, 0x78, 3},
	[REG_INDI_CFG] = {0xE0, 0x08, 3},
	[REG_INDI_CTRL] = {0xA0, 0xC0, 6},
	[REG_OPMODE] = {0xA0, 0x03, 0},
};

static struct lm355x_reg_data lm3556_regs[REG_MAX] = {
	[REG_FLAG] = {0x0B, 0xFF, 0},
	[REG_TORCH_CFG] = {0x0A, 0x10, 4},
	[REG_TORCH_CTRL] = {0x09, 0x70, 4},
	[REG_STROBE_CFG] = {0x0A, 0x20, 5},
	[REG_FLASH_CTRL] = {0x09, 0x0F, 0},
	[REG_INDI_CFG] = {0xFF, 0xFF, 0},
	[REG_INDI_CTRL] = {0x09, 0x70, 4},
	[REG_OPMODE] = {0x0A, 0x03, 0},
};

static char lm355x_name[][I2C_NAME_SIZE] = {
	[CHIP_LM3554] = LM3554_NAME,
	[CHIP_LM3556] = LM3556_NAME,
};

/* chip initialize */
static int lm355x_chip_init(struct lm355x_chip_data *chip)
{
	int ret;
	unsigned int reg_val;
	struct lm355x_platform_data *pdata = chip->pdata;

	/* input and output pins configuration */
	switch (chip->type) {
	case CHIP_LM3554:
		reg_val = pdata->pin_tx2 | pdata->ntc_pin;
		ret = regmap_update_bits(chip->regmap, 0xE0, 0x28, reg_val);
		if (ret < 0)
			goto out;
		reg_val = pdata->pass_mode;
		ret = regmap_update_bits(chip->regmap, 0xA0, 0x04, reg_val);
		if (ret < 0)
			goto out;
		break;

	case CHIP_LM3556:
		reg_val = pdata->pin_tx2 | pdata->ntc_pin | pdata->pass_mode;
		ret = regmap_update_bits(chip->regmap, 0x0A, 0xC4, reg_val);
		if (ret < 0)
			goto out;
		break;
	default:
		return -ENODATA;
	}

	return ret;
out:
	dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
	return ret;
}

/* chip control */
static void lm355x_control(struct lm355x_chip_data *chip,
			   u8 brightness, enum lm355x_mode opmode)
{
	int ret;
	unsigned int reg_val;
	struct lm355x_platform_data *pdata = chip->pdata;
	struct lm355x_reg_data *preg = chip->regs;

	ret = regmap_read(chip->regmap, preg[REG_FLAG].regno, &chip->last_flag);
	if (ret < 0)
		goto out;
	if (chip->last_flag & preg[REG_FLAG].mask)
		dev_info(chip->dev, "%s Last FLAG is 0x%x\n",
			 lm355x_name[chip->type],
			 chip->last_flag & preg[REG_FLAG].mask);
	/* brightness 0 means shutdown */
	if (!brightness)
		opmode = MODE_SHDN;

	switch (opmode) {
	case MODE_TORCH:
		ret =
		    regmap_update_bits(chip->regmap, preg[REG_TORCH_CTRL].regno,
				       preg[REG_TORCH_CTRL].mask,
				       (brightness - 1)
				       << preg[REG_TORCH_CTRL].shift);
		if (ret < 0)
			goto out;

		if (pdata->pin_tx1 != LM355x_PIN_TORCH_DISABLE) {
			ret =
			    regmap_update_bits(chip->regmap,
					       preg[REG_TORCH_CFG].regno,
					       preg[REG_TORCH_CFG].mask,
					       0x01 <<
					       preg[REG_TORCH_CFG].shift);
			if (ret < 0)
				goto out;
			opmode = MODE_SHDN;
			dev_info(chip->dev,
				 "torch brt is set - ext. torch pin mode\n");
		}
		break;

	case MODE_FLASH:

		ret =
		    regmap_update_bits(chip->regmap, preg[REG_FLASH_CTRL].regno,
				       preg[REG_FLASH_CTRL].mask,
				       (brightness - 1)
				       << preg[REG_FLASH_CTRL].shift);
		if (ret < 0)
			goto out;

		if (pdata->pin_strobe != LM355x_PIN_STROBE_DISABLE) {
			if (chip->type == CHIP_LM3554)
				reg_val = 0x00;
			else
				reg_val = 0x01;
			ret =
			    regmap_update_bits(chip->regmap,
					       preg[REG_STROBE_CFG].regno,
					       preg[REG_STROBE_CFG].mask,
					       reg_val <<
					       preg[REG_STROBE_CFG].shift);
			if (ret < 0)
				goto out;
			opmode = MODE_SHDN;
			dev_info(chip->dev,
				 "flash brt is set - ext. strobe pin mode\n");
		}
		break;

	case MODE_INDIC:
		ret =
		    regmap_update_bits(chip->regmap, preg[REG_INDI_CTRL].regno,
				       preg[REG_INDI_CTRL].mask,
				       (brightness - 1)
				       << preg[REG_INDI_CTRL].shift);
		if (ret < 0)
			goto out;

		if (pdata->pin_tx2 != LM355x_PIN_TX_DISABLE) {
			ret =
			    regmap_update_bits(chip->regmap,
					       preg[REG_INDI_CFG].regno,
					       preg[REG_INDI_CFG].mask,
					       0x01 <<
					       preg[REG_INDI_CFG].shift);
			if (ret < 0)
				goto out;
			opmode = MODE_SHDN;
		}
		break;
	case MODE_SHDN:
		break;
	default:
		return;
	}
	/* operation mode control */
	ret = regmap_update_bits(chip->regmap, preg[REG_OPMODE].regno,
				 preg[REG_OPMODE].mask,
				 opmode << preg[REG_OPMODE].shift);
	if (ret < 0)
		goto out;
	return;
out:
	dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
	return;
}

/* torch */
static void lm355x_deferred_torch_brightness_set(struct work_struct *work)
{
	struct lm355x_chip_data *chip =
	    container_of(work, struct lm355x_chip_data, work_torch);

	mutex_lock(&chip->lock);
	lm355x_control(chip, chip->br_torch, MODE_TORCH);
	mutex_unlock(&chip->lock);
}

static void lm355x_torch_brightness_set(struct led_classdev *cdev,
					enum led_brightness brightness)
{
	struct lm355x_chip_data *chip =
	    container_of(cdev, struct lm355x_chip_data, cdev_torch);

	chip->br_torch = brightness;
	schedule_work(&chip->work_torch);
}

/* flash */
static void lm355x_deferred_strobe_brightness_set(struct work_struct *work)
{
	struct lm355x_chip_data *chip =
	    container_of(work, struct lm355x_chip_data, work_flash);

	mutex_lock(&chip->lock);
	lm355x_control(chip, chip->br_flash, MODE_FLASH);
	mutex_unlock(&chip->lock);
}

static void lm355x_strobe_brightness_set(struct led_classdev *cdev,
					 enum led_brightness brightness)
{
	struct lm355x_chip_data *chip =
	    container_of(cdev, struct lm355x_chip_data, cdev_flash);

	chip->br_flash = brightness;
	schedule_work(&chip->work_flash);
}

/* indicator */
static void lm355x_deferred_indicator_brightness_set(struct work_struct *work)
{
	struct lm355x_chip_data *chip =
	    container_of(work, struct lm355x_chip_data, work_indicator);

	mutex_lock(&chip->lock);
	lm355x_control(chip, chip->br_indicator, MODE_INDIC);
	mutex_unlock(&chip->lock);
}

static void lm355x_indicator_brightness_set(struct led_classdev *cdev,
					    enum led_brightness brightness)
{
	struct lm355x_chip_data *chip =
	    container_of(cdev, struct lm355x_chip_data, cdev_indicator);

	chip->br_indicator = brightness;
	schedule_work(&chip->work_indicator);
}

/* indicator pattern only for lm3556*/
static ssize_t lm3556_indicator_pattern_store(struct device *dev,
					      struct device_attribute *attr,
					      const char *buf, size_t size)
{
	ssize_t ret;
	struct led_classdev *led_cdev = dev_get_drvdata(dev);
	struct lm355x_chip_data *chip =
	    container_of(led_cdev, struct lm355x_chip_data, cdev_indicator);
	unsigned int state;

	ret = kstrtouint(buf, 10, &state);
	if (ret)
		goto out;
	if (state > INDIC_PATTERN_SIZE - 1)
		state = INDIC_PATTERN_SIZE - 1;

	ret = regmap_write(chip->regmap, 0x04,
			   indicator_pattern[state].blinking);
	if (ret < 0)
		goto out;

	ret = regmap_write(chip->regmap, 0x05,
			   indicator_pattern[state].period_cnt);
	if (ret < 0)
		goto out;

	return size;
out:
	dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
	return ret;
}

static DEVICE_ATTR(pattern, S_IWUSR, NULL, lm3556_indicator_pattern_store);

static struct attribute *lm355x_indicator_attrs[] = {
	&dev_attr_pattern.attr,
	NULL
};
ATTRIBUTE_GROUPS(lm355x_indicator);

static const struct regmap_config lm355x_regmap = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = 0xFF,
};

/* module initialize */
static int lm355x_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	struct lm355x_platform_data *pdata = dev_get_platdata(&client->dev);
	struct lm355x_chip_data *chip;

	int err;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "i2c functionality check fail.\n");
		return -EOPNOTSUPP;
	}

	if (pdata == NULL) {
		dev_err(&client->dev, "needs Platform Data.\n");
		return -ENODATA;
	}

	chip = devm_kzalloc(&client->dev,
			    sizeof(struct lm355x_chip_data), GFP_KERNEL);
	if (!chip)
		return -ENOMEM;

	chip->dev = &client->dev;
	chip->type = id->driver_data;
	switch (id->driver_data) {
	case CHIP_LM3554:
		chip->regs = lm3554_regs;
		break;
	case CHIP_LM3556:
		chip->regs = lm3556_regs;
		break;
	default:
		return -ENOSYS;
	}
	chip->pdata = pdata;

	chip->regmap = devm_regmap_init_i2c(client, &lm355x_regmap);
	if (IS_ERR(chip->regmap)) {
		err = PTR_ERR(chip->regmap);
		dev_err(&client->dev,
			"Failed to allocate register map: %d\n", err);
		return err;
	}

	mutex_init(&chip->lock);
	i2c_set_clientdata(client, chip);

	err = lm355x_chip_init(chip);
	if (err < 0)
		goto err_out;

	/* flash */
	INIT_WORK(&chip->work_flash, lm355x_deferred_strobe_brightness_set);
	chip->cdev_flash.name = "flash";
	chip->cdev_flash.max_brightness = 16;
	chip->cdev_flash.brightness_set = lm355x_strobe_brightness_set;
	chip->cdev_flash.default_trigger = "flash";
	err = led_classdev_register((struct device *)
				    &client->dev, &chip->cdev_flash);
	if (err < 0)
		goto err_out;
	/* torch */
	INIT_WORK(&chip->work_torch, lm355x_deferred_torch_brightness_set);
	chip->cdev_torch.name = "torch";
	chip->cdev_torch.max_brightness = 8;
	chip->cdev_torch.brightness_set = lm355x_torch_brightness_set;
	chip->cdev_torch.default_trigger = "torch";
	err = led_classdev_register((struct device *)
				    &client->dev, &chip->cdev_torch);
	if (err < 0)
		goto err_create_torch_file;
	/* indicator */
	INIT_WORK(&chip->work_indicator,
		  lm355x_deferred_indicator_brightness_set);
	chip->cdev_indicator.name = "indicator";
	if (id->driver_data == CHIP_LM3554)
		chip->cdev_indicator.max_brightness = 4;
	else
		chip->cdev_indicator.max_brightness = 8;
	chip->cdev_indicator.brightness_set = lm355x_indicator_brightness_set;
	/* indicator pattern control only for LM3556 */
	if (id->driver_data == CHIP_LM3556)
		chip->cdev_indicator.groups = lm355x_indicator_groups;
	err = led_classdev_register((struct device *)
				    &client->dev, &chip->cdev_indicator);
	if (err < 0)
		goto err_create_indicator_file;

	dev_info(&client->dev, "%s is initialized\n",
		 lm355x_name[id->driver_data]);
	return 0;

err_create_indicator_file:
	led_classdev_unregister(&chip->cdev_torch);
err_create_torch_file:
	led_classdev_unregister(&chip->cdev_flash);
err_out:
	return err;
}

static int lm355x_remove(struct i2c_client *client)
{
	struct lm355x_chip_data *chip = i2c_get_clientdata(client);
	struct lm355x_reg_data *preg = chip->regs;

	regmap_write(chip->regmap, preg[REG_OPMODE].regno, 0);
	led_classdev_unregister(&chip->cdev_indicator);
	flush_work(&chip->work_indicator);
	led_classdev_unregister(&chip->cdev_torch);
	flush_work(&chip->work_torch);
	led_classdev_unregister(&chip->cdev_flash);
	flush_work(&chip->work_flash);
	dev_info(&client->dev, "%s is removed\n", lm355x_name[chip->type]);

	return 0;
}

static const struct i2c_device_id lm355x_id[] = {
	{LM3554_NAME, CHIP_LM3554},
	{LM3556_NAME, CHIP_LM3556},
	{}
};

MODULE_DEVICE_TABLE(i2c, lm355x_id);

static struct i2c_driver lm355x_i2c_driver = {
	.driver = {
		   .name = LM355x_NAME,
		   .pm = NULL,
		   },
	.probe = lm355x_probe,
	.remove = lm355x_remove,
	.id_table = lm355x_id,
};

module_i2c_driver(lm355x_i2c_driver);

MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM355x");
MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
MODULE_LICENSE("GPL v2");
