Skip to content

Commit b250c20

Browse files
dlechbroonie
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 <[email protected]> Link: https://lore.kernel.org/r/20240429-regulator-get-enable-get-votlage-v2-1-b1f11ab766c1@baylibre.com Signed-off-by: Mark Brown <[email protected]>
1 parent fec50db commit b250c20

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
@@ -433,6 +433,7 @@ REGULATOR
433433
devm_regulator_bulk_put()
434434
devm_regulator_get()
435435
devm_regulator_get_enable()
436+
devm_regulator_get_enable_read_voltage()
436437
devm_regulator_get_enable_optional()
437438
devm_regulator_get_exclusive()
438439
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
@@ -164,6 +164,7 @@ struct regulator *__must_check devm_regulator_get_optional(struct device *dev,
164164
const char *id);
165165
int devm_regulator_get_enable(struct device *dev, const char *id);
166166
int devm_regulator_get_enable_optional(struct device *dev, const char *id);
167+
int devm_regulator_get_enable_read_voltage(struct device *dev, const char *id);
167168
void regulator_put(struct regulator *regulator);
168169
void devm_regulator_put(struct regulator *regulator);
169170

@@ -329,6 +330,12 @@ static inline int devm_regulator_get_enable_optional(struct device *dev,
329330
return -ENODEV;
330331
}
331332

333+
static inline int devm_regulator_get_enable_read_voltage(struct device *dev,
334+
const char *id)
335+
{
336+
return -ENODEV;
337+
}
338+
332339
static inline struct regulator *__must_check
333340
regulator_get_optional(struct device *dev, const char *id)
334341
{

0 commit comments

Comments
 (0)