libryzenadj_alt/
lib.rs

1use errno::{errno, Errno};
2use num_enum::TryFromPrimitive;
3use thiserror::Error;
4
5pub use libryzenadj_sys_alt as libryzenadj_sys;
6
7///  Enumerates the possible errors returned from ryzenadj
8#[derive(Error, Debug)]
9pub enum RyzenAdjError {
10    /// ryzenadj struct init failed, provides `errno` returned by the library
11    #[error("ryzenadj init failed: {} {}", errno, errno.0)]
12    InitError { errno: Errno },
13    /// this error is returned when ryzenadj can not read out values from msr, setting values might still work
14    #[error("ryzenadj table init failed: {0}, set functions might still work")]
15    InitTableError(i32),
16    /// reading given value returned a NaN float
17    #[error("ryzenadj get returned NaN")]
18    GetNaN,
19    /// given cpu family is not supported by this crate
20    #[error("ryzenadj familly: {0} is not know")]
21    UnknowFamily(i32),
22    /// given cpu family is not supported by ryzenadj
23    #[error("ryzenadj adj family not supported")]
24    AdjFamilyNotSupported,
25    /// ryzenadj encured a memory access error
26    #[error("ryzenadj adj memory access error")]
27    AdjMemoryAccessError,
28    /// the cpu smu rejected the given value
29    #[error("ryzenadj adj smu rejected")]
30    AdjSmuRejected,
31    /// the cpu smu timeout out when trying to set the value
32    #[error("ryzenadj adj smu timeout")]
33    AdjSmuTimeout,
34    /// the cpu smu responed with setting this value is unsupported
35    #[error("ryzenadj adj smu unsupported")]
36    AdjSmuUnsupported,
37    /// unknow error ocured when tring to set give value
38    #[error("ryzenadj adj unknow error {0}")]
39    AdjUnknowError(i32),
40    /// given value is out of allowed range
41    #[error("ryzenadj adj value out or range")]
42    AdjValueOutOfRange,
43}
44/// libryzenadj result type returned by all available functions
45pub type RyzenAdjResult<T> = Result<T, RyzenAdjError>;
46
47/// Struct holding access to an open instance of ryzenadj
48pub struct RyzenAdj {
49    ryzen_adj: libryzenadj_sys::ryzen_access,
50    init_table_result: Option<i32>,
51}
52
53/// Enumerates supported CPU families
54#[derive(Debug, TryFromPrimitive)]
55#[non_exhaustive]
56#[repr(i32)]
57pub enum RyzenFamily {
58    /// Unknow CPU family
59    Unknow = libryzenadj_sys::ryzen_family_FAM_UNKNOWN,
60    /// Ryzen 2XXX and a few Athlons
61    Raven = libryzenadj_sys::ryzen_family_FAM_RAVEN,
62    /// Ryzen 3XXX and a few Athlons
63    Picassso = libryzenadj_sys::ryzen_family_FAM_PICASSO,
64    /// Ryzen 4XXX
65    Renoir = libryzenadj_sys::ryzen_family_FAM_RENOIR,
66    /// Ryzen 5XXX APUs only
67    Cezanne = libryzenadj_sys::ryzen_family_FAM_CEZANNE,
68    /// a few lower power Ryzen 3XXX
69    Dali = libryzenadj_sys::ryzen_family_FAM_DALI,
70    /// a few lower power Ryzen 5XXX
71    Lucienne = libryzenadj_sys::ryzen_family_FAM_LUCIENNE,
72    /// Athlon 4XXX?
73    Vangogh = libryzenadj_sys::ryzen_family_FAM_VANGOGH,
74    /// Ryzen 6XXX
75    Rembrandt = libryzenadj_sys::ryzen_family_FAM_REMBRANDT,
76}
77
78impl RyzenAdj {
79    /// Returns a new RyzenAdj instance
80    pub fn new() -> RyzenAdjResult<Self> {
81        let ryzen_adj = unsafe { libryzenadj_sys::init_ryzenadj() };
82
83        if ryzen_adj.is_null() {
84            Err(RyzenAdjError::InitError { errno: errno() })
85        } else {
86            let init_table_result = unsafe { libryzenadj_sys::init_table(ryzen_adj) };
87
88            let init_table_result = if init_table_result != 0 {
89                Some(init_table_result)
90            } else {
91                None
92            };
93
94            Ok(Self {
95                ryzen_adj,
96                init_table_result,
97            })
98        }
99    }
100
101    fn is_init_table(&self) -> RyzenAdjResult<()> {
102        if let Some(init_table_result) = self.init_table_result {
103            Err(RyzenAdjError::InitTableError(init_table_result))
104        } else {
105            Ok(())
106        }
107    }
108
109    fn is_nan(value: f32) -> RyzenAdjResult<f32> {
110        if value.is_nan() {
111            Err(RyzenAdjError::GetNaN)
112        } else {
113            Ok(value)
114        }
115    }
116
117    fn adj_code(code: i32) -> RyzenAdjResult<()> {
118        match code {
119            0 => Ok(()),
120            libryzenadj_sys::ADJ_ERR_FAM_UNSUPPORTED => Err(RyzenAdjError::AdjFamilyNotSupported),
121            libryzenadj_sys::ADJ_ERR_MEMORY_ACCESS => Err(RyzenAdjError::AdjMemoryAccessError),
122            libryzenadj_sys::ADJ_ERR_SMU_REJECTED => Err(RyzenAdjError::AdjSmuRejected),
123            libryzenadj_sys::ADJ_ERR_SMU_TIMEOUT => Err(RyzenAdjError::AdjSmuTimeout),
124            libryzenadj_sys::ADJ_ERR_SMU_UNSUPPORTED => Err(RyzenAdjError::AdjSmuUnsupported),
125            _ => Err(RyzenAdjError::AdjUnknowError(code)),
126        }
127    }
128    /// Refresh current readed values from the CPU
129    pub fn refresh(&self) -> RyzenAdjResult<()> {
130        self.is_init_table()?;
131        let result = unsafe { libryzenadj_sys::refresh_table(self.ryzen_adj) };
132        if result != 0 {
133            Err(RyzenAdjError::InitTableError(result))
134        } else {
135            Ok(())
136        }
137    }
138    /// Gets the APU skin temperature limit
139    pub fn get_apu_skin_temp_limit(&self) -> RyzenAdjResult<f32> {
140        self.is_init_table()?;
141        Self::is_nan(unsafe { libryzenadj_sys::get_apu_skin_temp_limit(self.ryzen_adj) })
142    }
143    /// Gets the APU skin temperature value
144    pub fn get_apu_skin_temp_value(&self) -> RyzenAdjResult<f32> {
145        self.is_init_table()?;
146        Self::is_nan(unsafe { libryzenadj_sys::get_apu_skin_temp_value(self.ryzen_adj) })
147    }
148    /// Gets the APU slow limit
149    pub fn get_apu_slow_limit(&self) -> RyzenAdjResult<f32> {
150        self.is_init_table()?;
151        Self::is_nan(unsafe { libryzenadj_sys::get_apu_slow_limit(self.ryzen_adj) })
152    }
153    /// Gets the APU slow value
154    pub fn get_apu_slow_value(&self) -> RyzenAdjResult<f32> {
155        self.is_init_table()?;
156        Self::is_nan(unsafe { libryzenadj_sys::get_apu_slow_value(self.ryzen_adj) })
157    }
158    /// Gets bios ver
159    pub fn get_bios_if_ver(&self) -> RyzenAdjResult<i32> {
160        self.is_init_table()?;
161        Ok(unsafe { libryzenadj_sys::get_bios_if_ver(self.ryzen_adj) })
162    }
163    /// Gets cclk busy value
164    pub fn get_cclk_busy_value(&self) -> RyzenAdjResult<f32> {
165        self.is_init_table()?;
166        Self::is_nan(unsafe { libryzenadj_sys::get_cclk_busy_value(self.ryzen_adj) })
167    }
168    /// Gets cclk setpoint
169    pub fn get_cclk_setpoint(&self) -> RyzenAdjResult<f32> {
170        self.is_init_table()?;
171        Self::is_nan(unsafe { libryzenadj_sys::get_cclk_setpoint(self.ryzen_adj) })
172    }
173    /// Gets current core clk
174    pub fn get_core_clk(&self, core: u32) -> RyzenAdjResult<f32> {
175        self.is_init_table()?;
176        Self::is_nan(unsafe { libryzenadj_sys::get_core_clk(self.ryzen_adj, core) })
177    }
178    /// Gets current core power
179    pub fn get_core_power(&self, core: u32) -> RyzenAdjResult<f32> {
180        self.is_init_table()?;
181        Self::is_nan(unsafe { libryzenadj_sys::get_core_power(self.ryzen_adj, core) })
182    }
183    /// Gets current core temp
184    pub fn get_core_temp(&self, core: u32) -> RyzenAdjResult<f32> {
185        self.is_init_table()?;
186        Self::is_nan(unsafe { libryzenadj_sys::get_core_temp(self.ryzen_adj, core) })
187    }
188    /// Gets current core volt
189    pub fn get_core_volt(&self, core: u32) -> RyzenAdjResult<f32> {
190        self.is_init_table()?;
191        Self::is_nan(unsafe { libryzenadj_sys::get_core_volt(self.ryzen_adj, core) })
192    }
193    /// Gets the cpu family
194    pub fn get_cpu_family(&self) -> RyzenAdjResult<RyzenFamily> {
195        self.is_init_table()?;
196        let family_int = unsafe { libryzenadj_sys::get_cpu_family(self.ryzen_adj) };
197        RyzenFamily::try_from(family_int).map_err(|_| RyzenAdjError::UnknowFamily(family_int))
198    }
199    /// Gets the dgpu skin temp limit
200    pub fn get_dgpu_skin_temp_limit(&self) -> RyzenAdjResult<f32> {
201        self.is_init_table()?;
202        Self::is_nan(unsafe { libryzenadj_sys::get_dgpu_skin_temp_limit(self.ryzen_adj) })
203    }
204    /// Gets the dgpu skin temp value
205    pub fn get_dgpu_skin_temp_value(&self) -> RyzenAdjResult<f32> {
206        self.is_init_table()?;
207        Self::is_nan(unsafe { libryzenadj_sys::get_dgpu_skin_temp_value(self.ryzen_adj) })
208    }
209    /// Gets the fast limit
210    pub fn get_fast_limit(&self) -> RyzenAdjResult<f32> {
211        self.is_init_table()?;
212        Self::is_nan(unsafe { libryzenadj_sys::get_fast_limit(self.ryzen_adj) })
213    }
214    /// Gets the fast value
215    pub fn get_fast_value(&self) -> RyzenAdjResult<f32> {
216        self.is_init_table()?;
217        Self::is_nan(unsafe { libryzenadj_sys::get_fast_value(self.ryzen_adj) })
218    }
219    /// Gets fclk
220    pub fn get_fclk(&self) -> RyzenAdjResult<f32> {
221        self.is_init_table()?;
222        Self::is_nan(unsafe { libryzenadj_sys::get_fclk(self.ryzen_adj) })
223    }
224    /// Gets gfx tmp
225    pub fn get_gfx_temp(&self) -> RyzenAdjResult<f32> {
226        self.is_init_table()?;
227        Self::is_nan(unsafe { libryzenadj_sys::get_gfx_temp(self.ryzen_adj) })
228    }
229    /// Gets gfx clk
230    pub fn get_gfx_clk(&self) -> RyzenAdjResult<f32> {
231        self.is_init_table()?;
232        Self::is_nan(unsafe { libryzenadj_sys::get_gfx_clk(self.ryzen_adj) })
233    }
234    /// Gets gfx volt
235    pub fn get_gfx_volt(&self) -> RyzenAdjResult<f32> {
236        self.is_init_table()?;
237        Self::is_nan(unsafe { libryzenadj_sys::get_gfx_volt(self.ryzen_adj) })
238    }
239    /// Gets l3 cache clk
240    pub fn get_l3_clk(&self) -> RyzenAdjResult<f32> {
241        self.is_init_table()?;
242        Self::is_nan(unsafe { libryzenadj_sys::get_l3_clk(self.ryzen_adj) })
243    }
244    /// Gets l3 logic
245    pub fn get_l3_logic(&self) -> RyzenAdjResult<f32> {
246        self.is_init_table()?;
247        Self::is_nan(unsafe { libryzenadj_sys::get_l3_logic(self.ryzen_adj) })
248    }
249    /// Gets l3 temp
250    pub fn get_l3_temp(&self) -> RyzenAdjResult<f32> {
251        self.is_init_table()?;
252        Self::is_nan(unsafe { libryzenadj_sys::get_l3_temp(self.ryzen_adj) })
253    }
254    /// Gets l3 vddm
255    pub fn get_l3_vddm(&self) -> RyzenAdjResult<f32> {
256        self.is_init_table()?;
257        Self::is_nan(unsafe { libryzenadj_sys::get_l3_vddm(self.ryzen_adj) })
258    }
259    /// Gets mem clk
260    pub fn get_mem_clk(&self) -> RyzenAdjResult<f32> {
261        self.is_init_table()?;
262        Self::is_nan(unsafe { libryzenadj_sys::get_mem_clk(self.ryzen_adj) })
263    }
264    /// Gets psi0 current
265    pub fn get_psi0_current(&self) -> RyzenAdjResult<f32> {
266        self.is_init_table()?;
267        Self::is_nan(unsafe { libryzenadj_sys::get_psi0_current(self.ryzen_adj) })
268    }
269    /// Gets psi0soc current
270    pub fn get_psi0soc_current(&self) -> RyzenAdjResult<f32> {
271        self.is_init_table()?;
272        Self::is_nan(unsafe { libryzenadj_sys::get_psi0soc_current(self.ryzen_adj) })
273    }
274    /// Gets slow limit
275    pub fn get_slow_limit(&self) -> RyzenAdjResult<f32> {
276        self.is_init_table()?;
277        Self::is_nan(unsafe { libryzenadj_sys::get_slow_limit(self.ryzen_adj) })
278    }
279    /// Gets slow time
280    pub fn get_slow_time(&self) -> RyzenAdjResult<f32> {
281        self.is_init_table()?;
282        Self::is_nan(unsafe { libryzenadj_sys::get_slow_time(self.ryzen_adj) })
283    }
284    /// Gets slow value
285    pub fn get_slow_value(&self) -> RyzenAdjResult<f32> {
286        self.is_init_table()?;
287        Self::is_nan(unsafe { libryzenadj_sys::get_slow_value(self.ryzen_adj) })
288    }
289    /// Gets soc power
290    pub fn get_soc_power(&self) -> RyzenAdjResult<f32> {
291        self.is_init_table()?;
292        Self::is_nan(unsafe { libryzenadj_sys::get_soc_power(self.ryzen_adj) })
293    }
294    /// Gets soc voltage
295    pub fn get_soc_volt(&self) -> RyzenAdjResult<f32> {
296        self.is_init_table()?;
297        Self::is_nan(unsafe { libryzenadj_sys::get_soc_volt(self.ryzen_adj) })
298    }
299    /// Gets socket power
300    pub fn get_socket_power(&self) -> RyzenAdjResult<f32> {
301        self.is_init_table()?;
302        Self::is_nan(unsafe { libryzenadj_sys::get_socket_power(self.ryzen_adj) })
303    }
304    /// Gets stamp limit
305    pub fn get_stapm_limit(&self) -> RyzenAdjResult<f32> {
306        self.is_init_table()?;
307        Self::is_nan(unsafe { libryzenadj_sys::get_stapm_limit(self.ryzen_adj) })
308    }
309    /// Gets stamp time
310    pub fn get_stapm_time(&self) -> RyzenAdjResult<f32> {
311        self.is_init_table()?;
312        Self::is_nan(unsafe { libryzenadj_sys::get_stapm_time(self.ryzen_adj) })
313    }
314    /// Gets stamp value
315    pub fn get_stapm_value(&self) -> RyzenAdjResult<f32> {
316        self.is_init_table()?;
317        Self::is_nan(unsafe { libryzenadj_sys::get_stapm_value(self.ryzen_adj) })
318    }
319    /// Gets tctl temp
320    pub fn get_tctl_temp(&self) -> RyzenAdjResult<f32> {
321        self.is_init_table()?;
322        Self::is_nan(unsafe { libryzenadj_sys::get_tctl_temp(self.ryzen_adj) })
323    }
324    /// Gets tctl temp value
325    pub fn get_tctl_temp_value(&self) -> RyzenAdjResult<f32> {
326        self.is_init_table()?;
327        Self::is_nan(unsafe { libryzenadj_sys::get_tctl_temp_value(self.ryzen_adj) })
328    }
329    /// Gets vrm current
330    pub fn get_vrm_current(&self) -> RyzenAdjResult<f32> {
331        self.is_init_table()?;
332        Self::is_nan(unsafe { libryzenadj_sys::get_vrm_current(self.ryzen_adj) })
333    }
334    /// Gets vrm current value
335    pub fn get_vrm_current_value(&self) -> RyzenAdjResult<f32> {
336        self.is_init_table()?;
337        Self::is_nan(unsafe { libryzenadj_sys::get_vrm_current_value(self.ryzen_adj) })
338    }
339    /// Gets vrmmax current
340    pub fn get_vrmmax_current(&self) -> RyzenAdjResult<f32> {
341        self.is_init_table()?;
342        Self::is_nan(unsafe { libryzenadj_sys::get_vrmmax_current(self.ryzen_adj) })
343    }
344    /// Gets vrmmax current value
345    pub fn get_vrmmax_current_value(&self) -> RyzenAdjResult<f32> {
346        self.is_init_table()?;
347        Self::is_nan(unsafe { libryzenadj_sys::get_vrmmax_current_value(self.ryzen_adj) })
348    }
349    /// Gets vrmsoc current
350    pub fn get_vrmsoc_current(&self) -> RyzenAdjResult<f32> {
351        self.is_init_table()?;
352        Self::is_nan(unsafe { libryzenadj_sys::get_vrmsoc_current(self.ryzen_adj) })
353    }
354    /// Gets vrmsoc current value
355    pub fn get_vrmsoc_current_value(&self) -> RyzenAdjResult<f32> {
356        self.is_init_table()?;
357        Self::is_nan(unsafe { libryzenadj_sys::get_vrmsoc_current_value(self.ryzen_adj) })
358    }
359    /// Gets vrmsocmax current
360    pub fn get_vrmsocmax_current(&self) -> RyzenAdjResult<f32> {
361        self.is_init_table()?;
362        Self::is_nan(unsafe { libryzenadj_sys::get_vrmsocmax_current(self.ryzen_adj) })
363    }
364    /// Gets vrmsocmax current value
365    pub fn get_vrmsocmax_current_value(&self) -> RyzenAdjResult<f32> {
366        self.is_init_table()?;
367        Self::is_nan(unsafe { libryzenadj_sys::get_vrmsocmax_current_value(self.ryzen_adj) })
368    }
369    /// Sets the apu skin temp limit
370    pub fn set_apu_skin_temp_limit(&self, value: u32) -> RyzenAdjResult<()> {
371        Self::adj_code(unsafe { libryzenadj_sys::set_apu_skin_temp_limit(self.ryzen_adj, value) })
372    }
373    /// Sets the apu slow limit
374    pub fn set_apu_slow_limit(&self, value: u32) -> RyzenAdjResult<()> {
375        Self::adj_code(unsafe { libryzenadj_sys::set_apu_slow_limit(self.ryzen_adj, value) })
376    }
377    /// Sets the all core curve optimiser
378    ///
379    /// Calling this function with a wrong value might crash you system
380    /// those marking it as unsafe
381    ///
382    /// # Safety
383    /// - `value` needs to be in proper range, the base of this value is 0x100000 and can go -/+ 30 decimal
384    pub unsafe fn set_unsafe_coall(&self, value: u32) -> RyzenAdjResult<()> {
385        Self::adj_code(libryzenadj_sys::set_coall(self.ryzen_adj, value))
386    }
387    /// Sets the igpu curve optimiser
388    ///
389    /// Calling this function with a wrong value might crash you system
390    /// those marking it as unsafe
391    ///
392    /// # Safety
393    /// - `value` needs to be in proper range, the base of this value is 0x100000 and can go -/+ 30 decimal
394    pub unsafe fn set_unsafe_cogfx(&self, value: u32) -> RyzenAdjResult<()> {
395        Self::adj_code(libryzenadj_sys::set_cogfx(self.ryzen_adj, value))
396    }
397    /// Sets the per core curve optimiser
398    ///
399    /// Calling this function with a wrong value might crash you system
400    /// those marking it as unsafe
401    ///
402    /// # Safety
403    /// - `value` needs to be in proper range, the base of this value is 0x100000
404    /// the formula for per core Curve Optimizer (on a single CCD mobile APU) is <core number> * 0x100000 + ((0x100000 + <value>) & 0xFFFFF).
405    /// for example to set -10 on core no.2 and -5 on core no.3 it's:
406    pub unsafe fn set_unsafe_coper(&self, value: u32) -> RyzenAdjResult<()> {
407        Self::adj_code(libryzenadj_sys::set_coper(self.ryzen_adj, value))
408    }
409
410    /// Sets the all core curve optimiser
411    pub fn set_coall(&self, value: i32) -> RyzenAdjResult<()> {
412        if (-30..=30).contains(&value) {
413            let value = 0x100000 + value;
414            Self::adj_code(unsafe { libryzenadj_sys::set_coall(self.ryzen_adj, value as u32) })
415        } else {
416            Err(RyzenAdjError::AdjValueOutOfRange)
417        }
418    }
419
420    /// Sets the per core curve optimiser
421    pub fn set_coper(&self, core: u32, value: i32) -> RyzenAdjResult<()> {
422        if (-30..=30).contains(&value) {
423            let value = (core * 0x100000) as i32 + value;
424            Self::adj_code(unsafe { libryzenadj_sys::set_coper(self.ryzen_adj, value as u32) })
425        } else {
426            Err(RyzenAdjError::AdjValueOutOfRange)
427        }
428    }
429
430    /// Sets the dgpu skin temp limit
431    pub fn set_dgpu_skin_temp_limit(&self, value: u32) -> RyzenAdjResult<()> {
432        Self::adj_code(unsafe { libryzenadj_sys::set_coall(self.ryzen_adj, value) })
433    }
434    /// Enable overclock (Renoir and up Only)
435    pub fn set_enable_oc(&self) -> RyzenAdjResult<()> {
436        Self::adj_code(unsafe { libryzenadj_sys::set_enable_oc(self.ryzen_adj) })
437    }
438    /// Disable overclock (Renoir and up Only)
439    pub fn set_disable_oc(&self) -> RyzenAdjResult<()> {
440        Self::adj_code(unsafe { libryzenadj_sys::set_disable_oc(self.ryzen_adj) })
441    }
442    /// Sets the fast limit
443    pub fn set_fast_limit(&self, value: u32) -> RyzenAdjResult<()> {
444        Self::adj_code(unsafe { libryzenadj_sys::set_fast_limit(self.ryzen_adj, value) })
445    }
446    /// Sets the gfx clk
447    pub fn set_gfx_clk(&self, value: u32) -> RyzenAdjResult<()> {
448        Self::adj_code(unsafe { libryzenadj_sys::set_gfx_clk(self.ryzen_adj, value) })
449    }
450    /// Sets maximum Transmission (CPU-GPU) Frequency
451    pub fn set_max_fclk_freq(&self, value: u32) -> RyzenAdjResult<()> {
452        Self::adj_code(unsafe { libryzenadj_sys::set_max_fclk_freq(self.ryzen_adj, value) })
453    }
454    /// Sets max gfxclk frequency
455    pub fn set_max_gfxclk_freq(&self, value: u32) -> RyzenAdjResult<()> {
456        Self::adj_code(unsafe { libryzenadj_sys::set_max_gfxclk_freq(self.ryzen_adj, value) })
457    }
458    /// Sets the max lclk
459    pub fn set_max_lclk(&self, value: u32) -> RyzenAdjResult<()> {
460        Self::adj_code(unsafe { libryzenadj_sys::set_max_lclk(self.ryzen_adj, value) })
461    }
462    /// Sets max perfomence mode
463    pub fn set_max_performance(&self) -> RyzenAdjResult<()> {
464        Self::adj_code(unsafe { libryzenadj_sys::set_max_performance(self.ryzen_adj) })
465    }
466    /// Sets max socclk freq
467    pub fn set_max_socclk_freq(&self, value: u32) -> RyzenAdjResult<()> {
468        Self::adj_code(unsafe { libryzenadj_sys::set_max_socclk_freq(self.ryzen_adj, value) })
469    }
470    /// Sets maximum Video Core Next freq
471    pub fn set_max_vcn(&self, value: u32) -> RyzenAdjResult<()> {
472        Self::adj_code(unsafe { libryzenadj_sys::set_max_vcn(self.ryzen_adj, value) })
473    }
474    /// Sets minimum Transmission (CPU-GPU) Frequency (MHz)
475    pub fn set_min_fclk_freq(&self, value: u32) -> RyzenAdjResult<()> {
476        Self::adj_code(unsafe { libryzenadj_sys::set_min_fclk_freq(self.ryzen_adj, value) })
477    }
478    /// Sets min gfxclk frequency
479    pub fn set_min_gfxclk_freq(&self, value: u32) -> RyzenAdjResult<()> {
480        Self::adj_code(unsafe { libryzenadj_sys::set_min_gfxclk_freq(self.ryzen_adj, value) })
481    }
482    /// Sets min lclk
483    pub fn set_min_lclk(&self, value: u32) -> RyzenAdjResult<()> {
484        Self::adj_code(unsafe { libryzenadj_sys::set_min_lclk(self.ryzen_adj, value) })
485    }
486    /// Sets min socclk freq
487    pub fn set_min_socclk_freq(&self, value: u32) -> RyzenAdjResult<()> {
488        Self::adj_code(unsafe { libryzenadj_sys::set_min_socclk_freq(self.ryzen_adj, value) })
489    }
490    /// Sets min Video Core Next freq
491    pub fn set_min_vcn(&self, value: u32) -> RyzenAdjResult<()> {
492        Self::adj_code(unsafe { libryzenadj_sys::set_min_vcn(self.ryzen_adj, value) })
493    }
494    /// Sets forced Core Clock Speed in MHz (Renoir and up Only)
495    pub fn set_oc_clk(&self, value: u32) -> RyzenAdjResult<()> {
496        Self::adj_code(unsafe { libryzenadj_sys::set_oc_clk(self.ryzen_adj, value) })
497    }
498    /// Sets forced Core VID: Must follow this calcuation (1.55 - [VID you want to set e.g. 1.25 for 1.25v]) / 0.00625 (Renoir and up Only)
499    pub fn set_oc_volt(&self, value: u32) -> RyzenAdjResult<()> {
500        Self::adj_code(unsafe { libryzenadj_sys::set_oc_volt(self.ryzen_adj, value) })
501    }
502    /// Sets forced per Core Clock Speed in MHz (Renoir and up Only)
503    pub fn set_per_core_oc_clk(&self, value: u32) -> RyzenAdjResult<()> {
504        Self::adj_code(unsafe { libryzenadj_sys::set_per_core_oc_clk(self.ryzen_adj, value) })
505    }
506    /// Sets power saving mode
507    pub fn set_power_saving(&self) -> RyzenAdjResult<()> {
508        Self::adj_code(unsafe { libryzenadj_sys::set_power_saving(self.ryzen_adj) })
509    }
510    /// Sets Ramp Time After Prochot is Deasserted: limit power based on value, higher values does apply tighter limits after prochot is over
511    pub fn set_prochot_deassertion_ramp(&self, value: u32) -> RyzenAdjResult<()> {
512        Self::adj_code(unsafe {
513            libryzenadj_sys::set_prochot_deassertion_ramp(self.ryzen_adj, value)
514        })
515    }
516    /// Sets PSI0 VDD Current Limit (mA)
517    pub fn set_psi0_current(&self, value: u32) -> RyzenAdjResult<()> {
518        Self::adj_code(unsafe { libryzenadj_sys::set_psi0_current(self.ryzen_adj, value) })
519    }
520    /// Sets PSI0 SoC Current Limit (mA)
521    pub fn set_psi0soc_current(&self, value: u32) -> RyzenAdjResult<()> {
522        Self::adj_code(unsafe { libryzenadj_sys::set_psi0soc_current(self.ryzen_adj, value) })
523    }
524    /// Sets PSI3 CPU Current Limit (mA)
525    pub fn set_psi3cpu_current(&self, value: u32) -> RyzenAdjResult<()> {
526        Self::adj_code(unsafe { libryzenadj_sys::set_psi3cpu_current(self.ryzen_adj, value) })
527    }
528    /// Sets PSI3 GFX Current Limit (mA)
529    pub fn set_psi3gfx_current(&self, value: u32) -> RyzenAdjResult<()> {
530        Self::adj_code(unsafe { libryzenadj_sys::set_psi3gfx_current(self.ryzen_adj, value) })
531    }
532    /// Sets Skin Temperature Power Limit (mW)
533    pub fn set_skin_temp_power_limit(&self, value: u32) -> RyzenAdjResult<()> {
534        Self::adj_code(unsafe { libryzenadj_sys::set_skin_temp_power_limit(self.ryzen_adj, value) })
535    }
536    /// Sets Average Power Limit - PPT LIMIT SLOW (mW)
537    pub fn set_slow_limit(&self, value: u32) -> RyzenAdjResult<()> {
538        Self::adj_code(unsafe { libryzenadj_sys::set_slow_limit(self.ryzen_adj, value) })
539    }
540    /// Sets Slow PPT Constant Time (s)
541    pub fn set_slow_time(&self, value: u32) -> RyzenAdjResult<()> {
542        Self::adj_code(unsafe { libryzenadj_sys::set_slow_time(self.ryzen_adj, value) })
543    }
544    /// Sets Sustained Power Limit - STAPM LIMIT (mW)
545    pub fn set_stapm_limit(&self, value: u32) -> RyzenAdjResult<()> {
546        Self::adj_code(unsafe { libryzenadj_sys::set_stapm_limit(self.ryzen_adj, value) })
547    }
548    /// Sets STAPM constant time (s)
549    pub fn set_stapm_time(&self, value: u32) -> RyzenAdjResult<()> {
550        Self::adj_code(unsafe { libryzenadj_sys::set_stapm_time(self.ryzen_adj, value) })
551    }
552    /// Sets Tctl Temperature Limit (degree C)
553    pub fn set_tctl_temp(&self, value: u32) -> RyzenAdjResult<()> {
554        Self::adj_code(unsafe { libryzenadj_sys::set_tctl_temp(self.ryzen_adj, value) })
555    }
556    /// Sets VRM Current Limit - TDC LIMIT VDD (mA)
557    pub fn set_vrm_current(&self, value: u32) -> RyzenAdjResult<()> {
558        Self::adj_code(unsafe { libryzenadj_sys::set_vrm_current(self.ryzen_adj, value) })
559    }
560    /// Sets VRM CVIP Current Limit - TDC LIMIT CVIP (mA)
561    pub fn set_vrmcvip_current(&self, value: u32) -> RyzenAdjResult<()> {
562        Self::adj_code(unsafe { libryzenadj_sys::set_vrmcvip_current(self.ryzen_adj, value) })
563    }
564    /// Sets VRM GFX Current Limit - TDC LIMIT GFX (mA)
565    pub fn set_vrmgfx_current(&self, value: u32) -> RyzenAdjResult<()> {
566        Self::adj_code(unsafe { libryzenadj_sys::set_vrmgfx_current(self.ryzen_adj, value) })
567    }
568    /// Sets VRM GFX Maximum Current Limit - EDC LIMIT GFX (mA)
569    pub fn set_vrmgfxmax_current(&self, value: u32) -> RyzenAdjResult<()> {
570        Self::adj_code(unsafe { libryzenadj_sys::set_vrmgfxmax_current(self.ryzen_adj, value) })
571    }
572    /// Sets VRM Maximum Current Limit - EDC LIMIT VDD (mA)
573    pub fn set_vrmmax_current(&self, value: u32) -> RyzenAdjResult<()> {
574        Self::adj_code(unsafe { libryzenadj_sys::set_vrmmax_current(self.ryzen_adj, value) })
575    }
576    /// Sets VRM SoC Current Limit - TDC LIMIT SoC (mA)
577    pub fn set_vrmsoc_current(&self, value: u32) -> RyzenAdjResult<()> {
578        Self::adj_code(unsafe { libryzenadj_sys::set_vrmsoc_current(self.ryzen_adj, value) })
579    }
580    /// Sets VRM SoC Maximum Current Limit - EDC LIMIT SoC (mA)
581    pub fn set_vrmsocmax_current(&self, value: u32) -> RyzenAdjResult<()> {
582        Self::adj_code(unsafe { libryzenadj_sys::set_vrmsocmax_current(self.ryzen_adj, value) })
583    }
584}
585
586impl Drop for RyzenAdj {
587    fn drop(&mut self) {
588        unsafe {
589            libryzenadj_sys::cleanup_ryzenadj(self.ryzen_adj);
590        }
591    }
592}