|
18 | 18 |
|
19 | 19 | use crate::{ |
20 | 20 | bindings, |
21 | | - device::Device, |
| 21 | + device::{Bound, Device}, |
22 | 22 | error::{from_err_ptr, to_result, Result}, |
23 | 23 | prelude::*, |
24 | 24 | }; |
@@ -69,6 +69,41 @@ pub struct Error<State: RegulatorState> { |
69 | 69 | /// The regulator that caused the error, so that the operation may be retried. |
70 | 70 | pub regulator: Regulator<State>, |
71 | 71 | } |
| 72 | +/// Obtains and enables a [`devres`]-managed regulator for a device. |
| 73 | +/// |
| 74 | +/// This calls [`regulator_disable()`] and [`regulator_put()`] automatically on |
| 75 | +/// driver detach. |
| 76 | +/// |
| 77 | +/// This API is identical to `devm_regulator_get_enable()`, and should be |
| 78 | +/// preferred over the [`Regulator<T: RegulatorState>`] API if the caller only |
| 79 | +/// cares about the regulator being enabled. |
| 80 | +/// |
| 81 | +/// [`devres`]: https://docs.kernel.org/driver-api/driver-model/devres.html |
| 82 | +/// [`regulator_disable()`]: https://docs.kernel.org/driver-api/regulator.html#c.regulator_disable |
| 83 | +/// [`regulator_put()`]: https://docs.kernel.org/driver-api/regulator.html#c.regulator_put |
| 84 | +pub fn devm_enable(dev: &Device<Bound>, name: &CStr) -> Result { |
| 85 | + // SAFETY: `dev` is a valid and bound device, while `name` is a valid C |
| 86 | + // string. |
| 87 | + to_result(unsafe { bindings::devm_regulator_get_enable(dev.as_raw(), name.as_ptr()) }) |
| 88 | +} |
| 89 | + |
| 90 | +/// Same as [`devm_enable`], but calls `devm_regulator_get_enable_optional` |
| 91 | +/// instead. |
| 92 | +/// |
| 93 | +/// This obtains and enables a [`devres`]-managed regulator for a device, but |
| 94 | +/// does not print a message nor provides a dummy if the regulator is not found. |
| 95 | +/// |
| 96 | +/// This calls [`regulator_disable()`] and [`regulator_put()`] automatically on |
| 97 | +/// driver detach. |
| 98 | +/// |
| 99 | +/// [`devres`]: https://docs.kernel.org/driver-api/driver-model/devres.html |
| 100 | +/// [`regulator_disable()`]: https://docs.kernel.org/driver-api/regulator.html#c.regulator_disable |
| 101 | +/// [`regulator_put()`]: https://docs.kernel.org/driver-api/regulator.html#c.regulator_put |
| 102 | +pub fn devm_enable_optional(dev: &Device<Bound>, name: &CStr) -> Result { |
| 103 | + // SAFETY: `dev` is a valid and bound device, while `name` is a valid C |
| 104 | + // string. |
| 105 | + to_result(unsafe { bindings::devm_regulator_get_enable_optional(dev.as_raw(), name.as_ptr()) }) |
| 106 | +} |
72 | 107 |
|
73 | 108 | /// A `struct regulator` abstraction. |
74 | 109 | /// |
@@ -146,6 +181,29 @@ pub struct Error<State: RegulatorState> { |
146 | 181 | /// } |
147 | 182 | /// ``` |
148 | 183 | /// |
| 184 | +/// If a driver only cares about the regulator being on for as long it is bound |
| 185 | +/// to a device, then it should use [`devm_enable`] or [`devm_enable_optional`]. |
| 186 | +/// This should be the default use-case unless more fine-grained control over |
| 187 | +/// the regulator's state is required. |
| 188 | +/// |
| 189 | +/// [`devm_enable`]: crate::regulator::devm_enable |
| 190 | +/// [`devm_optional`]: crate::regulator::devm_enable_optional |
| 191 | +/// |
| 192 | +/// ``` |
| 193 | +/// # use kernel::prelude::*; |
| 194 | +/// # use kernel::c_str; |
| 195 | +/// # use kernel::device::{Bound, Device}; |
| 196 | +/// # use kernel::regulator; |
| 197 | +/// fn enable(dev: &Device<Bound>) -> Result { |
| 198 | +/// // Obtain a reference to a (fictitious) regulator and enable it. This |
| 199 | +/// // call only returns whether the operation succeeded. |
| 200 | +/// regulator::devm_enable(dev, c_str!("vcc"))?; |
| 201 | +/// |
| 202 | +/// // The regulator will be disabled and put when `dev` is unbound. |
| 203 | +/// Ok(()) |
| 204 | +/// } |
| 205 | +/// ``` |
| 206 | +/// |
149 | 207 | /// ## Disabling a regulator |
150 | 208 | /// |
151 | 209 | /// ``` |
|
0 commit comments