Commit 0eee6a2b2a52e17066a572d30ad2805d3ebc7508
Committed by
Greg Kroah-Hartman
1 parent
ebb8a4e487
Exists in
master
and in
7 other branches
USB: add device IDs for igotu to navman
I recently bought a i-gotU USB GPS, and whilst hunting around for linux support discovered this post by you back in 2009: http://kerneltrap.org/mailarchive/linux-usb/2009/3/12/5148644 >Try the navman driver instead. You can either add the device id to the > driver and rebuild it, or do this before you plug the device in: > modprobe navman > echo -n "0x0df7 0x0900" > /sys/bus/usb-serial/drivers/navman/new_id > > and then plug your device in and see if that works. I can confirm that the navman driver works with the right device IDs on my i-gotU GT-600, which has the same device IDs. Attached is a patch adding the IDs. From: Ross Burton <ross@linux.intel.com> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Showing 1 changed file with 1 additions and 0 deletions Inline Diff
drivers/usb/serial/navman.c
1 | /* | 1 | /* |
2 | * Navman Serial USB driver | 2 | * Navman Serial USB driver |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Greg Kroah-Hartman <gregkh@suse.de> | 4 | * Copyright (C) 2006 Greg Kroah-Hartman <gregkh@suse.de> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
8 | * version 2 as published by the Free Software Foundation. | 8 | * version 2 as published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * TODO: | 10 | * TODO: |
11 | * Add termios method that uses copy_hw but also kills all echo | 11 | * Add termios method that uses copy_hw but also kills all echo |
12 | * flags as the navman is rx only so cannot echo. | 12 | * flags as the navman is rx only so cannot echo. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/gfp.h> | 15 | #include <linux/gfp.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/tty_flip.h> | 19 | #include <linux/tty_flip.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
22 | #include <linux/usb/serial.h> | 22 | #include <linux/usb/serial.h> |
23 | 23 | ||
24 | static int debug; | 24 | static int debug; |
25 | 25 | ||
26 | static const struct usb_device_id id_table[] = { | 26 | static const struct usb_device_id id_table[] = { |
27 | { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ | 27 | { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ |
28 | { USB_DEVICE(0x0df7, 0x0900) }, /* Mobile Action i-gotU */ | ||
28 | { }, | 29 | { }, |
29 | }; | 30 | }; |
30 | MODULE_DEVICE_TABLE(usb, id_table); | 31 | MODULE_DEVICE_TABLE(usb, id_table); |
31 | 32 | ||
32 | static struct usb_driver navman_driver = { | 33 | static struct usb_driver navman_driver = { |
33 | .name = "navman", | 34 | .name = "navman", |
34 | .probe = usb_serial_probe, | 35 | .probe = usb_serial_probe, |
35 | .disconnect = usb_serial_disconnect, | 36 | .disconnect = usb_serial_disconnect, |
36 | .id_table = id_table, | 37 | .id_table = id_table, |
37 | .no_dynamic_id = 1, | 38 | .no_dynamic_id = 1, |
38 | }; | 39 | }; |
39 | 40 | ||
40 | static void navman_read_int_callback(struct urb *urb) | 41 | static void navman_read_int_callback(struct urb *urb) |
41 | { | 42 | { |
42 | struct usb_serial_port *port = urb->context; | 43 | struct usb_serial_port *port = urb->context; |
43 | unsigned char *data = urb->transfer_buffer; | 44 | unsigned char *data = urb->transfer_buffer; |
44 | struct tty_struct *tty; | 45 | struct tty_struct *tty; |
45 | int status = urb->status; | 46 | int status = urb->status; |
46 | int result; | 47 | int result; |
47 | 48 | ||
48 | switch (status) { | 49 | switch (status) { |
49 | case 0: | 50 | case 0: |
50 | /* success */ | 51 | /* success */ |
51 | break; | 52 | break; |
52 | case -ECONNRESET: | 53 | case -ECONNRESET: |
53 | case -ENOENT: | 54 | case -ENOENT: |
54 | case -ESHUTDOWN: | 55 | case -ESHUTDOWN: |
55 | /* this urb is terminated, clean up */ | 56 | /* this urb is terminated, clean up */ |
56 | dbg("%s - urb shutting down with status: %d", | 57 | dbg("%s - urb shutting down with status: %d", |
57 | __func__, status); | 58 | __func__, status); |
58 | return; | 59 | return; |
59 | default: | 60 | default: |
60 | dbg("%s - nonzero urb status received: %d", | 61 | dbg("%s - nonzero urb status received: %d", |
61 | __func__, status); | 62 | __func__, status); |
62 | goto exit; | 63 | goto exit; |
63 | } | 64 | } |
64 | 65 | ||
65 | usb_serial_debug_data(debug, &port->dev, __func__, | 66 | usb_serial_debug_data(debug, &port->dev, __func__, |
66 | urb->actual_length, data); | 67 | urb->actual_length, data); |
67 | 68 | ||
68 | tty = tty_port_tty_get(&port->port); | 69 | tty = tty_port_tty_get(&port->port); |
69 | if (tty && urb->actual_length) { | 70 | if (tty && urb->actual_length) { |
70 | tty_insert_flip_string(tty, data, urb->actual_length); | 71 | tty_insert_flip_string(tty, data, urb->actual_length); |
71 | tty_flip_buffer_push(tty); | 72 | tty_flip_buffer_push(tty); |
72 | } | 73 | } |
73 | tty_kref_put(tty); | 74 | tty_kref_put(tty); |
74 | 75 | ||
75 | exit: | 76 | exit: |
76 | result = usb_submit_urb(urb, GFP_ATOMIC); | 77 | result = usb_submit_urb(urb, GFP_ATOMIC); |
77 | if (result) | 78 | if (result) |
78 | dev_err(&urb->dev->dev, | 79 | dev_err(&urb->dev->dev, |
79 | "%s - Error %d submitting interrupt urb\n", | 80 | "%s - Error %d submitting interrupt urb\n", |
80 | __func__, result); | 81 | __func__, result); |
81 | } | 82 | } |
82 | 83 | ||
83 | static int navman_open(struct tty_struct *tty, struct usb_serial_port *port) | 84 | static int navman_open(struct tty_struct *tty, struct usb_serial_port *port) |
84 | { | 85 | { |
85 | int result = 0; | 86 | int result = 0; |
86 | 87 | ||
87 | dbg("%s - port %d", __func__, port->number); | 88 | dbg("%s - port %d", __func__, port->number); |
88 | 89 | ||
89 | if (port->interrupt_in_urb) { | 90 | if (port->interrupt_in_urb) { |
90 | dbg("%s - adding interrupt input for treo", __func__); | 91 | dbg("%s - adding interrupt input for treo", __func__); |
91 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | 92 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
92 | if (result) | 93 | if (result) |
93 | dev_err(&port->dev, | 94 | dev_err(&port->dev, |
94 | "%s - failed submitting interrupt urb, error %d\n", | 95 | "%s - failed submitting interrupt urb, error %d\n", |
95 | __func__, result); | 96 | __func__, result); |
96 | } | 97 | } |
97 | return result; | 98 | return result; |
98 | } | 99 | } |
99 | 100 | ||
100 | static void navman_close(struct usb_serial_port *port) | 101 | static void navman_close(struct usb_serial_port *port) |
101 | { | 102 | { |
102 | dbg("%s - port %d", __func__, port->number); | 103 | dbg("%s - port %d", __func__, port->number); |
103 | 104 | ||
104 | usb_kill_urb(port->interrupt_in_urb); | 105 | usb_kill_urb(port->interrupt_in_urb); |
105 | } | 106 | } |
106 | 107 | ||
107 | static int navman_write(struct tty_struct *tty, struct usb_serial_port *port, | 108 | static int navman_write(struct tty_struct *tty, struct usb_serial_port *port, |
108 | const unsigned char *buf, int count) | 109 | const unsigned char *buf, int count) |
109 | { | 110 | { |
110 | dbg("%s - port %d", __func__, port->number); | 111 | dbg("%s - port %d", __func__, port->number); |
111 | 112 | ||
112 | /* | 113 | /* |
113 | * This device can't write any data, only read from the device | 114 | * This device can't write any data, only read from the device |
114 | */ | 115 | */ |
115 | return -EOPNOTSUPP; | 116 | return -EOPNOTSUPP; |
116 | } | 117 | } |
117 | 118 | ||
118 | static struct usb_serial_driver navman_device = { | 119 | static struct usb_serial_driver navman_device = { |
119 | .driver = { | 120 | .driver = { |
120 | .owner = THIS_MODULE, | 121 | .owner = THIS_MODULE, |
121 | .name = "navman", | 122 | .name = "navman", |
122 | }, | 123 | }, |
123 | .id_table = id_table, | 124 | .id_table = id_table, |
124 | .usb_driver = &navman_driver, | 125 | .usb_driver = &navman_driver, |
125 | .num_ports = 1, | 126 | .num_ports = 1, |
126 | .open = navman_open, | 127 | .open = navman_open, |
127 | .close = navman_close, | 128 | .close = navman_close, |
128 | .write = navman_write, | 129 | .write = navman_write, |
129 | .read_int_callback = navman_read_int_callback, | 130 | .read_int_callback = navman_read_int_callback, |
130 | }; | 131 | }; |
131 | 132 | ||
132 | static int __init navman_init(void) | 133 | static int __init navman_init(void) |
133 | { | 134 | { |
134 | int retval; | 135 | int retval; |
135 | 136 | ||
136 | retval = usb_serial_register(&navman_device); | 137 | retval = usb_serial_register(&navman_device); |
137 | if (retval) | 138 | if (retval) |
138 | return retval; | 139 | return retval; |
139 | retval = usb_register(&navman_driver); | 140 | retval = usb_register(&navman_driver); |
140 | if (retval) | 141 | if (retval) |
141 | usb_serial_deregister(&navman_device); | 142 | usb_serial_deregister(&navman_device); |
142 | return retval; | 143 | return retval; |
143 | } | 144 | } |
144 | 145 | ||
145 | static void __exit navman_exit(void) | 146 | static void __exit navman_exit(void) |
146 | { | 147 | { |
147 | usb_deregister(&navman_driver); | 148 | usb_deregister(&navman_driver); |
148 | usb_serial_deregister(&navman_device); | 149 | usb_serial_deregister(&navman_device); |
149 | } | 150 | } |
150 | 151 | ||
151 | module_init(navman_init); | 152 | module_init(navman_init); |
152 | module_exit(navman_exit); | 153 | module_exit(navman_exit); |
153 | MODULE_LICENSE("GPL"); | 154 | MODULE_LICENSE("GPL"); |
154 | 155 | ||
155 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 156 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
156 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | 157 | MODULE_PARM_DESC(debug, "Debug enabled or not"); |
157 | 158 |