Help figuring out how to associate a device with GNSS subsystem (gnss_* modules)

John Scott jscott at posteo.net
Mon Jan 19 19:17:32 EST 2026


Hello,

I'm trying to figure out how to use the kernel's GNSS subsystem to create device nodes such as /dev/gnss0 on a conventional (non-embedded) system. Some information from the author about the subsystem is at https://events19.linuxfoundation.org/wp-content/uploads/2017/12/The-GNSS-Subsystem-Johan-Hovold-Hovold-Consulting-AB.pdf#nameddest=page.17
GNSS receivers usually use a serial interface to send geolocation information to a host in a text format known informally as NMEA-0183. The hardware I have is an Adafruit Ultimate GPS (MediaTek MT3333) with a bundled USB serial converter (Silicon Labs CP2102N) so that the device can be plugged into a computer with USB. At https://cdn-shop.adafruit.com/product-files/1059/CD+PA1616D+Datasheet+v.05.pdf is a detailed description. I have been using it without the GNSS subsystem, just accessing the TTY in user-space applications like gpsd and GeoClue. Enumerating serial devices is notoriously difficult in general, but I'm lucky that the serial converter has a manufacturer's serial number baked in so I can reliably detect device insertion with a udev rule like this:
	SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ATTRS{serial}=="0e30054dff9fec11a7ec8fcfa29c855c", ...

I can use such a udev rule to match the hardware or start a service if I want, but without such a rule and out-of-the-box, the cp210x kernel driver gets loaded for this family of USB-serial converters, and the GNSS receiver is accessible at /dev/ttyUSB0 for example. Then I can read from the device to my heart's content.

What's confusing me, however, is how to tell the appropriate GNSS kernel module(s) about this device so they can offer advanced features. (For example, some GNSS receivers such as MediaTek's allow changing the serial baud rate on-the-fly using a special command. It's conceivable that a MediaTek GNSS driver would take care of this negotiation if a user application does 'stty 115200', say.) There are Devicetree properties recognized by the kernel for setting up GNSS device nodes, but I'm using an ordinary x86_64 PC at the moment which doesn't use Devicetree at all. The USB vendor/product ID is for the generic serial converter, and I would like to use a udev rule or something similar with "smarts" to use my device's serial number for intelligent identification.
There are a couple kernel modules to this subsystem:
 • gnss
 • gnss-mtk (depends on gnss-serial)
 • gnss-serial (depends on gnss)
 • gnss-usb (depends on gnss)

Technically gnss-mtk is the most specialized to my device; this is for MediaTek receivers. I think gnss-usb is for a non-TTY-type device that sends and receives the NMEA-0183 data from the USB endpoint descriptors directly, so I *think* it's irrelevant for me. In particular, the cp210x driver does a great job with the serial converter and exposing the USB serial converter as a TTY, so I guess gnss-mtk (and transitively gnss-serial) is supposed to "wrap" around the TTY device. The USB device is probably useless without cp210x because otherwise there'd be no way to know how to talk to the converter.

There is a teeny bit of information at https://docs.kernel.org/admin-guide/abi-testing.html#abi-sys-class-gnss-gnss-n-type that shows sysfs nodes for devices should look like "/sys/class/gnss/gnss<N>". We shouldn't have to worry about setting the 'type' parameter described there because it's implicit in the use of gnss-mtk.

As suggested at https://lwn.net/Articles/143397/ my serial adapter gets exposed as /dev/char/188:0, so I tried doing this:
# printf '188:0' > /sys/bus/serial/drivers/gnss-mtk/bind
but I get "No such device". Also, that LWN article is only using USB devices in its example and it's not obvious what syntax I would use for a serial device anyway. It also says that the device should not be bound to any driver already, but we need gnss-mtk to "wrap" around the serial converter's own driver so this is very tricky... I also looked in /sys/class/gnss/ for clues but that directory is empty.
It looks like in drivers/gnss/core.c there is a gnss_allocate_device() function that creates device nodes and assigns them names.

In summary, how do I actually use this subsystem? Is Devicetree the only way to set this up?
Thanks
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 411 bytes
Desc: This is a digitally signed message part
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20260120/cbbdd176/attachment.sig>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 6270 bytes
Desc: not available
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20260120/cbbdd176/attachment.p7s>


More information about the Kernelnewbies mailing list