brintos

brintos / linux-shallow public Read only

0
0
Text · 25.7 KiB · ba3f939 Raw
907 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2// Copyright (c) 2020, The Linux Foundation. All rights reserved.3 4#include <linux/module.h>5#include <linux/of_irq.h>6#include <linux/of.h>7#include <linux/of_device.h>8#include <linux/platform_device.h>9#include <linux/regmap.h>10#include <linux/regulator/driver.h>11#include <linux/regulator/of_regulator.h>12 13#define REG_PERPH_TYPE                  0x0414 15#define QCOM_LAB_TYPE			0x2416#define QCOM_IBB_TYPE			0x2017 18#define PMI8998_LAB_REG_BASE		0xde0019#define PMI8998_IBB_REG_BASE		0xdc0020#define PMI8998_IBB_LAB_REG_OFFSET	0x20021 22#define REG_LABIBB_STATUS1		0x0823 #define LABIBB_STATUS1_SC_BIT		BIT(6)24 #define LABIBB_STATUS1_VREG_OK_BIT	BIT(7)25 26#define REG_LABIBB_INT_SET_TYPE		0x1127#define REG_LABIBB_INT_POLARITY_HIGH	0x1228#define REG_LABIBB_INT_POLARITY_LOW	0x1329#define REG_LABIBB_INT_LATCHED_CLR	0x1430#define REG_LABIBB_INT_EN_SET		0x1531#define REG_LABIBB_INT_EN_CLR		0x1632 #define LABIBB_INT_VREG_OK		BIT(0)33 #define LABIBB_INT_VREG_TYPE_LEVEL	034 35#define REG_LABIBB_VOLTAGE		0x4136 #define LABIBB_VOLTAGE_OVERRIDE_EN	BIT(7)37 #define LAB_VOLTAGE_SET_MASK		GENMASK(3, 0)38 #define IBB_VOLTAGE_SET_MASK		GENMASK(5, 0)39 40#define REG_LABIBB_ENABLE_CTL		0x4641 #define LABIBB_CONTROL_ENABLE		BIT(7)42 43#define REG_LABIBB_PD_CTL		0x4744 #define LAB_PD_CTL_MASK		GENMASK(1, 0)45 #define IBB_PD_CTL_MASK		(BIT(0) | BIT(7))46 #define LAB_PD_CTL_STRONG_PULL		BIT(0)47 #define IBB_PD_CTL_HALF_STRENGTH	BIT(0)48 #define IBB_PD_CTL_EN			BIT(7)49 50#define REG_LABIBB_CURRENT_LIMIT	0x4b51 #define LAB_CURRENT_LIMIT_MASK		GENMASK(2, 0)52 #define IBB_CURRENT_LIMIT_MASK		GENMASK(4, 0)53 #define LAB_CURRENT_LIMIT_OVERRIDE_EN	BIT(3)54 #define LABIBB_CURRENT_LIMIT_EN	BIT(7)55 56#define REG_IBB_PWRUP_PWRDN_CTL_1	0x5857 #define IBB_CTL_1_DISCHARGE_EN		BIT(2)58 59#define REG_LABIBB_SOFT_START_CTL	0x5f60#define REG_LABIBB_SEC_ACCESS		0xd061 #define LABIBB_SEC_UNLOCK_CODE		0xa562 63#define LAB_ENABLE_CTL_MASK		BIT(7)64#define IBB_ENABLE_CTL_MASK		(BIT(7) | BIT(6))65 66#define LABIBB_OFF_ON_DELAY		100067#define LAB_ENABLE_TIME			(LABIBB_OFF_ON_DELAY * 2)68#define IBB_ENABLE_TIME			(LABIBB_OFF_ON_DELAY * 10)69#define LABIBB_POLL_ENABLED_TIME	100070#define OCP_RECOVERY_INTERVAL_MS	50071#define SC_RECOVERY_INTERVAL_MS		25072#define LABIBB_MAX_OCP_COUNT		473#define LABIBB_MAX_SC_COUNT		374#define LABIBB_MAX_FATAL_COUNT		275 76struct labibb_current_limits {77	u32				uA_min;78	u32				uA_step;79	u8				ovr_val;80};81 82struct labibb_regulator {83	struct regulator_desc		desc;84	struct device			*dev;85	struct regmap			*regmap;86	struct regulator_dev		*rdev;87	struct labibb_current_limits	uA_limits;88	struct delayed_work		ocp_recovery_work;89	struct delayed_work		sc_recovery_work;90	u16				base;91	u8				type;92	u8				dischg_sel;93	u8				soft_start_sel;94	int				sc_irq;95	int				sc_count;96	int				ocp_irq;97	int				ocp_irq_count;98	int				fatal_count;99};100 101struct labibb_regulator_data {102	const char			*name;103	u8				type;104	u16				base;105	const struct regulator_desc	*desc;106};107 108static int qcom_labibb_ocp_hw_enable(struct regulator_dev *rdev)109{110	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);111	int ret;112 113	/* Clear irq latch status to avoid spurious event */114	ret = regmap_update_bits(rdev->regmap,115				 vreg->base + REG_LABIBB_INT_LATCHED_CLR,116				 LABIBB_INT_VREG_OK, 1);117	if (ret)118		return ret;119 120	/* Enable OCP HW interrupt */121	return regmap_update_bits(rdev->regmap,122				  vreg->base + REG_LABIBB_INT_EN_SET,123				  LABIBB_INT_VREG_OK, 1);124}125 126static int qcom_labibb_ocp_hw_disable(struct regulator_dev *rdev)127{128	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);129 130	return regmap_update_bits(rdev->regmap,131				  vreg->base + REG_LABIBB_INT_EN_CLR,132				  LABIBB_INT_VREG_OK, 1);133}134 135/**136 * qcom_labibb_check_ocp_status - Check the Over-Current Protection status137 * @vreg: Main driver structure138 *139 * This function checks the STATUS1 register for the VREG_OK bit: if it is140 * set, then there is no Over-Current event.141 *142 * Returns: Zero if there is no over-current, 1 if in over-current or143 *          negative number for error144 */145static int qcom_labibb_check_ocp_status(struct labibb_regulator *vreg)146{147	u32 cur_status;148	int ret;149 150	ret = regmap_read(vreg->rdev->regmap, vreg->base + REG_LABIBB_STATUS1,151			  &cur_status);152	if (ret)153		return ret;154 155	return !(cur_status & LABIBB_STATUS1_VREG_OK_BIT);156}157 158/**159 * qcom_labibb_ocp_recovery_worker - Handle OCP event160 * @work: OCP work structure161 *162 * This is the worker function to handle the Over Current Protection163 * hardware event; This will check if the hardware is still164 * signaling an over-current condition and will eventually stop165 * the regulator if such condition is still signaled after166 * LABIBB_MAX_OCP_COUNT times.167 *168 * If the driver that is consuming the regulator did not take action169 * for the OCP condition, or the hardware did not stabilize, a cut170 * of the LAB and IBB regulators will be forced (regulators will be171 * disabled).172 *173 * As last, if the writes to shut down the LAB/IBB regulators fail174 * for more than LABIBB_MAX_FATAL_COUNT, then a kernel panic will be175 * triggered, as a last resort to protect the hardware from burning;176 * this, however, is expected to never happen, but this is kept to177 * try to further ensure that we protect the hardware at all costs.178 */179static void qcom_labibb_ocp_recovery_worker(struct work_struct *work)180{181	struct labibb_regulator *vreg;182	const struct regulator_ops *ops;183	int ret;184 185	vreg = container_of(work, struct labibb_regulator,186			    ocp_recovery_work.work);187	ops = vreg->rdev->desc->ops;188 189	if (vreg->ocp_irq_count >= LABIBB_MAX_OCP_COUNT) {190		/*191		 * If we tried to disable the regulator multiple times but192		 * we kept failing, there's only one last hope to save our193		 * hardware from the death: raise a kernel bug, reboot and194		 * hope that the bootloader kindly saves us. This, though195		 * is done only as paranoid checking, because failing the196		 * regmap write to disable the vreg is almost impossible,197		 * since we got here after multiple regmap R/W.198		 */199		BUG_ON(vreg->fatal_count > LABIBB_MAX_FATAL_COUNT);200		dev_err(&vreg->rdev->dev, "LABIBB: CRITICAL: Disabling regulator\n");201 202		/* Disable the regulator immediately to avoid damage */203		ret = ops->disable(vreg->rdev);204		if (ret) {205			vreg->fatal_count++;206			goto reschedule;207		}208		enable_irq(vreg->ocp_irq);209		vreg->fatal_count = 0;210		return;211	}212 213	ret = qcom_labibb_check_ocp_status(vreg);214	if (ret != 0) {215		vreg->ocp_irq_count++;216		goto reschedule;217	}218 219	ret = qcom_labibb_ocp_hw_enable(vreg->rdev);220	if (ret) {221		/* We cannot trust it without OCP enabled. */222		dev_err(vreg->dev, "Cannot enable OCP IRQ\n");223		vreg->ocp_irq_count++;224		goto reschedule;225	}226 227	enable_irq(vreg->ocp_irq);228	/* Everything went fine: reset the OCP count! */229	vreg->ocp_irq_count = 0;230	return;231 232reschedule:233	mod_delayed_work(system_wq, &vreg->ocp_recovery_work,234			 msecs_to_jiffies(OCP_RECOVERY_INTERVAL_MS));235}236 237/**238 * qcom_labibb_ocp_isr - Interrupt routine for OverCurrent Protection239 * @irq:  Interrupt number240 * @chip: Main driver structure241 *242 * Over Current Protection (OCP) will signal to the client driver243 * that an over-current event has happened and then will schedule244 * a recovery worker.245 *246 * Disabling and eventually re-enabling the regulator is expected247 * to be done by the driver, as some hardware may be triggering an248 * over-current condition only at first initialization or it may249 * be expected only for a very brief amount of time, after which250 * the attached hardware may be expected to stabilize its current251 * draw.252 *253 * Returns: IRQ_HANDLED for success or IRQ_NONE for failure.254 */255static irqreturn_t qcom_labibb_ocp_isr(int irq, void *chip)256{257	struct labibb_regulator *vreg = chip;258	const struct regulator_ops *ops = vreg->rdev->desc->ops;259	int ret;260 261	/* If the regulator is not enabled, this is a fake event */262	if (!ops->is_enabled(vreg->rdev))263		return IRQ_HANDLED;264 265	/* If we tried to recover for too many times it's not getting better */266	if (vreg->ocp_irq_count > LABIBB_MAX_OCP_COUNT)267		return IRQ_NONE;268 269	/*270	 * If we (unlikely) can't read this register, to prevent hardware271	 * damage at all costs, we assume that the overcurrent event was272	 * real; Moreover, if the status register is not signaling OCP,273	 * it was a spurious event, so it's all ok.274	 */275	ret = qcom_labibb_check_ocp_status(vreg);276	if (ret == 0) {277		vreg->ocp_irq_count = 0;278		goto end;279	}280	vreg->ocp_irq_count++;281 282	/*283	 * Disable the interrupt temporarily, or it will fire continuously;284	 * we will re-enable it in the recovery worker function.285	 */286	disable_irq_nosync(irq);287 288	/* Warn the user for overcurrent */289	dev_warn(vreg->dev, "Over-Current interrupt fired!\n");290 291	/* Disable the interrupt to avoid hogging */292	ret = qcom_labibb_ocp_hw_disable(vreg->rdev);293	if (ret)294		goto end;295 296	/* Signal overcurrent event to drivers */297	regulator_notifier_call_chain(vreg->rdev,298				      REGULATOR_EVENT_OVER_CURRENT, NULL);299 300end:301	/* Schedule the recovery work */302	schedule_delayed_work(&vreg->ocp_recovery_work,303			      msecs_to_jiffies(OCP_RECOVERY_INTERVAL_MS));304	if (ret)305		return IRQ_NONE;306 307	return IRQ_HANDLED;308}309 310static int qcom_labibb_set_ocp(struct regulator_dev *rdev, int lim,311			       int severity, bool enable)312{313	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);314	char *ocp_irq_name;315	u32 irq_flags = IRQF_ONESHOT;316	int irq_trig_low, ret;317 318	/*319	 * labibb supports only protection - and does not support setting320	 * limit. Furthermore, we don't support disabling protection.321	 */322	if (lim || severity != REGULATOR_SEVERITY_PROT || !enable)323		return -EINVAL;324 325	/* If there is no OCP interrupt, there's nothing to set */326	if (vreg->ocp_irq <= 0)327		return -EINVAL;328 329	ocp_irq_name = devm_kasprintf(vreg->dev, GFP_KERNEL, "%s-over-current",330				      vreg->desc.name);331	if (!ocp_irq_name)332		return -ENOMEM;333 334	/* IRQ polarities - LAB: trigger-low, IBB: trigger-high */335	switch (vreg->type) {336	case QCOM_LAB_TYPE:337		irq_flags |= IRQF_TRIGGER_LOW;338		irq_trig_low = 1;339		break;340	case QCOM_IBB_TYPE:341		irq_flags |= IRQF_TRIGGER_HIGH;342		irq_trig_low = 0;343		break;344	default:345		return -EINVAL;346	}347 348	/* Activate OCP HW level interrupt */349	ret = regmap_update_bits(rdev->regmap,350				 vreg->base + REG_LABIBB_INT_SET_TYPE,351				 LABIBB_INT_VREG_OK,352				 LABIBB_INT_VREG_TYPE_LEVEL);353	if (ret)354		return ret;355 356	/* Set OCP interrupt polarity */357	ret = regmap_update_bits(rdev->regmap,358				 vreg->base + REG_LABIBB_INT_POLARITY_HIGH,359				 LABIBB_INT_VREG_OK, !irq_trig_low);360	if (ret)361		return ret;362	ret = regmap_update_bits(rdev->regmap,363				 vreg->base + REG_LABIBB_INT_POLARITY_LOW,364				 LABIBB_INT_VREG_OK, irq_trig_low);365	if (ret)366		return ret;367 368	ret = qcom_labibb_ocp_hw_enable(rdev);369	if (ret)370		return ret;371 372	return devm_request_threaded_irq(vreg->dev, vreg->ocp_irq, NULL,373					 qcom_labibb_ocp_isr, irq_flags,374					 ocp_irq_name, vreg);375}376 377/**378 * qcom_labibb_check_sc_status - Check the Short Circuit Protection status379 * @vreg: Main driver structure380 *381 * This function checks the STATUS1 register on both LAB and IBB regulators382 * for the ShortCircuit bit: if it is set on *any* of them, then we have383 * experienced a short-circuit event.384 *385 * Returns: Zero if there is no short-circuit, 1 if in short-circuit or386 *          negative number for error387 */388static int qcom_labibb_check_sc_status(struct labibb_regulator *vreg)389{390	u32 ibb_status, ibb_reg, lab_status, lab_reg;391	int ret;392 393	/* We have to work on both regulators due to PBS... */394	lab_reg = ibb_reg = vreg->base + REG_LABIBB_STATUS1;395	if (vreg->type == QCOM_LAB_TYPE)396		ibb_reg -= PMI8998_IBB_LAB_REG_OFFSET;397	else398		lab_reg += PMI8998_IBB_LAB_REG_OFFSET;399 400	ret = regmap_read(vreg->rdev->regmap, lab_reg, &lab_status);401	if (ret)402		return ret;403	ret = regmap_read(vreg->rdev->regmap, ibb_reg, &ibb_status);404	if (ret)405		return ret;406 407	return !!(lab_status & LABIBB_STATUS1_SC_BIT) ||408	       !!(ibb_status & LABIBB_STATUS1_SC_BIT);409}410 411/**412 * qcom_labibb_sc_recovery_worker - Handle Short Circuit event413 * @work: SC work structure414 *415 * This is the worker function to handle the Short Circuit Protection416 * hardware event; This will check if the hardware is still417 * signaling a short-circuit condition and will eventually never418 * re-enable the regulator if such condition is still signaled after419 * LABIBB_MAX_SC_COUNT times.420 *421 * If the driver that is consuming the regulator did not take action422 * for the SC condition, or the hardware did not stabilize, this423 * worker will stop rescheduling, leaving the regulators disabled424 * as already done by the Portable Batch System (PBS).425 *426 * Returns: IRQ_HANDLED for success or IRQ_NONE for failure.427 */428static void qcom_labibb_sc_recovery_worker(struct work_struct *work)429{430	struct labibb_regulator *vreg;431	const struct regulator_ops *ops;432	u32 lab_reg, ibb_reg, lab_val, ibb_val, val;433	bool pbs_cut = false;434	int i, sc, ret;435 436	vreg = container_of(work, struct labibb_regulator,437			    sc_recovery_work.work);438	ops = vreg->rdev->desc->ops;439 440	/*441	 * If we tried to check the regulator status multiple times but we442	 * kept failing, then just bail out, as the Portable Batch System443	 * (PBS) will disable the vregs for us, preventing hardware damage.444	 */445	if (vreg->fatal_count > LABIBB_MAX_FATAL_COUNT)446		return;447 448	/* Too many short-circuit events. Throw in the towel. */449	if (vreg->sc_count > LABIBB_MAX_SC_COUNT)450		return;451 452	/*453	 * The Portable Batch System (PBS) automatically disables LAB454	 * and IBB when a short-circuit event is detected, so we have to455	 * check and work on both of them at the same time.456	 */457	lab_reg = ibb_reg = vreg->base + REG_LABIBB_ENABLE_CTL;458	if (vreg->type == QCOM_LAB_TYPE)459		ibb_reg -= PMI8998_IBB_LAB_REG_OFFSET;460	else461		lab_reg += PMI8998_IBB_LAB_REG_OFFSET;462 463	sc = qcom_labibb_check_sc_status(vreg);464	if (sc)465		goto reschedule;466 467	for (i = 0; i < LABIBB_MAX_SC_COUNT; i++) {468		ret = regmap_read(vreg->regmap, lab_reg, &lab_val);469		if (ret) {470			vreg->fatal_count++;471			goto reschedule;472		}473 474		ret = regmap_read(vreg->regmap, ibb_reg, &ibb_val);475		if (ret) {476			vreg->fatal_count++;477			goto reschedule;478		}479		val = lab_val & ibb_val;480 481		if (!(val & LABIBB_CONTROL_ENABLE)) {482			pbs_cut = true;483			break;484		}485		usleep_range(5000, 6000);486	}487	if (pbs_cut)488		goto reschedule;489 490 491	/*492	 * If we have reached this point, we either have successfully493	 * recovered from the SC condition or we had a spurious SC IRQ,494	 * which means that we can re-enable the regulators, if they495	 * have ever been disabled by the PBS.496	 */497	ret = ops->enable(vreg->rdev);498	if (ret)499		goto reschedule;500 501	/* Everything went fine: reset the OCP count! */502	vreg->sc_count = 0;503	enable_irq(vreg->sc_irq);504	return;505 506reschedule:507	/*508	 * Now that we have done basic handling of the short-circuit,509	 * reschedule this worker in the regular system workqueue, as510	 * taking action is not truly urgent anymore.511	 */512	vreg->sc_count++;513	mod_delayed_work(system_wq, &vreg->sc_recovery_work,514			 msecs_to_jiffies(SC_RECOVERY_INTERVAL_MS));515}516 517/**518 * qcom_labibb_sc_isr - Interrupt routine for Short Circuit Protection519 * @irq:  Interrupt number520 * @chip: Main driver structure521 *522 * Short Circuit Protection (SCP) will signal to the client driver523 * that a regulation-out event has happened and then will schedule524 * a recovery worker.525 *526 * The LAB and IBB regulators will be automatically disabled by the527 * Portable Batch System (PBS) and they will be enabled again by528 * the worker function if the hardware stops signaling the short529 * circuit event.530 *531 * Returns: IRQ_HANDLED for success or IRQ_NONE for failure.532 */533static irqreturn_t qcom_labibb_sc_isr(int irq, void *chip)534{535	struct labibb_regulator *vreg = chip;536 537	if (vreg->sc_count > LABIBB_MAX_SC_COUNT)538		return IRQ_NONE;539 540	/* Warn the user for short circuit */541	dev_warn(vreg->dev, "Short-Circuit interrupt fired!\n");542 543	/*544	 * Disable the interrupt temporarily, or it will fire continuously;545	 * we will re-enable it in the recovery worker function.546	 */547	disable_irq_nosync(irq);548 549	/* Signal out of regulation event to drivers */550	regulator_notifier_call_chain(vreg->rdev,551				      REGULATOR_EVENT_REGULATION_OUT, NULL);552 553	/* Schedule the short-circuit handling as high-priority work */554	mod_delayed_work(system_highpri_wq, &vreg->sc_recovery_work,555			 msecs_to_jiffies(SC_RECOVERY_INTERVAL_MS));556	return IRQ_HANDLED;557}558 559 560static int qcom_labibb_set_current_limit(struct regulator_dev *rdev,561					 int min_uA, int max_uA)562{563	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);564	struct regulator_desc *desc = &vreg->desc;565	struct labibb_current_limits *lim = &vreg->uA_limits;566	u32 mask, val;567	int i, ret, sel = -1;568 569	if (min_uA < lim->uA_min || max_uA < lim->uA_min)570		return -EINVAL;571 572	for (i = 0; i < desc->n_current_limits; i++) {573		int uA_limit = (lim->uA_step * i) + lim->uA_min;574 575		if (max_uA >= uA_limit && min_uA <= uA_limit)576			sel = i;577	}578	if (sel < 0)579		return -EINVAL;580 581	/* Current limit setting needs secure access */582	ret = regmap_write(vreg->regmap, vreg->base + REG_LABIBB_SEC_ACCESS,583			   LABIBB_SEC_UNLOCK_CODE);584	if (ret)585		return ret;586 587	mask = desc->csel_mask | lim->ovr_val;588	mask |= LABIBB_CURRENT_LIMIT_EN;589	val = (u32)sel | lim->ovr_val;590	val |= LABIBB_CURRENT_LIMIT_EN;591 592	return regmap_update_bits(vreg->regmap, desc->csel_reg, mask, val);593}594 595static int qcom_labibb_get_current_limit(struct regulator_dev *rdev)596{597	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);598	struct regulator_desc *desc = &vreg->desc;599	struct labibb_current_limits *lim = &vreg->uA_limits;600	unsigned int cur_step;601	int ret;602 603	ret = regmap_read(vreg->regmap, desc->csel_reg, &cur_step);604	if (ret)605		return ret;606	cur_step &= desc->csel_mask;607 608	return (cur_step * lim->uA_step) + lim->uA_min;609}610 611static int qcom_labibb_set_soft_start(struct regulator_dev *rdev)612{613	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);614	u32 val = 0;615 616	if (vreg->type == QCOM_IBB_TYPE)617		val = vreg->dischg_sel;618	else619		val = vreg->soft_start_sel;620 621	return regmap_write(rdev->regmap, rdev->desc->soft_start_reg, val);622}623 624static int qcom_labibb_get_table_sel(const int *table, int sz, u32 value)625{626	int i;627 628	for (i = 0; i < sz; i++)629		if (table[i] == value)630			return i;631	return -EINVAL;632}633 634/* IBB discharge resistor values in KOhms */635static const int dischg_resistor_values[] = { 300, 64, 32, 16 };636 637/* Soft start time in microseconds */638static const int soft_start_values[] = { 200, 400, 600, 800 };639 640static int qcom_labibb_of_parse_cb(struct device_node *np,641				   const struct regulator_desc *desc,642				   struct regulator_config *config)643{644	struct labibb_regulator *vreg = config->driver_data;645	u32 dischg_kohms, soft_start_time;646	int ret;647 648	ret = of_property_read_u32(np, "qcom,discharge-resistor-kohms",649				       &dischg_kohms);650	if (ret)651		dischg_kohms = 300;652 653	ret = qcom_labibb_get_table_sel(dischg_resistor_values,654					ARRAY_SIZE(dischg_resistor_values),655					dischg_kohms);656	if (ret < 0)657		return ret;658	vreg->dischg_sel = (u8)ret;659 660	ret = of_property_read_u32(np, "qcom,soft-start-us",661				   &soft_start_time);662	if (ret)663		soft_start_time = 200;664 665	ret = qcom_labibb_get_table_sel(soft_start_values,666					ARRAY_SIZE(soft_start_values),667					soft_start_time);668	if (ret < 0)669		return ret;670	vreg->soft_start_sel = (u8)ret;671 672	return 0;673}674 675static const struct regulator_ops qcom_labibb_ops = {676	.enable			= regulator_enable_regmap,677	.disable		= regulator_disable_regmap,678	.is_enabled		= regulator_is_enabled_regmap,679	.set_voltage_sel	= regulator_set_voltage_sel_regmap,680	.get_voltage_sel	= regulator_get_voltage_sel_regmap,681	.list_voltage		= regulator_list_voltage_linear,682	.map_voltage		= regulator_map_voltage_linear,683	.set_active_discharge	= regulator_set_active_discharge_regmap,684	.set_pull_down		= regulator_set_pull_down_regmap,685	.set_current_limit	= qcom_labibb_set_current_limit,686	.get_current_limit	= qcom_labibb_get_current_limit,687	.set_soft_start		= qcom_labibb_set_soft_start,688	.set_over_current_protection = qcom_labibb_set_ocp,689};690 691static const struct regulator_desc pmi8998_lab_desc = {692	.enable_mask		= LAB_ENABLE_CTL_MASK,693	.enable_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_ENABLE_CTL),694	.enable_val		= LABIBB_CONTROL_ENABLE,695	.enable_time		= LAB_ENABLE_TIME,696	.poll_enabled_time	= LABIBB_POLL_ENABLED_TIME,697	.soft_start_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_SOFT_START_CTL),698	.pull_down_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_PD_CTL),699	.pull_down_mask		= LAB_PD_CTL_MASK,700	.pull_down_val_on	= LAB_PD_CTL_STRONG_PULL,701	.vsel_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_VOLTAGE),702	.vsel_mask		= LAB_VOLTAGE_SET_MASK,703	.apply_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_VOLTAGE),704	.apply_bit		= LABIBB_VOLTAGE_OVERRIDE_EN,705	.csel_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_CURRENT_LIMIT),706	.csel_mask		= LAB_CURRENT_LIMIT_MASK,707	.n_current_limits	= 8,708	.off_on_delay		= LABIBB_OFF_ON_DELAY,709	.owner			= THIS_MODULE,710	.type			= REGULATOR_VOLTAGE,711	.min_uV			= 4600000,712	.uV_step		= 100000,713	.n_voltages		= 16,714	.ops			= &qcom_labibb_ops,715	.of_parse_cb		= qcom_labibb_of_parse_cb,716};717 718static const struct regulator_desc pmi8998_ibb_desc = {719	.enable_mask		= IBB_ENABLE_CTL_MASK,720	.enable_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_ENABLE_CTL),721	.enable_val		= LABIBB_CONTROL_ENABLE,722	.enable_time		= IBB_ENABLE_TIME,723	.poll_enabled_time	= LABIBB_POLL_ENABLED_TIME,724	.soft_start_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_SOFT_START_CTL),725	.active_discharge_off	= 0,726	.active_discharge_on	= IBB_CTL_1_DISCHARGE_EN,727	.active_discharge_mask	= IBB_CTL_1_DISCHARGE_EN,728	.active_discharge_reg	= (PMI8998_IBB_REG_BASE + REG_IBB_PWRUP_PWRDN_CTL_1),729	.pull_down_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_PD_CTL),730	.pull_down_mask		= IBB_PD_CTL_MASK,731	.pull_down_val_on	= IBB_PD_CTL_HALF_STRENGTH | IBB_PD_CTL_EN,732	.vsel_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_VOLTAGE),733	.vsel_mask		= IBB_VOLTAGE_SET_MASK,734	.apply_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_VOLTAGE),735	.apply_bit		= LABIBB_VOLTAGE_OVERRIDE_EN,736	.csel_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_CURRENT_LIMIT),737	.csel_mask		= IBB_CURRENT_LIMIT_MASK,738	.n_current_limits	= 32,739	.off_on_delay		= LABIBB_OFF_ON_DELAY,740	.owner			= THIS_MODULE,741	.type			= REGULATOR_VOLTAGE,742	.min_uV			= 1400000,743	.uV_step		= 100000,744	.n_voltages		= 64,745	.ops			= &qcom_labibb_ops,746	.of_parse_cb		= qcom_labibb_of_parse_cb,747};748 749static const struct labibb_regulator_data pmi8998_labibb_data[] = {750	{"lab", QCOM_LAB_TYPE, PMI8998_LAB_REG_BASE, &pmi8998_lab_desc},751	{"ibb", QCOM_IBB_TYPE, PMI8998_IBB_REG_BASE, &pmi8998_ibb_desc},752	{ },753};754 755static const struct of_device_id qcom_labibb_match[] = {756	{ .compatible = "qcom,pmi8998-lab-ibb", .data = &pmi8998_labibb_data},757	{ },758};759MODULE_DEVICE_TABLE(of, qcom_labibb_match);760 761static int qcom_labibb_regulator_probe(struct platform_device *pdev)762{763	struct labibb_regulator *vreg;764	struct device *dev = &pdev->dev;765	struct regulator_config cfg = {};766	struct device_node *reg_node;767	const struct labibb_regulator_data *reg_data;768	struct regmap *reg_regmap;769	unsigned int type;770	int ret;771 772	reg_regmap = dev_get_regmap(pdev->dev.parent, NULL);773	if (!reg_regmap) {774		dev_err(&pdev->dev, "Couldn't get parent's regmap\n");775		return -ENODEV;776	}777 778	reg_data = device_get_match_data(&pdev->dev);779	if (!reg_data)780		return -ENODEV;781 782	for (; reg_data->name; reg_data++) {783		char *sc_irq_name;784		int irq = 0;785 786		/* Validate if the type of regulator is indeed787		 * what's mentioned in DT.788		 */789		ret = regmap_read(reg_regmap, reg_data->base + REG_PERPH_TYPE,790				  &type);791		if (ret < 0) {792			dev_err(dev,793				"Peripheral type read failed ret=%d\n",794				ret);795			return -EINVAL;796		}797 798		if (WARN_ON((type != QCOM_LAB_TYPE) && (type != QCOM_IBB_TYPE)) ||799		    WARN_ON(type != reg_data->type))800			return -EINVAL;801 802		vreg  = devm_kzalloc(&pdev->dev, sizeof(*vreg),803					   GFP_KERNEL);804		if (!vreg)805			return -ENOMEM;806 807		sc_irq_name = devm_kasprintf(dev, GFP_KERNEL,808					     "%s-short-circuit",809					     reg_data->name);810		if (!sc_irq_name)811			return -ENOMEM;812 813		reg_node = of_get_child_by_name(pdev->dev.of_node,814						reg_data->name);815		if (!reg_node)816			return -EINVAL;817 818		/* The Short Circuit interrupt is critical */819		irq = of_irq_get_byname(reg_node, "sc-err");820		if (irq <= 0) {821			if (irq == 0)822				irq = -EINVAL;823 824			of_node_put(reg_node);825			return dev_err_probe(vreg->dev, irq,826					     "Short-circuit irq not found.\n");827		}828		vreg->sc_irq = irq;829 830		/* OverCurrent Protection IRQ is optional */831		irq = of_irq_get_byname(reg_node, "ocp");832		vreg->ocp_irq = irq;833		vreg->ocp_irq_count = 0;834		of_node_put(reg_node);835 836		vreg->regmap = reg_regmap;837		vreg->dev = dev;838		vreg->base = reg_data->base;839		vreg->type = reg_data->type;840		INIT_DELAYED_WORK(&vreg->sc_recovery_work,841				  qcom_labibb_sc_recovery_worker);842 843		if (vreg->ocp_irq > 0)844			INIT_DELAYED_WORK(&vreg->ocp_recovery_work,845					  qcom_labibb_ocp_recovery_worker);846 847		switch (vreg->type) {848		case QCOM_LAB_TYPE:849			/* LAB Limits: 200-1600mA */850			vreg->uA_limits.uA_min  = 200000;851			vreg->uA_limits.uA_step = 200000;852			vreg->uA_limits.ovr_val = LAB_CURRENT_LIMIT_OVERRIDE_EN;853			break;854		case QCOM_IBB_TYPE:855			/* IBB Limits: 0-1550mA */856			vreg->uA_limits.uA_min  = 0;857			vreg->uA_limits.uA_step = 50000;858			vreg->uA_limits.ovr_val = 0; /* No override bit */859			break;860		default:861			return -EINVAL;862		}863 864		memcpy(&vreg->desc, reg_data->desc, sizeof(vreg->desc));865		vreg->desc.of_match = reg_data->name;866		vreg->desc.name = reg_data->name;867 868		cfg.dev = vreg->dev;869		cfg.driver_data = vreg;870		cfg.regmap = vreg->regmap;871 872		vreg->rdev = devm_regulator_register(vreg->dev, &vreg->desc,873							&cfg);874 875		if (IS_ERR(vreg->rdev)) {876			dev_err(dev, "qcom_labibb: error registering %s : %d\n",877					reg_data->name, ret);878			return PTR_ERR(vreg->rdev);879		}880 881		ret = devm_request_threaded_irq(vreg->dev, vreg->sc_irq, NULL,882						qcom_labibb_sc_isr,883						IRQF_ONESHOT |884						IRQF_TRIGGER_RISING,885						sc_irq_name, vreg);886		if (ret)887			return ret;888	}889 890	return 0;891}892 893static struct platform_driver qcom_labibb_regulator_driver = {894	.driver	= {895		.name = "qcom-lab-ibb-regulator",896		.probe_type = PROBE_PREFER_ASYNCHRONOUS,897		.of_match_table	= qcom_labibb_match,898	},899	.probe = qcom_labibb_regulator_probe,900};901module_platform_driver(qcom_labibb_regulator_driver);902 903MODULE_DESCRIPTION("Qualcomm labibb driver");904MODULE_AUTHOR("Nisha Kumari <nishakumari@codeaurora.org>");905MODULE_AUTHOR("Sumit Semwal <sumit.semwal@linaro.org>");906MODULE_LICENSE("GPL v2");907