sirf.c 12 KB

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