projects/linux·blob master · refs

573 lines · 17.3 KiB

1// SPDX-License-Identifier: GPL-2.0
2/*
3 * USB HandSpring Visor, Palm m50x, and Sony Clie driver
4 * (supports all of the Palm OS USB devices)
5 *
6 * Copyright (C) 1999 - 2004
7 * Greg Kroah-Hartman ([email protected])
8 *
9 * See Documentation/usb/usb-serial.rst for more information on using this
10 * driver
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/errno.h>
16#include <linux/slab.h>
17#include <linux/tty.h>
18#include <linux/module.h>
19#include <linux/spinlock.h>
20#include <linux/usb.h>
21#include <linux/usb/serial.h>
22#include <linux/usb/cdc.h>
23#include "visor.h"
24
25/*
26 * Version Information
27 */
28#define DRIVER_AUTHOR "Greg Kroah-Hartman <[email protected]>"
29#define DRIVER_DESC "USB HandSpring Visor / Palm OS driver"
30
31/* function prototypes for a handspring visor */
32static int visor_open(struct tty_struct *tty, struct usb_serial_port *port);
33static void visor_close(struct usb_serial_port *port);
34static int visor_probe(struct usb_serial *serial,
35 const struct usb_device_id *id);
36static int visor_calc_num_ports(struct usb_serial *serial,
37 struct usb_serial_endpoints *epds);
38static int clie_5_calc_num_ports(struct usb_serial *serial,
39 struct usb_serial_endpoints *epds);
40static void visor_read_int_callback(struct urb *urb);
41static int clie_3_5_startup(struct usb_serial *serial);
42static int palm_os_3_probe(struct usb_serial *serial,
43 const struct usb_device_id *id);
44static int palm_os_4_probe(struct usb_serial *serial,
45 const struct usb_device_id *id);
46
47static const struct usb_device_id id_table[] = {
48 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID),
49 .driver_info = (kernel_ulong_t)&palm_os_3_probe },
50 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID),
51 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
52 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID),
53 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
54 { USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID),
55 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
56 { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID),
57 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
58 { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID),
59 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
60 { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID),
61 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
62 { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID),
63 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
64 { USB_DEVICE(PALM_VENDOR_ID, PALM_M100_ID),
65 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
66 { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID),
67 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
68 { USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID),
69 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
70 { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID),
71 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
72 { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650),
73 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
74 { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID),
75 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
76 { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID),
77 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
78 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID),
79 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
80 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID),
81 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
82 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID),
83 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
84 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID),
85 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
86 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID),
87 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
88 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID),
89 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
90 { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID),
91 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
92 { USB_DEVICE_INTERFACE_CLASS(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID, 0xff),
93 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
94 { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID),
95 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
96 { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID),
97 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
98 { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID),
99 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
100 { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID),
101 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
102 { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID),
103 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
104 { USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID),
105 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
106 { } /* Terminating entry */
107};
108
109static const struct usb_device_id clie_id_5_table[] = {
110 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID),
111 .driver_info = (kernel_ulong_t)&palm_os_4_probe },
112 { } /* Terminating entry */
113};
114
115static const struct usb_device_id clie_id_3_5_table[] = {
116 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
117 { } /* Terminating entry */
118};
119
120static const struct usb_device_id id_table_combined[] = {
121 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
122 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) },
123 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID) },
124 { USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID) },
125 { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
126 { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
127 { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) },
128 { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },
129 { USB_DEVICE(PALM_VENDOR_ID, PALM_M100_ID) },
130 { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
131 { USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) },
132 { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) },
133 { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) },
134 { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) },
135 { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) },
136 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
137 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
138 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) },
139 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) },
140 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) },
141 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) },
142 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID) },
143 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID) },
144 { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) },
145 { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID) },
146 { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID) },
147 { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) },
148 { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) },
149 { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) },
150 { USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID) },
151 { } /* Terminating entry */
152};
153
154MODULE_DEVICE_TABLE(usb, id_table_combined);
155
156/* All of the device info needed for the Handspring Visor,
157 and Palm 4.0 devices */
158static struct usb_serial_driver handspring_device = {
159 .driver = {
160 .name = "visor",
161 },
162 .description = "Handspring Visor / Palm OS",
163 .id_table = id_table,
164 .num_ports = 2,
165 .bulk_out_size = 256,
166 .open = visor_open,
167 .close = visor_close,
168 .throttle = usb_serial_generic_throttle,
169 .unthrottle = usb_serial_generic_unthrottle,
170 .probe = visor_probe,
171 .calc_num_ports = visor_calc_num_ports,
172 .read_int_callback = visor_read_int_callback,
173};
174
175/* All of the device info needed for the Clie UX50, TH55 Palm 5.0 devices */
176static struct usb_serial_driver clie_5_device = {
177 .driver = {
178 .name = "clie_5",
179 },
180 .description = "Sony Clie 5.0",
181 .id_table = clie_id_5_table,
182 .num_ports = 2,
183 .num_bulk_out = 2,
184 .bulk_out_size = 256,
185 .open = visor_open,
186 .close = visor_close,
187 .throttle = usb_serial_generic_throttle,
188 .unthrottle = usb_serial_generic_unthrottle,
189 .probe = visor_probe,
190 .calc_num_ports = clie_5_calc_num_ports,
191 .read_int_callback = visor_read_int_callback,
192};
193
194/* device info for the Sony Clie OS version 3.5 */
195static struct usb_serial_driver clie_3_5_device = {
196 .driver = {
197 .name = "clie_3.5",
198 },
199 .description = "Sony Clie 3.5",
200 .id_table = clie_id_3_5_table,
201 .num_ports = 1,
202 .bulk_out_size = 256,
203 .open = visor_open,
204 .close = visor_close,
205 .throttle = usb_serial_generic_throttle,
206 .unthrottle = usb_serial_generic_unthrottle,
207 .attach = clie_3_5_startup,
208};
209
210static struct usb_serial_driver * const serial_drivers[] = {
211 &handspring_device, &clie_5_device, &clie_3_5_device, NULL
212};
213
214/******************************************************************************
215 * Handspring Visor specific driver functions
216 ******************************************************************************/
217static int visor_open(struct tty_struct *tty, struct usb_serial_port *port)
218{
219 int result = 0;
220
221 if (!port->read_urb) {
222 /* this is needed for some brain dead Sony devices */
223 dev_err(&port->dev, "Device lied about number of ports, please use a lower one.\n");
224 return -ENODEV;
225 }
226
227 /* Start reading from the device */
228 result = usb_serial_generic_open(tty, port);
229 if (result)
230 goto exit;
231
232 if (port->interrupt_in_urb) {
233 dev_dbg(&port->dev, "adding interrupt input for treo\n");
234 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
235 if (result)
236 dev_err(&port->dev,
237 "%s - failed submitting interrupt urb, error %d\n",
238 __func__, result);
239 }
240exit:
241 return result;
242}
243
244
245static void visor_close(struct usb_serial_port *port)
246{
247 unsigned char *transfer_buffer;
248
249 usb_serial_generic_close(port);
250 usb_kill_urb(port->interrupt_in_urb);
251
252 transfer_buffer = kmalloc(0x12, GFP_KERNEL);
253 if (!transfer_buffer)
254 return;
255 usb_control_msg(port->serial->dev,
256 usb_rcvctrlpipe(port->serial->dev, 0),
257 VISOR_CLOSE_NOTIFICATION, 0xc2,
258 0x0000, 0x0000,
259 transfer_buffer, 0x12, 300);
260 kfree(transfer_buffer);
261}
262
263static void visor_read_int_callback(struct urb *urb)
264{
265 struct usb_serial_port *port = urb->context;
266 int status = urb->status;
267 int result;
268
269 switch (status) {
270 case 0:
271 /* success */
272 break;
273 case -ECONNRESET:
274 case -ENOENT:
275 case -ESHUTDOWN:
276 /* this urb is terminated, clean up */
277 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
278 __func__, status);
279 return;
280 default:
281 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
282 __func__, status);
283 goto exit;
284 }
285
286 /*
287 * This information is still unknown what it can be used for.
288 * If anyone has an idea, please let the author know...
289 *
290 * Rumor has it this endpoint is used to notify when data
291 * is ready to be read from the bulk ones.
292 */
293 usb_serial_debug_data(&port->dev, __func__, urb->actual_length,
294 urb->transfer_buffer);
295
296exit:
297 result = usb_submit_urb(urb, GFP_ATOMIC);
298 if (result)
299 dev_err(&urb->dev->dev,
300 "%s - Error %d submitting interrupt urb\n",
301 __func__, result);
302}
303
304static int palm_os_3_probe(struct usb_serial *serial,
305 const struct usb_device_id *id)
306{
307 struct device *dev = &serial->dev->dev;
308 struct visor_connection_info *connection_info;
309 unsigned char *transfer_buffer;
310 char *string;
311 int retval = 0;
312 int i;
313 int num_ports = 0;
314
315 transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL);
316 if (!transfer_buffer)
317 return -ENOMEM;
318
319 /* send a get connection info request */
320 retval = usb_control_msg(serial->dev,
321 usb_rcvctrlpipe(serial->dev, 0),
322 VISOR_GET_CONNECTION_INFORMATION,
323 0xc2, 0x0000, 0x0000, transfer_buffer,
324 sizeof(*connection_info), 300);
325 if (retval < 0) {
326 dev_err(dev, "%s - error %d getting connection information\n",
327 __func__, retval);
328 goto exit;
329 }
330
331 if (retval != sizeof(*connection_info)) {
332 dev_err(dev, "Invalid connection information received from device\n");
333 retval = -ENODEV;
334 goto exit;
335 }
336
337 connection_info = (struct visor_connection_info *)transfer_buffer;
338
339 num_ports = le16_to_cpu(connection_info->num_ports);
340
341 /* Handle devices that report invalid stuff here. */
342 if (num_ports == 0 || num_ports > 2) {
343 dev_warn(dev, "%s: No valid connect info available\n",
344 serial->type->description);
345 num_ports = 2;
346 }
347
348 for (i = 0; i < num_ports; ++i) {
349 switch (connection_info->connections[i].port_function_id) {
350 case VISOR_FUNCTION_GENERIC:
351 string = "Generic";
352 break;
353 case VISOR_FUNCTION_DEBUGGER:
354 string = "Debugger";
355 break;
356 case VISOR_FUNCTION_HOTSYNC:
357 string = "HotSync";
358 break;
359 case VISOR_FUNCTION_CONSOLE:
360 string = "Console";
361 break;
362 case VISOR_FUNCTION_REMOTE_FILE_SYS:
363 string = "Remote File System";
364 break;
365 default:
366 string = "unknown";
367 break;
368 }
369 dev_info(dev, "%s: port %d, is for %s use\n",
370 serial->type->description,
371 connection_info->connections[i].port, string);
372 }
373 dev_info(dev, "%s: Number of ports: %d\n", serial->type->description,
374 num_ports);
375
376 /*
377 * save off our num_ports info so that we can use it in the
378 * calc_num_ports callback
379 */
380 usb_set_serial_data(serial, (void *)(long)num_ports);
381
382 /* ask for the number of bytes available, but ignore the
383 response as it is broken */
384 retval = usb_control_msg(serial->dev,
385 usb_rcvctrlpipe(serial->dev, 0),
386 VISOR_REQUEST_BYTES_AVAILABLE,
387 0xc2, 0x0000, 0x0005, transfer_buffer,
388 0x02, 300);
389 if (retval < 0)
390 dev_err(dev, "%s - error %d getting bytes available request\n",
391 __func__, retval);
392 retval = 0;
393
394exit:
395 kfree(transfer_buffer);
396
397 return retval;
398}
399
400static int palm_os_4_probe(struct usb_serial *serial,
401 const struct usb_device_id *id)
402{
403 struct device *dev = &serial->dev->dev;
404 struct palm_ext_connection_info *connection_info;
405 unsigned char *transfer_buffer;
406 int retval;
407
408 transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL);
409 if (!transfer_buffer)
410 return -ENOMEM;
411
412 retval = usb_control_msg(serial->dev,
413 usb_rcvctrlpipe(serial->dev, 0),
414 PALM_GET_EXT_CONNECTION_INFORMATION,
415 0xc2, 0x0000, 0x0000, transfer_buffer,
416 sizeof(*connection_info), 300);
417 if (retval < 0)
418 dev_err(dev, "%s - error %d getting connection info\n",
419 __func__, retval);
420 else
421 usb_serial_debug_data(dev, __func__, retval, transfer_buffer);
422
423 kfree(transfer_buffer);
424 return 0;
425}
426
427
428static int visor_probe(struct usb_serial *serial,
429 const struct usb_device_id *id)
430{
431 int retval = 0;
432 int (*startup)(struct usb_serial *serial,
433 const struct usb_device_id *id);
434
435 /*
436 * some Samsung Android phones in modem mode have the same ID
437 * as SPH-I500, but they are ACM devices, so dont bind to them
438 */
439 if (id->idVendor == SAMSUNG_VENDOR_ID &&
440 id->idProduct == SAMSUNG_SPH_I500_ID &&
441 serial->dev->descriptor.bDeviceClass == USB_CLASS_COMM &&
442 serial->dev->descriptor.bDeviceSubClass ==
443 USB_CDC_SUBCLASS_ACM)
444 return -ENODEV;
445
446 if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
447 dev_err(&serial->dev->dev, "active config #%d != 1 ??\n",
448 serial->dev->actconfig->desc.bConfigurationValue);
449 return -ENODEV;
450 }
451
452 if (id->driver_info) {
453 startup = (void *)id->driver_info;
454 retval = startup(serial, id);
455 }
456
457 return retval;
458}
459
460static int visor_calc_num_ports(struct usb_serial *serial,
461 struct usb_serial_endpoints *epds)
462{
463 unsigned int vid = le16_to_cpu(serial->dev->descriptor.idVendor);
464 int num_ports = (int)(long)(usb_get_serial_data(serial));
465
466 if (num_ports)
467 usb_set_serial_data(serial, NULL);
468
469 /*
470 * Only swap the bulk endpoints for the Handspring devices with
471 * interrupt in endpoints, which for now are the Treo devices.
472 */
473 if (!(vid == HANDSPRING_VENDOR_ID || vid == KYOCERA_VENDOR_ID) ||
474 epds->num_interrupt_in == 0)
475 goto out;
476
477 if (epds->num_bulk_in < 2 || epds->num_interrupt_in < 2) {
478 dev_err(&serial->interface->dev, "missing endpoints\n");
479 return -ENODEV;
480 }
481
482 /*
483 * It appears that Treos and Kyoceras want to use the
484 * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
485 * so let's swap the 1st and 2nd bulk in and interrupt endpoints.
486 * Note that swapping the bulk out endpoints would break lots of
487 * apps that want to communicate on the second port.
488 */
489 swap(epds->bulk_in[0], epds->bulk_in[1]);
490 swap(epds->interrupt_in[0], epds->interrupt_in[1]);
491out:
492 return num_ports;
493}
494
495static int clie_5_calc_num_ports(struct usb_serial *serial,
496 struct usb_serial_endpoints *epds)
497{
498 /*
499 * TH55 registers 2 ports.
500 * Communication in from the UX50/TH55 uses the first bulk-in
501 * endpoint, while communication out to the UX50/TH55 uses the second
502 * bulk-out endpoint.
503 */
504
505 /*
506 * FIXME: Should we swap the descriptors instead of using the same
507 * bulk-out endpoint for both ports?
508 */
509 epds->bulk_out[0] = epds->bulk_out[1];
510
511 return serial->type->num_ports;
512}
513
514static int clie_3_5_startup(struct usb_serial *serial)
515{
516 struct device *dev = &serial->dev->dev;
517 int result;
518 u8 *data;
519
520 data = kmalloc(1, GFP_KERNEL);
521 if (!data)
522 return -ENOMEM;
523
524 /*
525 * Note that PEG-300 series devices expect the following two calls.
526 */
527
528 /* get the config number */
529 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
530 USB_REQ_GET_CONFIGURATION, USB_DIR_IN,
531 0, 0, data, 1, 3000);
532 if (result < 0) {
533 dev_err(dev, "%s: get config number failed: %d\n",
534 __func__, result);
535 goto out;
536 }
537 if (result != 1) {
538 dev_err(dev, "%s: get config number bad return length: %d\n",
539 __func__, result);
540 result = -EIO;
541 goto out;
542 }
543
544 /* get the interface number */
545 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
546 USB_REQ_GET_INTERFACE,
547 USB_DIR_IN | USB_RECIP_INTERFACE,
548 0, 0, data, 1, 3000);
549 if (result < 0) {
550 dev_err(dev, "%s: get interface number failed: %d\n",
551 __func__, result);
552 goto out;
553 }
554 if (result != 1) {
555 dev_err(dev,
556 "%s: get interface number bad return length: %d\n",
557 __func__, result);
558 result = -EIO;
559 goto out;
560 }
561
562 result = 0;
563out:
564 kfree(data);
565
566 return result;
567}
568
569module_usb_serial_driver(serial_drivers, id_table_combined);
570
571MODULE_AUTHOR(DRIVER_AUTHOR);
572MODULE_DESCRIPTION(DRIVER_DESC);
573MODULE_LICENSE("GPL v2");