linux-sg2042/include/linux/gnss.h

76 lines
1.5 KiB
C
Raw Normal View History

gnss: add GNSS receiver subsystem Add a new subsystem for GNSS (e.g. GPS) receivers. While GNSS receivers are typically accessed using a UART interface they often also support other I/O interfaces such as I2C, SPI and USB, while yet other devices use iomem or even some form of remote-processor messaging (rpmsg). The new GNSS subsystem abstracts the underlying interface and provides a new "gnss" class type, which exposes a character-device interface (e.g. /dev/gnss0) to user space. This allows GNSS receivers to have a representation in the Linux device model, something which is important not least for power management purposes. Note that the character-device interface provides raw access to whatever protocol the receiver is (currently) using, such as NMEA 0183, UBX or SiRF Binary. These protocols are expected to be continued to be handled by user space for the time being, even if some hybrid solutions are also conceivable (e.g. to have kernel drivers issue management commands). This will still allow for better platform integration by allowing GNSS devices and their resources (e.g. regulators and enable-gpios) to be described by firmware and managed by kernel drivers rather than platform-specific scripts and services. While the current interface is kept minimal, it could be extended using IOCTLs, sysfs or uevents as needs and proper abstraction levels are identified and determined (e.g. for device and feature identification). Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-01 16:22:52 +08:00
/* SPDX-License-Identifier: GPL-2.0 */
/*
* GNSS receiver support
*
* Copyright (C) 2018 Johan Hovold <johan@kernel.org>
*/
#ifndef _LINUX_GNSS_H
#define _LINUX_GNSS_H
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/kfifo.h>
#include <linux/mutex.h>
#include <linux/rwsem.h>
#include <linux/types.h>
#include <linux/wait.h>
struct gnss_device;
enum gnss_type {
GNSS_TYPE_NMEA = 0,
GNSS_TYPE_SIRF,
GNSS_TYPE_UBX,
GNSS_TYPE_COUNT
};
gnss: add GNSS receiver subsystem Add a new subsystem for GNSS (e.g. GPS) receivers. While GNSS receivers are typically accessed using a UART interface they often also support other I/O interfaces such as I2C, SPI and USB, while yet other devices use iomem or even some form of remote-processor messaging (rpmsg). The new GNSS subsystem abstracts the underlying interface and provides a new "gnss" class type, which exposes a character-device interface (e.g. /dev/gnss0) to user space. This allows GNSS receivers to have a representation in the Linux device model, something which is important not least for power management purposes. Note that the character-device interface provides raw access to whatever protocol the receiver is (currently) using, such as NMEA 0183, UBX or SiRF Binary. These protocols are expected to be continued to be handled by user space for the time being, even if some hybrid solutions are also conceivable (e.g. to have kernel drivers issue management commands). This will still allow for better platform integration by allowing GNSS devices and their resources (e.g. regulators and enable-gpios) to be described by firmware and managed by kernel drivers rather than platform-specific scripts and services. While the current interface is kept minimal, it could be extended using IOCTLs, sysfs or uevents as needs and proper abstraction levels are identified and determined (e.g. for device and feature identification). Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-01 16:22:52 +08:00
struct gnss_operations {
int (*open)(struct gnss_device *gdev);
void (*close)(struct gnss_device *gdev);
int (*write_raw)(struct gnss_device *gdev, const unsigned char *buf,
size_t count);
};
struct gnss_device {
struct device dev;
struct cdev cdev;
int id;
enum gnss_type type;
gnss: add GNSS receiver subsystem Add a new subsystem for GNSS (e.g. GPS) receivers. While GNSS receivers are typically accessed using a UART interface they often also support other I/O interfaces such as I2C, SPI and USB, while yet other devices use iomem or even some form of remote-processor messaging (rpmsg). The new GNSS subsystem abstracts the underlying interface and provides a new "gnss" class type, which exposes a character-device interface (e.g. /dev/gnss0) to user space. This allows GNSS receivers to have a representation in the Linux device model, something which is important not least for power management purposes. Note that the character-device interface provides raw access to whatever protocol the receiver is (currently) using, such as NMEA 0183, UBX or SiRF Binary. These protocols are expected to be continued to be handled by user space for the time being, even if some hybrid solutions are also conceivable (e.g. to have kernel drivers issue management commands). This will still allow for better platform integration by allowing GNSS devices and their resources (e.g. regulators and enable-gpios) to be described by firmware and managed by kernel drivers rather than platform-specific scripts and services. While the current interface is kept minimal, it could be extended using IOCTLs, sysfs or uevents as needs and proper abstraction levels are identified and determined (e.g. for device and feature identification). Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-01 16:22:52 +08:00
unsigned long flags;
struct rw_semaphore rwsem;
const struct gnss_operations *ops;
unsigned int count;
unsigned int disconnected:1;
struct mutex read_mutex;
struct kfifo read_fifo;
wait_queue_head_t read_queue;
struct mutex write_mutex;
char *write_buf;
};
struct gnss_device *gnss_allocate_device(struct device *parent);
void gnss_put_device(struct gnss_device *gdev);
int gnss_register_device(struct gnss_device *gdev);
void gnss_deregister_device(struct gnss_device *gdev);
int gnss_insert_raw(struct gnss_device *gdev, const unsigned char *buf,
size_t count);
static inline void gnss_set_drvdata(struct gnss_device *gdev, void *data)
{
dev_set_drvdata(&gdev->dev, data);
}
static inline void *gnss_get_drvdata(struct gnss_device *gdev)
{
return dev_get_drvdata(&gdev->dev);
}
#endif /* _LINUX_GNSS_H */