1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * SiRFstar GNSS receiver driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2018 Johan Hovold <johan@kernel.org>
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/errno.h>
9*4882a593Smuzhiyun #include <linux/gnss.h>
10*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
11*4882a593Smuzhiyun #include <linux/init.h>
12*4882a593Smuzhiyun #include <linux/interrupt.h>
13*4882a593Smuzhiyun #include <linux/kernel.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include <linux/of.h>
16*4882a593Smuzhiyun #include <linux/pm.h>
17*4882a593Smuzhiyun #include <linux/pm_runtime.h>
18*4882a593Smuzhiyun #include <linux/regulator/consumer.h>
19*4882a593Smuzhiyun #include <linux/sched.h>
20*4882a593Smuzhiyun #include <linux/serdev.h>
21*4882a593Smuzhiyun #include <linux/slab.h>
22*4882a593Smuzhiyun #include <linux/wait.h>
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #define SIRF_BOOT_DELAY 500
25*4882a593Smuzhiyun #define SIRF_ON_OFF_PULSE_TIME 100
26*4882a593Smuzhiyun #define SIRF_ACTIVATE_TIMEOUT 200
27*4882a593Smuzhiyun #define SIRF_HIBERNATE_TIMEOUT 200
28*4882a593Smuzhiyun /*
29*4882a593Smuzhiyun * If no data arrives for this time, we assume that the chip is off.
30*4882a593Smuzhiyun * REVISIT: The report cycle is configurable and can be several minutes long,
31*4882a593Smuzhiyun * so this will only work reliably if the report cycle is set to a reasonable
32*4882a593Smuzhiyun * low value. Also power saving settings (like send data only on movement)
33*4882a593Smuzhiyun * might things work even worse.
34*4882a593Smuzhiyun * Workaround might be to parse shutdown or bootup messages.
35*4882a593Smuzhiyun */
36*4882a593Smuzhiyun #define SIRF_REPORT_CYCLE 2000
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun struct sirf_data {
39*4882a593Smuzhiyun struct gnss_device *gdev;
40*4882a593Smuzhiyun struct serdev_device *serdev;
41*4882a593Smuzhiyun speed_t speed;
42*4882a593Smuzhiyun struct regulator *vcc;
43*4882a593Smuzhiyun struct regulator *lna;
44*4882a593Smuzhiyun struct gpio_desc *on_off;
45*4882a593Smuzhiyun struct gpio_desc *wakeup;
46*4882a593Smuzhiyun int irq;
47*4882a593Smuzhiyun bool active;
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun struct mutex gdev_mutex;
50*4882a593Smuzhiyun bool open;
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun struct mutex serdev_mutex;
53*4882a593Smuzhiyun int serdev_count;
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun wait_queue_head_t power_wait;
56*4882a593Smuzhiyun };
57*4882a593Smuzhiyun
sirf_serdev_open(struct sirf_data * data)58*4882a593Smuzhiyun static int sirf_serdev_open(struct sirf_data *data)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun int ret = 0;
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun mutex_lock(&data->serdev_mutex);
63*4882a593Smuzhiyun if (++data->serdev_count == 1) {
64*4882a593Smuzhiyun ret = serdev_device_open(data->serdev);
65*4882a593Smuzhiyun if (ret) {
66*4882a593Smuzhiyun data->serdev_count--;
67*4882a593Smuzhiyun goto out_unlock;
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun serdev_device_set_baudrate(data->serdev, data->speed);
71*4882a593Smuzhiyun serdev_device_set_flow_control(data->serdev, false);
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun out_unlock:
75*4882a593Smuzhiyun mutex_unlock(&data->serdev_mutex);
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun return ret;
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun
sirf_serdev_close(struct sirf_data * data)80*4882a593Smuzhiyun static void sirf_serdev_close(struct sirf_data *data)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun mutex_lock(&data->serdev_mutex);
83*4882a593Smuzhiyun if (--data->serdev_count == 0)
84*4882a593Smuzhiyun serdev_device_close(data->serdev);
85*4882a593Smuzhiyun mutex_unlock(&data->serdev_mutex);
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
sirf_open(struct gnss_device * gdev)88*4882a593Smuzhiyun static int sirf_open(struct gnss_device *gdev)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun struct sirf_data *data = gnss_get_drvdata(gdev);
91*4882a593Smuzhiyun struct serdev_device *serdev = data->serdev;
92*4882a593Smuzhiyun int ret;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun mutex_lock(&data->gdev_mutex);
95*4882a593Smuzhiyun data->open = true;
96*4882a593Smuzhiyun mutex_unlock(&data->gdev_mutex);
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun ret = sirf_serdev_open(data);
99*4882a593Smuzhiyun if (ret) {
100*4882a593Smuzhiyun mutex_lock(&data->gdev_mutex);
101*4882a593Smuzhiyun data->open = false;
102*4882a593Smuzhiyun mutex_unlock(&data->gdev_mutex);
103*4882a593Smuzhiyun return ret;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun ret = pm_runtime_get_sync(&serdev->dev);
107*4882a593Smuzhiyun if (ret < 0) {
108*4882a593Smuzhiyun dev_err(&gdev->dev, "failed to runtime resume: %d\n", ret);
109*4882a593Smuzhiyun pm_runtime_put_noidle(&serdev->dev);
110*4882a593Smuzhiyun goto err_close;
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun return 0;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun err_close:
116*4882a593Smuzhiyun sirf_serdev_close(data);
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun mutex_lock(&data->gdev_mutex);
119*4882a593Smuzhiyun data->open = false;
120*4882a593Smuzhiyun mutex_unlock(&data->gdev_mutex);
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun return ret;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun
sirf_close(struct gnss_device * gdev)125*4882a593Smuzhiyun static void sirf_close(struct gnss_device *gdev)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun struct sirf_data *data = gnss_get_drvdata(gdev);
128*4882a593Smuzhiyun struct serdev_device *serdev = data->serdev;
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun sirf_serdev_close(data);
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun pm_runtime_put(&serdev->dev);
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun mutex_lock(&data->gdev_mutex);
135*4882a593Smuzhiyun data->open = false;
136*4882a593Smuzhiyun mutex_unlock(&data->gdev_mutex);
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun
sirf_write_raw(struct gnss_device * gdev,const unsigned char * buf,size_t count)139*4882a593Smuzhiyun static int sirf_write_raw(struct gnss_device *gdev, const unsigned char *buf,
140*4882a593Smuzhiyun size_t count)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun struct sirf_data *data = gnss_get_drvdata(gdev);
143*4882a593Smuzhiyun struct serdev_device *serdev = data->serdev;
144*4882a593Smuzhiyun int ret;
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun /* write is only buffered synchronously */
147*4882a593Smuzhiyun ret = serdev_device_write(serdev, buf, count, MAX_SCHEDULE_TIMEOUT);
148*4882a593Smuzhiyun if (ret < 0 || ret < count)
149*4882a593Smuzhiyun return ret;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /* FIXME: determine if interrupted? */
152*4882a593Smuzhiyun serdev_device_wait_until_sent(serdev, 0);
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun return count;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun static const struct gnss_operations sirf_gnss_ops = {
158*4882a593Smuzhiyun .open = sirf_open,
159*4882a593Smuzhiyun .close = sirf_close,
160*4882a593Smuzhiyun .write_raw = sirf_write_raw,
161*4882a593Smuzhiyun };
162*4882a593Smuzhiyun
sirf_receive_buf(struct serdev_device * serdev,const unsigned char * buf,size_t count)163*4882a593Smuzhiyun static int sirf_receive_buf(struct serdev_device *serdev,
164*4882a593Smuzhiyun const unsigned char *buf, size_t count)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun struct sirf_data *data = serdev_device_get_drvdata(serdev);
167*4882a593Smuzhiyun struct gnss_device *gdev = data->gdev;
168*4882a593Smuzhiyun int ret = 0;
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun if (!data->wakeup && !data->active) {
171*4882a593Smuzhiyun data->active = true;
172*4882a593Smuzhiyun wake_up_interruptible(&data->power_wait);
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun mutex_lock(&data->gdev_mutex);
176*4882a593Smuzhiyun if (data->open)
177*4882a593Smuzhiyun ret = gnss_insert_raw(gdev, buf, count);
178*4882a593Smuzhiyun mutex_unlock(&data->gdev_mutex);
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun return ret;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun static const struct serdev_device_ops sirf_serdev_ops = {
184*4882a593Smuzhiyun .receive_buf = sirf_receive_buf,
185*4882a593Smuzhiyun .write_wakeup = serdev_device_write_wakeup,
186*4882a593Smuzhiyun };
187*4882a593Smuzhiyun
sirf_wakeup_handler(int irq,void * dev_id)188*4882a593Smuzhiyun static irqreturn_t sirf_wakeup_handler(int irq, void *dev_id)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun struct sirf_data *data = dev_id;
191*4882a593Smuzhiyun struct device *dev = &data->serdev->dev;
192*4882a593Smuzhiyun int ret;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun ret = gpiod_get_value_cansleep(data->wakeup);
195*4882a593Smuzhiyun dev_dbg(dev, "%s - wakeup = %d\n", __func__, ret);
196*4882a593Smuzhiyun if (ret < 0)
197*4882a593Smuzhiyun goto out;
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun data->active = ret;
200*4882a593Smuzhiyun wake_up_interruptible(&data->power_wait);
201*4882a593Smuzhiyun out:
202*4882a593Smuzhiyun return IRQ_HANDLED;
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
sirf_wait_for_power_state_nowakeup(struct sirf_data * data,bool active,unsigned long timeout)205*4882a593Smuzhiyun static int sirf_wait_for_power_state_nowakeup(struct sirf_data *data,
206*4882a593Smuzhiyun bool active,
207*4882a593Smuzhiyun unsigned long timeout)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun int ret;
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun /* Wait for state change (including any shutdown messages). */
212*4882a593Smuzhiyun msleep(timeout);
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun /* Wait for data reception or timeout. */
215*4882a593Smuzhiyun data->active = false;
216*4882a593Smuzhiyun ret = wait_event_interruptible_timeout(data->power_wait,
217*4882a593Smuzhiyun data->active, msecs_to_jiffies(SIRF_REPORT_CYCLE));
218*4882a593Smuzhiyun if (ret < 0)
219*4882a593Smuzhiyun return ret;
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun if (ret > 0 && !active)
222*4882a593Smuzhiyun return -ETIMEDOUT;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun if (ret == 0 && active)
225*4882a593Smuzhiyun return -ETIMEDOUT;
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun return 0;
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun
sirf_wait_for_power_state(struct sirf_data * data,bool active,unsigned long timeout)230*4882a593Smuzhiyun static int sirf_wait_for_power_state(struct sirf_data *data, bool active,
231*4882a593Smuzhiyun unsigned long timeout)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun int ret;
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun if (!data->wakeup)
236*4882a593Smuzhiyun return sirf_wait_for_power_state_nowakeup(data, active, timeout);
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun ret = wait_event_interruptible_timeout(data->power_wait,
239*4882a593Smuzhiyun data->active == active, msecs_to_jiffies(timeout));
240*4882a593Smuzhiyun if (ret < 0)
241*4882a593Smuzhiyun return ret;
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun if (ret == 0) {
244*4882a593Smuzhiyun dev_warn(&data->serdev->dev, "timeout waiting for active state = %d\n",
245*4882a593Smuzhiyun active);
246*4882a593Smuzhiyun return -ETIMEDOUT;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun return 0;
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun
sirf_pulse_on_off(struct sirf_data * data)252*4882a593Smuzhiyun static void sirf_pulse_on_off(struct sirf_data *data)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun gpiod_set_value_cansleep(data->on_off, 1);
255*4882a593Smuzhiyun msleep(SIRF_ON_OFF_PULSE_TIME);
256*4882a593Smuzhiyun gpiod_set_value_cansleep(data->on_off, 0);
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun
sirf_set_active(struct sirf_data * data,bool active)259*4882a593Smuzhiyun static int sirf_set_active(struct sirf_data *data, bool active)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun unsigned long timeout;
262*4882a593Smuzhiyun int retries = 3;
263*4882a593Smuzhiyun int ret;
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun if (active)
266*4882a593Smuzhiyun timeout = SIRF_ACTIVATE_TIMEOUT;
267*4882a593Smuzhiyun else
268*4882a593Smuzhiyun timeout = SIRF_HIBERNATE_TIMEOUT;
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun if (!data->wakeup) {
271*4882a593Smuzhiyun ret = sirf_serdev_open(data);
272*4882a593Smuzhiyun if (ret)
273*4882a593Smuzhiyun return ret;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun do {
277*4882a593Smuzhiyun sirf_pulse_on_off(data);
278*4882a593Smuzhiyun ret = sirf_wait_for_power_state(data, active, timeout);
279*4882a593Smuzhiyun } while (ret == -ETIMEDOUT && retries--);
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun if (!data->wakeup)
282*4882a593Smuzhiyun sirf_serdev_close(data);
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun if (ret)
285*4882a593Smuzhiyun return ret;
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun return 0;
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun
sirf_runtime_suspend(struct device * dev)290*4882a593Smuzhiyun static int sirf_runtime_suspend(struct device *dev)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun struct sirf_data *data = dev_get_drvdata(dev);
293*4882a593Smuzhiyun int ret2;
294*4882a593Smuzhiyun int ret;
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun if (data->on_off)
297*4882a593Smuzhiyun ret = sirf_set_active(data, false);
298*4882a593Smuzhiyun else
299*4882a593Smuzhiyun ret = regulator_disable(data->vcc);
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun if (ret)
302*4882a593Smuzhiyun return ret;
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun ret = regulator_disable(data->lna);
305*4882a593Smuzhiyun if (ret)
306*4882a593Smuzhiyun goto err_reenable;
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun return 0;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun err_reenable:
311*4882a593Smuzhiyun if (data->on_off)
312*4882a593Smuzhiyun ret2 = sirf_set_active(data, true);
313*4882a593Smuzhiyun else
314*4882a593Smuzhiyun ret2 = regulator_enable(data->vcc);
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun if (ret2)
317*4882a593Smuzhiyun dev_err(dev,
318*4882a593Smuzhiyun "failed to reenable power on failed suspend: %d\n",
319*4882a593Smuzhiyun ret2);
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun return ret;
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun
sirf_runtime_resume(struct device * dev)324*4882a593Smuzhiyun static int sirf_runtime_resume(struct device *dev)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun struct sirf_data *data = dev_get_drvdata(dev);
327*4882a593Smuzhiyun int ret;
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun ret = regulator_enable(data->lna);
330*4882a593Smuzhiyun if (ret)
331*4882a593Smuzhiyun return ret;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun if (data->on_off)
334*4882a593Smuzhiyun ret = sirf_set_active(data, true);
335*4882a593Smuzhiyun else
336*4882a593Smuzhiyun ret = regulator_enable(data->vcc);
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun if (ret)
339*4882a593Smuzhiyun goto err_disable_lna;
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun return 0;
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun err_disable_lna:
344*4882a593Smuzhiyun regulator_disable(data->lna);
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun return ret;
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun
sirf_suspend(struct device * dev)349*4882a593Smuzhiyun static int __maybe_unused sirf_suspend(struct device *dev)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun struct sirf_data *data = dev_get_drvdata(dev);
352*4882a593Smuzhiyun int ret = 0;
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun if (!pm_runtime_suspended(dev))
355*4882a593Smuzhiyun ret = sirf_runtime_suspend(dev);
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun if (data->wakeup)
358*4882a593Smuzhiyun disable_irq(data->irq);
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun return ret;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun
sirf_resume(struct device * dev)363*4882a593Smuzhiyun static int __maybe_unused sirf_resume(struct device *dev)
364*4882a593Smuzhiyun {
365*4882a593Smuzhiyun struct sirf_data *data = dev_get_drvdata(dev);
366*4882a593Smuzhiyun int ret = 0;
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun if (data->wakeup)
369*4882a593Smuzhiyun enable_irq(data->irq);
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun if (!pm_runtime_suspended(dev))
372*4882a593Smuzhiyun ret = sirf_runtime_resume(dev);
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun return ret;
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun static const struct dev_pm_ops sirf_pm_ops = {
378*4882a593Smuzhiyun SET_SYSTEM_SLEEP_PM_OPS(sirf_suspend, sirf_resume)
379*4882a593Smuzhiyun SET_RUNTIME_PM_OPS(sirf_runtime_suspend, sirf_runtime_resume, NULL)
380*4882a593Smuzhiyun };
381*4882a593Smuzhiyun
sirf_parse_dt(struct serdev_device * serdev)382*4882a593Smuzhiyun static int sirf_parse_dt(struct serdev_device *serdev)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun struct sirf_data *data = serdev_device_get_drvdata(serdev);
385*4882a593Smuzhiyun struct device_node *node = serdev->dev.of_node;
386*4882a593Smuzhiyun u32 speed = 9600;
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun of_property_read_u32(node, "current-speed", &speed);
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun data->speed = speed;
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun return 0;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
sirf_probe(struct serdev_device * serdev)395*4882a593Smuzhiyun static int sirf_probe(struct serdev_device *serdev)
396*4882a593Smuzhiyun {
397*4882a593Smuzhiyun struct device *dev = &serdev->dev;
398*4882a593Smuzhiyun struct gnss_device *gdev;
399*4882a593Smuzhiyun struct sirf_data *data;
400*4882a593Smuzhiyun int ret;
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
403*4882a593Smuzhiyun if (!data)
404*4882a593Smuzhiyun return -ENOMEM;
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun gdev = gnss_allocate_device(dev);
407*4882a593Smuzhiyun if (!gdev)
408*4882a593Smuzhiyun return -ENOMEM;
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun gdev->type = GNSS_TYPE_SIRF;
411*4882a593Smuzhiyun gdev->ops = &sirf_gnss_ops;
412*4882a593Smuzhiyun gnss_set_drvdata(gdev, data);
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun data->serdev = serdev;
415*4882a593Smuzhiyun data->gdev = gdev;
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun mutex_init(&data->gdev_mutex);
418*4882a593Smuzhiyun mutex_init(&data->serdev_mutex);
419*4882a593Smuzhiyun init_waitqueue_head(&data->power_wait);
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun serdev_device_set_drvdata(serdev, data);
422*4882a593Smuzhiyun serdev_device_set_client_ops(serdev, &sirf_serdev_ops);
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun ret = sirf_parse_dt(serdev);
425*4882a593Smuzhiyun if (ret)
426*4882a593Smuzhiyun goto err_put_device;
427*4882a593Smuzhiyun
428*4882a593Smuzhiyun data->vcc = devm_regulator_get(dev, "vcc");
429*4882a593Smuzhiyun if (IS_ERR(data->vcc)) {
430*4882a593Smuzhiyun ret = PTR_ERR(data->vcc);
431*4882a593Smuzhiyun goto err_put_device;
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun data->lna = devm_regulator_get(dev, "lna");
435*4882a593Smuzhiyun if (IS_ERR(data->lna)) {
436*4882a593Smuzhiyun ret = PTR_ERR(data->lna);
437*4882a593Smuzhiyun goto err_put_device;
438*4882a593Smuzhiyun }
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun data->on_off = devm_gpiod_get_optional(dev, "sirf,onoff",
441*4882a593Smuzhiyun GPIOD_OUT_LOW);
442*4882a593Smuzhiyun if (IS_ERR(data->on_off)) {
443*4882a593Smuzhiyun ret = PTR_ERR(data->on_off);
444*4882a593Smuzhiyun goto err_put_device;
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun if (data->on_off) {
448*4882a593Smuzhiyun data->wakeup = devm_gpiod_get_optional(dev, "sirf,wakeup",
449*4882a593Smuzhiyun GPIOD_IN);
450*4882a593Smuzhiyun if (IS_ERR(data->wakeup)) {
451*4882a593Smuzhiyun ret = PTR_ERR(data->wakeup);
452*4882a593Smuzhiyun goto err_put_device;
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun ret = regulator_enable(data->vcc);
456*4882a593Smuzhiyun if (ret)
457*4882a593Smuzhiyun goto err_put_device;
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun /* Wait for chip to boot into hibernate mode. */
460*4882a593Smuzhiyun msleep(SIRF_BOOT_DELAY);
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun if (data->wakeup) {
464*4882a593Smuzhiyun ret = gpiod_get_value_cansleep(data->wakeup);
465*4882a593Smuzhiyun if (ret < 0)
466*4882a593Smuzhiyun goto err_disable_vcc;
467*4882a593Smuzhiyun data->active = ret;
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun ret = gpiod_to_irq(data->wakeup);
470*4882a593Smuzhiyun if (ret < 0)
471*4882a593Smuzhiyun goto err_disable_vcc;
472*4882a593Smuzhiyun data->irq = ret;
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun ret = request_threaded_irq(data->irq, NULL, sirf_wakeup_handler,
475*4882a593Smuzhiyun IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
476*4882a593Smuzhiyun "wakeup", data);
477*4882a593Smuzhiyun if (ret)
478*4882a593Smuzhiyun goto err_disable_vcc;
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun if (data->on_off) {
482*4882a593Smuzhiyun if (!data->wakeup) {
483*4882a593Smuzhiyun data->active = false;
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun ret = sirf_serdev_open(data);
486*4882a593Smuzhiyun if (ret)
487*4882a593Smuzhiyun goto err_disable_vcc;
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun msleep(SIRF_REPORT_CYCLE);
490*4882a593Smuzhiyun sirf_serdev_close(data);
491*4882a593Smuzhiyun }
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun /* Force hibernate mode if already active. */
494*4882a593Smuzhiyun if (data->active) {
495*4882a593Smuzhiyun ret = sirf_set_active(data, false);
496*4882a593Smuzhiyun if (ret) {
497*4882a593Smuzhiyun dev_err(dev, "failed to set hibernate mode: %d\n",
498*4882a593Smuzhiyun ret);
499*4882a593Smuzhiyun goto err_free_irq;
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun }
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun if (IS_ENABLED(CONFIG_PM)) {
505*4882a593Smuzhiyun pm_runtime_set_suspended(dev); /* clear runtime_error flag */
506*4882a593Smuzhiyun pm_runtime_enable(dev);
507*4882a593Smuzhiyun } else {
508*4882a593Smuzhiyun ret = sirf_runtime_resume(dev);
509*4882a593Smuzhiyun if (ret < 0)
510*4882a593Smuzhiyun goto err_free_irq;
511*4882a593Smuzhiyun }
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun ret = gnss_register_device(gdev);
514*4882a593Smuzhiyun if (ret)
515*4882a593Smuzhiyun goto err_disable_rpm;
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun return 0;
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun err_disable_rpm:
520*4882a593Smuzhiyun if (IS_ENABLED(CONFIG_PM))
521*4882a593Smuzhiyun pm_runtime_disable(dev);
522*4882a593Smuzhiyun else
523*4882a593Smuzhiyun sirf_runtime_suspend(dev);
524*4882a593Smuzhiyun err_free_irq:
525*4882a593Smuzhiyun if (data->wakeup)
526*4882a593Smuzhiyun free_irq(data->irq, data);
527*4882a593Smuzhiyun err_disable_vcc:
528*4882a593Smuzhiyun if (data->on_off)
529*4882a593Smuzhiyun regulator_disable(data->vcc);
530*4882a593Smuzhiyun err_put_device:
531*4882a593Smuzhiyun gnss_put_device(data->gdev);
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun return ret;
534*4882a593Smuzhiyun }
535*4882a593Smuzhiyun
sirf_remove(struct serdev_device * serdev)536*4882a593Smuzhiyun static void sirf_remove(struct serdev_device *serdev)
537*4882a593Smuzhiyun {
538*4882a593Smuzhiyun struct sirf_data *data = serdev_device_get_drvdata(serdev);
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun gnss_deregister_device(data->gdev);
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun if (IS_ENABLED(CONFIG_PM))
543*4882a593Smuzhiyun pm_runtime_disable(&serdev->dev);
544*4882a593Smuzhiyun else
545*4882a593Smuzhiyun sirf_runtime_suspend(&serdev->dev);
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun if (data->wakeup)
548*4882a593Smuzhiyun free_irq(data->irq, data);
549*4882a593Smuzhiyun
550*4882a593Smuzhiyun if (data->on_off)
551*4882a593Smuzhiyun regulator_disable(data->vcc);
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun gnss_put_device(data->gdev);
554*4882a593Smuzhiyun };
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun #ifdef CONFIG_OF
557*4882a593Smuzhiyun static const struct of_device_id sirf_of_match[] = {
558*4882a593Smuzhiyun { .compatible = "fastrax,uc430" },
559*4882a593Smuzhiyun { .compatible = "linx,r4" },
560*4882a593Smuzhiyun { .compatible = "wi2wi,w2sg0004" },
561*4882a593Smuzhiyun { .compatible = "wi2wi,w2sg0008i" },
562*4882a593Smuzhiyun { .compatible = "wi2wi,w2sg0084i" },
563*4882a593Smuzhiyun {},
564*4882a593Smuzhiyun };
565*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, sirf_of_match);
566*4882a593Smuzhiyun #endif
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun static struct serdev_device_driver sirf_driver = {
569*4882a593Smuzhiyun .driver = {
570*4882a593Smuzhiyun .name = "gnss-sirf",
571*4882a593Smuzhiyun .of_match_table = of_match_ptr(sirf_of_match),
572*4882a593Smuzhiyun .pm = &sirf_pm_ops,
573*4882a593Smuzhiyun },
574*4882a593Smuzhiyun .probe = sirf_probe,
575*4882a593Smuzhiyun .remove = sirf_remove,
576*4882a593Smuzhiyun };
577*4882a593Smuzhiyun module_serdev_device_driver(sirf_driver);
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun MODULE_AUTHOR("Johan Hovold <johan@kernel.org>");
580*4882a593Smuzhiyun MODULE_DESCRIPTION("SiRFstar GNSS receiver driver");
581*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
582