1 // SPDX-License-Identifier: GPL-2.0
3 * u-blox GNSS receiver driver
5 * Copyright (C) 2018 Johan Hovold <johan@kernel.org>
8 #include <linux/errno.h>
9 #include <linux/gnss.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
15 #include <linux/regulator/consumer.h>
16 #include <linux/serdev.h>
21 struct regulator
*vcc
;
24 static int ubx_set_active(struct gnss_serial
*gserial
)
26 struct ubx_data
*data
= gnss_serial_get_drvdata(gserial
);
29 ret
= regulator_enable(data
->vcc
);
36 static int ubx_set_standby(struct gnss_serial
*gserial
)
38 struct ubx_data
*data
= gnss_serial_get_drvdata(gserial
);
41 ret
= regulator_disable(data
->vcc
);
48 static int ubx_set_power(struct gnss_serial
*gserial
,
49 enum gnss_serial_pm_state state
)
52 case GNSS_SERIAL_ACTIVE
:
53 return ubx_set_active(gserial
);
55 case GNSS_SERIAL_STANDBY
:
56 return ubx_set_standby(gserial
);
62 static const struct gnss_serial_ops ubx_gserial_ops
= {
63 .set_power
= ubx_set_power
,
66 static int ubx_probe(struct serdev_device
*serdev
)
68 struct gnss_serial
*gserial
;
69 struct gpio_desc
*reset
;
70 struct ubx_data
*data
;
73 gserial
= gnss_serial_allocate(serdev
, sizeof(*data
));
74 if (IS_ERR(gserial
)) {
75 ret
= PTR_ERR(gserial
);
79 gserial
->ops
= &ubx_gserial_ops
;
81 gserial
->gdev
->type
= GNSS_TYPE_UBX
;
83 data
= gnss_serial_get_drvdata(gserial
);
85 data
->vcc
= devm_regulator_get(&serdev
->dev
, "vcc");
86 if (IS_ERR(data
->vcc
)) {
87 ret
= PTR_ERR(data
->vcc
);
88 goto err_free_gserial
;
91 ret
= devm_regulator_get_enable_optional(&serdev
->dev
, "v-bckp");
92 if (ret
< 0 && ret
!= -ENODEV
)
93 goto err_free_gserial
;
96 reset
= devm_gpiod_get_optional(&serdev
->dev
, "reset", GPIOD_OUT_LOW
);
99 goto err_free_gserial
;
102 ret
= gnss_serial_register(gserial
);
104 goto err_free_gserial
;
109 gnss_serial_free(gserial
);
114 static void ubx_remove(struct serdev_device
*serdev
)
116 struct gnss_serial
*gserial
= serdev_device_get_drvdata(serdev
);
118 gnss_serial_deregister(gserial
);
119 gnss_serial_free(gserial
);
123 static const struct of_device_id ubx_of_match
[] = {
124 { .compatible
= "u-blox,neo-6m" },
125 { .compatible
= "u-blox,neo-8" },
126 { .compatible
= "u-blox,neo-m8" },
129 MODULE_DEVICE_TABLE(of
, ubx_of_match
);
132 static struct serdev_device_driver ubx_driver
= {
135 .of_match_table
= of_match_ptr(ubx_of_match
),
136 .pm
= &gnss_serial_pm_ops
,
139 .remove
= ubx_remove
,
141 module_serdev_device_driver(ubx_driver
);
143 MODULE_AUTHOR("Johan Hovold <johan@kernel.org>");
144 MODULE_DESCRIPTION("u-blox GNSS receiver driver");
145 MODULE_LICENSE("GPL v2");