// 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/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");
