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

Attachment: signature.asc
Description: This is a digitally signed message part

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
Kernelnewbies mailing list
[email protected]
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

Reply via email to