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