aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc/imon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/rc/imon.c')
-rw-r--r--drivers/media/rc/imon.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index dec203bb06f6..72e3fa652481 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -112,6 +112,7 @@ struct imon_context {
112 bool tx_control; 112 bool tx_control;
113 unsigned char usb_rx_buf[8]; 113 unsigned char usb_rx_buf[8];
114 unsigned char usb_tx_buf[8]; 114 unsigned char usb_tx_buf[8];
115 unsigned int send_packet_delay;
115 116
116 struct tx_t { 117 struct tx_t {
117 unsigned char data_buf[35]; /* user data buffer */ 118 unsigned char data_buf[35]; /* user data buffer */
@@ -185,6 +186,10 @@ enum {
185 IMON_KEY_PANEL = 2, 186 IMON_KEY_PANEL = 2,
186}; 187};
187 188
189enum {
190 IMON_NEED_20MS_PKT_DELAY = 1
191};
192
188/* 193/*
189 * USB Device ID for iMON USB Control Boards 194 * USB Device ID for iMON USB Control Boards
190 * 195 *
@@ -215,7 +220,7 @@ static struct usb_device_id imon_usb_id_table[] = {
215 /* SoundGraph iMON OEM Touch LCD (IR & 4.3" VGA LCD) */ 220 /* SoundGraph iMON OEM Touch LCD (IR & 4.3" VGA LCD) */
216 { USB_DEVICE(0x15c2, 0x0035) }, 221 { USB_DEVICE(0x15c2, 0x0035) },
217 /* SoundGraph iMON OEM VFD (IR & VFD) */ 222 /* SoundGraph iMON OEM VFD (IR & VFD) */
218 { USB_DEVICE(0x15c2, 0x0036) }, 223 { USB_DEVICE(0x15c2, 0x0036), .driver_info = IMON_NEED_20MS_PKT_DELAY },
219 /* device specifics unknown */ 224 /* device specifics unknown */
220 { USB_DEVICE(0x15c2, 0x0037) }, 225 { USB_DEVICE(0x15c2, 0x0037) },
221 /* SoundGraph iMON OEM LCD (IR & LCD) */ 226 /* SoundGraph iMON OEM LCD (IR & LCD) */
@@ -523,8 +528,10 @@ static int send_packet(struct imon_context *ictx)
523 mutex_unlock(&ictx->lock); 528 mutex_unlock(&ictx->lock);
524 retval = wait_for_completion_interruptible( 529 retval = wait_for_completion_interruptible(
525 &ictx->tx.finished); 530 &ictx->tx.finished);
526 if (retval) 531 if (retval) {
532 usb_kill_urb(ictx->tx_urb);
527 pr_err_ratelimited("task interrupted\n"); 533 pr_err_ratelimited("task interrupted\n");
534 }
528 mutex_lock(&ictx->lock); 535 mutex_lock(&ictx->lock);
529 536
530 retval = ictx->tx.status; 537 retval = ictx->tx.status;
@@ -535,12 +542,12 @@ static int send_packet(struct imon_context *ictx)
535 kfree(control_req); 542 kfree(control_req);
536 543
537 /* 544 /*
538 * Induce a mandatory 5ms delay before returning, as otherwise, 545 * Induce a mandatory delay before returning, as otherwise,
539 * send_packet can get called so rapidly as to overwhelm the device, 546 * send_packet can get called so rapidly as to overwhelm the device,
540 * particularly on faster systems and/or those with quirky usb. 547 * particularly on faster systems and/or those with quirky usb.
541 */ 548 */
542 timeout = msecs_to_jiffies(5); 549 timeout = msecs_to_jiffies(ictx->send_packet_delay);
543 set_current_state(TASK_UNINTERRUPTIBLE); 550 set_current_state(TASK_INTERRUPTIBLE);
544 schedule_timeout(timeout); 551 schedule_timeout(timeout);
545 552
546 return retval; 553 return retval;
@@ -1568,11 +1575,6 @@ static void imon_incoming_packet(struct imon_context *ictx,
1568 if (press_type < 0) 1575 if (press_type < 0)
1569 goto not_input_data; 1576 goto not_input_data;
1570 1577
1571 spin_lock_irqsave(&ictx->kc_lock, flags);
1572 if (ictx->kc == KEY_UNKNOWN)
1573 goto unknown_key;
1574 spin_unlock_irqrestore(&ictx->kc_lock, flags);
1575
1576 if (ktype != IMON_KEY_PANEL) { 1578 if (ktype != IMON_KEY_PANEL) {
1577 if (press_type == 0) 1579 if (press_type == 0)
1578 rc_keyup(ictx->rdev); 1580 rc_keyup(ictx->rdev);
@@ -1615,12 +1617,6 @@ static void imon_incoming_packet(struct imon_context *ictx,
1615 1617
1616 return; 1618 return;
1617 1619
1618unknown_key:
1619 spin_unlock_irqrestore(&ictx->kc_lock, flags);
1620 dev_info(dev, "%s: unknown keypress, code 0x%llx\n", __func__,
1621 (long long)scancode);
1622 return;
1623
1624not_input_data: 1620not_input_data:
1625 if (len != 8) { 1621 if (len != 8) {
1626 dev_warn(dev, "imon %s: invalid incoming packet " 1622 dev_warn(dev, "imon %s: invalid incoming packet "
@@ -2099,7 +2095,8 @@ static bool imon_find_endpoints(struct imon_context *ictx,
2099 2095
2100} 2096}
2101 2097
2102static struct imon_context *imon_init_intf0(struct usb_interface *intf) 2098static struct imon_context *imon_init_intf0(struct usb_interface *intf,
2099 const struct usb_device_id *id)
2103{ 2100{
2104 struct imon_context *ictx; 2101 struct imon_context *ictx;
2105 struct urb *rx_urb; 2102 struct urb *rx_urb;
@@ -2139,6 +2136,10 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
2139 ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor); 2136 ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor);
2140 ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct); 2137 ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct);
2141 2138
2139 /* default send_packet delay is 5ms but some devices need more */
2140 ictx->send_packet_delay = id->driver_info & IMON_NEED_20MS_PKT_DELAY ?
2141 20 : 5;
2142
2142 ret = -ENODEV; 2143 ret = -ENODEV;
2143 iface_desc = intf->cur_altsetting; 2144 iface_desc = intf->cur_altsetting;
2144 if (!imon_find_endpoints(ictx, iface_desc)) { 2145 if (!imon_find_endpoints(ictx, iface_desc)) {
@@ -2317,7 +2318,7 @@ static int imon_probe(struct usb_interface *interface,
2317 first_if_ctx = usb_get_intfdata(first_if); 2318 first_if_ctx = usb_get_intfdata(first_if);
2318 2319
2319 if (ifnum == 0) { 2320 if (ifnum == 0) {
2320 ictx = imon_init_intf0(interface); 2321 ictx = imon_init_intf0(interface, id);
2321 if (!ictx) { 2322 if (!ictx) {
2322 pr_err("failed to initialize context!\n"); 2323 pr_err("failed to initialize context!\n");
2323 ret = -ENODEV; 2324 ret = -ENODEV;
@@ -2325,7 +2326,14 @@ static int imon_probe(struct usb_interface *interface,
2325 } 2326 }
2326 2327
2327 } else { 2328 } else {
2328 /* this is the secondary interface on the device */ 2329 /* this is the secondary interface on the device */
2330
2331 /* fail early if first intf failed to register */
2332 if (!first_if_ctx) {
2333 ret = -ENODEV;
2334 goto fail;
2335 }
2336
2329 ictx = imon_init_intf1(interface, first_if_ctx); 2337 ictx = imon_init_intf1(interface, first_if_ctx);
2330 if (!ictx) { 2338 if (!ictx) {
2331 pr_err("failed to attach to context!\n"); 2339 pr_err("failed to attach to context!\n");