forked from mirrors/linux
		
	regulator: Add regmap helper for ramp-delay setting
Quite a few regulator ICs do support setting ramp-delay by writing a value matching the delay to a ramp-delay register. Provide a simple helper for table-based delay setting. Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> Link: https://lore.kernel.org/r/f101f1db564cf32cb58719c77af0b00d7236bb89.1617020713.git.matti.vaittinen@fi.rohmeurope.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
		
							parent
							
								
									e3baacf542
								
							
						
					
					
						commit
						fb8fee9efd
					
				
					 2 changed files with 70 additions and 0 deletions
				
			
		|  | @ -901,3 +901,68 @@ bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2) | |||
| 	return reg1->rdev == reg2->rdev; | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(regulator_is_equal); | ||||
| 
 | ||||
| static int find_closest_bigger(unsigned int target, const unsigned int *table, | ||||
| 			       unsigned int num_sel, unsigned int *sel) | ||||
| { | ||||
| 	unsigned int s, tmp, max, maxsel = 0; | ||||
| 	bool found = false; | ||||
| 
 | ||||
| 	max = table[0]; | ||||
| 
 | ||||
| 	for (s = 0; s < num_sel; s++) { | ||||
| 		if (table[s] > max) { | ||||
| 			max = table[s]; | ||||
| 			maxsel = s; | ||||
| 		} | ||||
| 		if (table[s] >= target) { | ||||
| 			if (!found || table[s] - target < tmp - target) { | ||||
| 				tmp = table[s]; | ||||
| 				*sel = s; | ||||
| 				found = true; | ||||
| 				if (tmp == target) | ||||
| 					break; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (!found) { | ||||
| 		*sel = maxsel; | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * regulator_set_ramp_delay_regmap - set_ramp_delay() helper | ||||
|  * | ||||
|  * @rdev: regulator to operate on | ||||
|  * | ||||
|  * Regulators that use regmap for their register I/O can set the ramp_reg | ||||
|  * and ramp_mask fields in their descriptor and then use this as their | ||||
|  * set_ramp_delay operation, saving some code. | ||||
|  */ | ||||
| int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay) | ||||
| { | ||||
| 	int ret; | ||||
| 	unsigned int sel; | ||||
| 
 | ||||
| 	if (!rdev->desc->n_ramp_values) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	ret = find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table, | ||||
| 				  rdev->desc->n_ramp_values, &sel); | ||||
| 
 | ||||
| 	if (ret) { | ||||
| 		dev_warn(rdev_get_dev(rdev), | ||||
| 			 "Can't set ramp-delay %u, setting %u\n", ramp_delay, | ||||
| 			 rdev->desc->ramp_delay_table[sel]); | ||||
| 	} | ||||
| 
 | ||||
| 	sel <<= ffs(rdev->desc->ramp_mask) - 1; | ||||
| 
 | ||||
| 	return regmap_update_bits(rdev->regmap, rdev->desc->ramp_reg, | ||||
| 				  rdev->desc->ramp_mask, sel); | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(regulator_set_ramp_delay_regmap); | ||||
|  |  | |||
|  | @ -373,6 +373,10 @@ struct regulator_desc { | |||
| 	unsigned int pull_down_reg; | ||||
| 	unsigned int pull_down_mask; | ||||
| 	unsigned int pull_down_val_on; | ||||
| 	unsigned int ramp_reg; | ||||
| 	unsigned int ramp_mask; | ||||
| 	const unsigned int *ramp_delay_table; | ||||
| 	unsigned int n_ramp_values; | ||||
| 
 | ||||
| 	unsigned int enable_time; | ||||
| 
 | ||||
|  | @ -535,6 +539,7 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev, | |||
| 				       int min_uA, int max_uA); | ||||
| int regulator_get_current_limit_regmap(struct regulator_dev *rdev); | ||||
| void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data); | ||||
| int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay); | ||||
| 
 | ||||
| /*
 | ||||
|  * Helper functions intended to be used by regulator drivers prior registering | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Matti Vaittinen
						Matti Vaittinen