xref: /linux/rust/kernel/regulator.rs (revision bf977a9ad33d204c8ca646cef83184eb364820ff)
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     device::Device,
22     error::{from_err_ptr, to_result, Result},
23     prelude::*,
24 };
25 
26 use core::{marker::PhantomData, mem::ManuallyDrop, ptr::NonNull};
27 
28 mod private {
29     pub trait Sealed {}
30 
31     impl Sealed for super::Enabled {}
32     impl Sealed for super::Disabled {}
33     impl Sealed for super::Dynamic {}
34 }
35 
36 /// A trait representing the different states a [`Regulator`] can be in.
37 pub trait RegulatorState: private::Sealed + 'static {
38     /// Whether the regulator should be disabled when dropped.
39     const DISABLE_ON_DROP: bool;
40 }
41 
42 /// A state where the [`Regulator`] is known to be enabled.
43 ///
44 /// The `enable` reference count held by this state is decremented when it is
45 /// dropped.
46 pub struct Enabled;
47 
48 /// A state where this [`Regulator`] handle has not specifically asked for the
49 /// underlying regulator to be enabled. This means that this reference does not
50 /// own an `enable` reference count, but the regulator may still be on.
51 pub struct Disabled;
52 
53 /// A state that models the C API. The [`Regulator`] can be either enabled or
54 /// disabled, and the user is in control of the reference count. This is also
55 /// the default state.
56 ///
57 /// Use [`Regulator::is_enabled`] to check the regulator's current state.
58 pub struct Dynamic;
59 
60 impl RegulatorState for Enabled {
61     const DISABLE_ON_DROP: bool = true;
62 }
63 
64 impl RegulatorState for Disabled {
65     const DISABLE_ON_DROP: bool = false;
66 }
67 
68 impl RegulatorState for Dynamic {
69     const DISABLE_ON_DROP: bool = false;
70 }
71 
72 /// A trait that abstracts the ability to check if a [`Regulator`] is enabled.
73 pub trait IsEnabled: RegulatorState {}
74 impl IsEnabled for Disabled {}
75 impl IsEnabled for Dynamic {}
76 
77 /// An error that can occur when trying to convert a [`Regulator`] between states.
78 pub struct Error<State: RegulatorState> {
79     /// The error that occurred.
80     pub error: kernel::error::Error,
81 
82     /// The regulator that caused the error, so that the operation may be retried.
83     pub regulator: Regulator<State>,
84 }
85 
86 /// A `struct regulator` abstraction.
87 ///
88 /// # Examples
89 ///
90 /// ## Enabling a regulator
91 ///
92 /// This example uses [`Regulator<Enabled>`], which is suitable for drivers that
93 /// enable a regulator at probe time and leave them on until the device is
94 /// removed or otherwise shutdown.
95 ///
96 /// These users can store [`Regulator<Enabled>`] directly in their driver's
97 /// private data struct.
98 ///
99 /// ```
100 /// # use kernel::prelude::*;
101 /// # use kernel::c_str;
102 /// # use kernel::device::Device;
103 /// # use kernel::regulator::{Voltage, Regulator, Disabled, Enabled};
104 /// fn enable(dev: &Device, min_voltage: Voltage, max_voltage: Voltage) -> Result {
105 ///     // Obtain a reference to a (fictitious) regulator.
106 ///     let regulator: Regulator<Disabled> = Regulator::<Disabled>::get(dev, c_str!("vcc"))?;
107 ///
108 ///     // The voltage can be set before enabling the regulator if needed, e.g.:
109 ///     regulator.set_voltage(min_voltage, max_voltage)?;
110 ///
111 ///     // The same applies for `get_voltage()`, i.e.:
112 ///     let voltage: Voltage = regulator.get_voltage()?;
113 ///
114 ///     // Enables the regulator, consuming the previous value.
115 ///     //
116 ///     // From now on, the regulator is known to be enabled because of the type
117 ///     // `Enabled`.
118 ///     //
119 ///     // If this operation fails, the `Error` will contain the regulator
120 ///     // reference, so that the operation may be retried.
121 ///     let regulator: Regulator<Enabled> =
122 ///         regulator.try_into_enabled().map_err(|error| error.error)?;
123 ///
124 ///     // The voltage can also be set after enabling the regulator, e.g.:
125 ///     regulator.set_voltage(min_voltage, max_voltage)?;
126 ///
127 ///     // The same applies for `get_voltage()`, i.e.:
128 ///     let voltage: Voltage = regulator.get_voltage()?;
129 ///
130 ///     // Dropping an enabled regulator will disable it. The refcount will be
131 ///     // decremented.
132 ///     drop(regulator);
133 ///
134 ///     // ...
135 ///
136 ///     Ok(())
137 /// }
138 /// ```
139 ///
140 /// A more concise shortcut is available for enabling a regulator. This is
141 /// equivalent to `regulator_get_enable()`:
142 ///
143 /// ```
144 /// # use kernel::prelude::*;
145 /// # use kernel::c_str;
146 /// # use kernel::device::Device;
147 /// # use kernel::regulator::{Voltage, Regulator, Enabled};
148 /// fn enable(dev: &Device) -> Result {
149 ///     // Obtain a reference to a (fictitious) regulator and enable it.
150 ///     let regulator: Regulator<Enabled> = Regulator::<Enabled>::get(dev, c_str!("vcc"))?;
151 ///
152 ///     // Dropping an enabled regulator will disable it. The refcount will be
153 ///     // decremented.
154 ///     drop(regulator);
155 ///
156 ///     // ...
157 ///
158 ///     Ok(())
159 /// }
160 /// ```
161 ///
162 /// ## Disabling a regulator
163 ///
164 /// ```
165 /// # use kernel::prelude::*;
166 /// # use kernel::device::Device;
167 /// # use kernel::regulator::{Regulator, Enabled, Disabled};
168 /// fn disable(dev: &Device, regulator: Regulator<Enabled>) -> Result {
169 ///     // We can also disable an enabled regulator without reliquinshing our
170 ///     // refcount:
171 ///     //
172 ///     // If this operation fails, the `Error` will contain the regulator
173 ///     // reference, so that the operation may be retried.
174 ///     let regulator: Regulator<Disabled> =
175 ///         regulator.try_into_disabled().map_err(|error| error.error)?;
176 ///
177 ///     // The refcount will be decremented when `regulator` is dropped.
178 ///     drop(regulator);
179 ///
180 ///     // ...
181 ///
182 ///     Ok(())
183 /// }
184 /// ```
185 ///
186 /// ## Using [`Regulator<Dynamic>`]
187 ///
188 /// This example mimics the behavior of the C API, where the user is in
189 /// control of the enabled reference count. This is useful for drivers that
190 /// might call enable and disable to manage the `enable` reference count at
191 /// runtime, perhaps as a result of `open()` and `close()` calls or whatever
192 /// other driver-specific or subsystem-specific hooks.
193 ///
194 /// ```
195 /// # use kernel::prelude::*;
196 /// # use kernel::c_str;
197 /// # use kernel::device::Device;
198 /// # use kernel::regulator::{Regulator, Dynamic};
199 /// struct PrivateData {
200 ///     regulator: Regulator<Dynamic>,
201 /// }
202 ///
203 /// // A fictictious probe function that obtains a regulator and sets it up.
204 /// fn probe(dev: &Device) -> Result<PrivateData> {
205 ///     // Obtain a reference to a (fictitious) regulator.
206 ///     let mut regulator = Regulator::<Dynamic>::get(dev, c_str!("vcc"))?;
207 ///
208 ///     Ok(PrivateData { regulator })
209 /// }
210 ///
211 /// // A fictictious function that indicates that the device is going to be used.
212 /// fn open(dev: &Device, data: &mut PrivateData) -> Result {
213 ///     // Increase the `enabled` reference count.
214 ///     data.regulator.enable()?;
215 ///
216 ///     Ok(())
217 /// }
218 ///
219 /// fn close(dev: &Device, data: &mut PrivateData) -> Result {
220 ///     // Decrease the `enabled` reference count.
221 ///     data.regulator.disable()?;
222 ///
223 ///     Ok(())
224 /// }
225 ///
226 /// fn remove(dev: &Device, data: PrivateData) -> Result {
227 ///     // `PrivateData` is dropped here, which will drop the
228 ///     // `Regulator<Dynamic>` in turn.
229 ///     //
230 ///     // The reference that was obtained by `regulator_get()` will be
231 ///     // released, but it is up to the user to make sure that the number of calls
232 ///     // to `enable()` and `disabled()` are balanced before this point.
233 ///     Ok(())
234 /// }
235 /// ```
236 ///
237 /// # Invariants
238 ///
239 /// - `inner` is a non-null wrapper over a pointer to a `struct
240 ///   regulator` obtained from [`regulator_get()`].
241 ///
242 /// [`regulator_get()`]: https://docs.kernel.org/driver-api/regulator.html#c.regulator_get
243 pub struct Regulator<State = Dynamic>
244 where
245     State: RegulatorState,
246 {
247     inner: NonNull<bindings::regulator>,
248     _phantom: PhantomData<State>,
249 }
250 
251 impl<T: RegulatorState> Regulator<T> {
252     /// Sets the voltage for the regulator.
253     ///
254     /// This can be used to ensure that the device powers up cleanly.
set_voltage(&self, min_voltage: Voltage, max_voltage: Voltage) -> Result255     pub fn set_voltage(&self, min_voltage: Voltage, max_voltage: Voltage) -> Result {
256         // SAFETY: Safe as per the type invariants of `Regulator`.
257         to_result(unsafe {
258             bindings::regulator_set_voltage(
259                 self.inner.as_ptr(),
260                 min_voltage.as_microvolts(),
261                 max_voltage.as_microvolts(),
262             )
263         })
264     }
265 
266     /// Gets the current voltage of the regulator.
get_voltage(&self) -> Result<Voltage>267     pub fn get_voltage(&self) -> Result<Voltage> {
268         // SAFETY: Safe as per the type invariants of `Regulator`.
269         let voltage = unsafe { bindings::regulator_get_voltage(self.inner.as_ptr()) };
270         if voltage < 0 {
271             Err(kernel::error::Error::from_errno(voltage))
272         } else {
273             Ok(Voltage::from_microvolts(voltage))
274         }
275     }
276 
get_internal(dev: &Device, name: &CStr) -> Result<Regulator<T>>277     fn get_internal(dev: &Device, name: &CStr) -> Result<Regulator<T>> {
278         // SAFETY: It is safe to call `regulator_get()`, on a device pointer
279         // received from the C code.
280         let inner = from_err_ptr(unsafe { bindings::regulator_get(dev.as_raw(), name.as_ptr()) })?;
281 
282         // SAFETY: We can safely trust `inner` to be a pointer to a valid
283         // regulator if `ERR_PTR` was not returned.
284         let inner = unsafe { NonNull::new_unchecked(inner) };
285 
286         Ok(Self {
287             inner,
288             _phantom: PhantomData,
289         })
290     }
291 
enable_internal(&mut self) -> Result292     fn enable_internal(&mut self) -> Result {
293         // SAFETY: Safe as per the type invariants of `Regulator`.
294         to_result(unsafe { bindings::regulator_enable(self.inner.as_ptr()) })
295     }
296 
disable_internal(&mut self) -> Result297     fn disable_internal(&mut self) -> Result {
298         // SAFETY: Safe as per the type invariants of `Regulator`.
299         to_result(unsafe { bindings::regulator_disable(self.inner.as_ptr()) })
300     }
301 }
302 
303 impl Regulator<Disabled> {
304     /// Obtains a [`Regulator`] instance from the system.
get(dev: &Device, name: &CStr) -> Result<Self>305     pub fn get(dev: &Device, name: &CStr) -> Result<Self> {
306         Regulator::get_internal(dev, name)
307     }
308 
309     /// Attempts to convert the regulator to an enabled state.
try_into_enabled(self) -> Result<Regulator<Enabled>, Error<Disabled>>310     pub fn try_into_enabled(self) -> Result<Regulator<Enabled>, Error<Disabled>> {
311         // We will be transferring the ownership of our `regulator_get()` count to
312         // `Regulator<Enabled>`.
313         let mut regulator = ManuallyDrop::new(self);
314 
315         regulator
316             .enable_internal()
317             .map(|()| Regulator {
318                 inner: regulator.inner,
319                 _phantom: PhantomData,
320             })
321             .map_err(|error| Error {
322                 error,
323                 regulator: ManuallyDrop::into_inner(regulator),
324             })
325     }
326 }
327 
328 impl Regulator<Enabled> {
329     /// Obtains a [`Regulator`] instance from the system and enables it.
330     ///
331     /// This is equivalent to calling `regulator_get_enable()` in the C API.
get(dev: &Device, name: &CStr) -> Result<Self>332     pub fn get(dev: &Device, name: &CStr) -> Result<Self> {
333         Regulator::<Disabled>::get_internal(dev, name)?
334             .try_into_enabled()
335             .map_err(|error| error.error)
336     }
337 
338     /// Attempts to convert the regulator to a disabled state.
try_into_disabled(self) -> Result<Regulator<Disabled>, Error<Enabled>>339     pub fn try_into_disabled(self) -> Result<Regulator<Disabled>, Error<Enabled>> {
340         // We will be transferring the ownership of our `regulator_get()` count
341         // to `Regulator<Disabled>`.
342         let mut regulator = ManuallyDrop::new(self);
343 
344         regulator
345             .disable_internal()
346             .map(|()| Regulator {
347                 inner: regulator.inner,
348                 _phantom: PhantomData,
349             })
350             .map_err(|error| Error {
351                 error,
352                 regulator: ManuallyDrop::into_inner(regulator),
353             })
354     }
355 }
356 
357 impl Regulator<Dynamic> {
358     /// Obtains a [`Regulator`] instance from the system. The current state of
359     /// the regulator is unknown and it is up to the user to manage the enabled
360     /// reference count.
361     ///
362     /// This closely mimics the behavior of the C API and can be used to
363     /// dynamically manage the enabled reference count at runtime.
get(dev: &Device, name: &CStr) -> Result<Self>364     pub fn get(dev: &Device, name: &CStr) -> Result<Self> {
365         Regulator::get_internal(dev, name)
366     }
367 
368     /// Increases the `enabled` reference count.
enable(&mut self) -> Result369     pub fn enable(&mut self) -> Result {
370         self.enable_internal()
371     }
372 
373     /// Decreases the `enabled` reference count.
disable(&mut self) -> Result374     pub fn disable(&mut self) -> Result {
375         self.disable_internal()
376     }
377 }
378 
379 impl<T: IsEnabled> Regulator<T> {
380     /// Checks if the regulator is enabled.
is_enabled(&self) -> bool381     pub fn is_enabled(&self) -> bool {
382         // SAFETY: Safe as per the type invariants of `Regulator`.
383         unsafe { bindings::regulator_is_enabled(self.inner.as_ptr()) != 0 }
384     }
385 }
386 
387 impl<T: RegulatorState> Drop for Regulator<T> {
drop(&mut self)388     fn drop(&mut self) {
389         if T::DISABLE_ON_DROP {
390             // SAFETY: By the type invariants, we know that `self` owns a
391             // reference on the enabled refcount, so it is safe to relinquish it
392             // now.
393             unsafe { bindings::regulator_disable(self.inner.as_ptr()) };
394         }
395         // SAFETY: By the type invariants, we know that `self` owns a reference,
396         // so it is safe to relinquish it now.
397         unsafe { bindings::regulator_put(self.inner.as_ptr()) };
398     }
399 }
400 
401 /// A voltage.
402 ///
403 /// This type represents a voltage value in microvolts.
404 #[repr(transparent)]
405 #[derive(Copy, Clone, PartialEq, Eq)]
406 pub struct Voltage(i32);
407 
408 impl Voltage {
409     /// Creates a new `Voltage` from a value in microvolts.
from_microvolts(uv: i32) -> Self410     pub fn from_microvolts(uv: i32) -> Self {
411         Self(uv)
412     }
413 
414     /// Returns the value of the voltage in microvolts as an [`i32`].
as_microvolts(self) -> i32415     pub fn as_microvolts(self) -> i32 {
416         self.0
417     }
418 }
419