// SPDX-License-Identifier: GPL-2.0-only
/*
 * MFD core driver for the Richtek RT5033.
 *
 * RT5033 comprises multiple sub-devices switcing charger, fuel gauge,
 * flash LED, current source, LDO and BUCK regulators.
 *
 * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
 * Author: Beomho Seo <beomho.seo@samsung.com>
 */

#include <linux/err.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/mfd/rt5033.h>
#include <linux/mfd/rt5033-private.h>

static const struct regmap_irq rt5033_irqs[] = {
	{ .mask = RT5033_PMIC_IRQ_BUCKOCP, },
	{ .mask = RT5033_PMIC_IRQ_BUCKLV, },
	{ .mask = RT5033_PMIC_IRQ_SAFELDOLV, },
	{ .mask = RT5033_PMIC_IRQ_LDOLV, },
	{ .mask = RT5033_PMIC_IRQ_OT, },
	{ .mask = RT5033_PMIC_IRQ_VDDA_UV, },
};

static const struct regmap_irq_chip rt5033_irq_chip = {
	.name		= "rt5033",
	.status_base	= RT5033_REG_PMIC_IRQ_STAT,
	.unmask_base	= RT5033_REG_PMIC_IRQ_CTRL,
	.num_regs	= 1,
	.irqs		= rt5033_irqs,
	.num_irqs	= ARRAY_SIZE(rt5033_irqs),
};

static const struct mfd_cell rt5033_devs[] = {
	{ .name = "rt5033-regulator", },
	{
		.name = "rt5033-charger",
		.of_compatible = "richtek,rt5033-charger",
	}, {
		.name = "rt5033-led",
		.of_compatible = "richtek,rt5033-led",
	},
};

static const struct regmap_config rt5033_regmap_config = {
	.reg_bits	= 8,
	.val_bits	= 8,
	.max_register	= RT5033_REG_END,
};

static int rt5033_i2c_probe(struct i2c_client *i2c)
{
	struct rt5033_dev *rt5033;
	unsigned int dev_id, chip_rev;
	int ret;

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

	i2c_set_clientdata(i2c, rt5033);
	rt5033->dev = &i2c->dev;
	rt5033->irq = i2c->irq;
	rt5033->wakeup = true;

	rt5033->regmap = devm_regmap_init_i2c(i2c, &rt5033_regmap_config);
	if (IS_ERR(rt5033->regmap)) {
		dev_err(&i2c->dev, "Failed to allocate register map.\n");
		return PTR_ERR(rt5033->regmap);
	}

	ret = regmap_read(rt5033->regmap, RT5033_REG_DEVICE_ID, &dev_id);
	if (ret) {
		dev_err(&i2c->dev, "Device not found\n");
		return -ENODEV;
	}
	chip_rev = dev_id & RT5033_CHIP_REV_MASK;
	dev_info(&i2c->dev, "Device found (rev. %d)\n", chip_rev);

	ret = devm_regmap_add_irq_chip(rt5033->dev, rt5033->regmap,
			rt5033->irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
			0, &rt5033_irq_chip, &rt5033->irq_data);
	if (ret) {
		dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
							rt5033->irq, ret);
		return ret;
	}

	ret = devm_mfd_add_devices(rt5033->dev, -1, rt5033_devs,
				   ARRAY_SIZE(rt5033_devs), NULL, 0,
				   regmap_irq_get_domain(rt5033->irq_data));
	if (ret < 0) {
		dev_err(&i2c->dev, "Failed to add RT5033 child devices.\n");
		return ret;
	}

	if (rt5033->wakeup) {
		ret = devm_device_init_wakeup(rt5033->dev);
		if (ret)
			return dev_err_probe(rt5033->dev, ret, "Failed to init wakeup\n");
	}

	return 0;
}

static const struct i2c_device_id rt5033_i2c_id[] = {
	{ "rt5033", },
	{ }
};
MODULE_DEVICE_TABLE(i2c, rt5033_i2c_id);

static const struct of_device_id rt5033_dt_match[] = {
	{ .compatible = "richtek,rt5033", },
	{ }
};
MODULE_DEVICE_TABLE(of, rt5033_dt_match);

static struct i2c_driver rt5033_driver = {
	.driver = {
		.name = "rt5033",
		.of_match_table = rt5033_dt_match,
	},
	.probe = rt5033_i2c_probe,
	.id_table = rt5033_i2c_id,
};
module_i2c_driver(rt5033_driver);

MODULE_DESCRIPTION("Richtek RT5033 multi-function core driver");
MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
MODULE_LICENSE("GPL");
