1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef _ZL3073X_REF_H 4 #define _ZL3073X_REF_H 5 6 #include <linux/bitfield.h> 7 #include <linux/math64.h> 8 #include <linux/types.h> 9 10 #include "regs.h" 11 12 struct zl3073x_dev; 13 14 /** 15 * struct zl3073x_ref - input reference state 16 * @ffo: current fractional frequency offset 17 * @phase_comp: phase compensation 18 * @esync_n_div: divisor for embedded sync or n-divided signal formats 19 * @freq_base: frequency base 20 * @freq_mult: frequnecy multiplier 21 * @freq_ratio_m: FEC mode multiplier 22 * @freq_ratio_n: FEC mode divisor 23 * @config: reference config 24 * @sync_ctrl: reference sync control 25 * @mon_status: reference monitor status 26 */ 27 struct zl3073x_ref { 28 s64 ffo; 29 u64 phase_comp; 30 u32 esync_n_div; 31 u16 freq_base; 32 u16 freq_mult; 33 u16 freq_ratio_m; 34 u16 freq_ratio_n; 35 u8 config; 36 u8 sync_ctrl; 37 u8 mon_status; 38 }; 39 40 int zl3073x_ref_state_fetch(struct zl3073x_dev *zldev, u8 index); 41 42 const struct zl3073x_ref *zl3073x_ref_state_get(struct zl3073x_dev *zldev, 43 u8 index); 44 45 int zl3073x_ref_state_set(struct zl3073x_dev *zldev, u8 index, 46 const struct zl3073x_ref *ref); 47 48 int zl3073x_ref_freq_factorize(u32 freq, u16 *base, u16 *mult); 49 50 /** 51 * zl3073x_ref_ffo_get - get current fractional frequency offset 52 * @ref: pointer to ref state 53 * 54 * Return: the latest measured fractional frequency offset 55 */ 56 static inline s64 57 zl3073x_ref_ffo_get(const struct zl3073x_ref *ref) 58 { 59 return ref->ffo; 60 } 61 62 /** 63 * zl3073x_ref_freq_get - get given input reference frequency 64 * @ref: pointer to ref state 65 * 66 * Return: frequency of the given input reference 67 */ 68 static inline u32 69 zl3073x_ref_freq_get(const struct zl3073x_ref *ref) 70 { 71 return mul_u64_u32_div(ref->freq_base * ref->freq_mult, 72 ref->freq_ratio_m, ref->freq_ratio_n); 73 } 74 75 /** 76 * zl3073x_ref_freq_set - set given input reference frequency 77 * @ref: pointer to ref state 78 * @freq: frequency to be set 79 * 80 * Return: 0 on success, <0 when frequency cannot be factorized 81 */ 82 static inline int 83 zl3073x_ref_freq_set(struct zl3073x_ref *ref, u32 freq) 84 { 85 u16 base, mult; 86 int rc; 87 88 rc = zl3073x_ref_freq_factorize(freq, &base, &mult); 89 if (rc) 90 return rc; 91 92 ref->freq_base = base; 93 ref->freq_mult = mult; 94 95 return 0; 96 } 97 98 /** 99 * zl3073x_ref_is_diff - check if the given input reference is differential 100 * @ref: pointer to ref state 101 * 102 * Return: true if reference is differential, false if reference is single-ended 103 */ 104 static inline bool 105 zl3073x_ref_is_diff(const struct zl3073x_ref *ref) 106 { 107 return !!FIELD_GET(ZL_REF_CONFIG_DIFF_EN, ref->config); 108 } 109 110 /** 111 * zl3073x_ref_is_enabled - check if the given input reference is enabled 112 * @ref: pointer to ref state 113 * 114 * Return: true if input refernce is enabled, false otherwise 115 */ 116 static inline bool 117 zl3073x_ref_is_enabled(const struct zl3073x_ref *ref) 118 { 119 return !!FIELD_GET(ZL_REF_CONFIG_ENABLE, ref->config); 120 } 121 122 /** 123 * zl3073x_ref_is_status_ok - check the given input reference status 124 * @ref: pointer to ref state 125 * 126 * Return: true if the status is ok, false otherwise 127 */ 128 static inline bool 129 zl3073x_ref_is_status_ok(const struct zl3073x_ref *ref) 130 { 131 return ref->mon_status == ZL_REF_MON_STATUS_OK; 132 } 133 134 #endif /* _ZL3073X_REF_H */ 135