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