/*
 * Driver for TPS65218 Integrated power management chipsets
 *
 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.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.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether expressed or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License version 2 for more details.
 */

#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/regmap.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>

#include <linux/mfd/core.h>
#include <linux/mfd/tps65218.h>

#define TPS65218_PASSWORD_REGS_UNLOCK   0x7D

/**
 * tps65218_reg_read: Read a single tps65218 register.
 *
 * @tps: Device to read from.
 * @reg: Register to read.
 * @val: Contians the value
 */
int tps65218_reg_read(struct tps65218 *tps, unsigned int reg,
			unsigned int *val)
{
	return regmap_read(tps->regmap, reg, val);
}
EXPORT_SYMBOL_GPL(tps65218_reg_read);

/**
 * tps65218_reg_write: Write a single tps65218 register.
 *
 * @tps65218: Device to write to.
 * @reg: Register to write to.
 * @val: Value to write.
 * @level: Password protected level
 */
int tps65218_reg_write(struct tps65218 *tps, unsigned int reg,
			unsigned int val, unsigned int level)
{
	int ret;
	unsigned int xor_reg_val;

	switch (level) {
	case TPS65218_PROTECT_NONE:
		return regmap_write(tps->regmap, reg, val);
	case TPS65218_PROTECT_L1:
		xor_reg_val = reg ^ TPS65218_PASSWORD_REGS_UNLOCK;
		ret = regmap_write(tps->regmap, TPS65218_REG_PASSWORD,
							xor_reg_val);
		if (ret < 0)
			return ret;

		return regmap_write(tps->regmap, reg, val);
	default:
		return -EINVAL;
	}
}
EXPORT_SYMBOL_GPL(tps65218_reg_write);

/**
 * tps65218_update_bits: Modify bits w.r.t mask, val and level.
 *
 * @tps65218: Device to write to.
 * @reg: Register to read-write to.
 * @mask: Mask.
 * @val: Value to write.
 * @level: Password protected level
 */
static int tps65218_update_bits(struct tps65218 *tps, unsigned int reg,
		unsigned int mask, unsigned int val, unsigned int level)
{
	int ret;
	unsigned int data;

	ret = tps65218_reg_read(tps, reg, &data);
	if (ret) {
		dev_err(tps->dev, "Read from reg 0x%x failed\n", reg);
		return ret;
	}

	data &= ~mask;
	data |= val & mask;

	mutex_lock(&tps->tps_lock);
	ret = tps65218_reg_write(tps, reg, data, level);
	if (ret)
		dev_err(tps->dev, "Write for reg 0x%x failed\n", reg);
	mutex_unlock(&tps->tps_lock);

	return ret;
}

int tps65218_set_bits(struct tps65218 *tps, unsigned int reg,
		unsigned int mask, unsigned int val, unsigned int level)
{
	return tps65218_update_bits(tps, reg, mask, val, level);
}
EXPORT_SYMBOL_GPL(tps65218_set_bits);

int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg,
		unsigned int mask, unsigned int level)
{
	return tps65218_update_bits(tps, reg, mask, 0, level);
}
EXPORT_SYMBOL_GPL(tps65218_clear_bits);

static struct regmap_config tps65218_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.cache_type = REGCACHE_RBTREE,
};

static const struct regmap_irq tps65218_irqs[] = {
	/* INT1 IRQs */
	[TPS65218_PRGC_IRQ] = {
		.mask = TPS65218_INT1_PRGC,
	},
	[TPS65218_CC_AQC_IRQ] = {
		.mask = TPS65218_INT1_CC_AQC,
	},
	[TPS65218_HOT_IRQ] = {
		.mask = TPS65218_INT1_HOT,
	},
	[TPS65218_PB_IRQ] = {
		.mask = TPS65218_INT1_PB,
	},
	[TPS65218_AC_IRQ] = {
		.mask = TPS65218_INT1_AC,
	},
	[TPS65218_VPRG_IRQ] = {
		.mask = TPS65218_INT1_VPRG,
	},
	[TPS65218_INVALID1_IRQ] = {
	},
	[TPS65218_INVALID2_IRQ] = {
	},
	/* INT2 IRQs*/
	[TPS65218_LS1_I_IRQ] = {
		.mask = TPS65218_INT2_LS1_I,
		.reg_offset = 1,
	},
	[TPS65218_LS2_I_IRQ] = {
		.mask = TPS65218_INT2_LS2_I,
		.reg_offset = 1,
	},
	[TPS65218_LS3_I_IRQ] = {
		.mask = TPS65218_INT2_LS3_I,
		.reg_offset = 1,
	},
	[TPS65218_LS1_F_IRQ] = {
		.mask = TPS65218_INT2_LS1_F,
		.reg_offset = 1,
	},
	[TPS65218_LS2_F_IRQ] = {
		.mask = TPS65218_INT2_LS2_F,
		.reg_offset = 1,
	},
	[TPS65218_LS3_F_IRQ] = {
		.mask = TPS65218_INT2_LS3_F,
		.reg_offset = 1,
	},
	[TPS65218_INVALID3_IRQ] = {
	},
	[TPS65218_INVALID4_IRQ] = {
	},
};

static struct regmap_irq_chip tps65218_irq_chip = {
	.name = "tps65218",
	.irqs = tps65218_irqs,
	.num_irqs = ARRAY_SIZE(tps65218_irqs),

	.num_regs = 2,
	.mask_base = TPS65218_REG_INT_MASK1,
};

static const struct of_device_id of_tps65218_match_table[] = {
	{ .compatible = "ti,tps65218", },
};

static int tps65218_probe(struct i2c_client *client,
				const struct i2c_device_id *ids)
{
	struct tps65218 *tps;
	const struct of_device_id *match;
	int ret;

	match = of_match_device(of_tps65218_match_table, &client->dev);
	if (!match) {
		dev_err(&client->dev,
			"Failed to find matching dt id\n");
		return -EINVAL;
	}

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

	i2c_set_clientdata(client, tps);
	tps->dev = &client->dev;
	tps->irq = client->irq;
	tps->regmap = devm_regmap_init_i2c(client, &tps65218_regmap_config);
	if (IS_ERR(tps->regmap)) {
		ret = PTR_ERR(tps->regmap);
		dev_err(tps->dev, "Failed to allocate register map: %d\n",
			ret);
		return ret;
	}

	mutex_init(&tps->tps_lock);

	ret = regmap_add_irq_chip(tps->regmap, tps->irq,
			IRQF_ONESHOT, 0, &tps65218_irq_chip,
			&tps->irq_data);
	if (ret < 0)
		return ret;

	ret = of_platform_populate(client->dev.of_node, NULL, NULL,
				   &client->dev);
	if (ret < 0)
		goto err_irq;

	return 0;

err_irq:
	regmap_del_irq_chip(tps->irq, tps->irq_data);

	return ret;
}

static int tps65218_remove(struct i2c_client *client)
{
	struct tps65218 *tps = i2c_get_clientdata(client);

	regmap_del_irq_chip(tps->irq, tps->irq_data);

	return 0;
}

static const struct i2c_device_id tps65218_id_table[] = {
	{ "tps65218", TPS65218 },
	{ },
};
MODULE_DEVICE_TABLE(i2c, tps65218_id_table);

static struct i2c_driver tps65218_driver = {
	.driver		= {
		.name	= "tps65218",
		.owner	= THIS_MODULE,
		.of_match_table = of_tps65218_match_table,
	},
	.probe		= tps65218_probe,
	.remove		= tps65218_remove,
	.id_table       = tps65218_id_table,
};

module_i2c_driver(tps65218_driver);

MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>");
MODULE_DESCRIPTION("TPS65218 chip family multi-function driver");
MODULE_LICENSE("GPL v2");
