drivers/regulator/qcom-labibb-regulator.c

Source file repositories/reference/linux-study-clean/drivers/regulator/qcom-labibb-regulator.c

File Facts

System
Linux kernel
Corpus path
drivers/regulator/qcom-labibb-regulator.c
Extension
.c
Size
26332 bytes
Lines
907
Domain
Driver Families
Bucket
drivers/regulator
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

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

Annotation

Implementation Notes