1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _ZL3073X_REF_H
#define _ZL3073X_REF_H
#include <linux/bitfield.h>
#include <linux/math64.h>
#include <linux/stddef.h>
#include <linux/types.h>
#include "regs.h"
struct zl3073x_dev;
/**
* struct zl3073x_ref - input reference state
* @phase_comp: phase compensation
* @esync_n_div: divisor for embedded sync or n-divided signal formats
* @freq_base: frequency base
* @freq_mult: frequnecy multiplier
* @freq_ratio_m: FEC mode multiplier
* @freq_ratio_n: FEC mode divisor
* @sync_ctrl: reference sync control
* @config: reference config
* @ffo: current fractional frequency offset
* @meas_freq: measured input frequency in Hz
* @mon_status: reference monitor status
*/
struct zl3073x_ref {
struct_group(cfg, /* Configuration */
u64 phase_comp;
u32 esync_n_div;
u16 freq_base;
u16 freq_mult;
u16 freq_ratio_m;
u16 freq_ratio_n;
u8 sync_ctrl;
);
struct_group(inv, /* Invariants */
u8 config;
);
struct_group(stat, /* Status */
s64 ffo;
u32 meas_freq;
u8 mon_status;
);
};
int zl3073x_ref_state_fetch(struct zl3073x_dev *zldev, u8 index);
const struct zl3073x_ref *zl3073x_ref_state_get(struct zl3073x_dev *zldev,
u8 index);
int zl3073x_ref_state_set(struct zl3073x_dev *zldev, u8 index,
const struct zl3073x_ref *ref);
int zl3073x_ref_state_update(struct zl3073x_dev *zldev, u8 index);
int zl3073x_ref_freq_factorize(u32 freq, u16 *base, u16 *mult);
/**
* zl3073x_ref_ffo_get - get current fractional frequency offset
* @ref: pointer to ref state
*
* Return: the latest measured fractional frequency offset
*/
static inline s64
zl3073x_ref_ffo_get(const struct zl3073x_ref *ref)
{
return ref->ffo;
}
/**
* zl3073x_ref_meas_freq_get - get measured input frequency
* @ref: pointer to ref state
*
* Return: measured input frequency in Hz
*/
static inline u32
zl3073x_ref_meas_freq_get(const struct zl3073x_ref *ref)
{
return ref->meas_freq;
}
/**
* zl3073x_ref_freq_get - get given input reference frequency
* @ref: pointer to ref state
*
* Return: frequency of the given input reference
*/
static inline u32
zl3073x_ref_freq_get(const struct zl3073x_ref *ref)
{
return mul_u64_u32_div(ref->freq_base * ref->freq_mult,
ref->freq_ratio_m, ref->freq_ratio_n);
}
/**
* zl3073x_ref_freq_set - set given input reference frequency
* @ref: pointer to ref state
* @freq: frequency to be set
*
* Return: 0 on success, <0 when frequency cannot be factorized
*/
static inline int
zl3073x_ref_freq_set(struct zl3073x_ref *ref, u32 freq)
{
u16 base, mult;
int rc;
rc = zl3073x_ref_freq_factorize(freq, &base, &mult);
if (rc)
return rc;
ref->freq_base = base;
ref->freq_mult = mult;
ref->freq_ratio_m = 1;
ref->freq_ratio_n = 1;
return 0;
}
/**
* zl3073x_ref_sync_mode_get - get sync control mode
* @ref: pointer to ref state
*
* Return: sync control mode (ZL_REF_SYNC_CTRL_MODE_*)
*/
static inline u8
zl3073x_ref_sync_mode_get(const struct zl3073x_ref *ref)
{
return FIELD_GET(ZL_REF_SYNC_CTRL_MODE, ref->sync_ctrl);
}
/**
* zl3073x_ref_sync_mode_set - set sync control mode
* @ref: pointer to ref state
* @mode: sync control mode (ZL_REF_SYNC_CTRL_MODE_*)
*/
static inline void
zl3073x_ref_sync_mode_set(struct zl3073x_ref *ref, u8 mode)
{
FIELD_MODIFY(ZL_REF_SYNC_CTRL_MODE, &ref->sync_ctrl, mode);
}
/**
* zl3073x_ref_sync_pair_get - get sync pair reference index
* @ref: pointer to ref state
*
* Return: paired reference index
*/
static inline u8
zl3073x_ref_sync_pair_get(const struct zl3073x_ref *ref)
{
return FIELD_GET(ZL_REF_SYNC_CTRL_PAIR, ref->sync_ctrl);
}
/**
* zl3073x_ref_sync_pair_set - set sync pair reference index
* @ref: pointer to ref state
* @pair: paired reference index
*/
static inline void
zl3073x_ref_sync_pair_set(struct zl3073x_ref *ref, u8 pair)
{
FIELD_MODIFY(ZL_REF_SYNC_CTRL_PAIR, &ref->sync_ctrl, pair);
}
/**
* zl3073x_ref_is_diff - check if the given input reference is differential
* @ref: pointer to ref state
*
* Return: true if reference is differential, false if reference is single-ended
*/
static inline bool
zl3073x_ref_is_diff(const struct zl3073x_ref *ref)
{
return !!FIELD_GET(ZL_REF_CONFIG_DIFF_EN, ref->config);
}
/**
* zl3073x_ref_is_enabled - check if the given input reference is enabled
* @ref: pointer to ref state
*
* Return: true if input refernce is enabled, false otherwise
*/
static inline bool
zl3073x_ref_is_enabled(const struct zl3073x_ref *ref)
{
return !!FIELD_GET(ZL_REF_CONFIG_ENABLE, ref->config);
}
/**
* zl3073x_ref_is_status_ok - check the given input reference status
* @ref: pointer to ref state
*
* Return: true if the status is ok, false otherwise
*/
static inline bool
zl3073x_ref_is_status_ok(const struct zl3073x_ref *ref)
{
return ref->mon_status == ZL_REF_MON_STATUS_OK;
}
#endif /* _ZL3073X_REF_H */
|