Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/dpll/zl3073x/core.h
51197 views
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_output_pin_freq_get - get output pin frequency
306
* @zldev: pointer to zl3073x device
307
* @id: output pin id
308
*
309
* Computes the output pin frequency based on the synth frequency, output
310
* divisor, and signal format. For N-div formats, N-pin frequency is
311
* additionally divided by esync_n_period.
312
*
313
* Return: frequency of the given output pin in Hz
314
*/
315
static inline u32
316
zl3073x_dev_output_pin_freq_get(struct zl3073x_dev *zldev, u8 id)
317
{
318
const struct zl3073x_synth *synth;
319
const struct zl3073x_out *out;
320
u8 out_id;
321
u32 freq;
322
323
out_id = zl3073x_output_pin_out_get(id);
324
out = zl3073x_out_state_get(zldev, out_id);
325
synth = zl3073x_synth_state_get(zldev, zl3073x_out_synth_get(out));
326
freq = zl3073x_synth_freq_get(synth) / out->div;
327
328
if (zl3073x_out_is_ndiv(out) && zl3073x_is_n_pin(id))
329
freq /= out->esync_n_period;
330
331
return freq;
332
}
333
334
/**
335
* zl3073x_dev_out_is_diff - check if the given output is differential
336
* @zldev: pointer to zl3073x device
337
* @index: output index
338
*
339
* Return: true if output is differential, false if output is single-ended
340
*/
341
static inline bool
342
zl3073x_dev_out_is_diff(struct zl3073x_dev *zldev, u8 index)
343
{
344
const struct zl3073x_out *out = zl3073x_out_state_get(zldev, index);
345
346
return zl3073x_out_is_diff(out);
347
}
348
349
/**
350
* zl3073x_dev_output_pin_is_enabled - check if the given output pin is enabled
351
* @zldev: pointer to zl3073x device
352
* @id: output pin id
353
*
354
* Checks if the output of the given output pin is enabled and also that
355
* its signal format also enables the given pin.
356
*
357
* Return: true if output pin is enabled, false if output pin is disabled
358
*/
359
static inline bool
360
zl3073x_dev_output_pin_is_enabled(struct zl3073x_dev *zldev, u8 id)
361
{
362
u8 out_id = zl3073x_output_pin_out_get(id);
363
const struct zl3073x_out *out;
364
365
out = zl3073x_out_state_get(zldev, out_id);
366
367
/* Check if the output is enabled - call _dev_ helper that
368
* additionally checks for attached synth enablement.
369
*/
370
if (!zl3073x_dev_out_is_enabled(zldev, out_id))
371
return false;
372
373
/* Check signal format */
374
switch (zl3073x_out_signal_format_get(out)) {
375
case ZL_OUTPUT_MODE_SIGNAL_FORMAT_DISABLED:
376
/* Both output pins are disabled by signal format */
377
return false;
378
379
case ZL_OUTPUT_MODE_SIGNAL_FORMAT_1P:
380
/* Output is one single ended P-pin output */
381
if (zl3073x_is_n_pin(id))
382
return false;
383
break;
384
case ZL_OUTPUT_MODE_SIGNAL_FORMAT_1N:
385
/* Output is one single ended N-pin output */
386
if (zl3073x_is_p_pin(id))
387
return false;
388
break;
389
default:
390
/* For other format both pins are enabled */
391
break;
392
}
393
394
return true;
395
}
396
397
#endif /* _ZL3073X_CORE_H */
398
399