19431063aSVadim Fedorenko /* SPDX-License-Identifier: GPL-2.0 */
29431063aSVadim Fedorenko /*
39431063aSVadim Fedorenko * Copyright (c) 2023 Meta Platforms, Inc. and affiliates
49431063aSVadim Fedorenko * Copyright (c) 2023 Intel and affiliates
59431063aSVadim Fedorenko */
69431063aSVadim Fedorenko
79431063aSVadim Fedorenko #ifndef __DPLL_H__
89431063aSVadim Fedorenko #define __DPLL_H__
99431063aSVadim Fedorenko
109431063aSVadim Fedorenko #include <uapi/linux/dpll.h>
119431063aSVadim Fedorenko #include <linux/device.h>
129431063aSVadim Fedorenko #include <linux/netlink.h>
130d60d8dfSEric Dumazet #include <linux/netdevice.h>
140d60d8dfSEric Dumazet #include <linux/rtnetlink.h>
159431063aSVadim Fedorenko
169431063aSVadim Fedorenko struct dpll_device;
179431063aSVadim Fedorenko struct dpll_pin;
18cda1fba1SArkadiusz Kubalewski struct dpll_pin_esync;
199431063aSVadim Fedorenko
209431063aSVadim Fedorenko struct dpll_device_ops {
219431063aSVadim Fedorenko int (*mode_get)(const struct dpll_device *dpll, void *dpll_priv,
229431063aSVadim Fedorenko enum dpll_mode *mode, struct netlink_ext_ack *extack);
239431063aSVadim Fedorenko int (*lock_status_get)(const struct dpll_device *dpll, void *dpll_priv,
249431063aSVadim Fedorenko enum dpll_lock_status *status,
25e2ca9e75SJiri Pirko enum dpll_lock_status_error *status_error,
269431063aSVadim Fedorenko struct netlink_ext_ack *extack);
279431063aSVadim Fedorenko int (*temp_get)(const struct dpll_device *dpll, void *dpll_priv,
289431063aSVadim Fedorenko s32 *temp, struct netlink_ext_ack *extack);
29*a1afb959SJiri Pirko int (*clock_quality_level_get)(const struct dpll_device *dpll,
30*a1afb959SJiri Pirko void *dpll_priv,
31*a1afb959SJiri Pirko unsigned long *qls,
32*a1afb959SJiri Pirko struct netlink_ext_ack *extack);
339431063aSVadim Fedorenko };
349431063aSVadim Fedorenko
359431063aSVadim Fedorenko struct dpll_pin_ops {
369431063aSVadim Fedorenko int (*frequency_set)(const struct dpll_pin *pin, void *pin_priv,
379431063aSVadim Fedorenko const struct dpll_device *dpll, void *dpll_priv,
389431063aSVadim Fedorenko const u64 frequency,
399431063aSVadim Fedorenko struct netlink_ext_ack *extack);
409431063aSVadim Fedorenko int (*frequency_get)(const struct dpll_pin *pin, void *pin_priv,
419431063aSVadim Fedorenko const struct dpll_device *dpll, void *dpll_priv,
429431063aSVadim Fedorenko u64 *frequency, struct netlink_ext_ack *extack);
439431063aSVadim Fedorenko int (*direction_set)(const struct dpll_pin *pin, void *pin_priv,
449431063aSVadim Fedorenko const struct dpll_device *dpll, void *dpll_priv,
459431063aSVadim Fedorenko const enum dpll_pin_direction direction,
469431063aSVadim Fedorenko struct netlink_ext_ack *extack);
479431063aSVadim Fedorenko int (*direction_get)(const struct dpll_pin *pin, void *pin_priv,
489431063aSVadim Fedorenko const struct dpll_device *dpll, void *dpll_priv,
499431063aSVadim Fedorenko enum dpll_pin_direction *direction,
509431063aSVadim Fedorenko struct netlink_ext_ack *extack);
519431063aSVadim Fedorenko int (*state_on_pin_get)(const struct dpll_pin *pin, void *pin_priv,
529431063aSVadim Fedorenko const struct dpll_pin *parent_pin,
539431063aSVadim Fedorenko void *parent_pin_priv,
549431063aSVadim Fedorenko enum dpll_pin_state *state,
559431063aSVadim Fedorenko struct netlink_ext_ack *extack);
569431063aSVadim Fedorenko int (*state_on_dpll_get)(const struct dpll_pin *pin, void *pin_priv,
579431063aSVadim Fedorenko const struct dpll_device *dpll,
589431063aSVadim Fedorenko void *dpll_priv, enum dpll_pin_state *state,
599431063aSVadim Fedorenko struct netlink_ext_ack *extack);
609431063aSVadim Fedorenko int (*state_on_pin_set)(const struct dpll_pin *pin, void *pin_priv,
619431063aSVadim Fedorenko const struct dpll_pin *parent_pin,
629431063aSVadim Fedorenko void *parent_pin_priv,
639431063aSVadim Fedorenko const enum dpll_pin_state state,
649431063aSVadim Fedorenko struct netlink_ext_ack *extack);
659431063aSVadim Fedorenko int (*state_on_dpll_set)(const struct dpll_pin *pin, void *pin_priv,
669431063aSVadim Fedorenko const struct dpll_device *dpll,
679431063aSVadim Fedorenko void *dpll_priv,
689431063aSVadim Fedorenko const enum dpll_pin_state state,
699431063aSVadim Fedorenko struct netlink_ext_ack *extack);
709431063aSVadim Fedorenko int (*prio_get)(const struct dpll_pin *pin, void *pin_priv,
719431063aSVadim Fedorenko const struct dpll_device *dpll, void *dpll_priv,
729431063aSVadim Fedorenko u32 *prio, struct netlink_ext_ack *extack);
739431063aSVadim Fedorenko int (*prio_set)(const struct dpll_pin *pin, void *pin_priv,
749431063aSVadim Fedorenko const struct dpll_device *dpll, void *dpll_priv,
759431063aSVadim Fedorenko const u32 prio, struct netlink_ext_ack *extack);
76d7fbc0b7SArkadiusz Kubalewski int (*phase_offset_get)(const struct dpll_pin *pin, void *pin_priv,
77d7fbc0b7SArkadiusz Kubalewski const struct dpll_device *dpll, void *dpll_priv,
78d7fbc0b7SArkadiusz Kubalewski s64 *phase_offset,
79d7fbc0b7SArkadiusz Kubalewski struct netlink_ext_ack *extack);
80d7fbc0b7SArkadiusz Kubalewski int (*phase_adjust_get)(const struct dpll_pin *pin, void *pin_priv,
81d7fbc0b7SArkadiusz Kubalewski const struct dpll_device *dpll, void *dpll_priv,
82d7fbc0b7SArkadiusz Kubalewski s32 *phase_adjust,
83d7fbc0b7SArkadiusz Kubalewski struct netlink_ext_ack *extack);
84d7fbc0b7SArkadiusz Kubalewski int (*phase_adjust_set)(const struct dpll_pin *pin, void *pin_priv,
85d7fbc0b7SArkadiusz Kubalewski const struct dpll_device *dpll, void *dpll_priv,
86d7fbc0b7SArkadiusz Kubalewski const s32 phase_adjust,
87d7fbc0b7SArkadiusz Kubalewski struct netlink_ext_ack *extack);
888a6286c1SJiri Pirko int (*ffo_get)(const struct dpll_pin *pin, void *pin_priv,
898a6286c1SJiri Pirko const struct dpll_device *dpll, void *dpll_priv,
908a6286c1SJiri Pirko s64 *ffo, struct netlink_ext_ack *extack);
91cda1fba1SArkadiusz Kubalewski int (*esync_set)(const struct dpll_pin *pin, void *pin_priv,
92cda1fba1SArkadiusz Kubalewski const struct dpll_device *dpll, void *dpll_priv,
93cda1fba1SArkadiusz Kubalewski u64 freq, struct netlink_ext_ack *extack);
94cda1fba1SArkadiusz Kubalewski int (*esync_get)(const struct dpll_pin *pin, void *pin_priv,
95cda1fba1SArkadiusz Kubalewski const struct dpll_device *dpll, void *dpll_priv,
96cda1fba1SArkadiusz Kubalewski struct dpll_pin_esync *esync,
97cda1fba1SArkadiusz Kubalewski struct netlink_ext_ack *extack);
989431063aSVadim Fedorenko };
999431063aSVadim Fedorenko
1009431063aSVadim Fedorenko struct dpll_pin_frequency {
1019431063aSVadim Fedorenko u64 min;
1029431063aSVadim Fedorenko u64 max;
1039431063aSVadim Fedorenko };
1049431063aSVadim Fedorenko
1059431063aSVadim Fedorenko #define DPLL_PIN_FREQUENCY_RANGE(_min, _max) \
1069431063aSVadim Fedorenko { \
1079431063aSVadim Fedorenko .min = _min, \
1089431063aSVadim Fedorenko .max = _max, \
1099431063aSVadim Fedorenko }
1109431063aSVadim Fedorenko
1119431063aSVadim Fedorenko #define DPLL_PIN_FREQUENCY(_val) DPLL_PIN_FREQUENCY_RANGE(_val, _val)
1129431063aSVadim Fedorenko #define DPLL_PIN_FREQUENCY_1PPS \
1139431063aSVadim Fedorenko DPLL_PIN_FREQUENCY(DPLL_PIN_FREQUENCY_1_HZ)
1149431063aSVadim Fedorenko #define DPLL_PIN_FREQUENCY_10MHZ \
1159431063aSVadim Fedorenko DPLL_PIN_FREQUENCY(DPLL_PIN_FREQUENCY_10_MHZ)
1169431063aSVadim Fedorenko #define DPLL_PIN_FREQUENCY_IRIG_B \
1179431063aSVadim Fedorenko DPLL_PIN_FREQUENCY(DPLL_PIN_FREQUENCY_10_KHZ)
1189431063aSVadim Fedorenko #define DPLL_PIN_FREQUENCY_DCF77 \
1199431063aSVadim Fedorenko DPLL_PIN_FREQUENCY(DPLL_PIN_FREQUENCY_77_5_KHZ)
1209431063aSVadim Fedorenko
121d7fbc0b7SArkadiusz Kubalewski struct dpll_pin_phase_adjust_range {
122d7fbc0b7SArkadiusz Kubalewski s32 min;
123d7fbc0b7SArkadiusz Kubalewski s32 max;
124d7fbc0b7SArkadiusz Kubalewski };
125d7fbc0b7SArkadiusz Kubalewski
126cda1fba1SArkadiusz Kubalewski struct dpll_pin_esync {
127cda1fba1SArkadiusz Kubalewski u64 freq;
128cda1fba1SArkadiusz Kubalewski const struct dpll_pin_frequency *range;
129cda1fba1SArkadiusz Kubalewski u8 range_num;
130cda1fba1SArkadiusz Kubalewski u8 pulse;
131cda1fba1SArkadiusz Kubalewski };
132cda1fba1SArkadiusz Kubalewski
1339431063aSVadim Fedorenko struct dpll_pin_properties {
1349431063aSVadim Fedorenko const char *board_label;
1359431063aSVadim Fedorenko const char *panel_label;
1369431063aSVadim Fedorenko const char *package_label;
1379431063aSVadim Fedorenko enum dpll_pin_type type;
1389431063aSVadim Fedorenko unsigned long capabilities;
1399431063aSVadim Fedorenko u32 freq_supported_num;
1409431063aSVadim Fedorenko struct dpll_pin_frequency *freq_supported;
141d7fbc0b7SArkadiusz Kubalewski struct dpll_pin_phase_adjust_range phase_range;
1429431063aSVadim Fedorenko };
1439431063aSVadim Fedorenko
1445f184269SJiri Pirko #if IS_ENABLED(CONFIG_DPLL)
145289e9225SJakub Kicinski void dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin);
146289e9225SJakub Kicinski void dpll_netdev_pin_clear(struct net_device *dev);
147289e9225SJakub Kicinski
148289e9225SJakub Kicinski size_t dpll_netdev_pin_handle_size(const struct net_device *dev);
149289e9225SJakub Kicinski int dpll_netdev_add_pin_handle(struct sk_buff *msg,
150289e9225SJakub Kicinski const struct net_device *dev);
1515f184269SJiri Pirko #else
152289e9225SJakub Kicinski static inline void
dpll_netdev_pin_set(struct net_device * dev,struct dpll_pin * dpll_pin)153289e9225SJakub Kicinski dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin) { }
dpll_netdev_pin_clear(struct net_device * dev)154289e9225SJakub Kicinski static inline void dpll_netdev_pin_clear(struct net_device *dev) { }
155289e9225SJakub Kicinski
dpll_netdev_pin_handle_size(const struct net_device * dev)156289e9225SJakub Kicinski static inline size_t dpll_netdev_pin_handle_size(const struct net_device *dev)
1575f184269SJiri Pirko {
1585f184269SJiri Pirko return 0;
1595f184269SJiri Pirko }
1605f184269SJiri Pirko
161289e9225SJakub Kicinski static inline int
dpll_netdev_add_pin_handle(struct sk_buff * msg,const struct net_device * dev)162289e9225SJakub Kicinski dpll_netdev_add_pin_handle(struct sk_buff *msg, const struct net_device *dev)
1635f184269SJiri Pirko {
1645f184269SJiri Pirko return 0;
1655f184269SJiri Pirko }
1665f184269SJiri Pirko #endif
1675f184269SJiri Pirko
1689431063aSVadim Fedorenko struct dpll_device *
1699431063aSVadim Fedorenko dpll_device_get(u64 clock_id, u32 dev_driver_id, struct module *module);
1709431063aSVadim Fedorenko
1719431063aSVadim Fedorenko void dpll_device_put(struct dpll_device *dpll);
1729431063aSVadim Fedorenko
1739431063aSVadim Fedorenko int dpll_device_register(struct dpll_device *dpll, enum dpll_type type,
1749431063aSVadim Fedorenko const struct dpll_device_ops *ops, void *priv);
1759431063aSVadim Fedorenko
1769431063aSVadim Fedorenko void dpll_device_unregister(struct dpll_device *dpll,
1779431063aSVadim Fedorenko const struct dpll_device_ops *ops, void *priv);
1789431063aSVadim Fedorenko
1799431063aSVadim Fedorenko struct dpll_pin *
1809431063aSVadim Fedorenko dpll_pin_get(u64 clock_id, u32 dev_driver_id, struct module *module,
1819431063aSVadim Fedorenko const struct dpll_pin_properties *prop);
1829431063aSVadim Fedorenko
1839431063aSVadim Fedorenko int dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin,
1849431063aSVadim Fedorenko const struct dpll_pin_ops *ops, void *priv);
1859431063aSVadim Fedorenko
1869431063aSVadim Fedorenko void dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin,
1879431063aSVadim Fedorenko const struct dpll_pin_ops *ops, void *priv);
1889431063aSVadim Fedorenko
1899431063aSVadim Fedorenko void dpll_pin_put(struct dpll_pin *pin);
1909431063aSVadim Fedorenko
1919431063aSVadim Fedorenko int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin,
1929431063aSVadim Fedorenko const struct dpll_pin_ops *ops, void *priv);
1939431063aSVadim Fedorenko
1949431063aSVadim Fedorenko void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin,
1959431063aSVadim Fedorenko const struct dpll_pin_ops *ops, void *priv);
1969431063aSVadim Fedorenko
1979d71b54bSVadim Fedorenko int dpll_device_change_ntf(struct dpll_device *dpll);
1989d71b54bSVadim Fedorenko
1999d71b54bSVadim Fedorenko int dpll_pin_change_ntf(struct dpll_pin *pin);
2009d71b54bSVadim Fedorenko
2019431063aSVadim Fedorenko #endif
202