1 // SPDX-License-Identifier: GPL-2.0
3 * Mediatek 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
*vbackup
;
21 struct regulator
*vcc
;
24 static int mtk_set_active(struct gnss_serial
*gserial
)
26 struct mtk_data
*data
= gnss_serial_get_drvdata(gserial
);
29 ret
= regulator_enable(data
->vcc
);
36 static int mtk_set_standby(struct gnss_serial
*gserial
)
38 struct mtk_data
*data
= gnss_serial_get_drvdata(gserial
);
41 ret
= regulator_disable(data
->vcc
);
48 static int mtk_set_power(struct gnss_serial
*gserial
,
49 enum gnss_serial_pm_state state
)
52 case GNSS_SERIAL_ACTIVE
:
53 return mtk_set_active(gserial
);
55 case GNSS_SERIAL_STANDBY
:
56 return mtk_set_standby(gserial
);
62 static const struct gnss_serial_ops mtk_gserial_ops
= {
63 .set_power
= mtk_set_power
,
66 static int mtk_probe(struct serdev_device
*serdev
)
68 struct gnss_serial
*gserial
;
69 struct mtk_data
*data
;
72 gserial
= gnss_serial_allocate(serdev
, sizeof(*data
));
73 if (IS_ERR(gserial
)) {
74 ret
= PTR_ERR(gserial
);
78 gserial
->ops
= &mtk_gserial_ops
;
80 gserial
->gdev
->type
= GNSS_TYPE_MTK
;
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
->vbackup
= devm_regulator_get_optional(&serdev
->dev
, "vbackup");
91 if (IS_ERR(data
->vbackup
)) {
92 ret
= PTR_ERR(data
->vbackup
);
96 goto err_free_gserial
;
100 ret
= regulator_enable(data
->vbackup
);
102 goto err_free_gserial
;
105 ret
= gnss_serial_register(gserial
);
107 goto err_disable_vbackup
;
113 regulator_disable(data
->vbackup
);
115 gnss_serial_free(gserial
);
120 static void mtk_remove(struct serdev_device
*serdev
)
122 struct gnss_serial
*gserial
= serdev_device_get_drvdata(serdev
);
123 struct mtk_data
*data
= gnss_serial_get_drvdata(gserial
);
125 gnss_serial_deregister(gserial
);
127 regulator_disable(data
->vbackup
);
128 gnss_serial_free(gserial
);
132 static const struct of_device_id mtk_of_match
[] = {
133 { .compatible
= "globaltop,pa6h" },
136 MODULE_DEVICE_TABLE(of
, mtk_of_match
);
139 static struct serdev_device_driver mtk_driver
= {
142 .of_match_table
= of_match_ptr(mtk_of_match
),
143 .pm
= &gnss_serial_pm_ops
,
146 .remove
= mtk_remove
,
148 module_serdev_device_driver(mtk_driver
);
150 MODULE_AUTHOR("Loys Ollivier <lollivier@baylibre.com>");
151 MODULE_DESCRIPTION("Mediatek GNSS receiver driver");
152 MODULE_LICENSE("GPL v2");