diff options
Diffstat (limited to 'drivers/media/rc/imon.c')
-rw-r--r-- | drivers/media/rc/imon.c | 170 |
1 files changed, 29 insertions, 141 deletions
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 950d068ba806..1041c056854d 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c | |||
@@ -92,7 +92,6 @@ struct imon_usb_dev_descr { | |||
92 | __u16 flags; | 92 | __u16 flags; |
93 | #define IMON_NO_FLAGS 0 | 93 | #define IMON_NO_FLAGS 0 |
94 | #define IMON_NEED_20MS_PKT_DELAY 1 | 94 | #define IMON_NEED_20MS_PKT_DELAY 1 |
95 | #define IMON_IR_RAW 2 | ||
96 | struct imon_panel_key_table key_table[]; | 95 | struct imon_panel_key_table key_table[]; |
97 | }; | 96 | }; |
98 | 97 | ||
@@ -123,12 +122,6 @@ struct imon_context { | |||
123 | unsigned char usb_tx_buf[8]; | 122 | unsigned char usb_tx_buf[8]; |
124 | unsigned int send_packet_delay; | 123 | unsigned int send_packet_delay; |
125 | 124 | ||
126 | struct rx_data { | ||
127 | int count; /* length of 0 or 1 sequence */ | ||
128 | int prev_bit; /* logic level of sequence */ | ||
129 | int initial_space; /* initial space flag */ | ||
130 | } rx; | ||
131 | |||
132 | struct tx_t { | 125 | struct tx_t { |
133 | unsigned char data_buf[35]; /* user data buffer */ | 126 | unsigned char data_buf[35]; /* user data buffer */ |
134 | struct completion finished; /* wait for write to finish */ | 127 | struct completion finished; /* wait for write to finish */ |
@@ -331,10 +324,6 @@ static const struct imon_usb_dev_descr imon_DH102 = { | |||
331 | } | 324 | } |
332 | }; | 325 | }; |
333 | 326 | ||
334 | static const struct imon_usb_dev_descr imon_ir_raw = { | ||
335 | .flags = IMON_IR_RAW, | ||
336 | }; | ||
337 | |||
338 | /* | 327 | /* |
339 | * USB Device ID for iMON USB Control Boards | 328 | * USB Device ID for iMON USB Control Boards |
340 | * | 329 | * |
@@ -418,18 +407,6 @@ static const struct usb_device_id imon_usb_id_table[] = { | |||
418 | /* device specifics unknown */ | 407 | /* device specifics unknown */ |
419 | { USB_DEVICE(0x15c2, 0x0046), | 408 | { USB_DEVICE(0x15c2, 0x0046), |
420 | .driver_info = (unsigned long)&imon_default_table}, | 409 | .driver_info = (unsigned long)&imon_default_table}, |
421 | /* TriGem iMON (IR only) -- TG_iMON.inf */ | ||
422 | { USB_DEVICE(0x0aa8, 0x8001), | ||
423 | .driver_info = (unsigned long)&imon_ir_raw}, | ||
424 | /* SoundGraph iMON (IR only) -- sg_imon.inf */ | ||
425 | { USB_DEVICE(0x04e8, 0xff30), | ||
426 | .driver_info = (unsigned long)&imon_ir_raw}, | ||
427 | /* SoundGraph iMON VFD (IR & VFD) -- iMON_VFD.inf */ | ||
428 | { USB_DEVICE(0x0aa8, 0xffda), | ||
429 | .driver_info = (unsigned long)&imon_ir_raw}, | ||
430 | /* SoundGraph iMON SS (IR & VFD) -- iMON_SS.inf */ | ||
431 | { USB_DEVICE(0x15c2, 0xffda), | ||
432 | .driver_info = (unsigned long)&imon_ir_raw}, | ||
433 | {} | 410 | {} |
434 | }; | 411 | }; |
435 | 412 | ||
@@ -1133,18 +1110,18 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) | |||
1133 | dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); | 1110 | dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); |
1134 | ir_proto_packet[0] = 0x01; | 1111 | ir_proto_packet[0] = 0x01; |
1135 | *rc_proto = RC_PROTO_BIT_RC6_MCE; | 1112 | *rc_proto = RC_PROTO_BIT_RC6_MCE; |
1136 | } else if (*rc_proto & RC_PROTO_BIT_OTHER) { | 1113 | } else if (*rc_proto & RC_PROTO_BIT_IMON) { |
1137 | dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); | 1114 | dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); |
1138 | if (!pad_stabilize) | 1115 | if (!pad_stabilize) |
1139 | dev_dbg(dev, "PAD stabilize functionality disabled\n"); | 1116 | dev_dbg(dev, "PAD stabilize functionality disabled\n"); |
1140 | /* ir_proto_packet[0] = 0x00; // already the default */ | 1117 | /* ir_proto_packet[0] = 0x00; // already the default */ |
1141 | *rc_proto = RC_PROTO_BIT_OTHER; | 1118 | *rc_proto = RC_PROTO_BIT_IMON; |
1142 | } else { | 1119 | } else { |
1143 | dev_warn(dev, "Unsupported IR protocol specified, overriding to iMON IR protocol\n"); | 1120 | dev_warn(dev, "Unsupported IR protocol specified, overriding to iMON IR protocol\n"); |
1144 | if (!pad_stabilize) | 1121 | if (!pad_stabilize) |
1145 | dev_dbg(dev, "PAD stabilize functionality disabled\n"); | 1122 | dev_dbg(dev, "PAD stabilize functionality disabled\n"); |
1146 | /* ir_proto_packet[0] = 0x00; // already the default */ | 1123 | /* ir_proto_packet[0] = 0x00; // already the default */ |
1147 | *rc_proto = RC_PROTO_BIT_OTHER; | 1124 | *rc_proto = RC_PROTO_BIT_IMON; |
1148 | } | 1125 | } |
1149 | 1126 | ||
1150 | memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); | 1127 | memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); |
@@ -1411,7 +1388,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) | |||
1411 | rel_x = buf[2]; | 1388 | rel_x = buf[2]; |
1412 | rel_y = buf[3]; | 1389 | rel_y = buf[3]; |
1413 | 1390 | ||
1414 | if (ictx->rc_proto == RC_PROTO_BIT_OTHER && pad_stabilize) { | 1391 | if (ictx->rc_proto == RC_PROTO_BIT_IMON && pad_stabilize) { |
1415 | if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) { | 1392 | if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) { |
1416 | dir = stabilize((int)rel_x, (int)rel_y, | 1393 | dir = stabilize((int)rel_x, (int)rel_y, |
1417 | timeout, threshold); | 1394 | timeout, threshold); |
@@ -1478,7 +1455,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) | |||
1478 | buf[0] = 0x01; | 1455 | buf[0] = 0x01; |
1479 | buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0; | 1456 | buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0; |
1480 | 1457 | ||
1481 | if (ictx->rc_proto == RC_PROTO_BIT_OTHER && pad_stabilize) { | 1458 | if (ictx->rc_proto == RC_PROTO_BIT_IMON && pad_stabilize) { |
1482 | dir = stabilize((int)rel_x, (int)rel_y, | 1459 | dir = stabilize((int)rel_x, (int)rel_y, |
1483 | timeout, threshold); | 1460 | timeout, threshold); |
1484 | if (!dir) { | 1461 | if (!dir) { |
@@ -1572,94 +1549,11 @@ static int imon_parse_press_type(struct imon_context *ictx, | |||
1572 | /* | 1549 | /* |
1573 | * Process the incoming packet | 1550 | * Process the incoming packet |
1574 | */ | 1551 | */ |
1575 | /* | 1552 | static void imon_incoming_packet(struct imon_context *ictx, |
1576 | * Convert bit count to time duration (in us) and submit | ||
1577 | * the value to lirc_dev. | ||
1578 | */ | ||
1579 | static void submit_data(struct imon_context *context) | ||
1580 | { | ||
1581 | DEFINE_IR_RAW_EVENT(ev); | ||
1582 | |||
1583 | ev.pulse = context->rx.prev_bit; | ||
1584 | ev.duration = US_TO_NS(context->rx.count * BIT_DURATION); | ||
1585 | ir_raw_event_store_with_filter(context->rdev, &ev); | ||
1586 | } | ||
1587 | |||
1588 | /* | ||
1589 | * Process the incoming packet | ||
1590 | */ | ||
1591 | static void imon_incoming_ir_raw(struct imon_context *context, | ||
1592 | struct urb *urb, int intf) | 1553 | struct urb *urb, int intf) |
1593 | { | 1554 | { |
1594 | int len = urb->actual_length; | 1555 | int len = urb->actual_length; |
1595 | unsigned char *buf = urb->transfer_buffer; | 1556 | unsigned char *buf = urb->transfer_buffer; |
1596 | struct device *dev = context->dev; | ||
1597 | int octet, bit; | ||
1598 | unsigned char mask; | ||
1599 | |||
1600 | if (len != 8) { | ||
1601 | dev_warn(dev, "imon %s: invalid incoming packet size (len = %d, intf%d)\n", | ||
1602 | __func__, len, intf); | ||
1603 | return; | ||
1604 | } | ||
1605 | |||
1606 | if (debug) | ||
1607 | dev_info(dev, "raw packet: %*ph\n", len, buf); | ||
1608 | /* | ||
1609 | * Translate received data to pulse and space lengths. | ||
1610 | * Received data is active low, i.e. pulses are 0 and | ||
1611 | * spaces are 1. | ||
1612 | * | ||
1613 | * My original algorithm was essentially similar to | ||
1614 | * Changwoo Ryu's with the exception that he switched | ||
1615 | * the incoming bits to active high and also fed an | ||
1616 | * initial space to LIRC at the start of a new sequence | ||
1617 | * if the previous bit was a pulse. | ||
1618 | * | ||
1619 | * I've decided to adopt his algorithm. | ||
1620 | */ | ||
1621 | |||
1622 | if (buf[7] == 1 && context->rx.initial_space) { | ||
1623 | /* LIRC requires a leading space */ | ||
1624 | context->rx.prev_bit = 0; | ||
1625 | context->rx.count = 4; | ||
1626 | submit_data(context); | ||
1627 | context->rx.count = 0; | ||
1628 | } | ||
1629 | |||
1630 | for (octet = 0; octet < 5; ++octet) { | ||
1631 | mask = 0x80; | ||
1632 | for (bit = 0; bit < 8; ++bit) { | ||
1633 | int curr_bit = !(buf[octet] & mask); | ||
1634 | |||
1635 | if (curr_bit != context->rx.prev_bit) { | ||
1636 | if (context->rx.count) { | ||
1637 | submit_data(context); | ||
1638 | context->rx.count = 0; | ||
1639 | } | ||
1640 | context->rx.prev_bit = curr_bit; | ||
1641 | } | ||
1642 | ++context->rx.count; | ||
1643 | mask >>= 1; | ||
1644 | } | ||
1645 | } | ||
1646 | |||
1647 | if (buf[7] == 10) { | ||
1648 | if (context->rx.count) { | ||
1649 | submit_data(context); | ||
1650 | context->rx.count = 0; | ||
1651 | } | ||
1652 | context->rx.initial_space = context->rx.prev_bit; | ||
1653 | } | ||
1654 | |||
1655 | ir_raw_event_handle(context->rdev); | ||
1656 | } | ||
1657 | |||
1658 | static void imon_incoming_scancode(struct imon_context *ictx, | ||
1659 | struct urb *urb, int intf) | ||
1660 | { | ||
1661 | int len = urb->actual_length; | ||
1662 | unsigned char *buf = urb->transfer_buffer; | ||
1663 | struct device *dev = ictx->dev; | 1557 | struct device *dev = ictx->dev; |
1664 | unsigned long flags; | 1558 | unsigned long flags; |
1665 | u32 kc; | 1559 | u32 kc; |
@@ -1745,11 +1639,18 @@ static void imon_incoming_scancode(struct imon_context *ictx, | |||
1745 | if (press_type == 0) | 1639 | if (press_type == 0) |
1746 | rc_keyup(ictx->rdev); | 1640 | rc_keyup(ictx->rdev); |
1747 | else { | 1641 | else { |
1748 | if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE || | 1642 | enum rc_proto proto; |
1749 | ictx->rc_proto == RC_PROTO_BIT_OTHER) | 1643 | |
1750 | rc_keydown(ictx->rdev, | 1644 | if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE) |
1751 | ictx->rc_proto == RC_PROTO_BIT_RC6_MCE ? RC_PROTO_RC6_MCE : RC_PROTO_OTHER, | 1645 | proto = RC_PROTO_RC6_MCE; |
1752 | ictx->rc_scancode, ictx->rc_toggle); | 1646 | else if (ictx->rc_proto == RC_PROTO_BIT_IMON) |
1647 | proto = RC_PROTO_IMON; | ||
1648 | else | ||
1649 | return; | ||
1650 | |||
1651 | rc_keydown(ictx->rdev, proto, ictx->rc_scancode, | ||
1652 | ictx->rc_toggle); | ||
1653 | |||
1753 | spin_lock_irqsave(&ictx->kc_lock, flags); | 1654 | spin_lock_irqsave(&ictx->kc_lock, flags); |
1754 | ictx->last_keycode = ictx->kc; | 1655 | ictx->last_keycode = ictx->kc; |
1755 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | 1656 | spin_unlock_irqrestore(&ictx->kc_lock, flags); |
@@ -1839,10 +1740,7 @@ static void usb_rx_callback_intf0(struct urb *urb) | |||
1839 | break; | 1740 | break; |
1840 | 1741 | ||
1841 | case 0: | 1742 | case 0: |
1842 | if (ictx->rdev->driver_type == RC_DRIVER_IR_RAW) | 1743 | imon_incoming_packet(ictx, urb, intfnum); |
1843 | imon_incoming_ir_raw(ictx, urb, intfnum); | ||
1844 | else | ||
1845 | imon_incoming_scancode(ictx, urb, intfnum); | ||
1846 | break; | 1744 | break; |
1847 | 1745 | ||
1848 | default: | 1746 | default: |
@@ -1883,10 +1781,7 @@ static void usb_rx_callback_intf1(struct urb *urb) | |||
1883 | break; | 1781 | break; |
1884 | 1782 | ||
1885 | case 0: | 1783 | case 0: |
1886 | if (ictx->rdev->driver_type == RC_DRIVER_IR_RAW) | 1784 | imon_incoming_packet(ictx, urb, intfnum); |
1887 | imon_incoming_ir_raw(ictx, urb, intfnum); | ||
1888 | else | ||
1889 | imon_incoming_scancode(ictx, urb, intfnum); | ||
1890 | break; | 1785 | break; |
1891 | 1786 | ||
1892 | default: | 1787 | default: |
@@ -1912,7 +1807,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx) | |||
1912 | { | 1807 | { |
1913 | u8 ffdc_cfg_byte = ictx->usb_rx_buf[6]; | 1808 | u8 ffdc_cfg_byte = ictx->usb_rx_buf[6]; |
1914 | u8 detected_display_type = IMON_DISPLAY_TYPE_NONE; | 1809 | u8 detected_display_type = IMON_DISPLAY_TYPE_NONE; |
1915 | u64 allowed_protos = RC_PROTO_BIT_OTHER; | 1810 | u64 allowed_protos = RC_PROTO_BIT_IMON; |
1916 | 1811 | ||
1917 | switch (ffdc_cfg_byte) { | 1812 | switch (ffdc_cfg_byte) { |
1918 | /* iMON Knob, no display, iMON IR + vol knob */ | 1813 | /* iMON Knob, no display, iMON IR + vol knob */ |
@@ -1960,8 +1855,10 @@ static void imon_get_ffdc_type(struct imon_context *ictx) | |||
1960 | default: | 1855 | default: |
1961 | dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR"); | 1856 | dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR"); |
1962 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | 1857 | detected_display_type = IMON_DISPLAY_TYPE_VFD; |
1963 | /* We don't know which one it is, allow user to set the | 1858 | /* |
1964 | * RC6 one from userspace if OTHER wasn't correct. */ | 1859 | * We don't know which one it is, allow user to set the |
1860 | * RC6 one from userspace if IMON wasn't correct. | ||
1861 | */ | ||
1965 | allowed_protos |= RC_PROTO_BIT_RC6_MCE; | 1862 | allowed_protos |= RC_PROTO_BIT_RC6_MCE; |
1966 | break; | 1863 | break; |
1967 | } | 1864 | } |
@@ -2000,14 +1897,11 @@ static void imon_set_display_type(struct imon_context *ictx) | |||
2000 | case 0x0041: | 1897 | case 0x0041: |
2001 | case 0x0042: | 1898 | case 0x0042: |
2002 | case 0x0043: | 1899 | case 0x0043: |
2003 | case 0x8001: | ||
2004 | case 0xff30: | ||
2005 | configured_display_type = IMON_DISPLAY_TYPE_NONE; | 1900 | configured_display_type = IMON_DISPLAY_TYPE_NONE; |
2006 | ictx->display_supported = false; | 1901 | ictx->display_supported = false; |
2007 | break; | 1902 | break; |
2008 | case 0x0036: | 1903 | case 0x0036: |
2009 | case 0x0044: | 1904 | case 0x0044: |
2010 | case 0xffda: | ||
2011 | default: | 1905 | default: |
2012 | configured_display_type = IMON_DISPLAY_TYPE_VFD; | 1906 | configured_display_type = IMON_DISPLAY_TYPE_VFD; |
2013 | break; | 1907 | break; |
@@ -2032,8 +1926,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) | |||
2032 | static const unsigned char fp_packet[] = { | 1926 | static const unsigned char fp_packet[] = { |
2033 | 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88 }; | 1927 | 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88 }; |
2034 | 1928 | ||
2035 | rdev = rc_allocate_device(ictx->dev_descr->flags & IMON_IR_RAW ? | 1929 | rdev = rc_allocate_device(RC_DRIVER_SCANCODE); |
2036 | RC_DRIVER_IR_RAW : RC_DRIVER_SCANCODE); | ||
2037 | if (!rdev) { | 1930 | if (!rdev) { |
2038 | dev_err(ictx->dev, "remote control dev allocation failed\n"); | 1931 | dev_err(ictx->dev, "remote control dev allocation failed\n"); |
2039 | goto out; | 1932 | goto out; |
@@ -2051,12 +1944,8 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) | |||
2051 | rdev->dev.parent = ictx->dev; | 1944 | rdev->dev.parent = ictx->dev; |
2052 | 1945 | ||
2053 | rdev->priv = ictx; | 1946 | rdev->priv = ictx; |
2054 | if (ictx->dev_descr->flags & IMON_IR_RAW) | 1947 | /* iMON PAD or MCE */ |
2055 | rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; | 1948 | rdev->allowed_protocols = RC_PROTO_BIT_IMON | RC_PROTO_BIT_RC6_MCE; |
2056 | else | ||
2057 | /* iMON PAD or MCE */ | ||
2058 | rdev->allowed_protocols = RC_PROTO_BIT_OTHER | | ||
2059 | RC_PROTO_BIT_RC6_MCE; | ||
2060 | rdev->change_protocol = imon_ir_change_protocol; | 1949 | rdev->change_protocol = imon_ir_change_protocol; |
2061 | rdev->driver_name = MOD_NAME; | 1950 | rdev->driver_name = MOD_NAME; |
2062 | 1951 | ||
@@ -2074,8 +1963,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) | |||
2074 | 1963 | ||
2075 | imon_set_display_type(ictx); | 1964 | imon_set_display_type(ictx); |
2076 | 1965 | ||
2077 | if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE || | 1966 | if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE) |
2078 | ictx->dev_descr->flags & IMON_IR_RAW) | ||
2079 | rdev->map_name = RC_MAP_IMON_MCE; | 1967 | rdev->map_name = RC_MAP_IMON_MCE; |
2080 | else | 1968 | else |
2081 | rdev->map_name = RC_MAP_IMON_PAD; | 1969 | rdev->map_name = RC_MAP_IMON_PAD; |