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 * @chip_id: chip ID read from hardware
39 * @ref: array of input references' invariants
40 * @out: array of outs' invariants
41 * @synth: array of synths' invariants
42 * @dplls: list of DPLLs
43 * @kworker: thread for periodic work
44 * @work: periodic work
45 * @clock_id: clock id of the device
46 * @phase_avg_factor: phase offset measurement averaging factor
47 */
48 struct zl3073x_dev {
49 struct device *dev;
50 struct regmap *regmap;
51 struct mutex multiop_lock;
52 u16 chip_id;
53
54 /* Invariants */
55 struct zl3073x_ref ref[ZL3073X_NUM_REFS];
56 struct zl3073x_out out[ZL3073X_NUM_OUTS];
57 struct zl3073x_synth synth[ZL3073X_NUM_SYNTHS];
58
59 /* DPLL channels */
60 struct list_head dplls;
61
62 /* Monitor */
63 struct kthread_worker *kworker;
64 struct kthread_delayed_work work;
65
66 /* Devlink parameters */
67 u64 clock_id;
68 u8 phase_avg_factor;
69 };
70
71 struct zl3073x_chip_info {
72 const u16 *ids;
73 size_t num_ids;
74 int num_channels;
75 };
76
77 extern const struct zl3073x_chip_info zl30731_chip_info;
78 extern const struct zl3073x_chip_info zl30732_chip_info;
79 extern const struct zl3073x_chip_info zl30733_chip_info;
80 extern const struct zl3073x_chip_info zl30734_chip_info;
81 extern const struct zl3073x_chip_info zl30735_chip_info;
82 extern const struct regmap_config zl3073x_regmap_config;
83
84 struct zl3073x_dev *zl3073x_devm_alloc(struct device *dev);
85 int zl3073x_dev_probe(struct zl3073x_dev *zldev,
86 const struct zl3073x_chip_info *chip_info);
87
88 int zl3073x_dev_start(struct zl3073x_dev *zldev, bool full);
89 void zl3073x_dev_stop(struct zl3073x_dev *zldev);
90
zl3073x_dev_phase_avg_factor_get(struct zl3073x_dev * zldev)91 static inline u8 zl3073x_dev_phase_avg_factor_get(struct zl3073x_dev *zldev)
92 {
93 return zldev->phase_avg_factor;
94 }
95
96 int zl3073x_dev_phase_avg_factor_set(struct zl3073x_dev *zldev, u8 factor);
97
98 /**********************
99 * Registers operations
100 **********************/
101
102 /**
103 * struct zl3073x_hwreg_seq_item - HW register write sequence item
104 * @addr: HW register to be written
105 * @value: value to be written to HW register
106 * @mask: bitmask indicating bits to be updated
107 * @wait: number of ms to wait after register write
108 */
109 struct zl3073x_hwreg_seq_item {
110 u32 addr;
111 u32 value;
112 u32 mask;
113 u32 wait;
114 };
115
116 #define HWREG_SEQ_ITEM(_addr, _value, _mask, _wait) \
117 { \
118 .addr = _addr, \
119 .value = FIELD_PREP_CONST(_mask, _value), \
120 .mask = _mask, \
121 .wait = _wait, \
122 }
123
124 int zl3073x_mb_op(struct zl3073x_dev *zldev, unsigned int op_reg, u8 op_val,
125 unsigned int mask_reg, u16 mask_val);
126 int zl3073x_poll_zero_u8(struct zl3073x_dev *zldev, unsigned int reg, u8 mask);
127 int zl3073x_read_u8(struct zl3073x_dev *zldev, unsigned int reg, u8 *val);
128 int zl3073x_read_u16(struct zl3073x_dev *zldev, unsigned int reg, u16 *val);
129 int zl3073x_read_u32(struct zl3073x_dev *zldev, unsigned int reg, u32 *val);
130 int zl3073x_read_u48(struct zl3073x_dev *zldev, unsigned int reg, u64 *val);
131 int zl3073x_write_u8(struct zl3073x_dev *zldev, unsigned int reg, u8 val);
132 int zl3073x_write_u16(struct zl3073x_dev *zldev, unsigned int reg, u16 val);
133 int zl3073x_write_u32(struct zl3073x_dev *zldev, unsigned int reg, u32 val);
134 int zl3073x_write_u48(struct zl3073x_dev *zldev, unsigned int reg, u64 val);
135 int zl3073x_read_hwreg(struct zl3073x_dev *zldev, u32 addr, u32 *value);
136 int zl3073x_write_hwreg(struct zl3073x_dev *zldev, u32 addr, u32 value);
137 int zl3073x_update_hwreg(struct zl3073x_dev *zldev, u32 addr, u32 value,
138 u32 mask);
139 int zl3073x_write_hwreg_seq(struct zl3073x_dev *zldev,
140 const struct zl3073x_hwreg_seq_item *seq,
141 size_t num_items);
142
143 /*****************
144 * Misc operations
145 *****************/
146
147 int zl3073x_ref_phase_offsets_update(struct zl3073x_dev *zldev, int channel);
148
149 /**
150 * zl3073x_dev_is_ref_phase_comp_32bit - check ref phase comp register size
151 * @zldev: pointer to zl3073x device
152 *
153 * Some chip IDs have a 32-bit wide ref_phase_offset_comp register instead
154 * of the default 48-bit.
155 *
156 * Return: true if the register is 32-bit, false if 48-bit
157 */
158 static inline bool
zl3073x_dev_is_ref_phase_comp_32bit(struct zl3073x_dev * zldev)159 zl3073x_dev_is_ref_phase_comp_32bit(struct zl3073x_dev *zldev)
160 {
161 switch (zldev->chip_id) {
162 case 0x0E30:
163 case 0x0E93:
164 case 0x0E94:
165 case 0x0E95:
166 case 0x0E96:
167 case 0x0E97:
168 case 0x1F60:
169 return true;
170 default:
171 return false;
172 }
173 }
174
175 static inline bool
zl3073x_is_n_pin(u8 id)176 zl3073x_is_n_pin(u8 id)
177 {
178 /* P-pins ids are even while N-pins are odd */
179 return id & 1;
180 }
181
182 static inline bool
zl3073x_is_p_pin(u8 id)183 zl3073x_is_p_pin(u8 id)
184 {
185 return !zl3073x_is_n_pin(id);
186 }
187
188 /**
189 * zl3073x_input_pin_ref_get - get reference for given input pin
190 * @id: input pin id
191 *
192 * Return: reference id for the given input pin
193 */
194 static inline u8
zl3073x_input_pin_ref_get(u8 id)195 zl3073x_input_pin_ref_get(u8 id)
196 {
197 return id;
198 }
199
200 /**
201 * zl3073x_output_pin_out_get - get output for the given output pin
202 * @id: output pin id
203 *
204 * Return: output id for the given output pin
205 */
206 static inline u8
zl3073x_output_pin_out_get(u8 id)207 zl3073x_output_pin_out_get(u8 id)
208 {
209 /* Output pin pair shares the single output */
210 return id / 2;
211 }
212
213 /**
214 * zl3073x_dev_ref_freq_get - get input reference frequency
215 * @zldev: pointer to zl3073x device
216 * @index: input reference index
217 *
218 * Return: frequency of given input reference
219 */
220 static inline u32
zl3073x_dev_ref_freq_get(struct zl3073x_dev * zldev,u8 index)221 zl3073x_dev_ref_freq_get(struct zl3073x_dev *zldev, u8 index)
222 {
223 const struct zl3073x_ref *ref = zl3073x_ref_state_get(zldev, index);
224
225 return zl3073x_ref_freq_get(ref);
226 }
227
228 /**
229 * zl3073x_dev_ref_is_diff - check if the given input reference is differential
230 * @zldev: pointer to zl3073x device
231 * @index: input reference index
232 *
233 * Return: true if reference is differential, false if reference is single-ended
234 */
235 static inline bool
zl3073x_dev_ref_is_diff(struct zl3073x_dev * zldev,u8 index)236 zl3073x_dev_ref_is_diff(struct zl3073x_dev *zldev, u8 index)
237 {
238 const struct zl3073x_ref *ref = zl3073x_ref_state_get(zldev, index);
239
240 return zl3073x_ref_is_diff(ref);
241 }
242
243 /*
244 * zl3073x_dev_ref_is_status_ok - check the given input reference status
245 * @zldev: pointer to zl3073x device
246 * @index: input reference index
247 *
248 * Return: true if the status is ok, false otherwise
249 */
250 static inline bool
zl3073x_dev_ref_is_status_ok(struct zl3073x_dev * zldev,u8 index)251 zl3073x_dev_ref_is_status_ok(struct zl3073x_dev *zldev, u8 index)
252 {
253 const struct zl3073x_ref *ref = zl3073x_ref_state_get(zldev, index);
254
255 return zl3073x_ref_is_status_ok(ref);
256 }
257
258 /**
259 * zl3073x_dev_synth_freq_get - get synth current freq
260 * @zldev: pointer to zl3073x device
261 * @index: synth index
262 *
263 * Return: frequency of given synthetizer
264 */
265 static inline u32
zl3073x_dev_synth_freq_get(struct zl3073x_dev * zldev,u8 index)266 zl3073x_dev_synth_freq_get(struct zl3073x_dev *zldev, u8 index)
267 {
268 const struct zl3073x_synth *synth;
269
270 synth = zl3073x_synth_state_get(zldev, index);
271 return zl3073x_synth_freq_get(synth);
272 }
273
274 /**
275 * zl3073x_dev_out_synth_get - get synth connected to given output
276 * @zldev: pointer to zl3073x device
277 * @index: output index
278 *
279 * Return: index of synth connected to given output.
280 */
281 static inline u8
zl3073x_dev_out_synth_get(struct zl3073x_dev * zldev,u8 index)282 zl3073x_dev_out_synth_get(struct zl3073x_dev *zldev, u8 index)
283 {
284 const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index);
285
286 return zl3073x_out_synth_get(out);
287 }
288
289 /**
290 * zl3073x_dev_out_is_enabled - check if the given output is enabled
291 * @zldev: pointer to zl3073x device
292 * @index: output index
293 *
294 * Return: true if the output is enabled, false otherwise
295 */
296 static inline bool
zl3073x_dev_out_is_enabled(struct zl3073x_dev * zldev,u8 index)297 zl3073x_dev_out_is_enabled(struct zl3073x_dev *zldev, u8 index)
298 {
299 const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index);
300 const struct zl3073x_synth *synth;
301 u8 synth_id;
302
303 /* Output is enabled only if associated synth is enabled */
304 synth_id = zl3073x_out_synth_get(out);
305 synth = zl3073x_synth_state_get(zldev, synth_id);
306
307 return zl3073x_synth_is_enabled(synth) && zl3073x_out_is_enabled(out);
308 }
309
310 /**
311 * zl3073x_dev_out_dpll_get - get DPLL ID the output is driven by
312 * @zldev: pointer to zl3073x device
313 * @index: output index
314 *
315 * Return: ID of DPLL the given output is driven by
316 */
317 static inline
zl3073x_dev_out_dpll_get(struct zl3073x_dev * zldev,u8 index)318 u8 zl3073x_dev_out_dpll_get(struct zl3073x_dev *zldev, u8 index)
319 {
320 const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index);
321 const struct zl3073x_synth *synth;
322 u8 synth_id;
323
324 /* Get synthesizer connected to given output */
325 synth_id = zl3073x_out_synth_get(out);
326 synth = zl3073x_synth_state_get(zldev, synth_id);
327
328 /* Return DPLL that drives the synth */
329 return zl3073x_synth_dpll_get(synth);
330 }
331
332 /**
333 * zl3073x_dev_output_pin_freq_get - get output pin frequency
334 * @zldev: pointer to zl3073x device
335 * @id: output pin id
336 *
337 * Computes the output pin frequency based on the synth frequency, output
338 * divisor, and signal format. For N-div formats, N-pin frequency is
339 * additionally divided by esync_n_period.
340 *
341 * Return: frequency of the given output pin in Hz
342 */
343 static inline u32
zl3073x_dev_output_pin_freq_get(struct zl3073x_dev * zldev,u8 id)344 zl3073x_dev_output_pin_freq_get(struct zl3073x_dev *zldev, u8 id)
345 {
346 const struct zl3073x_synth *synth;
347 const struct zl3073x_out *out;
348 u8 out_id;
349 u32 freq;
350
351 out_id = zl3073x_output_pin_out_get(id);
352 out = zl3073x_out_state_get(zldev, out_id);
353 synth = zl3073x_synth_state_get(zldev, zl3073x_out_synth_get(out));
354 freq = zl3073x_synth_freq_get(synth) / out->div;
355
356 if (zl3073x_out_is_ndiv(out) && zl3073x_is_n_pin(id))
357 freq /= out->esync_n_period;
358
359 return freq;
360 }
361
362 /**
363 * zl3073x_dev_out_is_diff - check if the given output is differential
364 * @zldev: pointer to zl3073x device
365 * @index: output index
366 *
367 * Return: true if output is differential, false if output is single-ended
368 */
369 static inline bool
zl3073x_dev_out_is_diff(struct zl3073x_dev * zldev,u8 index)370 zl3073x_dev_out_is_diff(struct zl3073x_dev *zldev, u8 index)
371 {
372 const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index);
373
374 return zl3073x_out_is_diff(out);
375 }
376
377 /**
378 * zl3073x_dev_output_pin_is_enabled - check if the given output pin is enabled
379 * @zldev: pointer to zl3073x device
380 * @id: output pin id
381 *
382 * Checks if the output of the given output pin is enabled and also that
383 * its signal format also enables the given pin.
384 *
385 * Return: true if output pin is enabled, false if output pin is disabled
386 */
387 static inline bool
zl3073x_dev_output_pin_is_enabled(struct zl3073x_dev * zldev,u8 id)388 zl3073x_dev_output_pin_is_enabled(struct zl3073x_dev *zldev, u8 id)
389 {
390 u8 out_id = zl3073x_output_pin_out_get(id);
391 const struct zl3073x_out *out;
392
393 out = zl3073x_out_state_get(zldev, out_id);
394
395 /* Check if the output is enabled - call _dev_ helper that
396 * additionally checks for attached synth enablement.
397 */
398 if (!zl3073x_dev_out_is_enabled(zldev, out_id))
399 return false;
400
401 /* Check signal format */
402 switch (zl3073x_out_signal_format_get(out)) {
403 case ZL_OUTPUT_MODE_SIGNAL_FORMAT_DISABLED:
404 /* Both output pins are disabled by signal format */
405 return false;
406
407 case ZL_OUTPUT_MODE_SIGNAL_FORMAT_1P:
408 /* Output is one single ended P-pin output */
409 if (zl3073x_is_n_pin(id))
410 return false;
411 break;
412 case ZL_OUTPUT_MODE_SIGNAL_FORMAT_1N:
413 /* Output is one single ended N-pin output */
414 if (zl3073x_is_p_pin(id))
415 return false;
416 break;
417 default:
418 /* For other format both pins are enabled */
419 break;
420 }
421
422 return true;
423 }
424
425 #endif /* _ZL3073X_CORE_H */
426