Commit 4d63143d authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

USB: spcp8x5: reimplement device type detection

Reimplement device type detection using the device id table and quirks.

Device type was used to detect one device type which did not support to
control functions. Add quirks to the device table and store them in the
private port data at probe instead.
Signed-off-by: default avatarJohan Hovold <jhovold@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0a967f62
......@@ -28,6 +28,9 @@
#define DRIVER_DESC "SPCP8x5 USB to serial adaptor driver"
#define SPCP825_QUIRK_NO_UART_STATUS 0x01
#define SPCP825_QUIRK_NO_WORK_MODE 0x02
#define SPCP8x5_007_VID 0x04FC
#define SPCP8x5_007_PID 0x0201
#define SPCP8x5_008_VID 0x04fc
......@@ -44,7 +47,9 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(SPCP8x5_INTERMATIC_VID, SPCP8x5_INTERMATIC_PID)},
{ USB_DEVICE(SPCP8x5_835_VID, SPCP8x5_835_PID)},
{ USB_DEVICE(SPCP8x5_008_VID, SPCP8x5_008_PID)},
{ USB_DEVICE(SPCP8x5_007_VID, SPCP8x5_007_PID)},
{ USB_DEVICE(SPCP8x5_007_VID, SPCP8x5_007_PID),
.driver_info = SPCP825_QUIRK_NO_UART_STATUS |
SPCP825_QUIRK_NO_WORK_MODE },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, id_table);
......@@ -136,47 +141,32 @@ struct spcp8x5_usb_ctrl_arg {
#define UART_OVERRUN_ERROR 0x40
#define UART_CTS 0x80
enum spcp8x5_type {
SPCP825_007_TYPE,
SPCP825_008_TYPE,
SPCP825_PHILIP_TYPE,
SPCP825_INTERMATIC_TYPE,
SPCP835_TYPE,
};
struct spcp8x5_private {
unsigned quirks;
spinlock_t lock;
enum spcp8x5_type type;
u8 line_control;
u8 line_status;
};
static int spcp8x5_probe(struct usb_serial *serial,
const struct usb_device_id *id)
{
usb_set_serial_data(serial, (void *)id);
return 0;
}
static int spcp8x5_port_probe(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
const struct usb_device_id *id = usb_get_serial_data(port->serial);
struct spcp8x5_private *priv;
enum spcp8x5_type type = SPCP825_007_TYPE;
u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
if (product == 0x0201)
type = SPCP825_007_TYPE;
else if (product == 0x0231)
type = SPCP835_TYPE;
else if (product == 0x0235)
type = SPCP825_008_TYPE;
else if (product == 0x0204)
type = SPCP825_INTERMATIC_TYPE;
else if (product == 0x0471 &&
serial->dev->descriptor.idVendor == cpu_to_le16(0x081e))
type = SPCP825_PHILIP_TYPE;
dev_dbg(&serial->dev->dev, "device type = %d\n", (int)type);
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
spin_lock_init(&priv->lock);
priv->type = type;
priv->quirks = id->driver_info;
usb_set_serial_port_data(port, priv);
......@@ -193,18 +183,13 @@ static int spcp8x5_port_remove(struct usb_serial_port *port)
return 0;
}
/*
* Set the modem control line of the device.
*
* NOTE: not supported by spcp825-007
*/
static int spcp8x5_set_ctrl_line(struct usb_serial_port *port, u8 mcr)
{
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
struct usb_device *dev = port->serial->dev;
int retval;
if (priv->type == SPCP825_007_TYPE)
if (priv->quirks & SPCP825_QUIRK_NO_UART_STATUS)
return -EPERM;
retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
......@@ -217,11 +202,6 @@ static int spcp8x5_set_ctrl_line(struct usb_serial_port *port, u8 mcr)
return retval;
}
/*
* Get the modem status register of the device.
*
* NOTE: not supported by spcp825-007
*/
static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status)
{
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
......@@ -229,9 +209,7 @@ static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status)
u8 *buf;
int ret;
/* I return Permited not support here but seem inval device
* is more fix */
if (priv->type == SPCP825_007_TYPE)
if (priv->quirks & SPCP825_QUIRK_NO_UART_STATUS)
return -EPERM;
buf = kzalloc(1, GFP_KERNEL);
......@@ -251,11 +229,6 @@ static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status)
return ret;
}
/*
* Select the work mode.
*
* NOTE: not supported by spcp825-007
*/
static void spcp8x5_set_work_mode(struct usb_serial_port *port, u16 value,
u16 index)
{
......@@ -263,9 +236,7 @@ static void spcp8x5_set_work_mode(struct usb_serial_port *port, u16 value,
struct usb_device *dev = port->serial->dev;
int ret;
/* I return Permited not support here but seem inval device
* is more fix */
if (priv->type == SPCP825_007_TYPE)
if (priv->quirks & SPCP825_QUIRK_NO_WORK_MODE)
return;
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
......@@ -518,6 +489,7 @@ static struct usb_serial_driver spcp8x5_device = {
.init_termios = spcp8x5_init_termios,
.tiocmget = spcp8x5_tiocmget,
.tiocmset = spcp8x5_tiocmset,
.probe = spcp8x5_probe,
.port_probe = spcp8x5_port_probe,
.port_remove = spcp8x5_port_remove,
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment