Merge tag 'for_v5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
[linux-2.6-microblaze.git] / drivers / pps / clients / pps-gpio.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * pps-gpio.c -- PPS client driver using GPIO
4  *
5  * Copyright (C) 2010 Ricardo Martins <rasm@fe.up.pt>
6  * Copyright (C) 2011 James Nuss <jamesnuss@nanometrics.ca>
7  */
8
9 #define PPS_GPIO_NAME "pps-gpio"
10 #define pr_fmt(fmt) PPS_GPIO_NAME ": " fmt
11
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/interrupt.h>
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/slab.h>
18 #include <linux/pps_kernel.h>
19 #include <linux/pps-gpio.h>
20 #include <linux/gpio/consumer.h>
21 #include <linux/list.h>
22 #include <linux/of_device.h>
23 #include <linux/of_gpio.h>
24 #include <linux/timer.h>
25 #include <linux/jiffies.h>
26
27 /* Info for each registered platform device */
28 struct pps_gpio_device_data {
29         int irq;                        /* IRQ used as PPS source */
30         struct pps_device *pps;         /* PPS source device */
31         struct pps_source_info info;    /* PPS source information */
32         struct gpio_desc *gpio_pin;     /* GPIO port descriptors */
33         struct gpio_desc *echo_pin;
34         struct timer_list echo_timer;   /* timer to reset echo active state */
35         bool assert_falling_edge;
36         bool capture_clear;
37         unsigned int echo_active_ms;    /* PPS echo active duration */
38         unsigned long echo_timeout;     /* timer timeout value in jiffies */
39 };
40
41 /*
42  * Report the PPS event
43  */
44
45 static irqreturn_t pps_gpio_irq_handler(int irq, void *data)
46 {
47         const struct pps_gpio_device_data *info;
48         struct pps_event_time ts;
49         int rising_edge;
50
51         /* Get the time stamp first */
52         pps_get_ts(&ts);
53
54         info = data;
55
56         rising_edge = gpiod_get_value(info->gpio_pin);
57         if ((rising_edge && !info->assert_falling_edge) ||
58                         (!rising_edge && info->assert_falling_edge))
59                 pps_event(info->pps, &ts, PPS_CAPTUREASSERT, data);
60         else if (info->capture_clear &&
61                         ((rising_edge && info->assert_falling_edge) ||
62                         (!rising_edge && !info->assert_falling_edge)))
63                 pps_event(info->pps, &ts, PPS_CAPTURECLEAR, data);
64
65         return IRQ_HANDLED;
66 }
67
68 /* This function will only be called when an ECHO GPIO is defined */
69 static void pps_gpio_echo(struct pps_device *pps, int event, void *data)
70 {
71         /* add_timer() needs to write into info->echo_timer */
72         struct pps_gpio_device_data *info = data;
73
74         switch (event) {
75         case PPS_CAPTUREASSERT:
76                 if (pps->params.mode & PPS_ECHOASSERT)
77                         gpiod_set_value(info->echo_pin, 1);
78                 break;
79
80         case PPS_CAPTURECLEAR:
81                 if (pps->params.mode & PPS_ECHOCLEAR)
82                         gpiod_set_value(info->echo_pin, 1);
83                 break;
84         }
85
86         /* fire the timer */
87         if (info->pps->params.mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR)) {
88                 info->echo_timer.expires = jiffies + info->echo_timeout;
89                 add_timer(&info->echo_timer);
90         }
91 }
92
93 /* Timer callback to reset the echo pin to the inactive state */
94 static void pps_gpio_echo_timer_callback(struct timer_list *t)
95 {
96         const struct pps_gpio_device_data *info;
97
98         info = from_timer(info, t, echo_timer);
99
100         gpiod_set_value(info->echo_pin, 0);
101 }
102
103 static int pps_gpio_setup(struct platform_device *pdev)
104 {
105         struct pps_gpio_device_data *data = platform_get_drvdata(pdev);
106         struct device_node *np = pdev->dev.of_node;
107         int ret;
108         u32 value;
109
110         data->gpio_pin = devm_gpiod_get(&pdev->dev,
111                 NULL,   /* request "gpios" */
112                 GPIOD_IN);
113         if (IS_ERR(data->gpio_pin)) {
114                 dev_err(&pdev->dev,
115                         "failed to request PPS GPIO\n");
116                 return PTR_ERR(data->gpio_pin);
117         }
118
119         data->echo_pin = devm_gpiod_get_optional(&pdev->dev,
120                         "echo",
121                         GPIOD_OUT_LOW);
122         if (data->echo_pin) {
123                 if (IS_ERR(data->echo_pin)) {
124                         dev_err(&pdev->dev, "failed to request ECHO GPIO\n");
125                         return PTR_ERR(data->echo_pin);
126                 }
127
128                 ret = of_property_read_u32(np,
129                         "echo-active-ms",
130                         &value);
131                 if (ret) {
132                         dev_err(&pdev->dev,
133                                 "failed to get echo-active-ms from OF\n");
134                         return ret;
135                 }
136                 data->echo_active_ms = value;
137                 /* sanity check on echo_active_ms */
138                 if (!data->echo_active_ms || data->echo_active_ms > 999) {
139                         dev_err(&pdev->dev,
140                                 "echo-active-ms: %u - bad value from OF\n",
141                                 data->echo_active_ms);
142                         return -EINVAL;
143                 }
144         }
145
146         if (of_property_read_bool(np, "assert-falling-edge"))
147                 data->assert_falling_edge = true;
148         return 0;
149 }
150
151 static unsigned long
152 get_irqf_trigger_flags(const struct pps_gpio_device_data *data)
153 {
154         unsigned long flags = data->assert_falling_edge ?
155                 IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
156
157         if (data->capture_clear) {
158                 flags |= ((flags & IRQF_TRIGGER_RISING) ?
159                                 IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING);
160         }
161
162         return flags;
163 }
164
165 static int pps_gpio_probe(struct platform_device *pdev)
166 {
167         struct pps_gpio_device_data *data;
168         int ret;
169         int pps_default_params;
170         const struct pps_gpio_platform_data *pdata = pdev->dev.platform_data;
171
172         /* allocate space for device info */
173         data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
174         if (!data)
175                 return -ENOMEM;
176         platform_set_drvdata(pdev, data);
177
178         /* GPIO setup */
179         if (pdata) {
180                 data->gpio_pin = pdata->gpio_pin;
181                 data->echo_pin = pdata->echo_pin;
182
183                 data->assert_falling_edge = pdata->assert_falling_edge;
184                 data->capture_clear = pdata->capture_clear;
185                 data->echo_active_ms = pdata->echo_active_ms;
186         } else {
187                 ret = pps_gpio_setup(pdev);
188                 if (ret)
189                         return -EINVAL;
190         }
191
192         /* IRQ setup */
193         ret = gpiod_to_irq(data->gpio_pin);
194         if (ret < 0) {
195                 dev_err(&pdev->dev, "failed to map GPIO to IRQ: %d\n", ret);
196                 return -EINVAL;
197         }
198         data->irq = ret;
199
200         /* initialize PPS specific parts of the bookkeeping data structure. */
201         data->info.mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT |
202                 PPS_ECHOASSERT | PPS_CANWAIT | PPS_TSFMT_TSPEC;
203         if (data->capture_clear)
204                 data->info.mode |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR |
205                         PPS_ECHOCLEAR;
206         data->info.owner = THIS_MODULE;
207         snprintf(data->info.name, PPS_MAX_NAME_LEN - 1, "%s.%d",
208                  pdev->name, pdev->id);
209         if (data->echo_pin) {
210                 data->info.echo = pps_gpio_echo;
211                 data->echo_timeout = msecs_to_jiffies(data->echo_active_ms);
212                 timer_setup(&data->echo_timer, pps_gpio_echo_timer_callback, 0);
213         }
214
215         /* register PPS source */
216         pps_default_params = PPS_CAPTUREASSERT | PPS_OFFSETASSERT;
217         if (data->capture_clear)
218                 pps_default_params |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR;
219         data->pps = pps_register_source(&data->info, pps_default_params);
220         if (IS_ERR(data->pps)) {
221                 dev_err(&pdev->dev, "failed to register IRQ %d as PPS source\n",
222                         data->irq);
223                 return PTR_ERR(data->pps);
224         }
225
226         /* register IRQ interrupt handler */
227         ret = devm_request_irq(&pdev->dev, data->irq, pps_gpio_irq_handler,
228                         get_irqf_trigger_flags(data), data->info.name, data);
229         if (ret) {
230                 pps_unregister_source(data->pps);
231                 dev_err(&pdev->dev, "failed to acquire IRQ %d\n", data->irq);
232                 return -EINVAL;
233         }
234
235         dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n",
236                  data->irq);
237
238         return 0;
239 }
240
241 static int pps_gpio_remove(struct platform_device *pdev)
242 {
243         struct pps_gpio_device_data *data = platform_get_drvdata(pdev);
244
245         pps_unregister_source(data->pps);
246         if (data->echo_pin) {
247                 del_timer_sync(&data->echo_timer);
248                 /* reset echo pin in any case */
249                 gpiod_set_value(data->echo_pin, 0);
250         }
251         dev_info(&pdev->dev, "removed IRQ %d as PPS source\n", data->irq);
252         return 0;
253 }
254
255 static const struct of_device_id pps_gpio_dt_ids[] = {
256         { .compatible = "pps-gpio", },
257         { /* sentinel */ }
258 };
259 MODULE_DEVICE_TABLE(of, pps_gpio_dt_ids);
260
261 static struct platform_driver pps_gpio_driver = {
262         .probe          = pps_gpio_probe,
263         .remove         = pps_gpio_remove,
264         .driver         = {
265                 .name   = PPS_GPIO_NAME,
266                 .of_match_table = pps_gpio_dt_ids,
267         },
268 };
269
270 module_platform_driver(pps_gpio_driver);
271 MODULE_AUTHOR("Ricardo Martins <rasm@fe.up.pt>");
272 MODULE_AUTHOR("James Nuss <jamesnuss@nanometrics.ca>");
273 MODULE_DESCRIPTION("Use GPIO pin as PPS source");
274 MODULE_LICENSE("GPL");
275 MODULE_VERSION("1.2.0");