xref: /linux/drivers/dpll/zl3073x/out.h (revision 53597deca0e38c30e6cd4ba2114fa42d2bcd85bb)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef _ZL3073X_OUT_H
4 #define _ZL3073X_OUT_H
5 
6 #include <linux/bitfield.h>
7 #include <linux/stddef.h>
8 #include <linux/types.h>
9 
10 #include "regs.h"
11 
12 struct zl3073x_dev;
13 
14 /**
15  * struct zl3073x_out - output state
16  * @div: output divisor
17  * @width: output pulse width
18  * @esync_n_period: embedded sync or n-pin period (for n-div formats)
19  * @esync_n_width: embedded sync or n-pin pulse width
20  * @phase_comp: phase compensation
21  * @mode: output mode
22  * @ctrl: output control
23  */
24 struct zl3073x_out {
25 	struct_group(cfg, /* Config */
26 		u32	div;
27 		u32	width;
28 		u32	esync_n_period;
29 		u32	esync_n_width;
30 		s32	phase_comp;
31 		u8	mode;
32 	);
33 	struct_group(inv, /* Invariants */
34 		u8	ctrl;
35 	);
36 };
37 
38 int zl3073x_out_state_fetch(struct zl3073x_dev *zldev, u8 index);
39 const struct zl3073x_out *zl3073x_out_state_get(struct zl3073x_dev *zldev,
40 						u8 index);
41 
42 int zl3073x_out_state_set(struct zl3073x_dev *zldev, u8 index,
43 			  const struct zl3073x_out *out);
44 
45 /**
46  * zl3073x_out_clock_type_get - get output clock type
47  * @out: pointer to out state
48  *
49  * Return: clock type of given output (ZL_OUTPUT_MODE_CLOCK_TYPE_*)
50  */
51 static inline u8 zl3073x_out_clock_type_get(const struct zl3073x_out *out)
52 {
53 	return FIELD_GET(ZL_OUTPUT_MODE_CLOCK_TYPE, out->mode);
54 }
55 
56 /**
57  * zl3073x_out_clock_type_set - set output clock type
58  * @out: pointer to out state
59  * @type: clock type (ZL_OUTPUT_MODE_CLOCK_TYPE_*)
60  */
61 static inline void
62 zl3073x_out_clock_type_set(struct zl3073x_out *out, u8 type)
63 {
64 	FIELD_MODIFY(ZL_OUTPUT_MODE_CLOCK_TYPE, &out->mode, type);
65 }
66 
67 /**
68  * zl3073x_out_signal_format_get - get output signal format
69  * @out: pointer to out state
70  *
71  * Return: signal format of given output
72  */
73 static inline u8 zl3073x_out_signal_format_get(const struct zl3073x_out *out)
74 {
75 	return FIELD_GET(ZL_OUTPUT_MODE_SIGNAL_FORMAT, out->mode);
76 }
77 
78 /**
79  * zl3073x_out_is_diff - check if the given output is differential
80  * @out: pointer to out state
81  *
82  * Return: true if output is differential, false if output is single-ended
83  */
84 static inline bool zl3073x_out_is_diff(const struct zl3073x_out *out)
85 {
86 	switch (zl3073x_out_signal_format_get(out)) {
87 	case ZL_OUTPUT_MODE_SIGNAL_FORMAT_LVDS:
88 	case ZL_OUTPUT_MODE_SIGNAL_FORMAT_DIFF:
89 	case ZL_OUTPUT_MODE_SIGNAL_FORMAT_LOWVCM:
90 		return true;
91 	default:
92 		break;
93 	}
94 
95 	return false;
96 }
97 
98 /**
99  * zl3073x_out_is_enabled - check if the given output is enabled
100  * @out: pointer to out state
101  *
102  * Return: true if output is enabled, false if output is disabled
103  */
104 static inline bool zl3073x_out_is_enabled(const struct zl3073x_out *out)
105 {
106 	return !!FIELD_GET(ZL_OUTPUT_CTRL_EN, out->ctrl);
107 }
108 
109 /**
110  * zl3073x_out_is_ndiv - check if the given output is in N-div mode
111  * @out: pointer to out state
112  *
113  * Return: true if output is in N-div mode, false otherwise
114  */
115 static inline bool zl3073x_out_is_ndiv(const struct zl3073x_out *out)
116 {
117 	switch (zl3073x_out_signal_format_get(out)) {
118 	case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV:
119 	case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV:
120 		return true;
121 	default:
122 		return false;
123 	}
124 }
125 
126 /**
127  * zl3073x_out_synth_get - get synth connected to given output
128  * @out: pointer to out state
129  *
130  * Return: index of synth connected to given output.
131  */
132 static inline u8 zl3073x_out_synth_get(const struct zl3073x_out *out)
133 {
134 	return FIELD_GET(ZL_OUTPUT_CTRL_SYNTH_SEL, out->ctrl);
135 }
136 
137 #endif /* _ZL3073X_OUT_H */
138