12b6a4403SJohan Hovold /* SPDX-License-Identifier: GPL-2.0 */
22b6a4403SJohan Hovold /*
32b6a4403SJohan Hovold * GNSS receiver support
42b6a4403SJohan Hovold *
52b6a4403SJohan Hovold * Copyright (C) 2018 Johan Hovold <johan@kernel.org>
62b6a4403SJohan Hovold */
72b6a4403SJohan Hovold
82b6a4403SJohan Hovold #ifndef _LINUX_GNSS_H
92b6a4403SJohan Hovold #define _LINUX_GNSS_H
102b6a4403SJohan Hovold
112b6a4403SJohan Hovold #include <linux/cdev.h>
122b6a4403SJohan Hovold #include <linux/device.h>
132b6a4403SJohan Hovold #include <linux/kfifo.h>
142b6a4403SJohan Hovold #include <linux/mutex.h>
152b6a4403SJohan Hovold #include <linux/rwsem.h>
162b6a4403SJohan Hovold #include <linux/types.h>
172b6a4403SJohan Hovold #include <linux/wait.h>
182b6a4403SJohan Hovold
192b6a4403SJohan Hovold struct gnss_device;
202b6a4403SJohan Hovold
2110f14663SJohan Hovold enum gnss_type {
2210f14663SJohan Hovold GNSS_TYPE_NMEA = 0,
2310f14663SJohan Hovold GNSS_TYPE_SIRF,
2410f14663SJohan Hovold GNSS_TYPE_UBX,
25625239d4SLoys Ollivier GNSS_TYPE_MTK,
2610f14663SJohan Hovold
2710f14663SJohan Hovold GNSS_TYPE_COUNT
2810f14663SJohan Hovold };
2910f14663SJohan Hovold
302b6a4403SJohan Hovold struct gnss_operations {
312b6a4403SJohan Hovold int (*open)(struct gnss_device *gdev);
322b6a4403SJohan Hovold void (*close)(struct gnss_device *gdev);
332b6a4403SJohan Hovold int (*write_raw)(struct gnss_device *gdev, const unsigned char *buf,
342b6a4403SJohan Hovold size_t count);
352b6a4403SJohan Hovold };
362b6a4403SJohan Hovold
372b6a4403SJohan Hovold struct gnss_device {
382b6a4403SJohan Hovold struct device dev;
392b6a4403SJohan Hovold struct cdev cdev;
402b6a4403SJohan Hovold int id;
412b6a4403SJohan Hovold
4210f14663SJohan Hovold enum gnss_type type;
432b6a4403SJohan Hovold unsigned long flags;
442b6a4403SJohan Hovold
452b6a4403SJohan Hovold struct rw_semaphore rwsem;
462b6a4403SJohan Hovold const struct gnss_operations *ops;
472b6a4403SJohan Hovold unsigned int count;
482b6a4403SJohan Hovold unsigned int disconnected:1;
492b6a4403SJohan Hovold
502b6a4403SJohan Hovold struct mutex read_mutex;
512b6a4403SJohan Hovold struct kfifo read_fifo;
522b6a4403SJohan Hovold wait_queue_head_t read_queue;
532b6a4403SJohan Hovold
542b6a4403SJohan Hovold struct mutex write_mutex;
552b6a4403SJohan Hovold char *write_buf;
562b6a4403SJohan Hovold };
572b6a4403SJohan Hovold
582b6a4403SJohan Hovold struct gnss_device *gnss_allocate_device(struct device *parent);
592b6a4403SJohan Hovold void gnss_put_device(struct gnss_device *gdev);
602b6a4403SJohan Hovold int gnss_register_device(struct gnss_device *gdev);
612b6a4403SJohan Hovold void gnss_deregister_device(struct gnss_device *gdev);
622b6a4403SJohan Hovold
632b6a4403SJohan Hovold int gnss_insert_raw(struct gnss_device *gdev, const unsigned char *buf,
642b6a4403SJohan Hovold size_t count);
652b6a4403SJohan Hovold
gnss_set_drvdata(struct gnss_device * gdev,void * data)662b6a4403SJohan Hovold static inline void gnss_set_drvdata(struct gnss_device *gdev, void *data)
672b6a4403SJohan Hovold {
682b6a4403SJohan Hovold dev_set_drvdata(&gdev->dev, data);
692b6a4403SJohan Hovold }
702b6a4403SJohan Hovold
gnss_get_drvdata(struct gnss_device * gdev)712b6a4403SJohan Hovold static inline void *gnss_get_drvdata(struct gnss_device *gdev)
722b6a4403SJohan Hovold {
732b6a4403SJohan Hovold return dev_get_drvdata(&gdev->dev);
742b6a4403SJohan Hovold }
752b6a4403SJohan Hovold
762b6a4403SJohan Hovold #endif /* _LINUX_GNSS_H */
77