// SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2020, The Linux Foundation. All rights reserved.

#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

#define REG_PERPH_TYPE                  0x04

#define QCOM_LAB_TYPE			0x24
#define QCOM_IBB_TYPE			0x20

#define PMI8998_LAB_REG_BASE		0xde00
#define PMI8998_IBB_REG_BASE		0xdc00
#define PMI8998_IBB_LAB_REG_OFFSET	0x200

#define REG_LABIBB_STATUS1		0x08
 #define LABIBB_STATUS1_SC_BIT		BIT(6)
 #define LABIBB_STATUS1_VREG_OK_BIT	BIT(7)

#define REG_LABIBB_INT_SET_TYPE		0x11
#define REG_LABIBB_INT_POLARITY_HIGH	0x12
#define REG_LABIBB_INT_POLARITY_LOW	0x13
#define REG_LABIBB_INT_LATCHED_CLR	0x14
#define REG_LABIBB_INT_EN_SET		0x15
#define REG_LABIBB_INT_EN_CLR		0x16
 #define LABIBB_INT_VREG_OK		BIT(0)
 #define LABIBB_INT_VREG_TYPE_LEVEL	0

#define REG_LABIBB_VOLTAGE		0x41
 #define LABIBB_VOLTAGE_OVERRIDE_EN	BIT(7)
 #define LAB_VOLTAGE_SET_MASK		GENMASK(3, 0)
 #define IBB_VOLTAGE_SET_MASK		GENMASK(5, 0)

#define REG_LABIBB_ENABLE_CTL		0x46
 #define LABIBB_CONTROL_ENABLE		BIT(7)

#define REG_LABIBB_PD_CTL		0x47
 #define LAB_PD_CTL_MASK		GENMASK(1, 0)
 #define IBB_PD_CTL_MASK		(BIT(0) | BIT(7))
 #define LAB_PD_CTL_STRONG_PULL		BIT(0)
 #define IBB_PD_CTL_HALF_STRENGTH	BIT(0)
 #define IBB_PD_CTL_EN			BIT(7)

#define REG_LABIBB_CURRENT_LIMIT	0x4b
 #define LAB_CURRENT_LIMIT_MASK		GENMASK(2, 0)
 #define IBB_CURRENT_LIMIT_MASK		GENMASK(4, 0)
 #define LAB_CURRENT_LIMIT_OVERRIDE_EN	BIT(3)
 #define LABIBB_CURRENT_LIMIT_EN	BIT(7)

#define REG_IBB_PWRUP_PWRDN_CTL_1	0x58
 #define IBB_CTL_1_DISCHARGE_EN		BIT(2)

#define REG_LABIBB_SOFT_START_CTL	0x5f
#define REG_LABIBB_SEC_ACCESS		0xd0
 #define LABIBB_SEC_UNLOCK_CODE		0xa5

#define LAB_ENABLE_CTL_MASK		BIT(7)
#define IBB_ENABLE_CTL_MASK		(BIT(7) | BIT(6))

#define LABIBB_OFF_ON_DELAY		1000
#define LAB_ENABLE_TIME			(LABIBB_OFF_ON_DELAY * 2)
#define IBB_ENABLE_TIME			(LABIBB_OFF_ON_DELAY * 10)
#define LABIBB_POLL_ENABLED_TIME	1000
#define OCP_RECOVERY_INTERVAL_MS	500
#define SC_RECOVERY_INTERVAL_MS		250
#define LABIBB_MAX_OCP_COUNT		4
#define LABIBB_MAX_SC_COUNT		3
#define LABIBB_MAX_FATAL_COUNT		2

struct labibb_current_limits {
	u32				uA_min;
	u32				uA_step;
	u8				ovr_val;
};

struct labibb_regulator {
	struct regulator_desc		desc;
	struct device			*dev;
	struct regmap			*regmap;
	struct regulator_dev		*rdev;
	struct labibb_current_limits	uA_limits;
	struct delayed_work		ocp_recovery_work;
	struct delayed_work		sc_recovery_work;
	u16				base;
	u8				type;
	u8				dischg_sel;
	u8				soft_start_sel;
	int				sc_irq;
	int				sc_count;
	int				ocp_irq;
	int				ocp_irq_count;
	int				fatal_count;
};

struct labibb_regulator_data {
	const char			*name;
	u8				type;
	u16				base;
	const struct regulator_desc	*desc;
};

static int qcom_labibb_ocp_hw_enable(struct regulator_dev *rdev)
{
	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
	int ret;

	/* Clear irq latch status to avoid spurious event */
	ret = regmap_update_bits(rdev->regmap,
				 vreg->base + REG_LABIBB_INT_LATCHED_CLR,
				 LABIBB_INT_VREG_OK, 1);
	if (ret)
		return ret;

	/* Enable OCP HW interrupt */
	return regmap_update_bits(rdev->regmap,
				  vreg->base + REG_LABIBB_INT_EN_SET,
				  LABIBB_INT_VREG_OK, 1);
}

static int qcom_labibb_ocp_hw_disable(struct regulator_dev *rdev)
{
	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);

	return regmap_update_bits(rdev->regmap,
				  vreg->base + REG_LABIBB_INT_EN_CLR,
				  LABIBB_INT_VREG_OK, 1);
}

/**
 * qcom_labibb_check_ocp_status - Check the Over-Current Protection status
 * @vreg: Main driver structure
 *
 * This function checks the STATUS1 register for the VREG_OK bit: if it is
 * set, then there is no Over-Current event.
 *
 * Returns: Zero if there is no over-current, 1 if in over-current or
 *          negative number for error
 */
static int qcom_labibb_check_ocp_status(struct labibb_regulator *vreg)
{
	u32 cur_status;
	int ret;

	ret = regmap_read(vreg->rdev->regmap, vreg->base + REG_LABIBB_STATUS1,
			  &cur_status);
	if (ret)
		return ret;

	return !(cur_status & LABIBB_STATUS1_VREG_OK_BIT);
}

/**
 * qcom_labibb_ocp_recovery_worker - Handle OCP event
 * @work: OCP work structure
 *
 * This is the worker function to handle the Over Current Protection
 * hardware event; This will check if the hardware is still
 * signaling an over-current condition and will eventually stop
 * the regulator if such condition is still signaled after
 * LABIBB_MAX_OCP_COUNT times.
 *
 * If the driver that is consuming the regulator did not take action
 * for the OCP condition, or the hardware did not stabilize, a cut
 * of the LAB and IBB regulators will be forced (regulators will be
 * disabled).
 *
 * As last, if the writes to shut down the LAB/IBB regulators fail
 * for more than LABIBB_MAX_FATAL_COUNT, then a kernel panic will be
 * triggered, as a last resort to protect the hardware from burning;
 * this, however, is expected to never happen, but this is kept to
 * try to further ensure that we protect the hardware at all costs.
 */
static void qcom_labibb_ocp_recovery_worker(struct work_struct *work)
{
	struct labibb_regulator *vreg;
	const struct regulator_ops *ops;
	int ret;

	vreg = container_of(work, struct labibb_regulator,
			    ocp_recovery_work.work);
	ops = vreg->rdev->desc->ops;

	if (vreg->ocp_irq_count >= LABIBB_MAX_OCP_COUNT) {
		/*
		 * If we tried to disable the regulator multiple times but
		 * we kept failing, there's only one last hope to save our
		 * hardware from the death: raise a kernel bug, reboot and
		 * hope that the bootloader kindly saves us. This, though
		 * is done only as paranoid checking, because failing the
		 * regmap write to disable the vreg is almost impossible,
		 * since we got here after multiple regmap R/W.
		 */
		BUG_ON(vreg->fatal_count > LABIBB_MAX_FATAL_COUNT);
		dev_err(&vreg->rdev->dev, "LABIBB: CRITICAL: Disabling regulator\n");

		/* Disable the regulator immediately to avoid damage */
		ret = ops->disable(vreg->rdev);
		if (ret) {
			vreg->fatal_count++;
			goto reschedule;
		}
		enable_irq(vreg->ocp_irq);
		vreg->fatal_count = 0;
		return;
	}

	ret = qcom_labibb_check_ocp_status(vreg);
	if (ret != 0) {
		vreg->ocp_irq_count++;
		goto reschedule;
	}

	ret = qcom_labibb_ocp_hw_enable(vreg->rdev);
	if (ret) {
		/* We cannot trust it without OCP enabled. */
		dev_err(vreg->dev, "Cannot enable OCP IRQ\n");
		vreg->ocp_irq_count++;
		goto reschedule;
	}

	enable_irq(vreg->ocp_irq);
	/* Everything went fine: reset the OCP count! */
	vreg->ocp_irq_count = 0;
	return;

reschedule:
	mod_delayed_work(system_wq, &vreg->ocp_recovery_work,
			 msecs_to_jiffies(OCP_RECOVERY_INTERVAL_MS));
}

/**
 * qcom_labibb_ocp_isr - Interrupt routine for OverCurrent Protection
 * @irq:  Interrupt number
 * @chip: Main driver structure
 *
 * Over Current Protection (OCP) will signal to the client driver
 * that an over-current event has happened and then will schedule
 * a recovery worker.
 *
 * Disabling and eventually re-enabling the regulator is expected
 * to be done by the driver, as some hardware may be triggering an
 * over-current condition only at first initialization or it may
 * be expected only for a very brief amount of time, after which
 * the attached hardware may be expected to stabilize its current
 * draw.
 *
 * Returns: IRQ_HANDLED for success or IRQ_NONE for failure.
 */
static irqreturn_t qcom_labibb_ocp_isr(int irq, void *chip)
{
	struct labibb_regulator *vreg = chip;
	const struct regulator_ops *ops = vreg->rdev->desc->ops;
	int ret;

	/* If the regulator is not enabled, this is a fake event */
	if (!ops->is_enabled(vreg->rdev))
		return IRQ_HANDLED;

	/* If we tried to recover for too many times it's not getting better */
	if (vreg->ocp_irq_count > LABIBB_MAX_OCP_COUNT)
		return IRQ_NONE;

	/*
	 * If we (unlikely) can't read this register, to prevent hardware
	 * damage at all costs, we assume that the overcurrent event was
	 * real; Moreover, if the status register is not signaling OCP,
	 * it was a spurious event, so it's all ok.
	 */
	ret = qcom_labibb_check_ocp_status(vreg);
	if (ret == 0) {
		vreg->ocp_irq_count = 0;
		goto end;
	}
	vreg->ocp_irq_count++;

	/*
	 * Disable the interrupt temporarily, or it will fire continuously;
	 * we will re-enable it in the recovery worker function.
	 */
	disable_irq_nosync(irq);

	/* Warn the user for overcurrent */
	dev_warn(vreg->dev, "Over-Current interrupt fired!\n");

	/* Disable the interrupt to avoid hogging */
	ret = qcom_labibb_ocp_hw_disable(vreg->rdev);
	if (ret)
		goto end;

	/* Signal overcurrent event to drivers */
	regulator_notifier_call_chain(vreg->rdev,
				      REGULATOR_EVENT_OVER_CURRENT, NULL);

end:
	/* Schedule the recovery work */
	schedule_delayed_work(&vreg->ocp_recovery_work,
			      msecs_to_jiffies(OCP_RECOVERY_INTERVAL_MS));
	if (ret)
		return IRQ_NONE;

	return IRQ_HANDLED;
}

static int qcom_labibb_set_ocp(struct regulator_dev *rdev, int lim,
			       int severity, bool enable)
{
	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
	char *ocp_irq_name;
	u32 irq_flags = IRQF_ONESHOT;
	int irq_trig_low, ret;

	/*
	 * labibb supports only protection - and does not support setting
	 * limit. Furthermore, we don't support disabling protection.
	 */
	if (lim || severity != REGULATOR_SEVERITY_PROT || !enable)
		return -EINVAL;

	/* If there is no OCP interrupt, there's nothing to set */
	if (vreg->ocp_irq <= 0)
		return -EINVAL;

	ocp_irq_name = devm_kasprintf(vreg->dev, GFP_KERNEL, "%s-over-current",
				      vreg->desc.name);
	if (!ocp_irq_name)
		return -ENOMEM;

	/* IRQ polarities - LAB: trigger-low, IBB: trigger-high */
	switch (vreg->type) {
	case QCOM_LAB_TYPE:
		irq_flags |= IRQF_TRIGGER_LOW;
		irq_trig_low = 1;
		break;
	case QCOM_IBB_TYPE:
		irq_flags |= IRQF_TRIGGER_HIGH;
		irq_trig_low = 0;
		break;
	default:
		return -EINVAL;
	}

	/* Activate OCP HW level interrupt */
	ret = regmap_update_bits(rdev->regmap,
				 vreg->base + REG_LABIBB_INT_SET_TYPE,
				 LABIBB_INT_VREG_OK,
				 LABIBB_INT_VREG_TYPE_LEVEL);
	if (ret)
		return ret;

	/* Set OCP interrupt polarity */
	ret = regmap_update_bits(rdev->regmap,
				 vreg->base + REG_LABIBB_INT_POLARITY_HIGH,
				 LABIBB_INT_VREG_OK, !irq_trig_low);
	if (ret)
		return ret;
	ret = regmap_update_bits(rdev->regmap,
				 vreg->base + REG_LABIBB_INT_POLARITY_LOW,
				 LABIBB_INT_VREG_OK, irq_trig_low);
	if (ret)
		return ret;

	ret = qcom_labibb_ocp_hw_enable(rdev);
	if (ret)
		return ret;

	return devm_request_threaded_irq(vreg->dev, vreg->ocp_irq, NULL,
					 qcom_labibb_ocp_isr, irq_flags,
					 ocp_irq_name, vreg);
}

/**
 * qcom_labibb_check_sc_status - Check the Short Circuit Protection status
 * @vreg: Main driver structure
 *
 * This function checks the STATUS1 register on both LAB and IBB regulators
 * for the ShortCircuit bit: if it is set on *any* of them, then we have
 * experienced a short-circuit event.
 *
 * Returns: Zero if there is no short-circuit, 1 if in short-circuit or
 *          negative number for error
 */
static int qcom_labibb_check_sc_status(struct labibb_regulator *vreg)
{
	u32 ibb_status, ibb_reg, lab_status, lab_reg;
	int ret;

	/* We have to work on both regulators due to PBS... */
	lab_reg = ibb_reg = vreg->base + REG_LABIBB_STATUS1;
	if (vreg->type == QCOM_LAB_TYPE)
		ibb_reg -= PMI8998_IBB_LAB_REG_OFFSET;
	else
		lab_reg += PMI8998_IBB_LAB_REG_OFFSET;

	ret = regmap_read(vreg->rdev->regmap, lab_reg, &lab_status);
	if (ret)
		return ret;
	ret = regmap_read(vreg->rdev->regmap, ibb_reg, &ibb_status);
	if (ret)
		return ret;

	return !!(lab_status & LABIBB_STATUS1_SC_BIT) ||
	       !!(ibb_status & LABIBB_STATUS1_SC_BIT);
}

/**
 * qcom_labibb_sc_recovery_worker - Handle Short Circuit event
 * @work: SC work structure
 *
 * This is the worker function to handle the Short Circuit Protection
 * hardware event; This will check if the hardware is still
 * signaling a short-circuit condition and will eventually never
 * re-enable the regulator if such condition is still signaled after
 * LABIBB_MAX_SC_COUNT times.
 *
 * If the driver that is consuming the regulator did not take action
 * for the SC condition, or the hardware did not stabilize, this
 * worker will stop rescheduling, leaving the regulators disabled
 * as already done by the Portable Batch System (PBS).
 *
 * Returns: IRQ_HANDLED for success or IRQ_NONE for failure.
 */
static void qcom_labibb_sc_recovery_worker(struct work_struct *work)
{
	struct labibb_regulator *vreg;
	const struct regulator_ops *ops;
	u32 lab_reg, ibb_reg, lab_val, ibb_val, val;
	bool pbs_cut = false;
	int i, sc, ret;

	vreg = container_of(work, struct labibb_regulator,
			    sc_recovery_work.work);
	ops = vreg->rdev->desc->ops;

	/*
	 * If we tried to check the regulator status multiple times but we
	 * kept failing, then just bail out, as the Portable Batch System
	 * (PBS) will disable the vregs for us, preventing hardware damage.
	 */
	if (vreg->fatal_count > LABIBB_MAX_FATAL_COUNT)
		return;

	/* Too many short-circuit events. Throw in the towel. */
	if (vreg->sc_count > LABIBB_MAX_SC_COUNT)
		return;

	/*
	 * The Portable Batch System (PBS) automatically disables LAB
	 * and IBB when a short-circuit event is detected, so we have to
	 * check and work on both of them at the same time.
	 */
	lab_reg = ibb_reg = vreg->base + REG_LABIBB_ENABLE_CTL;
	if (vreg->type == QCOM_LAB_TYPE)
		ibb_reg -= PMI8998_IBB_LAB_REG_OFFSET;
	else
		lab_reg += PMI8998_IBB_LAB_REG_OFFSET;

	sc = qcom_labibb_check_sc_status(vreg);
	if (sc)
		goto reschedule;

	for (i = 0; i < LABIBB_MAX_SC_COUNT; i++) {
		ret = regmap_read(vreg->regmap, lab_reg, &lab_val);
		if (ret) {
			vreg->fatal_count++;
			goto reschedule;
		}

		ret = regmap_read(vreg->regmap, ibb_reg, &ibb_val);
		if (ret) {
			vreg->fatal_count++;
			goto reschedule;
		}
		val = lab_val & ibb_val;

		if (!(val & LABIBB_CONTROL_ENABLE)) {
			pbs_cut = true;
			break;
		}
		usleep_range(5000, 6000);
	}
	if (pbs_cut)
		goto reschedule;


	/*
	 * If we have reached this point, we either have successfully
	 * recovered from the SC condition or we had a spurious SC IRQ,
	 * which means that we can re-enable the regulators, if they
	 * have ever been disabled by the PBS.
	 */
	ret = ops->enable(vreg->rdev);
	if (ret)
		goto reschedule;

	/* Everything went fine: reset the OCP count! */
	vreg->sc_count = 0;
	enable_irq(vreg->sc_irq);
	return;

reschedule:
	/*
	 * Now that we have done basic handling of the short-circuit,
	 * reschedule this worker in the regular system workqueue, as
	 * taking action is not truly urgent anymore.
	 */
	vreg->sc_count++;
	mod_delayed_work(system_wq, &vreg->sc_recovery_work,
			 msecs_to_jiffies(SC_RECOVERY_INTERVAL_MS));
}

/**
 * qcom_labibb_sc_isr - Interrupt routine for Short Circuit Protection
 * @irq:  Interrupt number
 * @chip: Main driver structure
 *
 * Short Circuit Protection (SCP) will signal to the client driver
 * that a regulation-out event has happened and then will schedule
 * a recovery worker.
 *
 * The LAB and IBB regulators will be automatically disabled by the
 * Portable Batch System (PBS) and they will be enabled again by
 * the worker function if the hardware stops signaling the short
 * circuit event.
 *
 * Returns: IRQ_HANDLED for success or IRQ_NONE for failure.
 */
static irqreturn_t qcom_labibb_sc_isr(int irq, void *chip)
{
	struct labibb_regulator *vreg = chip;

	if (vreg->sc_count > LABIBB_MAX_SC_COUNT)
		return IRQ_NONE;

	/* Warn the user for short circuit */
	dev_warn(vreg->dev, "Short-Circuit interrupt fired!\n");

	/*
	 * Disable the interrupt temporarily, or it will fire continuously;
	 * we will re-enable it in the recovery worker function.
	 */
	disable_irq_nosync(irq);

	/* Signal out of regulation event to drivers */
	regulator_notifier_call_chain(vreg->rdev,
				      REGULATOR_EVENT_REGULATION_OUT, NULL);

	/* Schedule the short-circuit handling as high-priority work */
	mod_delayed_work(system_highpri_wq, &vreg->sc_recovery_work,
			 msecs_to_jiffies(SC_RECOVERY_INTERVAL_MS));
	return IRQ_HANDLED;
}


static int qcom_labibb_set_current_limit(struct regulator_dev *rdev,
					 int min_uA, int max_uA)
{
	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
	struct regulator_desc *desc = &vreg->desc;
	struct labibb_current_limits *lim = &vreg->uA_limits;
	u32 mask, val;
	int i, ret, sel = -1;

	if (min_uA < lim->uA_min || max_uA < lim->uA_min)
		return -EINVAL;

	for (i = 0; i < desc->n_current_limits; i++) {
		int uA_limit = (lim->uA_step * i) + lim->uA_min;

		if (max_uA >= uA_limit && min_uA <= uA_limit)
			sel = i;
	}
	if (sel < 0)
		return -EINVAL;

	/* Current limit setting needs secure access */
	ret = regmap_write(vreg->regmap, vreg->base + REG_LABIBB_SEC_ACCESS,
			   LABIBB_SEC_UNLOCK_CODE);
	if (ret)
		return ret;

	mask = desc->csel_mask | lim->ovr_val;
	mask |= LABIBB_CURRENT_LIMIT_EN;
	val = (u32)sel | lim->ovr_val;
	val |= LABIBB_CURRENT_LIMIT_EN;

	return regmap_update_bits(vreg->regmap, desc->csel_reg, mask, val);
}

static int qcom_labibb_get_current_limit(struct regulator_dev *rdev)
{
	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
	struct regulator_desc *desc = &vreg->desc;
	struct labibb_current_limits *lim = &vreg->uA_limits;
	unsigned int cur_step;
	int ret;

	ret = regmap_read(vreg->regmap, desc->csel_reg, &cur_step);
	if (ret)
		return ret;
	cur_step &= desc->csel_mask;

	return (cur_step * lim->uA_step) + lim->uA_min;
}

static int qcom_labibb_set_soft_start(struct regulator_dev *rdev)
{
	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
	u32 val = 0;

	if (vreg->type == QCOM_IBB_TYPE)
		val = vreg->dischg_sel;
	else
		val = vreg->soft_start_sel;

	return regmap_write(rdev->regmap, rdev->desc->soft_start_reg, val);
}

static int qcom_labibb_get_table_sel(const int *table, int sz, u32 value)
{
	int i;

	for (i = 0; i < sz; i++)
		if (table[i] == value)
			return i;
	return -EINVAL;
}

/* IBB discharge resistor values in KOhms */
static const int dischg_resistor_values[] = { 300, 64, 32, 16 };

/* Soft start time in microseconds */
static const int soft_start_values[] = { 200, 400, 600, 800 };

static int qcom_labibb_of_parse_cb(struct device_node *np,
				   const struct regulator_desc *desc,
				   struct regulator_config *config)
{
	struct labibb_regulator *vreg = config->driver_data;
	u32 dischg_kohms, soft_start_time;
	int ret;

	ret = of_property_read_u32(np, "qcom,discharge-resistor-kohms",
				       &dischg_kohms);
	if (ret)
		dischg_kohms = 300;

	ret = qcom_labibb_get_table_sel(dischg_resistor_values,
					ARRAY_SIZE(dischg_resistor_values),
					dischg_kohms);
	if (ret < 0)
		return ret;
	vreg->dischg_sel = (u8)ret;

	ret = of_property_read_u32(np, "qcom,soft-start-us",
				   &soft_start_time);
	if (ret)
		soft_start_time = 200;

	ret = qcom_labibb_get_table_sel(soft_start_values,
					ARRAY_SIZE(soft_start_values),
					soft_start_time);
	if (ret < 0)
		return ret;
	vreg->soft_start_sel = (u8)ret;

	return 0;
}

static const struct regulator_ops qcom_labibb_ops = {
	.enable			= regulator_enable_regmap,
	.disable		= regulator_disable_regmap,
	.is_enabled		= regulator_is_enabled_regmap,
	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
	.list_voltage		= regulator_list_voltage_linear,
	.map_voltage		= regulator_map_voltage_linear,
	.set_active_discharge	= regulator_set_active_discharge_regmap,
	.set_pull_down		= regulator_set_pull_down_regmap,
	.set_current_limit	= qcom_labibb_set_current_limit,
	.get_current_limit	= qcom_labibb_get_current_limit,
	.set_soft_start		= qcom_labibb_set_soft_start,
	.set_over_current_protection = qcom_labibb_set_ocp,
};

static const struct regulator_desc pmi8998_lab_desc = {
	.enable_mask		= LAB_ENABLE_CTL_MASK,
	.enable_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_ENABLE_CTL),
	.enable_val		= LABIBB_CONTROL_ENABLE,
	.enable_time		= LAB_ENABLE_TIME,
	.poll_enabled_time	= LABIBB_POLL_ENABLED_TIME,
	.soft_start_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_SOFT_START_CTL),
	.pull_down_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_PD_CTL),
	.pull_down_mask		= LAB_PD_CTL_MASK,
	.pull_down_val_on	= LAB_PD_CTL_STRONG_PULL,
	.vsel_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_VOLTAGE),
	.vsel_mask		= LAB_VOLTAGE_SET_MASK,
	.apply_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_VOLTAGE),
	.apply_bit		= LABIBB_VOLTAGE_OVERRIDE_EN,
	.csel_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_CURRENT_LIMIT),
	.csel_mask		= LAB_CURRENT_LIMIT_MASK,
	.n_current_limits	= 8,
	.off_on_delay		= LABIBB_OFF_ON_DELAY,
	.owner			= THIS_MODULE,
	.type			= REGULATOR_VOLTAGE,
	.min_uV			= 4600000,
	.uV_step		= 100000,
	.n_voltages		= 16,
	.ops			= &qcom_labibb_ops,
	.of_parse_cb		= qcom_labibb_of_parse_cb,
};

static const struct regulator_desc pmi8998_ibb_desc = {
	.enable_mask		= IBB_ENABLE_CTL_MASK,
	.enable_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_ENABLE_CTL),
	.enable_val		= LABIBB_CONTROL_ENABLE,
	.enable_time		= IBB_ENABLE_TIME,
	.poll_enabled_time	= LABIBB_POLL_ENABLED_TIME,
	.soft_start_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_SOFT_START_CTL),
	.active_discharge_off	= 0,
	.active_discharge_on	= IBB_CTL_1_DISCHARGE_EN,
	.active_discharge_mask	= IBB_CTL_1_DISCHARGE_EN,
	.active_discharge_reg	= (PMI8998_IBB_REG_BASE + REG_IBB_PWRUP_PWRDN_CTL_1),
	.pull_down_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_PD_CTL),
	.pull_down_mask		= IBB_PD_CTL_MASK,
	.pull_down_val_on	= IBB_PD_CTL_HALF_STRENGTH | IBB_PD_CTL_EN,
	.vsel_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_VOLTAGE),
	.vsel_mask		= IBB_VOLTAGE_SET_MASK,
	.apply_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_VOLTAGE),
	.apply_bit		= LABIBB_VOLTAGE_OVERRIDE_EN,
	.csel_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_CURRENT_LIMIT),
	.csel_mask		= IBB_CURRENT_LIMIT_MASK,
	.n_current_limits	= 32,
	.off_on_delay		= LABIBB_OFF_ON_DELAY,
	.owner			= THIS_MODULE,
	.type			= REGULATOR_VOLTAGE,
	.min_uV			= 1400000,
	.uV_step		= 100000,
	.n_voltages		= 64,
	.ops			= &qcom_labibb_ops,
	.of_parse_cb		= qcom_labibb_of_parse_cb,
};

static const struct labibb_regulator_data pmi8998_labibb_data[] = {
	{"lab", QCOM_LAB_TYPE, PMI8998_LAB_REG_BASE, &pmi8998_lab_desc},
	{"ibb", QCOM_IBB_TYPE, PMI8998_IBB_REG_BASE, &pmi8998_ibb_desc},
	{ },
};

static const struct of_device_id qcom_labibb_match[] = {
	{ .compatible = "qcom,pmi8998-lab-ibb", .data = &pmi8998_labibb_data},
	{ },
};
MODULE_DEVICE_TABLE(of, qcom_labibb_match);

static int qcom_labibb_regulator_probe(struct platform_device *pdev)
{
	struct labibb_regulator *vreg;
	struct device *dev = &pdev->dev;
	struct regulator_config cfg = {};
	struct device_node *reg_node;
	const struct of_device_id *match;
	const struct labibb_regulator_data *reg_data;
	struct regmap *reg_regmap;
	unsigned int type;
	int ret;

	reg_regmap = dev_get_regmap(pdev->dev.parent, NULL);
	if (!reg_regmap) {
		dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
		return -ENODEV;
	}

	match = of_match_device(qcom_labibb_match, &pdev->dev);
	if (!match)
		return -ENODEV;

	for (reg_data = match->data; reg_data->name; reg_data++) {
		char *sc_irq_name;
		int irq = 0;

		/* Validate if the type of regulator is indeed
		 * what's mentioned in DT.
		 */
		ret = regmap_read(reg_regmap, reg_data->base + REG_PERPH_TYPE,
				  &type);
		if (ret < 0) {
			dev_err(dev,
				"Peripheral type read failed ret=%d\n",
				ret);
			return -EINVAL;
		}

		if (WARN_ON((type != QCOM_LAB_TYPE) && (type != QCOM_IBB_TYPE)) ||
		    WARN_ON(type != reg_data->type))
			return -EINVAL;

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

		sc_irq_name = devm_kasprintf(dev, GFP_KERNEL,
					     "%s-short-circuit",
					     reg_data->name);
		if (!sc_irq_name)
			return -ENOMEM;

		reg_node = of_get_child_by_name(pdev->dev.of_node,
						reg_data->name);
		if (!reg_node)
			return -EINVAL;

		/* The Short Circuit interrupt is critical */
		irq = of_irq_get_byname(reg_node, "sc-err");
		if (irq <= 0) {
			if (irq == 0)
				irq = -EINVAL;

			return dev_err_probe(vreg->dev, irq,
					     "Short-circuit irq not found.\n");
		}
		vreg->sc_irq = irq;

		/* OverCurrent Protection IRQ is optional */
		irq = of_irq_get_byname(reg_node, "ocp");
		vreg->ocp_irq = irq;
		vreg->ocp_irq_count = 0;
		of_node_put(reg_node);

		vreg->regmap = reg_regmap;
		vreg->dev = dev;
		vreg->base = reg_data->base;
		vreg->type = reg_data->type;
		INIT_DELAYED_WORK(&vreg->sc_recovery_work,
				  qcom_labibb_sc_recovery_worker);

		if (vreg->ocp_irq > 0)
			INIT_DELAYED_WORK(&vreg->ocp_recovery_work,
					  qcom_labibb_ocp_recovery_worker);

		switch (vreg->type) {
		case QCOM_LAB_TYPE:
			/* LAB Limits: 200-1600mA */
			vreg->uA_limits.uA_min  = 200000;
			vreg->uA_limits.uA_step = 200000;
			vreg->uA_limits.ovr_val = LAB_CURRENT_LIMIT_OVERRIDE_EN;
			break;
		case QCOM_IBB_TYPE:
			/* IBB Limits: 0-1550mA */
			vreg->uA_limits.uA_min  = 0;
			vreg->uA_limits.uA_step = 50000;
			vreg->uA_limits.ovr_val = 0; /* No override bit */
			break;
		default:
			return -EINVAL;
		}

		memcpy(&vreg->desc, reg_data->desc, sizeof(vreg->desc));
		vreg->desc.of_match = reg_data->name;
		vreg->desc.name = reg_data->name;

		cfg.dev = vreg->dev;
		cfg.driver_data = vreg;
		cfg.regmap = vreg->regmap;

		vreg->rdev = devm_regulator_register(vreg->dev, &vreg->desc,
							&cfg);

		if (IS_ERR(vreg->rdev)) {
			dev_err(dev, "qcom_labibb: error registering %s : %d\n",
					reg_data->name, ret);
			return PTR_ERR(vreg->rdev);
		}

		ret = devm_request_threaded_irq(vreg->dev, vreg->sc_irq, NULL,
						qcom_labibb_sc_isr,
						IRQF_ONESHOT |
						IRQF_TRIGGER_RISING,
						sc_irq_name, vreg);
		if (ret)
			return ret;
	}

	return 0;
}

static struct platform_driver qcom_labibb_regulator_driver = {
	.driver	= {
		.name = "qcom-lab-ibb-regulator",
		.of_match_table	= qcom_labibb_match,
	},
	.probe = qcom_labibb_regulator_probe,
};
module_platform_driver(qcom_labibb_regulator_driver);

MODULE_DESCRIPTION("Qualcomm labibb driver");
MODULE_AUTHOR("Nisha Kumari <nishakumari@codeaurora.org>");
MODULE_AUTHOR("Sumit Semwal <sumit.semwal@linaro.org>");
MODULE_LICENSE("GPL v2");
