Merge tag 'drm-next-2018-08-24' of git://anongit.freedesktop.org/drm/drm
[sfrench/cifs-2.6.git] / drivers / gnss / sirf.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * SiRFstar GNSS receiver driver
4  *
5  * Copyright (C) 2018 Johan Hovold <johan@kernel.org>
6  */
7
8 #include <linux/errno.h>
9 #include <linux/gnss.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/init.h>
12 #include <linux/interrupt.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/pm.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/regulator/consumer.h>
19 #include <linux/serdev.h>
20 #include <linux/slab.h>
21 #include <linux/wait.h>
22
23 #define SIRF_BOOT_DELAY                 500
24 #define SIRF_ON_OFF_PULSE_TIME          100
25 #define SIRF_ACTIVATE_TIMEOUT           200
26 #define SIRF_HIBERNATE_TIMEOUT          200
27
28 struct sirf_data {
29         struct gnss_device *gdev;
30         struct serdev_device *serdev;
31         speed_t speed;
32         struct regulator *vcc;
33         struct gpio_desc *on_off;
34         struct gpio_desc *wakeup;
35         int irq;
36         bool active;
37         wait_queue_head_t power_wait;
38 };
39
40 static int sirf_open(struct gnss_device *gdev)
41 {
42         struct sirf_data *data = gnss_get_drvdata(gdev);
43         struct serdev_device *serdev = data->serdev;
44         int ret;
45
46         ret = serdev_device_open(serdev);
47         if (ret)
48                 return ret;
49
50         serdev_device_set_baudrate(serdev, data->speed);
51         serdev_device_set_flow_control(serdev, false);
52
53         ret = pm_runtime_get_sync(&serdev->dev);
54         if (ret < 0) {
55                 dev_err(&gdev->dev, "failed to runtime resume: %d\n", ret);
56                 pm_runtime_put_noidle(&serdev->dev);
57                 goto err_close;
58         }
59
60         return 0;
61
62 err_close:
63         serdev_device_close(serdev);
64
65         return ret;
66 }
67
68 static void sirf_close(struct gnss_device *gdev)
69 {
70         struct sirf_data *data = gnss_get_drvdata(gdev);
71         struct serdev_device *serdev = data->serdev;
72
73         serdev_device_close(serdev);
74
75         pm_runtime_put(&serdev->dev);
76 }
77
78 static int sirf_write_raw(struct gnss_device *gdev, const unsigned char *buf,
79                                 size_t count)
80 {
81         struct sirf_data *data = gnss_get_drvdata(gdev);
82         struct serdev_device *serdev = data->serdev;
83         int ret;
84
85         /* write is only buffered synchronously */
86         ret = serdev_device_write(serdev, buf, count, 0);
87         if (ret < 0)
88                 return ret;
89
90         /* FIXME: determine if interrupted? */
91         serdev_device_wait_until_sent(serdev, 0);
92
93         return count;
94 }
95
96 static const struct gnss_operations sirf_gnss_ops = {
97         .open           = sirf_open,
98         .close          = sirf_close,
99         .write_raw      = sirf_write_raw,
100 };
101
102 static int sirf_receive_buf(struct serdev_device *serdev,
103                                 const unsigned char *buf, size_t count)
104 {
105         struct sirf_data *data = serdev_device_get_drvdata(serdev);
106         struct gnss_device *gdev = data->gdev;
107
108         return gnss_insert_raw(gdev, buf, count);
109 }
110
111 static const struct serdev_device_ops sirf_serdev_ops = {
112         .receive_buf    = sirf_receive_buf,
113         .write_wakeup   = serdev_device_write_wakeup,
114 };
115
116 static irqreturn_t sirf_wakeup_handler(int irq, void *dev_id)
117 {
118         struct sirf_data *data = dev_id;
119         struct device *dev = &data->serdev->dev;
120         int ret;
121
122         ret = gpiod_get_value_cansleep(data->wakeup);
123         dev_dbg(dev, "%s - wakeup = %d\n", __func__, ret);
124         if (ret < 0)
125                 goto out;
126
127         data->active = !!ret;
128         wake_up_interruptible(&data->power_wait);
129 out:
130         return IRQ_HANDLED;
131 }
132
133 static int sirf_wait_for_power_state(struct sirf_data *data, bool active,
134                                         unsigned long timeout)
135 {
136         int ret;
137
138         ret = wait_event_interruptible_timeout(data->power_wait,
139                         data->active == active, msecs_to_jiffies(timeout));
140         if (ret < 0)
141                 return ret;
142
143         if (ret == 0) {
144                 dev_warn(&data->serdev->dev, "timeout waiting for active state = %d\n",
145                                 active);
146                 return -ETIMEDOUT;
147         }
148
149         return 0;
150 }
151
152 static void sirf_pulse_on_off(struct sirf_data *data)
153 {
154         gpiod_set_value_cansleep(data->on_off, 1);
155         msleep(SIRF_ON_OFF_PULSE_TIME);
156         gpiod_set_value_cansleep(data->on_off, 0);
157 }
158
159 static int sirf_set_active(struct sirf_data *data, bool active)
160 {
161         unsigned long timeout;
162         int retries = 3;
163         int ret;
164
165         if (active)
166                 timeout = SIRF_ACTIVATE_TIMEOUT;
167         else
168                 timeout = SIRF_HIBERNATE_TIMEOUT;
169
170         while (retries-- > 0) {
171                 sirf_pulse_on_off(data);
172                 ret = sirf_wait_for_power_state(data, active, timeout);
173                 if (ret < 0) {
174                         if (ret == -ETIMEDOUT)
175                                 continue;
176
177                         return ret;
178                 }
179
180                 break;
181         }
182
183         if (retries == 0)
184                 return -ETIMEDOUT;
185
186         return 0;
187 }
188
189 static int sirf_runtime_suspend(struct device *dev)
190 {
191         struct sirf_data *data = dev_get_drvdata(dev);
192
193         if (!data->on_off)
194                 return regulator_disable(data->vcc);
195
196         return sirf_set_active(data, false);
197 }
198
199 static int sirf_runtime_resume(struct device *dev)
200 {
201         struct sirf_data *data = dev_get_drvdata(dev);
202
203         if (!data->on_off)
204                 return regulator_enable(data->vcc);
205
206         return sirf_set_active(data, true);
207 }
208
209 static int __maybe_unused sirf_suspend(struct device *dev)
210 {
211         struct sirf_data *data = dev_get_drvdata(dev);
212         int ret = 0;
213
214         if (!pm_runtime_suspended(dev))
215                 ret = sirf_runtime_suspend(dev);
216
217         if (data->wakeup)
218                 disable_irq(data->irq);
219
220         return ret;
221 }
222
223 static int __maybe_unused sirf_resume(struct device *dev)
224 {
225         struct sirf_data *data = dev_get_drvdata(dev);
226         int ret = 0;
227
228         if (data->wakeup)
229                 enable_irq(data->irq);
230
231         if (!pm_runtime_suspended(dev))
232                 ret = sirf_runtime_resume(dev);
233
234         return ret;
235 }
236
237 static const struct dev_pm_ops sirf_pm_ops = {
238         SET_SYSTEM_SLEEP_PM_OPS(sirf_suspend, sirf_resume)
239         SET_RUNTIME_PM_OPS(sirf_runtime_suspend, sirf_runtime_resume, NULL)
240 };
241
242 static int sirf_parse_dt(struct serdev_device *serdev)
243 {
244         struct sirf_data *data = serdev_device_get_drvdata(serdev);
245         struct device_node *node = serdev->dev.of_node;
246         u32 speed = 9600;
247
248         of_property_read_u32(node, "current-speed", &speed);
249
250         data->speed = speed;
251
252         return 0;
253 }
254
255 static int sirf_probe(struct serdev_device *serdev)
256 {
257         struct device *dev = &serdev->dev;
258         struct gnss_device *gdev;
259         struct sirf_data *data;
260         int ret;
261
262         data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
263         if (!data)
264                 return -ENOMEM;
265
266         gdev = gnss_allocate_device(dev);
267         if (!gdev)
268                 return -ENOMEM;
269
270         gdev->type = GNSS_TYPE_SIRF;
271         gdev->ops = &sirf_gnss_ops;
272         gnss_set_drvdata(gdev, data);
273
274         data->serdev = serdev;
275         data->gdev = gdev;
276
277         init_waitqueue_head(&data->power_wait);
278
279         serdev_device_set_drvdata(serdev, data);
280         serdev_device_set_client_ops(serdev, &sirf_serdev_ops);
281
282         ret = sirf_parse_dt(serdev);
283         if (ret)
284                 goto err_put_device;
285
286         data->vcc = devm_regulator_get(dev, "vcc");
287         if (IS_ERR(data->vcc)) {
288                 ret = PTR_ERR(data->vcc);
289                 goto err_put_device;
290         }
291
292         data->on_off = devm_gpiod_get_optional(dev, "sirf,onoff",
293                         GPIOD_OUT_LOW);
294         if (IS_ERR(data->on_off))
295                 goto err_put_device;
296
297         if (data->on_off) {
298                 data->wakeup = devm_gpiod_get_optional(dev, "sirf,wakeup",
299                                 GPIOD_IN);
300                 if (IS_ERR(data->wakeup))
301                         goto err_put_device;
302
303                 /*
304                  * Configurations where WAKEUP has been left not connected,
305                  * are currently not supported.
306                  */
307                 if (!data->wakeup) {
308                         dev_err(dev, "no wakeup gpio specified\n");
309                         ret = -ENODEV;
310                         goto err_put_device;
311                 }
312         }
313
314         if (data->wakeup) {
315                 ret = gpiod_to_irq(data->wakeup);
316                 if (ret < 0)
317                         goto err_put_device;
318
319                 data->irq = ret;
320
321                 ret = devm_request_threaded_irq(dev, data->irq, NULL,
322                                 sirf_wakeup_handler,
323                                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
324                                 "wakeup", data);
325                 if (ret)
326                         goto err_put_device;
327         }
328
329         if (data->on_off) {
330                 ret = regulator_enable(data->vcc);
331                 if (ret)
332                         goto err_put_device;
333
334                 /* Wait for chip to boot into hibernate mode */
335                 msleep(SIRF_BOOT_DELAY);
336         }
337
338         if (IS_ENABLED(CONFIG_PM)) {
339                 pm_runtime_set_suspended(dev);  /* clear runtime_error flag */
340                 pm_runtime_enable(dev);
341         } else {
342                 ret = sirf_runtime_resume(dev);
343                 if (ret < 0)
344                         goto err_disable_vcc;
345         }
346
347         ret = gnss_register_device(gdev);
348         if (ret)
349                 goto err_disable_rpm;
350
351         return 0;
352
353 err_disable_rpm:
354         if (IS_ENABLED(CONFIG_PM))
355                 pm_runtime_disable(dev);
356         else
357                 sirf_runtime_suspend(dev);
358 err_disable_vcc:
359         if (data->on_off)
360                 regulator_disable(data->vcc);
361 err_put_device:
362         gnss_put_device(data->gdev);
363
364         return ret;
365 }
366
367 static void sirf_remove(struct serdev_device *serdev)
368 {
369         struct sirf_data *data = serdev_device_get_drvdata(serdev);
370
371         gnss_deregister_device(data->gdev);
372
373         if (IS_ENABLED(CONFIG_PM))
374                 pm_runtime_disable(&serdev->dev);
375         else
376                 sirf_runtime_suspend(&serdev->dev);
377
378         if (data->on_off)
379                 regulator_disable(data->vcc);
380
381         gnss_put_device(data->gdev);
382 };
383
384 #ifdef CONFIG_OF
385 static const struct of_device_id sirf_of_match[] = {
386         { .compatible = "fastrax,uc430" },
387         { .compatible = "linx,r4" },
388         { .compatible = "wi2wi,w2sg0008i" },
389         { .compatible = "wi2wi,w2sg0084i" },
390         {},
391 };
392 MODULE_DEVICE_TABLE(of, sirf_of_match);
393 #endif
394
395 static struct serdev_device_driver sirf_driver = {
396         .driver = {
397                 .name           = "gnss-sirf",
398                 .of_match_table = of_match_ptr(sirf_of_match),
399                 .pm             = &sirf_pm_ops,
400         },
401         .probe  = sirf_probe,
402         .remove = sirf_remove,
403 };
404 module_serdev_device_driver(sirf_driver);
405
406 MODULE_AUTHOR("Johan Hovold <johan@kernel.org>");
407 MODULE_DESCRIPTION("SiRFstar GNSS receiver driver");
408 MODULE_LICENSE("GPL v2");