1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef _ZL3073X_CORE_H 4 #define _ZL3073X_CORE_H 5 6 #include <linux/bitfield.h> 7 #include <linux/kthread.h> 8 #include <linux/list.h> 9 #include <linux/mutex.h> 10 #include <linux/types.h> 11 12 #include "out.h" 13 #include "ref.h" 14 #include "regs.h" 15 #include "synth.h" 16 17 struct device; 18 struct regmap; 19 struct zl3073x_dpll; 20 21 /* 22 * Hardware limits for ZL3073x chip family 23 */ 24 #define ZL3073X_MAX_CHANNELS 5 25 #define ZL3073X_NUM_REFS 10 26 #define ZL3073X_NUM_OUTS 10 27 #define ZL3073X_NUM_SYNTHS 5 28 #define ZL3073X_NUM_INPUT_PINS ZL3073X_NUM_REFS 29 #define ZL3073X_NUM_OUTPUT_PINS (ZL3073X_NUM_OUTS * 2) 30 #define ZL3073X_NUM_PINS (ZL3073X_NUM_INPUT_PINS + \ 31 ZL3073X_NUM_OUTPUT_PINS) 32 33 /** 34 * struct zl3073x_dev - zl3073x device 35 * @dev: pointer to device 36 * @regmap: regmap to access device registers 37 * @multiop_lock: to serialize multiple register operations 38 * @ref: array of input references' invariants 39 * @out: array of outs' invariants 40 * @synth: array of synths' invariants 41 * @dplls: list of DPLLs 42 * @kworker: thread for periodic work 43 * @work: periodic work 44 * @clock_id: clock id of the device 45 * @phase_avg_factor: phase offset measurement averaging factor 46 */ 47 struct zl3073x_dev { 48 struct device *dev; 49 struct regmap *regmap; 50 struct mutex multiop_lock; 51 52 /* Invariants */ 53 struct zl3073x_ref ref[ZL3073X_NUM_REFS]; 54 struct zl3073x_out out[ZL3073X_NUM_OUTS]; 55 struct zl3073x_synth synth[ZL3073X_NUM_SYNTHS]; 56 57 /* DPLL channels */ 58 struct list_head dplls; 59 60 /* Monitor */ 61 struct kthread_worker *kworker; 62 struct kthread_delayed_work work; 63 64 /* Devlink parameters */ 65 u64 clock_id; 66 u8 phase_avg_factor; 67 }; 68 69 struct zl3073x_chip_info { 70 const u16 *ids; 71 size_t num_ids; 72 int num_channels; 73 }; 74 75 extern const struct zl3073x_chip_info zl30731_chip_info; 76 extern const struct zl3073x_chip_info zl30732_chip_info; 77 extern const struct zl3073x_chip_info zl30733_chip_info; 78 extern const struct zl3073x_chip_info zl30734_chip_info; 79 extern const struct zl3073x_chip_info zl30735_chip_info; 80 extern const struct regmap_config zl3073x_regmap_config; 81 82 struct zl3073x_dev *zl3073x_devm_alloc(struct device *dev); 83 int zl3073x_dev_probe(struct zl3073x_dev *zldev, 84 const struct zl3073x_chip_info *chip_info); 85 86 int zl3073x_dev_start(struct zl3073x_dev *zldev, bool full); 87 void zl3073x_dev_stop(struct zl3073x_dev *zldev); 88 89 static inline u8 zl3073x_dev_phase_avg_factor_get(struct zl3073x_dev *zldev) 90 { 91 return zldev->phase_avg_factor; 92 } 93 94 int zl3073x_dev_phase_avg_factor_set(struct zl3073x_dev *zldev, u8 factor); 95 96 /********************** 97 * Registers operations 98 **********************/ 99 100 /** 101 * struct zl3073x_hwreg_seq_item - HW register write sequence item 102 * @addr: HW register to be written 103 * @value: value to be written to HW register 104 * @mask: bitmask indicating bits to be updated 105 * @wait: number of ms to wait after register write 106 */ 107 struct zl3073x_hwreg_seq_item { 108 u32 addr; 109 u32 value; 110 u32 mask; 111 u32 wait; 112 }; 113 114 #define HWREG_SEQ_ITEM(_addr, _value, _mask, _wait) \ 115 { \ 116 .addr = _addr, \ 117 .value = FIELD_PREP_CONST(_mask, _value), \ 118 .mask = _mask, \ 119 .wait = _wait, \ 120 } 121 122 int zl3073x_mb_op(struct zl3073x_dev *zldev, unsigned int op_reg, u8 op_val, 123 unsigned int mask_reg, u16 mask_val); 124 int zl3073x_poll_zero_u8(struct zl3073x_dev *zldev, unsigned int reg, u8 mask); 125 int zl3073x_read_u8(struct zl3073x_dev *zldev, unsigned int reg, u8 *val); 126 int zl3073x_read_u16(struct zl3073x_dev *zldev, unsigned int reg, u16 *val); 127 int zl3073x_read_u32(struct zl3073x_dev *zldev, unsigned int reg, u32 *val); 128 int zl3073x_read_u48(struct zl3073x_dev *zldev, unsigned int reg, u64 *val); 129 int zl3073x_write_u8(struct zl3073x_dev *zldev, unsigned int reg, u8 val); 130 int zl3073x_write_u16(struct zl3073x_dev *zldev, unsigned int reg, u16 val); 131 int zl3073x_write_u32(struct zl3073x_dev *zldev, unsigned int reg, u32 val); 132 int zl3073x_write_u48(struct zl3073x_dev *zldev, unsigned int reg, u64 val); 133 int zl3073x_read_hwreg(struct zl3073x_dev *zldev, u32 addr, u32 *value); 134 int zl3073x_write_hwreg(struct zl3073x_dev *zldev, u32 addr, u32 value); 135 int zl3073x_update_hwreg(struct zl3073x_dev *zldev, u32 addr, u32 value, 136 u32 mask); 137 int zl3073x_write_hwreg_seq(struct zl3073x_dev *zldev, 138 const struct zl3073x_hwreg_seq_item *seq, 139 size_t num_items); 140 141 /***************** 142 * Misc operations 143 *****************/ 144 145 int zl3073x_ref_phase_offsets_update(struct zl3073x_dev *zldev, int channel); 146 147 static inline bool 148 zl3073x_is_n_pin(u8 id) 149 { 150 /* P-pins ids are even while N-pins are odd */ 151 return id & 1; 152 } 153 154 static inline bool 155 zl3073x_is_p_pin(u8 id) 156 { 157 return !zl3073x_is_n_pin(id); 158 } 159 160 /** 161 * zl3073x_input_pin_ref_get - get reference for given input pin 162 * @id: input pin id 163 * 164 * Return: reference id for the given input pin 165 */ 166 static inline u8 167 zl3073x_input_pin_ref_get(u8 id) 168 { 169 return id; 170 } 171 172 /** 173 * zl3073x_output_pin_out_get - get output for the given output pin 174 * @id: output pin id 175 * 176 * Return: output id for the given output pin 177 */ 178 static inline u8 179 zl3073x_output_pin_out_get(u8 id) 180 { 181 /* Output pin pair shares the single output */ 182 return id / 2; 183 } 184 185 /** 186 * zl3073x_dev_ref_freq_get - get input reference frequency 187 * @zldev: pointer to zl3073x device 188 * @index: input reference index 189 * 190 * Return: frequency of given input reference 191 */ 192 static inline u32 193 zl3073x_dev_ref_freq_get(struct zl3073x_dev *zldev, u8 index) 194 { 195 const struct zl3073x_ref *ref = zl3073x_ref_state_get(zldev, index); 196 197 return zl3073x_ref_freq_get(ref); 198 } 199 200 /** 201 * zl3073x_dev_ref_is_diff - check if the given input reference is differential 202 * @zldev: pointer to zl3073x device 203 * @index: input reference index 204 * 205 * Return: true if reference is differential, false if reference is single-ended 206 */ 207 static inline bool 208 zl3073x_dev_ref_is_diff(struct zl3073x_dev *zldev, u8 index) 209 { 210 const struct zl3073x_ref *ref = zl3073x_ref_state_get(zldev, index); 211 212 return zl3073x_ref_is_diff(ref); 213 } 214 215 /* 216 * zl3073x_dev_ref_is_status_ok - check the given input reference status 217 * @zldev: pointer to zl3073x device 218 * @index: input reference index 219 * 220 * Return: true if the status is ok, false otherwise 221 */ 222 static inline bool 223 zl3073x_dev_ref_is_status_ok(struct zl3073x_dev *zldev, u8 index) 224 { 225 const struct zl3073x_ref *ref = zl3073x_ref_state_get(zldev, index); 226 227 return zl3073x_ref_is_status_ok(ref); 228 } 229 230 /** 231 * zl3073x_dev_synth_freq_get - get synth current freq 232 * @zldev: pointer to zl3073x device 233 * @index: synth index 234 * 235 * Return: frequency of given synthetizer 236 */ 237 static inline u32 238 zl3073x_dev_synth_freq_get(struct zl3073x_dev *zldev, u8 index) 239 { 240 const struct zl3073x_synth *synth; 241 242 synth = zl3073x_synth_state_get(zldev, index); 243 return zl3073x_synth_freq_get(synth); 244 } 245 246 /** 247 * zl3073x_dev_out_synth_get - get synth connected to given output 248 * @zldev: pointer to zl3073x device 249 * @index: output index 250 * 251 * Return: index of synth connected to given output. 252 */ 253 static inline u8 254 zl3073x_dev_out_synth_get(struct zl3073x_dev *zldev, u8 index) 255 { 256 const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index); 257 258 return zl3073x_out_synth_get(out); 259 } 260 261 /** 262 * zl3073x_dev_out_is_enabled - check if the given output is enabled 263 * @zldev: pointer to zl3073x device 264 * @index: output index 265 * 266 * Return: true if the output is enabled, false otherwise 267 */ 268 static inline bool 269 zl3073x_dev_out_is_enabled(struct zl3073x_dev *zldev, u8 index) 270 { 271 const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index); 272 const struct zl3073x_synth *synth; 273 u8 synth_id; 274 275 /* Output is enabled only if associated synth is enabled */ 276 synth_id = zl3073x_out_synth_get(out); 277 synth = zl3073x_synth_state_get(zldev, synth_id); 278 279 return zl3073x_synth_is_enabled(synth) && zl3073x_out_is_enabled(out); 280 } 281 282 /** 283 * zl3073x_dev_out_dpll_get - get DPLL ID the output is driven by 284 * @zldev: pointer to zl3073x device 285 * @index: output index 286 * 287 * Return: ID of DPLL the given output is driven by 288 */ 289 static inline 290 u8 zl3073x_dev_out_dpll_get(struct zl3073x_dev *zldev, u8 index) 291 { 292 const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index); 293 const struct zl3073x_synth *synth; 294 u8 synth_id; 295 296 /* Get synthesizer connected to given output */ 297 synth_id = zl3073x_out_synth_get(out); 298 synth = zl3073x_synth_state_get(zldev, synth_id); 299 300 /* Return DPLL that drives the synth */ 301 return zl3073x_synth_dpll_get(synth); 302 } 303 304 /** 305 * zl3073x_dev_out_is_diff - check if the given output is differential 306 * @zldev: pointer to zl3073x device 307 * @index: output index 308 * 309 * Return: true if output is differential, false if output is single-ended 310 */ 311 static inline bool 312 zl3073x_dev_out_is_diff(struct zl3073x_dev *zldev, u8 index) 313 { 314 const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index); 315 316 return zl3073x_out_is_diff(out); 317 } 318 319 /** 320 * zl3073x_dev_output_pin_is_enabled - check if the given output pin is enabled 321 * @zldev: pointer to zl3073x device 322 * @id: output pin id 323 * 324 * Checks if the output of the given output pin is enabled and also that 325 * its signal format also enables the given pin. 326 * 327 * Return: true if output pin is enabled, false if output pin is disabled 328 */ 329 static inline bool 330 zl3073x_dev_output_pin_is_enabled(struct zl3073x_dev *zldev, u8 id) 331 { 332 u8 out_id = zl3073x_output_pin_out_get(id); 333 const struct zl3073x_out *out; 334 335 out = zl3073x_out_state_get(zldev, out_id); 336 337 /* Check if the output is enabled - call _dev_ helper that 338 * additionally checks for attached synth enablement. 339 */ 340 if (!zl3073x_dev_out_is_enabled(zldev, out_id)) 341 return false; 342 343 /* Check signal format */ 344 switch (zl3073x_out_signal_format_get(out)) { 345 case ZL_OUTPUT_MODE_SIGNAL_FORMAT_DISABLED: 346 /* Both output pins are disabled by signal format */ 347 return false; 348 349 case ZL_OUTPUT_MODE_SIGNAL_FORMAT_1P: 350 /* Output is one single ended P-pin output */ 351 if (zl3073x_is_n_pin(id)) 352 return false; 353 break; 354 case ZL_OUTPUT_MODE_SIGNAL_FORMAT_1N: 355 /* Output is one single ended N-pin output */ 356 if (zl3073x_is_p_pin(id)) 357 return false; 358 break; 359 default: 360 /* For other format both pins are enabled */ 361 break; 362 } 363 364 return true; 365 } 366 367 #endif /* _ZL3073X_CORE_H */ 368