/*
 * Core driver for TPS61050/61052 boost converters, used for while LED
 * driving, audio power amplification, white LED flash, and generic
 * boost conversion. Additionally it provides a 1-bit GPIO pin (out or in)
 * and a flash synchronization pin to synchronize flash events when used as
 * flashgun.
 *
 * Copyright (C) 2011 ST-Ericsson SA
 * Written on behalf of Linaro for ST-Ericsson
 *
 * Author: Linus Walleij <linus.walleij@linaro.org>
 *
 * License terms: GNU General Public License (GPL) version 2
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <linux/gpio.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/regulator/driver.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tps6105x.h>

int tps6105x_set(struct tps6105x *tps6105x, u8 reg, u8 value)
{
	int ret;

	ret = mutex_lock_interruptible(&tps6105x->lock);
	if (ret)
		return ret;
	ret = i2c_smbus_write_byte_data(tps6105x->client, reg, value);
	mutex_unlock(&tps6105x->lock);
	if (ret < 0)
		return ret;

	return 0;
}
EXPORT_SYMBOL(tps6105x_set);

int tps6105x_get(struct tps6105x *tps6105x, u8 reg, u8 *buf)
{
	int ret;

	ret = mutex_lock_interruptible(&tps6105x->lock);
	if (ret)
		return ret;
	ret = i2c_smbus_read_byte_data(tps6105x->client, reg);
	mutex_unlock(&tps6105x->lock);
	if (ret < 0)
		return ret;

	*buf = ret;
	return 0;
}
EXPORT_SYMBOL(tps6105x_get);

/*
 * Masks off the bits in the mask and sets the bits in the bitvalues
 * parameter in one atomic operation
 */
int tps6105x_mask_and_set(struct tps6105x *tps6105x, u8 reg,
			  u8 bitmask, u8 bitvalues)
{
	int ret;
	u8 regval;

	ret = mutex_lock_interruptible(&tps6105x->lock);
	if (ret)
		return ret;
	ret = i2c_smbus_read_byte_data(tps6105x->client, reg);
	if (ret < 0)
		goto fail;
	regval = ret;
	regval = (~bitmask & regval) | (bitmask & bitvalues);
	ret = i2c_smbus_write_byte_data(tps6105x->client, reg, regval);
fail:
	mutex_unlock(&tps6105x->lock);
	if (ret < 0)
		return ret;

	return 0;
}
EXPORT_SYMBOL(tps6105x_mask_and_set);

static int __devinit tps6105x_startup(struct tps6105x *tps6105x)
{
	int ret;
	u8 regval;

	ret = tps6105x_get(tps6105x, TPS6105X_REG_0, &regval);
	if (ret)
		return ret;
	switch (regval >> TPS6105X_REG0_MODE_SHIFT) {
	case TPS6105X_REG0_MODE_SHUTDOWN:
		dev_info(&tps6105x->client->dev,
			 "TPS6105x found in SHUTDOWN mode\n");
		break;
	case TPS6105X_REG0_MODE_TORCH:
		dev_info(&tps6105x->client->dev,
			 "TPS6105x found in TORCH mode\n");
		break;
	case TPS6105X_REG0_MODE_TORCH_FLASH:
		dev_info(&tps6105x->client->dev,
			 "TPS6105x found in FLASH mode\n");
		break;
	case TPS6105X_REG0_MODE_VOLTAGE:
		dev_info(&tps6105x->client->dev,
			 "TPS6105x found in VOLTAGE mode\n");
		break;
	default:
		break;
	}

	return ret;
}

/*
 * MFD cells - we have one cell which is selected operation
 * mode, and we always have a GPIO cell.
 */
static struct mfd_cell tps6105x_cells[] = {
	{
		/* name will be runtime assigned */
		.id = -1,
	},
	{
		.name = "tps6105x-gpio",
		.id = -1,
	},
};

static int __devinit tps6105x_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct tps6105x			*tps6105x;
	struct tps6105x_platform_data	*pdata;
	int ret;
	int i;

	tps6105x = kmalloc(sizeof(*tps6105x), GFP_KERNEL);
	if (!tps6105x)
		return -ENOMEM;

	i2c_set_clientdata(client, tps6105x);
	tps6105x->client = client;
	pdata = client->dev.platform_data;
	tps6105x->pdata = pdata;
	mutex_init(&tps6105x->lock);

	ret = tps6105x_startup(tps6105x);
	if (ret) {
		dev_err(&client->dev, "chip initialization failed\n");
		goto fail;
	}

	/* Remove warning texts when you implement new cell drivers */
	switch (pdata->mode) {
	case TPS6105X_MODE_SHUTDOWN:
		dev_info(&client->dev,
			 "present, not used for anything, only GPIO\n");
		break;
	case TPS6105X_MODE_TORCH:
		tps6105x_cells[0].name = "tps6105x-leds";
		dev_warn(&client->dev,
			 "torch mode is unsupported\n");
		break;
	case TPS6105X_MODE_TORCH_FLASH:
		tps6105x_cells[0].name = "tps6105x-flash";
		dev_warn(&client->dev,
			 "flash mode is unsupported\n");
		break;
	case TPS6105X_MODE_VOLTAGE:
		tps6105x_cells[0].name ="tps6105x-regulator";
		break;
	default:
		break;
	}

	/* Set up and register the platform devices. */
	for (i = 0; i < ARRAY_SIZE(tps6105x_cells); i++) {
		/* One state holder for all drivers, this is simple */
		tps6105x_cells[i].platform_data = tps6105x;
		tps6105x_cells[i].pdata_size = sizeof(*tps6105x);
	}

	ret = mfd_add_devices(&client->dev, 0, tps6105x_cells,
		ARRAY_SIZE(tps6105x_cells), NULL, 0);
	if (ret)
		goto fail;

	return 0;

fail:
	kfree(tps6105x);
	return ret;
}

static int __devexit tps6105x_remove(struct i2c_client *client)
{
	struct tps6105x *tps6105x = i2c_get_clientdata(client);

	mfd_remove_devices(&client->dev);

	/* Put chip in shutdown mode */
	tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
		TPS6105X_REG0_MODE_MASK,
		TPS6105X_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT);

	kfree(tps6105x);
	return 0;
}

static const struct i2c_device_id tps6105x_id[] = {
	{ "tps61050", 0 },
	{ "tps61052", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, tps6105x_id);

static struct i2c_driver tps6105x_driver = {
	.driver = {
		.name	= "tps6105x",
	},
	.probe		= tps6105x_probe,
	.remove		= __devexit_p(tps6105x_remove),
	.id_table	= tps6105x_id,
};

static int __init tps6105x_init(void)
{
	return i2c_add_driver(&tps6105x_driver);
}
subsys_initcall(tps6105x_init);

static void __exit tps6105x_exit(void)
{
	i2c_del_driver(&tps6105x_driver);
}
module_exit(tps6105x_exit);

MODULE_AUTHOR("Linus Walleij");
MODULE_DESCRIPTION("TPS6105x White LED Boost Converter Driver");
MODULE_LICENSE("GPL v2");
