/*
 * I2C driver for Maxim MAX8925
 *
 * Copyright (C) 2009 Marvell International Ltd.
 *	Haojian Zhuang <haojian.zhuang@marvell.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/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/mfd/max8925.h>
#include <linux/slab.h>

#define RTC_I2C_ADDR		0x68
#define ADC_I2C_ADDR		0x47

static inline int max8925_read_device(struct i2c_client *i2c,
				      int reg, int bytes, void *dest)
{
	int ret;

	if (bytes > 1)
		ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest);
	else {
		ret = i2c_smbus_read_byte_data(i2c, reg);
		if (ret < 0)
			return ret;
		*(unsigned char *)dest = (unsigned char)ret;
	}
	return ret;
}

static inline int max8925_write_device(struct i2c_client *i2c,
				       int reg, int bytes, void *src)
{
	unsigned char buf[9];
	int ret;

	buf[0] = (unsigned char)reg;
	memcpy(&buf[1], src, bytes);

	ret = i2c_master_send(i2c, buf, bytes + 1);
	if (ret < 0)
		return ret;
	return 0;
}

int max8925_reg_read(struct i2c_client *i2c, int reg)
{
	struct max8925_chip *chip = i2c_get_clientdata(i2c);
	unsigned char data = 0;
	int ret;

	mutex_lock(&chip->io_lock);
	ret = max8925_read_device(i2c, reg, 1, &data);
	mutex_unlock(&chip->io_lock);

	if (ret < 0)
		return ret;
	else
		return (int)data;
}
EXPORT_SYMBOL(max8925_reg_read);

int max8925_reg_write(struct i2c_client *i2c, int reg,
		unsigned char data)
{
	struct max8925_chip *chip = i2c_get_clientdata(i2c);
	int ret;

	mutex_lock(&chip->io_lock);
	ret = max8925_write_device(i2c, reg, 1, &data);
	mutex_unlock(&chip->io_lock);

	return ret;
}
EXPORT_SYMBOL(max8925_reg_write);

int max8925_bulk_read(struct i2c_client *i2c, int reg,
		int count, unsigned char *buf)
{
	struct max8925_chip *chip = i2c_get_clientdata(i2c);
	int ret;

	mutex_lock(&chip->io_lock);
	ret = max8925_read_device(i2c, reg, count, buf);
	mutex_unlock(&chip->io_lock);

	return ret;
}
EXPORT_SYMBOL(max8925_bulk_read);

int max8925_bulk_write(struct i2c_client *i2c, int reg,
		int count, unsigned char *buf)
{
	struct max8925_chip *chip = i2c_get_clientdata(i2c);
	int ret;

	mutex_lock(&chip->io_lock);
	ret = max8925_write_device(i2c, reg, count, buf);
	mutex_unlock(&chip->io_lock);

	return ret;
}
EXPORT_SYMBOL(max8925_bulk_write);

int max8925_set_bits(struct i2c_client *i2c, int reg,
		unsigned char mask, unsigned char data)
{
	struct max8925_chip *chip = i2c_get_clientdata(i2c);
	unsigned char value;
	int ret;

	mutex_lock(&chip->io_lock);
	ret = max8925_read_device(i2c, reg, 1, &value);
	if (ret < 0)
		goto out;
	value &= ~mask;
	value |= data;
	ret = max8925_write_device(i2c, reg, 1, &value);
out:
	mutex_unlock(&chip->io_lock);
	return ret;
}
EXPORT_SYMBOL(max8925_set_bits);


static const struct i2c_device_id max8925_id_table[] = {
	{ "max8925", 0 },
	{ },
};
MODULE_DEVICE_TABLE(i2c, max8925_id_table);

static int max8925_dt_init(struct device_node *np, struct device *dev,
			   struct max8925_platform_data *pdata)
{
	int ret;

	ret = of_property_read_u32(np, "maxim,tsc-irq", &pdata->tsc_irq);
	if (ret) {
		dev_err(dev, "Not found maxim,tsc-irq property\n");
		return -EINVAL;
	}
	return 0;
}

static int max8925_probe(struct i2c_client *client,
				   const struct i2c_device_id *id)
{
	struct max8925_platform_data *pdata = dev_get_platdata(&client->dev);
	static struct max8925_chip *chip;
	struct device_node *node = client->dev.of_node;

	if (node && !pdata) {
		/* parse DT to get platform data */
		pdata = devm_kzalloc(&client->dev,
				     sizeof(struct max8925_platform_data),
				     GFP_KERNEL);
		if (!pdata)
			return -ENOMEM;

		if (max8925_dt_init(node, &client->dev, pdata))
			return -EINVAL;
	} else if (!pdata) {
		pr_info("%s: platform data is missing\n", __func__);
		return -EINVAL;
	}

	chip = devm_kzalloc(&client->dev,
			    sizeof(struct max8925_chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;
	chip->i2c = client;
	chip->dev = &client->dev;
	i2c_set_clientdata(client, chip);
	dev_set_drvdata(chip->dev, chip);
	mutex_init(&chip->io_lock);

	chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
	if (!chip->rtc) {
		dev_err(chip->dev, "Failed to allocate I2C device for RTC\n");
		return -ENODEV;
	}
	i2c_set_clientdata(chip->rtc, chip);

	chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
	if (!chip->adc) {
		dev_err(chip->dev, "Failed to allocate I2C device for ADC\n");
		i2c_unregister_device(chip->rtc);
		return -ENODEV;
	}
	i2c_set_clientdata(chip->adc, chip);

	device_init_wakeup(&client->dev, 1);

	max8925_device_init(chip, pdata);

	return 0;
}

static int max8925_remove(struct i2c_client *client)
{
	struct max8925_chip *chip = i2c_get_clientdata(client);

	max8925_device_exit(chip);
	i2c_unregister_device(chip->adc);
	i2c_unregister_device(chip->rtc);
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int max8925_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct max8925_chip *chip = i2c_get_clientdata(client);

	if (device_may_wakeup(dev) && chip->wakeup_flag)
		enable_irq_wake(chip->core_irq);
	return 0;
}

static int max8925_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct max8925_chip *chip = i2c_get_clientdata(client);

	if (device_may_wakeup(dev) && chip->wakeup_flag)
		disable_irq_wake(chip->core_irq);
	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(max8925_pm_ops, max8925_suspend, max8925_resume);

static const struct of_device_id max8925_dt_ids[] = {
	{ .compatible = "maxim,max8925", },
	{},
};
MODULE_DEVICE_TABLE(of, max8925_dt_ids);

static struct i2c_driver max8925_driver = {
	.driver	= {
		.name	= "max8925",
		.pm     = &max8925_pm_ops,
		.of_match_table = max8925_dt_ids,
	},
	.probe		= max8925_probe,
	.remove		= max8925_remove,
	.id_table	= max8925_id_table,
};

static int __init max8925_i2c_init(void)
{
	int ret;

	ret = i2c_add_driver(&max8925_driver);
	if (ret != 0)
		pr_err("Failed to register MAX8925 I2C driver: %d\n", ret);

	return ret;
}
subsys_initcall(max8925_i2c_init);

static void __exit max8925_i2c_exit(void)
{
	i2c_del_driver(&max8925_driver);
}
module_exit(max8925_i2c_exit);

MODULE_DESCRIPTION("I2C Driver for Maxim 8925");
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
MODULE_LICENSE("GPL");
