Skip to contentSkip to conversation

gnss: add USB support

PATCH In review Johan Hovold 4 participants 9 messages Dec 20, 2021 – Dec 22, 2021

Subsystems (2)
lore
Share & tools
lore

Johan Hovold

author maintainer
#0 lore raw

cover gnss: add USB support

This series adds a generic driver for GNSS receivers with a USB interface and a first device id for the Sierra Wireless XM1210 receiver.

Johan

Johan Hovold (2):
gnss: add USB support
gnss: usb: add support for Sierra Wireless XM1210

 drivers/gnss/Kconfig  |  11 +++
 drivers/gnss/Makefile |   3 +
 drivers/gnss/usb.c    | 210 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 224 insertions(+)
 create mode 100644 drivers/gnss/usb.c
Signature · 1 line
2.32.0
author maintainer
#1 lore raw

PATCH 1/2 gnss: add USB support

Add a generic driver for GNSS receivers with a USB interface with two bulk endpoints.

The driver currently assumes that the device protocol is NMEA (only) but this can be generalised later as needed.

---
 drivers/gnss/Kconfig  |  11 +++
 drivers/gnss/Makefile |   3 +
 drivers/gnss/usb.c    | 209 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 223 insertions(+)
 create mode 100644 drivers/gnss/usb.c
drivers/gnss/Kconfig +11 -0
index bd12e3d57baa..d7fe265c2869 100644
@@ -54,4 +54,15 @@ config GNSS_UBX_SERIAL
 
 	  If unsure, say N.
 
+config GNSS_USB
+	tristate "USB GNSS receiver support"
+	depends on USB
+	help
+	  Say Y here if you have a GNSS receiver which uses a USB interface.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called gnss-usb.
+
+	  If unsure, say N.
+
 endif # GNSS
drivers/gnss/Makefile +3 -0
index 451f11401ecc..bb2cbada3435 100644
@@ -17,3 +17,6 @@ gnss-sirf-y := sirf.o
 
 obj-$(CONFIG_GNSS_UBX_SERIAL)		+= gnss-ubx.o
 gnss-ubx-y := ubx.o
+
+obj-$(CONFIG_GNSS_USB)			+= gnss-usb.o
+gnss-usb-y := usb.o
drivers/gnss/usb.c new file +209 -0

209 lines not on this page · raw message

Signature · 1 line
2.32.0
#2 lore raw
Quoted 23 lines · Johan Hovold
drivers/gnss/usb.c new file +23 -0
+static int gnss_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_endpoint_descriptor *in, *out;
+	struct gnss_device *gdev;
+	struct gnss_usb *gusb;
+	struct urb *urb;
+	size_t buf_len;
+	void *buf;
+	int ret;
+
+	ret = usb_find_common_endpoints(intf->cur_altsetting, &in, &out, NULL,
+			NULL);
+	if (ret)
+		return ret;
+
+	gusb = kzalloc(sizeof(*gusb), GFP_KERNEL);
+	if (!gusb)
+		return -ENOMEM;
+
+	gdev = gnss_allocate_device(&intf->dev);
+	if (!gdev) {
+		ret = -ENOMEM;

drivers/gnss/usb.c line 149

Quoted 10 lines
drivers/gnss/usb.c new file +10 -0
+		goto err_free_gusb;
+	}
+
+	gdev->ops = &gnss_usb_gnss_ops;
+	gdev->type = GNSS_TYPE_NMEA;
+	gnss_set_drvdata(gdev, gusb);
+
+	urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!urb)
+			goto err_put_gdev;

The value of 'ret' here is the result of usb_find_common_endpoints(), hence 0 due to the prior test.

Quoted 25 lines
drivers/gnss/usb.c new file +25 -0
+
+	buf_len = max(usb_endpoint_maxp(in), GNSS_USB_READ_BUF_LEN);
+
+	buf = kzalloc(buf_len, GFP_KERNEL);
+	if (!buf)
+		goto err_free_urb;
+
+	usb_fill_bulk_urb(urb, udev,
+			usb_rcvbulkpipe(udev, usb_endpoint_num(in)),
+			buf, buf_len, gnss_usb_rx_complete, gusb);
+
+	gusb->intf = intf;
+	gusb->udev = udev;
+	gusb->gdev = gdev;
+	gusb->read_urb = urb;
+	gusb->write_pipe = usb_sndbulkpipe(udev, usb_endpoint_num(out));
+
+	ret = gnss_register_device(gdev);
+	if (ret)
+		goto err_free_buf;
+
+	usb_set_intfdata(intf, gusb);
+
+	return 0;
+

drivers/gnss/usb.c line 184

Quoted 10 lines
drivers/gnss/usb.c new file +10 -0
+err_free_buf:
+	kfree(buf);
+err_free_urb:
+	usb_free_urb(urb);
+err_put_gdev:
+	gnss_put_device(gdev);
+err_free_gusb:
+	kfree(gusb);
+
+	return ret;

Yet you return it in the error case and subsequent error cases..

    HTH
        Oliver

author maintainer
#3 lore raw
Quoted 11 lines · Oliver Neukum

drivers/gnss/usb.c line 149

Quoted 5 lines · Johan Hovold
drivers/gnss/usb.c new file +4 -0
+static int gnss_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
+	urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!urb)
+			goto err_put_gdev;

The value of 'ret' here is the result of usb_find_common_endpoints(), hence 0 due to the prior test.

Quoted 11 lines

drivers/gnss/usb.c line 184

Quoted 10 lines
drivers/gnss/usb.c new file +10 -0
+err_free_buf:
+	kfree(buf);
+err_free_urb:
+	usb_free_urb(urb);
+err_put_gdev:
+	gnss_put_device(gdev);
+err_free_gusb:
+	kfree(gusb);
+
+	return ret;

Yet you return it in the error case and subsequent error cases..

Thanks for spotting that! I'll fix it up before applying.

Johan

author maintainer
#4 lore raw

PATCH 2/2 gnss: usb: add support for Sierra Wireless XM1210

In reply to Johan Hovold

Add support for the USB interface of the Sierra Wireless XM1210 receiver.

Note that the device only supports NMEA.

Bus 002 Device 003: ID 1199:b000 Sierra Wireless, Inc. Sierra Wireless_GNSS Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.00

  bDeviceClass            0
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x1199 Sierra Wireless, Inc.
  idProduct          0xb000
  bcdDevice            0.01
  iManufacturer           1 Sierra-wireless
  iProduct                2 Sierra Wireless_GNSS
  iSerial                 0
  bNumConfigurations      1

Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0020
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 50mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 0
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 255
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 255
can't get debug descriptor: Resource temporarily unavailable
Device Status: 0x0001
Self Powered

---
 drivers/gnss/usb.c | 1 +
 1 file changed, 1 insertion(+)
drivers/gnss/usb.c +1 -0
index 5c0251034def..792235a688ea 100644
@@ -17,6 +17,7 @@
 #define GNSS_USB_WRITE_TIMEOUT	1000
 
 static const struct usb_device_id gnss_usb_id_table[] = {
+	{ USB_DEVICE(0x1199, 0xb000) },		/* Sierra Wireless XM1210 */
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, gnss_usb_id_table);
Signature · 1 line
2.32.0
Tested-by on v1 2/2
#5 lore raw

Re: [PATCH 2/2] gnss: usb: add support for Sierra Wireless XM1210

Quoted 86 lines · Johan Hovold

Add support for the USB interface of the Sierra Wireless XM1210 receiver.

Note that the device only supports NMEA.

Bus 002 Device 003: ID 1199:b000 Sierra Wireless, Inc. Sierra Wireless_GNSS Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.00

  bDeviceClass            0
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x1199 Sierra Wireless, Inc.
  idProduct          0xb000
  bcdDevice            0.01
  iManufacturer           1 Sierra-wireless
  iProduct                2 Sierra Wireless_GNSS
  iSerial                 0
  bNumConfigurations      1

Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0020
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 50mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 0
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 255
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 255
can't get debug descriptor: Resource temporarily unavailable
Device Status: 0x0001
Self Powered

---
 drivers/gnss/usb.c | 1 +
 1 file changed, 1 insertion(+)
drivers/gnss/usb.c +1 -1
index 5c0251034def..792235a688ea 100644
@@ -17,6 +17,7 @@
 #define GNSS_USB_WRITE_TIMEOUT 1000
 
 static const struct usb_device_id gnss_usb_id_table[] = {
+       { USB_DEVICE(0x1199, 0xb000) },         /* Sierra Wireless XM1210 */
        { }
 };
 MODULE_DEVICE_TABLE(usb, gnss_usb_id_table);
--
Quoted 2 lines

2.32.0

Thank you Johan! Much appreciated!

With your patches applied on my platform (featuring the XM1210) , I get:

# lsmod | grep gnss
gnss_usb 16384 0 - Live 0xffffffffc011b000
gnss 16384 3 gnss_usb, Live 0xffffffffc0082000
# dmesg | grep gnss
gnss: GNSS driver registered with major 244
usbcore: registered new interface driver gnss-usb
# ls -l /dev/gnss0
crw-rw----    1 root     root      244,   0 Apr  8 08:39 /dev/gnss0

I also tested with gpsd and everything is working as expected, hence:

Marc

author maintainer
#6 lore raw

Re: [PATCH 2/2] gnss: usb: add support for Sierra Wireless XM1210

Quoted 41 lines · Marc Ferland
Quoted 26 lines · Johan Hovold

Add support for the USB interface of the Sierra Wireless XM1210 receiver.

Note that the device only supports NMEA.

---
 drivers/gnss/usb.c | 1 +
 1 file changed, 1 insertion(+)
drivers/gnss/usb.c +1 -1
index 5c0251034def..792235a688ea 100644
@@ -17,6 +17,7 @@
 #define GNSS_USB_WRITE_TIMEOUT 1000
 
 static const struct usb_device_id gnss_usb_id_table[] = {
+       { USB_DEVICE(0x1199, 0xb000) },         /* Sierra Wireless XM1210 */
        { }
 };
 MODULE_DEVICE_TABLE(usb, gnss_usb_id_table);
--
Quoted 2 lines

2.32.0

Thank you Johan! Much appreciated!

With your patches applied on my platform (featuring the XM1210) , I get:

# lsmod | grep gnss
gnss_usb 16384 0 - Live 0xffffffffc011b000
gnss 16384 3 gnss_usb, Live 0xffffffffc0082000
# dmesg | grep gnss
gnss: GNSS driver registered with major 244
usbcore: registered new interface driver gnss-usb
Quoted 6 lines
# ls -l /dev/gnss0
crw-rw----    1 root     root      244,   0 Apr  8 08:39 /dev/gnss0

I also tested with gpsd and everything is working as expected, hence:

Thanks for testing, Marc!

I've applied this series now after adding your Tested-by tag to both patches.

Johan

maintainer Reviewed-by on the v1 series
#7 lore raw
In reply to Johan Hovold
Quoted 10 lines · Johan Hovold

This series adds a generic driver for GNSS receivers with a USB interface and a first device id for the Sierra Wireless XM1210 receiver.

Johan

Johan Hovold (2):
gnss: add USB support
gnss: usb: add support for Sierra Wireless XM1210

Quoted 9 lines
 drivers/gnss/Kconfig  |  11 +++
 drivers/gnss/Makefile |   3 +
 drivers/gnss/usb.c    | 210 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 224 insertions(+)
 create mode 100644 drivers/gnss/usb.c
Signature · 1 line
2.32.0
author maintainer
#8 lore raw
Quoted 5 lines · Greg Kroah-Hartman
Quoted 2 lines · Johan Hovold

This series adds a generic driver for GNSS receivers with a USB interface and a first device id for the Sierra Wireless XM1210 receiver.

Thanks for reviewing.

Johan