1a99a9f0eSIvan Vecera // SPDX-License-Identifier: GPL-2.0-only
2a99a9f0eSIvan Vecera
3a99a9f0eSIvan Vecera #include <linux/array_size.h>
4a99a9f0eSIvan Vecera #include <linux/dev_printk.h>
5a99a9f0eSIvan Vecera #include <linux/err.h>
6a99a9f0eSIvan Vecera #include <linux/errno.h>
7a99a9f0eSIvan Vecera #include <linux/fwnode.h>
8a99a9f0eSIvan Vecera #include <linux/property.h>
9a99a9f0eSIvan Vecera #include <linux/slab.h>
10a99a9f0eSIvan Vecera #include <linux/string.h>
11a99a9f0eSIvan Vecera
12a99a9f0eSIvan Vecera #include "core.h"
13a99a9f0eSIvan Vecera #include "prop.h"
14a99a9f0eSIvan Vecera
15a99a9f0eSIvan Vecera /**
16a99a9f0eSIvan Vecera * zl3073x_pin_check_freq - verify frequency for given pin
17a99a9f0eSIvan Vecera * @zldev: pointer to zl3073x device
18a99a9f0eSIvan Vecera * @dir: pin direction
19a99a9f0eSIvan Vecera * @id: pin index
20a99a9f0eSIvan Vecera * @freq: frequency to check
21a99a9f0eSIvan Vecera *
22a99a9f0eSIvan Vecera * The function checks the given frequency is valid for the device. For input
23a99a9f0eSIvan Vecera * pins it checks that the frequency can be factorized using supported base
24a99a9f0eSIvan Vecera * frequencies. For output pins it checks that the frequency divides connected
25a99a9f0eSIvan Vecera * synth frequency without remainder.
26a99a9f0eSIvan Vecera *
27a99a9f0eSIvan Vecera * Return: true if the frequency is valid, false if not.
28a99a9f0eSIvan Vecera */
29a99a9f0eSIvan Vecera static bool
zl3073x_pin_check_freq(struct zl3073x_dev * zldev,enum dpll_pin_direction dir,u8 id,u64 freq)30a99a9f0eSIvan Vecera zl3073x_pin_check_freq(struct zl3073x_dev *zldev, enum dpll_pin_direction dir,
31a99a9f0eSIvan Vecera u8 id, u64 freq)
32a99a9f0eSIvan Vecera {
33a99a9f0eSIvan Vecera if (freq > U32_MAX)
34a99a9f0eSIvan Vecera goto err_inv_freq;
35a99a9f0eSIvan Vecera
36a99a9f0eSIvan Vecera if (dir == DPLL_PIN_DIRECTION_INPUT) {
37a99a9f0eSIvan Vecera int rc;
38a99a9f0eSIvan Vecera
39a99a9f0eSIvan Vecera /* Check if the frequency can be factorized */
40a99a9f0eSIvan Vecera rc = zl3073x_ref_freq_factorize(freq, NULL, NULL);
41a99a9f0eSIvan Vecera if (rc)
42a99a9f0eSIvan Vecera goto err_inv_freq;
43a99a9f0eSIvan Vecera } else {
44a99a9f0eSIvan Vecera u32 synth_freq;
45a99a9f0eSIvan Vecera u8 out, synth;
46a99a9f0eSIvan Vecera
47a99a9f0eSIvan Vecera /* Get output pin synthesizer */
48a99a9f0eSIvan Vecera out = zl3073x_output_pin_out_get(id);
49a99a9f0eSIvan Vecera synth = zl3073x_out_synth_get(zldev, out);
50a99a9f0eSIvan Vecera
51a99a9f0eSIvan Vecera /* Get synth frequency */
52a99a9f0eSIvan Vecera synth_freq = zl3073x_synth_freq_get(zldev, synth);
53a99a9f0eSIvan Vecera
54a99a9f0eSIvan Vecera /* Check the frequency divides synth frequency */
55a99a9f0eSIvan Vecera if (synth_freq % (u32)freq)
56a99a9f0eSIvan Vecera goto err_inv_freq;
57a99a9f0eSIvan Vecera }
58a99a9f0eSIvan Vecera
59a99a9f0eSIvan Vecera return true;
60a99a9f0eSIvan Vecera
61a99a9f0eSIvan Vecera err_inv_freq:
62a99a9f0eSIvan Vecera dev_warn(zldev->dev,
63a99a9f0eSIvan Vecera "Unsupported frequency %llu Hz in firmware node\n", freq);
64a99a9f0eSIvan Vecera
65a99a9f0eSIvan Vecera return false;
66a99a9f0eSIvan Vecera }
67a99a9f0eSIvan Vecera
68a99a9f0eSIvan Vecera /**
69a99a9f0eSIvan Vecera * zl3073x_prop_pin_package_label_set - get package label for the pin
70a99a9f0eSIvan Vecera * @zldev: pointer to zl3073x device
71a99a9f0eSIvan Vecera * @props: pointer to pin properties
72a99a9f0eSIvan Vecera * @dir: pin direction
73a99a9f0eSIvan Vecera * @id: pin index
74a99a9f0eSIvan Vecera *
75a99a9f0eSIvan Vecera * Generates package label string and stores it into pin properties structure.
76a99a9f0eSIvan Vecera *
77a99a9f0eSIvan Vecera * Possible formats:
78a99a9f0eSIvan Vecera * REF<n> - differential input reference
79a99a9f0eSIvan Vecera * REF<n>P & REF<n>N - single-ended input reference (P or N pin)
80a99a9f0eSIvan Vecera * OUT<n> - differential output
81a99a9f0eSIvan Vecera * OUT<n>P & OUT<n>N - single-ended output (P or N pin)
82a99a9f0eSIvan Vecera */
83a99a9f0eSIvan Vecera static void
zl3073x_prop_pin_package_label_set(struct zl3073x_dev * zldev,struct zl3073x_pin_props * props,enum dpll_pin_direction dir,u8 id)84a99a9f0eSIvan Vecera zl3073x_prop_pin_package_label_set(struct zl3073x_dev *zldev,
85a99a9f0eSIvan Vecera struct zl3073x_pin_props *props,
86a99a9f0eSIvan Vecera enum dpll_pin_direction dir, u8 id)
87a99a9f0eSIvan Vecera {
88a99a9f0eSIvan Vecera const char *prefix, *suffix;
89a99a9f0eSIvan Vecera bool is_diff;
90a99a9f0eSIvan Vecera
91a99a9f0eSIvan Vecera if (dir == DPLL_PIN_DIRECTION_INPUT) {
92a99a9f0eSIvan Vecera u8 ref;
93a99a9f0eSIvan Vecera
94a99a9f0eSIvan Vecera prefix = "REF";
95a99a9f0eSIvan Vecera ref = zl3073x_input_pin_ref_get(id);
96a99a9f0eSIvan Vecera is_diff = zl3073x_ref_is_diff(zldev, ref);
97a99a9f0eSIvan Vecera } else {
98a99a9f0eSIvan Vecera u8 out;
99a99a9f0eSIvan Vecera
100a99a9f0eSIvan Vecera prefix = "OUT";
101a99a9f0eSIvan Vecera out = zl3073x_output_pin_out_get(id);
102a99a9f0eSIvan Vecera is_diff = zl3073x_out_is_diff(zldev, out);
103a99a9f0eSIvan Vecera }
104a99a9f0eSIvan Vecera
105a99a9f0eSIvan Vecera if (!is_diff)
106a99a9f0eSIvan Vecera suffix = zl3073x_is_p_pin(id) ? "P" : "N";
107a99a9f0eSIvan Vecera else
108a99a9f0eSIvan Vecera suffix = ""; /* No suffix for differential one */
109a99a9f0eSIvan Vecera
110a99a9f0eSIvan Vecera snprintf(props->package_label, sizeof(props->package_label), "%s%u%s",
111a99a9f0eSIvan Vecera prefix, id / 2, suffix);
112a99a9f0eSIvan Vecera
113a99a9f0eSIvan Vecera /* Set package_label pointer in DPLL core properties to generated
114a99a9f0eSIvan Vecera * string.
115a99a9f0eSIvan Vecera */
116a99a9f0eSIvan Vecera props->dpll_props.package_label = props->package_label;
117a99a9f0eSIvan Vecera }
118a99a9f0eSIvan Vecera
119a99a9f0eSIvan Vecera /**
120a99a9f0eSIvan Vecera * zl3073x_prop_pin_fwnode_get - get fwnode for given pin
121a99a9f0eSIvan Vecera * @zldev: pointer to zl3073x device
122a99a9f0eSIvan Vecera * @props: pointer to pin properties
123a99a9f0eSIvan Vecera * @dir: pin direction
124a99a9f0eSIvan Vecera * @id: pin index
125a99a9f0eSIvan Vecera *
126a99a9f0eSIvan Vecera * Return: 0 on success, -ENOENT if the firmware node does not exist
127a99a9f0eSIvan Vecera */
128a99a9f0eSIvan Vecera static int
zl3073x_prop_pin_fwnode_get(struct zl3073x_dev * zldev,struct zl3073x_pin_props * props,enum dpll_pin_direction dir,u8 id)129a99a9f0eSIvan Vecera zl3073x_prop_pin_fwnode_get(struct zl3073x_dev *zldev,
130a99a9f0eSIvan Vecera struct zl3073x_pin_props *props,
131a99a9f0eSIvan Vecera enum dpll_pin_direction dir, u8 id)
132a99a9f0eSIvan Vecera {
133a99a9f0eSIvan Vecera struct fwnode_handle *pins_node, *pin_node;
134a99a9f0eSIvan Vecera const char *node_name;
135a99a9f0eSIvan Vecera
136a99a9f0eSIvan Vecera if (dir == DPLL_PIN_DIRECTION_INPUT)
137a99a9f0eSIvan Vecera node_name = "input-pins";
138a99a9f0eSIvan Vecera else
139a99a9f0eSIvan Vecera node_name = "output-pins";
140a99a9f0eSIvan Vecera
141a99a9f0eSIvan Vecera /* Get node containing input or output pins */
142a99a9f0eSIvan Vecera pins_node = device_get_named_child_node(zldev->dev, node_name);
143a99a9f0eSIvan Vecera if (!pins_node) {
144a99a9f0eSIvan Vecera dev_dbg(zldev->dev, "'%s' sub-node is missing\n", node_name);
145a99a9f0eSIvan Vecera return -ENOENT;
146a99a9f0eSIvan Vecera }
147a99a9f0eSIvan Vecera
148a99a9f0eSIvan Vecera /* Enumerate child pin nodes and find the requested one */
149a99a9f0eSIvan Vecera fwnode_for_each_child_node(pins_node, pin_node) {
150a99a9f0eSIvan Vecera u32 reg;
151a99a9f0eSIvan Vecera
152a99a9f0eSIvan Vecera if (fwnode_property_read_u32(pin_node, "reg", ®))
153a99a9f0eSIvan Vecera continue;
154a99a9f0eSIvan Vecera
155a99a9f0eSIvan Vecera if (id == reg)
156a99a9f0eSIvan Vecera break;
157a99a9f0eSIvan Vecera }
158a99a9f0eSIvan Vecera
159a99a9f0eSIvan Vecera /* Release pin parent node */
160a99a9f0eSIvan Vecera fwnode_handle_put(pins_node);
161a99a9f0eSIvan Vecera
162a99a9f0eSIvan Vecera /* Save found node */
163a99a9f0eSIvan Vecera props->fwnode = pin_node;
164a99a9f0eSIvan Vecera
165a99a9f0eSIvan Vecera dev_dbg(zldev->dev, "Firmware node for %s %sfound\n",
166a99a9f0eSIvan Vecera props->package_label, pin_node ? "" : "NOT ");
167a99a9f0eSIvan Vecera
168a99a9f0eSIvan Vecera return pin_node ? 0 : -ENOENT;
169a99a9f0eSIvan Vecera }
170a99a9f0eSIvan Vecera
171a99a9f0eSIvan Vecera /**
172a99a9f0eSIvan Vecera * zl3073x_pin_props_get - get pin properties
173a99a9f0eSIvan Vecera * @zldev: pointer to zl3073x device
174a99a9f0eSIvan Vecera * @dir: pin direction
175a99a9f0eSIvan Vecera * @index: pin index
176a99a9f0eSIvan Vecera *
177a99a9f0eSIvan Vecera * The function looks for firmware node for the given pin if it is provided
178a99a9f0eSIvan Vecera * by the system firmware (DT or ACPI), allocates pin properties structure,
179a99a9f0eSIvan Vecera * generates package label string according pin type and optionally fetches
180a99a9f0eSIvan Vecera * board label, connection type, supported frequencies and esync capability
181a99a9f0eSIvan Vecera * from the firmware node if it does exist.
182a99a9f0eSIvan Vecera *
183a99a9f0eSIvan Vecera * Pointer that is returned by this function should be freed using
184a99a9f0eSIvan Vecera * @zl3073x_pin_props_put().
185a99a9f0eSIvan Vecera *
186a99a9f0eSIvan Vecera * Return:
187a99a9f0eSIvan Vecera * * pointer to allocated pin properties structure on success
188a99a9f0eSIvan Vecera * * error pointer in case of error
189a99a9f0eSIvan Vecera */
zl3073x_pin_props_get(struct zl3073x_dev * zldev,enum dpll_pin_direction dir,u8 index)190a99a9f0eSIvan Vecera struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev,
191a99a9f0eSIvan Vecera enum dpll_pin_direction dir,
192a99a9f0eSIvan Vecera u8 index)
193a99a9f0eSIvan Vecera {
194a99a9f0eSIvan Vecera struct dpll_pin_frequency *ranges;
195a99a9f0eSIvan Vecera struct zl3073x_pin_props *props;
196a99a9f0eSIvan Vecera int i, j, num_freqs, rc;
197a99a9f0eSIvan Vecera const char *type;
198a99a9f0eSIvan Vecera u64 *freqs;
199a99a9f0eSIvan Vecera
200a99a9f0eSIvan Vecera props = kzalloc(sizeof(*props), GFP_KERNEL);
201a99a9f0eSIvan Vecera if (!props)
202a99a9f0eSIvan Vecera return ERR_PTR(-ENOMEM);
203a99a9f0eSIvan Vecera
2049686c8b0SIvan Vecera /* Set default pin type and capabilities */
2059686c8b0SIvan Vecera if (dir == DPLL_PIN_DIRECTION_INPUT) {
206a99a9f0eSIvan Vecera props->dpll_props.type = DPLL_PIN_TYPE_EXT;
2079686c8b0SIvan Vecera props->dpll_props.capabilities =
208*12ba92f0SIvan Vecera DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
2099686c8b0SIvan Vecera DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
2109686c8b0SIvan Vecera } else {
211a99a9f0eSIvan Vecera props->dpll_props.type = DPLL_PIN_TYPE_GNSS;
2129686c8b0SIvan Vecera }
213a99a9f0eSIvan Vecera
214a99a9f0eSIvan Vecera props->dpll_props.phase_range.min = S32_MIN;
215a99a9f0eSIvan Vecera props->dpll_props.phase_range.max = S32_MAX;
216a99a9f0eSIvan Vecera
217a99a9f0eSIvan Vecera zl3073x_prop_pin_package_label_set(zldev, props, dir, index);
218a99a9f0eSIvan Vecera
219a99a9f0eSIvan Vecera /* Get firmware node for the given pin */
220a99a9f0eSIvan Vecera rc = zl3073x_prop_pin_fwnode_get(zldev, props, dir, index);
221a99a9f0eSIvan Vecera if (rc)
222a99a9f0eSIvan Vecera return props; /* Return if it does not exist */
223a99a9f0eSIvan Vecera
224a99a9f0eSIvan Vecera /* Look for label property and store the value as board label */
225a99a9f0eSIvan Vecera fwnode_property_read_string(props->fwnode, "label",
226a99a9f0eSIvan Vecera &props->dpll_props.board_label);
227a99a9f0eSIvan Vecera
228a99a9f0eSIvan Vecera /* Look for pin type property and translate its value to DPLL
229a99a9f0eSIvan Vecera * pin type enum if it is present.
230a99a9f0eSIvan Vecera */
231a99a9f0eSIvan Vecera if (!fwnode_property_read_string(props->fwnode, "connection-type",
232a99a9f0eSIvan Vecera &type)) {
233a99a9f0eSIvan Vecera if (!strcmp(type, "ext"))
234a99a9f0eSIvan Vecera props->dpll_props.type = DPLL_PIN_TYPE_EXT;
235a99a9f0eSIvan Vecera else if (!strcmp(type, "gnss"))
236a99a9f0eSIvan Vecera props->dpll_props.type = DPLL_PIN_TYPE_GNSS;
237a99a9f0eSIvan Vecera else if (!strcmp(type, "int"))
238a99a9f0eSIvan Vecera props->dpll_props.type = DPLL_PIN_TYPE_INT_OSCILLATOR;
239a99a9f0eSIvan Vecera else if (!strcmp(type, "synce"))
240a99a9f0eSIvan Vecera props->dpll_props.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT;
241a99a9f0eSIvan Vecera else
242a99a9f0eSIvan Vecera dev_warn(zldev->dev,
243a99a9f0eSIvan Vecera "Unknown or unsupported pin type '%s'\n",
244a99a9f0eSIvan Vecera type);
245a99a9f0eSIvan Vecera }
246a99a9f0eSIvan Vecera
247a99a9f0eSIvan Vecera /* Check if the pin supports embedded sync control */
248a99a9f0eSIvan Vecera props->esync_control = fwnode_property_read_bool(props->fwnode,
249a99a9f0eSIvan Vecera "esync-control");
250a99a9f0eSIvan Vecera
251a99a9f0eSIvan Vecera /* Read supported frequencies property if it is specified */
252a99a9f0eSIvan Vecera num_freqs = fwnode_property_count_u64(props->fwnode,
253a99a9f0eSIvan Vecera "supported-frequencies-hz");
254a99a9f0eSIvan Vecera if (num_freqs <= 0)
255a99a9f0eSIvan Vecera /* Return if the property does not exist or number is 0 */
256a99a9f0eSIvan Vecera return props;
257a99a9f0eSIvan Vecera
258a99a9f0eSIvan Vecera /* The firmware node specifies list of supported frequencies while
259a99a9f0eSIvan Vecera * DPLL core pin properties requires list of frequency ranges.
260a99a9f0eSIvan Vecera * So read the frequency list into temporary array.
261a99a9f0eSIvan Vecera */
262a99a9f0eSIvan Vecera freqs = kcalloc(num_freqs, sizeof(*freqs), GFP_KERNEL);
263a99a9f0eSIvan Vecera if (!freqs) {
264a99a9f0eSIvan Vecera rc = -ENOMEM;
265a99a9f0eSIvan Vecera goto err_alloc_freqs;
266a99a9f0eSIvan Vecera }
267a99a9f0eSIvan Vecera
268a99a9f0eSIvan Vecera /* Read frequencies list from firmware node */
269a99a9f0eSIvan Vecera fwnode_property_read_u64_array(props->fwnode,
270a99a9f0eSIvan Vecera "supported-frequencies-hz", freqs,
271a99a9f0eSIvan Vecera num_freqs);
272a99a9f0eSIvan Vecera
273a99a9f0eSIvan Vecera /* Allocate frequency ranges list and fill it */
274a99a9f0eSIvan Vecera ranges = kcalloc(num_freqs, sizeof(*ranges), GFP_KERNEL);
275a99a9f0eSIvan Vecera if (!ranges) {
276a99a9f0eSIvan Vecera rc = -ENOMEM;
277a99a9f0eSIvan Vecera goto err_alloc_ranges;
278a99a9f0eSIvan Vecera }
279a99a9f0eSIvan Vecera
280a99a9f0eSIvan Vecera /* Convert list of frequencies to list of frequency ranges but
281a99a9f0eSIvan Vecera * filter-out frequencies that are not representable by device
282a99a9f0eSIvan Vecera */
283a99a9f0eSIvan Vecera for (i = 0, j = 0; i < num_freqs; i++) {
284a99a9f0eSIvan Vecera struct dpll_pin_frequency freq = DPLL_PIN_FREQUENCY(freqs[i]);
285a99a9f0eSIvan Vecera
286a99a9f0eSIvan Vecera if (zl3073x_pin_check_freq(zldev, dir, index, freqs[i])) {
287a99a9f0eSIvan Vecera ranges[j] = freq;
288a99a9f0eSIvan Vecera j++;
289a99a9f0eSIvan Vecera }
290a99a9f0eSIvan Vecera }
291a99a9f0eSIvan Vecera
292a99a9f0eSIvan Vecera /* Save number of freq ranges and pointer to them into pin properties */
293a99a9f0eSIvan Vecera props->dpll_props.freq_supported = ranges;
294a99a9f0eSIvan Vecera props->dpll_props.freq_supported_num = j;
295a99a9f0eSIvan Vecera
296a99a9f0eSIvan Vecera /* Free temporary array */
297a99a9f0eSIvan Vecera kfree(freqs);
298a99a9f0eSIvan Vecera
299a99a9f0eSIvan Vecera return props;
300a99a9f0eSIvan Vecera
301a99a9f0eSIvan Vecera err_alloc_ranges:
302a99a9f0eSIvan Vecera kfree(freqs);
303a99a9f0eSIvan Vecera err_alloc_freqs:
304a99a9f0eSIvan Vecera fwnode_handle_put(props->fwnode);
305a99a9f0eSIvan Vecera kfree(props);
306a99a9f0eSIvan Vecera
307a99a9f0eSIvan Vecera return ERR_PTR(rc);
308a99a9f0eSIvan Vecera }
309a99a9f0eSIvan Vecera
310a99a9f0eSIvan Vecera /**
311a99a9f0eSIvan Vecera * zl3073x_pin_props_put - release pin properties
312a99a9f0eSIvan Vecera * @props: pin properties to free
313a99a9f0eSIvan Vecera *
314a99a9f0eSIvan Vecera * The function deallocates given pin properties structure.
315a99a9f0eSIvan Vecera */
zl3073x_pin_props_put(struct zl3073x_pin_props * props)316a99a9f0eSIvan Vecera void zl3073x_pin_props_put(struct zl3073x_pin_props *props)
317a99a9f0eSIvan Vecera {
318a99a9f0eSIvan Vecera /* Free supported frequency ranges list if it is present */
319a99a9f0eSIvan Vecera kfree(props->dpll_props.freq_supported);
320a99a9f0eSIvan Vecera
321a99a9f0eSIvan Vecera /* Put firmware handle if it is present */
322a99a9f0eSIvan Vecera if (props->fwnode)
323a99a9f0eSIvan Vecera fwnode_handle_put(props->fwnode);
324a99a9f0eSIvan Vecera
325a99a9f0eSIvan Vecera kfree(props);
326a99a9f0eSIvan Vecera }
327a99a9f0eSIvan Vecera
328a99a9f0eSIvan Vecera /**
329a99a9f0eSIvan Vecera * zl3073x_prop_dpll_type_get - get DPLL channel type
330a99a9f0eSIvan Vecera * @zldev: pointer to zl3073x device
331a99a9f0eSIvan Vecera * @index: DPLL channel index
332a99a9f0eSIvan Vecera *
333a99a9f0eSIvan Vecera * Return: DPLL type for given DPLL channel
334a99a9f0eSIvan Vecera */
335a99a9f0eSIvan Vecera enum dpll_type
zl3073x_prop_dpll_type_get(struct zl3073x_dev * zldev,u8 index)336a99a9f0eSIvan Vecera zl3073x_prop_dpll_type_get(struct zl3073x_dev *zldev, u8 index)
337a99a9f0eSIvan Vecera {
338a99a9f0eSIvan Vecera const char *types[ZL3073X_MAX_CHANNELS];
339a99a9f0eSIvan Vecera int count;
340a99a9f0eSIvan Vecera
341a99a9f0eSIvan Vecera /* Read dpll types property from firmware */
342a99a9f0eSIvan Vecera count = device_property_read_string_array(zldev->dev, "dpll-types",
343a99a9f0eSIvan Vecera types, ARRAY_SIZE(types));
344a99a9f0eSIvan Vecera
345a99a9f0eSIvan Vecera /* Return default if property or entry for given channel is missing */
346a99a9f0eSIvan Vecera if (index >= count)
347a99a9f0eSIvan Vecera return DPLL_TYPE_PPS;
348a99a9f0eSIvan Vecera
349a99a9f0eSIvan Vecera if (!strcmp(types[index], "pps"))
350a99a9f0eSIvan Vecera return DPLL_TYPE_PPS;
351a99a9f0eSIvan Vecera else if (!strcmp(types[index], "eec"))
352a99a9f0eSIvan Vecera return DPLL_TYPE_EEC;
353a99a9f0eSIvan Vecera
354a99a9f0eSIvan Vecera dev_info(zldev->dev, "Unknown DPLL type '%s', using default\n",
355a99a9f0eSIvan Vecera types[index]);
356a99a9f0eSIvan Vecera
357a99a9f0eSIvan Vecera return DPLL_TYPE_PPS; /* Default */
358a99a9f0eSIvan Vecera }
359