xref: /linux-6.15/include/linux/pps_kernel.h (revision c79a39dc)
174ba9207SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2eae9d2baSRodolfo Giometti /*
3eae9d2baSRodolfo Giometti  * PPS API kernel header
4eae9d2baSRodolfo Giometti  *
5eae9d2baSRodolfo Giometti  * Copyright (C) 2009   Rodolfo Giometti <[email protected]>
6eae9d2baSRodolfo Giometti  */
7eae9d2baSRodolfo Giometti 
87a21a3ccSAlexander Gordeev #ifndef LINUX_PPS_KERNEL_H
97a21a3ccSAlexander Gordeev #define LINUX_PPS_KERNEL_H
107a21a3ccSAlexander Gordeev 
11eae9d2baSRodolfo Giometti #include <linux/pps.h>
12eae9d2baSRodolfo Giometti #include <linux/cdev.h>
13eae9d2baSRodolfo Giometti #include <linux/device.h>
14eae9d2baSRodolfo Giometti #include <linux/time.h>
15eae9d2baSRodolfo Giometti 
16eae9d2baSRodolfo Giometti /*
17eae9d2baSRodolfo Giometti  * Global defines
18eae9d2baSRodolfo Giometti  */
19eae9d2baSRodolfo Giometti 
205e196d34SAlexander Gordeev struct pps_device;
215e196d34SAlexander Gordeev 
22eae9d2baSRodolfo Giometti /* The specific PPS source info */
23eae9d2baSRodolfo Giometti struct pps_source_info {
24a2d81803SRobert P. J. Day 	char name[PPS_MAX_NAME_LEN];		/* symbolic name */
25eae9d2baSRodolfo Giometti 	char path[PPS_MAX_NAME_LEN];		/* path of connected device */
26a2d81803SRobert P. J. Day 	int mode;				/* PPS allowed mode */
27eae9d2baSRodolfo Giometti 
285e196d34SAlexander Gordeev 	void (*echo)(struct pps_device *pps,
295e196d34SAlexander Gordeev 			int event, void *data);	/* PPS echo function */
30eae9d2baSRodolfo Giometti 
31eae9d2baSRodolfo Giometti 	struct module *owner;
32513b032cSGeorge Spelvin 	struct device *dev;		/* Parent device for device_create */
33eae9d2baSRodolfo Giometti };
34eae9d2baSRodolfo Giometti 
356f4229b5SAlexander Gordeev struct pps_event_time {
36e2c18e49SAlexander Gordeev #ifdef CONFIG_NTP_PPS
37ade1bdffSArnd Bergmann 	struct timespec64 ts_raw;
38e2c18e49SAlexander Gordeev #endif /* CONFIG_NTP_PPS */
39ade1bdffSArnd Bergmann 	struct timespec64 ts_real;
406f4229b5SAlexander Gordeev };
416f4229b5SAlexander Gordeev 
42eae9d2baSRodolfo Giometti /* The main struct */
43eae9d2baSRodolfo Giometti struct pps_device {
44eae9d2baSRodolfo Giometti 	struct pps_source_info info;		/* PSS source info */
45eae9d2baSRodolfo Giometti 
46a2d81803SRobert P. J. Day 	struct pps_kparams params;		/* PPS current params */
47eae9d2baSRodolfo Giometti 
48a2d81803SRobert P. J. Day 	__u32 assert_sequence;			/* PPS assert event seq # */
49a2d81803SRobert P. J. Day 	__u32 clear_sequence;			/* PPS clear event seq # */
50eae9d2baSRodolfo Giometti 	struct pps_ktime assert_tu;
51eae9d2baSRodolfo Giometti 	struct pps_ktime clear_tu;
52eae9d2baSRodolfo Giometti 	int current_mode;			/* PPS mode at event time */
53eae9d2baSRodolfo Giometti 
543003d55bSAlexander Gordeev 	unsigned int last_ev;			/* last PPS event id */
55eae9d2baSRodolfo Giometti 	wait_queue_head_t queue;		/* PPS event queue */
56eae9d2baSRodolfo Giometti 
57eae9d2baSRodolfo Giometti 	unsigned int id;			/* PPS source unique ID */
58a2d81803SRobert P. J. Day 	void const *lookup_cookie;		/* For pps_lookup_dev() only */
59*c79a39dcSCalvin Owens 	struct device dev;
60eae9d2baSRodolfo Giometti 	struct fasync_struct *async_queue;	/* fasync method */
61eae9d2baSRodolfo Giometti 	spinlock_t lock;
62eae9d2baSRodolfo Giometti };
63eae9d2baSRodolfo Giometti 
64eae9d2baSRodolfo Giometti /*
65eae9d2baSRodolfo Giometti  * Global variables
66eae9d2baSRodolfo Giometti  */
67eae9d2baSRodolfo Giometti 
68bd0eae4eSGreg Kroah-Hartman extern const struct attribute_group *pps_groups[];
69eae9d2baSRodolfo Giometti 
70eae9d2baSRodolfo Giometti /*
71513b032cSGeorge Spelvin  * Internal functions.
72513b032cSGeorge Spelvin  *
73513b032cSGeorge Spelvin  * These are not actually part of the exported API, but this is a
74513b032cSGeorge Spelvin  * convenient header file to put them in.
75513b032cSGeorge Spelvin  */
76513b032cSGeorge Spelvin 
77513b032cSGeorge Spelvin extern int pps_register_cdev(struct pps_device *pps);
78513b032cSGeorge Spelvin extern void pps_unregister_cdev(struct pps_device *pps);
79513b032cSGeorge Spelvin 
80513b032cSGeorge Spelvin /*
81eae9d2baSRodolfo Giometti  * Exported functions
82eae9d2baSRodolfo Giometti  */
83eae9d2baSRodolfo Giometti 
845e196d34SAlexander Gordeev extern struct pps_device *pps_register_source(
855e196d34SAlexander Gordeev 		struct pps_source_info *info, int default_params);
865e196d34SAlexander Gordeev extern void pps_unregister_source(struct pps_device *pps);
875e196d34SAlexander Gordeev extern void pps_event(struct pps_device *pps,
885e196d34SAlexander Gordeev 		struct pps_event_time *ts, int event, void *data);
89a2d81803SRobert P. J. Day /* Look up a pps_device by magic cookie */
90513b032cSGeorge Spelvin struct pps_device *pps_lookup_dev(void const *cookie);
916f4229b5SAlexander Gordeev 
timespec_to_pps_ktime(struct pps_ktime * kt,struct timespec64 ts)926f4229b5SAlexander Gordeev static inline void timespec_to_pps_ktime(struct pps_ktime *kt,
93ade1bdffSArnd Bergmann 		struct timespec64 ts)
946f4229b5SAlexander Gordeev {
956f4229b5SAlexander Gordeev 	kt->sec = ts.tv_sec;
966f4229b5SAlexander Gordeev 	kt->nsec = ts.tv_nsec;
976f4229b5SAlexander Gordeev }
986f4229b5SAlexander Gordeev 
pps_get_ts(struct pps_event_time * ts)99ba26621eSChristopher S. Hall static inline void pps_get_ts(struct pps_event_time *ts)
100ba26621eSChristopher S. Hall {
101ba26621eSChristopher S. Hall 	struct system_time_snapshot snap;
102ba26621eSChristopher S. Hall 
103ba26621eSChristopher S. Hall 	ktime_get_snapshot(&snap);
104ba26621eSChristopher S. Hall 	ts->ts_real = ktime_to_timespec64(snap.real);
105e2c18e49SAlexander Gordeev #ifdef CONFIG_NTP_PPS
106ba26621eSChristopher S. Hall 	ts->ts_raw = ktime_to_timespec64(snap.raw);
107ba26621eSChristopher S. Hall #endif
108e2c18e49SAlexander Gordeev }
109e2c18e49SAlexander Gordeev 
110220a60a4SBen Hutchings /* Subtract known time delay from PPS event time(s) */
pps_sub_ts(struct pps_event_time * ts,struct timespec64 delta)111ade1bdffSArnd Bergmann static inline void pps_sub_ts(struct pps_event_time *ts, struct timespec64 delta)
112220a60a4SBen Hutchings {
113ade1bdffSArnd Bergmann 	ts->ts_real = timespec64_sub(ts->ts_real, delta);
114220a60a4SBen Hutchings #ifdef CONFIG_NTP_PPS
115ade1bdffSArnd Bergmann 	ts->ts_raw = timespec64_sub(ts->ts_raw, delta);
116220a60a4SBen Hutchings #endif
117220a60a4SBen Hutchings }
118220a60a4SBen Hutchings 
1197a21a3ccSAlexander Gordeev #endif /* LINUX_PPS_KERNEL_H */
120