Skip to content

Commit 5405107

Browse files
dlechnunojsa
authored andcommitted
regulator: devres: add API for reference voltage supplies
A common use case for regulators is to supply a reference voltage to an analog input or output device. This adds a new devres API to get, enable, and get the voltage in a single call. This allows eliminating boilerplate code in drivers that use reference supplies in this way. Signed-off-by: David Lechner <dlechner@baylibre.com> Link: https://lore.kernel.org/r/20240429-regulator-get-enable-get-votlage-v2-1-b1f11ab766c1@baylibre.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 725cb47 commit 5405107

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

Documentation/driver-api/driver-model/devres.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ REGULATOR
413413
devm_regulator_bulk_put()
414414
devm_regulator_get()
415415
devm_regulator_get_enable()
416+
devm_regulator_get_enable_read_voltage()
416417
devm_regulator_get_enable_optional()
417418
devm_regulator_get_exclusive()
418419
devm_regulator_get_optional()

drivers/regulator/devres.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,65 @@ struct regulator *devm_regulator_get_optional(struct device *dev,
145145
}
146146
EXPORT_SYMBOL_GPL(devm_regulator_get_optional);
147147

148+
/**
149+
* devm_regulator_get_enable_read_voltage - Resource managed regulator get and
150+
* enable that returns the voltage
151+
* @dev: device to supply
152+
* @id: supply name or regulator ID.
153+
*
154+
* Get and enable regulator for duration of the device life-time.
155+
* regulator_disable() and regulator_put() are automatically called on driver
156+
* detach. See regulator_get_optional(), regulator_enable(), and
157+
* regulator_get_voltage() for more information.
158+
*
159+
* This is a convenience function for supplies that provide a reference voltage
160+
* where the consumer driver just needs to know the voltage and keep the
161+
* regulator enabled.
162+
*
163+
* In cases where the supply is not strictly required, callers can check for
164+
* -ENODEV error and handle it accordingly.
165+
*
166+
* Returns: voltage in microvolts on success, or an error code on failure.
167+
*/
168+
int devm_regulator_get_enable_read_voltage(struct device *dev, const char *id)
169+
{
170+
struct regulator *r;
171+
int ret;
172+
173+
/*
174+
* Since we need a real voltage, we use devm_regulator_get_optional()
175+
* rather than getting a dummy regulator with devm_regulator_get() and
176+
* then letting regulator_get_voltage() fail with -EINVAL. This way, the
177+
* caller can handle the -ENODEV error code if needed instead of the
178+
* ambiguous -EINVAL.
179+
*/
180+
r = devm_regulator_get_optional(dev, id);
181+
if (IS_ERR(r))
182+
return PTR_ERR(r);
183+
184+
ret = regulator_enable(r);
185+
if (ret)
186+
goto err_regulator_put;
187+
188+
ret = devm_add_action_or_reset(dev, regulator_action_disable, r);
189+
if (ret)
190+
goto err_regulator_put;
191+
192+
ret = regulator_get_voltage(r);
193+
if (ret < 0)
194+
goto err_release_action;
195+
196+
return 0;
197+
198+
err_release_action:
199+
devm_release_action(dev, regulator_action_disable, r);
200+
err_regulator_put:
201+
devm_regulator_put(r);
202+
203+
return ret;
204+
}
205+
EXPORT_SYMBOL_GPL(devm_regulator_get_enable_read_voltage);
206+
148207
static int devm_regulator_match(struct device *dev, void *res, void *data)
149208
{
150209
struct regulator **r = res;

include/linux/regulator/consumer.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ struct regulator *__must_check devm_regulator_get_optional(struct device *dev,
209209
const char *id);
210210
int devm_regulator_get_enable(struct device *dev, const char *id);
211211
int devm_regulator_get_enable_optional(struct device *dev, const char *id);
212+
int devm_regulator_get_enable_read_voltage(struct device *dev, const char *id);
212213
void regulator_put(struct regulator *regulator);
213214
void devm_regulator_put(struct regulator *regulator);
214215

@@ -370,6 +371,12 @@ static inline int devm_regulator_get_enable_optional(struct device *dev,
370371
return -ENODEV;
371372
}
372373

374+
static inline int devm_regulator_get_enable_read_voltage(struct device *dev,
375+
const char *id)
376+
{
377+
return -ENODEV;
378+
}
379+
373380
static inline struct regulator *__must_check
374381
regulator_get_optional(struct device *dev, const char *id)
375382
{

0 commit comments

Comments
 (0)