/*
 * tps65912-core.c  --  TI TPS65912x
 *
 * Copyright 2011 Texas Instruments Inc.
 *
 * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk>
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under  the terms of the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the License, or (at your
 *  option) any later version.
 *
 *  This driver is based on wm8350 implementation.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tps65912.h>

static const struct mfd_cell tps65912s[] = {
	{
		.name = "tps65912-pmic",
	},
};

int tps65912_set_bits(struct tps65912 *tps65912, u8 reg, u8 mask)
{
	u8 data;
	int err;

	mutex_lock(&tps65912->io_mutex);

	err = tps65912->read(tps65912, reg, 1, &data);
	if (err) {
		dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);
		goto out;
	}

	data |= mask;
	err = tps65912->write(tps65912, reg, 1, &data);
	if (err)
		dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg);

out:
	mutex_unlock(&tps65912->io_mutex);
	return err;
}
EXPORT_SYMBOL_GPL(tps65912_set_bits);

int tps65912_clear_bits(struct tps65912 *tps65912, u8 reg, u8 mask)
{
	u8 data;
	int err;

	mutex_lock(&tps65912->io_mutex);
	err = tps65912->read(tps65912, reg, 1, &data);
	if (err) {
		dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);
		goto out;
	}

	data &= ~mask;
	err = tps65912->write(tps65912, reg, 1, &data);
	if (err)
		dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg);

out:
	mutex_unlock(&tps65912->io_mutex);
	return err;
}
EXPORT_SYMBOL_GPL(tps65912_clear_bits);

static inline int tps65912_read(struct tps65912 *tps65912, u8 reg)
{
	u8 val;
	int err;

	err = tps65912->read(tps65912, reg, 1, &val);
	if (err < 0)
		return err;

	return val;
}

static inline int tps65912_write(struct tps65912 *tps65912, u8 reg, u8 val)
{
	return tps65912->write(tps65912, reg, 1, &val);
}

int tps65912_reg_read(struct tps65912 *tps65912, u8 reg)
{
	int data;

	mutex_lock(&tps65912->io_mutex);

	data = tps65912_read(tps65912, reg);
	if (data < 0)
		dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);

	mutex_unlock(&tps65912->io_mutex);
	return data;
}
EXPORT_SYMBOL_GPL(tps65912_reg_read);

int tps65912_reg_write(struct tps65912 *tps65912, u8 reg, u8 val)
{
	int err;

	mutex_lock(&tps65912->io_mutex);

	err = tps65912_write(tps65912, reg, val);
	if (err < 0)
		dev_err(tps65912->dev, "Write for reg 0x%x failed\n", reg);

	mutex_unlock(&tps65912->io_mutex);
	return err;
}
EXPORT_SYMBOL_GPL(tps65912_reg_write);

int tps65912_device_init(struct tps65912 *tps65912)
{
	struct tps65912_board *pmic_plat_data = dev_get_platdata(tps65912->dev);
	struct tps65912_platform_data *init_data;
	int ret, dcdc_avs, value;

	init_data = kzalloc(sizeof(struct tps65912_platform_data), GFP_KERNEL);
	if (init_data == NULL)
		return -ENOMEM;

	mutex_init(&tps65912->io_mutex);
	dev_set_drvdata(tps65912->dev, tps65912);

	dcdc_avs = (pmic_plat_data->is_dcdc1_avs << 0 |
			pmic_plat_data->is_dcdc2_avs  << 1 |
				pmic_plat_data->is_dcdc3_avs << 2 |
					pmic_plat_data->is_dcdc4_avs << 3);
	if (dcdc_avs) {
		tps65912->read(tps65912, TPS65912_I2C_SPI_CFG, 1, &value);
		dcdc_avs |= value;
		tps65912->write(tps65912, TPS65912_I2C_SPI_CFG, 1, &dcdc_avs);
	}

	ret = mfd_add_devices(tps65912->dev, -1,
			      tps65912s, ARRAY_SIZE(tps65912s),
			      NULL, 0, NULL);
	if (ret < 0)
		goto err;

	init_data->irq = pmic_plat_data->irq;
	init_data->irq_base = pmic_plat_data->irq_base;
	ret = tps65912_irq_init(tps65912, init_data->irq, init_data);
	if (ret < 0)
		goto err;

	kfree(init_data);
	return ret;

err:
	kfree(init_data);
	mfd_remove_devices(tps65912->dev);
	return ret;
}

void tps65912_device_exit(struct tps65912 *tps65912)
{
	mfd_remove_devices(tps65912->dev);
	tps65912_irq_exit(tps65912);
}

MODULE_AUTHOR("Margarita Olaya	<magi@slimlogic.co.uk>");
MODULE_DESCRIPTION("TPS65912x chip family multi-function driver");
MODULE_LICENSE("GPL");
