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
|
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _ZL3073X_CHAN_H
#define _ZL3073X_CHAN_H
#include <linux/bitfield.h>
#include <linux/stddef.h>
#include <linux/types.h>
#include "regs.h"
struct zl3073x_dev;
/**
* struct zl3073x_chan - DPLL channel state
* @mode_refsel: mode and reference selection register value
* @ref_prio: reference priority registers (4 bits per ref, P/N packed)
* @mon_status: monitor status register value
* @refsel_status: reference selection status register value
*/
struct zl3073x_chan {
struct_group(cfg,
u8 mode_refsel;
u8 ref_prio[ZL3073X_NUM_REFS / 2];
);
struct_group(stat,
u8 mon_status;
u8 refsel_status;
);
};
int zl3073x_chan_state_fetch(struct zl3073x_dev *zldev, u8 index);
const struct zl3073x_chan *zl3073x_chan_state_get(struct zl3073x_dev *zldev,
u8 index);
int zl3073x_chan_state_set(struct zl3073x_dev *zldev, u8 index,
const struct zl3073x_chan *chan);
int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index);
/**
* zl3073x_chan_mode_get - get DPLL channel operating mode
* @chan: pointer to channel state
*
* Return: reference selection mode of the given DPLL channel
*/
static inline u8 zl3073x_chan_mode_get(const struct zl3073x_chan *chan)
{
return FIELD_GET(ZL_DPLL_MODE_REFSEL_MODE, chan->mode_refsel);
}
/**
* zl3073x_chan_ref_get - get manually selected reference
* @chan: pointer to channel state
*
* Return: reference selected in forced reference lock mode
*/
static inline u8 zl3073x_chan_ref_get(const struct zl3073x_chan *chan)
{
return FIELD_GET(ZL_DPLL_MODE_REFSEL_REF, chan->mode_refsel);
}
/**
* zl3073x_chan_mode_set - set DPLL channel operating mode
* @chan: pointer to channel state
* @mode: mode to set
*/
static inline void zl3073x_chan_mode_set(struct zl3073x_chan *chan, u8 mode)
{
FIELD_MODIFY(ZL_DPLL_MODE_REFSEL_MODE, &chan->mode_refsel, mode);
}
/**
* zl3073x_chan_ref_set - set manually selected reference
* @chan: pointer to channel state
* @ref: reference to set
*/
static inline void zl3073x_chan_ref_set(struct zl3073x_chan *chan, u8 ref)
{
FIELD_MODIFY(ZL_DPLL_MODE_REFSEL_REF, &chan->mode_refsel, ref);
}
/**
* zl3073x_chan_ref_prio_get - get reference priority
* @chan: pointer to channel state
* @ref: input reference index
*
* Return: priority of the given reference <0, 15>
*/
static inline u8
zl3073x_chan_ref_prio_get(const struct zl3073x_chan *chan, u8 ref)
{
u8 val = chan->ref_prio[ref / 2];
if (!(ref & 1))
return FIELD_GET(ZL_DPLL_REF_PRIO_REF_P, val);
else
return FIELD_GET(ZL_DPLL_REF_PRIO_REF_N, val);
}
/**
* zl3073x_chan_ref_prio_set - set reference priority
* @chan: pointer to channel state
* @ref: input reference index
* @prio: priority to set
*/
static inline void
zl3073x_chan_ref_prio_set(struct zl3073x_chan *chan, u8 ref, u8 prio)
{
u8 *val = &chan->ref_prio[ref / 2];
if (!(ref & 1))
FIELD_MODIFY(ZL_DPLL_REF_PRIO_REF_P, val, prio);
else
FIELD_MODIFY(ZL_DPLL_REF_PRIO_REF_N, val, prio);
}
/**
* zl3073x_chan_ref_is_selectable - check if reference is selectable
* @chan: pointer to channel state
* @ref: input reference index
*
* Return: true if the reference priority is not NONE, false otherwise
*/
static inline bool
zl3073x_chan_ref_is_selectable(const struct zl3073x_chan *chan, u8 ref)
{
return zl3073x_chan_ref_prio_get(chan, ref) != ZL_DPLL_REF_PRIO_NONE;
}
/**
* zl3073x_chan_lock_state_get - get DPLL channel lock state
* @chan: pointer to channel state
*
* Return: lock state of the given DPLL channel
*/
static inline u8 zl3073x_chan_lock_state_get(const struct zl3073x_chan *chan)
{
return FIELD_GET(ZL_DPLL_MON_STATUS_STATE, chan->mon_status);
}
/**
* zl3073x_chan_is_ho_ready - check if holdover is ready
* @chan: pointer to channel state
*
* Return: true if holdover is ready, false otherwise
*/
static inline bool zl3073x_chan_is_ho_ready(const struct zl3073x_chan *chan)
{
return !!FIELD_GET(ZL_DPLL_MON_STATUS_HO_READY, chan->mon_status);
}
/**
* zl3073x_chan_refsel_state_get - get reference selection state
* @chan: pointer to channel state
*
* Return: reference selection state of the given DPLL channel
*/
static inline u8 zl3073x_chan_refsel_state_get(const struct zl3073x_chan *chan)
{
return FIELD_GET(ZL_DPLL_REFSEL_STATUS_STATE, chan->refsel_status);
}
/**
* zl3073x_chan_refsel_ref_get - get currently selected reference in auto mode
* @chan: pointer to channel state
*
* Return: reference selected by the DPLL in automatic mode
*/
static inline u8 zl3073x_chan_refsel_ref_get(const struct zl3073x_chan *chan)
{
return FIELD_GET(ZL_DPLL_REFSEL_STATUS_REFSEL, chan->refsel_status);
}
#endif /* _ZL3073X_CHAN_H */
|