| 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | |
| 3 | //! Regulator abstractions, providing a standard kernel interface to control |
| 4 | //! voltage and current regulators. |
| 5 | //! |
| 6 | //! The intention is to allow systems to dynamically control regulator power |
| 7 | //! output in order to save power and prolong battery life. This applies to both |
| 8 | //! voltage regulators (where voltage output is controllable) and current sinks |
| 9 | //! (where current limit is controllable). |
| 10 | //! |
| 11 | //! C header: [`include/linux/regulator/consumer.h`](srctree/include/linux/regulator/consumer.h) |
| 12 | //! |
| 13 | //! Regulators are modeled in Rust with a collection of states. Each state may |
| 14 | //! enforce a given invariant, and they may convert between each other where applicable. |
| 15 | //! |
| 16 | //! See [Voltage and current regulator API](https://docs.kernel.org/driver-api/regulator.html) |
| 17 | //! for more information. |
| 18 | |
| 19 | use crate:: |
| 20 | bindings, |
| 21 | , |
| 22 | , |
| 23 | *, |
| 24 | ; |
| 25 | |
| 26 | use |
| 27 | PhantomData, |
| 28 | ManuallyDrop, // |
| 29 | ; |
| 30 | |
| 31 | |
| 32 | |
| 33 | |
| 34 | |
| 35 | |
| 36 | |
| 37 | |
| 38 | /// A trait representing the different states a [`Regulator`] can be in. |
| 39 | |
| 40 | /// Whether the regulator should be disabled when dropped. |
| 41 | const DISABLE_ON_DROP: bool; |
| 42 | |
| 43 | |
| 44 | /// A state where the [`Regulator`] is known to be enabled. |
| 45 | /// |
| 46 | /// The `enable` reference count held by this state is decremented when it is |
| 47 | /// dropped. |
| 48 | ; |
| 49 | |
| 50 | /// A state where this [`Regulator`] handle has not specifically asked for the |
| 51 | /// underlying regulator to be enabled. This means that this reference does not |
| 52 | /// own an `enable` reference count, but the regulator may still be on. |
| 53 | ; |
| 54 | |
| 55 | |
| 56 | const DISABLE_ON_DROP: bool = true; |
| 57 | |
| 58 | |
| 59 | |
| 60 | const DISABLE_ON_DROP: bool = false; |
| 61 | |
| 62 | |
| 63 | /// A trait that abstracts the ability to check if a [`Regulator`] is enabled. |
| 64 | |
| 65 | |
| 66 | |
| 67 | /// An error that can occur when trying to convert a [`Regulator`] between states. |
| 68 | |
| 69 | /// The error that occurred. |
| 70 | pub error: Error, |
| 71 | |
| 72 | /// The regulator that caused the error, so that the operation may be retried. |
| 73 | pub regulator: , |
| 74 | |
| 75 | /// Obtains and enables a [`devres`]-managed regulator for a device. |
| 76 | /// |
| 77 | /// This calls [`regulator_disable()`] and [`regulator_put()`] automatically on |
| 78 | /// driver detach. |
| 79 | /// |
| 80 | /// This API is identical to `devm_regulator_get_enable()`, and should be |
| 81 | /// preferred over the [`Regulator<T: RegulatorState>`] API if the caller only |
| 82 | /// cares about the regulator being enabled. |
| 83 | /// |
| 84 | /// [`devres`]: https://docs.kernel.org/driver-api/driver-model/devres.html |
| 85 | /// [`regulator_disable()`]: https://docs.kernel.org/driver-api/regulator.html#c.regulator_disable |
| 86 | /// [`regulator_put()`]: https://docs.kernel.org/driver-api/regulator.html#c.regulator_put |
| 87 | |
| 88 | // SAFETY: `dev` is a valid and bound device, while `name` is a valid C |
| 89 | // string. |
| 90 | to_result |
| 91 | |
| 92 | |
| 93 | /// Same as [`devm_enable`], but calls `devm_regulator_get_enable_optional` |
| 94 | /// instead. |
| 95 | /// |
| 96 | /// This obtains and enables a [`devres`]-managed regulator for a device, but |
| 97 | /// does not print a message nor provides a dummy if the regulator is not found. |
| 98 | /// |
| 99 | /// This calls [`regulator_disable()`] and [`regulator_put()`] automatically on |
| 100 | /// driver detach. |
| 101 | /// |
| 102 | /// [`devres`]: https://docs.kernel.org/driver-api/driver-model/devres.html |
| 103 | /// [`regulator_disable()`]: https://docs.kernel.org/driver-api/regulator.html#c.regulator_disable |
| 104 | /// [`regulator_put()`]: https://docs.kernel.org/driver-api/regulator.html#c.regulator_put |
| 105 | |
| 106 | // SAFETY: `dev` is a valid and bound device, while `name` is a valid C |
| 107 | // string. |
| 108 | to_result |
| 109 | devm_regulator_get_enable_optional |
| 110 | |
| 111 | |
| 112 | |
| 113 | /// A `struct regulator` abstraction. |
| 114 | /// |
| 115 | /// # Examples |
| 116 | /// |
| 117 | /// ## Enabling a regulator |
| 118 | /// |
| 119 | /// This example uses [`Regulator<Enabled>`], which is suitable for drivers that |
| 120 | /// enable a regulator at probe time and leave them on until the device is |
| 121 | /// removed or otherwise shutdown. |
| 122 | /// |
| 123 | /// These users can store [`Regulator<Enabled>`] directly in their driver's |
| 124 | /// private data struct. |
| 125 | /// |
| 126 | /// ``` |
| 127 | /// # use kernel::prelude::*; |
| 128 | /// # use kernel::device::Device; |
| 129 | /// # use kernel::regulator::{Voltage, Regulator, Disabled, Enabled}; |
| 130 | /// fn enable(dev: &Device, min_voltage: Voltage, max_voltage: Voltage) -> Result { |
| 131 | /// // Obtain a reference to a (fictitious) regulator. |
| 132 | /// let regulator: Regulator<Disabled> = Regulator::<Disabled>::get(dev, c"vcc")?; |
| 133 | /// |
| 134 | /// // The voltage can be set before enabling the regulator if needed, e.g.: |
| 135 | /// regulator.set_voltage(min_voltage, max_voltage)?; |
| 136 | /// |
| 137 | /// // The same applies for `get_voltage()`, i.e.: |
| 138 | /// let voltage: Voltage = regulator.get_voltage()?; |
| 139 | /// |
| 140 | /// // Enables the regulator, consuming the previous value. |
| 141 | /// // |
| 142 | /// // From now on, the regulator is known to be enabled because of the type |
| 143 | /// // `Enabled`. |
| 144 | /// // |
| 145 | /// // If this operation fails, the `Error` will contain the regulator |
| 146 | /// // reference, so that the operation may be retried. |
| 147 | /// let regulator: Regulator<Enabled> = |
| 148 | /// regulator.try_into_enabled().map_err(|error| error.error)?; |
| 149 | /// |
| 150 | /// // The voltage can also be set after enabling the regulator, e.g.: |
| 151 | /// regulator.set_voltage(min_voltage, max_voltage)?; |
| 152 | /// |
| 153 | /// // The same applies for `get_voltage()`, i.e.: |
| 154 | /// let voltage: Voltage = regulator.get_voltage()?; |
| 155 | /// |
| 156 | /// // Dropping an enabled regulator will disable it. The refcount will be |
| 157 | /// // decremented. |
| 158 | /// drop(regulator); |
| 159 | /// |
| 160 | /// // ... |
| 161 | /// |
| 162 | /// Ok(()) |
| 163 | /// } |
| 164 | /// ``` |
| 165 | /// |
| 166 | /// A more concise shortcut is available for enabling a regulator. This is |
| 167 | /// equivalent to `regulator_get_enable()`: |
| 168 | /// |
| 169 | /// ``` |
| 170 | /// # use kernel::prelude::*; |
| 171 | /// # use kernel::device::Device; |
| 172 | /// # use kernel::regulator::{Voltage, Regulator, Enabled}; |
| 173 | /// fn enable(dev: &Device) -> Result { |
| 174 | /// // Obtain a reference to a (fictitious) regulator and enable it. |
| 175 | /// let regulator: Regulator<Enabled> = Regulator::<Enabled>::get(dev, c"vcc")?; |
| 176 | /// |
| 177 | /// // Dropping an enabled regulator will disable it. The refcount will be |
| 178 | /// // decremented. |
| 179 | /// drop(regulator); |
| 180 | /// |
| 181 | /// // ... |
| 182 | /// |
| 183 | /// Ok(()) |
| 184 | /// } |
| 185 | /// ``` |
| 186 | /// |
| 187 | /// If a driver only cares about the regulator being on for as long it is bound |
| 188 | /// to a device, then it should use [`devm_enable`] or [`devm_enable_optional`]. |
| 189 | /// This should be the default use-case unless more fine-grained control over |
| 190 | /// the regulator's state is required. |
| 191 | /// |
| 192 | /// [`devm_enable`]: crate::regulator::devm_enable |
| 193 | /// [`devm_optional`]: crate::regulator::devm_enable_optional |
| 194 | /// |
| 195 | /// ``` |
| 196 | /// # use kernel::prelude::*; |
| 197 | /// # use kernel::device::{Bound, Device}; |
| 198 | /// # use kernel::regulator; |
| 199 | /// fn enable(dev: &Device<Bound>) -> Result { |
| 200 | /// // Obtain a reference to a (fictitious) regulator and enable it. This |
| 201 | /// // call only returns whether the operation succeeded. |
| 202 | /// regulator::devm_enable(dev, c"vcc")?; |
| 203 | /// |
| 204 | /// // The regulator will be disabled and put when `dev` is unbound. |
| 205 | /// Ok(()) |
| 206 | /// } |
| 207 | /// ``` |
| 208 | /// |
| 209 | /// ## Disabling a regulator |
| 210 | /// |
| 211 | /// ``` |
| 212 | /// # use kernel::prelude::*; |
| 213 | /// # use kernel::device::Device; |
| 214 | /// # use kernel::regulator::{Regulator, Enabled, Disabled}; |
| 215 | /// fn disable(dev: &Device, regulator: Regulator<Enabled>) -> Result { |
| 216 | /// // We can also disable an enabled regulator without reliquinshing our |
| 217 | /// // refcount: |
| 218 | /// // |
| 219 | /// // If this operation fails, the `Error` will contain the regulator |
| 220 | /// // reference, so that the operation may be retried. |
| 221 | /// let regulator: Regulator<Disabled> = |
| 222 | /// regulator.try_into_disabled().map_err(|error| error.error)?; |
| 223 | /// |
| 224 | /// // The refcount will be decremented when `regulator` is dropped. |
| 225 | /// drop(regulator); |
| 226 | /// |
| 227 | /// // ... |
| 228 | /// |
| 229 | /// Ok(()) |
| 230 | /// } |
| 231 | /// ``` |
| 232 | /// |
| 233 | /// # Invariants |
| 234 | /// |
| 235 | /// - `inner` is a pointer obtained from a successful call to |
| 236 | /// [`regulator_get()`]. It is treated as an opaque token that may only be |
| 237 | /// accessed using C API methods (e.g., it may be `NULL` if the C API returns |
| 238 | /// `NULL`). |
| 239 | /// |
| 240 | /// [`regulator_get()`]: https://docs.kernel.org/driver-api/regulator.html#c.regulator_get |
| 241 | |
| 242 | where |
| 243 | State: RegulatorState, |
| 244 | |
| 245 | inner: *mut regulator, |
| 246 | _phantom: , |
| 247 | |
| 248 | |
| 249 | |
| 250 | /// Sets the voltage for the regulator. |
| 251 | /// |
| 252 | /// This can be used to ensure that the device powers up cleanly. |
| 253 | |
| 254 | // SAFETY: Safe as per the type invariants of `Regulator`. |
| 255 | to_result |
| 256 | regulator_set_voltage |
| 257 | self.inner, |
| 258 | min_voltage.as_microvolts, |
| 259 | max_voltage.as_microvolts, |
| 260 | |
| 261 | |
| 262 | |
| 263 | |
| 264 | /// Gets the current voltage of the regulator. |
| 265 | |
| 266 | // SAFETY: Safe as per the type invariants of `Regulator`. |
| 267 | let voltage = unsafe ; |
| 268 | |
| 269 | to_result.map |
| 270 | |
| 271 | |
| 272 | |
| 273 | let inner = |
| 274 | // SAFETY: It is safe to call `regulator_get()`, on a device pointer |
| 275 | // received from the C code. |
| 276 | from_err_ptr?; |
| 277 | |
| 278 | // INVARIANT: `inner` is a pointer obtained from `regulator_get()`, and |
| 279 | // the call was successful. |
| 280 | Ok |
| 281 | inner, |
| 282 | _phantom: PhantomData, |
| 283 | |
| 284 | |
| 285 | |
| 286 | |
| 287 | // SAFETY: Safe as per the type invariants of `Regulator`. |
| 288 | to_result |
| 289 | |
| 290 | |
| 291 | |
| 292 | // SAFETY: Safe as per the type invariants of `Regulator`. |
| 293 | to_result |
| 294 | |
| 295 | |
| 296 | |
| 297 | |
| 298 | /// Obtains a [`Regulator`] instance from the system. |
| 299 | |
| 300 | get_internal |
| 301 | |
| 302 | |
| 303 | /// Attempts to convert the regulator to an enabled state. |
| 304 | |
| 305 | // We will be transferring the ownership of our `regulator_get()` count to |
| 306 | // `Regulator<Enabled>`. |
| 307 | let regulator = new; |
| 308 | |
| 309 | regulator |
| 310 | .enable_internal |
| 311 | .map |
| 312 | inner: regulator.inner, |
| 313 | _phantom: PhantomData, |
| 314 | |
| 315 | .map_err |
| 316 | error, |
| 317 | regulator: into_inner, |
| 318 | |
| 319 | |
| 320 | |
| 321 | |
| 322 | |
| 323 | /// Obtains a [`Regulator`] instance from the system and enables it. |
| 324 | /// |
| 325 | /// This is equivalent to calling `regulator_get_enable()` in the C API. |
| 326 | |
| 327 | get_internal? |
| 328 | .try_into_enabled |
| 329 | .map_err |
| 330 | |
| 331 | |
| 332 | /// Attempts to convert the regulator to a disabled state. |
| 333 | |
| 334 | // We will be transferring the ownership of our `regulator_get()` count |
| 335 | // to `Regulator<Disabled>`. |
| 336 | let regulator = new; |
| 337 | |
| 338 | regulator |
| 339 | .disable_internal |
| 340 | .map |
| 341 | inner: regulator.inner, |
| 342 | _phantom: PhantomData, |
| 343 | |
| 344 | .map_err |
| 345 | error, |
| 346 | regulator: into_inner, |
| 347 | |
| 348 | |
| 349 | |
| 350 | |
| 351 | |
| 352 | /// Checks if the regulator is enabled. |
| 353 | |
| 354 | // SAFETY: Safe as per the type invariants of `Regulator`. |
| 355 | unsafe |
| 356 | |
| 357 | |
| 358 | |
| 359 | |
| 360 | |
| 361 | if DISABLE_ON_DROP |
| 362 | // SAFETY: By the type invariants, we know that `self` owns a |
| 363 | // reference on the enabled refcount, so it is safe to relinquish it |
| 364 | // now. |
| 365 | unsafe ; |
| 366 | |
| 367 | // SAFETY: By the type invariants, we know that `self` owns a reference, |
| 368 | // so it is safe to relinquish it now. |
| 369 | unsafe ; |
| 370 | |
| 371 | |
| 372 | |
| 373 | // SAFETY: It is safe to send a `Regulator<T>` across threads. In particular, a |
| 374 | // Regulator<T> can be dropped from any thread. |
| 375 | unsafe |
| 376 | |
| 377 | // SAFETY: It is safe to send a &Regulator<T> across threads because the C side |
| 378 | // handles its own locking. |
| 379 | unsafe |
| 380 | |
| 381 | /// A voltage. |
| 382 | /// |
| 383 | /// This type represents a voltage value in microvolts. |
| 384 | |
| 385 | |
| 386 | ; |
| 387 | |
| 388 | |
| 389 | /// Creates a new `Voltage` from a value in microvolts. |
| 390 | |
| 391 | Self |
| 392 | |
| 393 | |
| 394 | /// Returns the value of the voltage in microvolts as an [`i32`]. |
| 395 | |
| 396 | self.0 |
| 397 | |
| 398 |