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/init.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
14 #include <linux/regulator/consumer.h>
15 #include <linux/serdev.h>
20 struct regulator
*v_bckp
;
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 ubx_data
*data
;
72 gserial
= gnss_serial_allocate(serdev
, sizeof(*data
));
73 if (IS_ERR(gserial
)) {
74 ret
= PTR_ERR(gserial
);
78 gserial
->ops
= &ubx_gserial_ops
;
80 gserial
->gdev
->type
= GNSS_TYPE_UBX
;
82 data
= gnss_serial_get_drvdata(gserial
);
84 data
->vcc
= devm_regulator_get(&serdev
->dev
, "vcc");
85 if (IS_ERR(data
->vcc
)) {
86 ret
= PTR_ERR(data
->vcc
);
87 goto err_free_gserial
;
90 data
->v_bckp
= devm_regulator_get_optional(&serdev
->dev
, "v-bckp");
91 if (IS_ERR(data
->v_bckp
)) {
92 ret
= PTR_ERR(data
->v_bckp
);
96 goto err_free_gserial
;
100 ret
= regulator_enable(data
->v_bckp
);
102 goto err_free_gserial
;
105 ret
= gnss_serial_register(gserial
);
107 goto err_disable_v_bckp
;
113 regulator_disable(data
->v_bckp
);
115 gnss_serial_free(gserial
);
120 static void ubx_remove(struct serdev_device
*serdev
)
122 struct gnss_serial
*gserial
= serdev_device_get_drvdata(serdev
);
123 struct ubx_data
*data
= gnss_serial_get_drvdata(gserial
);
125 gnss_serial_deregister(gserial
);
127 regulator_disable(data
->v_bckp
);
128 gnss_serial_free(gserial
);
132 static const struct of_device_id ubx_of_match
[] = {
133 { .compatible
= "u-blox,neo-6m" },
134 { .compatible
= "u-blox,neo-8" },
135 { .compatible
= "u-blox,neo-m8" },
138 MODULE_DEVICE_TABLE(of
, ubx_of_match
);
141 static struct serdev_device_driver ubx_driver
= {
144 .of_match_table
= of_match_ptr(ubx_of_match
),
145 .pm
= &gnss_serial_pm_ops
,
148 .remove
= ubx_remove
,
150 module_serdev_device_driver(ubx_driver
);
152 MODULE_AUTHOR("Johan Hovold <johan@kernel.org>");
153 MODULE_DESCRIPTION("u-blox GNSS receiver driver");
154 MODULE_LICENSE("GPL v2");