/*
 * Base driver for Dialog Semiconductor DA9030/DA9034
 *
 * Copyright (C) 2008 Compulab, Ltd.
 * 	Mike Rapoport <mike@compulab.co.il>
 *
 * Copyright (C) 2006-2008 Marvell International Ltd.
 * 	Eric Miao <eric.miao@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/interrupt.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/mfd/da903x.h>

#define DA9030_CHIP_ID		0x00
#define DA9030_EVENT_A		0x01
#define DA9030_EVENT_B		0x02
#define DA9030_EVENT_C		0x03
#define DA9030_STATUS		0x04
#define DA9030_IRQ_MASK_A	0x05
#define DA9030_IRQ_MASK_B	0x06
#define DA9030_IRQ_MASK_C	0x07
#define DA9030_SYS_CTRL_A	0x08
#define DA9030_SYS_CTRL_B	0x09
#define DA9030_FAULT_LOG	0x0a

#define DA9034_CHIP_ID		0x00
#define DA9034_EVENT_A		0x01
#define DA9034_EVENT_B		0x02
#define DA9034_EVENT_C		0x03
#define DA9034_EVENT_D		0x04
#define DA9034_STATUS_A		0x05
#define DA9034_STATUS_B		0x06
#define DA9034_IRQ_MASK_A	0x07
#define DA9034_IRQ_MASK_B	0x08
#define DA9034_IRQ_MASK_C	0x09
#define DA9034_IRQ_MASK_D	0x0a
#define DA9034_SYS_CTRL_A	0x0b
#define DA9034_SYS_CTRL_B	0x0c
#define DA9034_FAULT_LOG	0x0d

struct da903x_chip;

struct da903x_chip_ops {
	int	(*init_chip)(struct da903x_chip *);
	int	(*unmask_events)(struct da903x_chip *, unsigned int events);
	int	(*mask_events)(struct da903x_chip *, unsigned int events);
	int	(*read_events)(struct da903x_chip *, unsigned int *events);
	int	(*read_status)(struct da903x_chip *, unsigned int *status);
};

struct da903x_chip {
	struct i2c_client	*client;
	struct device		*dev;
	struct da903x_chip_ops	*ops;

	int			type;
	uint32_t		events_mask;

	struct mutex		lock;
	struct work_struct	irq_work;

	struct blocking_notifier_head notifier_list;
};

static inline int __da903x_read(struct i2c_client *client,
				int reg, uint8_t *val)
{
	int ret;

	ret = i2c_smbus_read_byte_data(client, reg);
	if (ret < 0) {
		dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
		return ret;
	}

	*val = (uint8_t)ret;
	return 0;
}

static inline int __da903x_reads(struct i2c_client *client, int reg,
				 int len, uint8_t *val)
{
	int ret;

	ret = i2c_smbus_read_i2c_block_data(client, reg, len, val);
	if (ret < 0) {
		dev_err(&client->dev, "failed reading from 0x%02x\n", reg);
		return ret;
	}
	return 0;
}

static inline int __da903x_write(struct i2c_client *client,
				 int reg, uint8_t val)
{
	int ret;

	ret = i2c_smbus_write_byte_data(client, reg, val);
	if (ret < 0) {
		dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n",
				val, reg);
		return ret;
	}
	return 0;
}

static inline int __da903x_writes(struct i2c_client *client, int reg,
				  int len, uint8_t *val)
{
	int ret;

	ret = i2c_smbus_write_i2c_block_data(client, reg, len, val);
	if (ret < 0) {
		dev_err(&client->dev, "failed writings to 0x%02x\n", reg);
		return ret;
	}
	return 0;
}

int da903x_register_notifier(struct device *dev, struct notifier_block *nb,
				unsigned int events)
{
	struct da903x_chip *chip = dev_get_drvdata(dev);

	chip->ops->unmask_events(chip, events);
	return blocking_notifier_chain_register(&chip->notifier_list, nb);
}
EXPORT_SYMBOL_GPL(da903x_register_notifier);

int da903x_unregister_notifier(struct device *dev, struct notifier_block *nb,
				unsigned int events)
{
	struct da903x_chip *chip = dev_get_drvdata(dev);

	chip->ops->mask_events(chip, events);
	return blocking_notifier_chain_unregister(&chip->notifier_list, nb);
}
EXPORT_SYMBOL_GPL(da903x_unregister_notifier);

int da903x_write(struct device *dev, int reg, uint8_t val)
{
	return __da903x_write(to_i2c_client(dev), reg, val);
}
EXPORT_SYMBOL_GPL(da903x_write);

int da903x_read(struct device *dev, int reg, uint8_t *val)
{
	return __da903x_read(to_i2c_client(dev), reg, val);
}
EXPORT_SYMBOL_GPL(da903x_read);

int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask)
{
	struct da903x_chip *chip = dev_get_drvdata(dev);
	uint8_t reg_val;
	int ret = 0;

	mutex_lock(&chip->lock);

	ret = __da903x_read(chip->client, reg, &reg_val);
	if (ret)
		goto out;

	if ((reg_val & bit_mask) == 0) {
		reg_val |= bit_mask;
		ret = __da903x_write(chip->client, reg, reg_val);
	}
out:
	mutex_unlock(&chip->lock);
	return ret;
}
EXPORT_SYMBOL_GPL(da903x_set_bits);

int da903x_clr_bits(struct device *dev, int reg, uint8_t bit_mask)
{
	struct da903x_chip *chip = dev_get_drvdata(dev);
	uint8_t reg_val;
	int ret = 0;

	mutex_lock(&chip->lock);

	ret = __da903x_read(chip->client, reg, &reg_val);
	if (ret)
		goto out;

	if (reg_val & bit_mask) {
		reg_val &= ~bit_mask;
		ret = __da903x_write(chip->client, reg, reg_val);
	}
out:
	mutex_unlock(&chip->lock);
	return ret;
}
EXPORT_SYMBOL_GPL(da903x_clr_bits);

int da903x_update(struct device *dev, int reg, uint8_t val, uint8_t mask)
{
	struct da903x_chip *chip = dev_get_drvdata(dev);
	uint8_t reg_val;
	int ret = 0;

	mutex_lock(&chip->lock);

	ret = __da903x_read(chip->client, reg, &reg_val);
	if (ret)
		goto out;

	if ((reg_val & mask) != val) {
		reg_val = (reg_val & ~mask) | val;
		ret = __da903x_write(chip->client, reg, reg_val);
	}
out:
	mutex_unlock(&chip->lock);
	return ret;
}
EXPORT_SYMBOL_GPL(da903x_update);

int da903x_query_status(struct device *dev, unsigned int sbits)
{
	struct da903x_chip *chip = dev_get_drvdata(dev);
	unsigned int status = 0;

	chip->ops->read_status(chip, &status);
	return ((status & sbits) == sbits);
}
EXPORT_SYMBOL(da903x_query_status);

static int __devinit da9030_init_chip(struct da903x_chip *chip)
{
	uint8_t chip_id;
	int err;

	err = __da903x_read(chip->client, DA9030_CHIP_ID, &chip_id);
	if (err)
		return err;

	err = __da903x_write(chip->client, DA9030_SYS_CTRL_A, 0xE8);
	if (err)
		return err;

	dev_info(chip->dev, "DA9030 (CHIP ID: 0x%02x) detected\n", chip_id);
	return 0;
}

static int da9030_unmask_events(struct da903x_chip *chip, unsigned int events)
{
	uint8_t v[3];

	chip->events_mask &= ~events;

	v[0] = (chip->events_mask & 0xff);
	v[1] = (chip->events_mask >> 8) & 0xff;
	v[2] = (chip->events_mask >> 16) & 0xff;

	return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v);
}

static int da9030_mask_events(struct da903x_chip *chip, unsigned int events)
{
	uint8_t v[3];

	chip->events_mask &= ~events;

	v[0] = (chip->events_mask & 0xff);
	v[1] = (chip->events_mask >> 8) & 0xff;
	v[2] = (chip->events_mask >> 16) & 0xff;

	return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v);
}

static int da9030_read_events(struct da903x_chip *chip, unsigned int *events)
{
	uint8_t v[3] = {0, 0, 0};
	int ret;

	ret = __da903x_reads(chip->client, DA9030_EVENT_A, 3, v);
	if (ret < 0)
		return ret;

	*events = (v[2] << 16) | (v[1] << 8) | v[0];
	return 0;
}

static int da9030_read_status(struct da903x_chip *chip, unsigned int *status)
{
	return __da903x_read(chip->client, DA9030_STATUS, (uint8_t *)status);
}

static int da9034_init_chip(struct da903x_chip *chip)
{
	uint8_t chip_id;
	int err;

	err = __da903x_read(chip->client, DA9034_CHIP_ID, &chip_id);
	if (err)
		return err;

	err = __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0xE8);
	if (err)
		return err;

	/* avoid SRAM power off during sleep*/
	__da903x_write(chip->client, 0x10, 0x07);
	__da903x_write(chip->client, 0x11, 0xff);
	__da903x_write(chip->client, 0x12, 0xff);

	/* Enable the ONKEY power down functionality */
	__da903x_write(chip->client, DA9034_SYS_CTRL_B, 0x20);
	__da903x_write(chip->client, DA9034_SYS_CTRL_A, 0x60);

	/* workaround to make LEDs work */
	__da903x_write(chip->client, 0x90, 0x01);
	__da903x_write(chip->client, 0xB0, 0x08);

	/* make ADTV1 and SDTV1 effective */
	__da903x_write(chip->client, 0x20, 0x00);

	dev_info(chip->dev, "DA9034 (CHIP ID: 0x%02x) detected\n", chip_id);
	return 0;
}

static int da9034_unmask_events(struct da903x_chip *chip, unsigned int events)
{
	uint8_t v[4];

	chip->events_mask &= ~events;

	v[0] = (chip->events_mask & 0xff);
	v[1] = (chip->events_mask >> 8) & 0xff;
	v[2] = (chip->events_mask >> 16) & 0xff;
	v[3] = (chip->events_mask >> 24) & 0xff;

	return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v);
}

static int da9034_mask_events(struct da903x_chip *chip, unsigned int events)
{
	uint8_t v[4];

	chip->events_mask |= events;

	v[0] = (chip->events_mask & 0xff);
	v[1] = (chip->events_mask >> 8) & 0xff;
	v[2] = (chip->events_mask >> 16) & 0xff;
	v[3] = (chip->events_mask >> 24) & 0xff;

	return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v);
}

static int da9034_read_events(struct da903x_chip *chip, unsigned int *events)
{
	uint8_t v[4] = {0, 0, 0, 0};
	int ret;

	ret = __da903x_reads(chip->client, DA9034_EVENT_A, 4, v);
	if (ret < 0)
		return ret;

	*events = (v[3] << 24) | (v[2] << 16) | (v[1] << 8) | v[0];
	return 0;
}

static int da9034_read_status(struct da903x_chip *chip, unsigned int *status)
{
	uint8_t v[2] = {0, 0};
	int ret = 0;

	ret = __da903x_reads(chip->client, DA9034_STATUS_A, 2, v);
	if (ret)
		return ret;

	*status = (v[1] << 8) | v[0];
	return 0;
}

static void da903x_irq_work(struct work_struct *work)
{
	struct da903x_chip *chip =
		container_of(work, struct da903x_chip, irq_work);
	unsigned int events = 0;

	while (1) {
		if (chip->ops->read_events(chip, &events))
			break;

		events &= ~chip->events_mask;
		if (events == 0)
			break;

		blocking_notifier_call_chain(
				&chip->notifier_list, events, NULL);
	}
	enable_irq(chip->client->irq);
}

static int da903x_irq_handler(int irq, void *data)
{
	struct da903x_chip *chip = data;

	disable_irq_nosync(irq);
	(void)schedule_work(&chip->irq_work);

	return IRQ_HANDLED;
}

static struct da903x_chip_ops da903x_ops[] = {
	[0] = {
		.init_chip	= da9030_init_chip,
		.unmask_events	= da9030_unmask_events,
		.mask_events	= da9030_mask_events,
		.read_events	= da9030_read_events,
		.read_status	= da9030_read_status,
	},
	[1] = {
		.init_chip	= da9034_init_chip,
		.unmask_events	= da9034_unmask_events,
		.mask_events	= da9034_mask_events,
		.read_events	= da9034_read_events,
		.read_status	= da9034_read_status,
	}
};

static const struct i2c_device_id da903x_id_table[] = {
	{ "da9030", 0 },
	{ "da9034", 1 },
	{ },
};
MODULE_DEVICE_TABLE(i2c, da903x_id_table);

static int __devexit __remove_subdev(struct device *dev, void *unused)
{
	platform_device_unregister(to_platform_device(dev));
	return 0;
}

static int __devexit da903x_remove_subdevs(struct da903x_chip *chip)
{
	return device_for_each_child(chip->dev, NULL, __remove_subdev);
}

static int __devinit da903x_add_subdevs(struct da903x_chip *chip,
					struct da903x_platform_data *pdata)
{
	struct da903x_subdev_info *subdev;
	struct platform_device *pdev;
	int i, ret = 0;

	for (i = 0; i < pdata->num_subdevs; i++) {
		subdev = &pdata->subdevs[i];

		pdev = platform_device_alloc(subdev->name, subdev->id);

		pdev->dev.parent = chip->dev;
		pdev->dev.platform_data = subdev->platform_data;

		ret = platform_device_add(pdev);
		if (ret)
			goto failed;
	}
	return 0;

failed:
	da903x_remove_subdevs(chip);
	return ret;
}

static int __devinit da903x_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	struct da903x_platform_data *pdata = client->dev.platform_data;
	struct da903x_chip *chip;
	unsigned int tmp;
	int ret;

	chip = kzalloc(sizeof(struct da903x_chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;

	chip->client = client;
	chip->dev = &client->dev;
	chip->ops = &da903x_ops[id->driver_data];

	mutex_init(&chip->lock);
	INIT_WORK(&chip->irq_work, da903x_irq_work);
	BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list);

	i2c_set_clientdata(client, chip);

	ret = chip->ops->init_chip(chip);
	if (ret)
		goto out_free_chip;

	/* mask and clear all IRQs */
	chip->events_mask = 0xffffffff;
	chip->ops->mask_events(chip, chip->events_mask);
	chip->ops->read_events(chip, &tmp);

	ret = request_irq(client->irq, da903x_irq_handler,
			IRQF_DISABLED | IRQF_TRIGGER_FALLING,
			"da903x", chip);
	if (ret) {
		dev_err(&client->dev, "failed to request irq %d\n",
				client->irq);
		goto out_free_chip;
	}

	ret = da903x_add_subdevs(chip, pdata);
	if (ret)
		goto out_free_irq;

	return 0;

out_free_irq:
	free_irq(client->irq, chip);
out_free_chip:
	i2c_set_clientdata(client, NULL);
	kfree(chip);
	return ret;
}

static int __devexit da903x_remove(struct i2c_client *client)
{
	struct da903x_chip *chip = i2c_get_clientdata(client);

	da903x_remove_subdevs(chip);
	kfree(chip);
	return 0;
}

static struct i2c_driver da903x_driver = {
	.driver	= {
		.name	= "da903x",
		.owner	= THIS_MODULE,
	},
	.probe		= da903x_probe,
	.remove		= __devexit_p(da903x_remove),
	.id_table	= da903x_id_table,
};

static int __init da903x_init(void)
{
	return i2c_add_driver(&da903x_driver);
}
module_init(da903x_init);

static void __exit da903x_exit(void)
{
	i2c_del_driver(&da903x_driver);
}
module_exit(da903x_exit);

MODULE_DESCRIPTION("PMIC Driver for Dialog Semiconductor DA9034");
MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
	      "Mike Rapoport <mike@compulab.co.il>");
MODULE_LICENSE("GPL");
