diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-07 21:34:37 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-07 21:34:37 +0200 |
commit | 3036bc45364f98515a2c446d7fac2c34dcfbeff4 (patch) | |
tree | f565c03254413b779981ee5e9ed81b19d5b62c78 /drivers/media/rc | |
parent | Merge tag 'powerpc-4.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/p... (diff) | |
parent | media: omap2: fix compile-testing with FB_OMAP2=m (diff) | |
download | linux-3036bc45364f98515a2c446d7fac2c34dcfbeff4.tar.xz linux-3036bc45364f98515a2c446d7fac2c34dcfbeff4.zip |
Merge tag 'media/v4.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- remove of atomisp driver from staging, as nobody would have time to
dedicate huge efforts to fix all the problems there. Also, we have a
feeling that the driver may not even run the way it is.
- move Zoran driver to staging, in order to be either fixed to use VB2
and the proper media kAPIs or to be removed
- remove videobuf-dvb driver, with is unused for a while
- some V4L2 documentation fixes/improvements
- new sensor drivers: imx258 and ov7251
- a new driver was added to allow using I2C transparent drivers
- several improvements at the ddbridge driver
- several improvements at the ISDB pt1 driver, making it more coherent
with the DVB framework
- added a new platform driver for MIPI CSI-2 RX: cadence
- now, all media drivers can be compiled on x86 with COMPILE_TEST
- almost all media drivers now build on non-x86 architectures with
COMPILE_TEST
- lots of other random stuff: cleanups, support for new board models,
bug fixes, etc
* tag 'media/v4.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (464 commits)
media: omap2: fix compile-testing with FB_OMAP2=m
media: media/radio/Kconfig: add back RADIO_ISA
media: v4l2-ioctl.c: fix missing unlock in __video_do_ioctl()
media: pxa_camera: ignore -ENOIOCTLCMD from v4l2_subdev_call for s_power
media: arch: sh: migor: Fix TW9910 PDN gpio
media: staging: tegra-vde: Reset VDE regardless of memory client resetting failure
media: marvel-ccic: mmp: select VIDEOBUF2_VMALLOC/DMA_CONTIG
media: marvel-ccic: allow ccic and mmp drivers to coexist
media: uvcvideo: Prevent setting unavailable flags
media: ddbridge: conditionally enable fast TS for stv0910-equipped bridges
media: dvb-frontends/stv0910: make TS speed configurable
media: ddbridge/mci: add identifiers to function definition arguments
media: ddbridge/mci: protect against out-of-bounds array access in stop()
media: rc: ensure input/lirc device can be opened after register
media: rc: nuvoton: Keep device enabled during reg init
media: rc: nuvoton: Keep track of users on CIR enable/disable
media: rc: nuvoton: Tweak the interrupt enabling dance
media: uvcvideo: Support realtek's UVC 1.5 device
media: uvcvideo: Fix driver reference counting
media: gspca_zc3xx: Enable short exposure times for OV7648
...
Diffstat (limited to 'drivers/media/rc')
-rw-r--r-- | drivers/media/rc/Kconfig | 10 | ||||
-rw-r--r-- | drivers/media/rc/ir-imon-decoder.c | 136 | ||||
-rw-r--r-- | drivers/media/rc/ir-jvc-decoder.c | 1 | ||||
-rw-r--r-- | drivers/media/rc/ir-mce_kbd-decoder.c | 64 | ||||
-rw-r--r-- | drivers/media/rc/ir-nec-decoder.c | 1 | ||||
-rw-r--r-- | drivers/media/rc/ir-rc5-decoder.c | 4 | ||||
-rw-r--r-- | drivers/media/rc/ir-rc6-decoder.c | 11 | ||||
-rw-r--r-- | drivers/media/rc/ir-sanyo-decoder.c | 1 | ||||
-rw-r--r-- | drivers/media/rc/ir-sharp-decoder.c | 1 | ||||
-rw-r--r-- | drivers/media/rc/ir-sony-decoder.c | 1 | ||||
-rw-r--r-- | drivers/media/rc/ir-spi.c | 4 | ||||
-rw-r--r-- | drivers/media/rc/ir-xmp-decoder.c | 1 | ||||
-rw-r--r-- | drivers/media/rc/ite-cir.c | 8 | ||||
-rw-r--r-- | drivers/media/rc/ite-cir.h | 7 | ||||
-rw-r--r-- | drivers/media/rc/lirc_dev.c | 31 | ||||
-rw-r--r-- | drivers/media/rc/mceusb.c | 53 | ||||
-rw-r--r-- | drivers/media/rc/mtk-cir.c | 4 | ||||
-rw-r--r-- | drivers/media/rc/nuvoton-cir.c | 89 | ||||
-rw-r--r-- | drivers/media/rc/rc-core-priv.h | 6 | ||||
-rw-r--r-- | drivers/media/rc/rc-ir-raw.c | 81 | ||||
-rw-r--r-- | drivers/media/rc/rc-main.c | 72 | ||||
-rw-r--r-- | drivers/media/rc/st_rc.c | 16 | ||||
-rw-r--r-- | drivers/media/rc/winbond-cir.c | 4 |
23 files changed, 430 insertions, 176 deletions
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index d5b35a6ba899..1021c08a9ba4 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -162,7 +162,7 @@ config RC_ATI_REMOTE config IR_ENE tristate "ENE eHome Receiver/Transceiver (pnp id: ENE0100/ENE02xxx)" - depends on PNP + depends on PNP || COMPILE_TEST depends on RC_CORE ---help--- Say Y here to enable support for integrated infrared receiver @@ -223,7 +223,7 @@ config IR_MCEUSB config IR_ITE_CIR tristate "ITE Tech Inc. IT8712/IT8512 Consumer Infrared Transceiver" - depends on PNP + depends on PNP || COMPILE_TEST depends on RC_CORE ---help--- Say Y here to enable support for integrated infrared receivers @@ -236,7 +236,7 @@ config IR_ITE_CIR config IR_FINTEK tristate "Fintek Consumer Infrared Transceiver" - depends on PNP + depends on PNP || COMPILE_TEST depends on RC_CORE ---help--- Say Y here to enable support for integrated infrared receiver @@ -270,7 +270,7 @@ config IR_MTK config IR_NUVOTON tristate "Nuvoton w836x7hg Consumer Infrared Transceiver" - depends on PNP + depends on PNP || COMPILE_TEST depends on RC_CORE ---help--- Say Y here to enable support for integrated infrared receiver @@ -318,7 +318,7 @@ config IR_STREAMZAP config IR_WINBOND_CIR tristate "Winbond IR remote control" - depends on X86 && PNP + depends on (X86 && PNP) || COMPILE_TEST depends on RC_CORE select NEW_LEDS select LEDS_CLASS diff --git a/drivers/media/rc/ir-imon-decoder.c b/drivers/media/rc/ir-imon-decoder.c index a1ff06a26542..67c1b0c15aae 100644 --- a/drivers/media/rc/ir-imon-decoder.c +++ b/drivers/media/rc/ir-imon-decoder.c @@ -31,9 +31,69 @@ enum imon_state { STATE_INACTIVE, STATE_BIT_CHK, STATE_BIT_START, - STATE_FINISHED + STATE_FINISHED, + STATE_ERROR, }; +static void ir_imon_decode_scancode(struct rc_dev *dev) +{ + struct imon_dec *imon = &dev->raw->imon; + + /* Keyboard/Mouse toggle */ + if (imon->bits == 0x299115b7) + imon->stick_keyboard = !imon->stick_keyboard; + + if ((imon->bits & 0xfc0000ff) == 0x680000b7) { + int rel_x, rel_y; + u8 buf; + + buf = imon->bits >> 16; + rel_x = (buf & 0x08) | (buf & 0x10) >> 2 | + (buf & 0x20) >> 4 | (buf & 0x40) >> 6; + if (imon->bits & 0x02000000) + rel_x |= ~0x0f; + buf = imon->bits >> 8; + rel_y = (buf & 0x08) | (buf & 0x10) >> 2 | + (buf & 0x20) >> 4 | (buf & 0x40) >> 6; + if (imon->bits & 0x01000000) + rel_y |= ~0x0f; + + if (rel_x && rel_y && imon->stick_keyboard) { + if (abs(rel_y) > abs(rel_x)) + imon->bits = rel_y > 0 ? + 0x289515b7 : /* KEY_DOWN */ + 0x2aa515b7; /* KEY_UP */ + else + imon->bits = rel_x > 0 ? + 0x2ba515b7 : /* KEY_RIGHT */ + 0x29a515b7; /* KEY_LEFT */ + } + + if (!imon->stick_keyboard) { + struct lirc_scancode lsc = { + .scancode = imon->bits, + .rc_proto = RC_PROTO_IMON, + }; + + ir_lirc_scancode_event(dev, &lsc); + + input_event(imon->idev, EV_MSC, MSC_SCAN, imon->bits); + + input_report_rel(imon->idev, REL_X, rel_x); + input_report_rel(imon->idev, REL_Y, rel_y); + + input_report_key(imon->idev, BTN_LEFT, + (imon->bits & 0x00010000) != 0); + input_report_key(imon->idev, BTN_RIGHT, + (imon->bits & 0x00040000) != 0); + input_sync(imon->idev); + return; + } + } + + rc_keydown(dev, RC_PROTO_IMON, imon->bits, 0); +} + /** * ir_imon_decode() - Decode one iMON pulse or space * @dev: the struct rc_dev descriptor of the device @@ -56,6 +116,22 @@ static int ir_imon_decode(struct rc_dev *dev, struct ir_raw_event ev) data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse)); + /* + * Since iMON protocol is a series of bits, if at any point + * we encounter an error, make sure that any remaining bits + * aren't parsed as a scancode made up of less bits. + * + * Note that if the stick is held, then the remote repeats + * the scancode with about 12ms between them. So, make sure + * we have at least 10ms of space after an error. That way, + * we're at a new scancode. + */ + if (data->state == STATE_ERROR) { + if (!ev.pulse && ev.duration > MS_TO_NS(10)) + data->state = STATE_INACTIVE; + return 0; + } + for (;;) { if (!geq_margin(ev.duration, IMON_UNIT, IMON_UNIT / 2)) return 0; @@ -95,7 +171,7 @@ static int ir_imon_decode(struct rc_dev *dev, struct ir_raw_event ev) case STATE_FINISHED: if (ev.pulse) goto err_out; - rc_keydown(dev, RC_PROTO_IMON, data->bits, 0); + ir_imon_decode_scancode(dev); data->state = STATE_INACTIVE; break; } @@ -107,7 +183,7 @@ err_out: data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse)); - data->state = STATE_INACTIVE; + data->state = STATE_ERROR; return -EINVAL; } @@ -165,11 +241,65 @@ static int ir_imon_encode(enum rc_proto protocol, u32 scancode, return e - events; } +static int ir_imon_register(struct rc_dev *dev) +{ + struct input_dev *idev; + struct imon_dec *imon = &dev->raw->imon; + int ret; + + idev = input_allocate_device(); + if (!idev) + return -ENOMEM; + + snprintf(imon->name, sizeof(imon->name), + "iMON PAD Stick (%s)", dev->device_name); + idev->name = imon->name; + idev->phys = dev->input_phys; + + /* Mouse bits */ + set_bit(EV_REL, idev->evbit); + set_bit(EV_KEY, idev->evbit); + set_bit(REL_X, idev->relbit); + set_bit(REL_Y, idev->relbit); + set_bit(BTN_LEFT, idev->keybit); + set_bit(BTN_RIGHT, idev->keybit); + + /* Report scancodes too */ + set_bit(EV_MSC, idev->evbit); + set_bit(MSC_SCAN, idev->mscbit); + + input_set_drvdata(idev, imon); + + ret = input_register_device(idev); + if (ret < 0) { + input_free_device(idev); + return -EIO; + } + + imon->idev = idev; + imon->stick_keyboard = false; + + return 0; +} + +static int ir_imon_unregister(struct rc_dev *dev) +{ + struct imon_dec *imon = &dev->raw->imon; + + input_unregister_device(imon->idev); + imon->idev = NULL; + + return 0; +} + static struct ir_raw_handler imon_handler = { .protocols = RC_PROTO_BIT_IMON, .decode = ir_imon_decode, .encode = ir_imon_encode, .carrier = 38000, + .raw_register = ir_imon_register, + .raw_unregister = ir_imon_unregister, + .min_timeout = IMON_UNIT * IMON_BITS * 2, }; static int __init ir_imon_decode_init(void) diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c index 8cb68ae43282..5706cfe60027 100644 --- a/drivers/media/rc/ir-jvc-decoder.c +++ b/drivers/media/rc/ir-jvc-decoder.c @@ -213,6 +213,7 @@ static struct ir_raw_handler jvc_handler = { .decode = ir_jvc_decode, .encode = ir_jvc_encode, .carrier = 38000, + .min_timeout = JVC_TRAILER_SPACE, }; static int __init ir_jvc_decode_init(void) diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c index c110984ca671..64ea42927669 100644 --- a/drivers/media/rc/ir-mce_kbd-decoder.c +++ b/drivers/media/rc/ir-mce_kbd-decoder.c @@ -119,17 +119,25 @@ static void mce_kbd_rx_timeout(struct timer_list *t) { struct ir_raw_event_ctrl *raw = from_timer(raw, t, mce_kbd.rx_timeout); unsigned char maskcode; + unsigned long flags; int i; dev_dbg(&raw->dev->dev, "timer callback clearing all keys\n"); - for (i = 0; i < 7; i++) { - maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i]; - input_report_key(raw->mce_kbd.idev, maskcode, 0); - } + spin_lock_irqsave(&raw->mce_kbd.keylock, flags); + + if (time_is_before_eq_jiffies(raw->mce_kbd.rx_timeout.expires)) { + for (i = 0; i < 7; i++) { + maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i]; + input_report_key(raw->mce_kbd.idev, maskcode, 0); + } + + for (i = 0; i < MCIR2_MASK_KEYS_START; i++) + input_report_key(raw->mce_kbd.idev, kbd_keycodes[i], 0); - for (i = 0; i < MCIR2_MASK_KEYS_START; i++) - input_report_key(raw->mce_kbd.idev, kbd_keycodes[i], 0); + input_sync(raw->mce_kbd.idev); + } + spin_unlock_irqrestore(&raw->mce_kbd.keylock, flags); } static enum mce_kbd_mode mce_kbd_mode(struct mce_kbd_dec *data) @@ -147,13 +155,14 @@ static enum mce_kbd_mode mce_kbd_mode(struct mce_kbd_dec *data) static void ir_mce_kbd_process_keyboard_data(struct rc_dev *dev, u32 scancode) { struct mce_kbd_dec *data = &dev->raw->mce_kbd; - u8 keydata = (scancode >> 8) & 0xff; + u8 keydata1 = (scancode >> 8) & 0xff; + u8 keydata2 = (scancode >> 16) & 0xff; u8 shiftmask = scancode & 0xff; - unsigned char keycode, maskcode; + unsigned char maskcode; int i, keystate; - dev_dbg(&dev->dev, "keyboard: keydata = 0x%02x, shiftmask = 0x%02x\n", - keydata, shiftmask); + dev_dbg(&dev->dev, "keyboard: keydata2 = 0x%02x, keydata1 = 0x%02x, shiftmask = 0x%02x\n", + keydata2, keydata1, shiftmask); for (i = 0; i < 7; i++) { maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i]; @@ -164,10 +173,12 @@ static void ir_mce_kbd_process_keyboard_data(struct rc_dev *dev, u32 scancode) input_report_key(data->idev, maskcode, keystate); } - if (keydata) { - keycode = kbd_keycodes[keydata]; - input_report_key(data->idev, keycode, 1); - } else { + if (keydata1) + input_report_key(data->idev, kbd_keycodes[keydata1], 1); + if (keydata2) + input_report_key(data->idev, kbd_keycodes[keydata2], 1); + + if (!keydata1 && !keydata2) { for (i = 0; i < MCIR2_MASK_KEYS_START; i++) input_report_key(data->idev, kbd_keycodes[i], 0); } @@ -263,9 +274,6 @@ again: return 0; case STATE_HEADER_BIT_END: - if (!is_transition(&ev, &dev->raw->prev_ev)) - break; - decrease_duration(&ev, MCIR2_BIT_END); if (data->count != MCIR2_HEADER_NBITS) { @@ -302,9 +310,6 @@ again: return 0; case STATE_BODY_BIT_END: - if (!is_transition(&ev, &dev->raw->prev_ev)) - break; - if (data->count == data->wanted_bits) data->state = STATE_FINISHED; else @@ -319,16 +324,20 @@ again: switch (data->wanted_bits) { case MCIR2_KEYBOARD_NBITS: - scancode = data->body & 0xffff; + scancode = data->body & 0xffffff; dev_dbg(&dev->dev, "keyboard data 0x%08x\n", data->body); - if (dev->timeout) - delay = usecs_to_jiffies(dev->timeout / 1000); - else - delay = msecs_to_jiffies(100); - mod_timer(&data->rx_timeout, jiffies + delay); + spin_lock(&data->keylock); + if (scancode) { + delay = nsecs_to_jiffies(dev->timeout) + + msecs_to_jiffies(100); + mod_timer(&data->rx_timeout, jiffies + delay); + } else { + del_timer(&data->rx_timeout); + } /* Pass data to keyboard buffer parser */ ir_mce_kbd_process_keyboard_data(dev, scancode); + spin_unlock(&data->keylock); lsc.rc_proto = RC_PROTO_MCIR2_KBD; break; case MCIR2_MOUSE_NBITS: @@ -355,7 +364,6 @@ out: dev_dbg(&dev->dev, "failed at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; - input_sync(data->idev); return -EINVAL; } @@ -394,6 +402,7 @@ static int ir_mce_kbd_register(struct rc_dev *dev) set_bit(MSC_SCAN, idev->mscbit); timer_setup(&mce_kbd->rx_timeout, mce_kbd_rx_timeout, 0); + spin_lock_init(&mce_kbd->keylock); input_set_drvdata(idev, mce_kbd); @@ -475,6 +484,7 @@ static struct ir_raw_handler mce_kbd_handler = { .raw_register = ir_mce_kbd_register, .raw_unregister = ir_mce_kbd_unregister, .carrier = 36000, + .min_timeout = MCIR2_MAX_LEN + MCIR2_UNIT / 2, }; static int __init ir_mce_kbd_decode_init(void) diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 21647b809e6f..6a8973ae3684 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -253,6 +253,7 @@ static struct ir_raw_handler nec_handler = { .decode = ir_nec_decode, .encode = ir_nec_encode, .carrier = 38000, + .min_timeout = NEC_TRAILER_SPACE, }; static int __init ir_nec_decode_init(void) diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index 74d3b859c3a2..63624654a71e 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -88,9 +88,6 @@ again: return 0; case STATE_BIT_END: - if (!is_transition(&ev, &dev->raw->prev_ev)) - break; - if (data->count == CHECK_RC5X_NBITS) data->state = STATE_CHECK_RC5X; else @@ -274,6 +271,7 @@ static struct ir_raw_handler rc5_handler = { .decode = ir_rc5_decode, .encode = ir_rc5_encode, .carrier = 36000, + .min_timeout = RC5_TRAILER, }; static int __init ir_rc5_decode_init(void) diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index 8314da32453f..68487ce9f79b 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -145,9 +145,6 @@ again: return 0; case STATE_HEADER_BIT_END: - if (!is_transition(&ev, &dev->raw->prev_ev)) - break; - if (data->count == RC6_HEADER_NBITS) data->state = STATE_TOGGLE_START; else @@ -165,10 +162,6 @@ again: return 0; case STATE_TOGGLE_END: - if (!is_transition(&ev, &dev->raw->prev_ev) || - !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2)) - break; - if (!(data->header & RC6_STARTBIT_MASK)) { dev_dbg(&dev->dev, "RC6 invalid start bit\n"); break; @@ -210,9 +203,6 @@ again: break; case STATE_BODY_BIT_END: - if (!is_transition(&ev, &dev->raw->prev_ev)) - break; - if (data->count == data->wanted_bits) data->state = STATE_FINISHED; else @@ -394,6 +384,7 @@ static struct ir_raw_handler rc6_handler = { .decode = ir_rc6_decode, .encode = ir_rc6_encode, .carrier = 36000, + .min_timeout = RC6_SUFFIX_SPACE, }; static int __init ir_rc6_decode_init(void) diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c index 4efe6db5376a..dd6ee1e339d6 100644 --- a/drivers/media/rc/ir-sanyo-decoder.c +++ b/drivers/media/rc/ir-sanyo-decoder.c @@ -210,6 +210,7 @@ static struct ir_raw_handler sanyo_handler = { .decode = ir_sanyo_decode, .encode = ir_sanyo_encode, .carrier = 38000, + .min_timeout = SANYO_TRAILER_SPACE, }; static int __init ir_sanyo_decode_init(void) diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c index 6a38c50566a4..f96e0c992eed 100644 --- a/drivers/media/rc/ir-sharp-decoder.c +++ b/drivers/media/rc/ir-sharp-decoder.c @@ -226,6 +226,7 @@ static struct ir_raw_handler sharp_handler = { .decode = ir_sharp_decode, .encode = ir_sharp_encode, .carrier = 38000, + .min_timeout = SHARP_ECHO_SPACE + SHARP_ECHO_SPACE / 4, }; static int __init ir_sharp_decode_init(void) diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c index 6764ec9de646..5065c081238d 100644 --- a/drivers/media/rc/ir-sony-decoder.c +++ b/drivers/media/rc/ir-sony-decoder.c @@ -224,6 +224,7 @@ static struct ir_raw_handler sony_handler = { .decode = ir_sony_decode, .encode = ir_sony_encode, .carrier = 40000, + .min_timeout = SONY_TRAILER_SPACE, }; static int __init ir_sony_decode_init(void) diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c index 7163d5ce2e64..66334e8d63ba 100644 --- a/drivers/media/rc/ir-spi.c +++ b/drivers/media/rc/ir-spi.c @@ -2,7 +2,7 @@ // SPI driven IR LED device driver // // Copyright (c) 2016 Samsung Electronics Co., Ltd. -// Copyright (c) Andi Shyti <andi.shyti@samsung.com> +// Copyright (c) Andi Shyti <andi@etezian.org> #include <linux/delay.h> #include <linux/fs.h> @@ -173,6 +173,6 @@ static struct spi_driver ir_spi_driver = { module_spi_driver(ir_spi_driver); -MODULE_AUTHOR("Andi Shyti <andi.shyti@samsung.com>"); +MODULE_AUTHOR("Andi Shyti <andi@etezian.org>"); MODULE_DESCRIPTION("SPI IR LED"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/rc/ir-xmp-decoder.c b/drivers/media/rc/ir-xmp-decoder.c index 58b47af1a763..c965f51df1c1 100644 --- a/drivers/media/rc/ir-xmp-decoder.c +++ b/drivers/media/rc/ir-xmp-decoder.c @@ -199,6 +199,7 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) static struct ir_raw_handler xmp_handler = { .protocols = RC_PROTO_BIT_XMP, .decode = ir_xmp_decode, + .min_timeout = XMP_TRAILER_SPACE, }; static int __init ir_xmp_decode_init(void) diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index 65e104c7ddfc..de77d22c30a7 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -1561,9 +1561,11 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id rdev->close = ite_close; rdev->s_idle = ite_s_idle; rdev->s_rx_carrier_range = ite_set_rx_carrier_range; - rdev->min_timeout = ITE_MIN_IDLE_TIMEOUT; - rdev->max_timeout = ITE_MAX_IDLE_TIMEOUT; - rdev->timeout = ITE_IDLE_TIMEOUT; + /* FIFO threshold is 17 bytes, so 17 * 8 samples minimum */ + rdev->min_timeout = 17 * 8 * ITE_BAUDRATE_DIVISOR * + itdev->params.sample_period; + rdev->timeout = IR_DEFAULT_TIMEOUT; + rdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; rdev->rx_resolution = ITE_BAUDRATE_DIVISOR * itdev->params.sample_period; rdev->tx_resolution = ITE_BAUDRATE_DIVISOR * diff --git a/drivers/media/rc/ite-cir.h b/drivers/media/rc/ite-cir.h index 0e8ebc880d1f..9cb24ac01350 100644 --- a/drivers/media/rc/ite-cir.h +++ b/drivers/media/rc/ite-cir.h @@ -154,13 +154,6 @@ struct ite_dev { /* default carrier freq for when demodulator is off (Hz) */ #define ITE_DEFAULT_CARRIER_FREQ 38000 -/* default idling timeout in ns (0.2 seconds) */ -#define ITE_IDLE_TIMEOUT 200000000UL - -/* limit timeout values */ -#define ITE_MIN_IDLE_TIMEOUT 100000000UL -#define ITE_MAX_IDLE_TIMEOUT 1000000000UL - /* convert bits to us */ #define ITE_BITS_TO_NS(bits, sample_period) \ ((u32) ((bits) * ITE_BAUDRATE_DIVISOR * sample_period)) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index da7013a12a58..f862f1b7f996 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -582,10 +582,17 @@ static long ir_lirc_ioctl(struct file *file, unsigned int cmd, } break; - case LIRC_SET_REC_TIMEOUT_REPORTS: + case LIRC_GET_REC_TIMEOUT: if (!dev->timeout) ret = -ENOTTY; else + val = DIV_ROUND_UP(dev->timeout, 1000); + break; + + case LIRC_SET_REC_TIMEOUT_REPORTS: + if (dev->driver_type != RC_DRIVER_IR_RAW) + ret = -ENOTTY; + else fh->send_timeout_reports = !!val; break; @@ -742,6 +749,7 @@ static void lirc_release_device(struct device *ld) int ir_lirc_register(struct rc_dev *dev) { + const char *rx_type, *tx_type; int err, minor; minor = ida_simple_get(&lirc_ida, 0, RC_DEV_MAX, GFP_KERNEL); @@ -766,8 +774,25 @@ int ir_lirc_register(struct rc_dev *dev) get_device(&dev->dev); - dev_info(&dev->dev, "lirc_dev: driver %s registered at minor = %d", - dev->driver_name, minor); + switch (dev->driver_type) { + case RC_DRIVER_SCANCODE: + rx_type = "scancode"; + break; + case RC_DRIVER_IR_RAW: + rx_type = "raw IR"; + break; + default: + rx_type = "no"; + break; + } + + if (dev->tx_ir) + tx_type = "raw IR"; + else + tx_type = "no"; + + dev_info(&dev->dev, "lirc_dev: driver %s registered at minor = %d, %s receiver, %s transmitter", + dev->driver_name, minor, rx_type, tx_type); return 0; diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 69ba57372c05..4c0c8008872a 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -181,6 +181,7 @@ enum mceusb_model_type { MCE_GEN2 = 0, /* Most boards */ MCE_GEN1, MCE_GEN3, + MCE_GEN3_BROKEN_IRTIMEOUT, MCE_GEN2_TX_INV, MCE_GEN2_TX_INV_RX_GOOD, POLARIS_EVK, @@ -199,6 +200,7 @@ struct mceusb_model { u32 mce_gen3:1; u32 tx_mask_normal:1; u32 no_tx:1; + u32 broken_irtimeout:1; /* * 2nd IR receiver (short-range, wideband) for learning mode: * 0, absent 2nd receiver (rx2) @@ -242,6 +244,12 @@ static const struct mceusb_model mceusb_model[] = { .tx_mask_normal = 1, .rx2 = 2, }, + [MCE_GEN3_BROKEN_IRTIMEOUT] = { + .mce_gen3 = 1, + .tx_mask_normal = 1, + .rx2 = 2, + .broken_irtimeout = 1 + }, [POLARIS_EVK] = { /* * In fact, the EVK is shipped without @@ -352,7 +360,7 @@ static const struct usb_device_id mceusb_dev_table[] = { .driver_info = MCE_GEN2_TX_INV }, /* Topseed eHome Infrared Transceiver */ { USB_DEVICE(VENDOR_TOPSEED, 0x0011), - .driver_info = MCE_GEN3 }, + .driver_info = MCE_GEN3_BROKEN_IRTIMEOUT }, /* Ricavision internal Infrared Transceiver */ { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, /* Itron ione Libra Q-11 */ @@ -564,6 +572,7 @@ static int mceusb_cmd_datasize(u8 cmd, u8 subcmd) datasize = 1; break; } + break; case MCE_CMD_PORT_IR: switch (subcmd) { case MCE_CMD_UNKNOWN: @@ -982,6 +991,25 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier) return 0; } +static int mceusb_set_timeout(struct rc_dev *dev, unsigned int timeout) +{ + u8 cmdbuf[4] = { MCE_CMD_PORT_IR, MCE_CMD_SETIRTIMEOUT, 0, 0 }; + struct mceusb_dev *ir = dev->priv; + unsigned int units; + + units = DIV_ROUND_CLOSEST(timeout, US_TO_NS(MCE_TIME_UNIT)); + + cmdbuf[2] = units >> 8; + cmdbuf[3] = units; + + mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); + + /* get receiver timeout value */ + mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT)); + + return 0; +} + /* * Select or deselect the 2nd receiver port. * Second receiver is learning mode, wide-band, short-range receiver. @@ -1150,6 +1178,11 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) init_ir_raw_event(&rawir); rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK); + if (unlikely(!rawir.duration)) { + dev_warn(ir->dev, "nonsensical irdata %02x with duration 0", + ir->buf_in[i]); + break; + } if (rawir.pulse) { ir->pulse_tunit += rawir.duration; ir->pulse_count++; @@ -1182,7 +1215,12 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) if (ir->rem) { ir->parser_state = PARSE_IRDATA; } else { - ir_raw_event_reset(ir->rc); + init_ir_raw_event(&rawir); + rawir.timeout = 1; + rawir.duration = ir->rc->timeout; + if (ir_raw_event_store_with_filter(ir->rc, + &rawir)) + event = true; ir->pulse_tunit = 0; ir->pulse_count = 0; } @@ -1415,7 +1453,18 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) rc->dev.parent = dev; rc->priv = ir; rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; + rc->min_timeout = US_TO_NS(MCE_TIME_UNIT); rc->timeout = MS_TO_NS(100); + if (!mceusb_model[ir->model].broken_irtimeout) { + rc->s_timeout = mceusb_set_timeout; + rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT; + } else { + /* + * If we can't set the timeout using CMD_SETIRTIMEOUT, we can + * rely on software timeouts for timeouts < 100ms. + */ + rc->max_timeout = rc->timeout; + } if (!ir->flags.no_tx) { rc->s_tx_mask = mceusb_set_tx_mask; rc->s_tx_carrier = mceusb_set_tx_carrier; diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c index e88eb64e8e69..e42efd9d382e 100644 --- a/drivers/media/rc/mtk-cir.c +++ b/drivers/media/rc/mtk-cir.c @@ -299,8 +299,6 @@ static int mtk_ir_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *dn = dev->of_node; - const struct of_device_id *of_id = - of_match_device(mtk_ir_match, &pdev->dev); struct resource *res; struct mtk_ir *ir; u32 val; @@ -312,7 +310,7 @@ static int mtk_ir_probe(struct platform_device *pdev) return -ENOMEM; ir->dev = dev; - ir->data = of_id->data; + ir->data = of_device_get_match_data(dev); ir->clk = devm_clk_get(dev, "clk"); if (IS_ERR(ir->clk)) { diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 5e1d866a61a5..b8299c9a9744 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -535,6 +535,8 @@ static void nvt_set_cir_iren(struct nvt_dev *nvt) static void nvt_cir_regs_init(struct nvt_dev *nvt) { + nvt_enable_logical_dev(nvt, LOGICAL_DEV_CIR); + /* set sample limit count (PE interrupt raised when reached) */ nvt_cir_reg_write(nvt, CIR_RX_LIMIT_COUNT >> 8, CIR_SLCH); nvt_cir_reg_write(nvt, CIR_RX_LIMIT_COUNT & 0xff, CIR_SLCL); @@ -543,31 +545,17 @@ static void nvt_cir_regs_init(struct nvt_dev *nvt) nvt_cir_reg_write(nvt, CIR_FIFOCON_TX_TRIGGER_LEV | CIR_FIFOCON_RX_TRIGGER_LEV, CIR_FIFOCON); - /* - * Enable TX and RX, specify carrier on = low, off = high, and set - * sample period (currently 50us) - */ - nvt_cir_reg_write(nvt, - CIR_IRCON_TXEN | CIR_IRCON_RXEN | - CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, - CIR_IRCON); - /* clear hardware rx and tx fifos */ nvt_clear_cir_fifo(nvt); nvt_clear_tx_fifo(nvt); - /* clear any and all stray interrupts */ - nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); - - /* and finally, enable interrupts */ - nvt_set_cir_iren(nvt); - - /* enable the CIR logical device */ - nvt_enable_logical_dev(nvt, LOGICAL_DEV_CIR); + nvt_disable_logical_dev(nvt, LOGICAL_DEV_CIR); } static void nvt_cir_wake_regs_init(struct nvt_dev *nvt) { + nvt_enable_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE); + /* * Disable RX, set specific carrier on = low, off = high, * and sample period (currently 50us) @@ -579,9 +567,6 @@ static void nvt_cir_wake_regs_init(struct nvt_dev *nvt) /* clear any and all stray interrupts */ nvt_cir_wake_reg_write(nvt, 0xff, CIR_WAKE_IRSTS); - - /* enable the CIR WAKE logical device */ - nvt_enable_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE); } static void nvt_enable_wake(struct nvt_dev *nvt) @@ -892,6 +877,32 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) return IRQ_HANDLED; } +static void nvt_enable_cir(struct nvt_dev *nvt) +{ + unsigned long flags; + + /* enable the CIR logical device */ + nvt_enable_logical_dev(nvt, LOGICAL_DEV_CIR); + + spin_lock_irqsave(&nvt->lock, flags); + + /* + * Enable TX and RX, specify carrier on = low, off = high, and set + * sample period (currently 50us) + */ + nvt_cir_reg_write(nvt, CIR_IRCON_TXEN | CIR_IRCON_RXEN | + CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, + CIR_IRCON); + + /* clear all pending interrupts */ + nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); + + /* enable interrupts */ + nvt_set_cir_iren(nvt); + + spin_unlock_irqrestore(&nvt->lock, flags); +} + static void nvt_disable_cir(struct nvt_dev *nvt) { unsigned long flags; @@ -920,25 +931,8 @@ static void nvt_disable_cir(struct nvt_dev *nvt) static int nvt_open(struct rc_dev *dev) { struct nvt_dev *nvt = dev->priv; - unsigned long flags; - - spin_lock_irqsave(&nvt->lock, flags); - - /* set function enable flags */ - nvt_cir_reg_write(nvt, CIR_IRCON_TXEN | CIR_IRCON_RXEN | - CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, - CIR_IRCON); - - /* clear all pending interrupts */ - nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); - - /* enable interrupts */ - nvt_set_cir_iren(nvt); - spin_unlock_irqrestore(&nvt->lock, flags); - - /* enable the CIR logical device */ - nvt_enable_logical_dev(nvt, LOGICAL_DEV_CIR); + nvt_enable_cir(nvt); return 0; } @@ -1093,19 +1087,13 @@ static void nvt_remove(struct pnp_dev *pdev) static int nvt_suspend(struct pnp_dev *pdev, pm_message_t state) { struct nvt_dev *nvt = pnp_get_drvdata(pdev); - unsigned long flags; nvt_dbg("%s called", __func__); - spin_lock_irqsave(&nvt->lock, flags); - - /* disable all CIR interrupts */ - nvt_cir_reg_write(nvt, 0, CIR_IREN); - - spin_unlock_irqrestore(&nvt->lock, flags); - - /* disable cir logical dev */ - nvt_disable_logical_dev(nvt, LOGICAL_DEV_CIR); + mutex_lock(&nvt->rdev->lock); + if (nvt->rdev->users) + nvt_disable_cir(nvt); + mutex_unlock(&nvt->rdev->lock); /* make sure wake is enabled */ nvt_enable_wake(nvt); @@ -1122,6 +1110,11 @@ static int nvt_resume(struct pnp_dev *pdev) nvt_cir_regs_init(nvt); nvt_cir_wake_regs_init(nvt); + mutex_lock(&nvt->rdev->lock); + if (nvt->rdev->users) + nvt_enable_cir(nvt); + mutex_unlock(&nvt->rdev->lock); + return 0; } diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index eb004757038b..e847bdad5c51 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -38,6 +38,7 @@ struct ir_raw_handler { int (*encode)(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max); u32 carrier; + u32 min_timeout; /* These two should only be used by the mce kbd decoder */ int (*raw_register)(struct rc_dev *dev); @@ -110,6 +111,8 @@ struct ir_raw_event_ctrl { } sharp; struct mce_kbd_dec { struct input_dev *idev; + /* locks key up timer */ + spinlock_t keylock; struct timer_list rx_timeout; char name[64]; char phys[64]; @@ -129,6 +132,9 @@ struct ir_raw_event_ctrl { int count; int last_chk; unsigned int bits; + bool stick_keyboard; + struct input_dev *idev; + char name[64]; } imon; }; diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 7675b7ee5bc7..2e0066b1a31c 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -22,16 +22,27 @@ static int ir_raw_event_thread(void *data) { struct ir_raw_event ev; struct ir_raw_handler *handler; - struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; + struct ir_raw_event_ctrl *raw = data; + struct rc_dev *dev = raw->dev; while (1) { mutex_lock(&ir_raw_handler_lock); while (kfifo_out(&raw->kfifo, &ev, 1)) { + if (is_timing_event(ev)) { + if (ev.duration == 0) + dev_err(&dev->dev, "nonsensical timing event of duration 0"); + if (is_timing_event(raw->prev_ev) && + !is_transition(&ev, &raw->prev_ev)) + dev_err(&dev->dev, "two consecutive events of type %s", + TO_STR(ev.pulse)); + if (raw->prev_ev.reset && ev.pulse == 0) + dev_err(&dev->dev, "timing event after reset should be pulse"); + } list_for_each_entry(handler, &ir_raw_handler_list, list) - if (raw->dev->enabled_protocols & + if (dev->enabled_protocols & handler->protocols || !handler->protocols) - handler->decode(raw->dev, ev); - ir_lirc_raw_event(raw->dev, ev); + handler->decode(dev, ev); + ir_lirc_raw_event(dev, ev); raw->prev_ev = ev; } mutex_unlock(&ir_raw_handler_lock); @@ -233,7 +244,49 @@ ir_raw_get_allowed_protocols(void) static int change_protocol(struct rc_dev *dev, u64 *rc_proto) { - /* the caller will update dev->enabled_protocols */ + struct ir_raw_handler *handler; + u32 timeout = 0; + + mutex_lock(&ir_raw_handler_lock); + list_for_each_entry(handler, &ir_raw_handler_list, list) { + if (!(dev->enabled_protocols & handler->protocols) && + (*rc_proto & handler->protocols) && handler->raw_register) + handler->raw_register(dev); + + if ((dev->enabled_protocols & handler->protocols) && + !(*rc_proto & handler->protocols) && + handler->raw_unregister) + handler->raw_unregister(dev); + } + mutex_unlock(&ir_raw_handler_lock); + + if (!dev->max_timeout) + return 0; + + mutex_lock(&ir_raw_handler_lock); + list_for_each_entry(handler, &ir_raw_handler_list, list) { + if (handler->protocols & *rc_proto) { + if (timeout < handler->min_timeout) + timeout = handler->min_timeout; + } + } + mutex_unlock(&ir_raw_handler_lock); + + if (timeout == 0) + timeout = IR_DEFAULT_TIMEOUT; + else + timeout += MS_TO_NS(10); + + if (timeout < dev->min_timeout) + timeout = dev->min_timeout; + else if (timeout > dev->max_timeout) + timeout = dev->max_timeout; + + if (dev->s_timeout) + dev->s_timeout(dev, timeout); + else + dev->timeout = timeout; + return 0; } @@ -569,6 +622,7 @@ int ir_raw_event_prepare(struct rc_dev *dev) dev->raw->dev = dev; dev->change_protocol = change_protocol; + dev->idle = true; spin_lock_init(&dev->raw->edge_spinlock); timer_setup(&dev->raw->edge_handle, ir_raw_edge_handle, 0); INIT_KFIFO(dev->raw->kfifo); @@ -578,7 +632,6 @@ int ir_raw_event_prepare(struct rc_dev *dev) int ir_raw_event_register(struct rc_dev *dev) { - struct ir_raw_handler *handler; struct task_struct *thread; thread = kthread_run(ir_raw_event_thread, dev->raw, "rc%u", dev->minor); @@ -589,9 +642,6 @@ int ir_raw_event_register(struct rc_dev *dev) mutex_lock(&ir_raw_handler_lock); list_add_tail(&dev->raw->list, &ir_raw_client_list); - list_for_each_entry(handler, &ir_raw_handler_list, list) - if (handler->raw_register) - handler->raw_register(dev); mutex_unlock(&ir_raw_handler_lock); return 0; @@ -619,7 +669,8 @@ void ir_raw_event_unregister(struct rc_dev *dev) mutex_lock(&ir_raw_handler_lock); list_del(&dev->raw->list); list_for_each_entry(handler, &ir_raw_handler_list, list) - if (handler->raw_unregister) + if (handler->raw_unregister && + (handler->protocols & dev->enabled_protocols)) handler->raw_unregister(dev); lirc_bpf_free(dev); @@ -640,13 +691,8 @@ void ir_raw_event_unregister(struct rc_dev *dev) int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) { - struct ir_raw_event_ctrl *raw; - mutex_lock(&ir_raw_handler_lock); list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); - if (ir_raw_handler->raw_register) - list_for_each_entry(raw, &ir_raw_client_list, list) - ir_raw_handler->raw_register(raw->dev); atomic64_or(ir_raw_handler->protocols, &available_protocols); mutex_unlock(&ir_raw_handler_lock); @@ -662,9 +708,10 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) mutex_lock(&ir_raw_handler_lock); list_del(&ir_raw_handler->list); list_for_each_entry(raw, &ir_raw_client_list, list) { - ir_raw_disable_protocols(raw->dev, protocols); - if (ir_raw_handler->raw_unregister) + if (ir_raw_handler->raw_unregister && + (raw->dev->enabled_protocols & protocols)) ir_raw_handler->raw_unregister(raw->dev); + ir_raw_disable_protocols(raw->dev, protocols); } atomic64_andnot(protocols, &available_protocols); mutex_unlock(&ir_raw_handler_lock); diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index b67be33bd62f..2e222d9ee01f 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -26,50 +26,50 @@ static const struct { unsigned int repeat_period; unsigned int scancode_bits; } protocols[] = { - [RC_PROTO_UNKNOWN] = { .name = "unknown", .repeat_period = 250 }, - [RC_PROTO_OTHER] = { .name = "other", .repeat_period = 250 }, + [RC_PROTO_UNKNOWN] = { .name = "unknown", .repeat_period = 125 }, + [RC_PROTO_OTHER] = { .name = "other", .repeat_period = 125 }, [RC_PROTO_RC5] = { .name = "rc-5", - .scancode_bits = 0x1f7f, .repeat_period = 250 }, + .scancode_bits = 0x1f7f, .repeat_period = 114 }, [RC_PROTO_RC5X_20] = { .name = "rc-5x-20", - .scancode_bits = 0x1f7f3f, .repeat_period = 250 }, + .scancode_bits = 0x1f7f3f, .repeat_period = 114 }, [RC_PROTO_RC5_SZ] = { .name = "rc-5-sz", - .scancode_bits = 0x2fff, .repeat_period = 250 }, + .scancode_bits = 0x2fff, .repeat_period = 114 }, [RC_PROTO_JVC] = { .name = "jvc", - .scancode_bits = 0xffff, .repeat_period = 250 }, + .scancode_bits = 0xffff, .repeat_period = 125 }, [RC_PROTO_SONY12] = { .name = "sony-12", - .scancode_bits = 0x1f007f, .repeat_period = 250 }, + .scancode_bits = 0x1f007f, .repeat_period = 100 }, [RC_PROTO_SONY15] = { .name = "sony-15", - .scancode_bits = 0xff007f, .repeat_period = 250 }, + .scancode_bits = 0xff007f, .repeat_period = 100 }, [RC_PROTO_SONY20] = { .name = "sony-20", - .scancode_bits = 0x1fff7f, .repeat_period = 250 }, + .scancode_bits = 0x1fff7f, .repeat_period = 100 }, [RC_PROTO_NEC] = { .name = "nec", - .scancode_bits = 0xffff, .repeat_period = 250 }, + .scancode_bits = 0xffff, .repeat_period = 110 }, [RC_PROTO_NECX] = { .name = "nec-x", - .scancode_bits = 0xffffff, .repeat_period = 250 }, + .scancode_bits = 0xffffff, .repeat_period = 110 }, [RC_PROTO_NEC32] = { .name = "nec-32", - .scancode_bits = 0xffffffff, .repeat_period = 250 }, + .scancode_bits = 0xffffffff, .repeat_period = 110 }, [RC_PROTO_SANYO] = { .name = "sanyo", - .scancode_bits = 0x1fffff, .repeat_period = 250 }, + .scancode_bits = 0x1fffff, .repeat_period = 125 }, [RC_PROTO_MCIR2_KBD] = { .name = "mcir2-kbd", - .scancode_bits = 0xffff, .repeat_period = 250 }, + .scancode_bits = 0xffffff, .repeat_period = 100 }, [RC_PROTO_MCIR2_MSE] = { .name = "mcir2-mse", - .scancode_bits = 0x1fffff, .repeat_period = 250 }, + .scancode_bits = 0x1fffff, .repeat_period = 100 }, [RC_PROTO_RC6_0] = { .name = "rc-6-0", - .scancode_bits = 0xffff, .repeat_period = 250 }, + .scancode_bits = 0xffff, .repeat_period = 114 }, [RC_PROTO_RC6_6A_20] = { .name = "rc-6-6a-20", - .scancode_bits = 0xfffff, .repeat_period = 250 }, + .scancode_bits = 0xfffff, .repeat_period = 114 }, [RC_PROTO_RC6_6A_24] = { .name = "rc-6-6a-24", - .scancode_bits = 0xffffff, .repeat_period = 250 }, + .scancode_bits = 0xffffff, .repeat_period = 114 }, [RC_PROTO_RC6_6A_32] = { .name = "rc-6-6a-32", - .scancode_bits = 0xffffffff, .repeat_period = 250 }, + .scancode_bits = 0xffffffff, .repeat_period = 114 }, [RC_PROTO_RC6_MCE] = { .name = "rc-6-mce", - .scancode_bits = 0xffff7fff, .repeat_period = 250 }, + .scancode_bits = 0xffff7fff, .repeat_period = 114 }, [RC_PROTO_SHARP] = { .name = "sharp", - .scancode_bits = 0x1fff, .repeat_period = 250 }, - [RC_PROTO_XMP] = { .name = "xmp", .repeat_period = 250 }, - [RC_PROTO_CEC] = { .name = "cec", .repeat_period = 550 }, + .scancode_bits = 0x1fff, .repeat_period = 125 }, + [RC_PROTO_XMP] = { .name = "xmp", .repeat_period = 125 }, + [RC_PROTO_CEC] = { .name = "cec", .repeat_period = 0 }, [RC_PROTO_IMON] = { .name = "imon", - .scancode_bits = 0x7fffffff, .repeat_period = 250 }, + .scancode_bits = 0x7fffffff, .repeat_period = 114 }, }; /* Used to keep track of known keymaps */ @@ -690,7 +690,8 @@ static void ir_timer_repeat(struct timer_list *t) void rc_repeat(struct rc_dev *dev) { unsigned long flags; - unsigned int timeout = protocols[dev->last_protocol].repeat_period; + unsigned int timeout = nsecs_to_jiffies(dev->timeout) + + msecs_to_jiffies(protocols[dev->last_protocol].repeat_period); struct lirc_scancode sc = { .scancode = dev->last_scancode, .rc_proto = dev->last_protocol, .keycode = dev->keypressed ? dev->last_keycode : KEY_RESERVED, @@ -706,7 +707,7 @@ void rc_repeat(struct rc_dev *dev) input_sync(dev->input_dev); if (dev->keypressed) { - dev->keyup_jiffies = jiffies + msecs_to_jiffies(timeout); + dev->keyup_jiffies = jiffies + timeout; mod_timer(&dev->timer_keyup, dev->keyup_jiffies); } @@ -801,7 +802,7 @@ void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode, ir_do_keydown(dev, protocol, scancode, keycode, toggle); if (dev->keypressed) { - dev->keyup_jiffies = jiffies + + dev->keyup_jiffies = jiffies + nsecs_to_jiffies(dev->timeout) + msecs_to_jiffies(protocols[protocol].repeat_period); mod_timer(&dev->timer_keyup, dev->keyup_jiffies); } @@ -1241,6 +1242,9 @@ static ssize_t store_protocols(struct device *device, if (rc < 0) goto out; + if (dev->driver_type == RC_DRIVER_IR_RAW) + ir_raw_load_modules(&new_protocols); + rc = dev->change_protocol(dev, &new_protocols); if (rc < 0) { dev_dbg(&dev->dev, "Error setting protocols to 0x%llx\n", @@ -1248,9 +1252,6 @@ static ssize_t store_protocols(struct device *device, goto out; } - if (dev->driver_type == RC_DRIVER_IR_RAW) - ir_raw_load_modules(&new_protocols); - if (new_protocols != old_protocols) { *current_protocols = new_protocols; dev_dbg(&dev->dev, "Protocols changed to 0x%llx\n", @@ -1647,6 +1648,7 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type) dev->input_dev->setkeycode = ir_setkeycode; input_set_drvdata(dev->input_dev, dev); + dev->timeout = IR_DEFAULT_TIMEOUT; timer_setup(&dev->timer_keyup, ir_timer_keyup, 0); timer_setup(&dev->timer_repeat, ir_timer_repeat, 0); @@ -1735,6 +1737,9 @@ static int rc_prepare_rx_device(struct rc_dev *dev) if (dev->driver_type == RC_DRIVER_SCANCODE && !dev->change_protocol) dev->enabled_protocols = dev->allowed_protocols; + if (dev->driver_type == RC_DRIVER_IR_RAW) + ir_raw_load_modules(&rc_proto); + if (dev->change_protocol) { rc = dev->change_protocol(dev, &rc_proto); if (rc < 0) @@ -1742,9 +1747,6 @@ static int rc_prepare_rx_device(struct rc_dev *dev) dev->enabled_protocols = rc_proto; } - if (dev->driver_type == RC_DRIVER_IR_RAW) - ir_raw_load_modules(&rc_proto); - set_bit(EV_KEY, dev->input_dev->evbit); set_bit(EV_REP, dev->input_dev->evbit); set_bit(EV_MSC, dev->input_dev->evbit); @@ -1860,6 +1862,8 @@ int rc_register_device(struct rc_dev *dev) dev->device_name ?: "Unspecified device", path ?: "N/A"); kfree(path); + dev->registered = true; + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { rc = rc_setup_rx_device(dev); if (rc) @@ -1879,8 +1883,6 @@ int rc_register_device(struct rc_dev *dev) goto out_lirc; } - dev->registered = true; - dev_dbg(&dev->dev, "Registered rc%u (driver: %s)\n", dev->minor, dev->driver_name ? dev->driver_name : "unknown"); diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index d2efd7b2c3bc..c855b177103c 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -96,19 +96,24 @@ static void st_rc_send_lirc_timeout(struct rc_dev *rdev) static irqreturn_t st_rc_rx_interrupt(int irq, void *data) { + unsigned long timeout; unsigned int symbol, mark = 0; struct st_rc_device *dev = data; int last_symbol = 0; - u32 status; + u32 status, int_status; DEFINE_IR_RAW_EVENT(ev); if (dev->irq_wake) pm_wakeup_event(dev->dev, 0); - status = readl(dev->rx_base + IRB_RX_STATUS); + /* FIXME: is 10ms good enough ? */ + timeout = jiffies + msecs_to_jiffies(10); + do { + status = readl(dev->rx_base + IRB_RX_STATUS); + if (!(status & (IRB_FIFO_NOT_EMPTY | IRB_OVERFLOW))) + break; - while (status & (IRB_FIFO_NOT_EMPTY | IRB_OVERFLOW)) { - u32 int_status = readl(dev->rx_base + IRB_RX_INT_STATUS); + int_status = readl(dev->rx_base + IRB_RX_INT_STATUS); if (unlikely(int_status & IRB_RX_OVERRUN_INT)) { /* discard the entire collection in case of errors! */ ir_raw_event_reset(dev->rdev); @@ -148,8 +153,7 @@ static irqreturn_t st_rc_rx_interrupt(int irq, void *data) } last_symbol = 0; - status = readl(dev->rx_base + IRB_RX_STATUS); - } + } while (time_is_after_jiffies(timeout)); writel(IRB_RX_INTS, dev->rx_base + IRB_RX_INT_CLEAR); diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 0adf0991f5ab..851acba9b436 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -989,8 +989,7 @@ wbcir_init_hw(struct wbcir_data *data) /* Clear RX state */ data->rxstate = WBCIR_RXSTATE_INACTIVE; - ir_raw_event_reset(data->dev); - ir_raw_event_set_idle(data->dev, true); + wbcir_idle_rx(data->dev, true); /* Clear TX state */ if (data->txstate == WBCIR_TXSTATE_ACTIVE) { @@ -1009,6 +1008,7 @@ wbcir_resume(struct pnp_dev *device) struct wbcir_data *data = pnp_get_drvdata(device); wbcir_init_hw(data); + ir_raw_event_reset(data->dev); enable_irq(data->irq); led_classdev_resume(&data->led); |