1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef _ZL3073X_CHAN_H 4 #define _ZL3073X_CHAN_H 5 6 #include <linux/bitfield.h> 7 #include <linux/stddef.h> 8 #include <linux/types.h> 9 10 #include "regs.h" 11 12 struct zl3073x_dev; 13 14 /** 15 * struct zl3073x_chan - DPLL channel state 16 * @mode_refsel: mode and reference selection register value 17 * @ref_prio: reference priority registers (4 bits per ref, P/N packed) 18 * @mon_status: monitor status register value 19 * @refsel_status: reference selection status register value 20 */ 21 struct zl3073x_chan { 22 struct_group(cfg, 23 u8 mode_refsel; 24 u8 ref_prio[ZL3073X_NUM_REFS / 2]; 25 ); 26 struct_group(stat, 27 u8 mon_status; 28 u8 refsel_status; 29 ); 30 }; 31 32 int zl3073x_chan_state_fetch(struct zl3073x_dev *zldev, u8 index); 33 const struct zl3073x_chan *zl3073x_chan_state_get(struct zl3073x_dev *zldev, 34 u8 index); 35 int zl3073x_chan_state_set(struct zl3073x_dev *zldev, u8 index, 36 const struct zl3073x_chan *chan); 37 38 int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index); 39 40 /** 41 * zl3073x_chan_mode_get - get DPLL channel operating mode 42 * @chan: pointer to channel state 43 * 44 * Return: reference selection mode of the given DPLL channel 45 */ 46 static inline u8 zl3073x_chan_mode_get(const struct zl3073x_chan *chan) 47 { 48 return FIELD_GET(ZL_DPLL_MODE_REFSEL_MODE, chan->mode_refsel); 49 } 50 51 /** 52 * zl3073x_chan_ref_get - get manually selected reference 53 * @chan: pointer to channel state 54 * 55 * Return: reference selected in forced reference lock mode 56 */ 57 static inline u8 zl3073x_chan_ref_get(const struct zl3073x_chan *chan) 58 { 59 return FIELD_GET(ZL_DPLL_MODE_REFSEL_REF, chan->mode_refsel); 60 } 61 62 /** 63 * zl3073x_chan_mode_set - set DPLL channel operating mode 64 * @chan: pointer to channel state 65 * @mode: mode to set 66 */ 67 static inline void zl3073x_chan_mode_set(struct zl3073x_chan *chan, u8 mode) 68 { 69 FIELD_MODIFY(ZL_DPLL_MODE_REFSEL_MODE, &chan->mode_refsel, mode); 70 } 71 72 /** 73 * zl3073x_chan_ref_set - set manually selected reference 74 * @chan: pointer to channel state 75 * @ref: reference to set 76 */ 77 static inline void zl3073x_chan_ref_set(struct zl3073x_chan *chan, u8 ref) 78 { 79 FIELD_MODIFY(ZL_DPLL_MODE_REFSEL_REF, &chan->mode_refsel, ref); 80 } 81 82 /** 83 * zl3073x_chan_ref_prio_get - get reference priority 84 * @chan: pointer to channel state 85 * @ref: input reference index 86 * 87 * Return: priority of the given reference <0, 15> 88 */ 89 static inline u8 90 zl3073x_chan_ref_prio_get(const struct zl3073x_chan *chan, u8 ref) 91 { 92 u8 val = chan->ref_prio[ref / 2]; 93 94 if (!(ref & 1)) 95 return FIELD_GET(ZL_DPLL_REF_PRIO_REF_P, val); 96 else 97 return FIELD_GET(ZL_DPLL_REF_PRIO_REF_N, val); 98 } 99 100 /** 101 * zl3073x_chan_ref_prio_set - set reference priority 102 * @chan: pointer to channel state 103 * @ref: input reference index 104 * @prio: priority to set 105 */ 106 static inline void 107 zl3073x_chan_ref_prio_set(struct zl3073x_chan *chan, u8 ref, u8 prio) 108 { 109 u8 *val = &chan->ref_prio[ref / 2]; 110 111 if (!(ref & 1)) 112 FIELD_MODIFY(ZL_DPLL_REF_PRIO_REF_P, val, prio); 113 else 114 FIELD_MODIFY(ZL_DPLL_REF_PRIO_REF_N, val, prio); 115 } 116 117 /** 118 * zl3073x_chan_ref_is_selectable - check if reference is selectable 119 * @chan: pointer to channel state 120 * @ref: input reference index 121 * 122 * Return: true if the reference priority is not NONE, false otherwise 123 */ 124 static inline bool 125 zl3073x_chan_ref_is_selectable(const struct zl3073x_chan *chan, u8 ref) 126 { 127 return zl3073x_chan_ref_prio_get(chan, ref) != ZL_DPLL_REF_PRIO_NONE; 128 } 129 130 /** 131 * zl3073x_chan_lock_state_get - get DPLL channel lock state 132 * @chan: pointer to channel state 133 * 134 * Return: lock state of the given DPLL channel 135 */ 136 static inline u8 zl3073x_chan_lock_state_get(const struct zl3073x_chan *chan) 137 { 138 return FIELD_GET(ZL_DPLL_MON_STATUS_STATE, chan->mon_status); 139 } 140 141 /** 142 * zl3073x_chan_is_ho_ready - check if holdover is ready 143 * @chan: pointer to channel state 144 * 145 * Return: true if holdover is ready, false otherwise 146 */ 147 static inline bool zl3073x_chan_is_ho_ready(const struct zl3073x_chan *chan) 148 { 149 return !!FIELD_GET(ZL_DPLL_MON_STATUS_HO_READY, chan->mon_status); 150 } 151 152 /** 153 * zl3073x_chan_refsel_state_get - get reference selection state 154 * @chan: pointer to channel state 155 * 156 * Return: reference selection state of the given DPLL channel 157 */ 158 static inline u8 zl3073x_chan_refsel_state_get(const struct zl3073x_chan *chan) 159 { 160 return FIELD_GET(ZL_DPLL_REFSEL_STATUS_STATE, chan->refsel_status); 161 } 162 163 /** 164 * zl3073x_chan_refsel_ref_get - get currently selected reference in auto mode 165 * @chan: pointer to channel state 166 * 167 * Return: reference selected by the DPLL in automatic mode 168 */ 169 static inline u8 zl3073x_chan_refsel_ref_get(const struct zl3073x_chan *chan) 170 { 171 return FIELD_GET(ZL_DPLL_REFSEL_STATUS_REFSEL, chan->refsel_status); 172 } 173 174 #endif /* _ZL3073X_CHAN_H */ 175