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 ...
This commit is contained in:
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
||||
for (i = 0; i < MCIR2_MASK_KEYS_START; i++)
|
||||
input_report_key(raw->mce_kbd.idev, kbd_keycodes[i], 0);
|
||||
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);
|
||||
|
||||
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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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");
|
||||
|
@@ -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)
|
||||
|
@@ -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 *
|
||||
|
@@ -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))
|
||||
|
@@ -582,9 +582,16 @@ 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;
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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)) {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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");
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
Viittaa uudesa ongelmassa
Block a user