xref: /openbmc/linux/drivers/usb/serial/navman.c (revision 627cfa89)
15fd54aceSGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2e9a66c64SGreg Kroah-Hartman /*
3e9a66c64SGreg Kroah-Hartman  * Navman Serial USB driver
4e9a66c64SGreg Kroah-Hartman  *
5e9a66c64SGreg Kroah-Hartman  * Copyright (C) 2006 Greg Kroah-Hartman <gregkh@suse.de>
6e9a66c64SGreg Kroah-Hartman  *
7a5b6f60cSAlan Cox  * TODO:
8a5b6f60cSAlan Cox  *	Add termios method that uses copy_hw but also kills all echo
9a5b6f60cSAlan Cox  *	flags as the navman is rx only so cannot echo.
10e9a66c64SGreg Kroah-Hartman  */
11e9a66c64SGreg Kroah-Hartman 
125a0e3ad6STejun Heo #include <linux/gfp.h>
13e9a66c64SGreg Kroah-Hartman #include <linux/kernel.h>
14e9a66c64SGreg Kroah-Hartman #include <linux/tty.h>
15e9a66c64SGreg Kroah-Hartman #include <linux/tty_flip.h>
16e9a66c64SGreg Kroah-Hartman #include <linux/module.h>
17e9a66c64SGreg Kroah-Hartman #include <linux/usb.h>
18a969888cSGreg Kroah-Hartman #include <linux/usb/serial.h>
19e9a66c64SGreg Kroah-Hartman 
207d40d7e8SNémeth Márton static const struct usb_device_id id_table[] = {
21e9a66c64SGreg Kroah-Hartman 	{ USB_DEVICE(0x0a99, 0x0001) },	/* Talon Technology device */
220eee6a2bSRoss Burton 	{ USB_DEVICE(0x0df7, 0x0900) },	/* Mobile Action i-gotU */
23e9a66c64SGreg Kroah-Hartman 	{ },
24e9a66c64SGreg Kroah-Hartman };
25e9a66c64SGreg Kroah-Hartman MODULE_DEVICE_TABLE(usb, id_table);
26e9a66c64SGreg Kroah-Hartman 
navman_read_int_callback(struct urb * urb)277d12e780SDavid Howells static void navman_read_int_callback(struct urb *urb)
28e9a66c64SGreg Kroah-Hartman {
29e9a66c64SGreg Kroah-Hartman 	struct usb_serial_port *port = urb->context;
30e9a66c64SGreg Kroah-Hartman 	unsigned char *data = urb->transfer_buffer;
319965d612SGreg Kroah-Hartman 	int status = urb->status;
32e9a66c64SGreg Kroah-Hartman 	int result;
33e9a66c64SGreg Kroah-Hartman 
349965d612SGreg Kroah-Hartman 	switch (status) {
35e9a66c64SGreg Kroah-Hartman 	case 0:
36e9a66c64SGreg Kroah-Hartman 		/* success */
37e9a66c64SGreg Kroah-Hartman 		break;
38e9a66c64SGreg Kroah-Hartman 	case -ECONNRESET:
39e9a66c64SGreg Kroah-Hartman 	case -ENOENT:
40e9a66c64SGreg Kroah-Hartman 	case -ESHUTDOWN:
41e9a66c64SGreg Kroah-Hartman 		/* this urb is terminated, clean up */
4200c533fdSGreg Kroah-Hartman 		dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
43441b62c1SHarvey Harrison 			__func__, status);
44e9a66c64SGreg Kroah-Hartman 		return;
45e9a66c64SGreg Kroah-Hartman 	default:
4600c533fdSGreg Kroah-Hartman 		dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
47441b62c1SHarvey Harrison 			__func__, status);
48e9a66c64SGreg Kroah-Hartman 		goto exit;
49e9a66c64SGreg Kroah-Hartman 	}
50e9a66c64SGreg Kroah-Hartman 
5159d33f2fSGreg Kroah-Hartman 	usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
52e9a66c64SGreg Kroah-Hartman 
532e124b4aSJiri Slaby 	if (urb->actual_length) {
5405c7cd39SJiri Slaby 		tty_insert_flip_string(&port->port, data, urb->actual_length);
552e124b4aSJiri Slaby 		tty_flip_buffer_push(&port->port);
56e9a66c64SGreg Kroah-Hartman 	}
57e9a66c64SGreg Kroah-Hartman 
58e9a66c64SGreg Kroah-Hartman exit:
59e9a66c64SGreg Kroah-Hartman 	result = usb_submit_urb(urb, GFP_ATOMIC);
60e9a66c64SGreg Kroah-Hartman 	if (result)
61e9a66c64SGreg Kroah-Hartman 		dev_err(&urb->dev->dev,
62e9a66c64SGreg Kroah-Hartman 			"%s - Error %d submitting interrupt urb\n",
63441b62c1SHarvey Harrison 			__func__, result);
64e9a66c64SGreg Kroah-Hartman }
65e9a66c64SGreg Kroah-Hartman 
navman_open(struct tty_struct * tty,struct usb_serial_port * port)66a509a7e4SAlan Cox static int navman_open(struct tty_struct *tty, struct usb_serial_port *port)
67e9a66c64SGreg Kroah-Hartman {
68e9a66c64SGreg Kroah-Hartman 	int result = 0;
69e9a66c64SGreg Kroah-Hartman 
70e9a66c64SGreg Kroah-Hartman 	if (port->interrupt_in_urb) {
7100c533fdSGreg Kroah-Hartman 		dev_dbg(&port->dev, "%s - adding interrupt input for treo\n",
7200c533fdSGreg Kroah-Hartman 			__func__);
73e9a66c64SGreg Kroah-Hartman 		result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
74e9a66c64SGreg Kroah-Hartman 		if (result)
75e9a66c64SGreg Kroah-Hartman 			dev_err(&port->dev,
76e9a66c64SGreg Kroah-Hartman 				"%s - failed submitting interrupt urb, error %d\n",
77441b62c1SHarvey Harrison 				__func__, result);
78e9a66c64SGreg Kroah-Hartman 	}
79e9a66c64SGreg Kroah-Hartman 	return result;
80e9a66c64SGreg Kroah-Hartman }
81e9a66c64SGreg Kroah-Hartman 
navman_close(struct usb_serial_port * port)82335f8514SAlan Cox static void navman_close(struct usb_serial_port *port)
83e9a66c64SGreg Kroah-Hartman {
84e9a66c64SGreg Kroah-Hartman 	usb_kill_urb(port->interrupt_in_urb);
85e9a66c64SGreg Kroah-Hartman }
86e9a66c64SGreg Kroah-Hartman 
navman_write(struct tty_struct * tty,struct usb_serial_port * port,const unsigned char * buf,int count)8795da310eSAlan Cox static int navman_write(struct tty_struct *tty, struct usb_serial_port *port,
88e9a66c64SGreg Kroah-Hartman 			const unsigned char *buf, int count)
89e9a66c64SGreg Kroah-Hartman {
90e9a66c64SGreg Kroah-Hartman 	/*
91e9a66c64SGreg Kroah-Hartman 	 * This device can't write any data, only read from the device
92e9a66c64SGreg Kroah-Hartman 	 */
93a5b6f60cSAlan Cox 	return -EOPNOTSUPP;
94e9a66c64SGreg Kroah-Hartman }
95e9a66c64SGreg Kroah-Hartman 
96e9a66c64SGreg Kroah-Hartman static struct usb_serial_driver navman_device = {
97e9a66c64SGreg Kroah-Hartman 	.driver = {
98e9a66c64SGreg Kroah-Hartman 		.owner =	THIS_MODULE,
99e9a66c64SGreg Kroah-Hartman 		.name =		"navman",
100e9a66c64SGreg Kroah-Hartman 	},
101e9a66c64SGreg Kroah-Hartman 	.id_table =		id_table,
102e9a66c64SGreg Kroah-Hartman 	.num_ports =		1,
103e9a66c64SGreg Kroah-Hartman 	.open =			navman_open,
104e9a66c64SGreg Kroah-Hartman 	.close = 		navman_close,
105e9a66c64SGreg Kroah-Hartman 	.write = 		navman_write,
106e9a66c64SGreg Kroah-Hartman 	.read_int_callback =	navman_read_int_callback,
107e9a66c64SGreg Kroah-Hartman };
108e9a66c64SGreg Kroah-Hartman 
109f667ddadSAlan Stern static struct usb_serial_driver * const serial_drivers[] = {
110f667ddadSAlan Stern 	&navman_device, NULL
111f667ddadSAlan Stern };
112f667ddadSAlan Stern 
11368e24113SGreg Kroah-Hartman module_usb_serial_driver(serial_drivers, id_table);
114e9a66c64SGreg Kroah-Hartman 
115627cfa89SJohan Hovold MODULE_LICENSE("GPL v2");
116